Ejemplo n.º 1
0
        private float Simulation(Node nodeToSimulate, 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.getGame().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);
        }
Ejemplo n.º 2
0
        private PlayerTask HandleMulligan(POGame poGame)
        {
            Controller me = poGame.CurrentPlayer;

            if (me.MulliganState == Mulligan.INPUT)
            {
                List <IPlayable> cards = me.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList();
                return(ChooseTask.Mulligan(me, cards.Where(x => x.Card.Cost <= 3).Select(x => x.Id).ToList()));
            }

            return(null);
        }
Ejemplo n.º 3
0
        private float Simulate(Node nodeToSimulate, POGame poGame)
        {
            float      result          = -1;
            int        simulationSteps = 0;
            PlayerTask task            = null;

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

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

            taskToSimulate.Add(null);

            while (poGame.getGame().State != SabberStoneCore.Enums.State.COMPLETE)
            {
                task = Greedy(poGame);
                taskToSimulate[0] = task;
                if (task.PlayerTaskType != PlayerTaskType.END_TURN)
                {
                    poGame = poGame.Simulate(taskToSimulate)[taskToSimulate[0]];
                }

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

                if (task.PlayerTaskType == PlayerTaskType.END_TURN)
                {
                    return(ScoreToValue(Score(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);
        }
Ejemplo n.º 4
0
        public double Evaluate(POGame state)
        {
            if (SOCKET_EVAL && NNSocket != null)
            {
                return((double)SocketEvaluate(state.getGame()));
            }

            if (!state.CurrentPlayer.Name.Equals(controller.Name))
            {
                Console.WriteLine("ERROR: Evaluating opponent's state!");
                return(new DogZooLockScore {
                    Controller = state.CurrentOpponent
                }.Evaluate());
            }
            return(new DogZooLockScore {
                Controller = state.CurrentPlayer
            }.Evaluate());
        }
Ejemplo n.º 5
0
        public override PlayerTask GetMove(POGame poGame)
        {
            Controller player = poGame.CurrentPlayer;
            IEnumerable <KeyValuePair <PlayerTask, POGame> > validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null);
            int optcount        = validOpts.Count();
            int maxMilliseconds = 25000;             // Math.Min(Math.Max(optcount * 2000, 8000), 20000);

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new MyScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }
            PlayerTask returnTask = validOpts.Any() ? GetMoveMCTS(poGame.getCopy(), maxMilliseconds) : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);

            if (returnTask == null)
            {
                returnTask = player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);
            }
            return(returnTask);
        }
        public override PlayerTask GetMove(POGame game)
        {
            var player = game.CurrentPlayer;
            int pid    = player.PlayerId;

            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new KnobiScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            // simulation stage 1
            var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null);

            if (validOpts.Any())
            {
                PlayerTask task = validOpts.First().Key;
                // initialize best score as current score
                int bestScore = Score(game, pid);

                // simulate the (maxSimPerStep) best solutions
                int i1 = 0;
                foreach (var opt in validOpts.OrderBy(x => - Score(x.Value, pid)))
                {
                    if (i1 > maxSimPerStep || opt.Key.PlayerTaskType == PlayerTaskType.END_TURN)
                    {
                        continue;
                    }
                    ++i1;
                    int optScore = Score(opt.Value, pid);
                    // return action if it leads to win
                    if (optScore == Int32.MaxValue)
                    {
                        return(opt.Key);
                    }
                    // skip action if it leads to defete
                    if (optScore == Int32.MinValue)
                    {
                        continue;
                    }

                    // start simulation stage 2
                    var validOpts2 = opt.Value.Simulate(opt.Value.CurrentPlayer.Options()).Where(x => x.Value != null);
                    int i2         = 0;
                    foreach (var opt2 in validOpts2.OrderBy(x => - Score(x.Value, pid)))
                    {
                        if (i2 > maxSimPerStep || opt2.Key.PlayerTaskType == PlayerTaskType.END_TURN)
                        {
                            continue;
                        }
                        ++i2;
                        optScore = Math.Max(optScore, Score(opt2.Value, pid));
                        if (optScore == Int32.MaxValue)
                        {
                            return(opt.Key);
                        }
                        if (optScore == Int32.MinValue)
                        {
                            continue;
                        }

                        //start simulation stage 3
                        if (useThirdStep)
                        {
                            var validOpts3 = opt.Value.Simulate(opt.Value.CurrentPlayer.Options()).Where(x => x.Value != null);
                            foreach (var opt3 in validOpts3.OrderBy(x => - Score(x.Value, pid)))
                            {
                                if (opt3.Key.PlayerTaskType == PlayerTaskType.END_TURN)
                                {
                                    continue;
                                }
                                optScore = Math.Max(optScore, Score(opt3.Value, pid));
                                if (optScore == Int32.MaxValue)
                                {
                                    return(opt.Key);
                                }
                                if (optScore == Int32.MinValue)
                                {
                                    continue;
                                }
                            }
                        }
                    }
                    // update desicion, if it is better
                    if (optScore > bestScore)
                    {
                        bestScore = optScore;
                        task      = opt.Key;
                    }
                }
                return(task);
            }
            // if there are no possible solutions, end the turn
            return(player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN));
        }
        public override PlayerTask GetMove(POGame poGame)
        {
            List <int>        values   = new List <int>();
            List <PlayerTask> turnList = new List <PlayerTask>();

            PlayerTask bestOption = null;
            int        bestValue  = int.MinValue;

            JadeScore jade = new JadeScore();

            Controller control = poGame.CurrentPlayer;

            Dictionary <PlayerTask, POGame> simulated = poGame.Simulate(control.Options());

            if (control.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = jade.MulliganRule().Invoke(control.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(control, mulligan));
            }

            if (control.Options().Count == 1)
            {
                return(control.Options()[0]);
            }

            oppPlayedCards = poGame.CurrentOpponent.PlayHistory;

            foreach (PlayHistoryEntry h in oppPlayedCards)
            {
                if (h.SourceCard.Name == "Flamestrike")
                {
                    countFlamestrike = 1;
                }
            }

            foreach (PlayerTask k in simulated.Keys)
            {
                if (k.PlayerTaskType == PlayerTaskType.END_TURN)
                {
                    continue;
                }


                if (poGame.CurrentPlayer.BoardZone.Count >= 4 && k.PlayerTaskType == PlayerTaskType.PLAY_CARD && k.Source.Card.Type == CardType.MINION)
                {
                    continue;
                }

                if (poGame.CurrentOpponent.HeroClass == CardClass.MAGE && poGame.CurrentOpponent.BaseMana >= 7 &&
                    countFlamestrike == 0 && k.PlayerTaskType == PlayerTaskType.PLAY_CARD && k.Source.Card.Type == CardType.MINION && k.Source.Card[GameTag.HEALTH] <= 4 && poGame.CurrentPlayer.BoardZone.Count >= 2)
                {
                    continue;
                }

                //controller of simulated option
                control = simulated.First(x => x.Key == k).Value?.CurrentPlayer;

                if (control == null)
                {
                    continue;
                }

                //set controller on rating function
                //controlScore.Controller = control;
                jade.Controller = control;

                //rate current option
                var currentValue = jade.BetterRate(_rewardOppNoBoard, _rewardOppNoHand, _rewardBoardDiff, _rewardTauntDiff, _rewardHeroDiff,
                                                   _rewardHandDiff, _rewardDeckDiff, _rewardMinAttDiff, _rewardMinHealthDiff, _rewardHeroAttDiff, _rewardHandCost);

                if (bestValue < currentValue)
                {
                    bestValue  = currentValue;
                    bestOption = k;
                }
            }

            //debug(turnList, values, bestOption, bestValue, poGame);

            return(bestOption ??
                   (bestOption = poGame.CurrentPlayer.Options().Find(x => x.PlayerTaskType == PlayerTaskType.END_TURN)));
        }
Ejemplo n.º 8
0
        public override PlayerTask GetMove(POGame poGame)
        {
            var player = poGame.CurrentPlayer;

            // During Mulligan: select Random cards
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = RandomMulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            // During Gameplay: select a random action
            List <PlayerTask> options = poGame.CurrentPlayer.Options();

            return(options[Rnd.Next(options.Count)]);
        }
        public override PlayerTask GetMove(POGame poGame)
        {
            outputOptional("-----------new get Move-------------");

            initialDebug(poGame);
            debugBoardZone(poGame);

            Controller    player = poGame.CurrentPlayer;
            List <double> scores = new List <double>();


            outputMyCards(poGame);

            if (player.MulliganState == Mulligan.INPUT)
            {
                outputOptional("\ntime for mulligan");
                List <int> mulligan = MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());

                outputOptional("mulligan options:");
                for (int i = 0; i < mulligan.Count; i++)
                {
                    outputOptional(mulligan[i].ToString());
                }


                outputOptional(ChooseTask.Mulligan(player, mulligan).ToString());
                //outputOptional("muligan choices: " + player.Choice.Choices.ToString());

                return(ChooseTask.Mulligan(player, mulligan));
            }



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

            debugOptions(options, player);

            if (options.Count == 1)
            {
                if (options[0].PlayerTaskType == PlayerTaskType.END_TURN)
                {
                    outputOptional("ending turn because only one end turn option available");
                    outputOptional("########### New Round ###########");
                    currentTurn += 1;
                    return(options[0]);
                }
                else
                {
                    outputPriorityHigh("[Error]: only one option left but its not ending a turn");
                    return(options[0]);
                }
            }
            var simulated = poGame.Simulate(options);

            foreach (var s in simulated)
            {
                // s.Value is the POGame of that simulated move
                scores.Add(Score(s.Key, s.Value));
            }


            //debugScoringOptions(simulated, scores);
            debugSimScoringOptions(simulated, scores);

            int highestScoringIndex = HighestValue(scores);

            if (highestScoringIndex == 0 && player.RemainingMana > 1)
            {
                numGamesEndturnManaMoreThanTwo++;
                numGamesEndturnManaMoreThanTwoTotal++;
                outputPriorityHigh("m8 premature end of turn: Mana:" + player.RemainingMana.ToString() + "|" + options[0].ToString());
            }
            outputOptional("choosing this task: " + options[highestScoringIndex].ToString() + " at " + highestScoringIndex);

            return(options[highestScoringIndex]);
        }
Ejemplo n.º 10
0
        public override PlayerTask GetMove(POGame game)
        {
            var player = game.CurrentPlayer;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new WeightedScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            //Lookhead n steps and choose the best scoring <PlayerTask> and each depth -> branch ->score->until depth
            //(DFS search)

            var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null);
            var voptcount = validOpts.Count();


            if (validOpts.Any())
            {
                var depth  = voptcount > 5 ? (voptcount > 25 ? 1: 2) : 3;
                var scored = validOpts.Select(x => Simulate(x, player.PlayerId, depth));
                // Array.ForEach(scored.Select(x=>x.Item1).ToArray(),Console.Write);
                // Console.Write($"\r{scored.Count()}  ");
                return(scored.OrderBy(x => x.Value).Last().Key);
            }
            else
            {
                return(player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN));
            }
        }
Ejemplo n.º 11
0
        public override PlayerTask GetMove(POGame poGame)
        {
            int myPlayerId            = poGame.CurrentPlayer.PlayerId;
            List <PlayerTask> options = poGame.CurrentPlayer.Options();

            // Implement a simple Mulligan Rule
            if (poGame.CurrentPlayer.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new AggroScore().MulliganRule().Invoke(poGame.CurrentPlayer.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());               //all mulligan handlers are the same for each score
                return(ChooseTask.Mulligan(poGame.CurrentPlayer, mulligan));
            }



            var simulationResults = poGame.Simulate(options);

            double     bestWorth = getWorth(poGame, myPlayerId);         //best worth starts with the current field
            PlayerTask bestTask  = null;

            foreach (PlayerTask t in options)
            {
                double resultingWorth = Double.NegativeInfinity;
                if (simulationResults.ContainsKey(t) && t.PlayerTaskType != PlayerTaskType.END_TURN)
                {
                    POGame resultingGameState = simulationResults[t];
                    resultingWorth = getWorth(resultingGameState, myPlayerId);
                }
                else                  //TODO: think of something to do if the key is unvalid
                                      //for now, do nothing if the resulting value is negative
                {
                }

                if (bestWorth < resultingWorth)
                {
                    bestWorth = resultingWorth;
                    bestTask  = t;
                }
            }

            if (bestTask == null)
            {
                return(EndTurnTask.Any(poGame.CurrentPlayer));
            }

            return(bestTask);
        }
Ejemplo n.º 12
0
        public override PlayerTask GetMove(POGame game)
        {
            Controller player = game.CurrentPlayer;

            if (h_score == -1)
            {
                determineScore(player);
            }
            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new HarderMidRangeScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            finishedBuildingTree = false;

            if (!finishedBuildingTree)
            {
                actionsToTake = new List <PlayerTask>();
            }

            if (actionsToTake.Count != 0)
            {
                PlayerTask action = DequeueTask();
                finishedBuildingTree = actionsToTake.Count != 0;

                /*if (!finishedBuildingTree) {
                 *  Console.WriteLine("My health: " + poGame.CurrentPlayer.Hero.Health);
                 *              Console.WriteLine("Opponent health: " + poGame.CurrentOpponent.Hero.Health);
                 *  Console.WriteLine("\n\n\n");
                 * }
                 * Console.WriteLine(String.Format("Action: {0}", action));*/
                return(action);
            }

            List <MinMaxAgentState> leaves       = new List <MinMaxAgentState>();
            List <MinMaxAgentState> parentStates = new List <MinMaxAgentState>()
            {
                new MinMaxAgentState(game)
            };

            // while we have moves to play
            // int generation = 0;
            while (true)
            {
                // split currentLevel into leaves "partitioned[false]"
                // and non-leaves "partitioned[true]"
                ILookup <bool, MinMaxAgentState> partitioned = parentStates.ToLookup(
                    currentLevelNonLeaf => currentLevelNonLeaf.OnlyActionIsEndTurn ||
                    currentLevelNonLeaf.ActionsToReachState.Count >= 6
                    );

                IEnumerable <MinMaxAgentState> parentLeaves    = partitioned[true];
                List <MinMaxAgentState>        nonParentLeaves = partitioned[false].ToList();

                leaves.AddRange(parentLeaves.ToList());

                if (nonParentLeaves.Count == 0)
                {
                    break;
                }

                //Console.WriteLine(String.Format("leaves.Count = {0}", leaves.Count));
                //Console.WriteLine(String.Format("haveMoreActions.Count = {0}\n", haveMoreActions.Count));

                //if (haveMoreActions.Count == 0) {
                //    break;
                //}

                List <MinMaxAgentState> childrenStates = new List <MinMaxAgentState>();

                //Console.WriteLine(String.Format("========== Actions My Bot Can Take =========="));
                //Console.WriteLine(String.Format("Iteration #{0}\n\n", ++generation));

                foreach (MinMaxAgentState hasMoreAction in nonParentLeaves)
                {
                    Dictionary <PlayerTask, POGame> mapping = hasMoreAction.State.Simulate(
                        hasMoreAction.AvailableActions.ToList()
                        );//.Where( x => x.Value != null );
                    foreach (KeyValuePair <PlayerTask, POGame> actionState in mapping)
                    {
                        if (actionState.Value != null)
                        {
                            /*if (actionState.Key.FullPrint().Contains("Player1")) {
                             *  continue;
                             * }
                             * Console.WriteLine(actionState.Key.FullPrint());*/
                            childrenStates.Add(new MinMaxAgentState(hasMoreAction, actionState));
                        }
                    }
                }

                // Get the top N childrenStates
                var childrenStatesWithScore = childrenStates.Zip(childrenStates.Select(
                                                                     childState => Score(childState.State, childState.State.CurrentPlayer.PlayerId)
                                                                     ), (state, score) => new Tuple <MinMaxAgentState, double>(state, score)).ToList();
                childrenStatesWithScore.Sort((lhs, rhs) => rhs.Item2.CompareTo(lhs.Item2));

                parentStates = childrenStatesWithScore.Take(MAX_CHILD_COUNT).Select(
                    stateScore => stateScore.Item1
                    ).ToList();
            }

            // No moves possible i.e. no leaves
            var finalCandidates = leaves.ToList();

            if (finalCandidates.Count == 0)
            {
                actionsToTake.Add(EndTurnTask.Any(parentStates[0].State.CurrentPlayer.Controller));
                return(DequeueTask());
            }

            // Get the very best
            MinMaxAgentState bestState = MaxByKey(finalCandidates, (lhs, rhs) => {
                return(Score(lhs.State, lhs.State.CurrentPlayer.Id) < Score(rhs.State, rhs.State.CurrentPlayer.Id) ? rhs : lhs);
            });

            actionsToTake = bestState.ActionsToReachState;
            if (actionsToTake.Count == 0 || actionsToTake[actionsToTake.Count - 1].PlayerTaskType != PlayerTaskType.END_TURN)
            {
                actionsToTake.Add(EndTurnTask.Any(bestState.State.CurrentPlayer.Controller));
            }

            finishedBuildingTree = true;
            // Console.WriteLine(String.Format("Turn Counter @ {0}", ++turnCounter));
            return(DequeueTask());
        }
Ejemplo n.º 13
0
        public override PlayerTask GetMove(POGame game)
        {
            if (SelectHeroPower)
            {
                SelectHeroPower = false;
                List <IPlayable> choices  = game.CurrentPlayer.Choice.Choices.Select(id => game.getGame().IdEntityDic[id]).ToList();
                string           selected = HeroPowerPriorities.choose(choices.Select(c => c.Card.Name).Distinct().ToList());
                return(ChooseTask.Pick(game.CurrentPlayer, choices.First(c => c.Card.Name == selected).Id));
            }

            int mana = game.CurrentPlayer.BaseMana + game.CurrentPlayer.TemporaryMana - game.CurrentPlayer.UsedMana;
            List <PlayerTask> options         = game.CurrentPlayer.Options();
            List <PlayerTask> heroPowers      = options.Where(t => t.PlayerTaskType == PlayerTaskType.HERO_POWER).ToList();
            List <PlayerTask> playCards       = options.Where(t => t.PlayerTaskType == PlayerTaskType.PLAY_CARD && t.Source.Card.Cost <= mana).ToList();
            List <Minion>     ourMinionsReady = game.Minions.Where(m => m.Controller.Id == game.CurrentPlayer.Id && m.CanAttack).ToList();

            if (game.CurrentPlayer.MulliganState == Mulligan.INPUT)
            {
                // mulligan
                List <IPlayable> choices = game.CurrentPlayer.Choice.Choices.Select(id => game.getGame().IdEntityDic[id]).ToList();
                choices = choices.Where(c => c.Cost <= 3 && c.Card.Name != "Patches the Pirate").ToList();
                return(ChooseTask.Mulligan(game.CurrentPlayer, choices.Select(c => c.Id).ToList()));
            }
            else if (playCards.Count != 0)
            {
                // play card
                List <string> cardNames = playCards.Select(c => c.Source.Card.Name).Distinct().ToList();

                string selectedCard;
                if (game.CurrentPlayer.Hero.Weapon != null)
                {
                    // we have a weapon
                    selectedCard = CardPrioritiesWithWeapon.choose(cardNames);
                }
                else
                {
                    // we don't have a weapon
                    selectedCard = CardPrioritiesNoWeapon.choose(cardNames);
                }

                if (selectedCard == "Sir Finley Mrrgglton")
                {
                    SelectHeroPower = true;
                }

                return(playCards.First(t => t.Source.Card.Name == selectedCard));
            }
            else if (game.CurrentPlayer.Hero.CanAttack)
            {
                // hero attack
                List <Minion> enemyMinions = game.Minions.Where(m => m.Controller.Id == game.CurrentOpponent.Id).ToList();
                List <Minion> enemyTaunts  = enemyMinions.Where(m => m.HasTaunt == true).ToList();

                if (enemyTaunts.Count != 0)
                {
                    return(HeroAttackTask.Any(game.CurrentPlayer, enemyTaunts[0]));
                }
                else
                {
                    return(HeroAttackTask.Any(game.CurrentPlayer, game.CurrentOpponent.Hero));
                }
            }
            else if (ourMinionsReady.Count != 0)
            {
                // minion attack
                List <Minion> enemyMinions = game.Minions.Where(m => m.Controller.Id == game.CurrentOpponent.Id).ToList();
                List <Minion> enemyTaunts  = enemyMinions.Where(m => m.HasTaunt == true).ToList();

                if (enemyTaunts.Count != 0)
                {
                    int tauntHealth = enemyTaunts[0].Health;
                    int tauntAttack = enemyTaunts[0].AttackDamage;

                    // perfectTraders: survive the attack, kill the Taunt and don't have more overkill/wasted damage than 2
                    List <Minion> perfectTraders = ourMinionsReady.Where(m => m.Health > tauntAttack && m.AttackDamage >= tauntHealth && m.AttackDamage <= (tauntHealth + 2)).ToList();

                    // almost perfect Traders: survive the attack and kill the Taunt
                    List <Minion> almostPerfectTraders = ourMinionsReady.Where(m => m.Health > tauntAttack && m.AttackDamage >= tauntHealth).ToList();

                    // goodTraders: kill Taunt
                    List <Minion> goodTraders = ourMinionsReady.Where(m => m.AttackDamage > tauntHealth).ToList();

                    // survivingTraders: survive an attack but don't necessarily kill the taunt
                    List <Minion> survivingTraders = ourMinionsReady.Where(m => m.Health > tauntAttack).ToList();

                    // trade perfect
                    if (perfectTraders.Count != 0)
                    {
                        perfectTraders = perfectTraders.OrderBy(m => m.Health + m.AttackDamage).ToList();
                        return(MinionAttackTask.Any(game.CurrentPlayer, perfectTraders[0], enemyTaunts[0]));
                    }

                    // trade almost perfect
                    else if (almostPerfectTraders.Count != 0)
                    {
                        almostPerfectTraders = almostPerfectTraders.OrderBy(m => m.Health + m.AttackDamage).ToList();
                        return(MinionAttackTask.Any(game.CurrentPlayer, almostPerfectTraders[0], enemyTaunts[0]));
                    }

                    // trade good
                    else if (goodTraders.Count != 0)
                    {
                        // sort good traders and choose weakest to not waste potential
                        goodTraders = goodTraders.OrderBy(m => m.Health + m.AttackDamage).ToList();
                        return(MinionAttackTask.Any(game.CurrentPlayer, goodTraders[0], enemyTaunts[0]));
                    }

                    // trade so that minions survive
                    else if (survivingTraders.Count != 0)
                    {
                        return(MinionAttackTask.Any(game.CurrentPlayer, survivingTraders[0], enemyTaunts[0]));
                    }

                    // trade random
                    else
                    {
                        return(MinionAttackTask.Any(game.CurrentPlayer, ourMinionsReady[0], enemyTaunts[0]));
                    }
                }
                else
                {
                    return(MinionAttackTask.Any(game.CurrentPlayer, ourMinionsReady[0], game.CurrentOpponent.Hero));
                }
            }
            else if (mana >= 2 && heroPowers.Count != 0)
            {
                // hero power
                if (game.CurrentPlayer.Hero.HeroPower.Card.Name == "Lesser Heal" || game.CurrentPlayer.Hero.HeroPower.Card.Name == "Fireblast")
                {
                    return(options[0]);                    // end turn, because we don't know how to set the target
                }
                else
                {
                    return(heroPowers[0]);                    // use hero power
                }
            }
            else
            {
                // fallback: end turn
                return(options[0]);
            }
        }
Ejemplo n.º 14
0
        public void FinalizeGame(POGame game)
        {
            bool won;

            if (_me.PlayerId == 1)
            {
                won = game.getGame().Player1.PlayState == PlayState.WON;
            }
            else
            {
                won = game.getGame().Player2.PlayState == PlayState.WON;
            }

            bool tied            = game.CurrentPlayer.PlayState == PlayState.TIED;
            bool maxTurnsReached = game.getGame().State == State.RUNNING;

            float discount = 0.98f;
            float alpha    = 0.00001f;

            //Console.WriteLine("Gamestate: " + game.getGame().State);
            //Console.WriteLine("I am player " + _me.PlayerId);
            //Console.WriteLine("State of Player1:" + game.getGame().Player1.PlayState);
            //Console.WriteLine("State of Player2:" + game.getGame().Player2.PlayState);
            //Console.WriteLine("Won: " + won);
            //Console.WriteLine("Tied: " + tied);
            //Console.WriteLine("Max turns reached: " + maxTurnsReached);

            double reward = won ? 10 : -10;

            reward = tied ? 0 : reward;
            reward = maxTurnsReached ? -5 : reward;

            //Console.WriteLine(reward);

            var weights = new List <double>(MagicNumberScore.Factors);

            double total_squared_error = 0;

            //Console.WriteLine(_scores.Count);
            for (int i = 1; i < _scores.Count; i++)
            {
                var    d_return = reward * Math.Pow(discount, (_scores.Count() - i - 1));
                double error    = d_return - _scores[i];
                //Console.WriteLine("Error in turn " + i + ": " + Math.Pow(error, 2));
                total_squared_error += Math.Pow(error, 2);
                var fl = new List <double>(_features[i]).Zip(new List <double>(_features[i - 1]), (a, b) => (a, b));
                weights = weights.Zip(fl, (w, f) => (w + alpha * error * (f.b - f.a))).ToList();
            }
            //Console.WriteLine("New Weights:");
            for (int i = 0; i < weights.Count(); i++)
            {
                Console.Write($"{i}: {weights[i]}|");
            }
            MagicNumberScore.Factors = weights.ToArray();
            //Console.WriteLine("Normailized Weights:");
            for (int i = 0; i < MagicNumberScore.Factors.Count(); i++)
            {
                Console.Write($"{i}: {MagicNumberScore.Factors[i]}|");
            }
            //Console.WriteLine("-------------");
            //Console.WriteLine("Total squared error this game: " + total_squared_error);
        }
Ejemplo n.º 15
0
        public override PlayerTask GetMove(POGame poGame)
        {
            //Console.WriteLine("NEW TURN:");

            Controller player = poGame.CurrentPlayer;

            if (player.HeroClass == CardClass.WARRIOR)
            {
                hWarrior = 1; hMage = 0; hShaman = 0;
            }
            else if (player.HeroClass == CardClass.MAGE)
            {
                hWarrior = 0; hMage = 1; hShaman = 0;
            }
            else
            {
                hWarrior = 0; hMage = 0; hShaman = 1;
            }

            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new MyScore().GetMulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
            }

            //  Get all simulation results for simulations that didn't fail
            IEnumerable <KeyValuePair <PlayerTask, POGame> > validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null);

            if (validOpts.Any())
            {
                var move   = new KeyValuePair <PlayerTask, int>(validOpts.First().Key, Score(poGame, player.PlayerId));
                var nScore = new KeyValuePair <PlayerTask, int>(validOpts.First().Key, Score(poGame, player.PlayerId));
                foreach (KeyValuePair <PlayerTask, POGame> playerTask in validOpts)
                {
                    if (validOpts.Count() >= 8)
                    {
                        if (validOpts.Count() >= 24)
                        {
                            nScore = nextScore(playerTask, player.PlayerId, 1);
                            if (nScore.Value > move.Value)
                            {
                                move = nScore;
                            }
                        }
                        else
                        {
                            nScore = nextScore(playerTask, player.PlayerId, 2);
                            if (nScore.Value > move.Value)
                            {
                                move = nScore;
                            }
                        }
                    }
                    else
                    {
                        nScore = nextScore(playerTask, player.PlayerId, 3);
                        if (nScore.Value > move.Value)
                        {
                            move = nScore;
                        }
                    }
                }                //Console.WriteLine(poGame.PartialPrint());
                                 //Console.WriteLine("......................");
                                 //Console.WriteLine(move.Key +" mit: "+ move.Value);
                                 //Console.WriteLine("-----------------------");
                return(move.Key);
            }
            else
            {
                return(player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN));
            }
        }
Ejemplo n.º 16
0
        public override PlayerTask GetMove(POGame game)
        {
            //StopWatch.StartWithReset();

            int threadCount = 4;
            var player      = game.CurrentPlayer;
            var opponent    = game.CurrentOpponent;

            var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null);
            var optsCount = validOpts.Count();
            var history   = opponent.PlayHistory;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            countProbabilities();

            MCTS       mcts   = new MCTS(game, DecksDict, ProbabilitiesDict, TurnDepth, TimeBudget, Selection, StateRate, ExplorationConstant);
            PlayerTask result = mcts.Search();

            //StopWatch.StopWithMessage(String.Format("Compute {0} options in {1} ms", optcount, StopWatch.ElapsedMilliseconds));

            //Console.WriteLine("Final task: " + result);
            return(result);

            void countProbabilities()
            {
                /* ----------- Counting probabilities ------------ */
                foreach (KeyValuePair <string, List <Card> > deck in DecksDict)
                {
                    int similarCount      = 0;
                    var playedCards       = history.Select(h => h.SourceCard).ToList();
                    var deckCards         = deck.Value;
                    var deckCardsDistinct = deckCards.Distinct().ToList();

                    playedCards
                    .ForEach(playedCard =>
                    {
                        deckCardsDistinct.ForEach(deckCard =>
                        {
                            if (playedCard.Name == deckCard.Name)
                            {
                                similarCount++;
                            }
                        });
                    });

                    double probability = Math.Round((double)similarCount / deckCards.Count(), 2);
                    ProbabilitiesDict[deck.Key] = probability;
                    //if (probability > 0) Console.WriteLine(deck.Key + " has probability of " + ProbabilitiesDict[deck.Key] * 100 + "%");
                }
            }
        }
Ejemplo n.º 17
0
        public override PlayerTask GetMove(POGame poGame)
        {
            var player = poGame.CurrentPlayer;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new CustomScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            if (poGame.CurrentPlayer.Options().Count == 1)
            {
                return(poGame.CurrentPlayer.Options()[0]);
            }

            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);

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

            return(SelectAction.selectTask(SELECTION_ACTION_METHOD, root, iterations, EXPLORE_CONSTANT));
        }
Ejemplo n.º 18
0
        public override PlayerTask GetMove(POGame poGame)
        {
            _player = poGame.CurrentPlayer;

            if (_player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new DefaultScore().MulliganRule().Invoke(_player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(_player, mulligan));
            }


            Dictionary <KeyValuePair <PlayerTask, POGame>, int> ScoreDict = new Dictionary <KeyValuePair <PlayerTask, POGame>, int>();
            Stopwatch stopwatch = new Stopwatch();

            var simulation = poGame.Simulate(_player.Options()).Where(x => x.Value != null);

            simulation = simulation.OrderBy(x => Score(x.Value, _player.PlayerId));
            stopwatch.Start();

            foreach (var task in simulation)
            {
                if (stopwatch.ElapsedMilliseconds > 25000)
                {
                    break;
                }

                if (task.Key.PlayerTaskType == PlayerTaskType.END_TURN)
                {
                    ScoreDict.Add(task, Score(task.Value, _player.PlayerId));
                    continue;
                }
                POGame gamecopy     = task.Value.getCopy();
                var    options      = gamecopy.CurrentPlayer.Options();
                var    simulationv2 = gamecopy.Simulate(options).Where(x => x.Value != null);
                simulationv2 = simulationv2.OrderBy(x => Score(x.Value, _player.PlayerId));
                Dictionary <KeyValuePair <PlayerTask, POGame>, int> ScoreDict2 = new Dictionary <KeyValuePair <PlayerTask, POGame>, int>();

                foreach (var task2 in simulationv2)
                {
                    if (stopwatch.ElapsedMilliseconds > 25000)
                    {
                        break;
                    }

                    POGame gamecopy2 = task2.Value.getCopy();
                    var    options2  = gamecopy2.CurrentPlayer.Options();
                    if (task2.Key.PlayerTaskType == PlayerTaskType.END_TURN || options2.Count > 20)
                    {
                        ScoreDict2.Add(task2, Score(task2.Value, _player.PlayerId));
                        continue;
                    }
                    var simulationv3 = gamecopy2.Simulate(options2).Where(x => x.Value != null);
                    simulationv3 = simulationv3.OrderBy(x => Score(x.Value, _player.PlayerId));

                    //evaluate the best score out of the third simulation and add it in scoredict 2
                    ScoreDict2.Add(task2, Score(simulationv3.OrderBy(x => Score(x.Value, _player.PlayerId)).Last().Value, _player.PlayerId));
                }
                ScoreDict.Add(task, ScoreDict2.OrderBy(x => x.Value).Last().Value);
            }
            //if(stopwatch.ElapsedMilliseconds>25000)
            //	Console.WriteLine(stopwatch.ElapsedMilliseconds);


            return(simulation.Any() ?
                   ScoreDict.OrderBy(x => x.Value).Last().Key.Key :
                   _player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN));
        }
Ejemplo n.º 19
0
        public override PlayerTask GetMove(POGame poGame)
        {
            var player = poGame.CurrentPlayer;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new CustomMidrangeScoreHempel().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                switch (poGame.CurrentPlayer.HeroClass)
                {
                case CardClass.SHAMAN: goto case CardClass.HUNTER;

                case CardClass.PALADIN: goto case CardClass.HUNTER;

                case CardClass.DRUID: goto case CardClass.HUNTER;

                case CardClass.ROGUE: goto case CardClass.HUNTER;

                case CardClass.HUNTER:
                    mulligan = new CustomMidrangeScoreHempel().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); break;

                case CardClass.WARLOCK: goto case CardClass.WARRIOR;

                case CardClass.WARRIOR:
                    mulligan = new CustomAggroScoreHempel().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); break;

                case CardClass.PRIEST: goto case CardClass.MAGE;

                case CardClass.MAGE:
                    mulligan = new CustomControlScoreHempel().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); break;

                default:
                    mulligan = new CustomMidrangeScoreHempel().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); break;
                }
                return(ChooseTask.Mulligan(player, mulligan));
            }


            // Get all simulation results for simulations that didn't fail
            var validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null);

            // List of best pairs
            var ActionScore = new List <KeyValuePair <PlayerTask, int> >();

            foreach (KeyValuePair <PlayerTask, POGame> pair in validOpts)
            {
                var optionsDeep1        = pair.Value.CurrentPlayer.Options(); //get substate options
                var bestDeepActionState = new KeyValuePair <PlayerTask, POGame>();

                if (optionsDeep1.Any() && pair.Key.PlayerTaskType != PlayerTaskType.END_TURN)
                {
                    var validDeep1Options = pair.Value.Simulate(optionsDeep1).Where(x => x.Value != null);                     //get valid substate options
                    if (validDeep1Options.Any())
                    {
                        bestDeepActionState = validDeep1Options.OrderBy(x => Score(x.Value, player.PlayerId)).Last();
                        ActionScore.Add(new KeyValuePair <PlayerTask, int>(pair.Key, (int)(0.2 * (double)Score(pair.Value, player.PlayerId) + 0.8 * (double)Score(bestDeepActionState.Value, player.PlayerId))));
                    }
                    else
                    {
                        ActionScore.Add(new KeyValuePair <PlayerTask, int>(pair.Key, Score(pair.Value, player.PlayerId)));
                    }
                }
                else
                {
                    // collect best tasks per done task
                    ActionScore.Add(new KeyValuePair <PlayerTask, int>(pair.Key, Score(pair.Value, player.PlayerId)));
                }
            }

            // return the action with the best combination of current task and next task
            return(validOpts.Any() ? ActionScore.OrderBy(x => x.Value).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN));
        }
            public override PlayerTask GetMove(POGame game)
            {
                var player = game.CurrentPlayer;

                // Implement a simple Mulligan Rule
                if (player.MulliganState == Mulligan.INPUT)
                {
                    List <int> mulligan = new CustomScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                    return(ChooseTask.Mulligan(player, mulligan));
                }

                var opponent = game.CurrentOpponent;
                var options  = player.Options();



                var validOpts = game.Simulate(options).Where(x => x.Value != null);
                var optcount  = validOpts.Count();

#if DEBUG
                /*
                 * var score_res = validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value);
                 *
                 * Console.WriteLine("Round Nr:" + Convert.ToString(game.Turn));
                 * Console.WriteLine("HeroHP: " + Convert.ToString(player.Hero.Health) + "\tOppHP: " + Convert.ToString(game.CurrentOpponent.Hero.Health));
                 * Console.WriteLine("HeroMinionHP: " + Convert.ToString(player.BoardZone.Sum(p => p.Health)) + "\tOppMinionHP: " + Convert.ToString(game.CurrentOpponent.BoardZone.Sum(p => p.Health)));
                 * Console.WriteLine("HeroMinionAtk: " + Convert.ToString(player.BoardZone.Sum(p => p.AttackDamage)) + "\tOppMinionAtk: " + Convert.ToString(game.CurrentOpponent.BoardZone.Sum(p => p.AttackDamage)));
                 * Console.WriteLine("HeroNbMinions: " + Convert.ToString(player.BoardZone.Count) + "\tOppMinionNB: " + Convert.ToString(game.CurrentOpponent.BoardZone.Count));
                 *
                 *
                 * foreach (var tmp_score in score_res)
                 *      {
                 *
                 *              Console.WriteLine(Convert.ToString(tmp_score.Key) + Convert.ToString(tmp_score.Value));
                 *      }
                 *      Console.WriteLine("-------------------------------------------------------");
                 * //PrintLog(game,  score_res);
                 */
#endif


                /*
                 * if (player.Hero.Health < DEFENSE_HEALTH_THRESHOLD * player.Hero.BaseHealth)
                 *      RuntimeScaling[0] += 0.1;
                 *
                 * if (opponent.Hero.Health < DEFENSE_HEALTH_THRESHOLD * opponent.Hero.Health)
                 *      RuntimeScaling[1] += 0.1;
                 */
                var opt1 = options.Where(x => x.HasSource && x.Source.Card.Name == "Reno Jackson");
                //if (opt1.Count() > 0 && (player.Hero.Health - opponent.Hero.AttackDamage - opponent.BoardZone.Sum(p => p.AttackDamage) <= 3 || player.Hero.Health<10))
                //if (opt1.Count() > 0 && (player.Hero.Health - opponent.Hero.AttackDamage - opponent.BoardZone.Sum(p => p.AttackDamage) <= 6 ))
                if (opt1.Count() > 0 && (player.Hero.Health - opponent.Hero.AttackDamage - opponent.BoardZone.Sum(p => p.AttackDamage) <= 3 || player.Hero.Health < 10))
                {
                    var tmp_game = game.getCopy();
                    //Reno Jackson has 6 mana

                    int mana = (tmp_game.CurrentPlayer.RemainingMana - 6) > 0 ? (tmp_game.CurrentPlayer.RemainingMana - 6) : 0;
                    //Console.WriteLine("mana " + Convert.ToString(tmp_game.CurrentPlayer.BaseMana));

                    var validOptsLoc = tmp_game.Simulate(options).Where(x => x.Value != null);
                    var optcountLoc  = validOptsLoc.Count();

                    var score_resLoc = validOptsLoc.Select(x => score(x, player.PlayerId, (optcountLoc >= 5) ? ((optcountLoc >= 25) ? 1 : 2) : 3)).Where(x => (x.Key.Source == null || x.Key.Source.Cost <= mana || x.Value == Int32.MaxValue)).Where(x => Convert.ToString(x.Key).Contains("Fireblast") != true || mana >= 1).OrderBy(x => x.Value);

                    /*Console.WriteLine("OPTS");
                     *
                     * foreach (var tmp_score in score_resLoc)
                     * {
                     *
                     *      Console.WriteLine(Convert.ToString(tmp_score.Key) + Convert.ToString(tmp_score.Value));
                     * }
                     * Console.WriteLine("-------------------------------------------------------");
                     *
                     * Console.WriteLine("Round Nr:" + Convert.ToString(game.Turn));
                     * Console.WriteLine("HeroHP: " + Convert.ToString(player.Hero.Health) + "\tOppHP: " + Convert.ToString(game.CurrentOpponent.Hero.Health));
                     * Console.WriteLine("HeroMinionHP: " + Convert.ToString(player.BoardZone.Sum(p => p.Health)) + "\tOppMinionHP: " + Convert.ToString(game.CurrentOpponent.BoardZone.Sum(p => p.Health)));
                     * Console.WriteLine("HeroMinionAtk: " + Convert.ToString(player.BoardZone.Sum(p => p.AttackDamage)) + "\tOppMinionAtk: " + Convert.ToString(game.CurrentOpponent.BoardZone.Sum(p => p.AttackDamage)));
                     * Console.WriteLine("HeroNbMinions: " + Convert.ToString(player.BoardZone.Count) + "\tOppMinionNB: " + Convert.ToString(game.CurrentOpponent.BoardZone.Count));
                     *
                     * //Console.WriteLine("OPTS:" + Convert.ToString(score_res.First()));
                     * //Console.WriteLine("OPTS:" + Convert.ToString(score_res.Last()));
                     * //Console.WriteLine("OPTS:" + Convert.ToString(score_res.Count()));
                     */

                    if (score_resLoc.Count() > 1)
                    {
                        //Console.WriteLine("OPTION TAKEN" + Convert.ToString(score_resLoc.Last().Key));

                        return(score_resLoc.Last().Key);
                    }


                    //Console.WriteLine("REEEEEEEEEEENNNNNNNNNNNOOOOOOOOOOOOOOO:" + Convert.ToString(player.Hero.Health));
                    //Console.WriteLine("OPTS:" + Convert.ToString(opt1.First()));
                    return(opt1.First());
                }

                var returnValue = validOpts.Any() ?
                                  validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value).Where(x => Convert.ToString(x.Key).Contains("Reno Jackson") != true).Last().Key :
                                  player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);

                return(returnValue);

                KeyValuePair <PlayerTask, int> score(KeyValuePair <PlayerTask, POGame> state, int player_id, int max_depth = 3)
                {
                    int max_score = int.MinValue;

                    if (max_depth > 0 && state.Value.CurrentPlayer.PlayerId == player_id)
                    {
                        var subactions = state.Value.Simulate(state.Value.CurrentPlayer.Options()).Where(x => x.Value != null);

                        foreach (var subaction in subactions)
                        {
                            max_score = Math.Max(max_score, score(subaction, player_id, max_depth - 1).Value);
                        }
                    }
                    max_score = Math.Max(max_score, Score(state.Value, player_id));
                    return(new KeyValuePair <PlayerTask, int>(state.Key, max_score));
                }
            }
        public override PlayerTask GetMove(POGame game)
        {
            if (!initialized)
            {
                Initialize(game);
            }

            // if there is a subagent
            if (subAgent != null)
            {
                // let subagent do the move, skip the following code
                return(subAgent.GetMove(game));
            }

            var player = game.CurrentPlayer;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new CustomScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            var opponent = game.CurrentOpponent;
            var options  = player.Options();

            var coins = options.Where(x => x.HasSource && x.Source.Card.Name == "The Coin");

            if (coins.Count() > 0)
            {
                return(coins.First());
            }

            var validOpts = game.Simulate(options).Where(x => x.Value != null);
            var optcount  = validOpts.Count();

#if DEBUG
            /*
             * var score_res = validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value);
             *
             *      Console.WriteLine("Round Nr:" + Convert.ToString(game.Turn));
             *      Console.WriteLine("HeroHP: " + Convert.ToString(player.Hero.Health) + "\tOppHP: " + Convert.ToString(game.CurrentOpponent.Hero.Health));
             *      Console.WriteLine("HeroMinionHP: " + Convert.ToString(player.BoardZone.Sum(p => p.Health)) + "\tOppMinionHP: " + Convert.ToString(game.CurrentOpponent.BoardZone.Sum(p => p.Health)));
             *      Console.WriteLine("HeroMinionAtk: " + Convert.ToString(player.BoardZone.Sum(p => p.AttackDamage)) + "\tOppMinionAtk: " + Convert.ToString(game.CurrentOpponent.BoardZone.Sum(p => p.AttackDamage)));
             *      foreach (var tmp_score in score_res)
             *      {
             *
             *              Console.WriteLine(Convert.ToString(tmp_score.Key) + Convert.ToString(tmp_score.Value));
             *      }
             *      Console.WriteLine("-------------------------------------------------------");
             * //PrintLog(game,  score_res);
             */
#endif

            if (player.Hero.Health < DEFENSE_HEALTH_THRESHOLD * player.Hero.BaseHealth)
            {
                RuntimeScaling[0] += 0.1;
            }

            if (opponent.Hero.Health < DEFENSE_HEALTH_THRESHOLD * opponent.Hero.Health)
            {
                RuntimeScaling[1] += 0.1;
            }

            var returnValue = validOpts.Any() ?
                              validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value).Last().Key :
                              player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);

            return(returnValue);

            KeyValuePair <PlayerTask, int> score(KeyValuePair <PlayerTask, POGame> state, int player_id, int max_depth = 3)
            {
                int max_score = int.MinValue;

                if (max_depth > 0 && state.Value.CurrentPlayer.PlayerId == player_id)
                {
                    var subactions = state.Value.Simulate(state.Value.CurrentPlayer.Options()).Where(x => x.Value != null);

                    foreach (var subaction in subactions)
                    {
                        max_score = Math.Max(max_score, score(subaction, player_id, max_depth - 1).Value);
                    }
                }
                max_score = Math.Max(max_score, Score(state.Value, player_id));
                return(new KeyValuePair <PlayerTask, int>(state.Key, max_score));
            }
        }
            /* Cannot be used when using threads
             * public void PrintLog(POGame game, IOrderedEnumerable<KeyValuePair<PlayerTask, int>> scoreres)
             * {
             *      var player = game.CurrentPlayer;
             *      var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null);
             *      var score_res = scoreres;
             *      Console.WriteLine("Round Nr:" + Convert.ToString(game.Turn));
             *      Console.WriteLine("HeroHP: " + Convert.ToString(player.Hero.Health) + "\tOppHP: " + Convert.ToString(game.CurrentOpponent.Hero.Health));
             *      Console.WriteLine("HeroMinionHP: " + Convert.ToString(player.BoardZone.Sum(p => p.Health)) + "\tOppMinionHP: " + Convert.ToString(game.CurrentOpponent.BoardZone.Sum(p => p.Health)));
             *      Console.WriteLine("HeroMinionAtk: " + Convert.ToString(player.BoardZone.Sum(p => p.AttackDamage)) + "\tOppMinionAtk: " + Convert.ToString(game.CurrentOpponent.BoardZone.Sum(p => p.AttackDamage)));
             *      foreach (var tmp_score in score_res)
             *      {
             *
             *              Console.WriteLine(Convert.ToString(tmp_score.Key) + Convert.ToString(tmp_score.Value));
             *      }
             *      Console.WriteLine("-------------------------------------------------------");
             * }
             */
            public override PlayerTask GetMove(POGame game)
            {
                var player = game.CurrentPlayer;

                // Implement a simple Mulligan Rule
                if (player.MulliganState == Mulligan.INPUT)
                {
                    List <int> mulligan = new CustomScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                    return(ChooseTask.Mulligan(player, mulligan));
                }

                var opponent  = game.CurrentOpponent;
                var options   = player.Options();
                var validOpts = game.Simulate(options).Where(x => x.Value != null);
                var optcount  = validOpts.Count();



                if (game.Turn == 1)
                {
                    var opt1 = options.Where(x => x.HasSource && x.Source.Card.Name == "N'Zoth's First Mate");
                    if (opt1.Count() > 0)
                    {
                        /*
                         * Console.WriteLine(opt1);
                         * Console.WriteLine(opt1.First());
                         * Console.WriteLine(opt1.Last());
                         */
                        return(opt1.First());
                    }
                }


                if (game.Turn == 3)
                {
                    var opt2 = options.Where(x => x.HasSource && x.Source.Card.Name == "Fiery War Axe");
                    if (opt2.Count() > 0)
                    {
                        return(opt2.First());
                    }
                }
                if (game.Turn == 5)
                {
                    var opt2 = options.Where(x => x.HasSource && x.Source.Card.Name == "Arcanite Reaper");
                    if (opt2.Count() > 0)
                    {
                        return(opt2.First());
                    }
                }


                /*
                 * if (player.Hero.Health < DEFENSE_HEALTH_THRESHOLD * player.Hero.BaseHealth)
                 *      RuntimeScaling[0] += 0.1;
                 *
                 * if (opponent.Hero.Health < DEFENSE_HEALTH_THRESHOLD * opponent.Hero.Health)
                 *      RuntimeScaling[1] += 0.1;
                 */
                var returnValue = validOpts.Any() ?
                                  validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value).Last().Key :
                                  player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);

                return(returnValue);

                KeyValuePair <PlayerTask, int> score(KeyValuePair <PlayerTask, POGame> state, int player_id, int max_depth = 3)
                {
                    int max_score = int.MinValue;

                    if (max_depth > 0 && state.Value.CurrentPlayer.PlayerId == player_id)
                    {
                        var subactions = state.Value.Simulate(state.Value.CurrentPlayer.Options()).Where(x => x.Value != null);

                        foreach (var subaction in subactions)
                        {
                            max_score = Math.Max(max_score, score(subaction, player_id, max_depth - 1).Value);
                        }
                    }
                    max_score = Math.Max(max_score, Score(state.Value, player_id));
                    return(new KeyValuePair <PlayerTask, int>(state.Key, max_score));
                }
            }
        public override PlayerTask GetMove(POGame game)
        {
            var player = game.CurrentPlayer;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new CustomScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }


            var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null);
            var optcount  = validOpts.Count();

            var returnValue = validOpts.Any() ?
                              validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value).Last().Key :
                              player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);

            return(returnValue);

            KeyValuePair <PlayerTask, int> score(KeyValuePair <PlayerTask, POGame> state, int player_id, int max_depth = 3)
            {
                int max_score = int.MinValue;

                if (max_depth > 0 && state.Value.CurrentPlayer.PlayerId == player_id)
                {
                    var subactions = state.Value.Simulate(state.Value.CurrentPlayer.Options()).Where(x => x.Value != null);

                    foreach (var subaction in subactions)
                    {
                        max_score = Math.Max(max_score, score(subaction, player_id, max_depth - 1).Value);
                    }
                }
                max_score = Math.Max(max_score, Score(state.Value, player_id));
                return(new KeyValuePair <PlayerTask, int>(state.Key, max_score));
            }
        }
Ejemplo n.º 24
0
        public override PlayerTask GetMove(POGame poGame)
        {
            Console.WriteLine(poGame.PartialPrint());

            var player = poGame.CurrentPlayer;

            // During Mulligan: select Random cards
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = RandomMulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

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

            int count = 0;

            foreach (PlayerTask option in options)
            {
                count++;
                Console.WriteLine("[" + count.ToString() + "] " + option);
            }

            bool success = false;
            int  choice  = 0;

            while (!success)
            {
                string input = Console.ReadLine();
                choice = int.Parse(input);
                if (choice > 0 && choice <= count)
                {
                    success = true;
                }
                else
                {
                    Console.WriteLine("Please enter a number for the option you choose.");
                }
            }

            return(options[choice - 1]);
        }
Ejemplo n.º 25
0
        public override PlayerTask GetMove(POGame poGame)
        {
            var player    = poGame.CurrentPlayer;
            var opponent  = poGame.CurrentOpponent;
            var validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null);
            var history   = opponent.PlayHistory;

            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new MyScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }
            updateProbabilities();

            ActionEstimator = new ActionEstimator(DecksDict, ProbabilitiesDict);

            int optionsCount = validOpts.Count();

            Console.WriteLine("Valid options for TestAgent: ");
            validOpts.ToList().ForEach(option => Console.WriteLine(option));

            var action = validOpts.Any() ?
                         validOpts.Select(option => Score(option, poGame.CurrentPlayer.PlayerId, (optionsCount >= 5) ? ((optionsCount >= 25) ? 1 : 2) : 3)).OrderBy(pair => pair.Value).Last().Key :
                         player.Options().First(option => option.PlayerTaskType == PlayerTaskType.END_TURN);

            Console.WriteLine("TestAgent: " + action);
            return(action);

            void updateProbabilities()
            {
                /* ----------- Counting probabilities ------------ */
                foreach (KeyValuePair <string, List <Card> > deck in DecksDict)
                {
                    int similarCount      = 0;
                    var playedCards       = history.Select(h => h.SourceCard).ToList();
                    var deckCards         = deck.Value;
                    var deckCardsDistinct = deckCards.Distinct().ToList();

                    playedCards
                    .ForEach(playedCard =>
                    {
                        deckCardsDistinct.ForEach(deckCard =>
                        {
                            if (playedCard.Name == deckCard.Name)
                            {
                                similarCount++;
                            }
                        });
                    });

                    double probability = Math.Round((double)similarCount / deckCards.Count(), 2);
                    ProbabilitiesDict[deck.Key] = probability;
                    //if (probability > 0) Console.WriteLine(deck.Key + " has probability of " + ProbabilitiesDict[deck.Key] * 100 + "%");
                }
            }
        }
        public override PlayerTask GetMove(POGame poGame)
        {
            var player = poGame.CurrentPlayer;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new ControlScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            // Apply MCTS and do the best move
            PlayerTask action = null;

            try
            {
                if (mcts)
                {
                    action = MCTS(poGame.getCopy());
                }
                else
                {
                    var legalMoves = poGame.Simulate(player.Options()).Where(x => x.Value != null);
                    return(legalMoves.Any() ?
                           legalMoves.OrderBy(x => Score(x.Value, player.PlayerId)).Last().Key :
                           player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN));
                }
            }
            catch (NullReferenceException)
            {
                action = player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);
            }
            if (myDebug)
            {
                Console.WriteLine();
                Console.WriteLine(poGame.FullPrint());
                Console.WriteLine("Chose action: " + action);
            }
            return(action);
        }
        public override PlayerTask GetMove(POGame game)
        {
            var player = game.CurrentPlayer;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            // Get all simulation results for simulations that didn't fail
            var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null);

            // If all simulations failed, play end turn option (always exists), else best according to score function
            return(validOpts.Any() ?
                   validOpts.OrderBy(x => Score(x.Value, player.PlayerId)).Last().Key :
                   player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN));
        }
Ejemplo n.º 28
0
        //POGame poGame2;
        public override PlayerTask GetMove(POGame poGame)
        {
            var player = poGame.CurrentPlayer;

            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new CustomScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

#if DEBUG
            Console.WriteLine($"root:{GetGameHashCode(poGame)}");
#endif
            PlayerTask bestAction = null;
            if (poGame.CurrentPlayer.Options().Count == 1)
            {
                bestAction = poGame.CurrentPlayer.Options()[0];
            }
            else
            {
                stopwatchForThisTurn.Start();

                long       bestActionCode = 0;
                Trajectory trajectory     = new Trajectory();

                List <PlayerTask> taskToSimulate = new List <PlayerTask>(1);
                taskToSimulate.Add(null);
                POGame poGameRoot = poGame;

                Node root;
                long gameHashCodeRoot = GetGameHashCode(poGameRoot);
                if (!nodeHashMap.TryGetValue(gameHashCodeRoot, out root))
                {
                    root = new Node();
                    nodeHashMap.Add(gameHashCodeRoot, root);
                }

                Expand(root, poGameRoot);

                /*foreach (var child in root.edges)
                 * {
                 *      Console.WriteLine(child.actionHashCode);
                 * }*/

                long      think_time = (30 * 1000 - stopwatchForThisTurn.ElapsedMilliseconds) / Math.Max(3, 5 - movesInThisTurn);
                Stopwatch stopwatch  = new Stopwatch();
                stopwatch.Start();
                //for (int itr = 0; itr < 100; ++itr)
                while (stopwatch.ElapsedMilliseconds <= think_time)
                {
                    Node node = root;
                    poGame = poGameRoot.getCopy();
                    long gameHashCode       = gameHashCodeRoot;
                    long actionHashCodeNext = 0;
                    bool simulateResult     = true;
                    int  index = 0;
                    trajectory.Clear();

                    // traverse
                    do
                    {
                        index = Select(node);

                        /*if (index >= node.edges.Count)
                         * {
                         *      Console.WriteLine($"{index}, {node.edges.Count}, {node == root}");
                         *      Debugger.Break();
                         * }*/
                        actionHashCodeNext = node.edges[index].actionHashCode;

                        // Until the end of my own turn
                        if (actionHashCodeNext == 0)
                        {
                            trajectory.Add((node, index));
                            break;
                        }

                        taskToSimulate[0] = null;
                        foreach (PlayerTask task in poGame.CurrentPlayer.Options())
                        {
                            if (GetActionHashCode(task) == actionHashCodeNext)
                            {
                                taskToSimulate[0] = task;
                                break;
                            }
                        }
                        if (taskToSimulate[0] == null)
                        {
                            // Hash key conflict
                            return(poGame.CurrentPlayer.Options().First());

                            /*foreach (PlayerTask task in poGame.CurrentPlayer.Options())
                             * {
                             *      Console.WriteLine($"{task}, {GetActionHashCode(task)}");
                             * }
                             * Console.WriteLine("---");
                             * foreach (var edge in node.edges)
                             * {
                             *      Console.WriteLine($"{edge.task}, {edge.actionHashCode}");
                             * }
                             * poGame2 = node.poGame;
                             * Console.WriteLine(poGame2.Turn);
                             * Console.WriteLine(gameHashCode);
                             * Console.WriteLine("---");
                             * foreach (var minion in poGame.CurrentPlayer.BoardZone)
                             * {
                             *      Console.WriteLine(minion.CantAttackHeroes);
                             * }
                             * var tasks = poGame.CurrentPlayer.Options();
                             * foreach (PlayerTask task in tasks)
                             * {
                             *      Console.WriteLine($"{task}, {GetActionHashCode(task)}");
                             * }
                             * Debugger.Break();*/
                        }

                        poGame = poGame.Simulate(taskToSimulate)[taskToSimulate[0]];
                        long gameHashCodeNext = GetGameHashCode(poGame);
                        if (gameHashCode == gameHashCodeNext)
                        {
                            // loop
                            node.edges.RemoveAt(index);
                            continue;
                        }
                        gameHashCode = gameHashCodeNext;

                        trajectory.Add((node, index));

                        if (!nodeHashMap.TryGetValue(gameHashCode, out node))
                        {
                            node = new Node();
                            //node.poGame = poGame;
                            nodeHashMap.Add(gameHashCode, node);
                        }
                    } while (node.edges != null);

                    if (simulateResult == false)
                    {
                        continue;
                    }

                    if (actionHashCodeNext != 0)
                    {
#if DEBUG
                        Console.WriteLine($"expand:{gameHashCode}");
#endif
                        Expand(node, poGame);

                        float value = Simulate(node, poGame);
                        Backup(trajectory, value);
                    }
                    else
                    {
                        float value;
                        if (node.edges[index].visitCount == 0)
                        {
                            value = ScoreToValue(Score(poGame));
                        }
                        else
                        {
                            value = node.edges[index].totalValue / node.edges[index].visitCount;
                        }
                        Backup(trajectory, value);
                    }
                }
                stopwatch.Stop();
                //Console.WriteLine($"{think_time}, {root.visitCount}, {root.visitCount * 1000 / stopwatch.ElapsedMilliseconds} nps");

                // Choose the most visited node
                float best = Single.MinValue;
                foreach (Edge child in root.edges)
                {
                    if (child.visitCount >= best)
                    {
                        best           = child.visitCount;
                        bestActionCode = child.actionHashCode;
                    }
                }

                // Choose an action with a matching hash code
                foreach (PlayerTask task in poGameRoot.CurrentPlayer.Options())
                {
                    if (GetActionHashCode(task) == bestActionCode)
                    {
                        bestAction = task;
                        break;
                    }
                }
            }

            stopwatchForThisTurn.Stop();
            ++movesInThisTurn;
            if (bestAction.PlayerTaskType == PlayerTaskType.END_TURN)
            {
                //Console.WriteLine(movesInThisTurn);
                stopwatchForThisTurn.Reset();
                movesInThisTurn = 0;
                nodeHashMap.Clear();
            }

            return(bestAction);
        }
Ejemplo n.º 29
0
        public override PlayerTask GetMove(POGame game)
        {
            Controller player = game.CurrentPlayer;

            if (h_score == -1)
            {
                determineScore(player);
            }
            // Implement a simple Mulligan Rule
            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new HarderMidRangeScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            int depth;
            int beamWidth;

            // Check how much time we have left on this turn. The hard limit is 75 seconds so we already stop
            // beam searching when 60 seconds have passed, just to be sure.
            if (_watch.ElapsedMilliseconds < 30 * 1000)
            {             // We still have ample time, proceed with beam search
                depth     = 15;
                beamWidth = 12;
            }
            else
            {             // Time is running out, just simulate one timestep now
                depth     = 1;
                beamWidth = 1;
                Console.WriteLine("Over 30s in turn already. Pausing beam search for this turn!");
            }

            _watch.Start();
            PlayerTask move = BeamSearch(game, depth, playerbeamWidth: beamWidth, opponentBeamWidth: 1);

            _watch.Stop();

            if (move.PlayerTaskType == PlayerTaskType.END_TURN)
            {
                _watch.Reset();
            }

            return(move);
        }
Ejemplo n.º 30
0
        public override PlayerTask GetMove(POGame poGame)
        {
            timeIsUp       = false;
            timer          = new Timer(28000);
            timer.Elapsed += whenTimeUp;
            timer.Enabled  = true;

            Controller player = poGame.CurrentPlayer;

            playerId = player.PlayerId;

            if (player.MulliganState == Mulligan.INPUT)
            {
                List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList());
                return(ChooseTask.Mulligan(player, mulligan));
            }

            IEnumerable <KeyValuePair <PlayerTask, POGame> > validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null);
            int countOptions = validOpts.Count();

            //AppendChildNodes(rootNode);

            int        bestScore  = Int32.MinValue;
            PlayerTask chosenTask = null;

            foreach (KeyValuePair <PlayerTask, POGame> option in validOpts)
            {
                int currentScore = MiniMax(0, option.Value, true, Int32.MinValue, Int32.MaxValue);
                //Console.WriteLine("Current Score: " + currentScore);
                if (currentScore > bestScore)
                {
                    bestScore  = currentScore;
                    chosenTask = option.Key;
                }
            }
            //Console.WriteLine("Best Score: " + bestScore);

            if (chosenTask == null)
            {
                chosenTask = player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);
            }

            //Console.WriteLine("Zugzeit " + stopWatch.Elapsed);
            //Console.WriteLine("Best Task: " + chosenTask);
            return(chosenTask);
        }