Skip to content

Commit

Permalink
feat: ✨ 完成済みのコードを実装
Browse files Browse the repository at this point in the history
  • Loading branch information
dino3616 committed Nov 29, 2024
1 parent 8754a40 commit 1dcf299
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Square } from '../component/square';
import { Game } from '../component/game';

export const App = () => {
return <Square />;
return <Game />;
};
95 changes: 95 additions & 0 deletions src/component/board.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { calculateWinner } from '../util/calculate-winner';
import { Square } from './square';

type BoardProps = {
xIsNext: boolean;
squares: (string | null)[];
onPlay: (squares: (string | null)[]) => void;
};

export const Board = ({ xIsNext, squares, onPlay }: BoardProps) => {
const handleClick = (i: number) => {
if (squares[i] || calculateWinner(squares)) {
return;
}

const newSquares = squares.slice();

if (xIsNext) {
newSquares[i] = 'X';
} else {
newSquares[i] = 'O';
}

onPlay(newSquares);
};

const winner = calculateWinner(squares);
const status = winner ? `Winner: ${winner}` : `Next player: ${xIsNext ? 'X' : 'O'}`;

return (
<>
<div className='status'>{status}</div>
<div className='board-row'>
<Square
value={squares[0]}
onClick={() => {
handleClick(0);
}}
/>
<Square
value={squares[1]}
onClick={() => {
handleClick(1);
}}
/>
<Square
value={squares[2]}
onClick={() => {
handleClick(2);
}}
/>
</div>
<div className='board-row'>
<Square
value={squares[3]}
onClick={() => {
handleClick(3);
}}
/>
<Square
value={squares[4]}
onClick={() => {
handleClick(4);
}}
/>
<Square
value={squares[5]}
onClick={() => {
handleClick(5);
}}
/>
</div>
<div className='board-row'>
<Square
value={squares[6]}
onClick={() => {
handleClick(6);
}}
/>
<Square
value={squares[7]}
onClick={() => {
handleClick(7);
}}
/>
<Square
value={squares[8]}
onClick={() => {
handleClick(8);
}}
/>
</div>
</>
);
};
40 changes: 40 additions & 0 deletions src/component/game.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useState } from 'react';
import { Board } from './board';

export const Game = () => {
const [history, setHistory] = useState([Array<string | null>(9).fill(null)]);
const [currentMove, setCurrentMove] = useState(0);
const xIsNext = currentMove % 2 === 0;
const currentSquares = history[currentMove]!;

const handlePlay = (nextSquares: (string | null)[]) => {
const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
setHistory(nextHistory);
setCurrentMove(nextHistory.length - 1);
};

const jumpTo = (nextMove: number) => {
setCurrentMove(nextMove);
};

const moves = history.map((_squares, move) => {
const description = move ? `Go to move #${move}` : 'Go to game start';

return (
<li key={move}>
<button onClick={() => jumpTo(move)}>{description}</button>
</li>
);
});

return (
<div className='game'>
<div className='game-board'>
<Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
</div>
<div className='game-info'>
<ol>{moves}</ol>
</div>
</div>
);
};
13 changes: 11 additions & 2 deletions src/component/square.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
export const Square = () => {
return <button className='square'>X</button>;
type SquareProps = {
value: string | null | undefined;
onClick: () => void;
};

export const Square = ({ value, onClick }: SquareProps) => {
return (
<button className='square' onClick={onClick}>
{value}
</button>
);
};

0 comments on commit 1dcf299

Please sign in to comment.