diff --git a/apps/desktop/src/components/ConnectFourBoard.tsx b/apps/desktop/src/components/ConnectFourBoard.tsx new file mode 100644 index 0000000..a4a32d3 --- /dev/null +++ b/apps/desktop/src/components/ConnectFourBoard.tsx @@ -0,0 +1,61 @@ +import { + C4_COLS, + C4_ROWS, + c4DropRow, + c4WinningCells, + type Cell, +} from '@chat-app/shared/chat'; + +interface Props { + board: Cell[]; + myPlayerIdx: 0 | 1 | null; + disabled: boolean; + onMove: (column: number) => void; +} + +export function ConnectFourBoard({ board, myPlayerIdx, disabled, onMove }: Props) { + const winCells = c4WinningCells(board); + const winSet = new Set(winCells ?? []); + + return ( +
+
+ {Array.from({ length: C4_ROWS * C4_COLS }, (_, idx) => { + const cell = board[idx]; + const col = idx % C4_COLS; + const dropTo = c4DropRow(board, col); + const canClickColumn = !disabled && dropTo >= 0 && myPlayerIdx !== null; + const inWin = winSet.has(idx); + return ( +
+
+ ); +} diff --git a/apps/desktop/src/components/TicTacToeBoard.tsx b/apps/desktop/src/components/TicTacToeBoard.tsx new file mode 100644 index 0000000..8c82365 --- /dev/null +++ b/apps/desktop/src/components/TicTacToeBoard.tsx @@ -0,0 +1,53 @@ +import { type Cell, tttWinningLine } from '@chat-app/shared/chat'; + +interface Props { + board: Cell[]; + myPlayerIdx: 0 | 1 | null; + disabled: boolean; + onMove: (cell: number) => void; +} + +const MARK = ['×', '○'] as const; + +export function TicTacToeBoard({ board, myPlayerIdx, disabled, onMove }: Props) { + const winLine = tttWinningLine(board); + const winSet = new Set(winLine ?? []); + + return ( +
+ {board.map((cell, i) => { + const filled = cell !== null; + const inWin = winSet.has(i); + const canClick = !disabled && !filled && myPlayerIdx !== null; + return ( + + ); + })} +
+ ); +}