Esempio n. 1
0
        public NewMainPage()
        {
            this.InitializeComponent();

            AvailablePlayer game = new AvailablePlayer("", typeof(DefaultPlayer), "Default - Easy", PlayerAlgorithm.Easy);

            AllPlayers.Add(game);
            PlayerOne = game;
            game      = new AvailablePlayer("-usedroptable", typeof(DefaultPlayer), "Default - Hard", PlayerAlgorithm.Hard);
            AllPlayers.Add(game);
            PlayerTwo = game;
            game      = new AvailablePlayer("", typeof(RandomPlayer), "Random Player", PlayerAlgorithm.Random);
            AllPlayers.Add(game);
            game = new AvailablePlayer("", typeof(CountingPlayer), "Improved Counting Player", PlayerAlgorithm.ImprovedCounting);
            AllPlayers.Add(game);
        }
Esempio n. 2
0
        /// <summary>
        ///     Create and run each of the games.  Keep track of how long it takes.  return the stats.
        /// </summary>
        /// <param name="iterations"></param>
        /// <param name="logger"></param>
        /// <param name="playerOne"></param>
        /// <param name="playerTwo"></param>
        /// <returns></returns>
        private async Task <GameStats> RunGames(int iterations, bool useLog, AvailablePlayer playerOne, AvailablePlayer playerTwo)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();


            ConcurrentBag <Game> gameBag = new ConcurrentBag <Game>();
            ConcurrentBag <Task> taskBag = new ConcurrentBag <Task>();
            bool playerOneStarts         = true;


            if (useLog)
            {
                //
                //  this has to happen on the main thread, so it can't happen inside the worker threads
                //
                //  this lets us put the documents in whatever location we want instead of inside the private storage area for the app, which is burried pretty deep in the
                //  disk heirarchy and hard to get to.  You only have to do this once per machine though.
                string content = "After clicking on \"Close\" pick the default location for all your CribbageAi saved state";
                _saveDirectory = await StaticHelpers.GetSaveFolder(content, "CribbageAI");

                _saveDirectory = await _saveDirectory.CreateFolderAsync(DateTime.Now.ToString("hh_mm_ss dd_MM_yyyy"));

                SaveDirectory = _saveDirectory.Path;
            }
            else
            {
                _saveDirectory = null;
                SaveDirectory  = "";
            }

            NotifyPropertyChanged("SaveDirectory");

            //
            //  this uses Parallel.For to create 1 thread per processor.  Each thread creates a tasks and starts running it.
            //  The task runs a game to completion, logging everything to a file. I do it this way so that I can wait for the
            //  logs to finish writing -- I found that if I did it outside of a Task list, it would finish the log writes async
            Parallel.For(0, iterations, i =>
            {
                taskBag.Add(Task.Run(async() =>
                {
                    Player player1 = (Player)Activator.CreateInstance(playerOne.GameType);
                    player1.Init(playerOne.Parameters);
                    player1.PlayerAlgorithm = playerOne.PlayerAlgorithm;

                    Player player2 = (Player)Activator.CreateInstance(playerTwo.GameType);
                    player2.Init(playerTwo.Parameters);
                    player2.PlayerAlgorithm = playerTwo.PlayerAlgorithm;


                    Game game = new Game(i, player1, player2, playerOneStarts);
                    await game.Init(useLog, _saveDirectory);

                    //
                    //  alternate who deals - looks like if you use the same algorithm, dealer *loses* 60% of the time!
                    if ((bool)AlternateWhoStarts)
                    {
                        if (playerOneStarts)
                        {
                            playerOneStarts = false;
                        }
                        else
                        {
                            playerOneStarts = true;
                        }
                    }


                    gameBag.Add(game);
                    await game.PlayGame();
                }
                                     ));
            });

            //
            //  wait for all the games to complete -- this includes the log writes
            Task.WaitAll(taskBag.ToArray());
            watch.Stop();

            //
            //  add up some stats
            GameStats stats = new GameStats();

            int totalP1LostScore = 0;
            int totalP2LostScore = 0;

            stats.WallClocktime = watch.ElapsedMilliseconds;
            stats.MSPerGame     = stats.WallClocktime / (double)iterations;



            foreach (var game in gameBag)
            {
                if (game == null)
                {
                    continue;
                }
                //
                //  this calculates the number of times each player one and the average of their *losing* score
                //
                if (game.PlayerOne.Winner)
                {
                    totalP2LostScore += game.PlayerTwo.Score;
                    stats.PlayerOneWin++;
                }
                else
                {
                    stats.PlayerTwoWin++;
                    totalP1LostScore += game.PlayerOne.Score;
                }

                stats.AverageCountPointsPlayerOne += game.AverageScore(PlayerName.PlayerOne, ScoreType.Count);
                stats.AverageCountPointsPlayerTwo += game.AverageScore(PlayerName.PlayerTwo, ScoreType.Count);

                stats.AverageHandPointsPlayerOne += game.AverageScore(PlayerName.PlayerOne, ScoreType.Hand);
                stats.AverageHandPointsPlayerTwo += game.AverageScore(PlayerName.PlayerTwo, ScoreType.Hand);

                stats.AverageCribPointsPlayerOne += game.AverageScore(PlayerName.PlayerOne, ScoreType.Crib);
                stats.AverageCribPointsPlayerTwo += game.AverageScore(PlayerName.PlayerTwo, ScoreType.Crib);
            }

            stats.AverageCountPointsPlayerOne /= gameBag.Count;
            stats.AverageCountPointsPlayerTwo /= gameBag.Count;
            stats.AverageHandPointsPlayerOne  /= gameBag.Count;
            stats.AverageHandPointsPlayerTwo  /= gameBag.Count;
            stats.AverageCribPointsPlayerOne  /= gameBag.Count;
            stats.AverageCribPointsPlayerTwo  /= gameBag.Count;
            stats.PlayerOneWinPercent          = Math.Round((double)stats.PlayerOneWin / (double)(iterations) * 100, 2);
            stats.PlayerTwoWinPercent          = Math.Round((double)stats.PlayerTwoWin / (double)(iterations) * 100, 2);
            stats.AverageScorePlayerOne        = Math.Round(totalP1LostScore / (double)(stats.PlayerTwoWin), 2);
            stats.AverageScorePlayerTwo        = Math.Round(totalP2LostScore / (double)(stats.PlayerOneWin), 2);

            return(stats);
        }