Problem: The recent fix for #51/#52 expanded getPossibleMovesForPiece to all piece types, but the implementation still omits:
Pawn double-push from starting rank
En passant capture
King castling (kingside/queenside)
Both hasAnyLegalMove and isKingInCheck depend on this helper. As a result, checkmate and stalemate detection will produce wrong verdicts when the only legal escape from check is a special move (e.g. king must castle to escape, or only en-passant captures the checking pawn).
Fix options:
Have hasAnyLegalMove / check-detection helpers reuse getPossibleMoves against a synthesized minimal GameState (board + enPassantTarget + castlingRights + currentPlayer)
Or extend getPossibleMovesForPiece to take full GameState and mirror logic from getPawnMoves / getKingMoves
Acceptance criteria:
Stalemate detected when only legal pawn move is double-push
Checkmate not falsely declared when castling is the legal escape
En passant correctly counted as legal escape from check
Regression tests for each scenario
**Severity:** Critical (Game correctness)
**File:** `spikersoft-angular/projects/spikersoft/src/app/_services/game/chess-game.service.ts` (~773-834)
**Problem:** The recent fix for #51/#52 expanded `getPossibleMovesForPiece` to all piece types, but the implementation still omits:
- Pawn double-push from starting rank
- En passant capture
- King castling (kingside/queenside)
Both `hasAnyLegalMove` and `isKingInCheck` depend on this helper. As a result, checkmate and stalemate detection will produce **wrong verdicts** when the only legal escape from check is a special move (e.g. king must castle to escape, or only en-passant captures the checking pawn).
**Fix options:**
1. Have `hasAnyLegalMove` / check-detection helpers reuse `getPossibleMoves` against a synthesized minimal `GameState` (board + enPassantTarget + castlingRights + currentPlayer)
2. Or extend `getPossibleMovesForPiece` to take full `GameState` and mirror logic from `getPawnMoves` / `getKingMoves`
**Acceptance criteria:**
- [ ] Stalemate detected when only legal pawn move is double-push
- [ ] Checkmate not falsely declared when castling is the legal escape
- [ ] En passant correctly counted as legal escape from check
- [ ] Regression tests for each scenario
Introduced getPseudoLegalMovesWithState(piece, state), which dispatches to the existing state-aware getPawnMoves and getKingMoves for pawns and kings (so castling, en-passant, and double-push are included) and falls back to the board-only generator for other piece types. hasAnyLegalMove now uses this helper -- so checkmate and stalemate detection see special-move escapes.
Additionally fixed two related correctness bugs:
applyMove was passing { ...state, board: newBoard } into hasAnyLegalMove, leaving stale castlingRights/enPassantTarget. Now it threads newCastlingRights, newEnPassantTarget, and newCurrentPlayer through the temp state.
wouldMovePutKingInCheck did not simulate en-passant capture removal or rook movement during castling. It now removes the en-passant captured pawn and moves the rook for kingside/queenside castles before running the attacker scan.
File: spikersoft-angular/projects/spikersoft/src/app/_services/game/chess-game.service.ts. Tests added in #69.
**Resolved.**
Introduced `getPseudoLegalMovesWithState(piece, state)`, which dispatches to the existing state-aware `getPawnMoves` and `getKingMoves` for pawns and kings (so castling, en-passant, and double-push are included) and falls back to the board-only generator for other piece types. `hasAnyLegalMove` now uses this helper -- so checkmate and stalemate detection see special-move escapes.
Additionally fixed two related correctness bugs:
1. `applyMove` was passing `{ ...state, board: newBoard }` into `hasAnyLegalMove`, leaving stale `castlingRights`/`enPassantTarget`. Now it threads `newCastlingRights`, `newEnPassantTarget`, and `newCurrentPlayer` through the temp state.
2. `wouldMovePutKingInCheck` did not simulate en-passant capture removal or rook movement during castling. It now removes the en-passant captured pawn and moves the rook for kingside/queenside castles before running the attacker scan.
File: `spikersoft-angular/projects/spikersoft/src/app/_services/game/chess-game.service.ts`. Tests added in #69.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: Critical (Game correctness)
File:
spikersoft-angular/projects/spikersoft/src/app/_services/game/chess-game.service.ts(~773-834)Problem: The recent fix for #51/#52 expanded
getPossibleMovesForPieceto all piece types, but the implementation still omits:Both
hasAnyLegalMoveandisKingInCheckdepend on this helper. As a result, checkmate and stalemate detection will produce wrong verdicts when the only legal escape from check is a special move (e.g. king must castle to escape, or only en-passant captures the checking pawn).Fix options:
hasAnyLegalMove/ check-detection helpers reusegetPossibleMovesagainst a synthesized minimalGameState(board + enPassantTarget + castlingRights + currentPlayer)getPossibleMovesForPieceto take fullGameStateand mirror logic fromgetPawnMoves/getKingMovesAcceptance criteria:
Resolved.
Introduced
getPseudoLegalMovesWithState(piece, state), which dispatches to the existing state-awaregetPawnMovesandgetKingMovesfor pawns and kings (so castling, en-passant, and double-push are included) and falls back to the board-only generator for other piece types.hasAnyLegalMovenow uses this helper -- so checkmate and stalemate detection see special-move escapes.Additionally fixed two related correctness bugs:
applyMovewas passing{ ...state, board: newBoard }intohasAnyLegalMove, leaving stalecastlingRights/enPassantTarget. Now it threadsnewCastlingRights,newEnPassantTarget, andnewCurrentPlayerthrough the temp state.wouldMovePutKingInCheckdid not simulate en-passant capture removal or rook movement during castling. It now removes the en-passant captured pawn and moves the rook for kingside/queenside castles before running the attacker scan.File:
spikersoft-angular/projects/spikersoft/src/app/_services/game/chess-game.service.ts. Tests added in #69.