From: Dylan Lloyd Date: Wed, 10 Jun 2015 21:52:45 +0000 (-0700) Subject: very messy, doesn't handle ties X-Git-Url: https://disinclined.org/git/?a=commitdiff_plain;h=12813d7a812c5c4631223d65edab0223cc30e548;p=minimax.git very messy, doesn't handle ties --- diff --git a/ai.js b/ai.js index be70f72..3dc86f7 100644 --- a/ai.js +++ b/ai.js @@ -62,9 +62,9 @@ $(document).ready(function(){ this.cellSize, this.cellSize); } } - if (this.turn == 'ai') { - minimax(this, 'x'); - } +// if (this.turn == 'ai') { +// minimax(this, 'x'); +// } return this; } this.serialize = function() { @@ -90,26 +90,39 @@ $(document).ready(function(){ if (x > cell.x && x < cell.x + cell.size && y > cell.y && y < cell.y + cell.size) { //cell.play(Math.random() > 0.5 ? 'x' : 'o'); - cell.play('x'); + if (!cell.state) { + var player = 'x'; + cell.play(player); + var aiMove = minimax(tictactoe.serialize(), player, ii, i).move; + console.log(aiMove); + tictactoe.cells[aiMove[1]][aiMove[0]].play('o'); + return; + } } } } - minimax(tictactoe, 'x'); }); - function generate(board, player) { + function generate(state, player) { + console.log('generating futures for ' + player); var possibilities = []; - for (var i = 0; i < board.cells.length; i++) { - for (var ii = 0; ii < board.cells[i].length; ii++) { - if (!board.cells[i][ii].state) { - var future = jQuery.extend(true, [], board.serialize()); + for (var i = 0; i < state.length; i++) { + for (var ii = 0; ii < state[i].length; ii++) { + if (!state[i][ii]) { + //console.log(state[i][ii]); + //console.log('i: ' + i + ', ii: ' + ii); + var future = jQuery.extend(true, [], state); future[i][ii] = player; - possibilities.push(future); - if (score(future, player, ii, i)) - console.log('found win condition'); + possibilities.push({ + 'state' : future, + 'player' : player, + 'x' : ii, + 'y' : i, + }); } } } + return possibilities; } function score(state, player, x, y) { @@ -125,21 +138,71 @@ $(document).ready(function(){ verticalTally++; if (state[i][i] == player) diagonalTally++; - if (state[i][(size-1)-i]) + if (state[i][(size-1)-i] == player) antiDiagonalTally++; } if (horizontalTally == size || verticalTally == size || diagonalTally == size || antiDiagonalTally == size) - return 'win'; + return player == 'o' ? 1 : -1; } - function minimax(board, player) { - generate(board, player); - //board.turn = 'player'; + function minimax(state, player, x, y) { + console.log('minimax: ' + state + ' by ' + player + ' at ' + x + ',' + y); + var win = score(state, player, x, y); + if (win) { + console.log((win == 1 ? 'o' : 'x') + ' won with ' + x + ',' + y); + return { + 'move' : [x,y], + 'score' : win + }; + } + player = player == 'x' ? 'o' : 'x'; + var scores = []; + var futures = generate(state, player); + for (var i in futures) { + var future = futures[i]; + scores.push(minimax(future.state, future.player, future.x, future.y)); + } + if (player == 'o') { + console.log(scores); + var bestScore = 1; + var bestMove; + for (var i in scores) { + if (scores[i].score <= bestScore) { + bestScore = scores[i].score; + bestMove = scores[i].move; + } + } + return { + 'move' : bestMove, + 'score' : bestScore + }; + } else if (player == 'x') { + console.log(scores); + var bestScore = -1; + var bestMove; + for (var i in scores) { + if (scores[i].score >= bestScore) { + console.log('assigning: ' + scores[i].move + ' to bestMove'); + console.log(scores[i]); + bestScore = scores[i].score; + bestMove = scores[i].move; + } + } + return { + 'move' : bestMove, + 'score' : bestScore + }; + } } var tictactoe = new board(3, 'player').init(); + tictactoe.cells[1][0].play('x'); + tictactoe.cells[0][2].play('o'); + tictactoe.cells[1][1].play('x'); + tictactoe.cells[2][1].play('o'); + });