AniUI Academy
medium+210 XP

Build tic-tac-toe

Build a 3x3 tic-tac-toe board. Players alternate, X first.

After each move, check whether the player who just moved has three in a row — any row, column, or diagonal — and if so, declare them the winner and stop accepting moves.

Requirements

  • Nine cells, `data-testid="cell-0"` through `data-testid="cell-8"` (row-major: 0,1,2 is the top row).
  • A `data-testid="status"` element mentions whose turn it is (containing "X" or "O") before the game ends.
  • Clicking an empty cell places the current player's mark and passes the turn.
  • Clicking an already-filled cell does nothing — no mark change, no turn change.
  • Once a player completes a line, the status becomes exactly "X wins!" or "O wins!", and no further clicks place a mark anywhere on the board.

Your workspace

import { useState } from "react";

export default function App() {
  const [cells, setCells] = useState(Array(9).fill(null));
  const [xIsNext, setXIsNext] = useState(true);

  // TODO: after each move, check whether the player who just moved has
  // three in a row (any row, column or diagonal) and if so, lock the
  // board and show "X wins!" / "O wins!" via data-testid="status".

  function handleClick(index) {
    if (cells[index]) return;
    const next = [...cells];
    next[index] = xIsNext ? "X" : "O";
    setCells(next);
    setXIsNext(!xIsNext);
  }

  return (
    <div style={{ fontFamily: "sans-serif", padding: 16 }}>
      <p data-testid="status">{xIsNext ? "X" : "O"}'s turn</p>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 48px)", gap: 4 }}>
        {cells.map((cell, index) => (
          <button
            key={index}
            data-testid={`cell-${index}`}
            onClick={() => handleClick(index)}
            style={{ height: 48, fontSize: 24 }}
          >
            {cell}
          </button>
        ))}
      </div>
    </div>
  );
}

Ready to check it?

5 tests run against your rendered component, right here in your browser. Sign in to claim the XP when you pass.

Stuck? The react course covers the ideas this problem is built on.