private static void WriteStats(IPlayerBaseSimulator playerBaseSim, TimeSimulator ts, MatchSimulator matchSimulator) { if (Console.CursorTop > 3) { Console.SetCursorPosition(0, Console.CursorTop - 3); } Evaluator.Calc(playerBaseSim); Console.WriteLine( $"Players online: {playerBaseSim.CurrentPlayerBase.Count}, Tick(Day): {ts.CurrentTick}({ts.CurrentDay})"); Console.WriteLine( $"Open Matchs (Total): {matchSimulator.CurrentNumberOfMatches} ({matchSimulator.TotalMatchesSimulated})"); }
static void Main(string[] args) { // assumption: player base is exactly as large as max system can hold. // if Hots Servers Scale good enough this assumption is fine. const int maxPlayerBase = 1000000; // Time Simulator signals a set of callbacks in a distinct order // each period of signals is called a "tick" - do not confuse with CPU ticks. var tickInfo = new TimeSimulatorTickInfo(24 * 60, 20); // This player factory generates the same set of players every time. // to proof certain assumptions, it will be necessary to create different set of players // TODO make seed configurable or make it random for batch runs DefaultPlayerFactory pf = new DefaultPlayerFactory { PlayerCount = maxPlayerBase }; // The player base simulator will use a sine function to simulate // day /night behavior of players (they are not always online). // More sophisticated models for better simulation results would be good, // but for first implementation of the simulation it is sufficient. IPlayerBaseSimulator playerBaseSim = new PlayerBaseSimulator(maxPlayerBase, pf, tickInfo); // The match maker picks the online players and queues them into matches. // This is the core simulation logic IMatchMaker matchMaker = new FirstInFirstOutMatchMaker(playerBaseSim, tickInfo); // The match simulation picks the matchups and after an average tick time it will // generate a match result based on a 50/50 chance, modified by the real MMR. MatchSimulator matchSimulator = new MatchSimulator(matchMaker, tickInfo); // The time simulator will trigger each other simulator by invoking the tick method // for each tick TimeSimulator ts = new TimeSimulator(tickInfo); ts.Register(playerBaseSim); ts.Register(matchMaker); ts.Register(matchSimulator); var stopwatch = new Stopwatch(); stopwatch.Start(); bool run = true; ts.Start(); do { if (stopwatch.Elapsed > TimeSpan.FromSeconds(3)) { WriteStats(playerBaseSim, ts, matchSimulator); stopwatch.Restart(); } if (Console.KeyAvailable) { ConsoleKeyInfo key = Console.ReadKey(true); switch (key.Key) { case ConsoleKey.Escape: run = false; break; default: WriteStats(playerBaseSim, ts, matchSimulator); break; } } // Do something more useful } while(run); ts.Stop(); Evaluator.Calc(playerBaseSim); }