Skip to content

Instantly share code, notes, and snippets.

@perlmonger42
Created August 30, 2012 22:49
Show Gist options
  • Save perlmonger42/3543760 to your computer and use it in GitHub Desktop.
Save perlmonger42/3543760 to your computer and use it in GitHub Desktop.
JavaScript function to determine whether a game of tic-tac-toe has been finished.
// Game_Board will have two slots:
// .boardString represents the contents of the 9 cells of the board
// .winner indicates whether or not the game has been won, and by whom
//
// Each cell in the game board has a cell #, as shown in this chart:
// | |
// 0 | 1 | 2
// ----+---+----
// 3 | 4 | 5
// ----+---+----
// 6 | 7 | 8
// | |
// GameBoard.boardString.charAt(cellNumber) is '-' if cellNumber is
// unplayed, 'X' if played in by player X, and 'O' if played in by
// player O.
//
// Game_Board.winner is:
// '?' if game is not finished
// 'X' if game has been won by X
// 'O' if game has been won by O
// 'C' if game has been won by 'cat' (no moves left, but no winner)
// game_overQ()
// checks the game in Game_Board.boardString to see if the game is
// finished. If the game is done, Game_Board.winner is set to 'X',
// 'O', or 'C' according to whether the game was won by player X,
// player O, or 'cat'. If the game is not yet finished, Game_Board.winner
// is set to '?'. winnerQ() and stalemateQ() do most of the work -- both
// functions set Game_Board.winner if and only if they return true.
function game_overQ()
{
Game_Board.winner = '?'; // Assume the outcome is in doubt, then check.
return winnerQ(0,1,2) // check for 3-in-a-row horizontally
|| winnerQ(3,4,5)
|| winnerQ(6,7,8)
|| winnerQ(0,3,6) // check for 3-in-a-row vertically
|| winnerQ(1,4,7)
|| winnerQ(2,5,8)
|| winnerQ(0,4,8) // check for 3-in-a-row diagonally
|| winnerQ(6,4,2)
|| stalemateQ(); // check for win by 'cat'
}
// winnerQ(p1, p2, p3)
// p1, p2, p3: three cell numbers (integers in the range 0..8).
// Returns a boolean indicating whether the indicated cells in
// Game_Board.boardString contain a three-in-a-row win for either player.
// If they do, Game_Board.winner will be set to 'X' or 'O' as appropriate
// before winnerQ() returns.
//
// The result will be nonsense unless the cell numbers are distinct cells
// which form three-in-a-row on the game board, since winnerQ() merely
// checks whether all three cells are occupied by 'X' or all three by 'O'.
function winnerQ(p1, p2, p3)
{
var s = Game_Board.boardString;
var c1 = s.charAt(p1);
if (c1 == '-') return false;
var c2 = s.charAt(p2);
if (c1 != c2) return false;
var c3 = s.charAt(p3);
if (c1 != c3) return false;
Game_Board.winner = c1;
return true;
}
// stalemateQ()
// Returns true if all the cells in Game_Board.boardString are occupied, and
// false otherwise. (Technically, this condition does not guarantee stalemate,
// but this routine is called only after all possible wins have been checked.)
// As a side effect, Game_Board.winner is set to 'C' (for 'cat') if the game
// is over.
function stalemateQ()
{
var s = Game_Board.boardString;
for (var i=0; i<9; i++) {
if (s.charAt(i) == '-') return false;
}
Game_Board.winner = "C";
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment