Menü schliessen
Created: February 4th 2021
Last updated: December 10th 2021
Categories: JavaScript Development
Author: Tim Fürer

JavaScript and jQuery: Make a Naughts and Crosses game

Tags:  Game,  Javascript,  jQuery
Donation Section: Background
Monero Badge: QR-Code
Monero Badge: Logo Icon Donate with Monero Badge: Logo Text
82uymVXLkvVbB4c4JpTd1tYm1yj1cKPKR2wqmw3XF8YXKTmY7JrTriP4pVwp2EJYBnCFdXhLq4zfFA6ic7VAWCFX5wfQbCC

In this post, I'm going to show you how to make the logic behind a simple Naughts and Crosses (or Tic Tac Toe) game in JavaScript in combination with some jQuery.

You should know how JavaScript and jQuery work in order to understand the logic.

First we're going to set up some variables used to track the games state.

We'll need:

  • Two Variables to track both players total amount of wins.
  • A Variable to determine which players turn it is.

And that's it. I set them up like so:

var P1wins = 0,
P2wins = 0,
Pturn = 1;

Next comes the main gameplay function. I'm going to split it into sections and explain what each one does.

 

$(document).ready(function() {
	$('.gamefield').on('click', function() {

This is the beginning of the function. We wait for the document to load and put down a listener. It listens for a click on any of the 9 fields you can place a mark on.

 

var $field = $(this).attr('id');

Now we cache the field that got clicked on in a local variable inside the function.

 

if (Pturn == 1) {
	$('#' + $field).text("x").attr('data-state', Pturn).prop("disabled", true);
}
else {
	$('#' + $field).text("o").attr('data-state', Pturn).prop("disabled", true);
}

Here we ask if it's Player 1's turn. If yes, mark the cached field with an "x", set it's "data-state" attribute to "1" and disable that field. If no, mark the field with an "o" instead of an "x" and set "data-state" to "2" instead of "1". "data-state" is an  attribute we created so we know which Player has put his mark on that field.

 

var A1 = $('#field_A1').attr('data-state'),
A2 = $('#field_A2').attr('data-state'),
A3 = $('#field_A3').attr('data-state'),
B1 = $('#field_B1').attr('data-state'),
B2 = $('#field_B2').attr('data-state'),
B3 = $('#field_B3').attr('data-state'),
C1 = $('#field_C1').attr('data-state'),
C2 = $('#field_C2').attr('data-state'),
C3 = $('#field_C3').attr('data-state');

We retrieve the "data-state" values of all the fields and store them in local variables called after their id's.

 

if ((A1 == 1 && A2 == 1 && A3 == 1) || (B1 == 1 && B2 == 1 && B3 == 1) || (C1 == 1 && C2 == 1 && C3 == 1) || (A1 == 1 && B1 == 1 && C1 == 1) || (A2 == 1 && B2 == 1 && C2 == 1) || (A3 == 1 && B3 == 1 && C3 == 1) || (A1 == 1 && B2 == 1 && C3 == 1) || (A3 == 1 && B2 == 1 && C1 == 1)) {
	//Player 1 won
	$('.gamefield').prop("disabled", true);
	P1wins++;
}
else if ((A1 == 2 && A2 == 2 && A3 == 2) || (B1 == 2 && B2 == 2 && B3 == 2) || (C1 == 2 && C2 == 2 && C3 == 2) || (A1 == 2 && B1 == 2 && C1 == 2) || (A2 == 2 && B2 == 2 && C2 == 2) || (A3 == 2 && B3 == 2 && C3 == 2) || (A1 == 2 && B2 == 2 && C3 == 2) || (A3 == 2 && B2 == 2 && C1 == 2)) {
	//Player 2 won
	$('.gamefield').prop("disabled", true);
	2wins++;
}
else if ((A1 + A2 + A3 + B1 + B2 + B3 + C1 + C2 + C3) == 13) {
	//Draw
	$('.gamefield').prop("disabled", true);
}

This if statement finds out, if the game has ended. We first compare the data of the field to find out if one of the Players has a line of three. If yes, disable all fields and increment the winning Players total win count. If neither has a line, we check if the game is in a draw. To find out if the game is in a draw, we add all the fields values together. In a game where both Players get to fill all fields, Player 1 will fill "5" fields and Player 2 will fill "4". Let's do some math: 5 * 1 + 4 * 2 = 13. Now we know that if all values together are equal to 13, the game must be in a draw situation, thus end the game.

 

if (Pturn == 1) {
	Pturn = 2;
}
else {
	Pturn = 1;
}

This block of code switches around which Players turn it is. If it's Player 1's turn, set it to Player 2's and vice versa.

 

		$('#P1Wins_label').text("P1 Wins: " + P1wins);
		$('#P2Wins_label').text("P2 Wins: " + P2wins);
	});
});

We update the two labels which say the total win count of both Players and end  the function.

 

Other than that, you might want to have a reset function. This is how I made mine:

function resetgame() {
	//Reset the game
	$('.gamefield').prop("disabled", false).text("").attr('data-state', "");
	Pturn = 1;
}

 

Congratulations, the logic is complete now. You may hook it up to a HTML and play some Naughts and Crosses.

Ready to use HTML

Here's a minifed HTML file with JS and all included for you to play and mess around with.

TicTacToe