JSFiddle - React, Tailwind, and code Playground
by MPelletier
HTML
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<body>
<div>
<h2>Tic-Tac-Toe</h2>
<h3 id="currentPlayer">Current player: <span id="currentTurn">X</span></h3>
<h2 id="gameWinner" class="helper-hidden">Player <span id="winningPlayer"></span> is the winner!</h2>
<h2 id="noWinner" class="helper-hidden">Draw!</h2>
</div>
<div>
<table id="game" cellpadding="0" cellspacing="0">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
</body>
CSS
body {
background-color: #0a2126;
color: #FFFFFF;
font-family: "montserrat", "verdana";
margin: 0;
padding: 0;
text-align: center;
}
#game {
border-collapse: collapse;
margin: 50px auto;
position: relative;
}
td {
border: 0px solid #113942;
border-right-width: 6px;
border-bottom-width: 6px;
cursor: pointer;
font-size: 80px;
height: 170px;
position: relative;
text-align: center;
width: 170px;
}
td:nth-child(3) { border-right-width: 0px; }
tr:last-child td { border-bottom-width: 0px; }
td.O { color: #60a0ae; }
td.X { color: #7de0b0; }
td.hover-0:after,
td.hover-1:after {
color: #FFF;
content: "X";
display: block;
font-size: 80px;
opacity: 0.6;
pointer-events: none;
position: relative;
text-align: center;
vertical-align: center;
}
td.hover-1:after {
content:"O";
}
td.X.hover-0:after, td.X.hover-1:after,
td.O.hover-0:after, td.O.hover-1:after {
display:none !important;
}
.helper-hidden {
display: none;
}
JavaScript
var Game = function() {
this.init = function(){
this.players = [
{ symbol: 'X', moves: [] },
{ symbol: 'O', moves: [] }
]
this.activePlayer = 0;
this.moves = 0;
this.gameInProgress = true;
this.board = [
null, null, null,
null, null, null,
null, null, null
];
this.potentialWins = [
[0,1,2], [3,4,5], [6,7,8], [0,3,6],
[1,4,7], [2,5,8], [0,4,8], [2,4,6]
];
this.bindEvents();
$('#game tr td').attr('class', '');
$('#currentPlayer').removeClass('helper-hidden');
$('#gameWinner').addClass('helper-hidden');
$('#noWinner').addClass('helper-hidden');
this.updateBoard();
}
this.bindEvents = function(){
var self = this;
// bind input actions
$('#game tr td').click(function() {
if (!self.gameInProgress) {
return;
}
var col = $(this).index();
var row = $(this).closest('tr').index();
// Convert Row/Column into Index
var position = col;
if (row === 1) {
position += 3;
} else if (row === 2) {
position += 6;
}
self.move(position);
});
$('#game tr td').hover(function() {
if (!self.gameInProgress) {
return;
}
$(this).addClass('hover-'+ self.activePlayer);
}, function(){
if (!self.gameInProgress) {
return;
}
$(this).removeClass('hover-0 hover-1');
})
};
this.updateActivePlayer = function() {
var currentPlayer = this.activePlayer;
this.activePlayer = currentPlayer === 0 ? 1 : 0;
$('#currentTurn').text(this.players[this.activePlayer].symbol);
};
this.tryMove = function(input){
if (this.board[input] == null) {
return true;
}
return false;
};
this.move = function(position){
var Player = this.players[this.activePlayer];
// Check to see if the position is vacant.
if (!this.tryMove(position)) {
return false;
}
Player.moves.push(position);
...