示例#1
0
        public TournamentResult(VolcanoGame state, string playerOne, string playerTwo, TournamentTerminationType termination, long milliseconds)
        {
            PlayerOne = playerOne;
            PlayerTwo = playerTwo;

            Termination         = termination;
            ElapsedMilliseconds = milliseconds;

            if (state.CurrentState.Winner == Player.One || termination == TournamentTerminationType.PlayerTwoError)
            {
                PlayerOneScore = 1m;
            }
            else if (state.CurrentState.Winner == Player.Two || termination == TournamentTerminationType.PlayerOneError)
            {
                PlayerTwoScore = 1m;
            }
            else
            {
                // Draw
                PlayerOneScore = 0.5m;
                PlayerTwoScore = 0.5m;
            }

            try
            {
                Moves = state.GetDetailedMoveList();
            }
            catch (Exception ex)
            {
                using (StreamWriter w = new StreamWriter("errors.txt", true))
                {
                    w.WriteLine("Failed to copy move history! :: " + ex.Message);
                }
                Moves = new List <Move>();
            }
            TotalMoves = state?.CurrentState?.Turn ?? 0;
            if (Moves.Count > 0)
            {
                FirstTile = Moves[0].Location;
            }

            WinningPath  = state?.CurrentState?.WinningPath ?? new List <int>();
            WinCondition = state?.CurrentState?.WinCondition ?? new int();
        }
示例#2
0
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            List <Action>           games   = new List <Action>();
            List <TournamentResult> results = new List <TournamentResult>();

            int completedGames = 0;

            foreach (var engine1 in _players)
            {
                foreach (var engine2 in _players)
                {
                    if (engine1 != engine2 || _allowSelfPlay)
                    {
                        games.Add(() =>
                        {
                            Stopwatch killswitch = Stopwatch.StartNew();
                            VolcanoGame game     = new VolcanoGame();

                            VictoryType victory = VictoryType.None;
                            game.OnGameOver    += (p, v) => victory = v;

                            try
                            {
                                game.RegisterEngine(Player.One, _engines.GetEngine(engine1));
                                game.RegisterEngine(Player.Two, _engines.GetEngine(engine2));
                                game.SecondsPerEngineMove = _secondsPerMove;
                                game.StartNewGame();
                                game.ComputerPlay();

                                while (victory == VictoryType.None && game.CurrentState.Winner == Player.Empty && game.CurrentState.Turn < VolcanoGame.Settings.TournamentAdjudicateMaxTurns && killswitch.ElapsedMilliseconds < VolcanoGame.Settings.TournamentAdjudicateMaxSeconds * 1000)
                                {
                                    System.Threading.Thread.Sleep(100);
                                }

                                var termination = TournamentTerminationType.Normal;
                                if (game.CurrentState.Winner == Player.Empty)
                                {
                                    if (game.CurrentState.Turn >= VolcanoGame.Settings.TournamentAdjudicateMaxTurns)
                                    {
                                        termination = TournamentTerminationType.AdjudicateMoves;
                                    }
                                    else if (killswitch.ElapsedMilliseconds >= VolcanoGame.Settings.TournamentAdjudicateMaxSeconds * 1000)
                                    {
                                        termination = TournamentTerminationType.AdjudicateTime;
                                    }
                                }
                                if (victory == VictoryType.ArenaAdjudication)
                                {
                                    if (game.BackgroundError != null)
                                    {
                                        if (game.CurrentState.Winner == Player.One)
                                        {
                                            termination = TournamentTerminationType.PlayerTwoError;
                                        }
                                        else if (game.CurrentState.Winner == Player.Two)
                                        {
                                            termination = TournamentTerminationType.PlayerOneError;
                                        }
                                        else
                                        {
                                            termination = TournamentTerminationType.Error;
                                        }
                                    }
                                    else
                                    {
                                        termination = TournamentTerminationType.IllegalMove;
                                    }
                                }

                                lock (results)
                                {
                                    results.Add(new TournamentResult(game, engine1, engine2, termination, killswitch.ElapsedMilliseconds));
                                }
                            }
                            catch (Exception ex)
                            {
                                using (StreamWriter w = new StreamWriter("errors.txt", true))
                                {
                                    w.WriteLine("Failed to play \"" + engine1 + "\" and \"" + engine2 + "\"! :: " + ex.Message);
                                }

                                try
                                {
                                    var termination = game?.CurrentState?.Player == Player.One ? TournamentTerminationType.PlayerOneError : TournamentTerminationType.PlayerTwoError;

                                    lock (results)
                                    {
                                        results.Add(new TournamentResult(game, engine1, engine2, termination, killswitch.ElapsedMilliseconds));
                                    }
                                }
                                catch (Exception eotw)
                                {
                                    using (StreamWriter w2 = new StreamWriter("errors.txt", true))
                                    {
                                        w2.WriteLine("Failed to log result! :: " + eotw.Message);
                                    }
                                }
                            }

                            completedGames++;
                            worker.ReportProgress(0, new TournamentStatus(completedGames, totalGames));
                        });
                    }
                }
            }

            for (int r = 0; r < _rounds; r++)
            {
                Parallel.ForEach(games, x => x());
            }

            using (StreamWriter w = new StreamWriter(_gameDataFile))
            {
                w.WriteLine("Player_One,Player_Two,Winner,Termination,Total_Moves,Total_Milliseconds,Starting_Tile_Index,Transcript,Winning_Path,Win_Condition,Seconds_Per_Move");
                foreach (var result in results)
                {
                    string gameResult = "Draw";
                    if (result.PlayerOneScore > result.PlayerTwoScore)
                    {
                        gameResult = "One";
                    }
                    if (result.PlayerTwoScore > result.PlayerOneScore)
                    {
                        gameResult = "Two";
                    }

                    string transcript = "";
                    if (result.Moves.Count > 0)
                    {
                        try
                        {
                            transcript = result.Moves.Select(x => x.Tile + (VolcanoGame.Settings.IndicateTranscriptMoveType && x.Addition ? "+" : "")).Aggregate((c, n) => c + " " + n);
                        }
                        catch (Exception ex)
                        {
                            transcript = ex.Message;
                        }
                    }

                    string winningPath = "";
                    if (result.WinningPath != null && result.WinningPath.Count > 0)
                    {
                        try
                        {
                            winningPath = result.WinningPath.Select(x => Constants.TileNames[x]).Aggregate((c, n) => c + " " + n);
                        }
                        catch (Exception ex)
                        {
                            winningPath = ex.Message;
                        }
                    }

                    string winCondition = "";
                    if (result.WinCondition == 1)
                    {
                        winCondition = "Tie-breaker";
                    }
                    else
                    {
                        winCondition = "Normal Win (no tie-breaker)";
                    }

                    w.WriteLine(result.PlayerOne + "," + result.PlayerTwo + "," + gameResult + "," + result.Termination.ToString() + "," + result.TotalMoves + "," + result.ElapsedMilliseconds + "," + result.FirstTile + "," + transcript + "," + winningPath + "," + winCondition + "," + _secondsPerMove);
                }
            }

            List <TournamentResultLine> lines = new List <TournamentResultLine>();

            foreach (var engine1 in _players)
            {
                decimal score             = 0m;
                TournamentResultLine line = new TournamentResultLine();
                line.Name = engine1;
                foreach (var engine2 in _players)
                {
                    if (engine1 != engine2 || _allowSelfPlay)
                    {
                        decimal wins = results.Where(x => x.PlayerOne == engine1 && x.PlayerTwo == engine2).Sum(x => x.PlayerOneScore) + results.Where(x => x.PlayerOne == engine2 && x.PlayerTwo == engine1).Sum(x => x.PlayerTwoScore);
                        score += wins;
                        line.Data.Add(engine2, wins);
                    }
                    else
                    {
                        line.Data.Add(engine2, -1);
                    }
                }
                decimal total = results.Where(x => x.PlayerOne == engine1 || x.PlayerTwo == engine1).Count();
                line.TotalScore      = score;
                line.TotalPercentage = score * 100m / total;
                line.Score           = score;
                lines.Add(line);
            }

            lines.Sort((c, n) => n.Sort.CompareTo(c.Sort));

            List <string> names = new List <string>();

            for (int i = 0; i < lines.Count; i++)
            {
                lines[i].CrossTableName = (i + 1) + ". " + lines[i].Name;
                names.Add((i + 1).ToString());

                lines[i].NeustadtlScore = 0m;
                foreach (var opponent in lines)
                {
                    if (opponent.Name != lines[i].Name)
                    {
                        lines[i].NeustadtlScore += opponent.TotalScore * lines[i].Data[opponent.Name];
                    }
                }
            }

            // It doesn't make sense to save a cross table when there's only one person competing
            if (!string.IsNullOrEmpty(_crossTableFile) && lines.Count > 1)
            {
                using (StreamWriter w = new StreamWriter(_crossTableFile))
                {
                    // cs = common score
                    // ns = neustadtl score (figures in strength of opposition)
                    w.WriteLine("," + names.Aggregate((c, n) => c + "," + n) + ",cs,ns");
                    foreach (var player in lines)
                    {
                        w.Write(player.CrossTableName);
                        foreach (var opponent in lines)
                        {
                            string val = player.Data[opponent.Name] >= 0 ? player.Data[opponent.Name].ToString() : "";
                            w.Write("," + val);
                        }
                        w.Write(", " + player.TotalScore);
                        w.Write(", " + player.NeustadtlScore.ToString("0.00"));
                        w.WriteLine();
                    }
                }
            }
        }
示例#3
0
        private void QueueGame(string engine1, string engine2)
        {
            games.Add(() =>
            {
                Stopwatch killswitch = Stopwatch.StartNew();
                VolcanoGame game     = new VolcanoGame();

                VictoryType victory = VictoryType.None;
                game.OnGameOver    += (p, v) => victory = v;

                try
                {
                    game.RegisterEngine(Player.One, _engines.GetEngine(engine1), true);
                    game.RegisterEngine(Player.Two, _engines.GetEngine(engine2), true);
                    game.SecondsPerEngineMove = _secondsPerMove;
                    game.StartNewGame();
                    game.ComputerPlay();

                    while (victory == VictoryType.None &&
                           game.CurrentState.Winner == Player.Empty &&
                           game.CurrentState.Turn < VolcanoGame.Settings.TournamentAdjudicateMaxTurns &&
                           killswitch.ElapsedMilliseconds < VolcanoGame.Settings.TournamentAdjudicateMaxSeconds * 1000)
                    {
                        System.Threading.Thread.Sleep(100);
                    }

                    game.ForceStop();

                    var termination = TournamentTerminationType.Normal;
                    if (game.CurrentState.Winner == Player.Empty)
                    {
                        if (game.CurrentState.Turn >= VolcanoGame.Settings.TournamentAdjudicateMaxTurns)
                        {
                            termination = TournamentTerminationType.AdjudicateMoves;
                        }
                        else if (killswitch.ElapsedMilliseconds >= VolcanoGame.Settings.TournamentAdjudicateMaxSeconds * 1000)
                        {
                            termination = TournamentTerminationType.AdjudicateTime;
                        }
                    }
                    if (victory == VictoryType.ArenaAdjudication)
                    {
                        if (game.BackgroundError != null)
                        {
                            if (game.CurrentState.Winner == Player.One)
                            {
                                termination = TournamentTerminationType.PlayerTwoError;
                            }
                            else if (game.CurrentState.Winner == Player.Two)
                            {
                                termination = TournamentTerminationType.PlayerOneError;
                            }
                            else
                            {
                                termination = TournamentTerminationType.Error;
                            }
                        }
                        else
                        {
                            termination = TournamentTerminationType.IllegalMove;
                        }
                    }
                    else if (victory == VictoryType.OpponentTimeout)
                    {
                        termination = TournamentTerminationType.Timeout;
                    }

                    lock (results)
                    {
                        results.Add(new TournamentResult(game, engine1, engine2, termination, killswitch.ElapsedMilliseconds));
                    }
                }
                catch (Exception ex)
                {
                    using (StreamWriter w = new StreamWriter("errors.txt", true))
                    {
                        w.WriteLine("Failed to play \"" + engine1 + "\" and \"" + engine2 + "\"! :: " + ex.Message);
                    }

                    try
                    {
                        var termination = game?.CurrentState?.Player == Player.One ? TournamentTerminationType.PlayerOneError : TournamentTerminationType.PlayerTwoError;

                        lock (results)
                        {
                            results.Add(new TournamentResult(game, engine1, engine2, termination, killswitch.ElapsedMilliseconds));
                        }
                    }
                    catch (Exception eotw)
                    {
                        using (StreamWriter w2 = new StreamWriter("errors.txt", true))
                        {
                            w2.WriteLine("Failed to log result! :: " + eotw.Message);
                        }
                    }
                }

                completedGames++;
                worker.ReportProgress(0, new TournamentStatus(completedGames, totalGames, timeouts));
            });
        }