From 5edfa7ef146c9eb1705995ec7b1bbc79d37710fa Mon Sep 17 00:00:00 2001 From: Dylan Lloyd Date: Tue, 9 Jun 2015 18:10:16 -0700 Subject: [PATCH] restructure things a bit, and start minimax deep copy won't update fn references! --- ai.js | 143 +++++++++++++++++++++++++++++++++++++++--------------- index.php | 3 -- style.css | 15 ------ 3 files changed, 104 insertions(+), 57 deletions(-) diff --git a/ai.js b/ai.js index 194d524..be70f72 100644 --- a/ai.js +++ b/ai.js @@ -8,59 +8,79 @@ $(document).ready(function(){ this.y = y; this.size = size; this.state = 0; - this.play = function(player) { + this.play = function(player, draw) { this.state = player; var centerX = this.x + this.size/2; var centerY = this.y + this.size/2; - if (player == 'o') { - ctx.beginPath(); - ctx.arc(centerX, centerY, - size/2-20, 0, 2 * Math.PI); - ctx.lineWidth = 10; - ctx.stroke(); - } else if (player == 'x') { - ctx.beginPath(); - ctx.moveTo(centerX, centerY); - ctx.lineTo(self.cellSize, canvas.height); - ctx.moveTo(centerX - 50, centerY - 50); - ctx.lineTo(centerX + 50, centerY + 50); - ctx.moveTo(centerX + 50, centerY - 50); - ctx.lineTo(centerX - 50, centerY + 50); - ctx.lineWidth = 10; - ctx.stroke() + if (typeof draw == 'undefined' ? true : draw) { + if (player == 'o') { + ctx.beginPath(); + ctx.arc(centerX, centerY, + size/2-20, 0, 2 * Math.PI); + ctx.lineWidth = 10; + ctx.stroke(); + } else if (player == 'x') { + ctx.beginPath(); + ctx.moveTo(centerX, centerY); + ctx.lineTo(self.cellSize, canvas.height); + ctx.moveTo(centerX - 50, centerY - 50); + ctx.lineTo(centerX + 50, centerY + 50); + ctx.moveTo(centerX + 50, centerY - 50); + ctx.lineTo(centerX - 50, centerY + 50); + ctx.lineWidth = 10; + ctx.stroke() + } } } } - function board(size) { + function board(size, startingActor) { var self = this; - self.cellSize = canvas.width / size; - self.cells = []; - ctx.lineWidth = 2; - for (var i = 0; i < size; i++) { - self.cells.push([]); - if (i > 0) { - ctx.beginPath(); - ctx.moveTo(0, self.cellSize*i); - ctx.lineTo(canvas.width, self.cellSize*i); - ctx.stroke(); - } - for (var ii = 0; ii < size; ii++) { - if (ii > 0) { + this.size = size; + this.cellSize = canvas.width / size; + this.cells = []; + this.turn = startingActor; + this.init = function() { + ctx.lineWidth = 2; + for (var i = 0; i < this.size; i++) { + this.cells.push([]); + if (i > 0) { ctx.beginPath(); - ctx.moveTo(self.cellSize*ii, 0); - ctx.lineTo(self.cellSize*ii, canvas.height); + ctx.moveTo(0, this.cellSize*i); + ctx.lineTo(canvas.width, this.cellSize*i); ctx.stroke(); } - self.cells[i][ii] = - new cell(self.cellSize*ii, self.cellSize*i, - self.cellSize, self.cellSize); + for (var ii = 0; ii < this.size; ii++) { + if (ii > 0) { + ctx.beginPath(); + ctx.moveTo(this.cellSize*ii, 0); + ctx.lineTo(this.cellSize*ii, canvas.height); + ctx.stroke(); + } + this.cells[i][ii] = + new cell(this.cellSize*ii, this.cellSize*i, + this.cellSize, this.cellSize); + } + } + if (this.turn == 'ai') { + minimax(this, 'x'); + } + return this; + } + this.serialize = function() { + var serial = [] + for (var i = 0; i < this.cells.length; i++) { + serial.push([]); + for (var ii = 0; ii < this.cells[i].length; ii++) { + serial[i][ii] = this.cells[i][ii].state; + } } + return serial; } } $('#board').on('click', function(e){ - if (!tictactoe) return; + if (!tictactoe && tictactoe.turn != 'player') return; event = e || window.event; x = event.pageX - canvas.offsetLeft, y = event.pageY - canvas.offsetTop; @@ -69,12 +89,57 @@ $(document).ready(function(){ var cell = tictactoe.cells[i][ii]; 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(Math.random() > 0.5 ? 'x' : 'o'); + cell.play('x'); } } } + minimax(tictactoe, 'x'); }); - var tictactoe = new board(3); + function generate(board, 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()); + future[i][ii] = player; + possibilities.push(future); + if (score(future, player, ii, i)) + console.log('found win condition'); + } + } + } + } + + function score(state, player, x, y) { + var horizontalTally = 0; + var verticalTally = 0; + var diagonalTally = 0; + var antiDiagonalTally = 0; + var size = state.length; + for (var i = 0; i < size; i++) { + if (state[y][i] == player) + horizontalTally++; + if (state[i][x] == player) + verticalTally++; + if (state[i][i] == player) + diagonalTally++; + if (state[i][(size-1)-i]) + antiDiagonalTally++; + } + if (horizontalTally == size + || verticalTally == size + || diagonalTally == size + || antiDiagonalTally == size) + return 'win'; + } + + function minimax(board, player) { + generate(board, player); + //board.turn = 'player'; + } + + var tictactoe = new board(3, 'player').init(); }); diff --git a/index.php b/index.php index 9bb24ed..1be5f70 100644 --- a/index.php +++ b/index.php @@ -8,8 +8,5 @@ -
-
Play!
-
diff --git a/style.css b/style.css index fd6c67f..1ae7188 100644 --- a/style.css +++ b/style.css @@ -6,18 +6,3 @@ body { margin: 0px auto; float: left; } - -#controls { - float: left; - margin-left: 30px; - width: 400px; -} - -.button { - width: 70px; - padding: 1px 0; - margin-top: 10px; - border: 3px solid black; - cursor: pointer; - text-align: center; -} -- 2.30.2