Created
October 24, 2014 14:03
-
-
Save kedmundson/34b7ea9c3e149a459f28 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
<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 file contains hidden or 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
// 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