Beispiel #1
0
        private double CalculateBoardScore(GameBoard gameBoard)
        {
            // Always score from white's point of view

            if (gameBoard.BoardState == BoardState.WhiteWins)
            {
                return(double.PositiveInfinity);
            }
            else if (gameBoard.BoardState == BoardState.BlackWins)
            {
                return(double.NegativeInfinity);
            }
            else if (gameBoard.BoardState == BoardState.Draw)
            {
                return(0.0);
            }

            ulong key = gameBoard.ZobristKey;

            if (_cachedBoardScores.TryLookup(key, out double score))
            {
                return(score);
            }

            BoardMetrics boardMetrics = gameBoard.GetBoardMetrics();

            score = CalculateBoardScore(boardMetrics, StartMetricWeights, EndMetricWeights);

            _cachedBoardScores.Store(key, score);

            return(score);
        }
Beispiel #2
0
        private void DeltaFromTransTable(GameBoard gameBoard, HashSet <ulong> visitedKeys, CancellationToken token, out MetricWeights deltaStart, out MetricWeights deltaEnd)
        {
            MetricWeights ds = new MetricWeights();
            MetricWeights de = new MetricWeights();

            ulong key    = gameBoard.ZobristKey;
            bool  newKey = visitedKeys.Add(key);

            if (newKey && TranspositionTable.TryLookup(key, out TranspositionTableEntry tEntry) && tEntry.Depth > 1 && !token.IsCancellationRequested)
            {
                double colorValue = gameBoard.CurrentTurnColor == PlayerColor.White ? 1.0 : -1.0;

                double boardScore = colorValue * TruncateBounds(CalculateBoardScore(gameBoard));

                double storedValue = TruncateBounds(tEntry.Value);

                BoardMetrics boardMetrics = gameBoard.GetBoardMetrics();

                MetricWeights startGradient = GetGradient(boardMetrics);
                MetricWeights endGradient   = startGradient.Clone();

                double scaleFactor = TreeStrapStepConstant * (storedValue - boardScore);

                double startRatio = boardMetrics.PiecesInHand / (double)(boardMetrics.PiecesInHand + boardMetrics.PiecesInPlay);
                double endRatio   = 1 - startRatio;

                startGradient.Scale(scaleFactor * startRatio * colorValue);
                endGradient.Scale(scaleFactor * endRatio * colorValue);

                if ((tEntry.Type == TranspositionTableEntryType.LowerBound || tEntry.Type == TranspositionTableEntryType.Exact) && storedValue > boardScore)
                {
                    ds.Add(startGradient);
                    de.Add(endGradient);
                }

                if ((tEntry.Type == TranspositionTableEntryType.UpperBound || tEntry.Type == TranspositionTableEntryType.Exact) && storedValue < boardScore)
                {
                    ds.Add(startGradient);
                    de.Add(endGradient);
                }

                foreach (Move move in GetValidMoves(gameBoard))
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    gameBoard.TrustedPlay(move);
                    DeltaFromTransTable(gameBoard, visitedKeys, token, out MetricWeights ds1, out MetricWeights de1);
                    ds.Add(ds1);
                    de.Add(de1);
                    gameBoard.UndoLastMove();
                }
            }

            deltaStart = ds;
            deltaEnd   = de;
        }
Beispiel #3
0
        private static double CalculateBoardScore(BoardMetrics boardMetrics, MetricWeights startMetricWeights, MetricWeights endMetricWeights)
        {
            double endScore = CalculateBoardScore(boardMetrics, endMetricWeights);

            if (boardMetrics.PiecesInHand == 0)
            {
                // In "end-game", no need to blend
                return(endScore);
            }
            else
            {
                // Pieces still in hand, blend start and end scores
                double startScore = CalculateBoardScore(boardMetrics, startMetricWeights);

                double startRatio = boardMetrics.PiecesInHand / (double)(boardMetrics.PiecesInHand + boardMetrics.PiecesInPlay);
                double endRatio   = 1 - startRatio;

                return((startRatio * startScore) + (endRatio * endScore));
            }
        }
Beispiel #4
0
        private MetricWeights GetGradient(BoardMetrics boardMetrics)
        {
            MetricWeights gradient = new MetricWeights();

            foreach (PieceName pieceName in EnumUtils.PieceNames)
            {
                BugType bugType = EnumUtils.GetBugType(pieceName);

                double colorValue = EnumUtils.GetColor(pieceName) == PlayerColor.White ? 1.0 : -1.0;

                gradient.Set(bugType, BugTypeWeight.InPlayWeight, gradient.Get(bugType, BugTypeWeight.InPlayWeight) + colorValue * boardMetrics[pieceName].InPlay);
                gradient.Set(bugType, BugTypeWeight.IsPinnedWeight, gradient.Get(bugType, BugTypeWeight.IsPinnedWeight) + colorValue * boardMetrics[pieceName].IsPinned);
                gradient.Set(bugType, BugTypeWeight.IsCoveredWeight, gradient.Get(bugType, BugTypeWeight.IsCoveredWeight) + colorValue * boardMetrics[pieceName].IsCovered);
                gradient.Set(bugType, BugTypeWeight.NoisyMoveWeight, gradient.Get(bugType, BugTypeWeight.NoisyMoveWeight) + colorValue * boardMetrics[pieceName].NoisyMoveCount);
                gradient.Set(bugType, BugTypeWeight.QuietMoveWeight, gradient.Get(bugType, BugTypeWeight.QuietMoveWeight) + colorValue * boardMetrics[pieceName].QuietMoveCount);
                gradient.Set(bugType, BugTypeWeight.FriendlyNeighborWeight, gradient.Get(bugType, BugTypeWeight.FriendlyNeighborWeight) + colorValue * boardMetrics[pieceName].FriendlyNeighborCount);
                gradient.Set(bugType, BugTypeWeight.EnemyNeighborWeight, gradient.Get(bugType, BugTypeWeight.EnemyNeighborWeight) + colorValue * boardMetrics[pieceName].EnemyNeighborCount);
            }

            return(gradient);
        }
Beispiel #5
0
        private static double CalculateBoardScore(BoardMetrics boardMetrics, MetricWeights metricWeights)
        {
            double score = 0;

            foreach (PieceName pieceName in EnumUtils.PieceNames)
            {
                BugType bugType = EnumUtils.GetBugType(pieceName);

                double colorValue = EnumUtils.GetColor(pieceName) == PlayerColor.White ? 1.0 : -1.0;

                score += colorValue * metricWeights.Get(bugType, BugTypeWeight.InPlayWeight) * boardMetrics[pieceName].InPlay;
                score += colorValue * metricWeights.Get(bugType, BugTypeWeight.IsPinnedWeight) * boardMetrics[pieceName].IsPinned;
                score += colorValue * metricWeights.Get(bugType, BugTypeWeight.IsCoveredWeight) * boardMetrics[pieceName].IsCovered;
                score += colorValue * metricWeights.Get(bugType, BugTypeWeight.NoisyMoveWeight) * boardMetrics[pieceName].NoisyMoveCount;
                score += colorValue * metricWeights.Get(bugType, BugTypeWeight.QuietMoveWeight) * boardMetrics[pieceName].QuietMoveCount;
                score += colorValue * metricWeights.Get(bugType, BugTypeWeight.FriendlyNeighborWeight) * boardMetrics[pieceName].FriendlyNeighborCount;
                score += colorValue * metricWeights.Get(bugType, BugTypeWeight.EnemyNeighborWeight) * boardMetrics[pieceName].EnemyNeighborCount;
            }

            return(score);
        }