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); }
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); }