Created
July 19, 2015 23:09
-
-
Save TimurM/d9ca011351ea615bf3c5 to your computer and use it in GitHub Desktop.
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
// 1. Think about the Data | |
// -Get out all of the data that's relavent in the right shape | |
// -Funcitons that transform that data from one state to the next state | |
// | |
// Invarient: True for every game | |
// -2 Players | |
// -2 symbols for each player | |
// -Some Mapping between the player and the symbol | |
// -3x3 grid with a total of 9 squares | |
// -moves / history of moves | |
// New Game: | |
var initGameState = { | |
player1: null, | |
player2: null, | |
sideLength: 3, | |
moves: [] | |
} | |
const WINNING_COMBINATIONS = [ | |
[[0,0], [0,1], [0,2]], | |
[[1,0], [1,1], [1,2]], | |
[[2,0], [2,1], [2,2]], | |
[[0,0], [1,0], [2,0]], | |
[[0,1], [1,1], [2,1]], | |
[[0,2], [1,2], [2,2]], | |
[[0,0], [1,1], [2,2]], | |
[[0,2], [1,1], [2,0]], | |
] | |
var getPlayerSymbols = function(/*Record*/ gameState) { /* Record */ | |
var sym = null; | |
do { | |
sym = prompt("Hello player one enter 'x' or 'o'?"); | |
} while (!validateSymbolSelection(sym)); | |
gameState.player1 = parseSymbolSelection(sym); | |
gameState.player2 = oppositeSym(sym); | |
return gameState; | |
} | |
var oppositeSym = function(/*string*/sym) { /* string */ | |
return (sym === 'x' ? 'o' : "x") | |
} | |
var validateSymbolSelection = function(/*String*/ sym) { /* string */ | |
return (sym === 'x' || sym === 'o'); | |
} | |
var parseSymbolSelection = function(/*String*/ sym) { /*string*/ | |
return sym.toLowerCase(); | |
} | |
var getPlayerMove = function(/*Record, string*/ gameState) { /* Record */ | |
var move = null; | |
var playerSym = winner(gameState); | |
do { | |
renderBoard(gameState.moves); | |
move = prompt("It's your turn to move, enter [x,y] coordiate of your move") | |
move = parseMoveString(move); | |
} while (!validateMove(move, gameState)); | |
var moveAndSym = [move, playerSym]; | |
gameState.moves.push(moveAndSym); | |
return gameState; | |
} | |
var renderBoard = function(/*List*/moves) { /* print row */ | |
var board = createBoard(moves); | |
board.forEach(function(row) { | |
console.log(row); | |
}) | |
} | |
var createBoard = function(/*list*/moves) {/* list */ | |
var board = [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]; | |
return moves.reduce(function(boardWithMoves, move) { | |
var x = move[0][0]; | |
var y = move[0][1]; | |
boardWithMoves[x][y] = move[1]; | |
return boardWithMoves; | |
}, board) | |
} | |
var validateMove = function(/*Pair<int, int>, Record */ move, gameState) {/* boolean */ | |
if(!arrayIncludesArray(gameState.moves, move)) { | |
return (move[0] >= 0 && move[0] < 3) && (move[1] >= 0 && move[1] < 3) | |
} else { | |
return false; | |
} | |
} | |
var parseMoveString = function(/*String*/ move) { /* Pair<int, int> */ | |
return move.split(",").map(function(el) { return parseInt(el) }) | |
} | |
var boardWinning = function(/*Record*/gameState) {/* Record */ | |
if(wonGame(gameState)) { | |
return winner(gameState); | |
} else if (gameState.moves.length === 8) { | |
return "it's a tie"; | |
} else { | |
var gameState = getPlayerMove(gameState); | |
return boardWinning(gameState); | |
} | |
} | |
var wonGame = function(/*Record*/ gameState) { /* boolean true or false */ | |
return WINNING_COMBINATIONS.reduce(function(won, winningCombo, player) { | |
return arrayContainsWinningMove(gameState, winningCombo) ? true : won; | |
}, false) | |
} | |
var arrayContainsWinningMove = function(/*Record, List<Triple<Pair<int, int>>>*/ gameState, innerArray) { | |
return innerArray.reduce(function(match, pair) { | |
return !winningArrIncludesSyms(gameState, pair) ? false : match; | |
}, true) | |
} | |
var winningArrIncludesSyms = function(/*Record, Pair<int, int>,*/gameState, moveArr) { /* boolean true or false */ | |
var player = winner(gameState); | |
return gameState.moves.reduce(function(checkedArray, arr) { | |
return arr[0].join("") === moveArr.join("") && player === arr[1] ? true : checkedArray; | |
}, false) | |
} | |
var arrayIncludesArray = function(/*Array, Pair<int, int>*/givenArray, moveArr) { /* boolean true or false */ | |
return givenArray.reduce(function(checkedArray, arr) { | |
return arr[0].join("") === moveArr.join("") ? true : checkedArray; | |
}, false) | |
} | |
var winner = function(/*Record */ gameState) { /* string */ | |
// determines whether player1 or player2 made the winning move | |
var numMoves = gameState.moves.length; | |
return numMoves === 0 || numMoves % 2 === 0 ? gameState.player1 : gameState.player2; | |
} | |
console.log(boardWinning(getPlayerSymbols(initGameState))); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment