Created
March 16, 2018 13:56
-
-
Save Johnicholas/76e2c729df880508b67cbffcaddf36f0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Takes a three-element list, and returns X if it is won for X, | |
// O if it is won for O, and null if it is not won | |
function tripleIsWon(triple) { | |
var count_x = 0; | |
var count_y = 0; | |
for (var i = 0; i < 3; i += 1) { | |
if (triple[i] == "X") { | |
count_x += 1; | |
} else if (triple[i] == "O") { | |
count_y += 1; | |
} | |
} | |
if (count_x == 3) { | |
return "X"; | |
} else if (count_y == 3) { | |
return "O"; | |
} else { | |
return null; | |
} | |
} | |
export default class TicTacToe { | |
constructor () { | |
this.turn = null; | |
this.state = null; | |
this.previous_update = null; | |
this.reset(); | |
} | |
// Puts the game state to the usual beginning of the game | |
reset() { | |
this.turn = "X"; | |
this.state = [ | |
[".", ".", "."], | |
[".", ".", "."], | |
[".", ".", "."], | |
]; | |
} | |
drawTheGrid(ctx) { | |
ctx.clearRect(0, 0, 300, 300); | |
ctx.beginPath(); | |
ctx.moveTo(100, 0); | |
ctx.lineTo(100, 300); | |
ctx.moveTo(200, 0); | |
ctx.lineTo(200, 300); | |
ctx.moveTo(0, 100); | |
ctx.lineTo(300, 100); | |
ctx.moveTo(0, 200); | |
ctx.lineTo(300, 200); | |
ctx.stroke(); | |
} | |
drawX(ctx, row, col) { | |
ctx.beginPath(); | |
ctx.moveTo(col * 100 + 33, row * 100 + 33); | |
ctx.lineTo(col * 100 + 66, row * 100 + 66); | |
ctx.moveTo(col * 100 + 66, row * 100 + 33); | |
ctx.lineTo(col * 100 + 33, row * 100 + 66); | |
ctx.stroke(); | |
} | |
drawO(ctx, row, col) { | |
ctx.beginPath(); | |
ctx.arc(col * 100 + 50, row * 100 + 50, 33, 0, 2 * Math.PI); | |
ctx.stroke(); | |
} | |
draw(ctx) { | |
this.drawTheGrid(ctx); | |
for (var row = 0; row < 3; row += 1) { | |
for (var col = 0; col < 3; col += 1) { | |
if (this.state[row][col] == "X") { | |
this.drawX(ctx, row, col); | |
} else if (this.state[row][col] == "O") { | |
this.drawO(ctx, row, col); | |
} | |
} | |
} | |
} | |
// Takes an x, y pair and interprets it as (an attempted) move | |
interpret(x, y) { | |
var row, col; | |
if (x < 100) { | |
col = 0; | |
} else if (x < 200) { | |
col = 1; | |
} else { | |
col = 2; | |
} | |
if (y < 100) { | |
row = 0; | |
} else if (y < 200) { | |
row = 1; | |
} else { | |
row = 2; | |
} | |
return [row, col]; | |
} | |
// The current player puts their mark at row, col, if it is open. | |
// Does nothing if it is not open. | |
move(row, col) { | |
if (this.state[row][col] != ".") { | |
return; | |
} | |
this.state[row][col] = this.turn; | |
if (this.turn == "X") { | |
this.turn = "O"; | |
} else { | |
this.turn = "X"; | |
} | |
} | |
// Returns "X" if X has won, "O" if O has won, or null if nobody has won. | |
won() { | |
return tripleIsWon([this.state[0][0], this.state[0][1], this.state[0][2]]) || | |
tripleIsWon([this.state[0][0], this.state[0][1], this.state[0][2]]) || | |
tripleIsWon([this.state[0][0], this.state[0][1], this.state[0][2]]) || | |
tripleIsWon([this.state[0][0], this.state[1][0], this.state[2][0]]) || | |
tripleIsWon([this.state[0][1], this.state[1][1], this.state[2][1]]) || | |
tripleIsWon([this.state[0][2], this.state[1][2], this.state[2][2]]) || | |
tripleIsWon([this.state[0][0], this.state[1][1], this.state[2][2]]) || | |
tripleIsWon([this.state[2][0], this.state[1][1], this.state[0][2]]); | |
} | |
// Returns true if there is a draw. | |
drawnGame() { | |
for (var row = 0; row < 3; row += 1) { | |
for (var col = 0; col < 3; col += 1) { | |
if (this.state[row][col] == ".") { | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
// Called periodically, resets the game when it is over | |
update(absolute_ms) { | |
if (this.previous_update === null) { | |
this.previous_update = absolute_ms; | |
} | |
var delta_ms = absolute_ms - this.previous_update; | |
console.log(delta_ms); | |
if (delta_ms > 1000) { | |
this.previous_update = absolute_ms; | |
var who = this.won(); | |
if (who != null) { | |
alert(`Yay, ${who} won!`); | |
this.reset(); | |
} else if (this.drawnGame()) { | |
alert("It's a draw!"); | |
this.reset(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment