fix: NCS-32 Queenside Castle doesn't care about pieces in the way (#23)
Build & Test (NowChessSystems) TeamCity build finished
Build & Test (NowChessSystems) TeamCity build finished
Reviewed-on: #23 Co-authored-by: Janis <janis.e.20@gmx.de> Co-committed-by: Janis <janis.e.20@gmx.de>
This commit was merged in pull request #23.
This commit is contained in:
@@ -163,6 +163,12 @@ object DefaultRules extends RuleSet:
|
|||||||
CastlingMove("e8", "c8", "d8", "a8", MoveType.CastleQueenside))
|
CastlingMove("e8", "c8", "d8", "a8", MoveType.CastleQueenside))
|
||||||
moves.toList
|
moves.toList
|
||||||
|
|
||||||
|
private def queensideBSquare(kingToAlg: String): List[String] =
|
||||||
|
kingToAlg match
|
||||||
|
case "c1" => List("b1")
|
||||||
|
case "c8" => List("b8")
|
||||||
|
case _ => List.empty
|
||||||
|
|
||||||
private def addCastleMove(
|
private def addCastleMove(
|
||||||
context: GameContext,
|
context: GameContext,
|
||||||
moves: scala.collection.mutable.ListBuffer[Move],
|
moves: scala.collection.mutable.ListBuffer[Move],
|
||||||
@@ -170,7 +176,8 @@ object DefaultRules extends RuleSet:
|
|||||||
castlingMove: CastlingMove
|
castlingMove: CastlingMove
|
||||||
): Unit =
|
): Unit =
|
||||||
if castlingRight then
|
if castlingRight then
|
||||||
val clearSqs = List(castlingMove.middleAlg, castlingMove.kingToAlg).flatMap(Square.fromAlgebraic)
|
val clearSqs = (List(castlingMove.middleAlg, castlingMove.kingToAlg) ++ queensideBSquare(castlingMove.kingToAlg))
|
||||||
|
.flatMap(Square.fromAlgebraic)
|
||||||
if squaresEmpty(context.board, clearSqs) then
|
if squaresEmpty(context.board, clearSqs) then
|
||||||
for
|
for
|
||||||
kf <- Square.fromAlgebraic(castlingMove.kingFromAlg)
|
kf <- Square.fromAlgebraic(castlingMove.kingFromAlg)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class DefaultRulesTest extends AnyFunSuite with Matchers:
|
|||||||
val moves = rules.allLegalMoves(context)
|
val moves = rules.allLegalMoves(context)
|
||||||
|
|
||||||
// King must move; e2 should be valid but d1 might be blocked by rook if still on same file
|
// King must move; e2 should be valid but d1 might be blocked by rook if still on same file
|
||||||
moves.filter(m => m.from == Square(File.E, Rank.R1)).nonEmpty shouldBe true
|
moves.exists(m => m.from == Square(File.E, Rank.R1)) shouldBe true
|
||||||
|
|
||||||
test("king cannot move to square attacked by opponent"):
|
test("king cannot move to square attacked by opponent"):
|
||||||
// FEN: white king e1, black rook e2 defended by black king e3
|
// FEN: white king e1, black rook e2 defended by black king e3
|
||||||
@@ -109,6 +109,28 @@ class DefaultRulesTest extends AnyFunSuite with Matchers:
|
|||||||
val castles = moves.filter(m => m.moveType == MoveType.CastleKingside)
|
val castles = moves.filter(m => m.moveType == MoveType.CastleKingside)
|
||||||
castles.isEmpty shouldBe true
|
castles.isEmpty shouldBe true
|
||||||
|
|
||||||
|
test("castling queenside is illegal when knight blocks on b8"):
|
||||||
|
// Black king e8, black rook a8, black knight b8 (blocks queenside path)
|
||||||
|
val board = Board(Map(
|
||||||
|
Square(File.A, Rank.R8) -> Piece(Color.Black, PieceType.Rook),
|
||||||
|
Square(File.B, Rank.R8) -> Piece(Color.Black, PieceType.Knight),
|
||||||
|
Square(File.E, Rank.R8) -> Piece(Color.Black, PieceType.King),
|
||||||
|
Square(File.A, Rank.R1) -> Piece(Color.White, PieceType.Rook),
|
||||||
|
Square(File.E, Rank.R1) -> Piece(Color.White, PieceType.King)
|
||||||
|
))
|
||||||
|
val context = GameContext(
|
||||||
|
board = board,
|
||||||
|
turn = Color.Black,
|
||||||
|
castlingRights = CastlingRights(whiteKingSide = true, whiteQueenSide = true, blackKingSide = true, blackQueenSide = true),
|
||||||
|
enPassantSquare = None,
|
||||||
|
halfMoveClock = 0,
|
||||||
|
moves = List.empty
|
||||||
|
)
|
||||||
|
val moves = rules.allLegalMoves(context)
|
||||||
|
|
||||||
|
val castles = moves.filter(m => m.moveType == MoveType.CastleQueenside)
|
||||||
|
castles.isEmpty shouldBe true
|
||||||
|
|
||||||
// ── En passant legality ──────────────────────────────────────────
|
// ── En passant legality ──────────────────────────────────────────
|
||||||
|
|
||||||
test("en passant is legal when en passant square is set"):
|
test("en passant is legal when en passant square is set"):
|
||||||
|
|||||||
Reference in New Issue
Block a user