feat: refactor move processing logic for improved readability and modularity
Build & Test (NowChessSystems) TeamCity build finished
Build & Test (NowChessSystems) TeamCity build finished
This commit is contained in:
@@ -39,43 +39,11 @@ object GameController:
|
|||||||
*/
|
*/
|
||||||
def processMove(board: Board, history: GameHistory, turn: Color, raw: String): MoveResult =
|
def processMove(board: Board, history: GameHistory, turn: Color, raw: String): MoveResult =
|
||||||
raw.trim match
|
raw.trim match
|
||||||
case "quit" | "q" =>
|
case "quit" | "q" => MoveResult.Quit
|
||||||
MoveResult.Quit
|
|
||||||
case trimmed =>
|
case trimmed =>
|
||||||
Parser.parseMove(trimmed) match
|
Parser.parseMove(trimmed) match
|
||||||
case None =>
|
case None => MoveResult.InvalidFormat(trimmed)
|
||||||
MoveResult.InvalidFormat(trimmed)
|
case Some((from, to)) => validateAndApply(board, history, turn, from, to)
|
||||||
case Some((from, to)) =>
|
|
||||||
board.pieceAt(from) match
|
|
||||||
case None =>
|
|
||||||
MoveResult.NoPiece
|
|
||||||
case Some(piece) if piece.color != turn =>
|
|
||||||
MoveResult.WrongColor
|
|
||||||
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))
|
|
||||||
else None
|
|
||||||
val isEP = EnPassantCalculator.isEnPassant(board, history, from, to)
|
|
||||||
val (newBoard, captured) = castleOpt match
|
|
||||||
case Some(side) => (board.withCastle(turn, side), None)
|
|
||||||
case None =>
|
|
||||||
val (b, cap) = board.withMove(from, to)
|
|
||||||
if isEP then
|
|
||||||
val capturedSq = EnPassantCalculator.capturedPawnSquare(to, turn)
|
|
||||||
(b.removed(capturedSq), board.pieceAt(capturedSq))
|
|
||||||
else (b, cap)
|
|
||||||
val newHistory = history.addMove(from, to, castleOpt)
|
|
||||||
GameRules.gameStatus(newBoard, newHistory, turn.opposite) match
|
|
||||||
case PositionStatus.Normal => MoveResult.Moved(newBoard, newHistory, captured, turn.opposite)
|
|
||||||
case PositionStatus.InCheck => MoveResult.MovedInCheck(newBoard, newHistory, captured, turn.opposite)
|
|
||||||
case PositionStatus.Mated => MoveResult.Checkmate(turn)
|
|
||||||
case PositionStatus.Drawn => MoveResult.Stalemate
|
|
||||||
|
|
||||||
/** Apply a previously detected promotion move with the chosen piece.
|
/** Apply a previously detected promotion move with the chosen piece.
|
||||||
* Called after processMove returned PromotionRequired.
|
* Called after processMove returned PromotionRequired.
|
||||||
@@ -94,8 +62,39 @@ object GameController:
|
|||||||
case PromotionPiece.Rook => PieceType.Rook
|
case PromotionPiece.Rook => PieceType.Rook
|
||||||
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))
|
val newHistory = history.addMove(from, to, None, Some(piece))
|
||||||
|
toMoveResult(newBoard, newHistory, captured, turn)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Private helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private def validateAndApply(board: Board, history: GameHistory, turn: Color, from: Square, to: Square): MoveResult =
|
||||||
|
board.pieceAt(from) match
|
||||||
|
case None => MoveResult.NoPiece
|
||||||
|
case Some(piece) if piece.color != turn => MoveResult.WrongColor
|
||||||
|
case Some(_) =>
|
||||||
|
if !MoveValidator.isLegal(board, history, from, to) then MoveResult.IllegalMove
|
||||||
|
else if MoveValidator.isPromotionMove(board, from, to) then
|
||||||
|
MoveResult.PromotionRequired(from, to, board, history, board.pieceAt(to), turn)
|
||||||
|
else applyNormalMove(board, history, turn, from, to)
|
||||||
|
|
||||||
|
private def applyNormalMove(board: Board, history: GameHistory, turn: Color, from: Square, to: Square): MoveResult =
|
||||||
|
val castleOpt = Option.when(MoveValidator.isCastle(board, from, to))(MoveValidator.castleSide(from, to))
|
||||||
|
val isEP = EnPassantCalculator.isEnPassant(board, history, from, to)
|
||||||
|
val (newBoard, captured) = castleOpt match
|
||||||
|
case Some(side) => (board.withCastle(turn, side), None)
|
||||||
|
case None =>
|
||||||
|
val (b, cap) = board.withMove(from, to)
|
||||||
|
if isEP then
|
||||||
|
val capturedSq = EnPassantCalculator.capturedPawnSquare(to, turn)
|
||||||
|
(b.removed(capturedSq), board.pieceAt(capturedSq))
|
||||||
|
else (b, cap)
|
||||||
|
val newHistory = history.addMove(from, to, castleOpt)
|
||||||
|
toMoveResult(newBoard, newHistory, captured, turn)
|
||||||
|
|
||||||
|
private def toMoveResult(newBoard: Board, newHistory: GameHistory, captured: Option[Piece], turn: Color): MoveResult =
|
||||||
GameRules.gameStatus(newBoard, newHistory, turn.opposite) match
|
GameRules.gameStatus(newBoard, newHistory, turn.opposite) match
|
||||||
case PositionStatus.Normal => MoveResult.Moved(newBoard, newHistory, captured, turn.opposite)
|
case PositionStatus.Normal => MoveResult.Moved(newBoard, newHistory, captured, turn.opposite)
|
||||||
case PositionStatus.InCheck => MoveResult.MovedInCheck(newBoard, newHistory, captured, turn.opposite)
|
case PositionStatus.InCheck => MoveResult.MovedInCheck(newBoard, newHistory, captured, turn.opposite)
|
||||||
|
|||||||
Reference in New Issue
Block a user