Created
February 6, 2017 14:34
-
-
Save evanemolo/de569b68aba2c435f65a3bcc098612d7 to your computer and use it in GitHub Desktop.
ESNext Tic Tac Toe
This file contains 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
/* 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