DEV Community

Kartik Budhraja
Kartik Budhraja

Posted on

Building a Simple Tic-Tac-Toe Game with React

Tic-Tac-Toe, the classic paper-and-pencil game, has been a favorite pastime for generations. Thanks to modern web technologies and frameworks like React, creating a digital version of this timeless game has never been easier. In this article, we'll walk through the steps of building a simple Tic-Tac-Toe game using React, providing both the code and the styling necessary to bring the game to life.

Initial Project Setup

Create a new project using create-react-app

npx create-react-app your-component-app
Enter fullscreen mode Exit fullscreen mode

Step 1: Import React and useState Hook

import React, { useState } from "react";
import "./TicTacToe.css";

export default function TicTacToe() {
  // ... component code ...
}
Enter fullscreen mode Exit fullscreen mode

Here, we import React and the useState hook from React. The useState hook allows functional components to manage state.

Step 2: Initialize State Variables

const [turn, setTurn] = useState("X");
const [cells, setCells] = useState(Array(9).fill(""));
const [winner, setWinner] = useState();
Enter fullscreen mode Exit fullscreen mode

Three state variables are initialized using the useState hook:

  • **turn**: Represents the current player's turn (either "X" or "O").

  • **cells**: An array representing the Tic-Tac-Toe grid, initialized with empty strings.

  • **winner** : Keeps track of the winner of the game.

Step 3: Define Winning Combinations

const combos = {
  across: [[0, 1, 2], [3, 4, 5], [6, 7, 8]],
  down: [[0, 3, 6], [1, 4, 7], [2, 5, 8]],
  diagonal: [[0, 4, 8], [2, 4, 6]]
};
Enter fullscreen mode Exit fullscreen mode

An object combos is defined to store the winning combinations for Tic-Tac-Toe. It includes arrays for horizontal, vertical, and diagonal winning patterns.

Step 4: Handle Cell Clicks

const handleClick = (num) => {
  if (cells[num] !== "") return;

  let arr = [...cells];
  if (turn === "X") {
    arr[num] = "X";
    setTurn("O");
  } else {
    arr[num] = "O";
    setTurn("X");
  }
  checkWinner(arr);
  setCells(arr);
};
Enter fullscreen mode Exit fullscreen mode

The handleClick function is called when a cell is clicked. It updates the game state based on the current player's turn, checks for a winner, and updates the cells state variable.

Step 5: Check for a Winner

const checkWinner = (arr) => {
  for (let combo in combos) {
    combos[combo].forEach((pattern) => {
      if (arr[pattern[0]] === "" || arr[pattern[1]] === "" || arr[pattern[2]] === "") {
        // Do nothing if any cell in the combination is empty.
      } else if (arr[pattern[0]] === arr[pattern[1]] && arr[pattern[1]] === arr[pattern[2]]) {
        setWinner(arr[pattern[0]]);
      }
    });
  }
};
Enter fullscreen mode Exit fullscreen mode

The checkWinner function iterates through the combos object and checks if any winning combination is present on the game board. If a winner is found, the winner state variable is updated with the winning player's symbol.

Step 6: Render Cells and Handle Reset

const Cell = ({ num }) => {
  const cellValue = cells[num];
  const cellClassName = cellValue ? `cell cell-${cellValue}` : "cell";

  return (
    <td className={cellClassName} onClick={() => handleClick(num)}>
      {cellValue}
    </td>
  );
};

const handleReset = () => {
  setWinner();
  setCells(Array(9).fill(""));
};
Enter fullscreen mode Exit fullscreen mode

The Cell component renders individual cells of the Tic-Tac-Toe grid. Each cell's click event is handled by the handleClick function. The handleReset function resets the game by clearing the winner state variable and resetting the cells state variable with empty values.

Step 7: Styling with CSS

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

table td {
  border: 1px solid grey;
  width: 100px;
  height: 100px;
}

.cell {
  width: 100px;
  height: 100px;
  text-align: center;
  font-size: 36px;
  cursor: pointer;
}

.cell-X {
  background-color: #e93737d7;
  color: #ffffff;
}

.cell-O {
  background-color: #2deb2dc0;
  color: #ffffff;
}

.winner {
  margin-top: 10px;
  margin-bottom: 10px;
  font-size: 24px;
  display: none;
}

.winner.show {
  display: block;
}

.reset-button {
  margin-top: 20px;
  padding: 10px 20px;
  font-size: 18px;
  border-radius: 5px;
  background-color: #007bff;
  color: #ffffff;
  border: none;
  cursor: pointer;
}

.reset-button:hover {
  background-color: #0056b3;
}
Enter fullscreen mode Exit fullscreen mode

CSS styles are applied to the components to create a visually appealing interface. Classes like cell, cell-X, cell-O, winner, and reset-button are used to style the game cells, winner display, and the reset button.

The link of the complete code is - https://codesandbox.io/s/tic-tac-toe-z87vh8?file=/src/App.js


Conclusion

By following these steps, the Tic-Tac-Toe game is built using React, combining state management, event handling, and CSS styling to create an interactive and visually appealing user experience.

Follow Me on Social Media!

If you found this article helpful, feel free to connect with me on LinkedIn and Twitter for more programming tips and tutorials. Let's learn and grow together!

LinkedIn: https://www.linkedin.com/in/kartikbudhraja/

Twitter: https://twitter.com/K_a_r_t_i_k_08

Top comments (0)