예제 #1
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));
            }
        }
예제 #2
0
        internal void TurnStart(ActivePlayer player)
        {
            if (!_isMulliganDone)
            {
                _game.Process(ChooseTask.Mulligan(_game.Player1, _toBeKept));
                _game.Process(ChooseTask.Mulligan(_game.Player2, _game.Player2.Choice.Choices));
            }
            _isMulliganDone = true;
            _isNewTurn      = true;
            _activePlayer   = player;
            _numberOfTurns++;

            if (_numberOfTurns > 1)
            {
                ProcessPlayerAction();
                _game.MainEnd();
                _game.MainNext();
            }

            GameV2 gameV2 = Core.Game;

            if (player == ActivePlayer.Player)
            {
                _messenger.Reset();
                _messenger.SetTitle("Turn " + gameV2.GetTurnNumber());
            }
            Converter.AreGamesInSync(_game, gameV2);
        }
예제 #3
0
        public static void Kazakus()
        {
            var game = new Game(new GameConfig
            {
                StartPlayer      = 1,
                Player1HeroClass = CardClass.DRUID,
                Player1Deck      = new List <Card>()
                {
                },
                Player2HeroClass = CardClass.DRUID,
                Player2Deck      = new List <Card>()
                {
                },
                FillDecks = false
            });

            game.StartGame();
            game.Player1.BaseMana = 10;
            game.Player2.BaseMana = 10;
            var testCard = Generic.DrawCard(game.CurrentPlayer, Cards.FromName("Kazakus"));

            game.Process(PlayCardTask.Minion(game.CurrentPlayer, testCard));
            game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[0]));
            game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[0]));
            game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[0]));

            ShowLog(game, LogLevel.VERBOSE);
        }
예제 #4
0
        static void CloneAdapt()
        {
            var game = new Game(new GameConfig
            {
                StartPlayer      = 1,
                Player1HeroClass = CardClass.DRUID,
                Player2HeroClass = CardClass.DRUID,
                FillDecks        = true
            });

            game.Player1.BaseMana = 10;
            game.Player2.BaseMana = 10;
            game.StartGame();

            var minion = Generic.DrawCard(game.CurrentPlayer, Cards.FromName("Elder Longneck"));
            var clone1 = game.Clone();
            var clone2 = game.Clone();
            var clone3 = game.Clone();
            var clone4 = game.Clone();

            game.Process(PlayCardTask.Minion(game.CurrentPlayer, game.CurrentPlayer.HandZone[4]));
            game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[0]));

            clone1.Process(PlayCardTask.Minion(clone1.CurrentPlayer, clone1.CurrentPlayer.HandZone[4]));
            clone1.Process(ChooseTask.Pick(clone1.CurrentPlayer, clone1.CurrentPlayer.Choice.Choices[0]));

            clone2.Process(PlayCardTask.Minion(clone2.CurrentPlayer, clone2.CurrentPlayer.HandZone[4]));
            clone2.Process(ChooseTask.Pick(clone2.CurrentPlayer, clone2.CurrentPlayer.Choice.Choices[0]));

            clone3.Process(PlayCardTask.Minion(clone3.CurrentPlayer, clone3.CurrentPlayer.HandZone[4]));
            clone3.Process(ChooseTask.Pick(clone3.CurrentPlayer, clone3.CurrentPlayer.Choice.Choices[0]));

            clone4.Process(PlayCardTask.Minion(clone4.CurrentPlayer, clone4.CurrentPlayer.HandZone[4]));
            clone4.Process(ChooseTask.Pick(clone4.CurrentPlayer, clone4.CurrentPlayer.Choice.Choices[0]));
        }
예제 #5
0
        public static void GameMulliganTest()
        {
            var game =
                new Game(new GameConfig
            {
                StartPlayer      = 1,
                Player1HeroClass = CardClass.PRIEST,
                Player2HeroClass = CardClass.HUNTER,
                FillDecks        = true,
                SkipMulligan     = false
            });

            game.StartGame();

            game.Process(ChooseTask.Mulligan(game.Player1,
                                             game.Player1.Choice.Choices.Where(p => game.IdEntityDic[p].Cost > 3).ToList()));

            game.Process(ChooseTask.Mulligan(game.Player2,
                                             game.Player2.Choice.Choices.Where(p => game.IdEntityDic[p].Cost > 3).ToList()));

            game.MainReady();

            ShowLog(game, LogLevel.VERBOSE);

            Console.WriteLine(game.Player1.Choice?.FullPrint());
            Console.WriteLine(game.Player2.Choice?.FullPrint());
        }
예제 #6
0
        public static void RandomGames()
        {
            int numGames = 1000;
            var watch    = Stopwatch.StartNew();

            long numTurns   = 0;
            long numOptions = 0;
            long numActions = 0;

            int[] wins = new[] { 0, 0 };

            for (int i = 0; i < numGames; i++)
            {
                var game = new Game(GameConfig());
                game.StartGame();

                game.Process(ChooseTask.Mulligan(game.Player1, new List <int> {
                }));
                game.Process(ChooseTask.Mulligan(game.Player2, new List <int> {
                }));

                game.MainReady();

                while (game.State != State.COMPLETE)
                {
                    List <PlayerTask> options = game.CurrentPlayer.Options();
                    PlayerTask        option  = options[Rnd.Next(options.Count)];
                    //Console.WriteLine(option.FullPrint());
                    game.Process(option);

                    numActions += 1;
                    numOptions += options.Count;
                }

                numTurns += game.Turn;

                if (game.Player1.PlayState == PlayState.WON)
                {
                    wins[0]++;
                }
                if (game.Player2.PlayState == PlayState.WON)
                {
                    wins[1]++;
                }
            }

            watch.Stop();

            Console.WriteLine($"{numGames} games with {numTurns} turns took {watch.ElapsedMilliseconds} ms => " +
                              $"Avg. {watch.ElapsedMilliseconds / (float) numGames} ms per game " +
                              $"and {numGames / (float) watch.ElapsedMilliseconds * 1000.0} games per second ");
            Console.WriteLine($"{numTurns / (float) numGames} turns per game!");
            Console.WriteLine($"{numActions / (float) numGames} actions per game and " +
                              $"{numActions / (float) numTurns} actions per turn!");
            Console.WriteLine($"{numOptions / (float) numTurns} options per action!");
            Console.WriteLine($"playerA {wins[0] * 100.0 / numGames}% vs. playerB {wins[1] * 100.0 / numGames}%!");
        }
        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 + "%");
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Choose Nth item from choices (the leftest one is 1)
        /// </summary>
        public static void ChooseNthChoice(this Game game, int n)
        {
            if (n > game.CurrentPlayer.Choice.Choices.Count)
            {
                throw new ArgumentOutOfRangeException();
            }

            game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[n - 1]));
        }
        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 + "%");
                }
            }
        }
예제 #10
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);
        }
예제 #11
0
        override public PlayerTask GetMulliganChoices()
        {
            Debug.Assert(_BoundController.Game.Step == Step.BEGIN_MULLIGAN);

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

            IEnumerable <IEnumerable <int> > choices = Util.GetPowerSet(_BoundController.Choice.Choices);

            choices.ToList().ForEach(p => options.Add(ChooseTask.Mulligan(this._BoundController, p.ToList())));

            return(options[Util.Random.Next(options.Count())]);
        }
예제 #12
0
파일: Program.cs 프로젝트: leod/SabberStone
        public static void OneTurn()
        {
            var game = new Game(
                new GameConfig()
            {
                StartPlayer      = 1,
                Player1Name      = "FitzVonGerald",
                Player1HeroClass = CardClass.WARRIOR,
                Player1Deck      = Decks.AggroPirateWarrior,
                Player2Name      = "RehHausZuckFuchs",
                Player2HeroClass = CardClass.SHAMAN,
                Player2Deck      = Decks.MidrangeJadeShaman,
                FillDecks        = false,
                Shuffle          = false,
                SkipMulligan     = false
            });

            game.Player1.BaseMana = 10;
            game.StartGame();

            var aiPlayer1 = new AggroScore();
            var aiPlayer2 = new AggroScore();

            game.Process(ChooseTask.Mulligan(game.Player1, aiPlayer1.MulliganRule().Invoke(game.Player1.Choice.Choices.Select(p => game.IdEntityDic[p]).ToList())));
            game.Process(ChooseTask.Mulligan(game.Player2, aiPlayer2.MulliganRule().Invoke(game.Player2.Choice.Choices.Select(p => game.IdEntityDic[p]).ToList())));

            game.MainReady();

            while (game.CurrentPlayer == game.Player1)
            {
                Console.WriteLine($"* Calculating solutions *** Player 1 ***");

                List <OptionNode> solutions = OptionNode.GetSolutions(game, game.Player1.Id, aiPlayer1, 10, 500);

                var solution = new List <PlayerTask>();
                solutions.OrderByDescending(p => p.Score).First().PlayerTasks(ref solution);
                Console.WriteLine($"- Player 1 - <{game.CurrentPlayer.Name}> ---------------------------");

                foreach (PlayerTask task in solution)
                {
                    Console.WriteLine(task.FullPrint());
                    game.Process(task);
                    if (game.CurrentPlayer.Choice != null)
                    {
                        break;
                    }
                }
            }

            Console.WriteLine(game.Player1.HandZone.FullPrint());
            Console.WriteLine(game.Player1.BoardZone.FullPrint());
        }
예제 #13
0
        /// <summary>
        /// Choose Nth item from choices (the leftest one is 1)
        /// </summary>
        public static void ChooseNthChoice(this Game game, int n)
        {
            if (n > game.CurrentPlayer.Choice.Choices.Count)
            {
                throw new ArgumentOutOfRangeException();
            }
            var option = ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[n - 1]);

            if (!game.Process(option))
            {
                throw new Exception($"{option} is not a valid task.");
            }
        }
예제 #14
0
        public static ChooseTask CreatePlayerTaskChoice(Game game, int PlayerId, ChoiceType choiceType, List <int> entities)
        {
            switch (choiceType)
            {
            case ChoiceType.MULLIGAN:
                return(ChooseTask.Mulligan(game.Player1.PlayerId == PlayerId ? game.Player1 : game.Player2.PlayerId == PlayerId ? game.Player2 : null, entities));

            case ChoiceType.GENERAL:
                return(ChooseTask.Pick(game.CurrentPlayer, entities[0]));

            default:
                return(null);
            }
        }
예제 #15
0
        private PlayerTask ProcessPowerChoiceData(int PlayerId, ChoiceType choiceType, List <int> entities)
        {
            switch (choiceType)
            {
            case ChoiceType.MULLIGAN:
                return(ChooseTask.Mulligan(_game.Player1.PlayerId == PlayerId ? _game.Player1 : _game.Player2.PlayerId == PlayerId ? _game.Player2 : null, entities));

            case ChoiceType.GENERAL:
                return(ChooseTask.Pick(_game.CurrentPlayer, entities[0]));

            default:
                return(null);
            }
        }
예제 #16
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)]);
        }
예제 #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));
        }
예제 #18
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);
        }
예제 #19
0
        /// <summary>
        /// Choose Nth item from choices (the leftest one is 1).
        /// </summary>
        /// <returns>The chosen entity.</returns>
        public static IPlayable ChooseNthChoice(this Game game, int n)
        {
            if (n > game.CurrentPlayer.Choice.Choices.Count)
            {
                throw new ArgumentOutOfRangeException();
            }

            int        pick   = game.CurrentPlayer.Choice.Choices[n - 1];
            ChooseTask option = ChooseTask.Pick(game.CurrentPlayer, pick);

            if (!game.Process(option))
            {
                throw new Exception($"{option} is not a valid task.");
            }

            return(game.IdEntityDic[pick]);
        }
예제 #20
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);
        }
예제 #21
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);
        }
        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));
        }
        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));
            }


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

            PlayerTask 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 = Int32.MinValue;

                if (max_depth > 0 && state.Value.CurrentPlayer.PlayerId == player_id)
                {
                    IEnumerable <KeyValuePair <PlayerTask, POGame> > subactions = state.Value.Simulate(state.Value.CurrentPlayer.Options()).Where(x => x.Value != null);

                    foreach (KeyValuePair <PlayerTask, POGame> 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));
            }
        }
예제 #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]);
        }
예제 #25
0
        public void OnChooseEntities(KettleChooseEntities chooseEntities)
        {
            Console.WriteLine("simulator OnChooseEntities called");

            var entityChoices = Game.EntityChoicesMap[chooseEntities.Id];
            var chooseTask    = entityChoices.ChoiceType == ChoiceType.MULLIGAN
                                ? ChooseTask.Mulligan(entityChoices.PlayerId == 1 ? Game.Player1 : Game.Player2, chooseEntities.Choices)
                                : ChooseTask.Pick(entityChoices.PlayerId == 1 ? Game.Player1 : Game.Player2, chooseEntities.Choices[0]);

            Console.WriteLine($"processing => {chooseTask.FullPrint()}");

            Adapter.SendMessage(new KettleEntitiesChosen
            {
                ChoiceType     = (int)entityChoices.ChoiceType,
                PlayerId       = entityChoices.PlayerId,
                ChooseEntities = chooseEntities,
            });

            Game.Process(chooseTask);
            ShowLog(Game, LogLevel.VERBOSE);

            SendPowerHistory(Game.PowerHistory.Last);
            SendChoicesOrOptions();

            if (Game.Step == Step.BEGIN_MULLIGAN &&
                Game.Player1.MulliganState == Mulligan.DONE &&
                Game.Player2.MulliganState == Mulligan.DONE)
            {
                Game.MainBegin();

                while (Game.Step != Step.MAIN_ACTION)
                {
                    Thread.Sleep(500);
                }

                ShowLog(Game, LogLevel.VERBOSE);

                SendPowerHistory(Game.PowerHistory.Last);
                SendChoicesOrOptions();
            }
        }
예제 #26
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 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 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);

            //Console.WriteLine("Dynamic Agent: " + returnValue);
            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));
            }
        }
예제 #29
0
        public static void Init()
        {
            int randomClassPlayer1 = r.Next() % 9;

            Player1Class = GetClassFromIndex(randomClassPlayer1);
            int randomClassPlayer2 = r.Next() % 9;

            Player2Class      = GetClassFromIndex(randomClassPlayer2);
            Player1Deck       = GetRandomStandardDeckFromClass(Player1Class);
            Player2Deck       = GetRandomStandardDeckFromClass(Player2Class);
            GameConfiguration = new GameConfig()
            {
                StartPlayer      = -1,
                Player1Name      = "Player 1",
                Player1HeroClass = Player1Class,
                Player1Deck      = Player1Deck,
                Player2Name      = "Player 2",
                Player2HeroClass = Player2Class,
                Player2Deck      = Player2Deck,
                FillDecks        = false,
                Shuffle          = true,
                SkipMulligan     = false,
                Logging          = false,
                History          = false
            };
            AllVisibleGame = new Game(GameConfiguration);
            AllVisibleGame.StartGame();
            AllVisibleGame.Process(ChooseTask.Mulligan(AllVisibleGame.Player1, MulliganRule().Invoke(AllVisibleGame.Player1.Choice.Choices.Select(p => AllVisibleGame.IdEntityDic[p]).ToList())));
            AllVisibleGame.Process(ChooseTask.Mulligan(AllVisibleGame.Player2, MulliganRule().Invoke(AllVisibleGame.Player2.Choice.Choices.Select(p => AllVisibleGame.IdEntityDic[p]).ToList())));
            AllVisibleGame.MainReady();

            PlayerViewGame       = CreatePartiallyObservableGame(AllVisibleGame);
            PlayerViewGameBinary = ObjectToByteArray(PlayerViewGame);
            List <PlayerTask> options = AllVisibleGame.CurrentPlayer.Options();

            NumberOfActions = options.Count;
            PlayerTurn      = AllVisibleGame.CurrentPlayer.Id;
        }
예제 #30
0
        public void OnEntityChoices(KettleEntityChoices entityChoices)
        {
            Console.WriteLine("AI EntityChoices called.");
            if (entityChoices.PlayerId != PlayerId)
            {
                return;
            }

            SabberStoneCore.Model.Entities.Controller player = PlayerId == 1 ? Session.Game.Player1 : Session.Game.Player2;
            Choice            Choice  = player.Choice;
            List <PlayerTask> options = new List <PlayerTask>();

            switch (Choice.ChoiceType)
            {
            case ChoiceType.GENERAL:
                Choice.Choices.ToList().ForEach(p => options.Add(ChooseTask.Pick(player, p)));
                break;

            case ChoiceType.MULLIGAN:
                IEnumerable <IEnumerable <int> > choices = SabberStoneCore.Model.Util.GetPowerSet(Choice.Choices);
                choices.ToList().ForEach(p => options.Add(ChooseTask.Mulligan(player, p.ToList())));
                break;

            default:
                throw new NotImplementedException();
            }

            // Do AI shit
            PlayerTask option = DoAI(options);

            // Convert it to a kettle choices
            KettleChooseEntities chooseEntities = new KettleChooseEntities();

            chooseEntities.Id      = entityChoices.Id;
            chooseEntities.Choices = ((ChooseTask)option).Choices;

            Adapter.SendMessage(chooseEntities);
        }