DEV Community

ZeeshanAli-0704
ZeeshanAli-0704

Posted on

React Coding Challenge : TIC-TAC-TOE

import { useState } from "react";
import "./styles.css";

function Square({ value, onClick }) {
  return (
    <button className="square" onClick={onClick} disabled={value !== null}>
      {value}
    </button>
  );
}

function Board({ squares, onSquareClick }) {
  return (
    <div className="board">
      {squares.map((sq, i) => (
        <Square key={i} value={sq} onClick={() => onSquareClick(i)} />
      ))}
    </div>
  );
}

function calculateWinner(s) {
  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 (const [a, b, c] of lines) {
    if (s[a] && s[b] && s[c]) {
      console.log(s[a], s[b], s[c]);
      if (s[a] == s[b] && s[b] == s[c]) return s[a];
    }
  }
  return null;
}

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

  const winner = calculateWinner(squares);
  const isDraw = !winner && squares.every((sq) => sq !== null);

  const status = winner
    ? `Winner: ${winner}`
    : isDraw
    ? "Draw!"
    : `Next player: ${xIsNext ? "X" : "O"}`;

  function handleSquareClick(i) {
    if (squares[i] || winner) return;
    const next = squares.slice();
    next[i] = xIsNext ? "X" : "O";
    setSquares(next);
    setXIsNext((prev) => !prev);
  }

  function reset() {
    setSquares(Array(9).fill(null));
    setXIsNext(true);
  }

  return (
    <div className="App">
      <h1>Tic-Tac-Toe</h1>
      <div className="status">{status}</div>
      <Board squares={squares} onSquareClick={handleSquareClick} />
      <button className="reset" onClick={reset}>
        Reset
      </button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode
* {
  box-sizing: border-box;
  font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}

.App {
  display: grid;
  place-items: center;
  min-height: 100vh;
  gap: 16px;
  background: #0f172a;
  color: #e2e8f0;
}

h1 {
  margin: 0;
}

.status {
  font-size: 1.25rem;
  margin-bottom: 8px;
}

.board {
  display: grid;
  grid-template-columns: repeat(3, 90px);
  grid-template-rows: repeat(3, 90px);
  gap: 8px;
}

.square {
  width: 90px;
  height: 90px;
  font-size: 2rem;
  font-weight: 700;
  border: 2px solid #334155;
  border-radius: 12px;
  color: #e2e8f0;
  background: #1e293b;
  cursor: pointer;
  transition: transform 0.05s ease, background 0.2s ease;
}

.square:hover:enabled {
  background: #233145;
}

.square:disabled {
  opacity: 0.9;
  cursor: default;
}

.reset {
  margin-top: 12px;
  padding: 8px 14px;
  font-size: 1rem;
  border-radius: 10px;
  border: 1px solid #334155;
  background: #0b1220;
  color: #e2e8f0;
  cursor: pointer;
}

.reset:hover {
  background: #111a2d;
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)