feat: NCS-11 propagate half-move clock flags through GameController
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -63,7 +63,8 @@ object GameController:
|
|||||||
case PromotionPiece.Bishop => PieceType.Bishop
|
case PromotionPiece.Bishop => PieceType.Bishop
|
||||||
case PromotionPiece.Knight => PieceType.Knight
|
case PromotionPiece.Knight => PieceType.Knight
|
||||||
val newBoard = boardAfterMove.updated(to, Piece(turn, promotedPieceType))
|
val newBoard = boardAfterMove.updated(to, Piece(turn, promotedPieceType))
|
||||||
val newHistory = history.addMove(from, to, None, Some(piece))
|
// Promotion is always a pawn move → clock resets
|
||||||
|
val newHistory = history.addMove(from, to, None, Some(piece), wasPawnMove = true)
|
||||||
toMoveResult(newBoard, newHistory, captured, turn)
|
toMoveResult(newBoard, newHistory, captured, turn)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -91,7 +92,9 @@ object GameController:
|
|||||||
val capturedSq = EnPassantCalculator.capturedPawnSquare(to, turn)
|
val capturedSq = EnPassantCalculator.capturedPawnSquare(to, turn)
|
||||||
(b.removed(capturedSq), board.pieceAt(capturedSq))
|
(b.removed(capturedSq), board.pieceAt(capturedSq))
|
||||||
else (b, cap)
|
else (b, cap)
|
||||||
val newHistory = history.addMove(from, to, castleOpt)
|
val wasPawnMove = board.pieceAt(from).exists(_.pieceType == PieceType.Pawn)
|
||||||
|
val wasCapture = captured.isDefined
|
||||||
|
val newHistory = history.addMove(from, to, castleOpt, wasPawnMove = wasPawnMove, wasCapture = wasCapture)
|
||||||
toMoveResult(newBoard, newHistory, captured, turn)
|
toMoveResult(newBoard, newHistory, captured, turn)
|
||||||
|
|
||||||
private def toMoveResult(newBoard: Board, newHistory: GameHistory, captured: Option[Piece], turn: Color): MoveResult =
|
private def toMoveResult(newBoard: Board, newHistory: GameHistory, captured: Option[Piece], turn: Color): MoveResult =
|
||||||
|
|||||||
@@ -488,3 +488,39 @@ class GameControllerTest extends AnyFunSuite with Matchers:
|
|||||||
PromotionPiece.Knight, Color.White
|
PromotionPiece.Knight, Color.White
|
||||||
)
|
)
|
||||||
result should be (MoveResult.Stalemate)
|
result should be (MoveResult.Stalemate)
|
||||||
|
|
||||||
|
// ──── half-move clock propagation ────────────────────────────────────
|
||||||
|
|
||||||
|
test("processMove: non-pawn non-capture increments halfMoveClock"):
|
||||||
|
// g1f3 is a knight move — not a pawn, not a capture
|
||||||
|
processMove(Board.initial, GameHistory.empty, Color.White, "g1f3") match
|
||||||
|
case MoveResult.Moved(_, newHistory, _, _) =>
|
||||||
|
newHistory.halfMoveClock shouldBe 1
|
||||||
|
case other => fail(s"Expected Moved, got $other")
|
||||||
|
|
||||||
|
test("processMove: pawn move resets halfMoveClock to 0"):
|
||||||
|
processMove(Board.initial, GameHistory.empty, Color.White, "e2e4") match
|
||||||
|
case MoveResult.Moved(_, newHistory, _, _) =>
|
||||||
|
newHistory.halfMoveClock shouldBe 0
|
||||||
|
case other => fail(s"Expected Moved, got $other")
|
||||||
|
|
||||||
|
test("processMove: capture resets halfMoveClock to 0"):
|
||||||
|
// White pawn on e5, Black pawn on d6 — exd6 is a capture
|
||||||
|
val board = Board(Map(
|
||||||
|
sq(File.E, Rank.R5) -> Piece.WhitePawn,
|
||||||
|
sq(File.D, Rank.R6) -> Piece.BlackPawn,
|
||||||
|
sq(File.E, Rank.R1) -> Piece.WhiteKing,
|
||||||
|
sq(File.E, Rank.R8) -> Piece.BlackKing
|
||||||
|
))
|
||||||
|
val history = GameHistory(halfMoveClock = 10)
|
||||||
|
processMove(board, history, Color.White, "e5d6") match
|
||||||
|
case MoveResult.Moved(_, newHistory, _, _) =>
|
||||||
|
newHistory.halfMoveClock shouldBe 0
|
||||||
|
case other => fail(s"Expected Moved, got $other")
|
||||||
|
|
||||||
|
test("processMove: clock carries from previous history on non-pawn non-capture"):
|
||||||
|
val history = GameHistory(halfMoveClock = 5)
|
||||||
|
processMove(Board.initial, history, Color.White, "g1f3") match
|
||||||
|
case MoveResult.Moved(_, newHistory, _, _) =>
|
||||||
|
newHistory.halfMoveClock shouldBe 6
|
||||||
|
case other => fail(s"Expected Moved, got $other")
|
||||||
|
|||||||
Reference in New Issue
Block a user