Beispiel #1
0
        /// <summary>
        /// Verifies if a piece attacks a square. This method does not check if the piece on "from"
        /// on the board is of the same type as this FlyweightPiece represents.
        /// </summary>
        /// <param name="board">Board to check attacking on.</param>
        /// <param name="from">Square on which attacking piece is placed.</param>
        /// <param name="to">The square to check if attacked.</param>
        /// <returns>True if a FlyweightPiece placed on "from" square attacks the "to" square. False otherwise.</returns>
        public bool Attacks(Board board, Square from, Square to)
        {
            if (Math.Abs(Board.File(from) - Board.File(to)) == Math.Abs(Board.Rank(from) - Board.Rank(to)))
            {
                return(board.IsPathClear(from, to));
            }

            return(false);
        }
Beispiel #2
0
        /// <summary>
        /// Verifies if a piece attacks a square. This method does not check if the piece on "from"
        /// on the board is of the same type as this FlyweightPiece represents.
        /// </summary>
        /// <param name="board">Board to check attacking on.</param>
        /// <param name="from">Square on which attacking piece is placed.</param>
        /// <param name="to">The square to check if attacked.</param>
        /// <returns>True if a FlyweightPiece placed on "from" square attacks the "to" square. False otherwise.</returns>
        public bool Attacks(Board board, Square from, Square to)
        {
            if (Board.File(from) != Board.File(to) &&
                Board.Rank(from) != Board.Rank(to) &&
                (Math.Abs(Board.File(from) - Board.File(to)) + Math.Abs(Board.Rank(from) - Board.Rank(to))) == 3)
            {
                return(true);
            }

            return(false);
        }
Beispiel #3
0
        /// <summary>
        /// XOR's an En-Passant target into the Zobrist key.
        /// </summary>
        public void HashFlipEnPassantTarget(Square square)
        {
            if (Board.Rank(square) == 3)
            {
                m_key  ^= ZobristValues.Keys[1541 + Board.File(square)];
                m_lock ^= ZobristValues.Locks[1541 + Board.File(square)];
            }

            if (Board.Rank(square) == 4)
            {
                m_key  ^= ZobristValues.Keys[1549 + Board.File(square)];
                m_lock ^= ZobristValues.Locks[1549 + Board.File(square)];
            }
        }
Beispiel #4
0
        /// <summary>
        /// Verifies if a piece attacks a square. This method does not check if the piece on "from"
        /// on the board is of the same type as this FlyweightPiece represents.
        /// </summary>
        /// <param name="board">Board to check attacking on.</param>
        /// <param name="from">Square on which attacking piece is placed.</param>
        /// <param name="to">The square to check if attacked.</param>
        /// <returns>True if a FlyweightPiece placed on "from" square attacks the "to" square. False otherwise.</returns>
        public bool Attacks(Board board, Square from, Square to)
        {
            if ((m_color == PieceColor.White && Board.Rank(to) == Board.Rank(from) + 1) ||
                (m_color == PieceColor.Black && Board.Rank(to) == Board.Rank(from) - 1))
            {
                if ((Math.Abs(Board.File(to) - Board.File(from)) == 1) &&
                    (board.GetPieceColor(to) != m_color))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #5
0
        /// <summary>
        /// Sets the hash value according to a board.
        /// </summary>
        /// <param name="board">The board a hash value will be generated for.</param>
        public void HashSet(Board board)
        {
            m_key  = 0;
            m_lock = 0;

            if (board != null)
            {
                foreach (Square square in board)
                {
                    if (board[square] != Piece.None)
                    {
                        m_key  ^= ZobristValues.Keys[((int)board[square] * 128) + (int)square];
                        m_lock ^= ZobristValues.Locks[((int)board[square] * 128) + (int)square];
                    }
                }

                if (board.State.ColorToPlay == PieceColor.White)
                {
                    m_key  ^= ZobristValues.Keys[1536];
                    m_lock ^= ZobristValues.Locks[1536];
                }

                if (board.State.WhiteCanCastleLong)
                {
                    m_key  ^= ZobristValues.Keys[1537];
                    m_lock ^= ZobristValues.Locks[1537];
                }

                if (board.State.WhiteCanCastleShort)
                {
                    m_key  ^= ZobristValues.Keys[1538];
                    m_lock ^= ZobristValues.Locks[1538];
                }

                if (board.State.BlackCanCastleLong)
                {
                    m_key  ^= ZobristValues.Keys[1539];
                    m_lock ^= ZobristValues.Locks[1539];
                }

                if (board.State.BlackCanCastleShort)
                {
                    m_key  ^= ZobristValues.Keys[1540];
                    m_lock ^= ZobristValues.Locks[1540];
                }


                if (board.State.EnPassantTarget != Square.None)
                {
                    if (Board.Rank(board.State.EnPassantTarget) == 3)
                    {
                        m_key  ^= ZobristValues.Keys[1541 + Board.File(board.State.EnPassantTarget)];
                        m_lock ^= ZobristValues.Locks[1541 + Board.File(board.State.EnPassantTarget)];
                    }

                    if (Board.Rank(board.State.EnPassantTarget) == 4)
                    {
                        m_key  ^= ZobristValues.Keys[1549 + Board.File(board.State.EnPassantTarget)];
                        m_lock ^= ZobristValues.Locks[1549 + Board.File(board.State.EnPassantTarget)];
                    }
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Generate moves a FlyweightPiece can make.
        /// This method does not varifies if a move puts its own king in check.
        /// This is done in MoveOrganizer when adding a move.
        /// </summary>
        /// <param name="board">Board to generate moves for.</param>
        /// <param name="location">Location of the piece.</param>
        /// <param name="moves">Container class to which all generated moves are added.</param>
        public void GenerateMoves(Board board, Square location, MoveOrganizer moves)
        {
            if (m_color == board.State.ColorToPlay)
            {
                for (int i = 0; i < m_directions.Length; i++)
                {
                    m_iterator.Reset(board, location, m_directions[i]);
                    if (m_iterator.Next())
                    {
                        if (m_iterator.CurrentPiece() == Piece.None &&
                            (m_iterator.CurrentDirection() == Direction.Up || m_iterator.CurrentDirection() == Direction.Down))
                        {
                            //Non hitting moves
                            switch (Board.Rank(m_iterator.CurrentSquare()))
                            {
                            case 0:
                                //Black non hitting promotion move
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.BlackBishop));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.BlackKnight));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.BlackQueen));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.BlackRook));
                                break;

                            case 7:
                                //White non hitting promotion move
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.WhiteBishop));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.WhiteKnight));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.WhiteQueen));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.WhiteRook));
                                break;

                            default:
                                //Basic non hitting move
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare()));
                                break;
                            }

                            if ((Board.Rank(m_iterator.CurrentSquare()) == 2 && m_iterator.CurrentDirection() == Direction.Up) ||
                                (Board.Rank(m_iterator.CurrentSquare()) == 5 && m_iterator.CurrentDirection() == Direction.Down))
                            {   //Two squares forward opening move
                                m_iterator.Next();
                                if (m_iterator.CurrentPiece() == Piece.None)
                                {
                                    moves.Add(new Move(board, location, m_iterator.CurrentSquare()));
                                }
                            }
                        }
                        else if (m_iterator.CurrentPiece() != Piece.None && m_iterator.CurrentPieceColor() != m_color &&
                                 m_iterator.CurrentDirection() != Direction.Up && m_iterator.CurrentDirection() != Direction.Down)
                        {
                            //Hitting moves
                            switch (Board.Rank(m_iterator.CurrentSquare()))
                            {
                            case 0:
                                //Black hitting promotion move
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.BlackBishop));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.BlackKnight));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.BlackQueen));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.BlackRook));
                                break;

                            case 7:
                                //White hitting promotion move
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.WhiteBishop));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.WhiteKnight));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.WhiteQueen));
                                moves.Add(new PawnPromotionMove(board, location, m_iterator.CurrentSquare(), Piece.WhiteRook));
                                break;

                            default:
                                //Basic hitting move
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare()));
                                break;
                            }
                        }
                    }
                }

                //EnPassant moves
                if (board.State.EnPassantTarget != Square.None &&
                    Math.Abs(board.State.EnPassantTarget - location) == 1 &&
                    Board.Rank(board.State.EnPassantTarget) == Board.Rank(location))
                {
                    switch (m_color)
                    {
                    case PieceColor.White:
                        moves.Add(new EnPassantCaptureMove(board, location, Board.Position(Board.File(board.State.EnPassantTarget), Board.Rank(location) + 1)));
                        break;

                    case PieceColor.Black:
                        moves.Add(new EnPassantCaptureMove(board, location, Board.Position(Board.File(board.State.EnPassantTarget), Board.Rank(location) - 1)));
                        break;
                    }
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Moves the iterator to the next square.
        /// </summary>
        /// <returns>True if if the new square is a valid and existing square. False otherwise.</returns>
        public bool Next()
        {
            switch (m_direction)
            {
            case Direction.Up:
                if (Board.Rank(m_currentSquare) == Board.NOF_SIDE_SQUARS - 1)
                {
                    return(false);
                }

                m_currentSquare += 8;
                return(true);

            case Direction.UpRight:
                if (Board.Rank(m_currentSquare) == Board.NOF_SIDE_SQUARS - 1 ||
                    Board.File(m_currentSquare) == Board.NOF_SIDE_SQUARS - 1)
                {
                    return(false);
                }

                m_currentSquare += 9;
                return(true);

            case Direction.Right:
                if (Board.File(m_currentSquare) == Board.NOF_SIDE_SQUARS - 1)
                {
                    return(false);
                }

                m_currentSquare += 1;
                return(true);

            case Direction.DownRight:
                if (Board.Rank(m_currentSquare) == 0 ||
                    Board.File(m_currentSquare) == Board.NOF_SIDE_SQUARS - 1)
                {
                    return(false);
                }

                m_currentSquare -= 7;
                return(true);

            case Direction.Down:
                if (Board.Rank(m_currentSquare) == 0)
                {
                    return(false);
                }

                m_currentSquare -= 8;
                return(true);

            case Direction.DownLeft:
                if (Board.Rank(m_currentSquare) == 0 ||
                    Board.File(m_currentSquare) == 0)
                {
                    return(false);
                }

                m_currentSquare -= 9;
                return(true);

            case Direction.Left:
                if (Board.File(m_currentSquare) == 0)
                {
                    return(false);
                }

                m_currentSquare -= 1;
                return(true);

            case Direction.UpLeft:
                if (Board.Rank(m_currentSquare) == Board.NOF_SIDE_SQUARS - 1 ||
                    Board.File(m_currentSquare) == 0)
                {
                    return(false);
                }

                m_currentSquare += 7;
                return(true);

            case Direction.NoDirection:
            default:
                return(false);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Generate moves a FlyweightPiece can make.
        /// This method does not varifies if a move puts its own king in check.
        /// This is done by a move when its carried out.
        /// </summary>
        /// <param name="board">Board to generate moves for.</param>
        /// <param name="location">Location of the piece.</param>
        /// <param name="moves">Container class to which all generated moves are added.</param>
        public void GenerateMoves(Board board, Square location, MoveOrganizer moves)
        {
            if (m_color == board.State.ColorToPlay)
            {
                //Non hitting moves
                m_iterator.Reset(board, location, m_directions[0]);
                if (m_iterator.Next())
                {
                    if (m_iterator.CurrentPiece() == Piece.None)
                    {
                        switch (Board.Rank(m_iterator.CurrentSquare()))
                        {
                        case 0:
                            //Black non hitting promotion move
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.BlackBishop));
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.BlackKnight));
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.BlackQueen));
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.BlackRook));
                            break;

                        case 7:
                            //White non hitting promotion move
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.WhiteBishop));
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.WhiteKnight));
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.WhiteQueen));
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.WhiteRook));
                            break;

                        default:
                            //Basic non hitting move
                            moves.Add(new Move(board, location, m_iterator.CurrentSquare()));
                            break;
                        }

                        //Two squares forward opening move
                        if (Board.Rank(m_iterator.CurrentSquare()) == moveAgainRow)
                        {
                            m_iterator.Next();
                            if (m_iterator.CurrentPiece() == Piece.None)
                            {
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare()));
                            }
                        }
                    }
                }

                //Hitting moves to the left and right
                for (int i = 1; i < m_directions.Length; ++i)
                {
                    m_iterator.Reset(board, location, m_directions[i]);
                    if (m_iterator.Next())
                    {
                        if (m_iterator.CurrentPieceColor() == m_opponentColor)
                        {
                            switch (Board.Rank(m_iterator.CurrentSquare()))
                            {
                            case 0:
                                //Black hitting promotion move
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.BlackBishop));
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.BlackKnight));
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.BlackQueen));
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.BlackRook));
                                break;

                            case 7:
                                //White hitting promotion move
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.WhiteBishop));
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.WhiteKnight));
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.WhiteQueen));
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare(), Piece.WhiteRook));
                                break;

                            default:
                                //Basic hitting move
                                moves.Add(new Move(board, location, m_iterator.CurrentSquare()));
                                break;
                            }
                        }
                    }
                }

                //EnPassant moves
                if (Math.Abs(board.State.EnPassantTarget - location) == 1)
                {
                    switch (m_color)
                    {
                    case PieceColor.White:
                        moves.Add(new Move(board, location, Board.Position(Board.File(board.State.EnPassantTarget), Board.Rank(location) + 1), board.State.EnPassantTarget));
                        break;

                    case PieceColor.Black:
                        moves.Add(new Move(board, location, Board.Position(Board.File(board.State.EnPassantTarget), Board.Rank(location) - 1), board.State.EnPassantTarget));
                        break;
                    }
                }
            }
        }