コード例 #1
0
        public void PawnHashBackPawnTests()
        {
            PawnHashEntry entry = new PawnHashEntry();

            int[] a = new int[] { 0, 15, 4, 0, 9, 15, 3, 2, 11, 8, 10, 0, 15, 15, 14, 1 };
            int[] b = new int[] { 1, 0, 4, 15, 14, 15, 15, 0, 2, 9, 4, 15, 0, 15, 14, 15 };
            for (int x = 0; x < 16; x++)
            {
                entry.SetBackPawnRank(0, x, a[x]);
                entry.SetBackPawnRank(1, x, b[x]);
            }
            for (int x = 0; x < 16; x++)
            {
                Assert.AreEqual(entry.GetBackPawnRank(0, x), a[x]);
                Assert.AreEqual(entry.GetBackPawnRank(1, x), b[x]);
            }
            for (int x = 0; x < 16; x++)
            {
                entry.SetBackPawnRank(0, x, b[x]);
                entry.SetBackPawnRank(1, x, a[x]);
            }
            for (int x = 0; x < 16; x++)
            {
                Assert.AreEqual(entry.GetBackPawnRank(0, x), b[x]);
                Assert.AreEqual(entry.GetBackPawnRank(1, x), a[x]);
            }
            //	make sure copying the struct works correctly
            PawnHashEntry e2;

            e2 = entry;
            for (int x = 0; x < 16; x++)
            {
                Assert.AreEqual(e2.GetBackPawnRank(0, x), b[x]);
                Assert.AreEqual(e2.GetBackPawnRank(1, x), a[x]);
            }
        }
コード例 #2
0
ファイル: GenericChess.cs プロジェクト: ColinSuess/ChessVFork
 protected override void cleanup()
 {
     base.cleanup();
     PawnStructureInfo = new PawnHashEntry();
 }
コード例 #3
0
        public override void AdjustEvaluation(ref int midgameEval, ref int endgameEval)
        {
            // *** CHECK PAWN STRUCTURE HASH TABLE *** //

            if (pawnHashTable == null)
            {
                pawnHashTable = new PawnHashEntry[65536];                 // 2^16 slots (4 MB)
                for (int x = 0; x < 65536; x++)
                {
                    pawnHashTable[x].PassedPawns = new BitBoard(board.NumSquares);
                }
            }

            game.Statistics.PawnHashLookups++;
            int slot = (int)(game.Board.PawnHashCode & 0x000000000000FFFFUL);

            if (pawnHashTable[slot].HashCode == game.Board.PawnHashCode)
            {
                midgameEval += pawnHashTable[slot].MidgameAdjustment;
                endgameEval += pawnHashTable[slot].EndgameAdjustment;
                if (PassedPawnEvaluation == true)
                {
                    EvaluatePassedPawns(pawnHashTable[slot].PassedPawns, ref midgameEval, ref endgameEval);
                }
                chessGame.PawnStructureInfo = pawnHashTable[slot];
                game.Statistics.PawnHashHits++;
                return;
            }


            // *** DETERMINE BASIC PAWN INFO *** //

            int midgameAdjustment = 0;
            int endgameAdjustment = 0;

            //  reset information
            pawnHashTable[slot].PassedPawns.Clear();
            for (int file = 0; file < board.NumFiles + 2; file++)
            {
                player0pawns[file]    = 0;
                player1pawns[file]    = 0;
                player0backPawn[file] = 15;
                player1backPawn[file] = 0;
            }

            //  loop through player 0's pawns
            BitBoard p0pawns = board.GetPieceTypeBitboard(0, pawnTypeNumber);

            while (p0pawns)
            {
                int square = p0pawns.ExtractLSB();
                int file   = board.GetFile(square);
                int rank   = board.GetRank(square);
                player0pawns[file + 1]++;
                if (rank < player0backPawn[file + 1])
                {
                    player0backPawn[file + 1] = rank;
                }
            }

            //  loop through player 1's pawns
            BitBoard p1pawns = board.GetPieceTypeBitboard(1, pawnTypeNumber);

            while (p1pawns)
            {
                int square = p1pawns.ExtractLSB();
                int file   = board.GetFile(square);
                int rank   = board.GetRank(square);
                player1pawns[file + 1]++;
                if (rank > player1backPawn[file + 1])
                {
                    player1backPawn[file + 1] = rank;
                }
            }

            //	Check for cylindrical board.  If we are playing with a
            //	cylindrical board, we need to consider the edges connected.
            if (board is Boards.CylindricalBoard)
            {
                player0pawns[0]    = player0pawns[board.NumFiles];
                player0backPawn[0] = player0backPawn[board.NumFiles];
                player0pawns[board.NumFiles + 1]    = player0pawns[1];
                player0backPawn[board.NumFiles + 1] = player0backPawn[1];
                player1pawns[0]    = player1pawns[board.NumFiles];
                player1backPawn[0] = player1backPawn[board.NumFiles];
                player1pawns[board.NumFiles + 1]    = player1pawns[1];
                player1backPawn[board.NumFiles + 1] = player1backPawn[1];
            }


            // *** APPLY THIS INFO TO EACH PAWN TO DETERMINE STATUS *** //

            //  lopp through player 0's pawns
            p0pawns = board.GetPieceTypeBitboard(0, pawnTypeNumber);
            while (p0pawns)
            {
                int  square   = p0pawns.ExtractLSB();
                int  pawnFile = board.GetFile(square);
                int  pawnRank = board.GetRank(square);
                bool isolated = false;
                bool backward = false;

                if (player0pawns[pawnFile] == 0 &&
                    player0pawns[pawnFile + 2] == 0)
                {
                    //	isolated pawn
                    midgameAdjustment -= Adjustments.IsolatedMidgame;
                    endgameAdjustment -= Adjustments.IsolatedEndgame;
                    isolated           = true;
                }
                if (player0backPawn[pawnFile] > pawnRank &&
                    player0backPawn[pawnFile + 2] > pawnRank)
                {
                    //	backward pawn
                    midgameAdjustment -= Adjustments.BackwardMidgame;
                    endgameAdjustment -= Adjustments.BackwardEndgame;
                    backward           = true;
                }
                if (player1pawns[pawnFile + 1] == 0)
                {
                    //	penalize weak, exposed pawns
                    if (backward)
                    {
                        midgameAdjustment -= Adjustments.WeakExposedMidgame;
                        endgameAdjustment -= Adjustments.WeakExposedEndgame;
                    }
                    if (isolated)
                    {
                        midgameAdjustment -= Adjustments.WeakExposedMidgame;
                        endgameAdjustment -= Adjustments.WeakExposedEndgame;
                    }
                }
                if (player0backPawn[pawnFile + 1] < pawnRank)
                {
                    //	doubled, trippled, etc.
                    midgameAdjustment -= Adjustments.DoubledMidgame;
                    endgameAdjustment -= Adjustments.DoubledEndgame;
                }
                if (pawnRank >= player1backPawn[pawnFile + 1] &&
                    pawnRank >= player1backPawn[pawnFile] &&
                    pawnRank >= player1backPawn[pawnFile + 2] &&
                    (player0pawns[pawnFile + 1] == 1 ||
                     pawnRank > player0backPawn[pawnFile + 1]))
                {
                    //	passed pawn
                    pawnHashTable[slot].PassedPawns.SetBit(square);
//					midgameAdjustment += Adjustments.PassedMidgame;
//					endgameAdjustment += Adjustments.PassedEndgame;
//					if( !isolated )
//					{
//						midgameAdjustment += Adjustments.PassedNotIsolatedMidgame;
//						endgameAdjustment += Adjustments.PassedNotIsolatedEndgame;
//					}
                }
            }

            //  loop through player 1's pawns
            p1pawns = board.GetPieceTypeBitboard(1, pawnTypeNumber);
            while (p1pawns)
            {
                int square   = p1pawns.ExtractLSB();
                int pawnFile = board.GetFile(square);
                int pawnRank = board.GetRank(square);

                bool isolated = false;
                bool backward = false;

                if (player1pawns[pawnFile] == 0 &&
                    player1pawns[pawnFile + 2] == 0)
                {
                    //	isolated pawn
                    midgameAdjustment += Adjustments.IsolatedMidgame;
                    endgameAdjustment += Adjustments.IsolatedEndgame;
                    isolated           = true;
                }
                if (player1backPawn[pawnFile] < pawnRank &&
                    player1backPawn[pawnFile + 2] < pawnRank)
                {
                    //	backward pawn
                    midgameAdjustment += Adjustments.BackwardMidgame;
                    endgameAdjustment += Adjustments.BackwardEndgame;
                    backward           = true;
                }
                if (player0pawns[pawnFile + 1] == 0)
                {
                    //	penalize weak, exposed pawns
                    if (backward)
                    {
                        midgameAdjustment += Adjustments.WeakExposedMidgame;
                        endgameAdjustment += Adjustments.WeakExposedEndgame;
                    }
                    if (isolated)
                    {
                        midgameAdjustment += Adjustments.WeakExposedMidgame;
                        endgameAdjustment += Adjustments.WeakExposedEndgame;
                    }
                }
                if (player1backPawn[pawnFile + 1] > pawnRank)
                {
                    //	doubled, trippled, etc.
                    midgameAdjustment += Adjustments.DoubledMidgame;
                    endgameAdjustment += Adjustments.DoubledEndgame;
                }
                if (pawnRank <= player0backPawn[pawnFile + 1] &&
                    pawnRank <= player0backPawn[pawnFile] &&
                    pawnRank <= player0backPawn[pawnFile + 2] &&
                    (player1pawns[pawnFile + 1] == 1 ||
                     pawnRank < player1backPawn[pawnFile + 1]))
                {
                    //	passed pawn
                    pawnHashTable[slot].PassedPawns.SetBit(square);
//					midgameAdjustment -= Adjustments.PassedMidgame;
//					endgameAdjustment -= Adjustments.PassedEndgame;
//					if( !isolated )
//					{
//						midgameAdjustment -= Adjustments.PassedNotIsolatedMidgame;
//						endgameAdjustment -= Adjustments.PassedNotIsolatedEndgame;
//					}
                }
            }
            if (PassedPawnEvaluation == true)
            {
                EvaluatePassedPawns(pawnHashTable[slot].PassedPawns, ref midgameEval, ref endgameEval);
            }

            //	store this information in the pawn hash table
            pawnHashTable[slot].HashCode          = board.PawnHashCode;
            pawnHashTable[slot].MidgameAdjustment = midgameAdjustment;
            pawnHashTable[slot].EndgameAdjustment = endgameAdjustment;
            for (int file = 0; file < board.NumFiles; file++)
            {
                pawnHashTable[slot].SetBackPawnRank(0, file, player0backPawn[file + 1]);
                pawnHashTable[slot].SetBackPawnRank(1, file, player1backPawn[file + 1]);
            }
            chessGame.PawnStructureInfo = pawnHashTable[slot];

            //	adjust the actual evaluations accordingly
            midgameEval += midgameAdjustment;
            endgameEval += endgameAdjustment;
        }
コード例 #4
0
        // *** OVERRIDES *** //

        public override void AdjustEvaluation(ref int midgameEval, ref int endgameEval)
        {
            int   penalty;
            int   kingsq;
            int   kingrank;
            int   kingfile;
            int   pawnguards;
            int   sq;
            Piece p;

            PawnHashEntry pawnhash = chessGame.PawnStructureInfo;

            // *** PLAYER 0 *** //

            penalty  = 0;
            kingsq   = board.GetPieceTypeBitboard(0, kingTypeNumber).LSB;
            kingrank = board.GetRank(kingsq);
            kingfile = board.GetFile(kingsq);

            // count pawn guards
            pawnguards = 0;
            if (kingfile == 0)
            {
                pawnguards++;
            }
            else
            {
                sq = board.NextSquare(PredefinedDirections.NW, kingsq);
                if (sq >= 0)
                {
                    p = board[sq];
                    if (p != null && p.Player == 0 && p.TypeNumber == pawnTypeNumber)
                    {
                        pawnguards++;
                    }
                }
            }
            if (kingfile == board.NumFiles - 1)
            {
                pawnguards++;
            }
            else
            {
                sq = board.NextSquare(PredefinedDirections.NE, kingsq);
                if (sq >= 0)
                {
                    p = board[sq];
                    if (p != null && p.Player == 0 && p.TypeNumber == pawnTypeNumber)
                    {
                        pawnguards++;
                    }
                }
            }
            sq = board.NextSquare(PredefinedDirections.N, kingsq);
            if (sq >= 0)
            {
                p = board[sq];
                if (p != null && p.Player == 0 && p.TypeNumber == pawnTypeNumber)
                {
                    pawnguards++;
                }
            }
            //	determine penalty for bad pawn protection
            penalty = 3 - pawnguards;
            if (kingrank != 0)
            {
                penalty += 3;
                if (kingfile == 0)
                {
                    penalty--;
                }
                else
                {
                    sq = board.NextSquare(PredefinedDirections.W, kingsq);
                    p  = board[sq];
                    if (p != null && p.Player == 0 && p.TypeNumber == pawnTypeNumber)
                    {
                        penalty--;
                    }
                }
                if (kingfile == board.NumFiles - 1)
                {
                    penalty--;
                }
                else
                {
                    sq = board.NextSquare(PredefinedDirections.E, kingsq);
                    p  = board[sq];
                    if (p != null && p.Player == 0 && p.TypeNumber == pawnTypeNumber)
                    {
                        penalty--;
                    }
                }
            }
            //	penalty for being on or adjacent to open file or in front of pawn line
            int a = pawnhash.GetBackPawnRank(0, kingfile);

            if (pawnhash.GetBackPawnRank(0, kingfile) == 15 ||
                pawnhash.GetBackPawnRank(0, kingfile) < board.GetRank(kingsq))
            {
                penalty += 2;
            }
            else if (kingfile > 0 &&
                     (pawnhash.GetBackPawnRank(0, kingfile - 1) == 15 ||
                      pawnhash.GetBackPawnRank(0, kingfile - 1) < board.GetRank(kingsq)))
            {
                penalty += 2;
            }
            else if (kingfile < board.NumFiles - 1 &&
                     (pawnhash.GetBackPawnRank(0, kingfile + 1) == 15 ||
                      pawnhash.GetBackPawnRank(0, kingfile + 1) < board.GetRank(kingsq)))
            {
                penalty += 2;
            }
            //	penalty for being close to enemy pieces of tropism types
            foreach (int type in tropismTypes)
            {
                BitBoard bb = board.GetPieceTypeBitboard(1, type);
                while (bb)
                {
                    int psq      = bb.ExtractLSB();
                    int distance = board.GetDistance(kingsq, psq);
                    if (distance < 3)
                    {
                        penalty++;
                        if (distance == 1)
                        {
                            penalty += 2;
                        }
                    }
                }
            }
            //	assess penalty
            midgameEval -= penalty * 4;
            if (penalty >= 2)
            {
                midgameEval -= (penalty - 1) * 3;
            }
            if (penalty >= 4)
            {
                midgameEval -= (penalty - 3) * 4;
            }


            // *** PLAYER 1 *** //

            penalty  = 0;
            kingsq   = board.GetPieceTypeBitboard(1, kingTypeNumber).LSB;
            kingrank = board.GetRank(kingsq);
            kingfile = board.GetFile(kingsq);

            // count pawn guards
            pawnguards = 0;
            if (kingfile == 0)
            {
                pawnguards++;
            }
            else
            {
                sq = board.NextSquare(PredefinedDirections.SW, kingsq);
                if (sq >= 0)
                {
                    p = board[sq];
                    if (p != null && p.Player == 1 && p.TypeNumber == pawnTypeNumber)
                    {
                        pawnguards++;
                    }
                }
            }
            if (kingfile == board.NumFiles - 1)
            {
                pawnguards++;
            }
            else
            {
                sq = board.NextSquare(PredefinedDirections.SE, kingsq);
                if (sq >= 0)
                {
                    p = board[sq];
                    if (p != null && p.Player == 1 && p.TypeNumber == pawnTypeNumber)
                    {
                        pawnguards++;
                    }
                }
            }
            sq = board.NextSquare(PredefinedDirections.S, kingsq);
            if (sq >= 0)
            {
                p = board[sq];
                if (p != null && p.Player == 1 && p.TypeNumber == pawnTypeNumber)
                {
                    pawnguards++;
                }
            }
            //	determine penalty for bad pawn protection
            penalty = 3 - pawnguards;
            if (kingrank != board.NumRanks - 1)
            {
                penalty += 3;
                if (kingfile == 0)
                {
                    penalty--;
                }
                else
                {
                    sq = board.NextSquare(PredefinedDirections.W, kingsq);
                    p  = board[sq];
                    if (p != null && p.Player == 1 && p.TypeNumber == pawnTypeNumber)
                    {
                        penalty--;
                    }
                }
                if (kingfile == board.NumFiles - 1)
                {
                    penalty--;
                }
                else
                {
                    sq = board.NextSquare(PredefinedDirections.E, kingsq);
                    p  = board[sq];
                    if (p != null && p.Player == 1 && p.TypeNumber == pawnTypeNumber)
                    {
                        penalty--;
                    }
                }
            }
            //	penalty for being on or adjacent to open file or in front of pawn line
            if (pawnhash.GetBackPawnRank(0, kingfile) == 0 ||
                pawnhash.GetBackPawnRank(0, kingfile) > board.GetRank(kingsq))
            {
                penalty += 2;
            }
            else if (kingfile > 0 &&
                     (pawnhash.GetBackPawnRank(0, kingfile - 1) == 0 ||
                      pawnhash.GetBackPawnRank(0, kingfile - 1) > board.GetRank(kingsq)))
            {
                penalty += 2;
            }
            else if (kingfile < board.NumFiles - 1 &&
                     (pawnhash.GetBackPawnRank(0, kingfile + 1) == 0 ||
                      pawnhash.GetBackPawnRank(0, kingfile + 1) > board.GetRank(kingsq)))
            {
                penalty += 2;
            }
            //	penalty for being close to enemy pieces of tropism types
            foreach (int type in tropismTypes)
            {
                BitBoard bb = board.GetPieceTypeBitboard(0, type);
                while (bb)
                {
                    int psq      = bb.ExtractLSB();
                    int distance = board.GetDistance(kingsq, psq);
                    if (distance < 3)
                    {
                        penalty++;
                        if (distance == 1)
                        {
                            penalty += 2;
                        }
                    }
                }
            }
            //	assess penalty
            midgameEval += penalty * 4;
            if (penalty >= 2)
            {
                midgameEval += (penalty - 1) * 3;
            }
            if (penalty >= 4)
            {
                midgameEval += (penalty - 3) * 4;
            }
        }