feat: add PromotionRequired to MoveResult and detect promotion in processMove
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package de.nowchess.chess.controller
|
||||
|
||||
import de.nowchess.api.board.{Board, Color, File, Piece, Rank, Square}
|
||||
import de.nowchess.api.move.PromotionPiece
|
||||
import de.nowchess.chess.logic.*
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -14,6 +15,14 @@ object MoveResult:
|
||||
case object NoPiece extends MoveResult
|
||||
case object WrongColor extends MoveResult
|
||||
case object IllegalMove extends MoveResult
|
||||
case class PromotionRequired(
|
||||
from: Square,
|
||||
to: Square,
|
||||
boardBefore: Board,
|
||||
historyBefore: GameHistory,
|
||||
captured: Option[Piece],
|
||||
turn: Color
|
||||
) extends MoveResult
|
||||
case class Moved(newBoard: Board, newHistory: GameHistory, captured: Option[Piece], newTurn: Color) extends MoveResult
|
||||
case class MovedInCheck(newBoard: Board, newHistory: GameHistory, captured: Option[Piece], newTurn: Color) extends MoveResult
|
||||
case class Checkmate(winner: Color) extends MoveResult
|
||||
@@ -45,6 +54,9 @@ object GameController:
|
||||
case Some(_) =>
|
||||
if !MoveValidator.isLegal(board, history, from, to) then
|
||||
MoveResult.IllegalMove
|
||||
else if MoveValidator.isPromotionMove(board, from, to) then
|
||||
val captured = board.pieceAt(to)
|
||||
MoveResult.PromotionRequired(from, to, board, history, captured, turn)
|
||||
else
|
||||
val castleOpt = if MoveValidator.isCastle(board, from, to)
|
||||
then Some(MoveValidator.castleSide(from, to))
|
||||
|
||||
@@ -3,6 +3,7 @@ package de.nowchess.chess.controller
|
||||
import de.nowchess.api.board.*
|
||||
import de.nowchess.api.game.CastlingRights
|
||||
import de.nowchess.chess.logic.{CastleSide, GameHistory}
|
||||
import de.nowchess.chess.notation.FenParser
|
||||
import org.scalatest.funsuite.AnyFunSuite
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
@@ -293,3 +294,30 @@ class GameControllerTest extends AnyFunSuite with Matchers:
|
||||
newBoard.pieceAt(Square(File.E, Rank.R3)) shouldBe Some(Piece.BlackPawn) // capturing pawn placed
|
||||
captured shouldBe Some(Piece.WhitePawn)
|
||||
case other => fail(s"Expected Moved but got $other")
|
||||
|
||||
// ──── pawn promotion detection ───────────────────────────────────────────
|
||||
|
||||
test("processMove detects white pawn reaching R8 and returns PromotionRequired"):
|
||||
val board = FenParser.parseBoard("8/4P3/4k3/8/8/8/8/8").get
|
||||
val result = GameController.processMove(board, GameHistory.empty, Color.White, "e7e8")
|
||||
result should matchPattern { case _: MoveResult.PromotionRequired => }
|
||||
result match
|
||||
case MoveResult.PromotionRequired(from, to, _, _, _, turn) =>
|
||||
from should be (sq(File.E, Rank.R7))
|
||||
to should be (sq(File.E, Rank.R8))
|
||||
turn should be (Color.White)
|
||||
case _ => fail("Expected PromotionRequired")
|
||||
|
||||
test("processMove detects black pawn reaching R1 and returns PromotionRequired"):
|
||||
val board = FenParser.parseBoard("8/8/8/8/4K3/8/4p3/8").get
|
||||
val result = GameController.processMove(board, GameHistory.empty, Color.Black, "e2e1")
|
||||
result should matchPattern { case _: MoveResult.PromotionRequired => }
|
||||
|
||||
test("processMove detects pawn capturing to back rank as PromotionRequired with captured piece"):
|
||||
val board = FenParser.parseBoard("3q4/4P3/8/8/8/8/8/8").get
|
||||
val result = GameController.processMove(board, GameHistory.empty, Color.White, "e7d8")
|
||||
result should matchPattern { case _: MoveResult.PromotionRequired => }
|
||||
result match
|
||||
case MoveResult.PromotionRequired(_, _, _, _, captured, _) =>
|
||||
captured should be (Some(Piece(Color.Black, PieceType.Queen)))
|
||||
case _ => fail("Expected PromotionRequired")
|
||||
|
||||
Reference in New Issue
Block a user