public static void GenerateMoves(Position position, List<Move> moves) { Debug.Assert(position != null); Debug.Assert(moves != null); Debug.Assert(moves.Count == 0); var my_pieces = position.GetPieces(position.PlayerToMove); var other_pieces = position.GetPieces( Helper.GetOtherPlayer(position.PlayerToMove)); // King's moves MakeKingMoves(my_pieces, other_pieces, moves); // Castle moves MakeCastleMoves(position, moves); // Knights moves MakeKnightMoves(my_pieces, other_pieces, moves); // Pawns moves MakePawnMoves(my_pieces, other_pieces, position.IsWhiteToMove, position.CaptureEnPassantColumn, moves); // Rooks moves MakeRookMoves(my_pieces, other_pieces, moves); // Bishops moves MakeBishopMoves(my_pieces, other_pieces, moves); // Queens moves MakeQueeenMoves(my_pieces, other_pieces, moves); }
public static bool IsMyMovePutsMyKingInCheck(Players player_who_moved, Move m, Position.Position p, bool is_king_was_in_check_before_the_move) { Debug.Assert(!m.IsNullMove); if (is_king_was_in_check_before_the_move || m.Piece == Pieces.King) { // Cannot optimize - do a full check var king_cell = new ChessboardCell(p.GetPieces(player_who_moved).KingsCell); return PositionHelper.IsCellAttacked(king_cell, p.PlayerToMove, p); } else { // My king can only be attacked now along the line between the king // and the cell, from where my piece has moved var player_to_move = p.PlayerToMove; var king_cell = new ChessboardCell( p.GetPieces(Helper.GetOtherPlayer(player_to_move)).KingsCell); return PositionHelper.IsCellAttackedFromDir(king_cell, new ChessboardCell(m.FromCell), p.GetPieces(p.PlayerToMove), p.GetPieces(Helper.GetOtherPlayer(p.PlayerToMove))); } }
public void Reset(Position position) { Debug.Assert(position != null); Reset(position.GetPieces(Players.White), position.GetPieces(Players.Black)); }
public static bool IsMyMoveAttacksTheKing(Move m, Position position_after_move) { Debug.Assert(!m.IsSameCells(Move.NULL_MOVE)); var moved_to_cell = new ChessboardCell(m.ToCell); var kings_cell = new ChessboardCell(position_after_move.GetPieces( position_after_move.PlayerToMove).KingsCell); var attacking_player = Helper.GetOtherPlayer( position_after_move.PlayerToMove); var attacking_pieces = position_after_move.GetPieces(attacking_player); var defending_pieces = position_after_move.GetPieces( Helper.GetOtherPlayer(attacking_player)); // TODO // Check if the piece which moved attacks the king // Promotions shall be respected there switch (m.IsPromotion ? m.PromoteToPiece : m.Piece) { case Exports.Pieces.Pawn: int pawn_move_row_delta = attacking_player == Players.White ? 1 : -1; if (IsPawnAttacks(moved_to_cell, kings_cell, pawn_move_row_delta)) { return true; } break; case Exports.Pieces.Knight: if (IsKnightAttacks(moved_to_cell, kings_cell)) { return true; } break; case Exports.Pieces.Bishop: if (IsBishopAttacks(moved_to_cell, kings_cell, attacking_pieces, defending_pieces)) { return true; } break; case Exports.Pieces.Rook: if (IsRookAttacks(moved_to_cell, kings_cell, attacking_pieces, defending_pieces)) { return true; } break; case Exports.Pieces.Queen: if (IsQueenAttacks(moved_to_cell, kings_cell, attacking_pieces, defending_pieces)) { return true; } break; case Exports.Pieces.King: { // Castling can put opponent's king in check if (m.IsShortCastle || m.IsLongCastle) { var rook_cell = new ChessboardCell( moved_to_cell.Row, m.IsShortCastle ? Chessboard.COLUMN_F : Chessboard.COLUMN_C); if (IsRookAttacks(rook_cell, kings_cell, attacking_pieces, defending_pieces)) { return true; } } } break; } // Check if the piece behind the piece which moved attacks the king return IsCellAttackedFromDir(kings_cell, new ChessboardCell(m.FromCell), attacking_pieces, defending_pieces); }
public static bool IsCellAttacked(ChessboardCell cell, Players attacking_player, Position position) { Debug.Assert(position != null); var my_pieces = position.GetPieces(attacking_player); var other_pieces = position.GetPieces( Helper.GetOtherPlayer(attacking_player)); int pawn_move_row_delta = attacking_player == Players.White ? 1 : -1; for (uint i = 0, e = my_pieces.PawnsCount; i < e; ++i) { if (IsPawnAttacks(new ChessboardCell(my_pieces.GetPawnCell(i)), cell, pawn_move_row_delta)) { return true; } } for (uint i = 0, e = my_pieces.KnightsCount; i < e; ++i) { if (IsKnightAttacks(new ChessboardCell(my_pieces.GetKnightCell(i)), cell)) { return true; } } for (uint i = 0, e = my_pieces.BishopsCount; i < e; ++i) { if (IsBishopAttacks(new ChessboardCell(my_pieces.GetBishopCell(i)), cell, my_pieces, other_pieces)) { return true; } } for (uint i = 0, e = my_pieces.RooksCount; i < e; ++i) { if (IsRookAttacks(new ChessboardCell(my_pieces.GetRookCell(i)), cell, my_pieces, other_pieces)) { return true; } } for (uint i = 0, e = my_pieces.QueensCount; i < e; ++i) { if (IsQueenAttacks(new ChessboardCell(my_pieces.GetQueenCell(i)), cell, my_pieces, other_pieces)) { return true; } } if (IsKingAttacks(new ChessboardCell(my_pieces.KingsCell), cell)) { return true; } return false; }
public void SetRoot(Position.Position p, Move parent_move) { Clean(); if (p != null) { Root = new AnalysisNode(null, p, parent_move); m_node_count = 1; // Probably this position was not analyzed yet, and IsInCheck // is not initialized yet. Evaluate and set IsInCheck flag p.IsInCheck = PositionHelper.IsCellAttacked( new ChessboardCell(p.GetPieces(p.PlayerToMove).KingsCell), Helper.GetOtherPlayer(p.PlayerToMove), p); // For root we want to create children and grandchildren // To detect stalemate or checkmate GenerateAllChildren(Root, 2); } m_listener.RootPositionChanged(p); }
private static void MakeCastleMoves(Position p, List<Move> moves) { var player_to_move = p.PlayerToMove; var other_player = Helper.GetOtherPlayer(player_to_move); var my_pieces = p.GetPieces(player_to_move); int base_row = player_to_move == Players.White ? Chessboard.ROW_MIN : Chessboard.ROW_MAX; if (my_pieces.KingsCell != ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_E) || p.IsInCheck) { return; } if (p.IsCanCastleShort(player_to_move) && my_pieces.IsOccupiedCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_H)) && my_pieces.IsRookAtCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_H)) && p.IsEmptyCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_F)) && p.IsEmptyCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_G)) && !PositionHelper.IsCellAttacked( new ChessboardCell(base_row, Chessboard.COLUMN_F), other_player, p)) { moves.Add(new Move(Exports.Pieces.King, ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_E), ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_G), 0, Move.Flags.ShortCastle)); } if (p.IsCanCastleLong(player_to_move) && my_pieces.IsOccupiedCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_A)) && my_pieces.IsRookAtCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_A)) && p.IsEmptyCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_D)) && p.IsEmptyCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_C)) && p.IsEmptyCell(ChessboardCell.CalculateValue( base_row, Chessboard.COLUMN_B)) && !PositionHelper.IsCellAttacked( new ChessboardCell(base_row, Chessboard.COLUMN_D), other_player, p)) { moves.Add(new Move(Exports.Pieces.King, ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_E), ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_C), 0, Move.Flags.LongCastle)); } }