Tic-Tac-Toe with Javascript ES2015: Building the User Interface

Ali Alaa
4 min readOct 12, 2017

--

In this final part, we will build a simple user interface for the tic-tac-toe board. We will use classes and methods created in previous parts to simulate a game with a certain search depth and a starting player.

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

The HTML Markup

Our HTML markup will be quite simple, just a div with an id of board. This div will be populated with cells inside our JavaScript code. In addition to that, we will add a couple of drop-downs for the starting player and the depth and a new game button. Our index.html inside the root folder should finally look like this:

Preparing the webpack Entry Point

As mentioned in Part 1, webpack has a JS file called the entry point. This file is where we import all our different JS classes and styles so that webpack can compile the final code. In our case we set the entry point to be index.js file in the src directory. We will start by importing all the necessary files and we will also define some helper functions we will use in adding and removing classes.

In addition to that, we will define another helper function that takes the object returned from isTerminal() method and uses the direction and row/column number to add a certain class to the board. This class will help us animate a line for the winning cells using CSS. For instance, if the winner won at the first row horizontally, then the class will be H1. We finally set a small timeout before we add another class (full) which transitions the lines width from 0 to 100% so that we can have an animation.

The New Game Function

It’s time now to create a function that is responsible for creating a new game. The newGame function will take two arguments; the depth and the starting player (1 for human, 0 for computer). We will instantiate a new player with the given depth and a new empty board. After that we will clear all classes on the board div from previous games and populate it with the cells divs. We will then store the populated cells in an array so we can loop on them and attach click events. We will also initialize some variables that we will use later and those are the starting player, whether the human is maximizing or minimizing and the current player turn.

In the next step, we will check if the computer will start. If so, instead to running the performance costly recursive getBestMove function on an empty board, we will choose a random cell as long as it’s a corner or the centre since an edge is not a great place to start. We will assume the maximizing player is always X and the minimizing is O. Furthermore, we will add a class of x or o to the cell so we can use that in the CSS.

Finally, in our newGame function we will attach click events to each cell. While looping over our board state, we will attach a click event to the corresponding HTML cell that we stored inside html_cells. Inside the event handler, we will break out of the function if the cell clicked is occupied or the game is over or it’s not the human’s turn. Otherwise we will insert the symbol into the cell and check if this move is a terminal win and draw the winning line accordingly. If it’s not a terminal move, we will switch turn and use getBestMove to play the computer’s turn and do the same terminal checks.

Final Touches

We are now left with just initializing a new game when the page loads or when the user clicks the new game button. Notice that if the new game button is clicked, we will initialize the game with the arguments that the user has chosen:

We are now done with the JavaScript part. We now need to style the board with a little bit of css. I used sass here which we configured webpack to compile.

The final output should look like this:

--

--