fix: promotion dialog only fires for genuine pawn promotions
The "Promote pawn" dialog popped for any pawn "moved" toward the last rank: the commit paths checked piece type + destination rank but never the pawn's SOURCE rank. With the phantom layer now filling ranks 7-8 with tappable phantom pieces, tapping one (which falls through to the real-move handler) while a real pawn was armed triggered the dialog for a move no pawn could make — and for any phantom type, not just pawns. Root cause: incomplete promotion detection, duplicated in Game.svelte `onCommit` and the server's `isPromotionRequired`. Replaced with one shared `isPromotionMove(piece, from, to)` — pawn, from the rank adjacent to promotion, to the promotion rank, at most one file over — used by both. 7 unit tests in packages/shared. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { Move } from 'chess.js';
|
||||
import {
|
||||
geometricMoves,
|
||||
isPromotionMove,
|
||||
type Announcement,
|
||||
type Color,
|
||||
type Piece,
|
||||
@@ -124,9 +125,6 @@ function chessJsLegalFrom(game: Game, from: Square): string[] {
|
||||
|
||||
function isPromotionRequired(game: Game, from: Square, to: Square): boolean {
|
||||
const piece = game.chess.get(from);
|
||||
if (!piece || piece.type !== 'p') return false;
|
||||
const toRank = to[1];
|
||||
if (piece.color === 'w' && toRank === '8') return true;
|
||||
if (piece.color === 'b' && toRank === '1') return true;
|
||||
return false;
|
||||
if (!piece) return false;
|
||||
return isPromotionMove({ color: piece.color, type: piece.type }, from, to);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user