77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
"use client"
|
|
|
|
import type { ChessPiece, Position } from "@/lib/chess-types"
|
|
import ChessSquare from "./chess-square"
|
|
|
|
interface ChessBoardProps {
|
|
board: (ChessPiece | null)[][]
|
|
selectedPiece: Position | null
|
|
validMoves: Position[]
|
|
onSquareClick: (position: Position) => void
|
|
}
|
|
|
|
export default function ChessBoard({ board, selectedPiece, validMoves, onSquareClick }: ChessBoardProps) {
|
|
const isValidMove = (row: number, col: number) => {
|
|
return validMoves.some((move) => move.row === row && move.col === col)
|
|
}
|
|
|
|
const isSelected = (row: number, col: number) => {
|
|
return selectedPiece?.row === row && selectedPiece?.col === col
|
|
}
|
|
|
|
// Generate column labels (a-h)
|
|
const columnLabels = Array.from({ length: 8 }, (_, i) => String.fromCharCode(97 + i))
|
|
|
|
// Generate row labels (1-8)
|
|
const rowLabels = Array.from({ length: 8 }, (_, i) => 8 - i)
|
|
|
|
return (
|
|
<div className="relative">
|
|
<div className="grid grid-cols-[auto_repeat(8,1fr)] grid-rows-[repeat(8,1fr)_auto]">
|
|
{/* Empty top-left corner */}
|
|
<div className="w-6"></div>
|
|
|
|
{/* Column labels (top) */}
|
|
{columnLabels.map((label) => (
|
|
<div key={`top-${label}`} className="flex justify-center items-center h-6 text-sm text-gray-600">
|
|
{label}
|
|
</div>
|
|
))}
|
|
|
|
{/* Board with row labels */}
|
|
{board.map((row, rowIndex) => (
|
|
<>
|
|
{/* Row label */}
|
|
<div key={`label-${rowIndex}`} className="flex justify-center items-center w-6 text-sm text-gray-600">
|
|
{rowLabels[rowIndex]}
|
|
</div>
|
|
|
|
{/* Chess squares */}
|
|
{row.map((piece, colIndex) => (
|
|
<ChessSquare
|
|
key={`${rowIndex}-${colIndex}`}
|
|
piece={piece}
|
|
position={{ row: rowIndex, col: colIndex }}
|
|
isLight={(rowIndex + colIndex) % 2 === 0}
|
|
isSelected={isSelected(rowIndex, colIndex)}
|
|
isValidMove={isValidMove(rowIndex, colIndex)}
|
|
onClick={() => onSquareClick({ row: rowIndex, col: colIndex })}
|
|
/>
|
|
))}
|
|
</>
|
|
))}
|
|
|
|
{/* Empty bottom-left corner */}
|
|
<div className="w-6"></div>
|
|
|
|
{/* Column labels (bottom) */}
|
|
{columnLabels.map((label) => (
|
|
<div key={`bottom-${label}`} className="flex justify-center items-center h-6 text-sm text-gray-600">
|
|
{label}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|