How to build a Tic-tac-toe Game in Reactjs

ยท

6 min read

Understanding the game concept

Tic-tac-toe game is a two-player game represented with "X" player one and "0" player two. The game board has 3 by 3 grid layout. The winner of the game plays repeated values of (X or 0) in each square vertically, horizontally or diagonally.

Using a pen and paper, this game is easily designed and played. However, we are making a web version of it. View the demo below and let's code this game!

Demo

React setup

To start the game setup. You would need to install NodeJS on your local machine. Once you've installed Node, you need to install create-react-app to start a React environment. The command below both installs create-react-app and also sets up the Tic-tac-toe-app folder and all necessary files to start a new React project.

npx create-react-app Tic-tac-toe-app

This code syntax does not make sense to you right, let me break it down

npx is a command that controls package handling node pack manager registry.
create-react-app helps you set up pipeline packages for the applications with the latest ES6 features.

Tic-tac-toe-app is the project folder name. This folder houses all packages and code files needed for the project.

Check the output by writing this command.

npm run start

This runs a local server in your machine, and generate a link for output view, with a port number attached http://localhost:3000

Navigating through the folders and preparing the file

cd Tic-tac-toe-app
cd src
# on Windows:
del *

cd command is to move into the tic-tac-toe-app folder.

We deleted all * files in the src (source) folder.

Since we deleted all files, let's create new files in the src folder

  1. Index.js file for script code in react js
  2. Index.css for styling code

Then navigate to the script file.
Import react library from react module in the package installed, same as the react virtual dom and the external styling sheet file in the source folder.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

Game code and lessons

React is structured with components, a component stores reusable pieces of code. Greatly, components interact with each other in a specific pattern, parent to child, through which resource sharing is possible.

Two types of react components will be discussed

  1. Functional-based component
  2. Class-based component

Functional-based component

A simple way to write react component is using the functional-based component because it is simply writing javascript functions. It can be used when a component has no interactivity with other components.

Class-based component

It is quite similar to other functional component but it allows complex features in react to be implemented example life cycle hooks, render method and passing of props which is the core of interaction among components.

Square component

function Square(props) {
   return (
      <div>
         <button className="square" onClick={props.onClick}>
          {props.value}
         </button>  
      </div> 
   );
 }

The function above is a Functional-based component and it does the following:

  • Props which means property is passed as a parameter.
  • The props is a JavaScript object.
  • The function returns a div, and a button embedded.
  • The button reacts to an event listener (onClick) attached to props
  • The button's value is passed in as a prop - props.value.

Board component

class Board extends React.Component{

   constructor(props){
      super(props);
      this.state ={
         squares: Array(9).fill(null),
         xIsNext: true,
      }
   }

   handleClick(i) {
      const squares = this.state.squares.slice();

      if (calculateWinner(squares) || squares[i]) {
         return;
       }

      squares[i]= this.state.xIsNext ? 'X' : 'O'

      this.setState({
         squares: squares,
         xIsNext: !this.state.xIsNext,
      });
    }

   renderSquare(i){
      return <Square 
      value={this.state.squares[i]}
      onClick={()=> this.handleClick(i)}
      />;
   }

   render() {
      const gameName = "TIC TAC TOE"
      const winner = calculateWinner(this.state.squares);
      let status;
      if (winner) {
         status = 'Winner: ' + winner;
      } else {
         status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
      }

   return (
      <div className="board">
          <div className="gameName">{gameName}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
        <div className="status">{status}</div>
        <div className="btn">
            <App/> 
        </div>
      </div>
    );
   }
}

This class component named Square(function name).
Has 5 categories of actions

  • The constructor category, calls a superclass constructor, initializing the state.
    Defining squares and assigning them to 9 empty array spaces in the memory.
    Defining xIsNext and assigning to true.
  • The handleclick method, controls the value for each square and on next click what value is to be assigned (X or 0), also with each click the winner can be calculated.
  • Render square output square value on click. A child component square in Board component
  • Render method for the board control the logic for the game-winner and the next player.
  • Return for board output the title of the game, the grid, the status of the game, and a button for refreshing the whole game.

Game component

class Game extends React.Component {
  render() {
    return (
      <div className="game">
        <div className="game-board">
          <Board />
        </div>
      </div>
    )
  }
}
  • The above component is a class component.
  • The render method displays the content as the main output on the localhost.
  • It calls a child component board in it.
  • The className is a styling selector in CSS for styling.

Creating the resulting logic and refresh functionality

Button component

function btnApp() {
  function refreshPage() {
    window.location.reload(false)
  }

  return (
    <div>
      <button className="refreshBtn" onClick={refreshPage}>
        Refresh{" "}
      </button>
    </div>
  )
}
  • The btnApp function is a react function based component.
  • This function controls the refresh button
  • The function refreshPage uses the window.location.reload method to provide means to reload the page at current URL.
  • The return display the HTML output for the button, and styling on the class name refreshBtn and an add event listener (onclick) calls the refreshPage function to refresh the game when clicked. -

The winner game logic

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
  ]
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i]
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a]
    }
  }
  return null
}

A 3 by 3 grid pattern is designed for the board right, each square is numbered between (0-8).

Remember, how a player wins the game. A player wins if a value fills in the squares diagonally, horizontally or vertically.

With the number grid(0-8). let's generate an instance of output for X or Y value

Horizontally: (0,1,2) (3,4,5)(6,7,8)

Vertically: (0,3,6)(0,4,7)(2,5,8)

Diagonally: (0,4,8)(2,4,6)

This square position on the board determines the output prediction of the game.

The function calculateWinner run all the possible output, return the result. The generate output is assigned to a nested array[[a,b,c]].

Looping to the array, to get an exact result of the game.

A condition is created. Moves by player
square[a] = X

square[a]== square[b] it means player played X in square b

square[a]== square[C] and the same player played X in square C

It means three square positions are filled with X, so player x is the winner.

React dom call

ReactDOM.render(<Game />, document.getElementById("root"))

Conclusion

Style any of the className with the desired styling and achieve the same output.

A simple guide to developing a tic-tac-toe game.

Play Tic-tac-toe Game here:

Kindly use the comment section, if you have questions about this article.

Want to follow me on Twitter? @Bolarinwaajayi1

References

React documentation tutorial

Github link to the full code file

npx in details

Did you find this article valuable?

Support BeeC00des by becoming a sponsor. Any amount is appreciated!

ย