Ejemplo n.º 1
0
        private List <double[]> Evaluate(List <double[]> pop)
        {
            foreach (var item in pop)
            {
                item[item.Length - 1] = 0;
            }

            foreach (var player1 in pop)
            {
                AbstractAgent agent1 = new GreedyAgent();
                AbstractAgent agent2 = new KISSBot();

                Random rnd = new Random(Guid.NewGuid().GetHashCode());



                var gameHandler1 = new POGameHandler(gameConfig1, agent1, agent2, repeatDraws: false);
                var gameHandler2 = new POGameHandler(gameConfig2, agent1, agent2, repeatDraws: false);
                var gameHandler3 = new POGameHandler(gameConfig3, agent1, agent2, repeatDraws: false);
                //gameHandler.PlayGame(debug: true);
                gameHandler1.PlayGames(nr_of_games: _numGames, addResultToGameStats: true, debug: false);
                gameHandler2.PlayGames(nr_of_games: _numGames, addResultToGameStats: true, debug: false);
                gameHandler3.PlayGames(nr_of_games: _numGames, addResultToGameStats: true, debug: false);

                player1[player1.Length - 1] += gameHandler1.getGameStats().PlayerB_Wins;
                player1[player1.Length - 1] += gameHandler2.getGameStats().PlayerB_Wins;
                player1[player1.Length - 1] += gameHandler3.getGameStats().PlayerB_Wins;
            }

            return(pop.OrderByDescending(x => x[x.Length - 1]).ToList());
        }
Ejemplo n.º 2
0
        public static void TestPOGame()
        {
            Console.WriteLine("Setup gameConfig");

            var gameConfig = new GameConfig()
            {
                StartPlayer      = 1,
                Player1HeroClass = CardClass.MAGE,
                Player2HeroClass = CardClass.MAGE,
                Player1Deck      = Decks.RenoKazakusMage,
                Player2Deck      = Decks.RenoKazakusMage,
                FillDecks        = false,
                Shuffle          = true,
                Logging          = false
            };

            Console.WriteLine("Setup POGameHandler");
            AbstractAgent player1     = new GreedyAgent();
            AbstractAgent player2     = new GreedyAgent();
            var           gameHandler = new POGameHandler(gameConfig, player1, player2, repeatDraws: false);

            Console.WriteLine("Simulate Games");
            //gameHandler.PlayGame();
            gameHandler.PlayGames(nr_of_games: 1000, addResultToGameStats: true, debug: false);
            GameStats gameStats = gameHandler.getGameStats();

            gameStats.printResults();

            Console.WriteLine("Test successful");
            Console.ReadLine();
        }
Ejemplo n.º 3
0
        private static void Main()
        {
            Console.WriteLine("Setup gameConfig");

            var gameConfig = new GameConfig()
            {
                StartPlayer = 1,
                // line for deck selection in here
                Player1HeroClass = CardClass.WARRIOR,
                Player2HeroClass = CardClass.WARRIOR,
                FillDecks        = true,
                Shuffle          = true,
                Logging          = false
            };

            Console.WriteLine("Setup POGameHandler");
            AbstractAgent player1     = new GreedyAgent();
            AbstractAgent player2     = new MyAgent();
            var           gameHandler = new POGameHandler(gameConfig, player1, player2, repeatDraws: false);

            Console.WriteLine("Simulate Games");
            //gameHandler.PlayGame();
            gameHandler.PlayGames(nr_of_games: 100, addResultToGameStats: true, debug: false);
            GameStats gameStats = gameHandler.getGameStats();

            gameStats.printResults();

            Console.WriteLine("Test successful");
            Console.ReadLine();
        }
Ejemplo n.º 4
0
    public void PlayRandomGreedy(Game game)
    {
        RandomAgent player1 = new RandomAgent(1);
        GreedyAgent player2 = new GreedyAgent(2);

        PlayGame(game, player1, player2);
    }
Ejemplo n.º 5
0
        public void ShouldPlayCardOnOnlyOwlThatGoesFurthest()
        {
            var player = new GreedyAgent();
            var state  = TestUtilities.GenerateTestState(2, 1);

            var play = player.FormulatePlay(state);

            Assert.AreEqual(CardType.Red, play.Card);
            Assert.AreEqual(0, play.Position);
        }
Ejemplo n.º 6
0
        public void ShouldPlayCardOnOwlThatGoesFurthestWithHootingIntoNest()
        {
            var player = new GreedyAgent();
            var state  = TestUtilities.GenerateTestState(2);

            state.Board.Owls.Move(0, 6);

            var play = player.FormulatePlay(state);

            Assert.AreEqual(CardType.Red, play.Card);
            Assert.AreEqual(1, play.Position);
        }
Ejemplo n.º 7
0
        public void ShouldPlayCardOnOnlyOwlThatGoesFurthestWhenUsingGreedyStrategy()
        {
            var player       = new EpsilonGreedyAgent(0);
            var greedyPlayer = new GreedyAgent();

            var state = TestUtilities.GenerateTestState(2, 1);

            var play       = player.FormulatePlay(state);
            var greedyPlay = greedyPlayer.FormulatePlay(state);

            Assert.AreEqual(play.Card, greedyPlay.Card);
            Assert.AreEqual(play.Position, greedyPlay.Position);
        }
Ejemplo n.º 8
0
        private static void testWeights(Dictionary <string, CardClass> classMap, Dictionary <string, List <Card> > deckMap, List <string> deckList, List <double> weights)
        {
            Console.WriteLine("Simulate Games");
            Random r        = new Random();
            double wins     = 0.0;
            double losses   = 0.0;
            double numGames = 3000;

            for (int i = 0; i < numGames; i++)
            {
                string p1Deck = deckList[r.Next(deckList.Count)];
                string p2Deck = deckList[r.Next(deckList.Count)];

                var gameConfig = new GameConfig()
                {
                    StartPlayer      = r.Next(2) + 1,
                    Player1HeroClass = classMap.GetValueOrDefault(p1Deck, CardClass.MAGE),
                    Player2HeroClass = classMap.GetValueOrDefault(p2Deck, CardClass.ROGUE),
                    Player1Deck      = deckMap.GetValueOrDefault(p1Deck, Decks.RenoKazakusMage),
                    Player2Deck      = deckMap.GetValueOrDefault(p2Deck, Decks.MiraclePirateRogue),
                    FillDecks        = true,
                    Shuffle          = true,
                    Logging          = false
                };

                AbstractAgent player1 = new GreedyAgent();
                AbstractAgent player2 = new NNAgent(weights);
                Console.WriteLine("Game " + i + " " + p1Deck + " " + p2Deck);
                var gameHandler = new POGameHandler(gameConfig, player1, player2, repeatDraws: false);
                gameHandler.PlayGames(nr_of_games: 1, addResultToGameStats: true, debug: false);
                GameStats gameStats = gameHandler.getGameStats();
                wins   += gameStats.PlayerB_Wins;
                losses += gameStats.PlayerA_Wins;
            }

            Console.WriteLine("Bot winrate: " + (wins / (wins + losses)));
            Console.WriteLine("Wins: " + wins);
            Console.WriteLine("Losses: " + losses);
            Console.WriteLine("Draws: " + (numGames - (wins + losses)));
        }
Ejemplo n.º 9
0
    //? To score a game we set up three kinds of matchup, condense each one into a score,
    //? add the scores together and then normalise them between 0 and 1.
    public IEnumerator ScoreGame(Game game)
    {
        //? Reset
        playerBiasScore       = 0f;
        greedIsGoodScore      = 0f;
        skillIsBetterScore    = 0f;
        drawsAreBadScore      = 0f;
        highSkillBalanceScore = 0f;
        string scoresSoFar = "";

        if (interfaceEnabled)
        {
            currentRulesText.text  = game.GameToString();
            scoresSoFar            = "First Play Bias: " + ToScore(playerBiasScore) + "\n";
            currentScoresText.text = scoresSoFar;
            yield return(0);
        }

        //? Random vs. Random: These games can go either way, the only thing we're interested
        //? is if there's a clear bias towards playing first or second. This is a good indicator.
        //? Score is therefore proportional to the amount one agent won over the other.
        RandomAgent randomAgent1 = new RandomAgent(1);
        RandomAgent randomAgent2 = new RandomAgent(2);
        int         firstWon = 0; int secondWon = 0;

        for (int i = 0; i < randomRandomMatches; i++)
        {
            if (interfaceEnabled)
            {
                currentScoresText.text = "First Play Bias: Playing (" + i + "/" + randomRandomMatches + ")\n";
            }

            //NOTE MJ: Playing the games could be coroutines, so they don't block UI.
            //res is redundant game.endStatus already has info.
            yield return(GameEvaluation.instance.PlayGame(game, randomAgent1, randomAgent2));

            if (game.endStatus == 1)
            {
                firstWon++;
            }
            if (game.endStatus == 2)
            {
                secondWon++;
            }
            //? Yield after each playout - we could yield more frequently, this is OK though.
            yield return(0);
        }

        playerBiasScore = 1 - (Mathf.Abs(firstWon - secondWon) / randomRandomMatches);

        if (interfaceEnabled)
        {
            scoresSoFar            = "First Play Bias: " + ToScore(playerBiasScore) + "\n";
            currentScoresText.text = scoresSoFar;
            yield return(0);
        }

        //? We could also add in a measure of 'decisiveness' - i.e. games shouldn't end in draws.
        //? However for random agents this might happen just because they aren't very good.

        //? Random vs. Greedy: Greedy may not always win the game, but we expect it to
        //? win more than random. Score is proportion to the number of games greedy won or tied.
        int randomAgentWon = 0;

        for (int i = 0; i < greedyRandomMatches; i++)
        {
            if (interfaceEnabled)
            {
                currentScoresText.text = scoresSoFar + "Simple Beats Random: Playing (" + i + "/" + greedyRandomMatches + ")\n";
                yield return(0);
            }

            //? Small detail: note that we swap who plays first, to compensate
            //? for first-player advantage
            RandomAgent randomAgent = new RandomAgent(1 + (i % 2));
            GreedyAgent greedyAgent = new GreedyAgent(2 - (i % 2));

            //NOTE MJ: Playing the games could be coroutines, so they don't block UI. res could be an out parameter.
            yield return(GameEvaluation.instance.PlayGame(game, randomAgent, greedyAgent));

            if (game.endStatus == 1 + (i % 2))
            {
                randomAgentWon++;
            }
            yield return(0);
        }

        greedIsGoodScore = 1 - ((float)randomAgentWon / greedyRandomMatches);

        if (interfaceEnabled)
        {
            scoresSoFar           += "Simple Beats Random: " + ToScore(greedIsGoodScore) + "\n";
            currentScoresText.text = scoresSoFar;
            yield return(0);
        }

        //? Greedy vs. MCTS: We know that greedy players will avoid causing their own loss, and
        //? win if given the opportunity, but MCTS players can look ahead and plan. As a result,
        //? a more strategic game should be won by MCTS agents. Score is proportion of games MCTS
        //? agent won. Note that we might need to give the MCTS agent more computational resources
        //? for some games to ensure it is performing better.
        int mctsAgentWon = 0;

        for (int i = 0; i < greedySkilledMatches; i++)
        {
            if (interfaceEnabled)
            {
                currentScoresText.text = scoresSoFar + "Clever Beats Simple: Playing (" + i + "/" + greedySkilledMatches + ")\n";
                yield return(0);
            }

            MCTSAgent   skilledAgent = new MCTSAgent(1 + (i % 2));
            GreedyAgent greedyAgent  = new GreedyAgent(2 - (i % 2));

            //NOTE MJ: Playing the games could be coroutines, so they don't block UI. res could be an out parameter.
            yield return(GameEvaluation.instance.PlayGame(game, skilledAgent, greedyAgent));

            if (game.endStatus == 1 + (i % 2))
            {
                mctsAgentWon++;
            }
            yield return(0);
        }

        skillIsBetterScore = (float)mctsAgentWon / greedySkilledMatches;

        if (interfaceEnabled)
        {
            scoresSoFar           += "Clever Beats Simple: " + ToScore(skillIsBetterScore) + "\n";
            currentScoresText.text = scoresSoFar;
            yield return(0);
        }

        //? Finally, MCTS vs MCTS. If we wanted more depth, we could do two version of this,
        //? one with MCTS agents that are given different amounts of computation, to really
        //? test to see if more thinking time = better play. However, here we're just going to
        //? test a good old fashioned mirror matchup. For two good equal players, we want
        //? a) not too much imbalance in favour of either player and b) not too many draws.
        int       drawnGames = 0;
        int       firstPlayerWon = 0; int secondPlayerWon = 0;
        MCTSAgent skilledAgent1 = new MCTSAgent(1);
        MCTSAgent skilledAgent2 = new MCTSAgent(2);

        for (int i = 0; i < skilledMirrorMatches; i++)
        {
            if (interfaceEnabled)
            {
                currentScoresText.text = scoresSoFar +
                                         "Avoid Draws: Playing (" + i + "/" + skilledMirrorMatches + ")\n" +
                                         "High Skill Mirror Matchup: Playing (" + i + "/" + skilledMirrorMatches + ")\n";
                yield return(0);
            }

            //NOTE MJ: Playing the games could be coroutines, so they don't block UI. res could be an out parameter.
            yield return(GameEvaluation.instance.PlayGame(game, skilledAgent1, skilledAgent2));

            if (game.endStatus == 1)
            {
                firstPlayerWon++;
            }
            if (game.endStatus == 2)
            {
                secondPlayerWon++;
            }
            if (game.endStatus == 3 || game.endStatus == 0)
            {
                drawnGames++;
            }
            yield return(0);
        }

        drawsAreBadScore      = 1 - ((float)drawnGames / skilledMirrorMatches);
        highSkillBalanceScore = Mathf.Abs(firstPlayerWon - secondPlayerWon) / skilledMirrorMatches;

        if (interfaceEnabled)
        {
            currentScoresText.text = scoresSoFar + "Avoid Draws: " + ToScore(drawsAreBadScore) + "\n" +
                                     "High Skill Mirror Matchup: " + ToScore(highSkillBalanceScore) + "\n";
            yield return(0);
        }

        //? Now we can add up the scores and return them. If we wanted we could balance them so
        //? some scores are more important than others, or we could partition them into "must-haves"
        //? and "nice-to-haves". I discuss this in the tutorial video.

        // Debug.Log("Random vs. Random: "+playerBiasScore);
        // Debug.Log("Greedy vs. Random: "+greedIsGoodScore);
        // Debug.Log("MCTS vs. Greedy: "+skillIsBetterScore);
        // Debug.Log("MCTS vs. MCTS (draws): "+drawsAreBadScore);
        // Debug.Log("MCTS vs. MCTS (win balance): "+highSkillBalanceScore);

        game.evaluatedScore = (playerBiasScore + greedIsGoodScore + skillIsBetterScore + drawsAreBadScore + highSkillBalanceScore) / 5f;
    }
Ejemplo n.º 10
0
        private static void Main()
        {
            Console.WriteLine("Setup gameConfig");
            double[] values =
                new double[] { 41.9584023938321, 20.9314780959075, 42.5709950325876, 29.2160915509873, 3.02713018633757,
                               39.1902154319408, 16.5569344163206, 41.7280641359873, 25.5307942824582, 44.74108665634, 26.4395090874469,
                               34.6203779911717 };

            //var gameConfig = new GameConfig()
            //{
            //	StartPlayer = 1,
            //	Player1HeroClass = CardClass.SHAMAN,
            //	Player2HeroClass = CardClass.SHAMAN,
            //	Player1Deck = Decks.MidrangeJadeShaman,
            //	Player2Deck = Decks.MidrangeJadeShaman,
            //	FillDecks = true,
            //	Shuffle = true,
            //	Logging = false,
            //	History = true
            //};

            //EA ea = new EA(100, 0.1f, 6, 10, 4, 12);
            //var result = ea.StartEA();

            //Console.WriteLine("Values");
            //foreach (var item in result)
            //{
            //	Console.WriteLine(String.Join(',', item));
            //}

            Console.WriteLine("Setup POGameHandler");
            AbstractAgent player1 = new GreedyAgent();
            AbstractAgent player2 = new KISSBot();

            Random rnd = new Random(Guid.NewGuid().GetHashCode());

            GameConfig gameConfig1 = new GameConfig()
            {
                StartPlayer      = 1,
                Player1HeroClass = CardClass.SHAMAN,
                Player2HeroClass = CardClass.SHAMAN,
                Player1Deck      = Decks.MidrangeJadeShaman,
                Player2Deck      = Decks.MidrangeJadeShaman,
                FillDecks        = true,
                Shuffle          = true,
                Logging          = false,
                History          = true
            };
            GameConfig gameConfig2 = new GameConfig()
            {
                StartPlayer      = 1,
                Player1HeroClass = CardClass.MAGE,
                Player2HeroClass = CardClass.MAGE,
                Player1Deck      = Decks.RenoKazakusMage,
                Player2Deck      = Decks.RenoKazakusMage,
                FillDecks        = true,
                Shuffle          = true,
                Logging          = false,
                History          = true
            };
            GameConfig gameConfig3 = new GameConfig()
            {
                StartPlayer      = 1,
                Player1HeroClass = CardClass.WARRIOR,
                Player2HeroClass = CardClass.WARRIOR,
                Player1Deck      = Decks.AggroPirateWarrior,
                Player2Deck      = Decks.AggroPirateWarrior,
                FillDecks        = true,
                Shuffle          = true,
                Logging          = false,
                History          = true
            };

            Console.WriteLine("Simulate Games");
            var gameHandler1  = new POGameHandler(gameConfig1, player2, player1, repeatDraws: false);
            var gameHandler11 = new POGameHandler(gameConfig1, player1, player2, repeatDraws: false);
            var gameHandler2  = new POGameHandler(gameConfig2, player2, player1, repeatDraws: false);
            var gameHandler21 = new POGameHandler(gameConfig2, player1, player2, repeatDraws: false);
            var gameHandler3  = new POGameHandler(gameConfig3, player2, player1, repeatDraws: false);
            var gameHandler31 = new POGameHandler(gameConfig3, player1, player2, repeatDraws: false);

            //gameHandler11.PlayGame(debug: true);
            //gameHandler11.getGameStats().printResults();
            gameHandler1.PlayGames(nr_of_games: 100, addResultToGameStats: true, debug: false);
            gameHandler1.getGameStats().printResults();

            gameHandler11.PlayGames(nr_of_games: 100, addResultToGameStats: true, debug: false);
            gameHandler11.getGameStats().printResults();

            gameHandler2.PlayGames(nr_of_games: 100, addResultToGameStats: true, debug: false);
            gameHandler2.getGameStats().printResults();

            gameHandler21.PlayGames(nr_of_games: 100, addResultToGameStats: true, debug: false);
            gameHandler21.getGameStats().printResults();

            gameHandler3.PlayGames(nr_of_games: 100, addResultToGameStats: true, debug: false);
            gameHandler3.getGameStats().printResults();

            gameHandler31.PlayGames(nr_of_games: 100, addResultToGameStats: true, debug: false);
            gameHandler31.getGameStats().printResults();

            Console.ReadLine();
        }