diff --git a/apps/web/src/games/chess/index.tsx b/apps/web/src/games/chess/index.tsx index 3fa282a..dc4741c 100644 --- a/apps/web/src/games/chess/index.tsx +++ b/apps/web/src/games/chess/index.tsx @@ -277,7 +277,8 @@ function ChessBoard({ view: v, act, pending }: BoardProps) { onPointerDown={(e) => { setKbd(false); const sq = cellAt(e); - if (!sq || !ownMovable(sq) || pending) return; + // Chess960: with the king picked, my own rook is a castling target, not a new selection. + if (!sq || !ownMovable(sq) || pending || (selected && targets.some((m) => m.to === sq))) return; drag.current = { from: sq, wasSelected: selected === sq, sx: e.clientX, sy: e.clientY, moved: false }; setSelected(sq); svgRef.current?.setPointerCapture(e.pointerId); @@ -361,6 +362,18 @@ function ChessBoard({ view: v, act, pending }: BoardProps) { {showDots && targets.map((m) => { const c = cell(m.to); + if (m.castle) { + // Castling target (king's square or, in 960, the own rook): gold frame + label, so it is never mistaken for a capture. + return ( + + + + + 캐슬링 + + + ); + } const capture = !!pieceAt(v, m.to) || (pieceAt(v, m.from)?.toLowerCase() === 'p' && m.from[0] !== m.to[0]); return capture ? ( @@ -386,6 +399,15 @@ function ChessBoard({ view: v, act, pending }: BoardProps) {

{announce}

+ {myTurn && selected && targets.some((m) => m.castle) && (showDots || v.chess960Index !== null) && ( +

+ {v.chess960Index === null + ? '캐슬링하려면 노란 테두리 칸을 누르세요.' + : showDots + ? '캐슬링하려면 노란 테두리 칸(내 룩, 또는 킹이 갈 g·c열 칸)을 누르세요.' + : '캐슬링하려면 내 룩이나 킹이 갈 g·c열 칸을 누르세요.'} +

+ )} {!v.myColor && (
)} + {castles.length > 0 && ( +
+ {castles.map((side) => ( + + ))} +
+ )} {canClaim && (