protected void AssertMove(string expected, ChessboardCell from,
     ChessboardCell to)
 {
     var move = m_engine.GetLegalMove(from, to);
     Assert.IsNotNull(move);
     Factory.Instance.CreateCommand(Commands.PlayMove, move).Execute(m_engine);
     Assert.AreEqual(expected, move.ToString(Notation.LongAlgebraic));
 }
 public bool IsPieceAt(ChessboardCell cell, out Players player,
     out Exports.Pieces piece)
 {
     int data = m_cells[cell.Value];
     player = (Players)DecodePlayer(data);
     piece = (Exports.Pieces)DecodePiece(data);
     return piece != Exports.Pieces.NoPiece;
 }
Beispiel #3
0
 public PiecePosition(Players player, Pieces piece, ChessboardCell cell)
 {
     Debug.Assert(cell.Row >= Chessboard.ROW_MIN
         && cell.Row <= Chessboard.ROW_MAX);
     Debug.Assert(cell.Column >= Chessboard.COLUMN_MIN &&
         cell.Column <= Chessboard.COLUMN_MAX);
     m_player = player;
     m_piece = piece;
     m_cell = cell;
 }
Beispiel #4
0
 public MoveDesc GetLegalMove(ChessboardCell from, ChessboardCell to)
 {
     lock (m_legal_moves_lock)
     {
         return m_legal_moves?.Find(x =>
             x.From.IsSame(from)
             && x.To.IsSame(to)
             && !x.IsPromotion);
     }
 }
Beispiel #5
0
 // TODO - add parameters
 public MoveDesc(Pieces piece, ChessboardCell from, ChessboardCell to,
     Pieces promote_to, bool is_capture, bool is_check, bool is_checkmate)
 {
     Debug.Assert(piece != Pieces.NoPiece);
     Debug.Assert(!from.IsSame(to));
     Debug.Assert(!(is_checkmate && !is_check));
     m_piece = piece;
     m_from = from;
     m_to = to;
     m_promote_to = promote_to;
     m_is_capture = is_capture;
     m_is_check = is_check;
     m_is_checkmate = is_checkmate;
 }
 private static void FillLines(ulong[] masks, int move_delta_row,
     int move_delta_column)
 {
     for (int i = 0; i < masks.Length; ++i)
     {
         var cell = new ChessboardCell(i);
         int cur_row = cell.Row;
         int cur_column = cell.Column;
         while (cur_row >= Chessboard.ROW_MIN && cur_row <= Chessboard.ROW_MAX
             && cur_column >= Chessboard.COLUMN_MIN
             && cur_column <= Chessboard.COLUMN_MAX)
         {
             masks[i] |= (1UL << cell.Value);
             cur_row += move_delta_row;
             cur_column += move_delta_column;
         }
     }
 }
        // TODO - should we have this for a king as well?
        static PieceEvaluationMasks()
        {
            FillPawnValues(m_white_pawn, 1);
            FillPawnValues(m_black_pawn, -1);

            for (int i = 0; i < m_knight.Length; ++i)
            {
                var cell = new ChessboardCell(i);
                m_knight[i] = (1UL << i);
                foreach (var move_delta in Position.MovesGenerator.m_knight_moves)
                {
                    int new_row = cell.Row + move_delta.m_delta_row;
                    int new_column = cell.Column + move_delta.m_delta_column;
                    if (new_row >= Chessboard.ROW_MIN && new_row <= Chessboard.ROW_MAX
                        && new_column >= Chessboard.COLUMN_MIN
                        && new_column <= Chessboard.COLUMN_MAX)
                    {
                        int new_index = ChessboardCell.CalculateValue(new_row,
                            new_column);
                        m_knight[i] |= (1UL << new_index);
                    }
                }
            }

            FillLines(m_bishop, -1, -1);
            FillLines(m_bishop, -1, 1);
            FillLines(m_bishop, 1, -1);
            FillLines(m_bishop, 1, 1);

            FillLines(m_rook, -1, 0);
            FillLines(m_rook, 0, -1);
            FillLines(m_rook, 0, 1);
            FillLines(m_rook, 1, 0);

            for (int i = 0; i < m_queen.Length; ++i)
            {
                m_queen[i] = m_bishop[i] | m_rook[i];
            }
        }
 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 static bool IsRookAttacks(ChessboardCell rook_cell,
     ChessboardCell cell_to_check, PlayerPieceSet my_pieces,
     PlayerPieceSet other_pieces)
 {
     return (rook_cell.Row == cell_to_check.Row
         || rook_cell.Column == cell_to_check.Column)
         && IsCellAttackedFromDir(cell_to_check, rook_cell,
             my_pieces, other_pieces);
 }
Beispiel #10
0
 public static bool IsBishopAttacks(ChessboardCell bishop_cell,
     ChessboardCell cell_to_check, PlayerPieceSet my_pieces,
     PlayerPieceSet other_pieces)
 {
     return bishop_cell.IsSameDiagonal(cell_to_check)
         && IsCellAttackedFromDir(cell_to_check, bishop_cell,
         my_pieces, other_pieces);
 }
Beispiel #11
0
 public static bool IsKnightAttacks(ChessboardCell knight_cell,
     ChessboardCell cell_to_check)
 {
     int delta_row = Math.Abs(knight_cell.Row - cell_to_check.Row);
     // Slightly optimized version of
     // if ((delta_row == 1 && delta_column == 2)
     //     || (delta_row == 2 && delta_column == 1))
     if (delta_row == 1 || delta_row == 2)
     {
         int delta_column = Math.Abs(knight_cell.Column - cell_to_check.Column);
         if (delta_row + delta_column == 3)
         {
             return true;
         }
     }
     return false;
 }
Beispiel #12
0
 public static bool IsPawnAttacks(ChessboardCell pawn_cell,
     ChessboardCell cell_to_check, int pawn_move_row_delta)
 {
     return ((pawn_cell.Row + pawn_move_row_delta == cell_to_check.Row)
         && (cell_to_check.Column == pawn_cell.Column - 1
         || cell_to_check.Column == pawn_cell.Column + 1));
 }
Beispiel #13
0
 public bool IsNeighbour(ChessboardCell other)
 {
     return Math.Abs(Row - other.Row) <= 1 && Math.Abs(Column - other.Column) <= 1;
 }
Beispiel #14
0
 public MoveDesc GetLegalMove(ChessboardCell from, ChessboardCell to,
     Pieces promote_to)
 {
     return m_analyzer.GetLegalMove(from, to, promote_to);
 }
Beispiel #15
0
        public static bool IsCellAttackedFromDir(ChessboardCell attacked_cell,
            ChessboardCell attack_origin, PlayerPieceSet attacker_pieces,
            PlayerPieceSet defender_pieces)
        {
            Debug.Assert(!attacked_cell.IsSame(attack_origin));
            int delta_row = attack_origin.Row - attacked_cell.Row;
            int delta_column = attack_origin.Column - attacked_cell.Column;

            // Fast check if the two cells are on the same vertical or horizontal line
            // or one the same diagonal
            if (delta_row != 0 && delta_column != 0 && delta_row != delta_column
                && delta_row != -delta_column)
            {
                return false;
            }

            // Check the ray from attacked_cell towards attack_origin and possibly behind
            // attack_origin until we reach the edge of the chessboard
            bool result = false;
            int row_inc = 0;
            int column_inc = 0;
            int iter_count = int.MaxValue;
            if (delta_row < 0)
            {
                row_inc = -1;
                iter_count = attacked_cell.Row - Chessboard.ROW_MIN;
            }
            else if (delta_row > 0)
            {
                row_inc = 1;
                iter_count = Chessboard.ROW_MAX - attacked_cell.Row;
            }
            if (delta_column < 0)
            {
                column_inc = -1;
                iter_count = Math.Min(iter_count,
                    attacked_cell.Column - Chessboard.COLUMN_MIN);
            }
            else if (delta_column > 0)
            {
                column_inc = 1;
                iter_count = Math.Min(iter_count,
                    Chessboard.COLUMN_MAX - attacked_cell.Column);
            }

            int cur_row = attacked_cell.Row;
            int cur_column = attacked_cell.Column;

            for (int i = 0; i < iter_count; ++i)
            {
                cur_row += row_inc;
                cur_column += column_inc;

                Debug.Assert(cur_row >= Chessboard.ROW_MIN
                    && cur_row <= Chessboard.ROW_MAX
                    && cur_column >= Chessboard.COLUMN_MIN
                    && cur_column <= Chessboard.COLUMN_MAX);
                int cur_cell = ChessboardCell.CalculateValue(cur_row, cur_column);
                if (defender_pieces.IsOccupiedCell(cur_cell))
                {
                    result = false;
                    break;
                }
                if (attacker_pieces.IsOccupiedCell(cur_cell))
                {
                    if (attacker_pieces.IsQueenAtCell(cur_cell))
                    {
                        result = true;
                    }
                    else if (row_inc == 0 || column_inc == 0)
                    {
                        result = attacker_pieces.IsRookAtCell(cur_cell);
                    }
                    else
                    {
                        result = attacker_pieces.IsBishopAtCell(cur_cell);
                    }
                    break;
                }
            }

            return result;
        }
Beispiel #16
0
        public bool MakeChildNewRoot(ChessboardCell from, ChessboardCell to,
            Exports.Pieces promote_to = Exports.Pieces.NoPiece)
        {
            if (Root == null)
            {
                return false;
            }

            // Discard all root children and their subtrees, except the child
            // specified by the method parameters
            ReleaseChildren(child =>
            {
                return child.ParentMove.FromCell != from.Value
                    || child.ParentMove.ToCell != to.Value
                    || child.ParentMove.PromoteToPiece != promote_to;
            }, Root);

            if (Root.Children.Count != 1)
            {
                Clean();
                m_listener.RootPositionChanged(null);
                return false;
            }

            // Discard current root
            Interlocked.Decrement(ref m_node_count);

            // Set a new root
            Root = Root.Children[0];
            m_listener.RootPositionChanged(Root.Position);
            GenerateAllChildren(Root, 2);
            return true;
        }
Beispiel #17
0
 public MoveDesc GetLegalMove(ChessboardCell from, ChessboardCell to,
     Exports.Pieces promote_to)
 {
     lock (m_legal_moves_lock)
     {
         return m_legal_moves?.Find(x =>
             x.From.IsSame(from)
             && x.To.IsSame(to)
             && x.IsPromotion
             && x.PromoteTo == promote_to);
     }
 }
Beispiel #18
0
        public static string Encode(IReadOnlyPosition position,
            EncodingOptions options = EncodingOptions.None)
        {
            Debug.Assert(position != null);
            var s = new StringBuilder(80);
            // Encode the chessboard
            var board = Factory.Instance.CreateChessboardArray(position);
            for (int row = Chessboard.ROW_MAX; row >= Chessboard.ROW_MIN; --row)
            {
                int empty_cells = 0;
                for (int column = Chessboard.COLUMN_MIN;
                    column <= Chessboard.COLUMN_MAX; ++column)
                {
                    var cur_cell = new ChessboardCell(row, column);
                    Players player;
                    Pieces piece;
                    if (board.IsPieceAt(cur_cell, out player, out piece))
                    {
                        if (empty_cells != 0)
                        {
                            s.Append(empty_cells);
                            empty_cells = 0;
                        }
                        s.Append(PieceToChar(player, piece));
                    }
                    else
                    {
                        ++empty_cells;
                    }
                }
                if (empty_cells != 0)
                {
                    s.Append(empty_cells);
                    empty_cells = 0;
                }
                if (row != Chessboard.ROW_MIN)
                {
                    s.Append(ROWS_SEPARATOR);
                }
            }

            // Encode player to move
            s.Append(' ');
            s.Append(position.IsWhiteToMove ? FEN_WHITE_TO_MOVE : FEN_BLACK_TO_MOVE);

            // Encode castling availability
            s.Append(' ');
            if (!position.IsCanCastleShort(Players.White)
                && !position.IsCanCastleLong(Players.White)
                && !position.IsCanCastleShort(Players.Black)
                && !position.IsCanCastleLong(Players.Black))
            {
                s.Append(FEN_NO_ONE_CAN_CASTLE);
            }
            else
            {
                if (position.IsCanCastleShort(Players.White))
                {
                    s.Append(FEN_WHITE_CAN_CASTLE_SHORT);
                }
                if (position.IsCanCastleLong(Players.White))
                {
                    s.Append(FEN_WHITE_CAN_CASTLE_LONG);
                }
                if (position.IsCanCastleShort(Players.Black))
                {
                    s.Append(FEN_BLACK_CAN_CASTLE_SHORT);
                }
                if (position.IsCanCastleLong(Players.Black))
                {
                    s.Append(FEN_BLACK_CAN_CASTLE_LONG);
                }
            }

            // Encode en passant caputre possibility
            s.Append(' ');
            int? capture_en_passant_column = position.CaptureEnPassantColumn;
            if (capture_en_passant_column.HasValue)
            {
                var cell = new ChessboardCell(position.IsWhiteToMove ? 5 : 2,
                    capture_en_passant_column.Value);
                s.Append(cell.ToString());
            }
            else
            {
                s.Append(FEN_CANNOT_CAPTURE_EN_PASSANT);
            }

            s.Append(' ').Append(position.HalfmoveClock);

            s.Append(' ').Append(options.HasFlag(EncodingOptions.SetMovesCountToOne)
                ? 1 : position.FullmoveNumber);

            return s.ToString();
        }
Beispiel #19
0
 public bool IsSameDiagonal(ChessboardCell other)
 {
     int delta_row = Row - other.Row;
     int delta_column = Column - other.Column;
     return delta_row == delta_column || delta_row == -delta_column;
 }
Beispiel #20
0
 public bool IsSame(ChessboardCell other)
 {
     return m_row == other.m_row && m_column == other.m_column;
 }
Beispiel #21
0
 public static bool IsQueenAttacks(ChessboardCell queen_cell,
     ChessboardCell cell_to_check, PlayerPieceSet my_pieces,
     PlayerPieceSet other_pieces)
 {
     return IsBishopAttacks(queen_cell, cell_to_check, my_pieces, other_pieces)
         || IsRookAttacks(queen_cell, cell_to_check, my_pieces, other_pieces);
 }
 private static void FillPawnValues(ulong[] pawn, int move_row_delta)
 {
     for (int i = 0; i < pawn.Length; ++i)
     {
         var cell = new ChessboardCell(i);
         if (cell.Row != Chessboard.ROW_MIN && cell.Row != Chessboard.ROW_MAX)
         {
             if (cell.Column > Chessboard.COLUMN_MIN)
             {
                 int new_cell = ChessboardCell.CalculateValue(
                     cell.Row + move_row_delta, cell.Column - 1);
                 pawn[i] |= (1UL << new_cell);
             }
             if (cell.Column < Chessboard.COLUMN_MAX)
             {
                 int new_cell = ChessboardCell.CalculateValue(
                     cell.Row + move_row_delta, cell.Column + 1);
                 pawn[i] |= (1UL << new_cell);
             }
         }
     }
 }
Beispiel #23
0
 public static bool IsKingAttacks(ChessboardCell king_cell,
     ChessboardCell cell_to_check)
 {
     return cell_to_check.IsNeighbour(king_cell);
 }
Beispiel #24
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;
        }
Beispiel #25
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;
        }
Beispiel #26
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);
        }
Beispiel #27
0
 private static void WritePawnMove(int from_cell, int to_cell, uint cell_index,
     Move.Flags flags, List<Move> moves)
 {
     var to_cell_obj = new ChessboardCell(to_cell);
     if (to_cell_obj.Row == Chessboard.ROW_MIN
         || to_cell_obj.Row == Chessboard.ROW_MAX)
     {
         foreach (var promotion in m_pawn_promotions)
         {
             moves.Add(new Move(from_cell, to_cell,
                 flags | Move.Flags.Promotion, promotion));
         }
     }
     else
     {
         moves.Add(new Move(Exports.Pieces.Pawn, from_cell, to_cell,
             cell_index, flags));
     }
 }
Beispiel #28
0
 public int CompareTo(ChessboardCell other)
 {
     return Value.CompareTo(other.Value);
 }
Beispiel #29
0
 protected void PlayMove(ChessboardCell from, ChessboardCell to,
     Pieces promote_to)
 {
     Factory.Instance.CreateCommand(Commands.PlayMove,
         m_engine.GetLegalMove(from, to, promote_to)).Execute(m_engine);
 }
Beispiel #30
0
        private static void MakePawnMoves(PlayerPieceSet my_pieces, PlayerPieceSet other_pieces,
            bool is_white_to_move, int? en_passant_capture_column, List<Move> moves)
        {
            int move_row_diff = is_white_to_move ? 1 : -1;
            for (uint i = 0, e = my_pieces.PawnsCount; i < e; ++i)
            {
                uint cell_index;
                var pawn_cell = new ChessboardCell(my_pieces.GetPawnCell(i,
                    out cell_index));
                var new_cell_value = ChessboardCell.CalculateValue(
                    pawn_cell.Row + move_row_diff, pawn_cell.Column);

                // Moves without captures
                if (!my_pieces.IsOccupiedCell(new_cell_value)
                    && !other_pieces.IsOccupiedCell(new_cell_value))
                {
                    WritePawnMove(pawn_cell.Value, new_cell_value, cell_index, 0,
                        moves);
                    // Two-rows move from the initial rank
                    int initial_row = is_white_to_move ? Chessboard.ROW_MIN + 1
                        : Chessboard.ROW_MAX - 1;
                    if (pawn_cell.Row == initial_row)
                    {
                        new_cell_value = ChessboardCell.CalculateValue(
                            pawn_cell.Row + 2 * move_row_diff, pawn_cell.Column);
                        if (!my_pieces.IsOccupiedCell(new_cell_value)
                            && !other_pieces.IsOccupiedCell(new_cell_value))
                        {
                            WritePawnMove(pawn_cell.Value, new_cell_value, cell_index,
                                0, moves);
                        }
                    }
                }

                // Captures except en passant captures
                // delta_column can be -1 or 1
                for (int delta_column = -1; delta_column <= 1; delta_column += 2)
                {
                    int new_column = pawn_cell.Column + delta_column;
                    if (new_column >= Chessboard.COLUMN_MIN
                        && new_column <= Chessboard.COLUMN_MAX)
                    {
                        new_cell_value = ChessboardCell.CalculateValue(pawn_cell.Row
                            + move_row_diff, new_column);
                        if (other_pieces.IsOccupiedCell(new_cell_value))
                        {
                            WritePawnMove(pawn_cell.Value, new_cell_value, cell_index,
                                Move.Flags.Capture, moves);
                        }
                    }
                }

                // En passant capture
                if (en_passant_capture_column.HasValue
                    && ((is_white_to_move && pawn_cell.Row == 4)
                        || (!is_white_to_move && pawn_cell.Row == 3))
                    && Math.Abs(pawn_cell.Column - en_passant_capture_column.Value) == 1)
                {
                    new_cell_value = ChessboardCell.CalculateValue(pawn_cell.Row
                        + move_row_diff, en_passant_capture_column.Value);
                    // Since en passant capture is allowed, we know that the destination
                    // cell is not occupied
                    WritePawnMove(pawn_cell.Value, new_cell_value, cell_index,
                        Move.Flags.Capture | Move.Flags.EnPassantCapture, moves);
                }

                // TODO - add en passant captures
                // TODO - uncomment
                //throw new NotImplementedException();
            }
        }