Tic-Tac-Toe JavaScript game for beginners
Tags: javascript, tutorial, beginners
Published: 2024-04-17 14:29:38

**Tic-tac-toe** is a classic game played on a grid of **3x3 squares**. Two players take turns marking **X** or **O** in empty squares, aiming to get three of their marks in a row, either horizontally, vertically, or diagonally. It's a quick and strategic game often enjoyed by people of all ages.

Is a seemingly straightforward game that offers valuable problem-solving opportunities, particularly for beginners. This article provides a step-by-step explanation of how to create the game using an HTML Canvas element and JavaScript.

## The tools

- **JavaScript:** It is versatile, compatible with browsers, and supports both front-end and back-end development.

- **HTML:** It organizes and presents information on the web.

- **CSS:**  It separates content and design, facilitating maintenance and updates.

If you want to delve deeper into the subject, I'll leave my recommended readings below:

1. _"Eloquent JavaScript" by Marijn Haverbeke_
2. _"HTML and CSS: Design and Build Websites" by Jon Duckett_
3. _"CSS Secrets: Better Solutions to Everyday Web Design Problems" by Lea Verou_

## The Concepts

- **Class:** It's like a template for party invitations, defining the design and basic information. In JavaScript, a class is a blueprint for creating objects with properties and methods.

- **Object:** It's like a personalized party invitation representing a distinct object with unique details. In JavaScript, an object is an instance of a class, representing a specific entity with its own characteristics and actions.

- **Constructor:** It's how you prepare invitations, defining the basic structure and initial information. In JavaScript, the constructor is a special method within a class that initializes the object's properties for use.

## Inicial Setup
To start, create an HTML file with the basic structure, including a canvas element and a script tag. While you can separate the JavaScript code into a different file, for this tutorial, we'll keep everything in one file.

The canvas element acts as the background for the game's scene. If desired, you can adapt the game to work with other elements like a div tag, but that would require modifying the code provided in this tutorial.

![Figure 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bvg1nb0ghj0pcfvtgcou.png)
_Figure 1: This part demonstrates a basic HTML structure that includes a canvas element and a script tag._

## The Game’s Classes

Classes in JavaScript provide a way to organize code by creating objects with related properties and methods. In the Tic-Tac-Toe game, we have the TicTacToe class for managing the game instance and the Square class for representing each square on the game board. 

The TicTacToe class takes the ID of a canvas element as a parameter, which is used for rendering graphics. The Square class stores position and click information, and has methods for drawing and displaying symbols on the canvas.

Now, let's see how these concepts are applied in the game code.

![Figure 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1vwgbl50veoao9g4lis.png)
_Figure 2: This is how our basic structure for the game will look like._

When creating a instance, the canvas element ID is passed as a parameter, allowing multiple instances for different screen elements. The Square class represents a square on the game board, storing position, size, and click information. It provides methods to draw the square and display the player's symbol. 

The Square class generates square objects for a 3x3 grid. It has properties such as `x`, `y`, `width`, `height`, `ctx`, and `actor`. `x` and `y` determine the position, `width` and `height` define the dimensions, `ctx` references the canvas interface, and actor indicates the player's symbol ('**x**' or '**o**').

In JavaScript, a constructor is a special function that creates and initializes objects. It establishes the object's properties and methods. To call a constructor, we use the new keyword followed by the constructor function's name. The constructor function associates the new object with the this variable, allowing us to define the object's properties.

When instantiating a Square object, all properties except actor should be provided to the constructor. The actor property should be set to null within the constructor to ensure it exists on Square objects.

![Figure 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7its9dytuyxgffdnvzxf.png)
_Figure 3: Demonstrates the implementation of the Square class._

The class should include a `draw()` method responsible for rendering a square and displaying the symbol of the player who interacted with it. The `draw()` method utilizes the `strokeRect(x, y, width, height)` method, accessed through the `ctx` property, to draw the square on the canvas. Additionally, the `ctx` property provides access to the `strokeStyle` property, allowing for customization of the border color.

![Figure 4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5sh3ikjot8zx5rkgyz07.png)
_Figure 4: Demonstrates the implementation of the draw() method._

The draw method utilizes the `fillText(text, x, y)` method from the `ctx` property to inscribe the symbol of the player who interacted with the square. The text is precisely placed at the square's center by adding half of its width and height to its **x** and **y** positions. The `ctx` property also possesses a `textAlign` property that can be set to center, ensuring the text is perfectly aligned towards the center.

Next, we proceed with creating the TicTacToe class, which entails a constructor and three essential methods: `click(event)`, `checkForWinner()`, and `reset()`.

![Figure 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/whii903g8kiznivmtg0m.png)
_Figure 5: Demonstrates the implementation of a TicTacToe class._

The TicTacToe class constructor requires a canvas element id as input. The id is used to fetch the corresponding HTML canvas element using `getElementById(id)` and assigned to the `canvas` property. The `canvas` property is then used to obtain a `CanvasRenderingContext2D` instance assigned to the `ctx` property, serving as the drawing interface within the canvas.

![Figure 6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qc4l9owsl551q9urr0v.png)
_Figure 6: Demonstrates the implementation of a TicTacToe class constructor._

To instantiate the Square objects, a loop of 3x3 is performed, creating a Square object for each iteration and adding it to the `squares` property. The loop starts at **(x=0, y=0)** and continues until 9 squares are created.

The class requires three additional properties: `actors` (an array of two strings representing the players and their symbols '**x**' and '**o**'), `turn` (a number between 0-1 specifying the next player's turn), and `gameOver` (a boolean indicating if the game has ended).

In the constructor, the square objects `draw()` method is called, and a click event listener is added to the class `click()` method.

The click method is triggered when the user clicks on the canvas, and it retrieves the cursor's position from the event argument. The first section of the click method includes a guard clause that resets the game if the `gameOver` property is set to true, allowing the user to start a new game by clicking on the canvas.

![Figure 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n34mw2em2x24p0jsufnf.png)
_Figure 7: Demonstrates the implementation of a TicTacToe class click method._

The method iterates over Square objects, checking if the mouse position is within a square. If true, the actor is added to the square's `actor` property to indicate selection. The `turn` property allows the next player to choose.

The method then calls `checkForWinner()` to determine if there is a winner. It checks for three squares selected in a horizontal, vertical, or diagonal line.

Using an array of arrays, the method checks if three squares match any winning combinations. If true, `gameOver` is set to true, resetting the game on the next canvas click.

The method also draws a line and displays the winner's text representing the winning combination.

![Figure 8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7jl92ewzk4jydb6t64r.png)
_Figure 8: Displays the implementation of the checkForWinner() method in the TicTacToe class._

The final part of the method checks if all squares have a non-null actor, indicating that the game is a draw. This check is performed after determining if there is a winner to ensure that the game is not mistakenly considered a draw when the last empty square is selected and a winner is found.

The reset method is responsible for restoring the properties of a TicTacToe instance to their initial values, preparing for a new game.

Firstly, the method clears the canvas by using the `clearRect(x, y, width, height)` method of the `ctx` property.

After clearing the canvas, the actor property of each square is set to null, and the squares are redrawn on the canvas.

Finally, the method resets the turn to 0, allowing players to take turns again, and sets gameOver to false. This indicates that the `click()` method can assign players to squares and search for a new winner or a draw.

![Figure 9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30ygv83cdnlq5h9f5wvn.png)
_Figure 9: Illustrates how the reset() method is implemented within the TicTacToe class._

The game is now fully prepared and ready for players to engage. To begin, simply add a new line below the class definitions to instantiate a fresh instance of the class. This will initialize all the necessary game components and set the stage for an exciting gameplay experience. 

So go ahead, create a new instance and let the gaming fun begin!


![Figure 10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4j4x3f5zpbg66pf7j207.png)
_Figure 10: Demonstrates the process of initiating the Tic-tac-toe game._

---

You can find this code through the following link: [https://github.com/marcconci/educational-tic-tac-toe](https://github.com/marcconci/educational-tic-tac-toe). Additionally, you can also access my GitHub page through it.