Skip to content

Instantly share code, notes, and snippets.

@brandontle
Created October 19, 2018 11:34
Show Gist options
  • Select an option

  • Save brandontle/3c4fc651756e39e8f0240413298a5b14 to your computer and use it in GitHub Desktop.

Select an option

Save brandontle/3c4fc651756e39e8f0240413298a5b14 to your computer and use it in GitHub Desktop.
//tic-tac-toe game for play within console
//with two humans
//---
//game class with logic
class TicTacToe {
constructor() {
this.board = this.makeBoard();
this.currentPlayer = 1;
this.winner = null;
this.gameFinished = false;
}
makeBoard() {
//Setup board as array with cellNumber as value
// 0 1 2
// 3 4 5
// 6 7 8
let board = Array.from({ length: 9 }, (x, i) => i);
return board;
}
//determine winner from given mark
determineWinner(val) {
return val === 'x' ? 1 : 2;
}
checkRowsForWin() {
let bo = this.board;
//3-marks in same row
//1st row
if (bo[0] === bo[1] && bo[0] === bo[2]) {
return bo[0];
}
//2nd row
if (bo[3] === bo[4] && bo[3] === bo[5]) {
return bo[3];
}
//3rd row
if (bo[6] === bo[7] && bo[6] === bo[8]) {
return bo[6];
}
}
checkColsForWin() {
let bo = this.board;
//3-marks in same col
//first col
if (bo[0] === bo[3] && bo[0] === bo[6]) {
return bo[0][0];
}
//2nd col
if (bo[1] === bo[4] && bo[1] === bo[7]) {
return bo[1];
}
//3rd col
if (bo[2] === bo[5] && bo[2] === bo[8]) {
return bo[2];
}
}
checkDiagsForWin() {
let bo = this.board;
//3-marks in diag
//down-diag
if (bo[0] === bo[4] && bo[0] === bo[8]) {
return bo[0];
}
//up-diag
if (bo[2] === bo[4] && bo[2] === bo[6]) {
return bo[2];
}
}
checkForTie() {
let bo = this.board;
//if no digits remain after rows, cols, and diags have been checked, then tie
if (bo.every(val => typeof val === 'string')) {
return 'tie';
}
}
checkWinner() {
let winner = null;
if (this.checkColsForWin()) {
winner = this.determineWinner(this.checkColsForWin());
} else if (this.checkRowsForWin()) {
winner = this.determineWinner(this.checkRowsForWin());
} else if (this.checkDiagsForWin()) {
winner = this.determineWinner(this.checkRowsForWin());
} else if (this.checkForTie() === 'tie') {
winner = this.checkForTie();
}
return winner;
}
updateState() {
//updates state and returns a string to display one of three states: won, tie, in-progress
this.winner = this.checkWinner();
//won
if (this.winner && this.winner !== 'tie') {
this.gameFinished = true;
return `Player ${this.currentPlayer} wins!`;
}
//tie
else if (this.winner === 'tie') {
this.gameFinished = true;
return 'Tie!';
}
}
playTurn(cellNumber) {
if (cellNumber > 8 || cellNumber < 0 || cellNumber === '') {
return `ERROR: Please pick a number between 0 and 8, inclusive!\nStill Player ${
this.currentPlayer
}'s turn!`;
} else if (typeof this.board[cellNumber] === 'string') {
return `ERROR:Pick another square!\nStill Player ${
this.currentPlayer
}'s turn!`;
} else {
this.board[cellNumber] = this.currentPlayer === 1 ? 'x' : 'o';
let message = this.updateState();
this.currentPlayer = this.currentPlayer === 1 ? 2 : 1;
return message ? message : `Player ${this.currentPlayer}'s turn!`;
}
}
}
//---
//console interface
let game = new TicTacToe();
const prompt = data => {
let bo = game.board;
console.log('\n-------');
console.log('Current Board:');
console.log(bo[0], bo[1], bo[2]);
console.log(bo[3], bo[4], bo[5]);
console.log(bo[6], bo[7], bo[8]);
console.log('-------');
process.stdout.write(
`\nCurrent Mark: ${
game.currentPlayer === 1 ? 'x' : 'o'
}\nPlease enter a cell number> `
);
};
prompt();
process.stdin.on('data', data => {
const cellNumber = data.toString().trim();
let message = game.playTurn(cellNumber);
console.log('\n*******\n');
console.log(message);
if (!game.gameFinished) {
prompt();
} else {
process.stdout.write(`Play another game? (y)> `);
process.stdin.on('data', data => {
const resp = data.toString().trim();
if (resp.toLowerCase() === 'y') {
game = new TicTacToe();
prompt();
}
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment