예제 #1
0
        public static int RunSimulation(string fileName, DateTime?fromDate, DateTime?toDate, int verbosity,
                                        bool graphic, Int32 delay, bool interactive, bool csvOutput)
        {
            Engine engine = new Engine();

            if (fileName.Length == 0)
            {
                throw new Exception("no file specified");
            }

            DateTime currentTime = engine.LoadYaml(fileName, true);

            Console.WriteLine("Loaded file in {0} ms", engine.LoadDelay.Milliseconds);
            engine.World.Time.Restart();

            DateTime reachDate = toDate ?? currentTime;

            if (fromDate != null)
            {
                if (fromDate < engine.World.Time.Start)
                {
                    throw new Exception(String.Format(
                                            "`from` date ({0:yyyy-MM-dd}) cannot be lower than the simulation start date ({1:yyyy-MM-dd})",
                                            fromDate, engine.World.Time.Start));
                }
                engine.World.Time.Current = (DateTime)fromDate;  // Yes, the current date, NOT the starting one
                verbosity = Math.Max(1, verbosity);
            }

            if (toDate != null)
            {
                if (toDate < engine.World.Time.Start)
                {
                    throw new Exception(String.Format(
                                            "`to` date ({0:yyyy-MM-dd}) cannot be lower than the simulation start date ({1:yyyy-MM-dd})",
                                            toDate, engine.World.Time.Start));
                }
            }

            if (fromDate != null && reachDate < fromDate)
            {
                throw new Exception(String.Format(
                                        "the target date ({0:yyyy-MM-dd}) cannot be lower than `from` date ({1:yyyy-MM-dd})", reachDate,
                                        fromDate));
            }

            if (verbosity <= 0) // No step details to show? Fast-forward directly to target!
            {
                engine.World.Time.Current = reachDate;
            }

            ChoCSVWriter csvWriter = null;

            if (csvOutput)
            {
                csvWriter = new ChoCSVWriter(fileName + ".csv");
                csvWriter.WithFirstLineHeader();
                string[] fields =
                    new string[2 + engine.World.Kpis.Count + (verbosity > 1
                        ? engine.World.Map.SizeX * engine.World.Map.SizeY * engine.World.Resources.Count
                        : 0)];
                int i = 0;
                fields[i++] = "#";
                fields[i++] = "Date";
                foreach (var kpi in engine.World.Kpis)
                {
                    fields[i++] = kpi.Name;
                }

                for (int y = 0; y < engine.World.Map.SizeY; y++)
                {
                    for (int x = 0; x < engine.World.Map.SizeX; x++)
                    {
                        foreach (var resource in engine.World.Resources.Values)
                        {
                            fields[i++] = "[" + x + ":" + y + "] " + resource.Name;
                        }
                    }
                }

                csvWriter.WriteHeader(fields);
            }

            IDictionary <string, int> widths = engine.World.ComputeWidths(); // Compute all the maximum widths

            (int, int)startPosition = Console.GetCursorPosition();

            //-- Main loop
            while (!engine.World.Time.Reached(reachDate) || interactive)
            {
                if (verbosity >= 1)
                {
                    PrintCurrent(engine, verbosity, graphic, startPosition, widths, csvWriter);
                }

                if (interactive)
                {
                    ConsoleKeyInfo cki = Console.ReadKey(true);
                    if ((cki.Key == ConsoleKey.LeftArrow) || (cki.Key == ConsoleKey.PageUp))
                    {
                        // Go Backward
                        engine.World.Time.StepBack();
                    }
                    else if ((cki.Key == ConsoleKey.UpArrow) || (cki.Key == ConsoleKey.Home))
                    {
                        // Go to Start
                        engine.World.Time.Restart();
                    }
                    else if ((cki.Key == ConsoleKey.DownArrow) || (cki.Key == ConsoleKey.End))
                    {
                        // Go to End
                        engine.World.Time.Current = engine.World.Time.End;
                    }
                    else if ((cki.Key == ConsoleKey.T))
                    {
                        // Go to target date
                        engine.World.Time.Current = reachDate;
                    }
                    else if ((cki.Key == ConsoleKey.Escape) || (cki.Key == ConsoleKey.Q))
                    {
                        //Exit
                        break;
                    }
                    else
                    {
                        engine.World.Time.Step();
                    }
                }
                else
                {
                    if (delay > 0)
                    {
                        Thread.Sleep(delay);
                    }
                    engine.World.Time.Step();
                }
            }

            PrintCurrent(engine, verbosity, graphic, startPosition, widths, csvWriter);

            if (csvWriter != null)
            {
                csvWriter.Close();
            }
            return(0);
        }