public static List <PlayerMetric> GetPlayerComparisons(Dictionary <string, Dictionary <int?, int> > metrics, SimulationSummary simulationSummary) { var playerMetrics = new List <PlayerMetric>(); foreach (var item in metrics) { var metric = item.Key; var scoresByPlayer = item.Value.ToDictionary(i => i.Key, i => i.Value.ToString()); var playerIds = simulationSummary.PlayersData.Select(p => p.Id).ToList(); // using the following formula, comparison = score / 2nd best score var orderedList = scoresByPlayer.OrderBy(s => Convert.ToInt16(s.Value)).ToList(); var secondBestValue = orderedList.Count == 1 ? orderedList.Last().Value : orderedList.ElementAt(orderedList.Count - 2).Value; var secondBest = Convert.ToInt16(secondBestValue); foreach (var playerId in playerIds) { var score = 0; if (playerId.HasValue && scoresByPlayer.TryGetValue(playerId, out var value)) { score = Convert.ToInt16(value); } var playerData = simulationSummary.PlayersData.First(p => p.Id == playerId); var comparison = new PlayerMetric { PlayerData = playerData, Metric = metric, Score = score, Ratio = (float)score / secondBest }; playerMetrics.Add(comparison); } } return(playerMetrics); }
public static List <PlayerMetric> GetPlayerBestMetrics(Dictionary <string, Dictionary <int?, int> > sumByPlayerByMetrics, SimulationSummary simulationSummary) { var playerComparisons = GetPlayerComparisons(sumByPlayerByMetrics, simulationSummary); var unique = UniquePlayerBests(playerComparisons); return(unique); //LogMetrics(unique); }
DisplaySeries createDisplaySeriesFromSummary(SimulationSummary summary) { DisplaySeries d = new DisplaySeries(); d.Mean = new LineSeries(); d.Mean.Title = summary.Name; d.Mean.ItemsSource = summary.Mean; d.UpperStandardError = new LineSeries(); d.UpperStandardError.ItemsSource = summary.UpperStandardError; d.UpperStandardError.LineStyle = LineStyle.Dash; d.LowerStandardError = new LineSeries(); d.LowerStandardError.ItemsSource = summary.LowerStandardError; d.LowerStandardError.LineStyle = LineStyle.Dash; return d; }
static void Main(string[] args) { /* * UnitTestSuite testSuite = new UnitTestSuite(); * testSuite.Run(); */ GunFactory gunFactory = new GunFactory(); //IGun mh = gunFactory.Get(GunType.Pistol); IGun mh = gunFactory.Get(GunType.Pepperbox); IGun artificerMh = gunFactory.Get(GunType.Pistol, WeaponTier.ArtificerReloadProperty); List <IGun> ohs = new List <IGun>() { gunFactory.Get(GunType.PalmPistol), gunFactory.Get(GunType.PalmPistol) }; List <IGun> artificerOhs = new List <IGun>() { gunFactory.Get(GunType.PalmPistol, WeaponTier.ArtificerReloadProperty) }; //List<Feat> feats = new List<Feat>() { Feat.None }; List <Feat> feats = new List <Feat>() { Feat.Sharpshooter }; List <MagicInitiateSpell> buffs = new List <MagicInitiateSpell>() { MagicInitiateSpell.None }; //List<MagicInitiateSpell> buffs = new List<MagicInitiateSpell>() { MagicInitiateSpell.Bless }; //List<MagicInitiateSpell> buffs = new List<MagicInitiateSpell>() { MagicInitiateSpell.Hex }; Rng rng = new Rng(); //buffs = new List<MagicInitiateSpell>() { MagicInitiateSpell.Bless }; //buffs = new List<MagicInitiateSpell>() { MagicInitiateSpell.Hex }; Player player = new Player(rng, 8, 8, FightingStyle.Archery, mh, ohs, feats, buffs); //Player player = new Player(rng, 6, 8, FightingStyle.Archery, artificerMh, artificerOhs, feats, buffs); int numTurns = 7; Enemy enemy = new Enemy(17); int numSims = 100000; //int numSimsPerThread = numSims / 4; int numSimsPerThread = numSims; BulkGunSlingerSimulation sim = new BulkGunSlingerSimulation(rng, numTurns, numSims, numSimsPerThread); SimulationSummary summary = sim.BulkSimulate(player, enemy); int totalTurns = numSims * numTurns; double dmgPerTurn = (double)summary.DamageDone / totalTurns; double shotsPerTurn = (double)summary.Shots / totalTurns; double hitsPerTurn = (double)summary.Hits / totalTurns; double critsPerTurn = (double)summary.Crits / totalTurns; double costPerSim = ((double)summary.Cost / numSims) / 100; double brokenGunsPerTurn = (double)summary.NumberOfBrokenGuns / totalTurns; Console.WriteLine("------ Summary ------"); Console.WriteLine($"Enemy AC: {enemy.ArmorClass}."); Console.WriteLine($"Number of Turns per sim: {numTurns}."); Console.WriteLine($"Number of total Turns: {totalTurns}.\n"); Console.WriteLine($"Damage per turn: " + string.Format("{0:0.000}", dmgPerTurn)); Console.WriteLine($"Shots per turn: " + string.Format("{0:0.000}", shotsPerTurn)); Console.WriteLine($"Hits per turn: " + string.Format("{0:0.000}", hitsPerTurn)); Console.WriteLine($"Crits per turn: " + string.Format("{0:0.000}", critsPerTurn)); Console.WriteLine($"Cost per combat encounter: " + string.Format("{0:0.000}", costPerSim) + "g"); Console.WriteLine($"Broken Guns per turn: " + string.Format("{0:0.000}", brokenGunsPerTurn)); //Misfires? Console.WriteLine("---------------------"); }
public int Run() { init(); if (UseDatabase) { ConnectDb(); } else if (TruncateFirst || DropAndCreateFirst || ClearTablesForMarker) { Print("You cannot do any data operations without --usedb"); return(1); } EmployeeTypesCM employeeTypesCM = new EmployeeTypesCM(); employeeTypesCM.Load(EmployeeTypesFilename); WorkshiftsCM workshifts = new WorkshiftsCM(employeeTypesCM); workshifts.Load(WorkshiftsFilename); TicketGenerationPlan ticketGenerationPlan = new TicketGenerationPlan(); ticketGenerationPlan.Load(TicketGenerationPlan); Print("All files loaded"); Print(string.Format("Total tickets: {0}", ticketGenerationPlan.TotalTickets)); if (Days == null) { Days = ticketGenerationPlan.NumberOfDays; Print("Found {0} days in ticket plan", Days); } int run = 0; if (UseDatabase) { if (DropAndCreateFirst) { DropTables(true); CreateTables(); } if (TruncateFirst) { TruncateTables(); } if (ClearTablesForMarker) { Print("Deleted old datapoints (if exists) ({0})", DeleteDatapointsForMarker(Name)); Print("Deleted old summary (if exists) ({0})", DeleteSummariesForMarker(Name)); } var getRunNumberCmd = new MySqlCommand(string.Format("select ifnull(max(run),0) as max from datapoints where marker=@Marker", Statics.TableSummaries), conn); getRunNumberCmd.Parameters.Add("@Marker", MySqlDbType.VarChar).Value = Name; using (var getRunNumberCmdReader = getRunNumberCmd.ExecuteReader()) { getRunNumberCmdReader.Read(); run = getRunNumberCmdReader.GetInt32("max") + 1; } Print("Run number {0}", run); } SimulationManager sm = new SimulationManager(Name, run, workshifts, ticketGenerationPlan, Days.Value); if (UseDatabase) { sm.NewDatapoint += Sm_NewDatapoint; } if (Debug) { sm.LogEvent += Print; } sm.Run(); if (UseDatabase) { Print("Inserting {0} datapoints into db if connected", datapoints.Count); int inserts = 0; if (datapoints.Count > 0) { inserts += InternalMySqlHelper.GetBulkInsert(conn, "datapoints", datapoints.ToArray()).ExecuteNonQuery(); } Print("Inserts: {0}", inserts); } List <TicketEntity> tickets = ticketGenerationPlan.Tickets; SimulationSummary ss = new SimulationSummary( Name, run, tickets.Where(t => t.Solved).Count(), tickets.Where(t => t.Deployed).Count(), tickets.Where(t => t.Started).Count(), tickets.Count(), tickets.Where(t => !t.Solved && t.Difficulty == Models.SupportLevel.Level1st).Count(), tickets.Where(t => !t.Solved && t.Difficulty == Models.SupportLevel.Level2nd).Count(), tickets.Where(t => t.Solved).Any() ? tickets.Where(t => t.Solved).Average(i => i.Duration) : 0, sm.Accounting.TotalExpenses, sm.Accounting.TotalWorkingHours, sm.Accounting.TotalWorkingHours != 0? sm.Accounting.TotalExpenses / sm.Accounting.TotalWorkingHours : 0, tickets.Where(t => !t.Solved).Count() ); if (UseDatabase) { var summaryInsert = InternalMySqlHelper.GetInsert(conn, TablePrefix + Statics.TableSummaries, ss); Print("Insert summary ({0})", summaryInsert.ExecuteNonQuery()); } Print("Solved tickets: {0}/{1}", ss.SolvedTickets, ss.TotalTickets); Print("Deployed tickets: {0} ", ss.DeployedTickets); Print("Started tickets: {0} ", ss.StartedTickets); Print("Open 1st level tickets: {0} ", ss.Open1stLevelTickets); Print("Open 2nd level tickets: {0} ", ss.Open2ndLevelTickets); Print("Average Duration: {0} ", ss.AverageTicketSolveDuration); Print("Total Costs: {0:C} ", ss.TotalCosts); Print("Total Costs: {0:#,##0} h ", ss.TotalCosts); Print("Average hourly wage: {0:C}", ss.AverageHourlyWage); return(0); }