47 - Tic-Tac-Toe Game

Description

Create a Tic-Tac-Toe game that displays a 3x3 grid of buttons representing squares, allows players to take turns clicking squares to mark them with X or O, detects horizontal, vertical, or diagonal wins for either player, and announces the winner or draw when the game ends.

Algorithm

  1. Render a 3x3 grid of buttons

  2. Initialize game state (player turn, board state)

  3. Handle button clicks (mark square with X or O, update game state)

  4. Check for wins (horizontal, vertical, diagonal) after each move

  5. Announce winner or draw when game ends

Classes

  • TicTacToe: The main game component

  • Square: A single square in the grid

  • GameBoard: The 3x3 grid of squares

Code

TicTacToe.js

import React, { useState } from 'react';
import GameBoard from './GameBoard';

const TicTacToe = () => {
  const [playerTurn, setPlayerTurn] = useState('X');
  const [boardState, setBoardState] = useState([
    ['', '', ''],
    ['', '', ''],
    ['', '', ''],
  ]);
  const [winner, setWinner] = useState(null);

  const handleClick = (row, col) => {
    const newBoardState = [...boardState];
    newBoardState[row][col] = playerTurn;
    setBoardState(newBoardState);
    setPlayerTurn(playerTurn === 'X' ? 'O' : 'X');
    checkForWin();
  };

  const checkForWin = () => {
    const winConditions = [
      [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 < winConditions.length; i++) {
      const condition = winConditions[i];
      if (
        boardState[condition[0]] === playerTurn &&
        boardState[condition[1]] === playerTurn &&
        boardState[condition[2]] === playerTurn
      ) {
        setWinner(playerTurn);
        return;
      }
    }
    if (!boardState.includes('')) {
      setWinner('draw');
    }
  };

  return (
    <div>
      <GameBoard
        boardState={boardState}
        handleClick={handleClick}
      />
      {winner && <p>Winner: {winner}</p>}
    </div>
  );
};

export default TicTacToe;

GameBoard.js

import React from 'react';
import Square from './Square';

const GameBoard = ({ boardState, handleClick }) => {
  return (
    <div>
      {boardState.map((row, rowIndex) => (
        <div key={rowIndex}>
          {row.map((square, colIndex) => (
            <Square
              key={colIndex}
              value={square}
              handleClick={() => handleClick(rowIndex, colIndex)}
            />
          ))}
        </div>
      ))}
    </div>
  );
};

export default GameBoard;

Square.js

import React from 'react';

const Square = ({ value, handleClick }) => {
  return (
    <button onClick={handleClick}>
      {value}
    </button>
  );
};

export default Square;

Explanation

The TicTacToe component renders a 3x3 grid of Square components, which represent the game board. The GameBoard component handles the logic for rendering the squares and detecting wins. The Square component renders a single square with an X or O, depending on the game state. The game state is managed using the useState hook, which keeps track of the current player turn, board state, and winner. The handleClick function updates the game state when a square is clicked, and the checkForWin function checks for wins after each move.

Possible Future Enhancements

  • Game history: Keep a history of past games and allow users to review them.

  • Multiplayer: Add support for multiplayer games, where two users can play against each other.

  • Customizable game board: Allow users to customize the game board size and design.

  • Animations and sound effects: Add animations and sound effects to enhance the game experience.

Last updated