Mercurial
comparison react_games/src/Tictactoe/example.tsx @ 37:fb9bcd3145cb
[ReactGames] Few games I made using react just to practice few things.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 01 Dec 2025 20:22:47 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 36:84672efec192 | 37:fb9bcd3145cb |
|---|---|
| 1 import { useState } from 'react'; | |
| 2 | |
| 3 function Square({ value, onSquareClick }) { | |
| 4 return ( | |
| 5 <button className="square" onClick={onSquareClick}> | |
| 6 {value} | |
| 7 </button> | |
| 8 ); | |
| 9 } | |
| 10 | |
| 11 function Board({ xIsNext, squares, onPlay }) { | |
| 12 function handleClick(i) { | |
| 13 if (calculateWinner(squares) || squares[i]) { | |
| 14 return; | |
| 15 } | |
| 16 const nextSquares = squares.slice(); | |
| 17 if (xIsNext) { | |
| 18 nextSquares[i] = 'X'; | |
| 19 } else { | |
| 20 nextSquares[i] = 'O'; | |
| 21 } | |
| 22 onPlay(nextSquares); | |
| 23 } | |
| 24 | |
| 25 const winner = calculateWinner(squares); | |
| 26 let status; | |
| 27 if (winner) { | |
| 28 status = 'Winner: ' + winner; | |
| 29 } else { | |
| 30 status = 'Next player: ' + (xIsNext ? 'X' : 'O'); | |
| 31 } | |
| 32 | |
| 33 return ( | |
| 34 <> | |
| 35 <div className="status">{status}</div> | |
| 36 <div className="board-row"> | |
| 37 <Square value={squares[0]} onSquareClick={() => handleClick(0)} /> | |
| 38 <Square value={squares[1]} onSquareClick={() => handleClick(1)} /> | |
| 39 <Square value={squares[2]} onSquareClick={() => handleClick(2)} /> | |
| 40 </div> | |
| 41 <div className="board-row"> | |
| 42 <Square value={squares[3]} onSquareClick={() => handleClick(3)} /> | |
| 43 <Square value={squares[4]} onSquareClick={() => handleClick(4)} /> | |
| 44 <Square value={squares[5]} onSquareClick={() => handleClick(5)} /> | |
| 45 </div> | |
| 46 <div className="board-row"> | |
| 47 <Square value={squares[6]} onSquareClick={() => handleClick(6)} /> | |
| 48 <Square value={squares[7]} onSquareClick={() => handleClick(7)} /> | |
| 49 <Square value={squares[8]} onSquareClick={() => handleClick(8)} /> | |
| 50 </div> | |
| 51 </> | |
| 52 ); | |
| 53 } | |
| 54 | |
| 55 export default function Game() { | |
| 56 const [history, setHistory] = useState([Array(9).fill(null)]); | |
| 57 const [currentMove, setCurrentMove] = useState(0); | |
| 58 const xIsNext = currentMove % 2 === 0; | |
| 59 const currentSquares = history[currentMove]; | |
| 60 | |
| 61 function handlePlay(nextSquares) { | |
| 62 const nextHistory = [...history.slice(0, currentMove + 1), nextSquares]; | |
| 63 setHistory(nextHistory); | |
| 64 setCurrentMove(nextHistory.length - 1); | |
| 65 } | |
| 66 | |
| 67 function jumpTo(nextMove) { | |
| 68 setCurrentMove(nextMove); | |
| 69 } | |
| 70 | |
| 71 const moves = history.map((squares, move) => { | |
| 72 let description; | |
| 73 if (move > 0) { | |
| 74 description = 'Go to move #' + move; | |
| 75 } else { | |
| 76 description = 'Go to game start'; | |
| 77 } | |
| 78 return ( | |
| 79 <li key={move}> | |
| 80 <button onClick={() => jumpTo(move)}>{description}</button> | |
| 81 </li> | |
| 82 ); | |
| 83 }); | |
| 84 | |
| 85 return ( | |
| 86 <div className="game"> | |
| 87 <div className="game-board"> | |
| 88 <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} /> | |
| 89 </div> | |
| 90 <div className="game-info"> | |
| 91 <ol>{moves}</ol> | |
| 92 </div> | |
| 93 </div> | |
| 94 ); | |
| 95 } | |
| 96 | |
| 97 function calculateWinner(squares) { | |
| 98 const lines = [ | |
| 99 [0, 1, 2], | |
| 100 [3, 4, 5], | |
| 101 [6, 7, 8], | |
| 102 [0, 3, 6], | |
| 103 [1, 4, 7], | |
| 104 [2, 5, 8], | |
| 105 [0, 4, 8], | |
| 106 [2, 4, 6], | |
| 107 ]; | |
| 108 for (let i = 0; i < lines.length; i++) { | |
| 109 const [a, b, c] = lines[i]; | |
| 110 if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { | |
| 111 return squares[a]; | |
| 112 } | |
| 113 } | |
| 114 return null; | |
| 115 } |