Esempio n. 1
0
        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);
        }
Esempio n. 2
0
 // TODO - consider removing
 //public Fingerprint Fingerprint { get; set; }
 public AnalysisNode(AnalysisNode parent, Position.Position p, Move m)
 {
     Debug.Assert(p != null);
     Parent = parent;
     // Must init ParentMove before Position
     m_parent_move = m;
     Position = p;
     Children = null;
     IsWhiteToMove = p.IsWhiteToMove;
 }
Esempio n. 3
0
 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)));
     }
 }
Esempio n. 4
0
 public MoveDesc ToMoveDesc(Position child_position)
 {
     // TODO - consider null moves
     return new MoveDesc(Piece, new ChessboardCell(FromCell),
         new ChessboardCell(ToCell), PromoteToPiece, IsCapture, IsCheck,
         child_position.IsCheckmate);
 }
Esempio n. 5
0
 public void Reset(Position position)
 {
     Debug.Assert(position != null);
     Reset(position.GetPieces(Players.White),
         position.GetPieces(Players.Black));
 }
Esempio n. 6
0
        public Position PlayMove(Move move)
        {
            // 'My' refers to player to move, 'other' refers to other player
            var my_player = PlayerToMove;
            var other_player = Helper.GetOtherPlayer(my_player);

            var my_pieces = GetPieces(my_player);
            var other_pieces = GetPieces(other_player);

            PlayerPieceSet new_my_pieces = null;
            if (move.IsPromotion)
            {
                Debug.Assert(move.Piece == Exports.Pieces.Pawn);
                var tmp_pieces = PlayerPieceSet.RemovePiece(my_pieces,
                    Exports.Pieces.Pawn, move.FromCell);
                new_my_pieces = PlayerPieceSet.InsertPiece(tmp_pieces,
                    move.PromoteToPiece, move.ToCell);
            }
            else if (move.IsShortCastle || move.IsLongCastle)
            {
                int base_row = my_player == Players.White ?
                    Chessboard.ROW_MIN : Chessboard.ROW_MAX;
                Debug.Assert(move.Piece == Exports.Pieces.King);
                var tmp_pieces = PlayerPieceSet.MovePiece(my_pieces,
                    Exports.Pieces.King, move.FromCell, move.ToCell);

                if (move.IsShortCastle)
                {
                    new_my_pieces = PlayerPieceSet.MovePiece(tmp_pieces,
                        Exports.Pieces.Rook,
                        ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_H),
                        ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_F));
                }
                else
                {
                    new_my_pieces = PlayerPieceSet.MovePiece(tmp_pieces,
                        Exports.Pieces.Rook,
                        ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_A),
                        ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_D));
                }
            }
            else
            {
                new_my_pieces = PlayerPieceSet.MovePiece(my_pieces,
                    move.Piece, move.FromCell, move.ToCell);
            }

            PlayerPieceSet new_other_pieces = null;
            if (move.IsCapture)
            {
                Exports.Pieces piece_to_remove = Exports.Pieces.NoPiece;
                int remove_piece_at = 0;
                if (move.IsEnPassantCapture)
                {
                    var move_to_cell = new ChessboardCell(move.ToCell);
                    remove_piece_at = ChessboardCell.CalculateValue(
                        move_to_cell.Row + (IsWhiteToMove ? -1 : 1),
                        move_to_cell.Column);
                    // Only pawns can capture en passant
                    piece_to_remove = Exports.Pieces.Pawn;
                }
                else
                {
                    remove_piece_at = move.ToCell;
                    piece_to_remove = other_pieces.GetPieceAtCell(remove_piece_at);
                }
                new_other_pieces = PlayerPieceSet.RemovePiece(other_pieces,
                    piece_to_remove, remove_piece_at);
            }
            else
            {
                // No change to other player's pieces, re-use the object
                new_other_pieces = other_pieces;
            }

            // TODO - consider memory pooling here
            var result = new Position();
            var new_white_pieces =
                IsWhiteToMove ? new_my_pieces : new_other_pieces;
            var new_black_pieces =
                IsWhiteToMove ? new_other_pieces : new_my_pieces;

            int? new_en_passant_capture_column = null;
            if (move.Piece == Exports.Pieces.Pawn)
            {
                var from = new ChessboardCell(move.FromCell);
                var to_row = new ChessboardCell(move.ToCell).Row;
                if (Math.Abs(from.Row - to_row) == 2)
                {
                    new_en_passant_capture_column = from.Column;
                }
            }

            var new_fullmove_number = FullmoveNumber;
            if (other_player == Players.White)
            {
                ++new_fullmove_number;
            }

            var new_halfmove_clock = HalfmoveClock + 1;
            if (move.Piece == Exports.Pieces.Pawn || move.IsCapture)
            {
                new_halfmove_clock = 0;
            }

            var new_white_castling_options = CalcNewCastlingOptions(Players.White,
                new_white_pieces, Chessboard.ROW_MIN);
            var new_black_castling_options = CalcNewCastlingOptions(Players.Black,
                new_black_pieces, Chessboard.ROW_MAX);

            result.Reset(new_white_pieces,
                new_black_pieces,
                other_player,
                new_white_castling_options,
                new_black_castling_options,
                new_en_passant_capture_column,
                new_fullmove_number,
                (ushort)new_halfmove_clock);

            return result;
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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;
        }
Esempio n. 9
0
 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);
 }
Esempio n. 10
0
 public void SetCurrentPosition(Position.Position p)
 {
     // TODO - stop ongoing analysis somehow
     m_tree.SetRoot(p, Move.NULL_MOVE);
     CurrentGame = new Game();
     CurrentGame.m_initial_position = p == null ? Fen.InitialPosition
         : Fen.Encode(p);
 }
Esempio n. 11
0
 public void RootPositionChanged(Position.Position root_position)
 {
     CurrentPosition = root_position;
     m_stats = null;
 }
Esempio n. 12
0
        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));
            }
        }