Example #1
0
        private float Simulation(Node nodeToSimulate, POGame.POGame poGame)
        {
            float      result          = -1;
            int        simulationSteps = 0;
            PlayerTask task            = null;

            List <PlayerTask> taskToSimulate = new List <PlayerTask>();

            if (poGame == null)
            {
                return(0.5f);
            }

            if (nodeToSimulate.task.PlayerTaskType == PlayerTaskType.END_TURN)
            {
                return(Estimator.estimateFromState(ESTIMATION_MODE, poGame));
            }

            while (poGame.getCopy().State != SabberStoneCore.Enums.State.COMPLETE)
            {
                task = SimulationPolicies.selectSimulationPolicy(SIMULATION_POLICY, poGame, Rnd, greedyAgent, CHILDREN_CONSIDERED_SIMULATING);
                taskToSimulate.Add(task);
                if (task.PlayerTaskType != PlayerTaskType.END_TURN)
                {
                    poGame = poGame.Simulate(taskToSimulate)[taskToSimulate[0]];
                }

                taskToSimulate.Clear();

                if (poGame == null)
                {
                    return(0.5f);
                }

                if (task.PlayerTaskType == PlayerTaskType.END_TURN)
                {
                    return(Estimator.estimateFromState(ESTIMATION_MODE, poGame));
                }

                simulationSteps++;
            }


            if (poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.CONCEDED ||
                poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.LOST)
            {
                result = 0;
            }
            else if (poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON)
            {
                result = 1;
            }

            return(result);
        }
        public POOptionNode(POOptionNode parent, POGame.POGame game, int playerId, PlayerTask playerTask, IScore scoring)
        {
            _parent    = parent;
            _game      = game.getCopy();        // create clone
            _playerId  = playerId;
            PlayerTask = playerTask;
            Scoring    = scoring;

            if (!IsRoot)
            {
                Execute();
            }
        }
Example #3
0
        //public MCTSNode(int playerId, IScore scoring, POGame.POGame game, PlayerTask task, MCTSNode parent)
        public MCTSNode(int playerId, List <ScoreExt> scorings, POGame.POGame game, PlayerTask task, MCTSNode parent)
        {
            _parent = parent;
            //_scoring = scoring;
            _scorings = scorings;
            _playerId = playerId;
            //_game = game.Clone();
            _game = game.getCopy();
            _task = task;

            VisitCount = 1;

            if (Task != null)
            {
                //Game.Process(Task);
                Dictionary <PlayerTask, POGame.POGame> dir = Game.Simulate(new List <PlayerTask> {
                    Task
                });
                POGame.POGame newGame = dir[Task];

                Game = newGame;
                // simulation has failed, maybe reduce score?
                if (Game == null)
                {
                    //_gameState = _endTurn = 1;
                    _endTurn = 1;
                }
                else
                {
                    //if (Game.CurrentPlayer.Choice != null)
                    //{
                    //	Console.WriteLine("Choices are null");
                    //}

                    _gameState = Game.State == State.RUNNING ? 0
                                                : (PlayerController.PlayState == PlayState.WON ? 1 : -1);
                    _endTurn = Game.CurrentPlayer.Id != _playerId ? 1 : 0;

                    //Scoring.Controller = PlayerController;
                    //_score = Scoring.Rate();
                    foreach (ScoreExt scoring in Scorings)
                    {
                        scoring.Controller = PlayerController;
                        _score            += scoring.Value * scoring.Rate();
                    }
                    _score     /= Scorings.Count;
                    TotalScore += _score;
                }
            }
        }
Example #4
0
        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);

            return(bestNode);
        }
Example #5
0
            private int Simulate()
            {
                POGame.POGame gameClone     = Game.getCopy();
                int           initialPlayer = gameClone.CurrentPlayer.PlayerId;

                while (true)
                {
                    if (gameClone.State == SabberStoneCore.Enums.State.COMPLETE)
                    {
                        Controller currPlayer = gameClone.CurrentPlayer;
                        if (currPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON &&
                            currPlayer.PlayerId == initialPlayer)
                        {
                            return(1);
                        }
                        if (currPlayer.PlayState == SabberStoneCore.Enums.PlayState.LOST &&
                            currPlayer.PlayerId == initialPlayer)
                        {
                            return(0);
                        }
                    }

                    List <PlayerTask> options = gameClone.CurrentPlayer.Options();



                    int        randomNumber = rand.Next(options.Count);
                    PlayerTask action       = options[randomNumber];
                    try
                    {
                        // Process fails as soon as opponent plays a card, so use simulate here
                        Dictionary <PlayerTask, POGame.POGame> dic = gameClone.Simulate(new List <PlayerTask> {
                            action
                        });
                        gameClone = dic[action];                        //更新遊戲狀態
                        if (gameClone == null)
                        {
                            Debug.WriteLine(action.FullPrint());
                        }
                    }
                    catch (Exception e)
                    {
                        //Debug.WriteLine("Exception during single game simulation");
                        //Debug.WriteLine(e.StackTrace);
                    }
                }
            }
Example #6
0
        private Node Selection(Node root, int iterations, ref POGame.POGame poGame)
        {
            Node   bestNode   = new Node();
            double bestScore  = double.MinValue;
            double childScore = 0;

            POGame.POGame pOGameIfSimulationFail = poGame.getCopy();

            foreach (Node node in root.children)
            {
                childScore = TreePolicies.selectTreePolicy(TREE_POLICY, node, iterations, EXPLORE_CONSTANT, ref poGame, SCORE_IMPORTANCE, greedyAgent);
                if (childScore > bestScore)
                {
                    bestScore = childScore;
                    bestNode  = node;
                }
            }
            List <PlayerTask> taskToSimulate = new List <PlayerTask>();

            taskToSimulate.Add(bestNode.task);

            if (bestNode.task.PlayerTaskType != PlayerTaskType.END_TURN)
            {
                poGame = poGame.Simulate(taskToSimulate)[bestNode.task];
            }

            if (poGame == null)
            {
                root.children.Remove(bestNode);
                if (root.children.Count == 0)
                {
                    root = root.parent;
                }

                poGame = pOGameIfSimulationFail;
                return(Selection(root, iterations, ref poGame));
            }

            if (bestNode.children.Count != 0)
            {
                bestNode = Selection(bestNode, iterations, ref poGame);
            }

            return(bestNode);
        }
Example #7
0
        public override PlayerTask GetMove(POGame.POGame poGame)
        {
            if (poGame.CurrentPlayer.Options().Count == 1)
            {
                return(poGame.CurrentPlayer.Options()[0]);
            }

            Console.WriteLine("Turn #" + poGame.Turn + ": AlvaroAgent needs to take a decision...");
            Console.WriteLine(poGame.FullPrint());
            POGame.POGame initialState = poGame.getCopy();

            Node root = new Node();

            Node  selectedNode;
            Node  nodeToSimulate;
            float scoreOfSimulation;
            int   iterations = 0;

            InitializeRoot(root, initialState);

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            while (stopwatch.ElapsedMilliseconds <= MAX_TIME)
            {
                poGame         = initialState;
                selectedNode   = Selection(root, iterations, ref poGame);
                nodeToSimulate = Expansion(selectedNode, ref poGame);

                Console.WriteLine("Iteration #" + iterations + ": node to be simulated:" + selectedNode);

                for (int i = 0; i < NUM_SIMULATIONS; i++)
                {
                    scoreOfSimulation = Simulation(nodeToSimulate, poGame);
                    Backpropagation(nodeToSimulate, scoreOfSimulation);
                    iterations++;
                }
            }
            stopwatch.Stop();

            PlayerTask selectedTask = SelectAction.selectTask(SELECTION_ACTION_METHOD, root, iterations, EXPLORE_CONSTANT);

            Console.WriteLine("Turn #" + poGame.Turn + ", selected task:" + selectedTask);
            return(selectedTask);
        }
Example #8
0
        private Node Expansion(Node leaf, ref POGame.POGame poGame)
        {
            Node nodeToSimulate;

            POGame.POGame pOGameIfSimulationFail = poGame.getCopy();
            if (leaf.timesVisited == 0 || leaf.depth >= TREE_MAXIMUM_DEPTH || leaf.task.PlayerTaskType == PlayerTaskType.END_TURN)
            {
                nodeToSimulate = leaf;
            }
            else
            {
                foreach (PlayerTask task in poGame.CurrentPlayer.Options())
                {
                    leaf.children.Add(new Node(task, leaf, leaf.depth + 1));
                }

                nodeToSimulate = leaf.children[0];
                List <PlayerTask> taskToSimulate = new List <PlayerTask>();
                taskToSimulate.Add(nodeToSimulate.task);
                if (nodeToSimulate.task.PlayerTaskType != PlayerTaskType.END_TURN)
                {
                    poGame = poGame.Simulate(taskToSimulate)[nodeToSimulate.task];
                }

                while (poGame == null)
                {
                    if (leaf.children.Count <= 1)
                    {
                        return(leaf);
                    }
                    poGame = pOGameIfSimulationFail;
                    taskToSimulate.Clear();
                    leaf.children.Remove(leaf.children[0]);
                    nodeToSimulate = leaf.children[0];
                    taskToSimulate.Add(nodeToSimulate.task);
                    if (nodeToSimulate.task.PlayerTaskType != PlayerTaskType.END_TURN)
                    {
                        poGame = poGame.Simulate(taskToSimulate)[nodeToSimulate.task];
                    }
                }
            }
            return(nodeToSimulate);
        }
Example #9
0
        /// <summary>
        /// simulate the chosen move and update scorematrix with it
        /// </summary>
        /// <param name="poGame"></param>
        /// <param name="task"></param>
        /// <param name="options"></param>
        /// <returns>returns different Task if simulated Task produces errors</returns>
        PlayerTask SimulateNextTaskAndUpdateScoreMatrix(POGame.POGame poGame, PlayerTask task, List <PlayerTask> options)
        {
            POGame.POGame simulatedGame = poGame.getCopy();
            try
            {
                Dictionary <PlayerTask, POGame.POGame> simulatedGames = simulatedGame.Simulate(new List <PlayerTask>()
                {
                    task
                });
                int tries = 0;
                while ((simulatedGames[task] == null || simulatedGames[task].State == SabberStoneCore.Enums.State.INVALID) && options.Count > 1)
                {
                    if (tries > 3)
                    {
                        break;
                    }
                    task           = options[Rnd.Next(options.Count)];
                    simulatedGames = simulatedGame.Simulate(new List <PlayerTask>()
                    {
                        task
                    });
                    tries++;
                }
                simulatedGame.Process(task);
            }
            catch { }

            if (simulatedGame != null)
            {
                gameStateScoreMatrix.VisitState(GetExtensiveScoreParametersOfGame(simulatedGame));
            }
            // check if game is ending to computer reward
            if (simulatedGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON)
            {
                Log(LogLevel.INFO, "Might be winning next round, with health: " + simulatedGame.CurrentPlayer.Hero.Health);
                float additionalReward = Math.Clamp(simulatedGame.CurrentPlayer.Hero.Health / 30, 0, 1) * 100f;
                reward = 100f + additionalReward;
            }

            return(task);
        }
Example #10
0
 public NodeGameState(POGame.POGame poGame, PlayerTask task = null, NodeGameState parent = null)
 {
     chdr        = new List <NodeGameState>();
     prt         = parent;
     game        = poGame.getCopy();
     this.task   = task;
     WasExpanded = false;
     PlayerId    = game.CurrentPlayer.PlayerId;
     if (parent == null)
     {
         isEnemyNode = false;                             // root is always MyPlayer
     }
     else if (PlayerId != parent.PlayerId)
     {
         isEnemyNode = !parent.isEnemyNode;
     }
     else
     {
         isEnemyNode = parent.isEnemyNode;
     }
 }
Example #11
0
        public static PlayerTask GetBestAction(POGame.POGame game, int iterations)
        {
            TaskNode root = new TaskNode(null, null, game.getCopy());

            for (int i = 0; i < iterations; ++i)
            {
                try
                {
                    TaskNode node = root.SelectNode();
                    node = node.Expand();
                    int r = node.SimulateGames(5);
                    node.Backpropagate(r);
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                }
            }

            TaskNode best = null;

            foreach (TaskNode child in root.Children)
            {
                //Console.WriteLine("visits: " + child.TotNumVisits);
                //Console.WriteLine("wins: " + child.Wins);

                if (best == null || child.TotNumVisits > best.TotNumVisits)
                {
                    best = child;
                }
            }

            //Console.WriteLine("best visits: " + best.TotNumVisits);
            //Console.WriteLine("best wins: " + best.Wins);

            return(best.Action);
        }
 public Tree(POGame.POGame game)
 {
     Root = new Node(new State(game.getCopy(false), null));
 }
Example #13
0
        /*
         * public static PlayerTask GetBestAction_iteration(POGame.POGame game, int iterations)
         * {
         *      TaskNode root = new TaskNode(null, null, game.getCopy());
         *
         *      for (int i = 0; i < iterations; ++i)
         *      {
         *              try
         *              {
         *                      TaskNode node = root.SelectNode();
         *                      node = node.Expand();
         *                      int r = node.SimulateGames(10);
         *                      node.Backpropagate(r);
         *              }
         *              catch (Exception e)
         *              {
         *                      Debug.WriteLine(e.Message);
         *                      Debug.WriteLine(e.StackTrace);
         *              }
         *      }
         *
         *      TaskNode best = null;
         *
         *      foreach (TaskNode child in root.Children)
         *      {
         *              //Console.WriteLine("visits: " + child.TotNumVisits);
         *              //Console.WriteLine("wins: " + child.Wins);
         *
         *              if (best == null || child.TotNumVisits > best.TotNumVisits)
         *              {
         *                      best = child;
         *              }
         *      }
         *
         *      //Console.WriteLine("best visits: " + best.TotNumVisits);
         *      //Console.WriteLine("best wins: " + best.Wins);
         *
         *      return best.Action;
         * }
         */

        public static PlayerTask GetBestAction_second(POGame.POGame game, double seconds)
        {
            DateTime start = DateTime.Now;
            TaskNode root  = new TaskNode(null, null, game.getCopy());

            int i = 0;

            while (true)
            {
                if (TimeUp(start, seconds - 0.1))
                {
                    break;
                }

                try
                {
                    TaskNode node = root.SelectNode();
                    if (TimeUp(start, seconds))
                    {
                        break;
                    }

                    node = node.Expand();
                    if (TimeUp(start, seconds))
                    {
                        break;
                    }

                    int r = node.SimulateGames(5);                    //預設5
                    if (TimeUp(start, seconds))
                    {
                        break;
                    }

                    node.Backpropagate(r);
                }
                catch (Exception e)
                {
                    //Debug.WriteLine(e.Message);
                    //Debug.WriteLine(e.StackTrace);
                }

                ++i;
            }

            TaskNode best = null;

            //Console.WriteLine($"Iterations: {i}, Time: " + (DateTime.Now-start).TotalMilliseconds + "ms");

            foreach (TaskNode child in root.Children)
            {
                //Console.WriteLine("visits: " + child.TotNumVisits);
                //Console.WriteLine("wins: " + child.Wins);

                if (best == null || child.TotNumVisits > best.TotNumVisits || (child.TotNumVisits == best.TotNumVisits && child.Wins > best.Wins))
                {
                    best = child;
                }
            }

            //Console.WriteLine("best visits: " + best.TotNumVisits);
            //Console.WriteLine("best wins: " + best.Wins);

            if (best == null)
            {
                //Debug.WriteLine("best == null");
                return(game.CurrentPlayer.Options()[0]);
            }

            //Console.WriteLine("best wins: " + best.Wins + " best visits: " + best.TotNumVisits);
            return(best.Action);
        }
Example #14
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());
        }
Example #15
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);
        }
Example #16
0
        public static int simulation_num = 5; //模擬次數,預設5

        /*
         * public static PlayerTask GetBestAction_iteration(POGame.POGame game, int iterations)
         * {
         *      TaskNode root = new TaskNode(null, null, game.getCopy());
         *
         *      for (int i = 0; i < iterations; ++i)
         *      {
         *              try
         *              {
         *                      TaskNode node = root.SelectNode();
         *                      node = node.Expand();
         *                      int r = node.SimulateGames(simulation_num);
         *                      node.Backpropagate(r);
         *              }
         *              catch (Exception e)
         *              {
         *                      Debug.WriteLine(e.Message);
         *                      Debug.WriteLine(e.StackTrace);
         *              }
         *      }
         *
         *      TaskNode best = null;
         *
         *      foreach (TaskNode child in root.Children)
         *      {
         *              Console.WriteLine("visits: " + child.TotNumVisits);
         *              Console.WriteLine("wins: " + child.Wins);
         *
         *              if (best == null || child.TotNumVisits > best.TotNumVisits)
         *              {
         *                      best = child;
         *              }
         *      }
         *
         *      //Console.WriteLine("best visits: " + best.TotNumVisits);
         *      //Console.WriteLine("best wins: " + best.Wins);
         *
         *      return best.Action;
         * }
         */

        public static PlayerTask GetBestAction_second(POGame.POGame game, double seconds)
        {
            DateTime start = DateTime.Now;
            TaskNode root  = new TaskNode(null, null, game.getCopy());

            int i = 0;



            while (true)
            {
                if (TimeUp(start, seconds - 0.1))
                {
                    break;
                }
                //Board_Analysis(game);//場面分析函式
                Controller my = game.CurrentPlayer;
                Controller op = game.CurrentOpponent;
                //分配數值
                num_my_board       = my.BoardZone.Count;
                num_op_board       = op.BoardZone.Count;
                num_my_hand        = my.HandZone.Count;
                num_op_hand        = op.HandZone.Count;
                num_my_hero        = my.Hero.Health;
                num_op_hero        = op.Hero.Health;
                num_my_deck        = my.DeckZone.Count;
                num_op_deck        = op.DeckZone.Count;
                num_remaining_mana = my.RemainingMana;

                TreeScore.treescore.tree_score.tree_node = SabberStoneCoreAi.src.Program.main.node_string;


                c = Math.Round(TreeScore.treescore.tree_score.Node_Evaluation(num_my_board, num_op_board, num_my_hand, num_op_hand,
                                                                              num_my_hero, num_op_hero, num_my_deck, num_op_deck, num_remaining_mana), 2, MidpointRounding.AwayFromZero);
                //Console.WriteLine(num_my_board+"  "+ num_op_board + "  " + num_my_hand + "  " + num_op_hand + "  " +
                //	num_my_hero + "  " + num_op_hero + "  " + num_my_deck + "  " + num_op_deck + "  " + num_remaining_mana);

                if (c < 0)
                {
                    c = 0;
                }
                //Console.WriteLine("c=" + c);
                //simulation_num = (int) Math.Round(TreeScore.treescore.tree_score.Node_Evaluation(num_my_board, num_op_board, num_my_hand, num_op_hand,
                //	num_my_hero, num_op_hero, num_my_deck, num_op_deck), 0, MidpointRounding.AwayFromZero);

                //if (simulation_num < 0)
                //{
                //	simulation_num = 1;
                //}

                //Console.WriteLine("模擬次數為:" + simulation_num);

                try
                {
                    TaskNode node = root.SelectNode();
                    if (TimeUp(start, seconds))
                    {
                        break;
                    }

                    node = node.Expand();
                    if (TimeUp(start, seconds))
                    {
                        break;
                    }

                    int r = node.SimulateGames(simulation_num);                    //預設5
                    if (TimeUp(start, seconds))
                    {
                        break;
                    }

                    node.Backpropagate(r);
                }
                catch (Exception e)
                {
                    //Debug.WriteLine(e.Message);
                    //Debug.WriteLine(e.StackTrace);
                }

                ++i;
            }

            TaskNode best = null;

            //Console.WriteLine($"Iterations: {i}, Time: " + (DateTime.Now-start).TotalMilliseconds + "ms");

            foreach (TaskNode child in root.Children)
            {
                //Console.WriteLine("visits: " + child.TotNumVisits);//刪除註解
                //Console.WriteLine("wins: " + child.Wins);

                if (best == null || child.TotNumVisits > best.TotNumVisits || (child.TotNumVisits == best.TotNumVisits && child.Wins > best.Wins))
                {
                    best = child;
                }
            }

            //Console.WriteLine("best visits: " + best.TotNumVisits);
            //Console.WriteLine("best wins: " + best.Wins);

            if (best == null)
            {
                //Debug.WriteLine("best == null");
                return(game.CurrentPlayer.Options()[0]);
            }

            //Console.WriteLine("best wins: " + best.Wins + " best visits: " + best.TotNumVisits);
            return(best.Action);
        }