Exemplo n.º 1
0
        public ulong Hash(IPieceMap board, Colour colour)
        {
            var squares = (board.White | board.Black).ToList();

            ulong hash = 0ul;

            foreach (var square in squares)
            {
                var piece = PieceMapHelpers.GetPiece(board, square);

                hash ^= this.squares[square.ToSquareIndex(), (int)Index(piece)];
            }

            if (colour == Colour.White)
            {
                hash ^= colours[0];
            }
            else
            {
                hash ^= colours[1];
            }

            return(hash);
        }
Exemplo n.º 2
0
        public void MakeMove(uint move)
        {
            var colour           = move.GetColour();
            var fromSquare       = move.GetFrom();
            var fromSquareIndex  = move.GetFromIndex();
            var toSquare         = move.GetTo();
            var toSquareIndex    = move.GetToIndex();
            var moveType         = move.GetMoveType();
            var pieceType        = move.GetPieceType();
            var capturePieceType = move.GetCapturePieceType();

            // Copy current state
            var state = CurrentState.StateFlags;

            var enPassantSquare = (SquareFlag)0;

            if (moveType == MoveType.CastleKing)
            {
                if (colour == Colour.White)
                {
                    MakeWhiteKingSideCastle();
                }
                else
                {
                    MakeBlackKingSideCastle();
                }

                state = RemoveCastleAvailability(colour, state);
            }
            else if (moveType == MoveType.CastleQueen)
            {
                if (colour == Colour.White)
                {
                    MakeWhiteQueenSideCastle();
                }
                else
                {
                    MakeBlackQueenSideCastle();
                }

                state = RemoveCastleAvailability(colour, state);
            }
            else if (moveType == MoveType.EnPassant)
            {
                MovePiece(colour, pieceType, fromSquare, toSquare);

                // Capturing behind the opponent pawn so shift as if we are opponent
                var captureSquare = toSquare.PawnForward(colour.Opposite(), 1);

                RemovePiece(colour.Opposite(), captureSquare);
            }
            else if (moveType == MoveType.PromotionQueen)
            {
                if (capturePieceType != PieceType.None)
                {
                    RemovePiece(colour.Opposite(), toSquare);
                }

                MovePiece(colour, pieceType, fromSquare, toSquare);

                PromotePiece(colour, PieceType.Queen, toSquare);
            }
            else if (moveType == MoveType.PromotionRook)
            {
                if (capturePieceType != PieceType.None)
                {
                    RemovePiece(colour.Opposite(), toSquare);
                }

                MovePiece(colour, pieceType, fromSquare, toSquare);

                PromotePiece(colour, PieceType.Rook, toSquare);
            }
            else if (moveType == MoveType.PromotionBishop)
            {
                if (capturePieceType != PieceType.None)
                {
                    RemovePiece(colour.Opposite(), toSquare);
                }

                MovePiece(colour, pieceType, fromSquare, toSquare);

                PromotePiece(colour, PieceType.Bishop, toSquare);
            }
            else if (moveType == MoveType.PromotionKnight)
            {
                if (capturePieceType != PieceType.None)
                {
                    RemovePiece(colour.Opposite(), toSquare);
                }

                MovePiece(colour, pieceType, fromSquare, toSquare);

                PromotePiece(colour, PieceType.Knight, toSquare);
            }
            else if (pieceType == PieceType.Pawn)
            {
                // We can only move forward two from start square
                var toSquareTemp = fromSquare.PawnForward(colour, 2);

                // So if the 'to' square is the same it might set en passant flag
                if (toSquareTemp == toSquare)
                {
                    var targetSquare = (SquareFlag)((ulong)toSquare >> Math.Abs((int)MoveDirection.West));

                    var targetPiece = PieceMapHelpers.GetPiece(this, targetSquare);

                    if (targetPiece.Colour == colour.Opposite() && targetPiece.Type == PieceType.Pawn)
                    {
                        enPassantSquare = fromSquare.PawnForward(colour, 1);
                    }
                    else
                    {
                        targetSquare = (SquareFlag)((ulong)toSquare << (int)MoveDirection.East);

                        targetPiece = PieceMapHelpers.GetPiece(this, targetSquare);

                        if (targetPiece.Colour == colour.Opposite() && targetPiece.Type == PieceType.Pawn)
                        {
                            enPassantSquare = fromSquare.PawnForward(colour, 1);
                        }
                    }
                }

                MovePiece(colour, pieceType, fromSquare, toSquare);

                if (capturePieceType != PieceType.None)
                {
                    RemovePiece(colour.Opposite(), toSquare);
                }
            }
            else
            {
                MovePiece(colour, pieceType, fromSquare, toSquare);

                if (pieceType == PieceType.Rook)
                {
                    if (colour == Colour.White)
                    {
                        if (fromSquare == SquareFlagConstants.WhiteKingSideRookStartSquare)
                        {
                            state = RemoveCastleAvailability(colour, MoveType.CastleKing, state);
                        }
                        else if (fromSquare == SquareFlagConstants.WhiteQueenSideRookStartSquare)
                        {
                            state = RemoveCastleAvailability(colour, MoveType.CastleQueen, state);
                        }
                    }
                    else
                    {
                        if (fromSquare == SquareFlagConstants.BlackKingSideRookStartSquare)
                        {
                            state = RemoveCastleAvailability(colour, MoveType.CastleKing, state);
                        }
                        else if (fromSquare == SquareFlagConstants.BlackQueenSideRookStartSquare)
                        {
                            state = RemoveCastleAvailability(colour, MoveType.CastleQueen, state);
                        }
                    }
                }
                else if (pieceType == PieceType.King)
                {
                    state = RemoveCastleAvailability(colour, state);
                }

                if (capturePieceType != PieceType.None)
                {
                    RemovePiece(colour.Opposite(), toSquare);

                    if (capturePieceType == PieceType.Rook)
                    {
                        if (colour == Colour.White)
                        {
                            if (toSquare == SquareFlagConstants.BlackKingSideRookStartSquare)
                            {
                                state = RemoveCastleAvailability(Colour.Black, MoveType.CastleKing, state);
                            }
                            else if (toSquare == SquareFlagConstants.BlackQueenSideRookStartSquare)
                            {
                                state = RemoveCastleAvailability(Colour.Black, MoveType.CastleQueen, state);
                            }
                        }
                        else
                        {
                            if (toSquare == SquareFlagConstants.WhiteKingSideRookStartSquare)
                            {
                                state = RemoveCastleAvailability(Colour.White, MoveType.CastleKing, state);
                            }
                            else if (toSquare == SquareFlagConstants.WhiteQueenSideRookStartSquare)
                            {
                                state = RemoveCastleAvailability(Colour.White, MoveType.CastleQueen, state);
                            }
                        }
                    }
                }
            }

            Key = keyGen.UpdateHash(Key, move);

            var historyItem = new BoardStateInfo(Key, move, state, enPassantSquare);

            history.Push(historyItem);
        }