/// <summary> /// Some data, like En Passant right, needs resetting before a new move is applied /// </summary> /// <returns></returns> public void ResetHashBeforeMove(ref ulong hash, IrrevState irrevState) { if (irrevState.EnPassantCapture != 0) { UpdateEnPassant(ref hash, irrevState.EnPassantCapture); } }
protected IEnumerable <Move> GenerateCastlingMoves(ulong sq) { IrrevState irrevState = gameState.GetIrrevState(); for (int i = 0; i <= 1; i++) { if (IsCastlingAllowed(irrevState, i)) { ulong target = castlingKingTarget[i] & BitboardUtils.FIRST_RANK[gameState.Turn]; Move move = new CastlingMove(gameState, sq, target); yield return(move); } } }
public int GetKingFileScore(int pl, int file, bool rooksConnected, IrrevState irrevState) { int score = kingFile[file]; if (score < 0) { if (!irrevState.CastlingAllowed[pl, 0] && !irrevState.CastlingAllowed[pl, 1]) { score = (int)(score * 1.5); } } else if (!rooksConnected) { score = (int)(score * 0.2); } return(score); }
public ulong GenerateHash(GameState gameState) { ulong hash = 0; for (int pl = 0; pl < 2; pl++) { for (int i = 0; i < 6; i++) { int pInd = GetPieceIndex(pl, (PieceType)i); ulong pieces = gameState.Pieces[pl, i]; while (pieces > 0) { int sqInd = BitboardUtils.PopLSB(ref pieces); hash ^= piecePosBitstring[pInd, sqInd]; } } } IrrevState irrevState = gameState.GetIrrevState(); for (int pl = 0; pl < 2; pl++) { if (!irrevState.CastlingAllowed[pl, 0]) { DisableCastling(ref hash, pl, 0); } if (!irrevState.CastlingAllowed[pl, 1]) { DisableCastling(ref hash, pl, 1); } } if (irrevState.EnPassantCapture != 0) { UpdateEnPassant(ref hash, irrevState.EnPassantCapture); } return(hash); }
protected bool IsCastlingAllowed(IrrevState irrevState, int side) { return(irrevState.CastlingAllowed[gameState.Turn, side] && (castlingEmptySquares[side] & BitboardUtils.FIRST_RANK[gameState.Turn] & gameState.FullOccupancy) == 0); }
public void Load(string fen, GameState gameState, bool verifyValidity = false) { if (verifyValidity && !IsValid(fen)) { throw new ArgumentException("Invalid FEN"); } gameState.Reset(); IrrevState irrevState = gameState.GetIrrevState(); ulong currPos = 1; string[] parts = fen.Split(' '); string[] ranks = parts[0].Split('/'); for (int i = ranks.Length - 1; i >= 0; i--) { string rank = ranks[i]; for (int j = 0; j < rank.Length; j++) { char c = rank[j]; if (char.IsDigit(c)) { int shift = (int)char.GetNumericValue(c); currPos = currPos << shift; } else { int pl = char.IsLower(c) ? 1 : 0; int pieceType = (int)c.ToPieceType(); gameState.Pieces[pl, pieceType] |= currPos; gameState.Occupancy[pl] |= currPos; currPos = currPos << 1; } } } int turn = parts[1] == "w" ? 0 : 1; if (gameState.Turn != turn) { gameState.ChangeTurn(); } if (parts[2].IndexOf('Q') < 0) { irrevState.CastlingAllowed[0, 0] = false; } if (parts[2].IndexOf('K') < 0) { irrevState.CastlingAllowed[0, 1] = false; } if (parts[2].IndexOf('q') < 0) { irrevState.CastlingAllowed[1, 0] = false; } if (parts[2].IndexOf('k') < 0) { irrevState.CastlingAllowed[1, 1] = false; } if (parts[3] != "-") { irrevState.EnPassantCapture = BitboardUtils.GetBitboard(parts[3].StringToPos()); } irrevState.HalfmoveClock = int.Parse(parts[4]); irrevState.ZobristHash = gameState.ZobristHashUtils.GenerateHash(gameState); }
public string Convert(GameState gameState) { StringBuilder builder = new StringBuilder(); for (int r = 7; r >= 0; r--) { int emptySq = 0; for (int f = 0; f < 8; f++) { int sqInd = r * 8 + f; string piece = GetPieceBySquare(gameState, sqInd); if (piece == null) { emptySq++; } else { if (emptySq > 0) { builder.Append(emptySq); emptySq = 0; } builder.Append(piece); } } if (emptySq > 0) { builder.Append(emptySq); } if (r > 0) { builder.Append('/'); } } char turn = gameState.Turn == 0 ? 'w' : 'b'; builder.Append(" " + turn + " "); string castling = ""; IrrevState irrevState = gameState.GetIrrevState(); if (irrevState.CastlingAllowed[0, 1]) { castling += 'K'; } if (irrevState.CastlingAllowed[0, 0]) { castling += 'Q'; } if (irrevState.CastlingAllowed[1, 1]) { castling += 'k'; } if (irrevState.CastlingAllowed[1, 0]) { castling += 'q'; } if (castling == "") { castling = "-"; } builder.Append(castling + " "); string enPassant = "-"; if (irrevState.EnPassantCapture != 0) { enPassant = irrevState.EnPassantCapture.PosToString(); } builder.Append(enPassant + " "); builder.Append(irrevState.HalfmoveClock + " "); builder.Append(gameState.GetTurnNum()); return(builder.ToString()); }
protected void SetIrrevState() { irrevState = gameState.GetIrrevState(); }
private IEnumerable <Move> GetRegularMovesFromSquare(ulong sq, GenerationMode generationMode) { ulong reversedFullOccupancy = ~gameState.FullOccupancy; ulong to; ulong attacks; if (gameState.Turn == 0) { if (generationMode == GenerationMode.Normal) { to = sq << 8 & reversedFullOccupancy; if (to != 0) { yield return(new Move(gameState, sq, to, pieceType)); if ((sq & BitboardUtils.SECOND_RANK[gameState.Turn]) > 0) { to = to << 8 & reversedFullOccupancy; if (to != 0) { yield return(new Move(gameState, sq, to, pieceType)); } } } } to = sq << 7 & BitboardUtils.NOT_H_FILE; attacks = to; if ((to & gameState.Occupancy[1 - gameState.Turn]) != 0) { yield return(new Move(gameState, sq, to, pieceType)); } to = sq << 9 & BitboardUtils.NOT_A_FILE; attacks |= to; if ((to & gameState.Occupancy[1 - gameState.Turn]) != 0) { yield return(new Move(gameState, sq, to, pieceType)); } } else { if (generationMode == GenerationMode.Normal) { to = sq >> 8 & reversedFullOccupancy; if (to != 0) { yield return(new Move(gameState, sq, to, pieceType)); if ((sq & BitboardUtils.SECOND_RANK[gameState.Turn]) > 0) { to = to >> 8 & reversedFullOccupancy; if (to != 0) { yield return(new Move(gameState, sq, to, pieceType)); } } } } to = sq >> 9 & BitboardUtils.NOT_H_FILE; attacks = to; if ((to & gameState.Occupancy[1 - gameState.Turn]) != 0) { yield return(new Move(gameState, sq, to, pieceType)); } to = sq >> 7 & BitboardUtils.NOT_A_FILE; attacks |= to; if ((to & gameState.Occupancy[1 - gameState.Turn]) != 0) { yield return(new Move(gameState, sq, to, pieceType)); } } //En Passant IrrevState irrevState = gameState.GetIrrevState(); if ((irrevState.EnPassantCapture & attacks) > 0) { yield return(new EnPassantMove(gameState, sq, irrevState.EnPassantCapture)); } }