Skip to content

Instantly share code, notes, and snippets.

@Johnicholas
Created March 16, 2018 13:56
Show Gist options
  • Save Johnicholas/76e2c729df880508b67cbffcaddf36f0 to your computer and use it in GitHub Desktop.
Save Johnicholas/76e2c729df880508b67cbffcaddf36f0 to your computer and use it in GitHub Desktop.
// 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