Tic-Tac-Toe with Javascript ES2015: Building the Tic-Tac-Toe Board

Ali Alaa
4 min readOct 12, 2017

--

In this part, we will start building the logic behind the Tic-Tac-Toe board. We will learn how to create a Javascript class that represents the board. This class will hold the current state of the board in addition to methods that get some info about the board.

View a demo or visit the project’s github page.

The Board Structure

The only argument for our board class will be an array of length 9. This array will hold the state of the board. The state refers to the current configuration of the board or the positions of X’s and O’s. Each index in the array will refer to a certain cell in the board. If we define the state as [‘x’,”,’o’,’o’,”,”,’x’,”,”] it will map to this:

Let’s create a new folder inside our src directory and call it classes. Inside classes folder, create a new file called Board.js. In this file we will define our board class:

Remember our entry point where webpack is going to look at is src/index.js. So in this file we will import all of our classes and any other imports. To import our board class, we use an import statement with a relative path:

Printing a Formatted Board

The first method we are going to create is not necessary for the game’s logic; however, it’s going to help us visualize the board in the browser’s console as we develop. This method is going to be called printFormattedBoard:

This methods iterates the state array using forEach, and prints each cell content + a vertical line next to it. Every 3 cells, we print 3 horizontal lines using \u2015 unicode charachter in a new line. We also make sure that we don’t print the 3 horizontal lines after the last 3 cells. To test this, in index.js type:

Checking the Board’s Status

The next 3 methods will be used to check the current status of the board. We need to check for 3 things; is the board empty? is the board full? and is the board in a terminal state? Terminal state is where either one of the players won or the game is a draw.

To check if the board is empty, we will use ES2015 array helper every.

The every helper will return true if every iteration returned true; i.e. if cell == '' is true for all cells. cell == '' can be refactored to !cell since an empty string is a false statement. Also, we can use arrow functions instead of normal functions. Thus, isEmpty and isFull can be as so:

The last thing we need to check is the terminal state board. This is method is going to be long but very systematic and repetitive. First we will use isEmpty and return false if the board is empty. Then using if conditions we will check for horizontal, vertical and diagonal wins. If non of the conditions is true, we will check if the board is full. If the board is full and none of the winning conditions is met, then it must be a draw.

In case a win or a draw happen, an object will be returned containing the winner, the direction of winning and the row/column number where he won. This object will be very useful when we build our UI for the game.

Let’s test this in our index.js:

Inserting a Symbol and Getting Moves

Insert method will simply insert a symbol at a certain cell. The method will receive the symbol and the position. We will check first if the cell is occupied or does not exist. Otherwise we will simply update the state array:

Finally, we will create a method that returns an array containing all available moves. This will simply iterate the state array and pushes to the returned array the index of the cell only if it’s empty:

Let’s now test these 2 methods. In index.js type:

Here is how the final board class should look:

In the next part, we will start creating a Player class. This class will use an algorithm to get the best possible move. We will also add different difficulty levels to this player.

--

--