Exemple #1
0
        static Cuckoo()
        {
            // initialize cuckoo tables
            CuckooKeys  = new HashKey[8192];
            CuckooMoves = new Move[8192];

            Span <Piece> pieces = stackalloc Piece[]
            {
                Enums.Pieces.WhitePawn,
                Enums.Pieces.WhiteKnight,
                Enums.Pieces.WhiteBishop,
                Enums.Pieces.WhiteRook,
                Enums.Pieces.WhiteQueen,
                Enums.Pieces.WhiteKing,
                Enums.Pieces.BlackPawn,
                Enums.Pieces.BlackKnight,
                Enums.Pieces.BlackBishop,
                Enums.Pieces.BlackRook,
                Enums.Pieces.BlackQueen,
                Enums.Pieces.BlackKing
            };

            var count = 0;

            foreach (var pc in pieces)
            {
                foreach (var sq1 in BitBoards.AllSquares)
                {
                    for (var sq2 = sq1 + 1; sq2 <= Enums.Squares.h8; ++sq2)
                    {
                        if ((pc.Type().PseudoAttacks(sq1) & sq2).IsEmpty)
                        {
                            continue;
                        }

                        var     move = Move.Create(sq1, sq2);
                        HashKey key  = pc.GetZobristPst(sq1) ^ pc.GetZobristPst(sq2) ^ Zobrist.GetZobristSide();
                        var     i    = CuckooHashOne(key);
                        while (true)
                        {
                            (CuckooKeys[i], key)   = (key, CuckooKeys[i].Key);
Exemple #2
0
        /// <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 ^= _stateList[PositionIndex - 1].EnPassantSquare.File().GetZobristEnPessant();
            }

            if (State.EnPassantSquare != ESquare.none)
            {
                key ^= State.EnPassantSquare.File().GetZobristEnPessant();
            }

            if (move.IsNullMove())
            {
                State.Key = key ^ pawnKey;
                State.PawnStructureKey = pawnKey;
                return;
            }

            var pawnPiece = move.GetMovingPieceType() == EPieceType.Pawn;
            var squareTo  = move.GetToSquare();

            if (move.IsPromotionMove())
            {
                key ^= move.GetPromotedPiece().GetZobristPst(squareTo);
            }
            else
            {
                if (pawnPiece)
                {
                    pawnKey ^= move.GetMovingPiece().GetZobristPst(squareTo);
                }
                else
                {
                    key ^= move.GetMovingPiece().GetZobristPst(squareTo);
                }
            }

            if (pawnPiece)
            {
                pawnKey ^= move.GetMovingPiece().GetZobristPst(move.GetFromSquare());
                if (move.IsEnPassantMove())
                {
                    pawnKey ^= move.GetCapturedPiece().GetZobristPst(squareTo + State.SideToMove.PawnPushDistance());
                }
                else if (move.IsCaptureMove())
                {
                    pawnKey ^= move.GetCapturedPiece().GetZobristPst(squareTo);
                }
            }
            else
            {
                key ^= move.GetMovingPiece().GetZobristPst(move.GetFromSquare());
                if (move.IsCaptureMove())
                {
                    key ^= move.GetCapturedPiece().GetZobristPst(squareTo);
                }
                else if (move.IsCastlelingMove())
                {
                    var piece = EPieceType.Rook.MakePiece(Position.State.SideToMove);
                    key ^= piece.GetZobristPst(Position.GetRookCastleFrom(squareTo));
                    key ^= piece.GetZobristPst(squareTo.GetRookCastleTo());
                }
            }

            // castling rights
            if (State.CastlelingRights != _stateList[PositionIndex - 1].CastlelingRights)
            {
                key ^= _stateList[PositionIndex - 1].CastlelingRights.GetZobristCastleling();
                key ^= State.CastlelingRights.GetZobristCastleling();
            }

            State.Key = key ^ pawnKey;
            State.PawnStructureKey = pawnKey;
        }
Exemple #3
0
        public KeyGeneratorFixture()
        {
            KeyGenerator = new Zobrist();

            KeyGenerator.Init();
        }
Exemple #4
0
        /// <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;
        }
Exemple #5
0
        /// <summary>
        /// Apply a FEN string board setup to the board structure.
        /// </summary>
        /// <param name="fenString">The string to set</param>
        /// <param name="validate">If true, the fen string is validated, otherwise not</param>
        /// <returns>
        /// 0 = all ok.
        /// -1 = Error in piece file layout parsing
        /// -2 = Error in piece rank layout parsing
        /// -3 = Unknown piece detected
        /// -4 = Error while parsing moving side
        /// -5 = Error while parsing castleling
        /// -6 = Error while parsing en-passant square
        /// -9 = FEN length exceeding maximum
        /// </returns>
        public FenError SetFen(FenData fen, bool validate = false)
        {
            if (validate)
            {
                Fen.Fen.Validate(fen.Fen.ToString());
            }

            // correctly clear all pieces and invoke possible notification(s)
            var bb = Occupied;

            while (bb)
            {
                var square = bb.Lsb();
                Position.RemovePiece(square, Position.BoardLayout[square.AsInt()]);
                BitBoards.ResetLsb(ref bb);
            }

            var chunk = fen.Chunk();

            if (chunk.IsEmpty)
            {
                return(new FenError());
            }

            var    f = 1; // file (column)
            var    r = 8; // rank (row)
            Player player;

            foreach (var c in chunk)
            {
                if (char.IsDigit(c))
                {
                    f += c - '0';
                    if (f > 9)
                    {
                        return(new FenError(-1, fen.Index));
                    }
                }
                else if (c == '/')
                {
                    if (f != 9)
                    {
                        return(new FenError(-2, fen.Index));
                    }

                    r--;
                    f = 1;
                }
                else
                {
                    var pieceIndex = PieceExtensions.PieceChars.IndexOf(c);

                    if (pieceIndex == -1)
                    {
                        return(new FenError(-3, fen.Index));
                    }

                    player = char.IsLower(PieceExtensions.PieceChars[pieceIndex]);

                    var square = new Square(r - 1, f - 1);

                    AddPiece(square, player, (EPieceType)pieceIndex);

                    f++;
                }
            }

            // player
            chunk = fen.Chunk();

            if (chunk.IsEmpty || chunk.Length != 1)
            {
                return(new FenError(-3, fen.Index));
            }

            player = (chunk[0] != 'w').ToInt();

            // castleling
            chunk = fen.Chunk();

            if (!SetupCastleling(chunk))
            {
                return(new FenError(-5, fen.Index));
            }

            // en-passant
            chunk = fen.Chunk();

            if (chunk.Length == 1 || chunk[0] == '-' || !chunk[0].InBetween('a', 'h'))
            {
                State.EnPassantSquare = ESquare.none;
            }
            else
            {
                State.EnPassantSquare = chunk[1].InBetween('3', '6') ? ESquare.none : new Square(chunk[1] - '1', chunk[0] - 'a').Value;
            }

            // move number
            chunk = fen.Chunk();

            var moveNum     = 0;
            var halfMoveNum = 0;

            if (!chunk.IsEmpty)
            {
                chunk.ToIntegral(out halfMoveNum);

                // half move number
                chunk = fen.Chunk();

                chunk.ToIntegral(out moveNum);

                if (moveNum > 0)
                {
                    moveNum--;
                }
            }

            PositionIndex = PositionStart = moveNum;

            Position.State = _stateList[PositionIndex];

            State.ReversibleHalfMoveCount = halfMoveNum;

            State.SideToMove = player;

            if (player.IsBlack())
            {
                State.Key ^= Zobrist.GetZobristSide();
                State.PawnStructureKey ^= Zobrist.GetZobristSide();
            }

            State.Key ^= State.CastlelingRights.GetZobristCastleling();

            if (State.EnPassantSquare != ESquare.none)
            {
                State.Key ^= State.EnPassantSquare.File().GetZobristEnPessant();
            }

            Position.InCheck = Position.IsAttacked(Position.GetPieceSquare(EPieceType.King, player), ~player);

            return(0);
        }
        internal static void EvaluateBoardScore(Board board)
        {
            if ((int)board.EnPassantPosition == 0 && !board.EndGamePhase)
            {
                int?nullable1 = Zobrist.SearchEval(board.ZobristHash);
                if (nullable1.HasValue)
                {
                    int?nullable2 = nullable1;
                    int num       = 0;
                    if ((nullable2.GetValueOrDefault() == num ? (!nullable2.HasValue ? 1 : 0) : 1) != 0)
                    {
                        board.Score = nullable1.Value;
                        return;
                    }
                }
            }
            board.Score = 0;
            bool insufficientMaterial = true;

            if (board.StaleMate || (int)board.FiftyMove >= 50 || (int)board.RepeatedMove >= 3)
            {
                return;
            }
            if (board.BlackMate)
            {
                board.Score = (int)short.MaxValue;
            }
            else if (board.WhiteMate)
            {
                board.Score = -32767;
            }
            else
            {
                if (board.BlackCheck)
                {
                    board.Score += 70;
                    if (board.EndGamePhase)
                    {
                        board.Score += 10;
                    }
                }
                else if (board.WhiteCheck)
                {
                    board.Score -= 70;
                    if (board.EndGamePhase)
                    {
                        board.Score -= 10;
                    }
                }
                if (board.BlackCastled)
                {
                    board.Score -= 50;
                }
                if (board.WhiteCastled)
                {
                    board.Score += 50;
                }
                if (board.WhoseMove == ChessPieceColor.White)
                {
                    board.Score += 10;
                }
                else
                {
                    board.Score -= 10;
                }
                byte bishopCount1 = 0;
                byte bishopCount2 = 0;
                byte knightCount1 = 0;
                byte knightCount2 = 0;
                byte num          = 0;
                Evaluation.blackPawnCount = new short[8];
                Evaluation.whitePawnCount = new short[8];
                for (byte position = 0; (int)position < 64; ++position)
                {
                    Square square = board.Squares[(int)position];
                    if (square.Piece != null)
                    {
                        if (square.Piece.PieceColor == ChessPieceColor.White)
                        {
                            board.Score += Evaluation.EvaluatePieceScore(square, position, board.EndGamePhase, ref knightCount2, ref bishopCount2, ref insufficientMaterial);
                            if (square.Piece.PieceType == ChessPieceType.King && (int)position != 59 && (int)position != 60)
                            {
                                int pawnPos1 = (int)position - 8;
                                board.Score += Evaluation.CheckPawnWall(board, pawnPos1, (int)position);
                                int pawnPos2 = (int)position - 7;
                                board.Score += Evaluation.CheckPawnWall(board, pawnPos2, (int)position);
                                int pawnPos3 = (int)position - 9;
                                board.Score += Evaluation.CheckPawnWall(board, pawnPos3, (int)position);
                            }
                        }
                        else if (square.Piece.PieceColor == ChessPieceColor.Black)
                        {
                            board.Score -= Evaluation.EvaluatePieceScore(square, position, board.EndGamePhase, ref knightCount1, ref bishopCount1, ref insufficientMaterial);
                            if (square.Piece.PieceType == ChessPieceType.King && (int)position != 3 && (int)position != 4)
                            {
                                int pawnPos1 = (int)position + 8;
                                board.Score -= Evaluation.CheckPawnWall(board, pawnPos1, (int)position);
                                int pawnPos2 = (int)position + 7;
                                board.Score -= Evaluation.CheckPawnWall(board, pawnPos2, (int)position);
                                int pawnPos3 = (int)position + 9;
                                board.Score -= Evaluation.CheckPawnWall(board, pawnPos3, (int)position);
                            }
                        }
                        if (square.Piece.PieceType == ChessPieceType.Knight)
                        {
                            ++num;
                            if ((int)num > 1)
                            {
                                insufficientMaterial = false;
                            }
                        }
                        if ((int)bishopCount1 + (int)bishopCount2 > 1)
                        {
                            insufficientMaterial = false;
                        }
                        else if ((int)bishopCount1 + (int)knightCount1 > 1)
                        {
                            insufficientMaterial = false;
                        }
                        else if ((int)bishopCount2 + (int)knightCount2 > 1)
                        {
                            insufficientMaterial = false;
                        }
                    }
                }
                if (insufficientMaterial)
                {
                    board.Score                = 0;
                    board.StaleMate            = true;
                    board.InsufficientMaterial = true;
                }
                else
                {
                    if (board.EndGamePhase)
                    {
                        if (board.BlackCheck)
                        {
                            board.Score += 10;
                        }
                        else if (board.WhiteCheck)
                        {
                            board.Score -= 10;
                        }
                    }
                    else
                    {
                        if (!board.WhiteCanCastle && !board.WhiteCastled)
                        {
                            board.Score -= 50;
                        }
                        if (!board.BlackCanCastle && !board.BlackCastled)
                        {
                            board.Score += 50;
                        }
                    }
                    if ((int)Evaluation.blackPawnCount[0] >= 1 && (int)Evaluation.blackPawnCount[1] == 0)
                    {
                        board.Score += 12;
                    }
                    if ((int)Evaluation.blackPawnCount[1] >= 1 && (int)Evaluation.blackPawnCount[0] == 0 && (int)Evaluation.blackPawnCount[2] == 0)
                    {
                        board.Score += 14;
                    }
                    if ((int)Evaluation.blackPawnCount[2] >= 1 && (int)Evaluation.blackPawnCount[1] == 0 && (int)Evaluation.blackPawnCount[3] == 0)
                    {
                        board.Score += 16;
                    }
                    if ((int)Evaluation.blackPawnCount[3] >= 1 && (int)Evaluation.blackPawnCount[2] == 0 && (int)Evaluation.blackPawnCount[4] == 0)
                    {
                        board.Score += 20;
                    }
                    if ((int)Evaluation.blackPawnCount[4] >= 1 && (int)Evaluation.blackPawnCount[3] == 0 && (int)Evaluation.blackPawnCount[5] == 0)
                    {
                        board.Score += 20;
                    }
                    if ((int)Evaluation.blackPawnCount[5] >= 1 && (int)Evaluation.blackPawnCount[4] == 0 && (int)Evaluation.blackPawnCount[6] == 0)
                    {
                        board.Score += 16;
                    }
                    if ((int)Evaluation.blackPawnCount[6] >= 1 && (int)Evaluation.blackPawnCount[5] == 0 && (int)Evaluation.blackPawnCount[7] == 0)
                    {
                        board.Score += 14;
                    }
                    if ((int)Evaluation.blackPawnCount[7] >= 1 && (int)Evaluation.blackPawnCount[6] == 0)
                    {
                        board.Score += 12;
                    }
                    if ((int)Evaluation.whitePawnCount[0] >= 1 && (int)Evaluation.whitePawnCount[1] == 0)
                    {
                        board.Score -= 12;
                    }
                    if ((int)Evaluation.whitePawnCount[1] >= 1 && (int)Evaluation.whitePawnCount[0] == 0 && (int)Evaluation.whitePawnCount[2] == 0)
                    {
                        board.Score -= 14;
                    }
                    if ((int)Evaluation.whitePawnCount[2] >= 1 && (int)Evaluation.whitePawnCount[1] == 0 && (int)Evaluation.whitePawnCount[3] == 0)
                    {
                        board.Score -= 16;
                    }
                    if ((int)Evaluation.whitePawnCount[3] >= 1 && (int)Evaluation.whitePawnCount[2] == 0 && (int)Evaluation.whitePawnCount[4] == 0)
                    {
                        board.Score -= 20;
                    }
                    if ((int)Evaluation.whitePawnCount[4] >= 1 && (int)Evaluation.whitePawnCount[3] == 0 && (int)Evaluation.whitePawnCount[5] == 0)
                    {
                        board.Score -= 20;
                    }
                    if ((int)Evaluation.whitePawnCount[5] >= 1 && (int)Evaluation.whitePawnCount[4] == 0 && (int)Evaluation.whitePawnCount[6] == 0)
                    {
                        board.Score -= 16;
                    }
                    if ((int)Evaluation.whitePawnCount[6] >= 1 && (int)Evaluation.whitePawnCount[5] == 0 && (int)Evaluation.whitePawnCount[7] == 0)
                    {
                        board.Score -= 14;
                    }
                    if ((int)Evaluation.whitePawnCount[7] >= 1 && (int)Evaluation.whitePawnCount[6] == 0)
                    {
                        board.Score -= 12;
                    }
                    if ((int)Evaluation.blackPawnCount[0] >= 1 && (int)Evaluation.whitePawnCount[0] == 0)
                    {
                        board.Score -= (int)Evaluation.blackPawnCount[0];
                    }
                    if ((int)Evaluation.blackPawnCount[1] >= 1 && (int)Evaluation.whitePawnCount[1] == 0)
                    {
                        board.Score -= (int)Evaluation.blackPawnCount[1];
                    }
                    if ((int)Evaluation.blackPawnCount[2] >= 1 && (int)Evaluation.whitePawnCount[2] == 0)
                    {
                        board.Score -= (int)Evaluation.blackPawnCount[2];
                    }
                    if ((int)Evaluation.blackPawnCount[3] >= 1 && (int)Evaluation.whitePawnCount[3] == 0)
                    {
                        board.Score -= (int)Evaluation.blackPawnCount[3];
                    }
                    if ((int)Evaluation.blackPawnCount[4] >= 1 && (int)Evaluation.whitePawnCount[4] == 0)
                    {
                        board.Score -= (int)Evaluation.blackPawnCount[4];
                    }
                    if ((int)Evaluation.blackPawnCount[5] >= 1 && (int)Evaluation.whitePawnCount[5] == 0)
                    {
                        board.Score -= (int)Evaluation.blackPawnCount[5];
                    }
                    if ((int)Evaluation.blackPawnCount[6] >= 1 && (int)Evaluation.whitePawnCount[6] == 0)
                    {
                        board.Score -= (int)Evaluation.blackPawnCount[6];
                    }
                    if ((int)Evaluation.blackPawnCount[7] >= 1 && (int)Evaluation.whitePawnCount[7] == 0)
                    {
                        board.Score -= (int)Evaluation.blackPawnCount[7];
                    }
                    if ((int)Evaluation.whitePawnCount[0] >= 1 && (int)Evaluation.blackPawnCount[1] == 0)
                    {
                        board.Score += (int)Evaluation.whitePawnCount[0];
                    }
                    if ((int)Evaluation.whitePawnCount[1] >= 1 && (int)Evaluation.blackPawnCount[1] == 0)
                    {
                        board.Score += (int)Evaluation.whitePawnCount[1];
                    }
                    if ((int)Evaluation.whitePawnCount[2] >= 1 && (int)Evaluation.blackPawnCount[2] == 0)
                    {
                        board.Score += (int)Evaluation.whitePawnCount[2];
                    }
                    if ((int)Evaluation.whitePawnCount[3] >= 1 && (int)Evaluation.blackPawnCount[3] == 0)
                    {
                        board.Score += (int)Evaluation.whitePawnCount[3];
                    }
                    if ((int)Evaluation.whitePawnCount[4] >= 1 && (int)Evaluation.blackPawnCount[4] == 0)
                    {
                        board.Score += (int)Evaluation.whitePawnCount[4];
                    }
                    if ((int)Evaluation.whitePawnCount[5] >= 1 && (int)Evaluation.blackPawnCount[5] == 0)
                    {
                        board.Score += (int)Evaluation.whitePawnCount[5];
                    }
                    if ((int)Evaluation.whitePawnCount[6] >= 1 && (int)Evaluation.blackPawnCount[6] == 0)
                    {
                        board.Score += (int)Evaluation.whitePawnCount[6];
                    }
                    if ((int)Evaluation.whitePawnCount[7] >= 1 && (int)Evaluation.blackPawnCount[7] == 0)
                    {
                        board.Score += (int)Evaluation.whitePawnCount[7];
                    }
                    if ((int)board.EnPassantPosition != 0 || board.EndGamePhase || board.Score == 0)
                    {
                        return;
                    }
                    Zobrist.AddEntryEval(board.ZobristHash, board.Score);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Apply a FEN string board setup to the board structure.
        /// *EXCEPTION FREE FUNCTION*
        /// </summary>
        /// <param name="fenString">The string to set</param>
        /// <param name="validate">If true, the fen string is validated, otherwise not</param>
        /// <returns>
        /// 0 = all ok.
        /// -1 = Error in piece file layout parsing
        /// -2 = Error in piece rank layout parsing
        /// -3 = Unknown piece detected
        /// -4 = Error while parsing moving side
        /// -5 = Error while parsing castleling
        /// -6 = Error while parsing en-passant square
        /// -9 = FEN length exceeding maximum
        /// </returns>
        public FenError SetFen(string fenString, bool validate = false)
        {
            // TODO : Replace with stream at some point

            // basic validation, catches format errors
            if (validate)
            {
                Fen.Fen.Validate(fenString);
            }

            foreach (var square in Occupied)
            {
                Position.RemovePiece(square, Position.BoardLayout[square.AsInt()]);
            }

            //for (var i = 0; i <= PositionIndex; i++)
            //    _stateList[i].Clear();

            Position.Clear();

            var fen = new FenData(fenString);

            Player player;
            var    c = fen.GetAdvance;

            var f = 1; // file (column)
            var r = 8; // rank (row)

            // map pieces to data structure
            while (c != 0 && !(f == 9 && r == 1))
            {
                if (char.IsDigit(c))
                {
                    f += c - '0';
                    if (f > 9)
                    {
                        return(new FenError(-1, fen.Index));
                    }

                    c = fen.GetAdvance;
                    continue;
                }

                if (c == '/')
                {
                    if (f != 9)
                    {
                        return(new FenError(-2, fen.Index));
                    }

                    r--;
                    f = 1;
                    c = fen.GetAdvance;
                    continue;
                }

                var pieceIndex = PieceExtensions.PieceChars.IndexOf(c);

                if (pieceIndex == -1)
                {
                    return(new FenError(-3, fen.Index));
                }

                player = char.IsLower(PieceExtensions.PieceChars[pieceIndex]);

                var square = new Square(r - 1, f - 1);

                AddPiece(square, player, (EPieceType)pieceIndex);

                c = fen.GetAdvance;

                f++;
            }

            if (!Fen.Fen.IsDelimiter(c))
            {
                return(new FenError(-4, fen.Index));
            }

            c = fen.GetAdvance;

            player = c == 'w' ? 0 : 1;

            if (player == -1)
            {
                return(new FenError(-4, fen.Index));
            }

            if (!Fen.Fen.IsDelimiter(fen.GetAdvance))
            {
                return(new FenError(-5, fen.Index));
            }

            if (!SetupCastleling(fen))
            {
                return(new FenError(-5, fen.Index));
            }

            if (!Fen.Fen.IsDelimiter(fen.GetAdvance))
            {
                return(new FenError(-6, fen.Index));
            }

            State.EnPassantSquare = fen.GetEpSquare();

            // temporary.. the whole method should be using this, but this will do for now.

            var moveCounters = fen.Fen.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            var first  = moveCounters[moveCounters.Length - 2];
            var second = moveCounters[moveCounters.Length - 1];

            second.ToIntegral(out int number);

            if (number > 0)
            {
                number -= 1;
            }

            PositionIndex = PositionStart = number;

            first.ToIntegral(out number);

            State = Position.State = _stateList[PositionIndex];

            State.ReversibleHalfMoveCount = number;

            State.SideToMove = player;

            if (player.IsBlack())
            {
                var zobristSide = Zobrist.GetZobristSide();
                State.Key ^= zobristSide;
                State.PawnStructureKey ^= zobristSide;
            }

            State.Key ^= Zobrist.GetZobristCastleling(State.CastlelingRights);

            if (State.EnPassantSquare != ESquare.none)
            {
                State.Key ^= Zobrist.GetZobristEnPessant(State.EnPassantSquare.File().AsInt());
            }

            Position.InCheck = Position.IsAttacked(Position.GetPieceSquare(EPieceType.King, State.SideToMove), ~State.SideToMove);

            //State.GenerateMoves(true);

            return(0);
        }
Exemple #8
0
 public void HashSide() => Value ^= Zobrist.GetZobristSide();
Exemple #9
0
 public void Hash(int enPassantFile) => Value ^= Zobrist.GetZobristEnPessant(enPassantFile);
Exemple #10
0
 public void Hash(ECastleling castleling, ERank rank) => Value ^= Zobrist.GetZobristCastleling((int)rank);
Exemple #11
0
 public void Hash(Piece piece, Square square) => Value ^= Zobrist.GetZobristPst(piece, square);
Exemple #12
0
 public void Xor(ref Zobrist zobr1, ref Zobrist zobr2)
 {
     key   = zobr1.key ^ zobr2.key;
     lock0 = zobr1.lock0 ^ zobr2.lock0;
     lock1 = zobr1.lock1 ^ zobr2.lock1;
 }
Exemple #13
0
 /// <summary>
 /// 执行异或操作
 /// </summary>
 /// <param name="zobr"></param>
 public void Xor(ref Zobrist zobr)
 {
     key   ^= zobr.key;
     lock0 ^= zobr.lock0;
     lock1 ^= zobr.lock1;
 }
Exemple #14
0
 public static void Init()
 {
     Zobrist.Init();
     Bitboard.Init();
 }
Exemple #15
0
        internal Board(string fen)
            : this()
        {
            byte num1 = 0;
            byte num2 = 0;

            this.WhiteCastled = true;
            this.BlackCastled = true;
            byte num3 = 0;

            this.WhoseMove = ChessPieceColor.White;
            if (fen.Contains("a3"))
            {
                this.EnPassantColor    = ChessPieceColor.White;
                this.EnPassantPosition = (byte)40;
            }
            else if (fen.Contains("b3"))
            {
                this.EnPassantColor    = ChessPieceColor.White;
                this.EnPassantPosition = (byte)41;
            }
            else if (fen.Contains("c3"))
            {
                this.EnPassantColor    = ChessPieceColor.White;
                this.EnPassantPosition = (byte)42;
            }
            else if (fen.Contains("d3"))
            {
                this.EnPassantColor    = ChessPieceColor.White;
                this.EnPassantPosition = (byte)43;
            }
            else if (fen.Contains("e3"))
            {
                this.EnPassantColor    = ChessPieceColor.White;
                this.EnPassantPosition = (byte)44;
            }
            else if (fen.Contains("f3"))
            {
                this.EnPassantColor    = ChessPieceColor.White;
                this.EnPassantPosition = (byte)45;
            }
            else if (fen.Contains("g3"))
            {
                this.EnPassantColor    = ChessPieceColor.White;
                this.EnPassantPosition = (byte)46;
            }
            else if (fen.Contains("h3"))
            {
                this.EnPassantColor    = ChessPieceColor.White;
                this.EnPassantPosition = (byte)47;
            }
            if (fen.Contains("a6"))
            {
                this.EnPassantColor    = ChessPieceColor.Black;
                this.EnPassantPosition = (byte)16;
            }
            else if (fen.Contains("b6"))
            {
                this.EnPassantColor    = ChessPieceColor.Black;
                this.EnPassantPosition = (byte)17;
            }
            else if (fen.Contains("c6"))
            {
                this.EnPassantColor    = ChessPieceColor.Black;
                this.EnPassantPosition = (byte)18;
            }
            else if (fen.Contains("d6"))
            {
                this.EnPassantColor    = ChessPieceColor.Black;
                this.EnPassantPosition = (byte)19;
            }
            else if (fen.Contains("e6"))
            {
                this.EnPassantColor    = ChessPieceColor.Black;
                this.EnPassantPosition = (byte)20;
            }
            else if (fen.Contains("f6"))
            {
                this.EnPassantColor    = ChessPieceColor.Black;
                this.EnPassantPosition = (byte)21;
            }
            else if (fen.Contains("g6"))
            {
                this.EnPassantColor    = ChessPieceColor.Black;
                this.EnPassantPosition = (byte)22;
            }
            else if (fen.Contains("h6"))
            {
                this.EnPassantColor    = ChessPieceColor.Black;
                this.EnPassantPosition = (byte)23;
            }
            if (fen.Contains(" w "))
            {
                this.WhoseMove = ChessPieceColor.White;
            }
            if (fen.Contains(" b "))
            {
                this.WhoseMove = ChessPieceColor.Black;
            }
            foreach (char ch in fen)
            {
                if ((int)num1 < 64 && (int)num2 == 0)
                {
                    if ((int)ch == 49 && (int)num1 < 63)
                    {
                        ++num1;
                    }
                    else if ((int)ch == 50 && (int)num1 < 62)
                    {
                        num1 += (byte)2;
                    }
                    else if ((int)ch == 51 && (int)num1 < 61)
                    {
                        num1 += (byte)3;
                    }
                    else if ((int)ch == 52 && (int)num1 < 60)
                    {
                        num1 += (byte)4;
                    }
                    else if ((int)ch == 53 && (int)num1 < 59)
                    {
                        num1 += (byte)5;
                    }
                    else if ((int)ch == 54 && (int)num1 < 58)
                    {
                        num1 += (byte)6;
                    }
                    else if ((int)ch == 55 && (int)num1 < 57)
                    {
                        num1 += (byte)7;
                    }
                    else if ((int)ch == 56 && (int)num1 < 56)
                    {
                        num1 += (byte)8;
                    }
                    else if ((int)ch == 80)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Pawn, ChessPieceColor.White);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 78)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Knight, ChessPieceColor.White);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 66)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Bishop, ChessPieceColor.White);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 82)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Rook, ChessPieceColor.White);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 81)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Queen, ChessPieceColor.White);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 75)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.King, ChessPieceColor.White);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 112)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Pawn, ChessPieceColor.Black);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 110)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Knight, ChessPieceColor.Black);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 98)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Bishop, ChessPieceColor.Black);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 114)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Rook, ChessPieceColor.Black);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 113)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.Queen, ChessPieceColor.Black);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch == 107)
                    {
                        this.Squares[(int)num1].Piece       = new Piece(ChessPieceType.King, ChessPieceColor.Black);
                        this.Squares[(int)num1].Piece.Moved = true;
                        ++num1;
                    }
                    else if ((int)ch != 47 && (int)ch == 32)
                    {
                        ++num2;
                    }
                }
                else if ((int)ch == 75)
                {
                    if (this.Squares[60].Piece != null && this.Squares[60].Piece.PieceType == ChessPieceType.King)
                    {
                        this.Squares[60].Piece.Moved = false;
                    }
                    if (this.Squares[63].Piece != null && this.Squares[63].Piece.PieceType == ChessPieceType.Rook)
                    {
                        this.Squares[63].Piece.Moved = false;
                    }
                    this.WhiteCastled = false;
                }
                else if ((int)ch == 81)
                {
                    if (this.Squares[60].Piece != null && this.Squares[60].Piece.PieceType == ChessPieceType.King)
                    {
                        this.Squares[60].Piece.Moved = false;
                    }
                    if (this.Squares[56].Piece != null && this.Squares[56].Piece.PieceType == ChessPieceType.Rook)
                    {
                        this.Squares[56].Piece.Moved = false;
                    }
                    this.WhiteCastled = false;
                }
                else if ((int)ch == 107)
                {
                    if (this.Squares[4].Piece != null && this.Squares[4].Piece.PieceType == ChessPieceType.King)
                    {
                        this.Squares[4].Piece.Moved = false;
                    }
                    if (this.Squares[7].Piece != null && this.Squares[7].Piece.PieceType == ChessPieceType.Rook)
                    {
                        this.Squares[7].Piece.Moved = false;
                    }
                    this.BlackCastled = false;
                }
                else if ((int)ch == 113)
                {
                    if (this.Squares[4].Piece != null && this.Squares[4].Piece.PieceType == ChessPieceType.King)
                    {
                        this.Squares[4].Piece.Moved = false;
                    }
                    if (this.Squares[0].Piece != null && this.Squares[0].Piece.PieceType == ChessPieceType.Rook)
                    {
                        this.Squares[0].Piece.Moved = false;
                    }
                    this.BlackCastled = false;
                }
                else if ((int)ch == 32)
                {
                    ++num3;
                }
                else if ((int)ch == 49 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 1);
                }
                else if ((int)ch == 50 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 2);
                }
                else if ((int)ch == 51 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 3);
                }
                else if ((int)ch == 52 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 4);
                }
                else if ((int)ch == 53 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 5);
                }
                else if ((int)ch == 54 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 6);
                }
                else if ((int)ch == 55 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 7);
                }
                else if ((int)ch == 56 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 8);
                }
                else if ((int)ch == 57 && (int)num3 == 4)
                {
                    this.FiftyMove = (byte)((int)this.FiftyMove * 10 + 9);
                }
                else if ((int)ch == 48 && (int)num3 == 4)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 0);
                }
                else if ((int)ch == 49 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 1);
                }
                else if ((int)ch == 50 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 2);
                }
                else if ((int)ch == 51 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 3);
                }
                else if ((int)ch == 52 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 4);
                }
                else if ((int)ch == 53 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 5);
                }
                else if ((int)ch == 54 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 6);
                }
                else if ((int)ch == 55 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 7);
                }
                else if ((int)ch == 56 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 8);
                }
                else if ((int)ch == 57 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 9);
                }
                else if ((int)ch == 48 && (int)num3 == 5)
                {
                    this.MoveCount = (int)(byte)(this.MoveCount * 10 + 0);
                }
            }
            Zobrist.InitiateZobristTable();
            this.ZobristHash = Zobrist.CalculateZobristHash(this);
        }
Exemple #16
0
        internal static ulong UpdateZobristHash(ulong hash, MoveContent move, ChessPieceColor whosMove, bool pawnPromote)
        {
            hash = Zobrist.GetHashResult((int)move.MovingPiecePrimary.SrcPosition, move.MovingPiecePrimary.PieceType, move.MovingPiecePrimary.PieceColor, hash);
            if (move.MovingPieceSecondary.PieceType != ChessPieceType.None)
            {
                hash = Zobrist.GetHashResult((int)move.MovingPieceSecondary.SrcPosition, move.MovingPieceSecondary.PieceType, move.MovingPieceSecondary.PieceColor, hash);
                hash = Zobrist.GetHashResult((int)move.MovingPieceSecondary.DstPosition, move.MovingPieceSecondary.PieceType, move.MovingPieceSecondary.PieceColor, hash);
                if (move.MovingPieceSecondary.PieceColor == ChessPieceColor.White)
                {
                    hash ^= Zobrist.ZobristTable[770];
                }
                else
                {
                    hash ^= Zobrist.ZobristTable[771];
                }
            }
            if (move.TakenPiece.PieceType != ChessPieceType.None)
            {
                hash = Zobrist.GetHashResult((int)move.TakenPiece.Position, move.TakenPiece.PieceType, move.TakenPiece.PieceColor, hash);
            }
            hash = !pawnPromote?Zobrist.GetHashResult((int)move.MovingPiecePrimary.DstPosition, move.MovingPiecePrimary.PieceType, move.MovingPiecePrimary.PieceColor, hash) : Zobrist.GetHashResult((int)move.MovingPiecePrimary.DstPosition, ChessPieceType.Queen, move.MovingPiecePrimary.PieceColor, hash);

            if (whosMove == ChessPieceColor.White)
            {
                hash ^= Zobrist.ZobristTable[769];
                hash ^= Zobrist.ZobristTable[768];
            }
            else
            {
                hash ^= Zobrist.ZobristTable[768];
                hash ^= Zobrist.ZobristTable[769];
            }
            return(hash);
        }