Beispiel #1
0
        /// <summary>
        /// TODO: API
        /// </summary>
        /// <param name="oppGame"></param>
        /// <param name="opponent">the controller of the opponent</param>
        /// <param name="predicitionMap">the map with all predictions</param>
        /// <param name="newSimulations"></param>
        /// <returns></returns>
        private double simulateOpponentWithPrediction(double lowerTimeBound, double timePerLeaf, POGame.POGame oppGame, Controller opponent,
                                                      List <Prediction> predicitionMap, ref Dictionary <POGame.POGame, List <MCTSNode> > newSimulations)
        {
            double predictionScore = 0;

            if (predicitionMap?.Any() ?? false)
            {
                int denominator = predicitionMap.Count;
                var scorings    = predicitionMap.GroupBy(p => p.Deck.Scoring)
                                  .Select(c => new MCTSNode.ScoreExt(((double)c.Count() / denominator), c.Key))
                                  .OrderByDescending(s => s.Value).ToList();

                // the simulation time for one prediction
                double timePerPrediction = timePerLeaf / predicitionMap.Count;

                // use prediction for each game
                for (int i = 0; i < predicitionMap.Count; i++)
                {
                    Prediction prediction   = predicitionMap[i];
                    var        setasideZone = opponent.ControlledZones[Zone.SETASIDE] as SetasideZone;
                    setasideZone = new SetasideZone(opponent);

                    // create deck zone
                    List <Card> deckCards = prediction.Deck.Cards;
                    var         deckZone  = opponent.ControlledZones[Zone.DECK] as DeckZone;
                    deckZone = new DeckZone(opponent);
                    createZone(opponent, deckCards, deckZone, ref setasideZone);
                    deckZone.Shuffle();

                    // create hand zone
                    List <Card> handCards = prediction.Hand.Cards;
                    var         handZone  = opponent.ControlledZones[Zone.HAND] as HandZone;
                    handZone = new HandZone(opponent);
                    createZone(opponent, handCards, handZone, ref setasideZone);

                    var    oppLeafNodes = new List <MCTSNode>();
                    IScore oppStrategy  = prediction.Deck.Scoring;

                    // forward game
                    POGame.POGame forwardGame = oppGame.getCopy();

                    // upper time bound for simulation the opponent using the current prediction
                    double oppSimulationTime = lowerTimeBound + (i + 1) * timePerPrediction / 2;

                    // simulate opponent's moves
                    while (forwardGame != null &&
                           forwardGame.State == State.RUNNING &&
                           forwardGame.CurrentPlayer.Id == opponent.Id)
                    {
                        // simulate
                        var      oppRoot     = new MCTSNode(opponent.Id, scorings, forwardGame, null, null);
                        MCTSNode bestOppNode = simulate(oppSimulationTime, oppRoot, ref oppLeafNodes);
                        // get solution
                        List <PlayerTask> solutions = bestOppNode.GetSolution();
                        for (int j = 0; j < solutions.Count && (forwardGame != null); j++)
                        {
                            PlayerTask oppTask = solutions[j];
                            Dictionary <PlayerTask, POGame.POGame> dir = forwardGame.Simulate(new List <PlayerTask> {
                                oppTask
                            });
                            forwardGame = dir[oppTask];

                            if (forwardGame != null && forwardGame.CurrentPlayer.Choice != null)
                            {
                                break;
                            }
                        }
                    }

                    // upper time bound for simulation the player using the forwarded game
                    double simulationTime = oppSimulationTime + timePerPrediction / 2;
                    double score          = 0;
                    var    leafs          = new List <MCTSNode>();

                    // simulate player using forwarded opponent game
                    while (forwardGame != null &&
                           forwardGame.State == State.RUNNING &&
                           forwardGame.CurrentPlayer.Id == _playerId)
                    {
                        // simulate
                        var root = new MCTSNode(_playerId, new List <MCTSNode.ScoreExt> {
                            new MCTSNode.ScoreExt(1.0, _scoring)
                        }, forwardGame, null, null);
                        MCTSNode bestNode = simulate(simulationTime, root, ref leafs);
                        // get solution
                        List <PlayerTask> solutions = bestNode.GetSolution();
                        for (int j = 0; j < solutions.Count && (forwardGame != null); j++)
                        {
                            PlayerTask task = solutions[j];
                            Dictionary <PlayerTask, POGame.POGame> dir = forwardGame.Simulate(new List <PlayerTask> {
                                task
                            });
                            forwardGame = dir[task];

                            if (forwardGame != null && forwardGame.CurrentPlayer.Choice != null)
                            {
                                break;
                            }
                        }
                        // TODO: maybe penalty forwardGame == null
                        score = bestNode.TotalScore;
                    }
                    predictionScore += score;

                    if (forwardGame != null)
                    {
                        newSimulations.Add(forwardGame, leafs);
                    }
                }
            }
            return(predictionScore);
        }
Beispiel #2
0
        /// <summary>
        /// TODO: API
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public override MCTSNode simulate(POGame.POGame game)
        {
            POGame.POGame gameCopy = game.getCopy();

            // initials root node
            var initLeafs = new List <MCTSNode>();
            var root      = new MCTSNode(_playerId, new List <MCTSNode.ScoreExt> {
                new MCTSNode.ScoreExt(1.0, _scoring)
            }, gameCopy, null, null);

            // simulate
            MCTSNode bestNode = simulate(_deltaTime, root, ref initLeafs);

            // initials opponent's history
            if (_oppHistory == null)
            {
                List <PlayHistoryEntry> history     = gameCopy.CurrentOpponent.PlayHistory;
                PlayHistoryEntry[]      copyHistory = new PlayHistoryEntry[history.Count];
                history.CopyTo(copyHistory);
                _oppHistory = copyHistory.ToList();
            }

            var simulationQueue = new Queue <KeyValuePair <POGame.POGame, List <MCTSNode> > >();

            simulationQueue.Enqueue(new KeyValuePair <POGame.POGame, List <MCTSNode> >(gameCopy, initLeafs));

            int i = 0;

            while (i < _predictionParameters.SimulationDepth &&
                   simulationQueue.Count > 0)
            {
                // calculate the lower and upper time bound of the current depth
                double lowerSimulationTimeBound = _deltaTime + i * (2 * _deltaTime);

                KeyValuePair <POGame.POGame, List <MCTSNode> > simulation = simulationQueue.Dequeue();
                POGame.POGame   simulationGame = simulation.Key;
                List <MCTSNode> leafs          = simulation.Value;

                leafs = leafs.Where(l => l.Game != null)
                        .OrderByDescending(l => l.Score)
                        .Take((leafs.Count > _predictionParameters.LeafCount)
                                                        ? _predictionParameters.LeafCount : leafs.Count)
                        .ToList();
                if (leafs.Count() < 0)
                {
                    return(bestNode);
                }

                Controller        opponent       = getOpponent(simulationGame);
                List <Prediction> predicitionMap = getPredictionMap(simulationGame, opponent);
                var oldSimulations = new Dictionary <POGame.POGame, List <MCTSNode> >();

                // the simulation time for one leaf
                double timePerLeaf = (2 * _deltaTime) / leafs.Count;

                // get all games from all leaf nodes
                for (int j = 0; j < leafs.Count; j++)
                {
                    // calculate the lower time bound of the current leaf
                    double lowerLeafTimeBound = lowerSimulationTimeBound + j * timePerLeaf;

                    MCTSNode      leafNode = leafs[j];
                    POGame.POGame oppGame  = leafNode.Game;
                    double        leafScore;
                    // XXX: game can be null

                    leafScore = simulateOpponentWithPrediction(lowerLeafTimeBound, timePerLeaf,
                                                               oppGame, opponent, predicitionMap, ref oldSimulations);
                    // back-propagate score
                    backpropagate(leafNode, leafScore);
                }

                var newSimulations = new Dictionary <POGame.POGame, List <MCTSNode> >();
                oldSimulations.ToList()
                .OrderByDescending(s => s.Value.Sum(l => l.TotalScore))
                .Take((leafs.Count > _predictionParameters.OverallLeafCount) ? _predictionParameters.OverallLeafCount : leafs.Count)
                .ToList()
                .ForEach(l => newSimulations.Add(l.Key, l.Value));

                // add new simulations
                foreach (KeyValuePair <POGame.POGame, List <MCTSNode> > sim in oldSimulations)
                {
                    simulationQueue.Enqueue(sim);
                }
                i++;
            }
            return(root.Children
                   .OrderByDescending(c => c.TotalScore)
                   .First());
        }
Beispiel #3
0
 /// <summary>
 /// The expanditation step of the MCTS which adds all children to the selected leaf node.
 /// </summary>
 /// <param name="selectedNode">the selected leaf node</param>
 protected void expand(MCTSNode selectedNode)
 {
     // TODO: add something like a expansion-threshold
     selectedNode.Children = selectedNode
                             .Tasks.Select(t => new MCTSNode(selectedNode.Game, t, selectedNode)).ToList();
 }