5 September 2020

How to make a tic-tac-toe game using Javascript


In this tutorial, you'll be learning on how to make your own tic-tac-toe game using Javascript. In a traditional tic-tac-toe game, there will be two-player that in turn try to get 3 consecutive cells with their assigned icon (usually a circle, O and times, X) in a 3x3 grid. This is a simplified version of my tic-tac-toe game, where there you're up against a bot created with the minimax algorithm. While in this version, you'll need to ask some of your friends or family members to play with you or you could just play it alone. You can find my tic-tac-toe game through this Github link. All the code for this tutorial could be found here and if you want to play the game, you could visit this Github page. Now let's get started with the things that our game will need. 


Our game will need a few components for it to work:

  • drawing the grid for us to play
  • initialize needed variable & resetting variable values
  • detecting the click events in each grid cell
  • adding player icon into one valid cell on their turn
  • changing turns
  • check for empty cells in the grid
  • check if there's a winner for the game after each turn
  • Ending a game if a winner is found
  • Lastly, restart the game

Index for this tutorial:



Setting up the grid with HTML.


To get started with the project, we'll first need to create or grid using HTML. 


Code for the grid cells.


We'll also need a way to restart the game as well as ending a game. That's why we need a restart button that would clear and reset everything and a menu for displaying the winner of the game.


The restart button and the game-over menu.



Styling the elements


At first, the page will not display anything. Let's add some style to the table. You can also change the background colour for the game if you want to. There's something that I would like to style the table:


  • Height and width of the game board
  • Player icon size
  • Cursor style when hovering to the grid cells
  • Making the cell's border collapsed.
  • Making the restart button to the centre and some animation when hovered
  • Positioning the game-over menu to the centre as well as fixing the height and width
  • and many more...





The CSS file code for the whole game.



The global variable, DOM elements and constants initialisation.


Now, you'll notice there's a beautifully placed 3x3 grid at the centre of the page. While the game-over menu and restart button are not displayed (display: none). Next, let's declare some global variable to hold some of our data, some DOM elements as well as some constant variable. 


Declaring some global variable and constant as well as initialising some DOM element.



The "turn" variable is used to store which player should be playing for this "turn", and the "board" variable is used to store the gameboard data. The "currentWinner" variable is used to store the current round winner (it could be player_1, player_2, draw or null). While some of the other variables are to store the DOM elements. The constant "TEAM_ICON" is used to store the icon for the two players, and the TEAM_NAME is used to store the two player's name. While the SOLUTIONS 2D-array constant is used to store all the possible solutions for the tic-tac-toe game.



Initiating the game


After that, we'll need a function to initialise global variables and setting up the gameboard to detect if any of the cells have been clicked. 


The function that handles the initialisation of the game and resetting the game.



Handling cells when they're clicked


Then if a player clicks in any of the cells, the cellsClicked will be triggered, and then it'll try to insert the current player icon into the cell by calling a function called addArea. If the cell is valid (its value in the "board" variable is still null) the system can then insert the icon of the current player into the cell (as well as updating the "board" variable value for that index). After we insert the icon, we then need to check if there's a winner after that round by calling a function called checkWinner. If there's a winner for the game, the game-over menu is triggered with the match result passed to the gameOver function. After that, no matter if there's a winner for the current round or not, we need to change the player's turn. But since the turn is changed after the gameOver function call, we don't need to worry about the turn messed up during the displaying of the game result.


The function cellsClicked to handle the event when one of the cells got clicked.



Adding icon (base on player's turn) into the cell


In the addArea function, we'll first check if there's currently a winner for the current round. If there's a winner for the current game round,  nothing will happen. But if currently there's still no winner for the game (the game has not ended), then we can proceed with inserting the player icon into the cells and the array that store the grid data. But before inserting the value, you'll also need to check if the cells are valid or not (not occupying by another player's icon). If the cells indeed are valid, our game will then insert the value into the table grid cell and in the array that store the value of the cell. If the cell is not valid, then the system will not do anything and wait for the next event to happens.


The addArea function which is used to insert an icon into cells and the array (when conditions meet).



Checking for winner


In the checkWinner function, all it does is checks if the current player has won the game after his turn. Here you can see I used the reduce method to find the index of the element inside the parameter variable "tempBoard" that has the icon for the current turn's player in String form. Then by using the String that has the index of the element that has the same icon as the current turn's player,  we check if there are the indexes that match one of the solutions in the "SOLUTIONS" constant. If a match is found, then the team name will be returned to its caller which is the cellsClicked, and it'll then trigger the gameOver function. But if there's no match found, the code will continue to the next section where we check if there's any more empty space in the grid. If there's no empty space left, then that means it's a draw. If it's a draw, we return the string "Draw" to the cellsClicked function. If both of the checks do not meet, it means that there's no winner yet, so we'll need to return null back to cellsClicked so that it won't trigger the gameOver function.


Checks if there's a winner after each turn.



Checking if there's still empty cell available


While to check if there are any more empty cells in the grid, we will call a function called getEmptyCellsSize. In this function, we can simply filter the board array to see if any of the cells are still holding a null value. 


Checking if there are still empty cells left in the board.



Displaying the reset button and the game-over menu


Now when a player has won the game, the game will then trigger the gameOver function from the cellsClicked function. In the gameOver function, all it does is show the reset button and the game over the menu as well as displaying the current round winner (Player_1, Player_2, or draw).


Showing the game-over menu and reset button.



Hiding the game-over menu


Lastly, we'll also need a function to hide back the game over the menu. 


Hide the game-over menu after the user has clicked the close button.


To reset the game, we can simply call the gameInit function again since it'll reset everything in our game.


That's about all of the things that you need to make a simple tic-tac-toe game. I hope you've now learned how to make your own tic-tac-toe game. If you're still confused with the code, please re-read the article. If you really need any help, feel free to post a comment in the comment section below. I'll do my best to answer your question. Also if you skipped the introduction, the code for this project is available here.


Beside commenting question, if you have any suggestion or critics also feel free to post a comment as well. Also please share this article with others that might find it helpful. Thanks for reading and see you until next time, cheers.

No comments:

Post a Comment