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>
);
}
* {
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;
}
Top comments (0)