Exemple #1
0
        public void ZobristUpdateTest_DisableCastling()
        {
            Move  move         = new Move(gameState, BitboardUtils.GetBitboard(6), BitboardUtils.GetBitboard(7), PieceType.King);
            ulong expectedHash = GetPieceBitstring(0, PieceType.King, 6) ^ GetPieceBitstring(0, PieceType.King, 7) ^ GetBlackTurnBitstring();

            TestMove("r4k2/1p4pp/pb6/3N2B1/4Q1b1/P4N2/1pn2PPP/4RRK1 w - - 2 12", move, expectedHash);

            move         = new Move(gameState, BitboardUtils.GetBitboard(4), BitboardUtils.GetBitboard(13), PieceType.King);
            expectedHash = GetPieceBitstring(0, PieceType.King, 4) ^ GetPieceBitstring(0, PieceType.King, 13)
                           ^ GetPieceBitstring(1, PieceType.Knight, 13) ^ GetCastlingBitstring()[0, 0] ^ GetCastlingBitstring()[0, 1] ^ GetBlackTurnBitstring();
            TestMove("rnbqkb1r/pp1p1ppp/2p5/4P3/2B5/8/PPP1NnPP/RNBQK2R w KQkq - 0 1", move, expectedHash);

            move         = new CastlingMove(gameState, BitboardUtils.GetBitboard(60), BitboardUtils.GetBitboard(58));
            expectedHash = GetPieceBitstring(1, PieceType.King, 60) ^ GetPieceBitstring(1, PieceType.King, 58)
                           ^ GetPieceBitstring(1, PieceType.Rook, 56) ^ GetPieceBitstring(1, PieceType.Rook, 59)
                           ^ GetCastlingBitstring()[1, 0] ^ GetBlackTurnBitstring();
            TestMove("r3kbr1/pp3ppp/n1p5/3pP1q1/2B2Nb1/2N1B3/PPPQ1KPP/4R2R b q - 5 6", move, expectedHash);

            move         = new Move(gameState, BitboardUtils.GetBitboard(7), BitboardUtils.GetBitboard(6), PieceType.Rook);
            expectedHash = GetPieceBitstring(0, PieceType.Rook, 7) ^ GetPieceBitstring(0, PieceType.Rook, 6)
                           ^ GetCastlingBitstring()[0, 1] ^ GetBlackTurnBitstring();
            TestMove("rnbqkb1r/pp1p1ppp/2p5/4P3/2B5/8/PPP1NnPP/RNBQK2R w KQkq - 0 1", move, expectedHash);

            move         = new Move(gameState, BitboardUtils.GetBitboard(13), BitboardUtils.GetBitboard(7), PieceType.Knight);
            expectedHash = GetPieceBitstring(1, PieceType.Knight, 13) ^ GetPieceBitstring(1, PieceType.Knight, 7)
                           ^ GetPieceBitstring(0, PieceType.Rook, 7) ^ GetCastlingBitstring()[0, 1] ^ GetBlackTurnBitstring();
            TestMove("rnbqkb1r/pp1p1ppp/2p5/4P3/2B5/2N5/PPP1NnPP/R1BQK2R b KQkq - 1 1", move, expectedHash);
        }
Exemple #2
0
        public override ulong GenerateAttacksFromSquare(int sqInd)
        {
            ulong pawn = BitboardUtils.GetBitboard(sqInd);
            int   pl   = (gameState.Pieces[0, (int)pieceType] & pawn) > 0 ? 0 : 1;

            return(GenerateAttacksByPawns(pawn, pl));
        }
        protected virtual int EvaluateMaterial(int pl, PieceType pieceType, int[] materialArr)
        {
            int score = BitboardUtils.Popcount(gameState.Pieces[pl, (int)pieceType]) * config.GetPieceValue(pieceType);

            materialArr[pl] += score;
            return(ApplySign(pl, score));
        }
        /// <summary>
        /// Adds or removes a piece on the given position, depending on whether there's already a piece there
        /// </summary>
        /// <param name="hash"></param>
        /// <param name="pl"></param>
        /// <param name="pieceType"></param>
        /// <param name="pos"></param>
        public void UpdatePiece(ref ulong hash, int pl, PieceType pieceType, ulong pos)
        {
            int sqInd = BitboardUtils.BitScanForward(pos);
            int pInd  = GetPieceIndex(pl, pieceType);

            hash ^= piecePosBitstring[pInd, sqInd];
        }
Exemple #5
0
        public void PopcountSpeedTest()
        {
            Stopwatch stopwatch = new Stopwatch();
            int       amount    = 100000000;

            stopwatch.Start();
            for (int i = 0; i < amount; i++)
            {
                ulong bb = BitboardUtils.RandomBitstring();
                BitboardUtils.SparsePopcount(bb);
            }
            stopwatch.Stop();
            long sparsePopcountTime = stopwatch.ElapsedMilliseconds;

            stopwatch.Restart();
            for (int i = 0; i < amount; i++)
            {
                ulong bb = BitboardUtils.RandomBitstring();
                BitboardUtils.Popcount(bb);
            }
            stopwatch.Stop();
            long popcountTime = stopwatch.ElapsedMilliseconds;

            Console.WriteLine($"Popcount: {popcountTime}ms,\nSparse Popcount: {sparsePopcountTime}ms");
        }
Exemple #6
0
        public override GameAction GetAction()
        {
            int        target = BitboardUtils.BitScanForward(GetEnPassantTarget());
            GameAction action = new GameAction(gameState, this, BitboardUtils.BitScanForward(From), BitboardUtils.BitScanForward(To), target);

            return(action);
        }
        protected virtual int CalculateIsolatedPawnPenalty(int pl, int pawnRank, int pawnFile, ulong leftRightFilesMask, ulong pawns, ulong opPawns)
        {
            int score = 0;

            if ((pawns & leftRightFilesMask) == 0)
            {
                ulong aboveMask = BitboardUtils.GetFileMask(pawnFile);
                if (pl == 0)
                {
                    aboveMask <<= (pawnRank + 1) * 8;
                }
                else
                {
                    aboveMask >>= (8 - pawnRank) * 8;
                }
                if ((opPawns & aboveMask) == 0)
                {
                    score = config.GetIsolatedPawnOpenFilePenalty();
                }
                else
                {
                    score = config.GetIsolatedPawnPenalty();
                }
            }
            return(score);
        }
        protected virtual int EvaluateKnightSquare(int pl, int sq)
        {
            int   file          = BitboardUtils.GetFile(sq);
            int   rank          = BitboardUtils.GetRank(sq);
            ulong leftFileMask  = file > 0 ? BitboardUtils.GetFileMask(file - 1) : 0;
            ulong rightFileMask = file < 7 ? BitboardUtils.GetFileMask(file + 1) : 0;
            ulong fileMask      = leftFileMask | rightFileMask;

            if (pl == 0)
            {
                fileMask <<= (rank + 1) * 8;
            }
            else
            {
                fileMask >>= (8 - rank) * 8;
            }
            bool outpost = false;

            if ((gameState.Pieces[1 - pl, (int)PieceType.Pawn] & fileMask) == 0)
            {
                outpost = true;
            }
            ulong pawnDefenders       = gameState.MoveGenerators[(int)PieceType.Pawn].GenerateAttacksFromSquare(sq, 1 - pl) & gameState.Pieces[pl, (int)PieceType.Pawn];
            int   pawnDefendersAmount = BitboardUtils.SparsePopcount(pawnDefenders);
            int   score = config.GetKnightSquareScore(pl, sq, pawnDefendersAmount, outpost);

            return(ApplySign(pl, score));
        }
        protected virtual int EvaluateRookRank(int pl, int rookSqInd, GameStage gameStage)
        {
            int rank  = BitboardUtils.GetRank(rookSqInd);
            int score = config.GetRookRankScore(pl, rank, gameStage);

            return(ApplySign(pl, score));
        }
Exemple #10
0
        public void GetMSBTest()
        {
            ulong bb1         = BitboardUtils.GetMSB(0b01110100011100);
            ulong expectedBb1 = 0b1000000000000;

            ulong bb2         = BitboardUtils.GetMSB(0b111);
            ulong expectedBb2 = 0b100;

            ulong bb3         = BitboardUtils.GetMSB(0b1001110010);
            ulong expectedBb3 = 0b1000000000;

            ulong bb4         = BitboardUtils.GetMSB(0b1000000);
            ulong expectedBb4 = 0b1000000;

            ulong bb5         = BitboardUtils.GetMSB(0);
            ulong expectedBb5 = 0;

            ulong bb6         = BitboardUtils.GetMSB(0x30AB067088F2);
            ulong expectedBb6 = 0x200000000000;


            Assert.AreEqual(expectedBb1, bb1);
            Assert.AreEqual(expectedBb2, bb2);
            Assert.AreEqual(expectedBb3, bb3);
            Assert.AreEqual(expectedBb4, bb4);
            Assert.AreEqual(expectedBb5, bb5);
            Assert.AreEqual(expectedBb6, bb6);
        }
        protected virtual int EvaluatePieceCenterControl(int pl, PieceType pieceType, ulong pieceAttacks)
        {
            ulong pieceCenterControl = (gameState.Pieces[pl, (int)pieceType] | pieceAttacks) & BitboardUtils.EXTENDED_CENTER_MASK;
            int   score = BitboardUtils.Popcount(pieceCenterControl) * config.GetPieceCentralControlScore();

            return(ApplySign(pl, score));
        }
Exemple #12
0
        public void UpdatePiecesAfterActionUndo(GameAction action)
        {
            UIPiece piece = GetPieceByPos(action.To);

            piece.UpdatePosition(action.From);

            if (action.Capture != null)
            {
                ulong     capturedBB        = BitboardUtils.GetBitboard(action.Capture.Value);
                PieceType capturedPieceType = gameState.GetPieceBySquare(1 - gameState.Turn, capturedBB).Value;
                CreatePiece(capturedPieceType, 1 - gameState.Turn, action.Capture.Value);
            }

            if (action.ChangeType != null)
            {
                ulong     fromBB            = BitboardUtils.GetBitboard(action.From);
                PieceType originalPieceType = gameState.GetPieceBySquare(gameState.Turn, fromBB).Value;
                piece.ChangeType(originalPieceType);
            }

            if (action.ExtraAction != null)
            {
                UpdatePiecesAfterActionUndo(action.ExtraAction);
            }
        }
        protected virtual int EvaluateEndgameKingSquare(int pl)
        {
            int kingSq = BitboardUtils.GetSquareInd(gameState.Pieces[pl, (int)PieceType.King]);
            int score  = config.GetEndgameKingSquareScore(pl, kingSq);

            return(ApplySign(pl, score));
        }
Exemple #14
0
 public int GetEndgameKingSquareScore(int pl, int kingSq)
 {
     if (pl == 1)
     {
         kingSq = BitboardUtils.MirrorRank(kingSq);
     }
     return(endgameKingSquare[kingSq]);
 }
        protected virtual int CalculatePieceKingAttackScore(int pl, PieceType pieceType, ulong directKingAttacks, ulong quarterKingAttacks, double kingAttackModifier, int[] kingAttacksScore)
        {
            int score = (int)((BitboardUtils.SparsePopcount(directKingAttacks) * config.GetPieceAttackScore(pieceType) +
                               BitboardUtils.Popcount(quarterKingAttacks) * config.GetExtendedPieceAttackScore(pieceType)) * kingAttackModifier);

            kingAttacksScore[pl] += score;
            return(score);
        }
Exemple #16
0
 public void PopcountCompareTest()
 {
     for (int i = 0; i < 10000; i++)
     {
         ulong bb = BitboardUtils.RandomBitstring();
         Assert.AreEqual(BitboardUtils.Popcount(bb), BitboardUtils.SparsePopcount(bb));
     }
 }
        protected int GetOpposition()
        {
            int wking      = BitboardUtils.GetSquareInd(gameState.Pieces[0, (int)PieceType.King]);
            int bking      = BitboardUtils.GetSquareInd(gameState.Pieces[1, (int)PieceType.King]);
            int distance   = BitboardUtils.Distance(wking, bking);
            int opposition = distance % 2 == 0 ? 1 - gameState.Turn : gameState.Turn;

            return(opposition);
        }
        public void UpdatePiecePos(ref ulong hash, int pl, PieceType pieceType, ulong from, ulong to)
        {
            int fromInd = BitboardUtils.BitScanForward(from);
            int toInd   = BitboardUtils.BitScanForward(to);
            int pInd    = GetPieceIndex(pl, pieceType);

            hash ^= piecePosBitstring[pInd, fromInd];
            hash ^= piecePosBitstring[pInd, toInd];
        }
        protected virtual int CalculatePieceKingDefenseScore(int pl, PieceType pieceType, ulong pieceAttacks, ulong opKingAttacks, ulong kingSurrounding, int[] kingAttacksScore)
        {
            ulong defense         = opKingAttacks & pieceAttacks & kingSurrounding;
            ulong extendedDefense = (opKingAttacks & pieceAttacks) ^ defense;
            int   score           = BitboardUtils.Popcount(defense) * config.GetPieceDefenseScore(pieceType) +
                                    BitboardUtils.Popcount(extendedDefense) * config.GetExtendedPieceDefenseScore(pieceType);

            kingAttacksScore[1 - pl] -= score;
            return(score);
        }
Exemple #20
0
        public override GameAction GetAction()
        {
            int        rookFromInd = BitboardUtils.BitScanForward(AdjustForPl(rookFrom[dir], gameState.Turn));
            int        rookToInd   = BitboardUtils.BitScanForward(AdjustForPl(rookTo[dir], gameState.Turn));
            GameAction rookAction  = new GameAction(gameState, this, rookFromInd, rookToInd);
            GameAction action      = new GameAction(gameState, this, BitboardUtils.BitScanForward(From), BitboardUtils.BitScanForward(To),
                                                    null, null, rookAction);

            return(action);
        }
Exemple #21
0
        public void ZobristUpdateTest_RegularMove()
        {
            Move  move         = new Move(gameState, BitboardUtils.GetBitboard(12), BitboardUtils.GetBitboard(20), PieceType.Pawn);
            ulong expectedHash = GetPieceBitstring(0, PieceType.Pawn, 12) ^ GetPieceBitstring(0, PieceType.Pawn, 20) ^ GetBlackTurnBitstring();

            TestMove("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", move, expectedHash);

            move         = new Move(gameState, BitboardUtils.GetBitboard(36), BitboardUtils.GetBitboard(30), PieceType.Knight);
            expectedHash = GetPieceBitstring(1, PieceType.Knight, 36) ^ GetPieceBitstring(1, PieceType.Knight, 30) ^ GetBlackTurnBitstring();
            TestMove("r2qkb1r/pbp1pppp/1p3n2/3pn3/2BP4/5N2/PPP2PPP/RNBQR1K1 b kq - 1 7", move, expectedHash);
        }
        protected virtual int EvaluatePawnStorm(int pl, ulong pawnsOnFile, double kingAttackModifier)
        {
            int score = 0;

            if (pawnsOnFile > 0)
            {
                int pawnRank = BitboardUtils.GetRank(BitboardUtils.GetMostAdvanced(pl, pawnsOnFile));
                score = (int)(config.GetPawnStormScore(pl, pawnRank) * kingAttackModifier);
            }
            return(ApplySign(pl, score));
        }
Exemple #23
0
        /// <summary>
        /// Get a bitboard of the attacks, including friendly attacks (defenders).
        /// </summary>
        /// <param name="pl"></param>
        /// <returns></returns>
        public virtual ulong GenerateAttacks(int pl)
        {
            ulong attacks = 0;
            ulong piece   = gameState.Pieces[pl, (int)pieceType];

            while (piece > 0)
            {
                int from = BitboardUtils.PopLSB(ref piece);
                attacks |= GenerateAttacksFromSquare(from);
            }
            return(attacks);
        }
Exemple #24
0
        public int GetKnightSquareScore(int pl, int sq, int pawnProtectors, bool outpost)
        {
            if (pl == 1)
            {
                sq = BitboardUtils.MirrorRank(sq);
            }
            double score           = knightSquare[sq];
            double outpostModifier = outpost ? knightOutpostModifier : 1;

            score *= Math.Pow(knightPawnProtectorModifier, pawnProtectors) * outpostModifier;
            return((int)score);
        }
Exemple #25
0
        public void ZobristUpdateTest_Promotion()
        {
            Move  move         = new PromotionMove(gameState, BitboardUtils.GetBitboard(52), BitboardUtils.GetBitboard(61), PieceType.Queen);
            ulong expectedHash = GetPieceBitstring(0, PieceType.Pawn, 52) ^ GetPieceBitstring(0, PieceType.Queen, 61)
                                 ^ GetPieceBitstring(1, PieceType.Rook, 61) ^ GetBlackTurnBitstring();

            TestMove("r4rk1/1pp1Pppp/pb6/6B1/2B1n1b1/P1N2N2/1Pn1QPPP/R4RK1 w - - 0 5", move, expectedHash);

            move         = new PromotionMove(gameState, BitboardUtils.GetBitboard(9), BitboardUtils.GetBitboard(1), PieceType.Knight);
            expectedHash = GetPieceBitstring(1, PieceType.Pawn, 9) ^ GetPieceBitstring(1, PieceType.Knight, 1) ^ GetBlackTurnBitstring();
            TestMove("r7/1p3kpp/pb6/3N2B1/4Q1b1/P4N2/1pn2PPP/4RRK1 b - - 1 11", move, expectedHash);
        }
Exemple #26
0
        public override GameAction GetAction()
        {
            int?capture = null;

            if ((gameState.Occupancy[1 - gameState.Turn] & To) > 0)
            {
                capture = BitboardUtils.BitScanForward(To);
            }
            GameAction action = new GameAction(gameState, this, BitboardUtils.BitScanForward(From), BitboardUtils.BitScanForward(To), capture, PromotionType);

            return(action);
        }
        protected virtual int EvaluateRookOpenFile(int pl, int rookSqInd)
        {
            int   score    = 0;
            int   file     = BitboardUtils.GetFile(rookSqInd);
            ulong fileMask = BitboardUtils.GetFileMask(file);
            ulong pawns    = gameState.Pieces[pl, (int)PieceType.Pawn] & fileMask;

            if (pawns == 0)
            {
                score = config.GetRookOpenFileScore();
            }
            return(ApplySign(pl, score));
        }
Exemple #28
0
        protected override IEnumerable <Move> GenerateMovesFromSquare(int sqInd, GenerationMode generationMode = GenerationMode.Normal)
        {
            ulong sq = BitboardUtils.GetBitboard(sqInd);
            IEnumerable <Move> moves = base.GenerateMovesFromSquare(sqInd, generationMode);

            if (generationMode == GenerationMode.Normal)
            {
                IEnumerable <Move> castling = GenerateCastlingMoves(sq);
                moves = castling.Concat(moves);
            }

            return(moves);
        }
Exemple #29
0
        public void ZobristUpdateTest_EnPassant()
        {
            Move  move         = new EnPassantMove(gameState, BitboardUtils.GetBitboard(35), BitboardUtils.GetBitboard(42));
            ulong expectedHash = GetPieceBitstring(0, PieceType.Pawn, 35) ^ GetPieceBitstring(0, PieceType.Pawn, 42)
                                 ^ GetPieceBitstring(1, PieceType.Pawn, 34) ^ GetEnPassantBitstring()[2] ^ GetBlackTurnBitstring();

            TestMove("rnbqkbnr/pp2pppp/8/2pP4/8/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 3", move, expectedHash);

            move         = new Move(gameState, BitboardUtils.GetBitboard(55), BitboardUtils.GetBitboard(39), PieceType.Pawn);
            expectedHash = GetPieceBitstring(1, PieceType.Pawn, 55) ^ GetPieceBitstring(1, PieceType.Pawn, 39)
                           ^ GetEnPassantBitstring()[5] ^ GetEnPassantBitstring()[7] ^ GetBlackTurnBitstring();
            TestMove("r1bk1b1r/pp1n1ppp/5n2/q1pP2P1/N3pP1P/1P6/P1PP4/R1BQKBNR b KQ f3 0 9", move, expectedHash);
        }
Exemple #30
0
        public void ZobristUpdateTest_Capture()
        {
            Move  move         = new Move(gameState, BitboardUtils.GetBitboard(4), BitboardUtils.GetBitboard(28), PieceType.Rook);
            ulong expectedHash = GetPieceBitstring(0, PieceType.Rook, 4) ^ GetPieceBitstring(0, PieceType.Rook, 28)
                                 ^ GetPieceBitstring(1, PieceType.Knight, 28) ^ GetBlackTurnBitstring();

            TestMove("r2q1b1r/pbp1pkpp/1p6/3p4/2BPn3/8/PPP2PPP/RNB1R1K1 w - - 0 10", move, expectedHash);

            move         = new Move(gameState, BitboardUtils.GetBitboard(27), BitboardUtils.GetBitboard(34), PieceType.Pawn);
            expectedHash = GetPieceBitstring(0, PieceType.Pawn, 27) ^ GetPieceBitstring(0, PieceType.Pawn, 34)
                           ^ GetPieceBitstring(1, PieceType.Pawn, 34) ^ GetEnPassantBitstring()[2] ^ GetBlackTurnBitstring();
            TestMove("r2q1b1r/pb2pkpp/1p6/2pp4/P1BPn3/8/1PP2PPP/RNB1R1K1 w - c6 0 11", move, expectedHash);
        }