Skip to content

Instantly share code, notes, and snippets.

@evanemolo
Created February 6, 2017 14:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evanemolo/de569b68aba2c435f65a3bcc098612d7 to your computer and use it in GitHub Desktop.
Save evanemolo/de569b68aba2c435f65a3bcc098612d7 to your computer and use it in GitHub Desktop.
ESNext Tic Tac Toe
/* global require process */
const readline = require('readline');
const log = console.log;
class TicTacToe {
static get combos() {
return [
// rows
[0, 1, 2], [3, 4, 5], [6, 7, 8],
// cols
[0, 3, 6], [1, 4, 7], [2, 5, 8],
// diag
[0, 4, 8], [2, 4, 6]
];
}
static get symbols() { return {player1: 'X', player2: 'O'}; }
constructor(readline) {
this.rl = readline;
this.board = [1,2,3,4,5,6,7,8,9];
this.currentPlayer = 'player2';
this.onNext();
}
get symbol() { return TicTacToe.symbols[this.currentPlayer]; }
checkValidCell(input) {
return typeof this.board[input - 1] === 'number';
}
checkWin() {
const board = this.board;
const combos = TicTacToe.combos;
for (let combo of combos) {
let total = 0;
for (let cell of combo) {
// skip to next combo
if (board[cell] !== this.symbol) { break; }
total++;
if (total === 3) { return true; }
}
}
return false;
}
displayBoard() {
const board = this.board;
const len = board.length;
let s = '';
for (let i = 1; i <= len; i++) {
s += i % 3 !== 0 ?
// all cells that are not end of row cells should end with '|'
(board[i - 1] + '|') :
// between each row insert long dash line break, except for last row
i === 9 ? board[i - 1] : (board[i - 1] + `\n\u2014 \u2014 \u2014\n`);
}
log(`\n${s}\n`);
}
onNext(input) {
input = this.processInput(input);
// input is 'undefined' when game starts
if (input !== undefined) {
if (input === -1 || !this.checkValidCell(input)) {
log('invalid input or cell already in use. try again.');
this.rl.setPrompt(`${this.currentPlayer}: `);
this.rl.prompt();
return;
}
this.setBoard(input);
if (this.checkWin()) {
this.displayBoard();
log(`${this.currentPlayer} wins!`);
process.exit(0);
}
}
this.displayBoard();
this.currentPlayer = this.currentPlayer === 'player1' ? 'player2' : 'player1';
this.rl.setPrompt(`${this.currentPlayer}: `);
this.rl.prompt();
}
processInput(input) {
if (input === undefined) { return; }
input = Number.parseInt(input.trim().charAt(0));
if (Number.isNaN(input) || input === 0) { return -1; }
return input;
}
setBoard(input) {
this.board[input - 1] = TicTacToe.symbols[this.currentPlayer];
}
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const game = new TicTacToe(rl);
rl.on('line', input => game.onNext(input));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment