private static void TestZobrist() { var fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; var fact = new BoardFactory(); var board = fact.ParseFEN(fen); var key = ZobristKeys.CalculateKey(board); var keySame = board.Key == key; Console.WriteLine(keySame ? "Initial keys match" : "Initial keys are different"); var move = new Move(8, 16, ChessPiece.WhitePawn); board.DoMove2(move); var keyAfterMove = ZobristKeys.CalculateKey(board); board.UndoMove(); var keySameAfterMove = board.Key == keyAfterMove; var manualKey = board.Key; manualKey ^= ZobristKeys.ZPieces[8][ChessPiece.WhitePawn]; manualKey ^= ZobristKeys.ZPieces[16][ChessPiece.WhitePawn]; manualKey ^= ZobristKeys.ZWhiteToMove; Console.WriteLine(keySameAfterMove ? "Keys after move match" : "Keys after move are different"); }
public static Board ToDebugRookBoard(this ulong bitBoard) { var board = new Board(); board.ArrayBoard = new Piece[64]; board.BitBoard = new ulong[ChessPiece.Count]; board.BitBoard[ChessPiece.WhiteRook] = bitBoard; board.SyncExtraBitBoards(); board.SyncBitBoardsToArrayBoard(); SyncPiecesCount(board); board.SyncMaterial(); board.Key = ZobristKeys.CalculateKey(board); return(board); }
public static void CheckBoard(this Board board) { Assert(board.PieceCounts[ChessPiece.WhiteKing] == 1, "White king count != 1"); Assert(board.PieceCounts[ChessPiece.BlackKing] == 1, "Black king count != 1"); Assert(board.WhitePieces == (board.BitBoard[ChessPiece.WhitePawn] | board.BitBoard[ChessPiece.WhiteKnight] | board.BitBoard[ChessPiece.WhiteBishop] | board.BitBoard[ChessPiece.WhiteRook] | board.BitBoard[ChessPiece.WhiteQueen] | board.BitBoard[ChessPiece.WhiteKing])); Assert(board.BlackPieces == (board.BitBoard[ChessPiece.BlackPawn] | board.BitBoard[ChessPiece.BlackKnight] | board.BitBoard[ChessPiece.BlackBishop] | board.BitBoard[ChessPiece.BlackRook] | board.BitBoard[ChessPiece.BlackQueen] | board.BitBoard[ChessPiece.BlackKing])); Assert(board.AllPieces == (board.WhitePieces | board.BlackPieces)); Assert(board.EmptySquares == ~board.AllPieces); Assert(board.Key == ZobristKeys.CalculateKey(board), "Zobrist key mismatch when checking board"); }
public Board ParseFEN(string fen) { fen = fen.Trim(); var board = new Board(); board.ArrayBoard = new int[64]; board.BitBoard = new ulong[13]; board.CastlingPermissions = new bool[4]; board.History = new HistoryEntry[0]; var boardPosition = 0; var fenPosition = 0; for (; fenPosition < fen.Length; fenPosition++) { var fixedBoardPosition = (7 - boardPosition / 8) * 8 + boardPosition % 8; var ch = fen[fenPosition]; var pieceBitBoard = 1UL << fixedBoardPosition; switch (ch) { case 'p': board.BitBoard[ChessPiece.BlackPawn] |= pieceBitBoard; boardPosition++; continue; case 'P': board.BitBoard[ChessPiece.WhitePawn] |= pieceBitBoard; boardPosition++; continue; case 'n': board.BitBoard[ChessPiece.BlackKnight] |= pieceBitBoard; boardPosition++; continue; case 'N': board.BitBoard[ChessPiece.WhiteKnight] |= pieceBitBoard; boardPosition++; continue; case 'b': board.BitBoard[ChessPiece.BlackBishop] |= pieceBitBoard; boardPosition++; continue; case 'B': board.BitBoard[ChessPiece.WhiteBishop] |= pieceBitBoard; boardPosition++; continue; case 'r': board.BitBoard[ChessPiece.BlackRook] |= pieceBitBoard; boardPosition++; continue; case 'R': board.BitBoard[ChessPiece.WhiteRook] |= pieceBitBoard; boardPosition++; continue; case 'q': board.BitBoard[ChessPiece.BlackQueen] |= pieceBitBoard; boardPosition++; continue; case 'Q': board.BitBoard[ChessPiece.WhiteQueen] |= pieceBitBoard; boardPosition++; continue; case 'k': board.BitBoard[ChessPiece.BlackKing] |= pieceBitBoard; boardPosition++; continue; case 'K': board.BitBoard[ChessPiece.WhiteKing] |= pieceBitBoard; boardPosition++; continue; } byte emptySpaces; if (byte.TryParse(ch.ToString(), out emptySpaces)) { boardPosition += emptySpaces; continue; } if (ch == ' ') { break; } } fenPosition++; if (fen[fenPosition] == 'w') { board.WhiteToMove = true; } fenPosition += 2; for (var i = 0; i < 4; i++) { if (fenPosition >= fen.Length) { break; } switch (fen[fenPosition]) { case 'K': board.CastlingPermissions[CastlePermission.WhiteKingSide] = true; break; case 'Q': board.CastlingPermissions[CastlePermission.WhiteQueenSide] = true; break; case 'k': board.CastlingPermissions[CastlePermission.BlackKingSide] = true; break; case 'q': board.CastlingPermissions[CastlePermission.BlackQueenSide] = true; break; } fenPosition++; } board.SyncExtraBitBoards(); board.SyncBitBoardsToArrayBoard(); board.SyncPiecesCount(); board.SyncMaterial(); board.Key = ZobristKeys.CalculateKey(board); return(board); }
public Board ParseFEN(string fen) { fen = fen.Trim().Replace("/", string.Empty); var board = new Board(); board.ArrayBoard = new Piece[64]; board.BitBoard = new ulong[ChessPiece.Count]; board.CastlingPermissions = CastlingPermission.None; board.History2 = new UndoMove[1024]; //for (int i = 0; i < board.History2.Length; i++) //{ // board.History2[i] = new UndoMove(); //} board.PieceCounts = new int[ChessPiece.Count]; board.PawnMaterial = new Score[2]; board.PieceMaterial = new Score[2]; board.KingPositions = new Position[2]; var boardPosition = 0; var fenPosition = 0; for (; fenPosition < fen.Length; fenPosition++) { var fixedBoardPosition = (Position)((7 - boardPosition / 8) * 8 + boardPosition % 8); var ch = fen[fenPosition]; var pieceBitBoard = 1UL << fixedBoardPosition; var success = TryParsePiece(ch, out var piece); if (success) { board.BitBoard[piece] |= pieceBitBoard; board.ArrayBoard[fixedBoardPosition] = piece; board.PieceCounts[piece]++; if (piece == ChessPiece.WhiteKing) { board.KingPositions[ChessPiece.White] = fixedBoardPosition; } else if (piece == ChessPiece.BlackKing) { board.KingPositions[ChessPiece.Black] = fixedBoardPosition; } boardPosition++; continue; } byte emptySpaces; if (byte.TryParse(ch.ToString(), out emptySpaces)) { boardPosition += emptySpaces; continue; } if (ch == ' ') { break; } } fenPosition++; board.WhiteToMove = fen[fenPosition] switch { 'w' => true, 'b' => false, _ => throw new Exception("Unknown color") }; fenPosition += 2; for (var i = 0; i < 4; i++) { if (fenPosition >= fen.Length) { break; } bool done = false; switch (fen[fenPosition]) { case 'K': board.CastlingPermissions |= CastlingPermission.WhiteKing; break; case 'Q': board.CastlingPermissions |= CastlingPermission.WhiteQueen; break; case 'k': board.CastlingPermissions |= CastlingPermission.BlackKing; break; case 'q': board.CastlingPermissions |= CastlingPermission.BlackQueen; break; case ' ': fenPosition--; done = true; break; case '-': done = true; break; default: throw new Exception("Unknown character in castling permissions"); } fenPosition++; if (done) { break; } } fenPosition++; if (fenPosition < fen.Length && fen[fenPosition] != '-') { var lower = char.ToLowerInvariant(fen[fenPosition]); var file = (sbyte)(lower - 0x61); //var rank = fen[fenPosition] - 0x30; if (file >= 0 && file < 8) { board.EnPassantFileIndex = file; board.EnPassantFile = BitboardConstants.Files[file]; } fenPosition++; board.EnPassantRankIndex = (sbyte)(fen[fenPosition] - '0' - 1); } board.SyncExtraBitBoards(); //board.SyncBitBoardsToArrayBoard(); //board.SyncPiecesCount(); board.SyncMaterial(); board.Key = ZobristKeys.CalculateKey(board); //board.Key2 = ZobristKeys2.CalculateKey(board); board.PawnKey = ZobristKeys.CalculatePawnKey(board); //board.SetPinsAndChecks(); return(board); }