feat(P5B.T4): TicTacToeBoard + ConnectFourBoard render-only components
This commit is contained in:
@@ -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<number>(winCells ?? []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="mx-auto w-full max-w-2xl rounded-2xl bg-sky-900/40 p-3"
|
||||
role="grid"
|
||||
aria-label="Vier-Gewinnt"
|
||||
>
|
||||
<div
|
||||
className="grid gap-1.5"
|
||||
style={{ gridTemplateColumns: 'repeat(' + C4_COLS + ', minmax(0, 1fr))' }}
|
||||
>
|
||||
{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 (
|
||||
<button
|
||||
key={idx}
|
||||
type="button"
|
||||
onClick={() => canClickColumn && onMove(col)}
|
||||
disabled={!canClickColumn}
|
||||
aria-label={'Spalte ' + (col + 1) + (cell !== null ? ' belegt' : '')}
|
||||
className={
|
||||
'flex aspect-square items-center justify-center rounded-full border-2 transition ' +
|
||||
(inWin
|
||||
? 'border-emerald-300 bg-emerald-400 shadow-[0_0_12px_rgba(110,231,183,0.7)]'
|
||||
: cell === 0
|
||||
? 'border-rose-300 bg-rose-500'
|
||||
: cell === 1
|
||||
? 'border-amber-300 bg-amber-400'
|
||||
: canClickColumn
|
||||
? 'cursor-pointer border-sky-700 bg-sky-950 hover:bg-sky-900'
|
||||
: 'cursor-not-allowed border-sky-800 bg-sky-950 opacity-80')
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user