refactor(core): simplify castling logic and improve move translation methods
Build & Test (NowChessSystems) TeamCity build failed
Build & Test (NowChessSystems) TeamCity build failed
This commit is contained in:
@@ -138,25 +138,10 @@ object DefaultRules extends RuleSet:
|
||||
if from != expected then List.empty
|
||||
else
|
||||
val moves = scala.collection.mutable.ListBuffer[Move]()
|
||||
|
||||
// King-side castling
|
||||
if context.castlingRights.whiteKingSide then
|
||||
val clearSqs = List("f1", "g1").flatMap(Square.fromAlgebraic)
|
||||
if squaresEmpty(context.board, clearSqs) then
|
||||
for
|
||||
kf <- Square.fromAlgebraic("e1")
|
||||
kt <- Square.fromAlgebraic("g1")
|
||||
do moves += Move(kf, kt, MoveType.CastleKingside)
|
||||
|
||||
// Queen-side castling
|
||||
if context.castlingRights.whiteQueenSide then
|
||||
val clearSqs = List("b1", "c1", "d1").flatMap(Square.fromAlgebraic)
|
||||
if squaresEmpty(context.board, clearSqs) then
|
||||
for
|
||||
kf <- Square.fromAlgebraic("e1")
|
||||
kt <- Square.fromAlgebraic("c1")
|
||||
do moves += Move(kf, kt, MoveType.CastleQueenside)
|
||||
|
||||
addCastleMove(context, moves, context.castlingRights.whiteKingSide,
|
||||
"e1", "g1", "f1", "h1", MoveType.CastleKingside)
|
||||
addCastleMove(context, moves, context.castlingRights.whiteQueenSide,
|
||||
"e1", "c1", "d1", "a1", MoveType.CastleQueenside)
|
||||
moves.toList
|
||||
|
||||
private def blackCastles(context: GameContext, from: Square): List[Move] =
|
||||
@@ -164,27 +149,30 @@ object DefaultRules extends RuleSet:
|
||||
if from != expected then List.empty
|
||||
else
|
||||
val moves = scala.collection.mutable.ListBuffer[Move]()
|
||||
|
||||
// King-side castling
|
||||
if context.castlingRights.blackKingSide then
|
||||
val clearSqs = List("f8", "g8").flatMap(Square.fromAlgebraic)
|
||||
if squaresEmpty(context.board, clearSqs) then
|
||||
for
|
||||
kf <- Square.fromAlgebraic("e8")
|
||||
kt <- Square.fromAlgebraic("g8")
|
||||
do moves += Move(kf, kt, MoveType.CastleKingside)
|
||||
|
||||
// Queen-side castling
|
||||
if context.castlingRights.blackQueenSide then
|
||||
val clearSqs = List("b8", "c8", "d8").flatMap(Square.fromAlgebraic)
|
||||
if squaresEmpty(context.board, clearSqs) then
|
||||
for
|
||||
kf <- Square.fromAlgebraic("e8")
|
||||
kt <- Square.fromAlgebraic("c8")
|
||||
do moves += Move(kf, kt, MoveType.CastleQueenside)
|
||||
|
||||
addCastleMove(context, moves, context.castlingRights.blackKingSide,
|
||||
"e8", "g8", "f8", "h8", MoveType.CastleKingside)
|
||||
addCastleMove(context, moves, context.castlingRights.blackQueenSide,
|
||||
"e8", "c8", "d8", "a8", MoveType.CastleQueenside)
|
||||
moves.toList
|
||||
|
||||
private def addCastleMove(
|
||||
context: GameContext,
|
||||
moves: scala.collection.mutable.ListBuffer[Move],
|
||||
castlingRight: Boolean,
|
||||
kingFromAlg: String,
|
||||
kingToAlg: String,
|
||||
middleAlg: String,
|
||||
rookAlg: String,
|
||||
moveType: MoveType
|
||||
): Unit =
|
||||
if castlingRight then
|
||||
val clearSqs = List(middleAlg, kingToAlg).flatMap(Square.fromAlgebraic)
|
||||
if squaresEmpty(context.board, clearSqs) then
|
||||
for
|
||||
kf <- Square.fromAlgebraic(kingFromAlg)
|
||||
kt <- Square.fromAlgebraic(kingToAlg)
|
||||
do moves += Move(kf, kt, moveType)
|
||||
|
||||
private def squaresEmpty(board: Board, squares: List[Square]): Boolean =
|
||||
squares.forall(sq => board.pieceAt(sq).isEmpty)
|
||||
|
||||
@@ -287,12 +275,12 @@ object DefaultRules extends RuleSet:
|
||||
val newBoard = move.moveType match
|
||||
case MoveType.CastleKingside => applyCastle(board, color, kingside = true)
|
||||
case MoveType.CastleQueenside => applyCastle(board, color, kingside = false)
|
||||
case MoveType.EnPassant => applyEnPassant(board, move, color)
|
||||
case MoveType.EnPassant => applyEnPassant(board, move)
|
||||
case MoveType.Promotion(pp) => applyPromotion(board, move, color, pp)
|
||||
case MoveType.Normal(_) => board.applyMove(move)
|
||||
|
||||
val newCastlingRights = updateCastlingRights(context.castlingRights, board, move, color)
|
||||
val newEnPassantSquare = computeEnPassantSquare(board, move, color)
|
||||
val newEnPassantSquare = computeEnPassantSquare(board, move)
|
||||
val isCapture = move.moveType match
|
||||
case MoveType.Normal(capture) => capture
|
||||
case MoveType.EnPassant => true
|
||||
@@ -322,7 +310,7 @@ object DefaultRules extends RuleSet:
|
||||
.updated(kingTo, king)
|
||||
.updated(rookTo, rook)
|
||||
|
||||
private def applyEnPassant(board: Board, move: Move, color: Color): Board =
|
||||
private def applyEnPassant(board: Board, move: Move): Board =
|
||||
val capturedRank = move.from.rank // the captured pawn is on the same rank as the moving pawn
|
||||
val capturedSquare = Square(move.to.file, capturedRank)
|
||||
board.applyMove(move).removed(capturedSquare)
|
||||
@@ -360,7 +348,7 @@ object DefaultRules extends RuleSet:
|
||||
if move.to == blackQueensideRook then r = r.revokeQueenSide(Color.Black)
|
||||
r
|
||||
|
||||
private def computeEnPassantSquare(board: Board, move: Move, color: Color): Option[Square] =
|
||||
private def computeEnPassantSquare(board: Board, move: Move): Option[Square] =
|
||||
val piece = board.pieceAt(move.from)
|
||||
val isDoublePawnPush = piece.exists(_.pieceType == PieceType.Pawn) &&
|
||||
math.abs(move.to.rank.ordinal - move.from.rank.ordinal) == 2
|
||||
|
||||
Reference in New Issue
Block a user