feat(tictactoe): migrate to multi-board state structure

- Replaced single `board` state with `boards` map in App.tsx
- Updated state parsing to use `state.boards` instead of `state.board.grid`
- Updated TicTacToeBoard props to accept `boards` instead of `board`
- Safely extracted TicTacToe board using `boards['tictactoe']?.grid ?? null`
- Added loading fallback when board is not yet available
- Updated rendering guards to prevent undefined map errors

This change fully aligns the frontend with the new multi-board MatchState
introduced on the server (supports TicTacToe, Battleship, and future games).
This commit is contained in:
2025-12-03 17:36:29 +05:30
parent 7b677653a7
commit 2b0af9fd1f
2 changed files with 11 additions and 8 deletions

View File

@@ -7,8 +7,8 @@ import { PlayerModel } from "./models/player";
import TicTacToeBoard from "./games/tictactoe/TicTacToeBoard"; import TicTacToeBoard from "./games/tictactoe/TicTacToeBoard";
export default function App() { export default function App() {
// setting up a 2D game board // setting up a 2D game boards
const [board, setBoard] = useState<string[][]>([[]]); const [boards, setBoards] = useState<Record<string, { grid: string[][] }>>({});
const [turn, setTurn] = useState<number>(0); const [turn, setTurn] = useState<number>(0);
const [winner, setWinner] = useState<string | null>(null); const [winner, setWinner] = useState<string | null>(null);
const [gameOver, setGameOver] = useState<boolean | null>(null); const [gameOver, setGameOver] = useState<boolean | null>(null);
@@ -26,7 +26,7 @@ export default function App() {
const state = msg.data; const state = msg.data;
console.log("Match state:", state); console.log("Match state:", state);
setBoard(state.board.grid); setBoards(state.boards);
setTurn(state.turn); setTurn(state.turn);
setGameOver(state.game_over); setGameOver(state.game_over);
if (state.winner >= 0) { if (state.winner >= 0) {
@@ -114,7 +114,7 @@ export default function App() {
}} }}
> >
<TicTacToeBoard <TicTacToeBoard
board={board} boards={boards}
turn={turn} turn={turn}
winner={winner} winner={winner}
gameOver={gameOver} gameOver={gameOver}

View File

@@ -5,7 +5,7 @@ import getHaiku from "../../utils/haikus";
import { PlayerModel } from "../../models/player"; import { PlayerModel } from "../../models/player";
interface BoardProps { interface BoardProps {
board: string[][]; boards: Record<string, { grid: string[][] }>;
turn: number; turn: number;
winner: string | null; winner: string | null;
gameOver: boolean | null; gameOver: boolean | null;
@@ -15,7 +15,7 @@ interface BoardProps {
} }
export default function TicTacToeBoard({ export default function TicTacToeBoard({
board, boards,
turn, turn,
winner, winner,
gameOver, gameOver,
@@ -62,6 +62,7 @@ export default function TicTacToeBoard({
const nextLineIn = 3600; const nextLineIn = 3600;
const allLinesStay = 2400; const allLinesStay = 2400;
const allLinesFade = 1200; const allLinesFade = 1200;
const board = boards['tictactoe']?.grid ?? null;
useEffect(() => { useEffect(() => {
const totalTime = haiku.length * nextLineIn + allLinesStay + allLinesFade; const totalTime = haiku.length * nextLineIn + allLinesStay + allLinesFade;
@@ -107,7 +108,9 @@ export default function TicTacToeBoard({
{/* ------------------------- {/* -------------------------
BOARD BOARD
-------------------------- */} -------------------------- */}
<motion.div {!board && <div style={{ textAlign: "center", marginTop: "14px" }}>Loading...</div>}
{board && <motion.div
layout layout
style={{ style={{
display: "grid", display: "grid",
@@ -180,7 +183,7 @@ export default function TicTacToeBoard({
); );
}) })
)} )}
</motion.div> </motion.div>}
{!winner && ( {!winner && (
<div <div