File size: 3,457 Bytes
e4d7d50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
 * ChessBoard component — live chess board with piece animations
 * Design: Quantitative Finance Dark — cream/brown squares, high-contrast pieces
 *
 * FIX: Black pieces now use #FFD700 (gold) instead of #1a1a2e (invisible on dark squares)
 * FIX: Square colors changed to classic chess cream (#F0D9B5) and brown (#B58863)
 * FIX: Larger font size and stronger shadows for visibility
 */
import { useEffect, useState } from "react";
import { PIECES, type GameState } from "@/lib/simulation";

interface ChessBoardProps {
  state: GameState;
}

export default function ChessBoard({ state }: ChessBoardProps) {
  const [lastMove, setLastMove] = useState<{ from: string; to: string } | null>(null);
  const [prevMoves, setPrevMoves] = useState<string[]>([]);

  useEffect(() => {
    if (state.moves.length > prevMoves.length) {
      setPrevMoves(state.moves);
    }
  }, [state.moves]);

  const files = "abcdefgh";
  const ranks = "87654321";

  const getSquareClass = (rank: number, file: number) => {
    const isLight = (rank + file) % 2 === 0;
    return isLight ? "chess-square-light" : "chess-square-dark";
  };

  return (
    <div className="flex flex-col gap-1">
      {/* Rank labels + board */}
      <div className="flex gap-1">
        {/* Rank labels */}
        <div className="flex flex-col justify-around w-4">
          {ranks.split("").map((r) => (
            <span key={r} className="text-center font-mono leading-none" style={{ fontSize: "10px", fontWeight: 600, color: "#c8c8c8" }}>
              {r}
            </span>
          ))}
        </div>
        {/* Board */}
        <div className="chess-board flex-1 aspect-square">
          {state.board.map((row, rankIdx) =>
            row.map((piece, fileIdx) => {
              const squareClass = getSquareClass(rankIdx, fileIdx);
              return (
                <div
                  key={`${rankIdx}-${fileIdx}`}
                  className={`${squareClass} flex items-center justify-center relative`}
                  style={{ aspectRatio: "1" }}
                >
                  {piece && (
                    <span
                      className="chess-piece select-none"
                      style={{
                        fontSize: "clamp(16px, 3vw, 32px)",
                        // White pieces: bright white; Black pieces: vivid goldboth visible on any square
                        color: piece === piece.toUpperCase() ? "#ffffff" : "#FFD700",
                        textShadow: piece === piece.toUpperCase()
                          ? "0 1px 3px rgba(0,0,0,0.9), 0 0 8px rgba(180,210,255,0.7)"
                          : "0 1px 3px rgba(0,0,0,0.9), 0 0 10px rgba(255,215,0,0.8)",
                        filter: piece === piece.toUpperCase()
                          ? "drop-shadow(0 0 4px rgba(180,210,255,0.6))"
                          : "drop-shadow(0 0 5px rgba(255,215,0,0.9))",
                      }}
                    >
                      {PIECES[piece] ?? piece}
                    </span>
                  )}
                </div>
              );
            })
          )}
        </div>
      </div>
      {/* File labels */}
      <div className="flex ml-5">
        {files.split("").map((f) => (
          <span key={f} className="flex-1 text-center font-mono" style={{ fontSize: "10px", fontWeight: 600, color: "#c8c8c8" }}>
            {f}
          </span>
        ))}
      </div>
    </div>
  );
}