Skip to content

Instantly share code, notes, and snippets.

@kedmundson
Created October 24, 2014 14:03
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 kedmundson/34b7ea9c3e149a459f28 to your computer and use it in GitHub Desktop.
Save kedmundson/34b7ea9c3e149a459f28 to your computer and use it in GitHub Desktop.
<html>
<head>
<title>Play Tic Tac Toe</title>
<script src="ticTacToe.js"></script>
<style>
table {
margin: 1% auto;
border-collapse: collapse;
width: 300px;
height: 300px;
}
td {
width: 33%;
height: 33%;
border-right: 5px solid #999;
border-bottom: 5px solid #999;
text-align: center;
font: normal 4em Helvetica, sans-serif;
color: #999;
}
td:last-child {
border-right: 0;
}
tr:last-child > td {
border-bottom: 0;
}
</style>
</head>
<body>
<div id="ticTacToeBoard"></div>
</body>
</html>
// This is a game of Tic Tac Toe for two human players to play
// in a browser. X begins each game.
(function () {
var playerX = { gamePiece: 'X', score: 0 }
, playerO = { gamePiece: 'O', score: 0 }
, currentPlayer
, moves
, movesLimit = 9
, boxScore
, boxes = []
, createBoard = function () {
newGame();
var board = document.createElement('table')
, row
, box
, boxScore = 1
;
for (var i = 0; i < 3; i++) {
row = document.createElement('tr');
board.appendChild(row);
for (var k = 0; k < 3; k++) {
box = document.createElement('td');
box.textContent = '';
box.onclick = recordMove;
//
// Assign a unique score to each box, starting in the top left box
// with boxScore = 1 and ascending in multiples of 2. This way we
// can represent the boxes a player has marked with a bit string
// and its corresponding numeral score, and check it against a
// list of winning scores that we defined by adding the boxScores of
// all the three-across, three-down, and three-diagonal combinations.
// Credit for the bit string idea goes to this jsFiddle poster:
// http://jsfiddle.net/5wKfF/
//
box.boxScore = boxScore;
boxScore = (boxScore * 2);
boxes.push(box);
row.appendChild(box);
}
}
document.getElementById('ticTacToeBoard').appendChild(board);
}
, winningScores = [ 7, 15, 56, 84, 146, 273, 292, 448 ]
, recordMove = function () {
if (this.textContent !== '') return;
this.textContent = currentPlayer.gamePiece;
currentPlayer.score += this.boxScore;
moves += 1;
if ( checkForWins(currentPlayer) || checkForTie() ) {
return;
} else {
switchPlayer(currentPlayer);
}
}
, checkForWins = function (player) {
if (moves >= 5) {
for (var i = 0; i < winningScores.length; i++) {
//
// Convert player.score and winningScores[i] to bit representations
// and binary AND them using the '&' bitwise operator. If the two
// operands match, the result will be the same as either operand
// and therefore equal to winningScores[i]
//
// Using bits to represent an X or O in each box of the game board means that
// this operation will work even if a player has marked more than three boxes
// before getting a win.
//
if ((player.score & winningScores[i]) === winningScores[i]) {
alert(player.gamePiece + " won! Do you want to play again?");
newGame();
return true;
}
}
}
}
// End game in a tie if no one wins before movesLimit is reached
, checkForTie = function () {
if (moves === movesLimit) {
alert("It's a tie. Play again?");
newGame();
return true;
}
}
, switchPlayer = function (player) {
currentPlayer = (player === playerX) ? playerO : playerX;
}
// Reset the game board
, newGame = function () {
playerX.score = 0,
playerO.score = 0,
currentPlayer = playerX;
moves = 0;
for (var i = 0; i < boxes.length; i++) {
document.getElementsByTagName('TD')[i].textContent = '';
}
}
;
window.onload = function () {
createBoard();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment