/// <summary> /// Adds a piece to the board, and updates the hash keys if needed /// </summary> /// <param name="square">The square for the piece</param> /// <param name="side">For which side the piece is to be added</param> /// <param name="pieceType">The type of piece to add</param> private void AddPiece(Square square, Player side, EPieceType pieceType) { Piece piece = (int)pieceType | (side << 3); Position.AddPiece(piece, square); State.Key ^= Zobrist.GetZobristPst(piece, square); if (pieceType == EPieceType.Pawn) { State.PawnStructureKey ^= Zobrist.GetZobristPst(piece, square); } State.Material.Add(piece); }
/// <summary> /// Updates the hash key depending on a move /// </summary> /// <param name="move">The move the hash key is depending on</param> private void UpdateKey(Move move) { // TODO : Merge with MakeMove to avoid duplicate ifs var pawnKey = State.PawnStructureKey; var key = State.Key ^ pawnKey; pawnKey ^= Zobrist.GetZobristSide(); if (_stateList[PositionIndex - 1].EnPassantSquare != ESquare.none) { key ^= Zobrist.GetZobristEnPessant(_stateList[PositionIndex - 1].EnPassantSquare.File().AsInt()); } if (State.EnPassantSquare != ESquare.none) { key ^= Zobrist.GetZobristEnPessant(State.EnPassantSquare.File().AsInt()); } if (move.IsNullMove()) { key ^= pawnKey; State.Key = key; State.PawnStructureKey = pawnKey; return; } var pawnPiece = move.GetMovingPieceType() == EPieceType.Pawn; if (pawnPiece) { pawnKey ^= Zobrist.GetZobristPst(move.GetMovingPiece(), move.GetFromSquare()); } else { key ^= Zobrist.GetZobristPst(move.GetMovingPiece(), move.GetFromSquare()); } var squareTo = move.GetToSquare(); if (move.IsPromotionMove()) { key ^= Zobrist.GetZobristPst(move.GetPromotedPiece(), squareTo); } else { if (pawnPiece) { pawnKey ^= Zobrist.GetZobristPst(move.GetMovingPiece(), squareTo); } else { key ^= Zobrist.GetZobristPst(move.GetMovingPiece(), squareTo); } } if (pawnPiece && move.IsEnPassantMove()) { pawnKey ^= Zobrist.GetZobristPst(move.GetCapturedPiece().Type() + (State.SideToMove << 3), squareTo + (State.SideToMove.Side == 0 ? 8 : -8)); } else if (move.IsCaptureMove()) { if (pawnPiece) { pawnKey ^= Zobrist.GetZobristPst(move.GetCapturedPiece(), squareTo); } else { key ^= Zobrist.GetZobristPst(move.GetCapturedPiece(), squareTo); } } else if (move.IsCastlelingMove()) { var piece = (EPieces)(EPieceType.Rook + move.GetSideMask()); key ^= Zobrist.GetZobristPst(piece, Position.GetRookCastleFrom(squareTo)); key ^= Zobrist.GetZobristPst(piece, squareTo.GetRookCastleTo()); } // castleling // castling rights if (State.CastlelingRights != _stateList[PositionIndex - 1].CastlelingRights) { key ^= Zobrist.GetZobristCastleling(_stateList[PositionIndex - 1].CastlelingRights); key ^= Zobrist.GetZobristCastleling(State.CastlelingRights); } key ^= pawnKey; State.Key = key; State.PawnStructureKey = pawnKey; }
public void Hash(Piece piece, Square square) => Value ^= Zobrist.GetZobristPst(piece, square);