A little while ago I got this idea in my head to make games in jQuery and so to see how easy or hard it would be I wanted to first make a simple Tic-Tac-Toe game, and then go from there. And as it turns out it is VERY simple :-) lol. I am at work on an adventure game, but am getting really caught up in the graphics lol, so until that is done i thought i would share my Tic-Tac-Toe game.
I first concentrated on the basics of the game, what would it require? I needed to map out the cycle of the game and all possible outcomes. I wanted to just focus on the game play, and not the starting or stopping of it, or the players logic.
player clicks space -> need to check if space is already marked -> if no mark : mark for player -- else : do nothing or alert to pick different space
if player marks space -> need to validate board to check for winner -> if winner : alert winner/game ends -- if no more space : alert tie/game ends -- else next player turn
if End Game -> need to reset board
Since it was looking like the whole game would be progressed by each players 'onClick()' of the game board, so i made a function called playerMove() which would take the current element (the space that was clicked) and used that as the point of reference. When the player clicked on a space, if the space has not been marked, mark it for that player and validate the board.
<table>
<tbody>
<tr>
</table>
<tbody>
<tr>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
</tr>
<tr>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
</tr>
<tr>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
</tr>
</tbody><td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
</tr>
<tr>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
</tr>
<tr>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
<td onclick="playerMove(this);"></td>
</tr>
</table>
function playerMove(t){
if(!($(t).hasClass(pClassOne())) && !($(t).hasClass(pClassTwo())) && $('#mainWrap').hasClass('started')){
$(t).addClass(pClass());
if(validateBoard()){
$('#mainWrap').removeClass('started');
$('#GameButton').removeClass('hideMe');
}else{
nextTurn();
}
}
}
if(!($(t).hasClass(pClassOne())) && !($(t).hasClass(pClassTwo())) && $('#mainWrap').hasClass('started')){
$(t).addClass(pClass());
if(validateBoard()){
$('#mainWrap').removeClass('started');
$('#GameButton').removeClass('hideMe');
}else{
nextTurn();
}
}
}
The validation was simple as well, there is only 8 possible combinations for a win in tic-tac-toe so i made one method that checks them all, of course this could be broken up to smaller methods but thats up to you. But if the board validates i pass the winning indexes to the showWinner() function so that it can highlight those spaces and show how the player won.
function checkIfFull(){
var booleanCheck = true;
$('table').find('td').each(function(){
if(!$(this).hasClass(pClassOne()) && !$(this).hasClass(pClassTwo())){
booleanCheck = false;
}
});
if(booleanCheck){
return true;
}else{
return false;
}
}
function validateBoard(){
if($('td:eq(0)').hasClass(pClass()) && $('td:eq(1)').hasClass(pClass()) && $('td:eq(2)').hasClass(pClass())){
showWinner(0,1,2);
return true;
}else if($('td:eq(3)').hasClass(pClass()) && $('td:eq(4)').hasClass(pClass()) && $('td:eq(5)').hasClass(pClass())){
showWinner(3,4,5);
return true;
}else if($('td:eq(6)').hasClass(pClass()) && $('td:eq(7)').hasClass(pClass()) && $('td:eq(8)').hasClass(pClass())){
showWinner(6,7,8);
return true;
}else if($('td:eq(0)').hasClass(pClass()) && $('td:eq(3)').hasClass(pClass()) && $('td:eq(6)').hasClass(pClass())){
showWinner(0,3,6);
return true;
}else if($('td:eq(1)').hasClass(pClass()) && $('td:eq(4)').hasClass(pClass()) && $('td:eq(7)').hasClass(pClass())){
showWinner(1,4,7);
return true;
}else if($('td:eq(2)').hasClass(pClass()) && $('td:eq(5)').hasClass(pClass()) && $('td:eq(8)').hasClass(pClass())){
showWinner(2,5,8);
return true;
}else if($('td:eq(0)').hasClass(pClass()) && $('td:eq(4)').hasClass(pClass()) && $('td:eq(8)').hasClass(pClass())){
showWinner(0,4,8);
return true;
}else if($('td:eq(2)').hasClass(pClass()) && $('td:eq(4)').hasClass(pClass()) && $('td:eq(6)').hasClass(pClass())){
showWinner(2,4,6);
return true;
}else{
if(checkIfFull()){
showTie();
return true;
}else{
return false;
}
}
}
if($('td:eq(0)').hasClass(pClass()) && $('td:eq(1)').hasClass(pClass()) && $('td:eq(2)').hasClass(pClass())){
showWinner(0,1,2);
return true;
}else if($('td:eq(3)').hasClass(pClass()) && $('td:eq(4)').hasClass(pClass()) && $('td:eq(5)').hasClass(pClass())){
showWinner(3,4,5);
return true;
}else if($('td:eq(6)').hasClass(pClass()) && $('td:eq(7)').hasClass(pClass()) && $('td:eq(8)').hasClass(pClass())){
showWinner(6,7,8);
return true;
}else if($('td:eq(0)').hasClass(pClass()) && $('td:eq(3)').hasClass(pClass()) && $('td:eq(6)').hasClass(pClass())){
showWinner(0,3,6);
return true;
}else if($('td:eq(1)').hasClass(pClass()) && $('td:eq(4)').hasClass(pClass()) && $('td:eq(7)').hasClass(pClass())){
showWinner(1,4,7);
return true;
}else if($('td:eq(2)').hasClass(pClass()) && $('td:eq(5)').hasClass(pClass()) && $('td:eq(8)').hasClass(pClass())){
showWinner(2,5,8);
return true;
}else if($('td:eq(0)').hasClass(pClass()) && $('td:eq(4)').hasClass(pClass()) && $('td:eq(8)').hasClass(pClass())){
showWinner(0,4,8);
return true;
}else if($('td:eq(2)').hasClass(pClass()) && $('td:eq(4)').hasClass(pClass()) && $('td:eq(6)').hasClass(pClass())){
showWinner(2,4,6);
return true;
}else{
if(checkIfFull()){
showTie();
return true;
}else{
return false;
}
}
}
function showWinner(numOne,numTwo,numThree){
$('td:eq('+numOne+'),td:eq('+ numTwo +'),td:eq('+ numThree +')').addClass('flash');
$('#messageBox').text(player()+ ' WINS!!');
}
$('td:eq('+numOne+'),td:eq('+ numTwo +'),td:eq('+ numThree +')').addClass('flash');
$('#messageBox').text(player()+ ' WINS!!');
}
Once I got the main game going, it was time to add the players, and the logic around them. To start, i wanted the players to have the ability to create custom names, but with that I would also need to ensure that the names where not the same otherwise the validation would fail. I would also add a start and end buttons, and if the game is left untouched i wanted it to reset itself, so i added player cookies to track session and current player.
function startGame(){
if((pOne() != null && pOne() != '')&&(pTwo() != null && pTwo() != '')){
if(pOne() != pTwo()){
$('.startWrap').addClass('hideMe');
$('#GameButton').addClass('hideMe').find('.btn').attr('onCLick','endGame();').find('#buttonText').text('End');
$('#mainWrap').addClass('started');
$.cookie('player', pOne());
$.cookie(pOne(), 'one');
$.cookie(pTwo(), 'two');
$('#messageBox').text(player()+' go!');
}else{
$('#messageBox').text('Each player must have a unique name');
}
}else{
$('#messageBox').text('We need two players to start the game... DUH');
}
}
if((pOne() != null && pOne() != '')&&(pTwo() != null && pTwo() != '')){
if(pOne() != pTwo()){
$('.startWrap').addClass('hideMe');
$('#GameButton').addClass('hideMe').find('.btn').attr('onCLick','endGame();').find('#buttonText').text('End');
$('#mainWrap').addClass('started');
$.cookie('player', pOne());
$.cookie(pOne(), 'one');
$.cookie(pTwo(), 'two');
$('#messageBox').text(player()+' go!');
}else{
$('#messageBox').text('Each player must have a unique name');
}
}else{
$('#messageBox').text('We need two players to start the game... DUH');
}
}
function nextTurn(){
if(player() == pOne()){
$.cookie('player', pTwo());
}else{
$.cookie('player', pOne());
}
$('#messageBox').text(player()+ ' go!');
}
if(player() == pOne()){
$.cookie('player', pTwo());
}else{
$.cookie('player', pOne());
}
$('#messageBox').text(player()+ ' go!');
}
function endGame(){
$('td').each(function(){
$(this).removeClass(pClassOne()).removeClass(pClassTwo()).removeClass('flash');
});
$('input:text').val('');
$('#GameButton').removeClass('hideMe').find('.btn').attr('onCLick','endGame();').find('#buttonText').text('End');
$('.startWrap').removeClass('hideMe');
$('#messageBox').text('');
}
$('td').each(function(){
$(this).removeClass(pClassOne()).removeClass(pClassTwo()).removeClass('flash');
});
$('input:text').val('');
$('#GameButton').removeClass('hideMe').find('.btn').attr('onCLick','endGame();').find('#buttonText').text('End');
$('.startWrap').removeClass('hideMe');
$('#messageBox').text('');
}
To see it in action or to see the complete jQuery file, just download the files below and then just launch the page and play!
for a complete zip of all the files:http://ge.tt/3aXFzJ5
Questions?