public void Add(HistoryMove move) { _history.Add(move); if ((move.Bits & (byte)(MoveBits.Capture | MoveBits.Pawn)) > 0) { _pawnOrCapIndices.Add(_history.Count - 1); } }
public bool MakeMove(Move m, bool checkLegal=true) { var hm = new HistoryMove(HashKey, m); hm.EnPassant = EnPassant; hm.CastleStatus = CastleStatus; //castle if ((m.Bits & (byte)MoveBits.King) > 0 && Math.Abs(m.To.File() - m.From.File()) == 2) MakeCastleMove(m); UpdateCastleStatus(m); if(CastleStatus != hm.CastleStatus){ HashKey ^= TranspositionTable.CastleStatusKey[hm.CastleStatus]; HashKey ^= TranspositionTable.CastleStatusKey[CastleStatus]; } UpdateCapture(m, hm); UpdateBitBoards(m); if (m.Promotion > 0) UpdatePromotion(m); if(EnPassant >0){ int file = EnPassant.BitScanForward().File(); HashKey ^= TranspositionTable.EnPassantFileKey[file]; // remove } //set enpassant sq if (((m.Bits & (byte)MoveBits.Pawn) > 0) && Math.Abs(m.To - m.From) == 16) { EnPassant = BitMask.Mask[m.From + (SideToMove == 1 ? 8 : -8)]; HashKey ^= TranspositionTable.EnPassantFileKey[m.To.File()]; } else EnPassant = 0; SideToMove ^= 1; HashKey ^= TranspositionTable.SideToMoveKey; // push the move onto the list of moves History.Add(hm); //make sure we are legal if (checkLegal && InCheck(SideToMove ^ 1)) { UnMakeMove(); return false; } return true; }
void UnmakeCapture(HistoryMove m) { var xside = SideToMove ^ 1; int sq = m.To; Piece p = Piece.Empty; if (m.CapturedPiece == MoveBits.Pawn) { p = Piece.Pawn; if (BitMask.Mask[m.To] == m.EnPassant) { sq = SideToMove == 0 ? m.To + 8 : m.To - 8; Pawns[xside] |= BitMask.Mask[sq]; } else Pawns[xside] |= BitMask.Mask[m.To]; } if (m.CapturedPiece == MoveBits.Knight) { Knights[xside] |= BitMask.Mask[m.To]; p = Piece.Knight; } else if (m.CapturedPiece == MoveBits.Bishop) { Bishops[xside] |= BitMask.Mask[m.To]; p = Piece.Bishop; } else if (m.CapturedPiece == MoveBits.Rook) { Rooks[xside] |= BitMask.Mask[m.To]; p = Piece.Rook; } else if (m.CapturedPiece == MoveBits.Queen) { Queens[xside] |= BitMask.Mask[m.To]; p = Piece.Queen; } else if (m.CapturedPiece == MoveBits.King){ King[xside] |= BitMask.Mask[m.To]; p=Piece.King; } AllPieces ^= BitMask.Mask[sq]; Pieces[xside] ^= BitMask.Mask[sq]; AllPiecesL45 ^= BitMask.Mask[RotatedL45Map[sq]]; AllPiecesR45 ^= BitMask.Mask[RotatedR45Map[sq]]; AllPiecesR90 ^= BitMask.Mask[Rotated90Map[sq]]; HashKey ^= TranspositionTable.HashKeys[xside, (int)p - 1, sq]; }
private void MakeNullMove() { var nullMove = new HistoryMove(MyBoard.HashKey, null); MyBoard.SideToMove ^= 1; MyBoard.HashKey ^= TranspositionTable.SideToMoveKey; Ply++; if (MyBoard.EnPassant > 0) { nullMove.EnPassant = MyBoard.EnPassant; var file = MyBoard.EnPassant.BitScanForward().File(); MyBoard.HashKey ^= TranspositionTable.EnPassantFileKey[file]; MyBoard.EnPassant = 0; } MyBoard.History.Add(nullMove);//store a null move in history }
void UpdateCapture(Move m, HistoryMove hm) { if ((m.Bits & (byte)MoveBits.Capture) == 0) return; //find the captured piece var xside = SideToMove ^ 1; int sq = m.To; Piece p = Piece.King;//needs to be assigned if ((Knights[xside] & BitMask.Mask[m.To]) > 0) { p = Piece.Knight; Knights[xside] ^= BitMask.Mask[m.To]; hm.CapturedPiece = MoveBits.Knight; } else if ((Bishops[xside] & BitMask.Mask[m.To]) > 0) { p = Piece.Bishop; Bishops[xside] ^= BitMask.Mask[m.To]; hm.CapturedPiece = MoveBits.Bishop; } else if ((Rooks[xside] & BitMask.Mask[m.To]) > 0) { p = Piece.Rook; Rooks[xside] ^= BitMask.Mask[m.To]; hm.CapturedPiece = MoveBits.Rook; } else if ((Queens[xside] & BitMask.Mask[m.To]) > 0) { p = Piece.Queen; Queens[xside] ^= BitMask.Mask[m.To]; hm.CapturedPiece = MoveBits.Queen; } else if ((Pawns[xside] & BitMask.Mask[m.To]) > 0) { p = Piece.Pawn; Pawns[xside] ^= BitMask.Mask[m.To]; hm.CapturedPiece = MoveBits.Pawn; } else if ((BitMask.Mask[m.To] & EnPassant) > 0) { var epSq = xside == 1 ? m.To + 8 : m.To - 8; Pawns[xside] ^= BitMask.Mask[epSq]; hm.CapturedPiece = MoveBits.Pawn; AllPieces ^= BitMask.Mask[epSq]; Pieces[xside] ^= BitMask.Mask[epSq]; AllPiecesL45 ^= BitMask.Mask[RotatedL45Map[epSq]]; AllPiecesR45 ^= BitMask.Mask[RotatedR45Map[epSq]]; AllPiecesR90 ^= BitMask.Mask[Rotated90Map[epSq]]; HashKey ^= TranspositionTable.HashKeys[xside, (int)Piece.Pawn - 1, epSq]; return; } else if ((King[xside] & BitMask.Mask[m.To]) > 0) { p=Piece.King; King[xside] ^= BitMask.Mask[m.To]; hm.CapturedPiece = MoveBits.King; } AllPieces ^= BitMask.Mask[sq]; Pieces[xside] ^= BitMask.Mask[sq]; AllPiecesL45 ^= BitMask.Mask[RotatedL45Map[sq]]; AllPiecesR45 ^= BitMask.Mask[RotatedR45Map[sq]]; AllPiecesR90 ^= BitMask.Mask[Rotated90Map[sq]]; HashKey ^= TranspositionTable.HashKeys[xside, (int)p - 1, sq]; }