Tic Tac Toe
by Bill Withers
HTML
<script src="https://raw.github.com/LeaVerou/prefixfree/master/prefixfree.min.js"></script>
<p class="score" id="X">0</p>
<p class="score" id="O">0</p>
<div id="ttt">
<ol>
<li></li> <li></li> <li></li>
<li></li> <li></li> <li></li>
<li></li> <li></li> <li></li>
</ol>
</div>
CSS
body {font-family: sans-serif;}
#ttt {background: #f9f9f9; margin: 40px auto; width: 300px; height: 300px; padding: 5px 0 2px 5px; border: 1px solid #eee; box-shadow: 0px 15px 10px -15px rgba(0,0,0,0.2);}
#ttt li {float: left; width: 97px; height: 97px; border: 1px solid #ddd; background: #fff;}
#ttt li[class] {text-shadow: 0 2px 1px rgba(255,255,255,1), 0 -2px 1px rgba(0,0,0,0.05);}
#ttt .X, #X {background: #d9f4ff;}
#ttt .O, #O {background: #ffedd9;}
.X:before, .O:before { display: block; text-align: center; font-size: 62px; width: 97px; line-height: 97px;}
#X:before, #O:before { color: #777; margin-right: 10px;}
.score {padding: 5px; font-family: Consolas, monospace; font-weight: bold; font-size: 22px;}
.X:before, #X:before {content: "X";}
.O:before, #O:before {content: "O";}
JavaScript
(function TicTacToe() {
var board = $('#ttt'),
boxes = board.find('li'),
map = { X: '', O: '' },
players = {
X: { score: 0 },
O: { score: 0 }
},
active = 'X',
turns = 0,
wins = ['012', '345', '678', '036', '147', '258', '048', '246'];
function turn() {
++turns;
var box = $(this),
a = map[active];
box.addClass(active);
map[active] += box.index();
map[active] = map[active].split('').sort().join('');
checkTurn();
}
function checkTurn() {
var over = false;
$.each(wins, function(i, win) {
var winning = new RegExp('.?' + win[0] + '.?' + win[1] + '.?' + win[2] + '.?');
if (winning.test(map[active])) over = true;
});
if (over) { // matched a winning combination
gameOver(active);
} else {
if (turns === 9) { // tie
gameOver();
} else { // prepare next turn
active = (active === 'X') ? 'O' : 'X';
}
}
}
function gameOver(winner) {
if (winner) {
alert(winner + ', you Won! :-D');
$('#' + active).text(++players[active].score);
} else {
alert('Well, it\'s a tie.');
}
newGame();
}
function newGame() {
map['X'] = '';
map['O'] = '';
turns = 0;
boxes.removeAttr('class');
}
function init() {
board.delegate('li:not([class])', 'click', turn);
}
$(init);
})();