public ForagerWindow(ForagerSettings settings) : base(settings.ScreenWidth, settings.ScreenHeight, GraphicsMode.Default, "Forager", settings.Fullscreen ? GameWindowFlags.Fullscreen : 0) { logger.Info("Initializing Forager game window"); this.Settings = settings; Keyboard.KeyDown += Keyboard_KeyDown; // Open data file if (!string.IsNullOrEmpty(Settings.DataFilePath)) { logger.DebugFormat("Opening data file at {0}", Settings.DataFilePath); dataWriter = new YAMLOutputStream(Settings.DataFilePath); } // Validate number of players var playerTextureBasePath = Path.Combine(basePath, Path.Combine("etc", "player_images")); var playerImageCount = Directory.GetFiles(playerTextureBasePath, "*.png").Length; if (Settings.Players > playerImageCount) { logger.WarnFormat("Too few player images are present, only allowing {0} players", playerImageCount); Settings.Players = playerImageCount; } players = Enumerable.Range(0, Settings.Players).Select(i => new Player(i)).ToArray(); playerShadows = players.Select(p => new PlayerShadow(p.Id)).ToArray(); // Load player textures logger.DebugFormat("Loading player textures from {0}", playerTextureBasePath); playerTextureIds = Textures.LoadPlayers(playerTextureBasePath, Settings.Players).ToArray(); playerGrayTextureIds = Textures.LoadPlayers(playerTextureBasePath, Settings.Players, (image) => Textures.MakeGrayScale(image)).ToArray(); // Load food textures var foodTextureBasePath = Path.Combine(basePath, Path.Combine("etc", "food_images")); var foodImageCount = Directory.GetFiles(foodTextureBasePath, "*.png").Length; logger.DebugFormat("Loading food textures from {0}", foodTextureBasePath); foodTextureIds = Textures.Load(foodTextureBasePath, "food", foodImageCount, x => x).ToArray(); plots = Enumerable.Range(0, Settings.Plots).Select(i => RectangleF.Empty).ToArray(); plotNumberOffsets = Enumerable.Range(0, Settings.Plots).Select(i => PointF.Empty).ToArray(); emptyPlotFood = Enumerable.Range(0, Settings.Plots).Select(i => new EmptyPlotFood()).ToArray(); CalculateSizesAndLoadFonts(); NormalizeProbabilities(); AssignPlayerPositions(); // Output settings if (dataWriter != null) { dataWriter.WriteStartDocument(); dataWriter.WriteHashSingle("Version", ForagerSettings.FileVersion); dataWriter.WriteLine(); dataWriter.WriteStartList("Settings"); dataWriter.WriteHashSingle("Description", Settings.GameDescription); dataWriter.WriteHashSingle("Players", Settings.Players); dataWriter.WriteStartList("Player Plots"); dataWriter.WriteComment("player, plot"); foreach (var player in players) { dataWriter.WriteText(string.Format("{0}, {1}", player.Id, player.PlotNumber + 1)); } // Player plots dataWriter.WriteEndList(); dataWriter.WriteHashSingle("Game Duration", Settings.GameSeconds); dataWriter.WriteHashSingle("Travel Time", Settings.TravelTime); dataWriter.WriteHashSingle("Food Rate", Settings.FoodRate); dataWriter.WriteHashSingle("Plots", Settings.Plots); if (Settings.ProbabilityShiftTimes.Count > 0) { dataWriter.WriteStartList("Probability Shift Times"); dataWriter.WriteComment("set, seconds from last shift"); int setIndex = 1; foreach (var shiftTime in settings.ProbabilityShiftTimes) { dataWriter.WriteText(string.Format("{0}, {1}", setIndex, shiftTime)); setIndex++; } // Probability Shift Times dataWriter.WriteEndList(); } dataWriter.WriteStartList("Plot Probabilities"); dataWriter.WriteComment("set, plot #, probability"); int probabilitySet = 1; double probabilitySum = 0; foreach (var probabilities in Settings.PlotProbabilities) { for (int plotIndex = 0; plotIndex < probabilities.Count; plotIndex++) { var plotProbability = probabilities[plotIndex] - probabilitySum; probabilitySum += plotProbability; dataWriter.WriteText(string.Format("{0}, {1}, {2:N2}", probabilitySet, plotIndex + 1, plotProbability)); } probabilitySet++; probabilitySum = 0; } // Plot probabilities dataWriter.WriteEndList(); // Settings dataWriter.WriteEndList(); dataWriter.WriteLine(); dataWriter.WriteStartList("Actions"); dataWriter.WriteComment("time in milliseconds, action, player, plot number"); } inputTimer.Start(); // Connect to input server if (Settings.Port > 0) { try { inputClient.Connect(IPAddress.Loopback, Settings.Port); inputClient.Client.BeginReceive(inputBuffer, 0, 2, SocketFlags.None, inputClient_DataReceived, null); } catch (Exception ex) { logger.Error("Failed to connect to input server", ex); } } gameSecondsLeft = Settings.GameSeconds; probabilitySecondsLeft = Settings.ProbabilityShiftTimes.FirstOrDefault(); UpdateStatusText(); roundTimer = new System.Timers.Timer(1000); roundTimer.Elapsed += roundTimer_Elapsed; roundTimer.Start(); }
public static void Main(string[] args) { if (!log4net.LogManager.GetRepository().Configured) { log4net.Config.BasicConfigurator.Configure(); } log4net.ILog logger = log4net.LogManager.GetLogger("Forager.Program"); logger.Info("Starting up Forager"); var settings = new ForagerSettings() { IsDebugMode = false, ScreenWidth = DisplayDevice.Default.Width, ScreenHeight = DisplayDevice.Default.Height, Fullscreen = false, Players = 0, Port = 0, Plots = 0, TravelTime = 3, FoodRate = 3, GameSeconds = 120 }; logger.Debug("Parsing command-line options"); // Parse command-line options bool showHelp = false; var options = new OptionSet() { { "h|?|help", "Show this help message", v => showHelp = !string.IsNullOrEmpty(v) }, { "debug", "Enable debug mode (random commands can be issued with 'R')", v => settings.IsDebugMode = !string.IsNullOrEmpty(v) }, { "screen-width=", "Screen width in pixels (default: current)", v => settings.ScreenWidth = Convert.ToInt32(v) }, { "screen-height=", "Screen heigh in pixels (default: current)", v => settings.ScreenHeight = Convert.ToInt32(v) }, { "full-screen", "Enables full-screen mode", v => settings.Fullscreen = !string.IsNullOrEmpty(v) }, { "players=", "Number of players (required)", v => settings.Players = Convert.ToInt32(v) }, { "port=", "Network port of input server", v => settings.Port = Convert.ToInt32(v) }, { "data-file=", "Path to the output data file", v => settings.DataFilePath = v }, { "description=", "Text to display at the top of the screen during gameplay", v => settings.GameDescription = v }, { "plots=", "Number of plots for players to forage in [2-8] (default: 8)", v => settings.Plots = Convert.ToInt32(v) }, { "travel-time=", "Delay in seconds when traveling between plots (default: 3)", v => settings.TravelTime = Convert.ToDouble(v) }, { "food-rate=", "Number of food items given out per second (default: 3)", v => settings.FoodRate = Convert.ToInt32(v) }, { "plot-probabilities=", "Relative probabilities of plots (default: same)", v => settings.PlotProbabilities.AddRange(CLIObject.FromMultiArrayString <double>(v).Select(x => x.ToList())) }, { "game-duration=", "Number of seconds that the entire game lasts (default: 120)", v => settings.GameSeconds = Convert.ToInt32(v) }, { "probability-shift-times=", "Number of seconds before the next plot probability set is used (default: never)", v => settings.ProbabilityShiftTimes = CLIObject.FromArrayString <int>(v).ToList() } }; options.Parse(args); if (showHelp) { options.WriteOptionDescriptions(Console.Out); return; } if (settings.Players < 1) { logger.Fatal("players option is required"); return; } if (settings.Plots < 2) { settings.Plots = 8; } if (settings.PlotProbabilities.Count < 1) { logger.Debug("Assuming all plots have equal probability"); // Equal probabilities if none are given by user settings.PlotProbabilities.Add(Enumerable.Range(0, settings.Plots).Select(i => 1.0).ToList()); } else { foreach (var probabilities in settings.PlotProbabilities) { if (probabilities.Count >= settings.Plots) { continue; } var forgottenPlots = probabilities.Count - settings.Plots; logger.WarnFormat("Last {0} plot(s) are assumed to have zero probability", forgottenPlots); // Assume non-specified plots have zero probability probabilities.AddRange(Enumerable.Range(0, forgottenPlots).Select(i => 0.0).ToList()); } } if (settings.ProbabilityShiftTimes.Count < (settings.PlotProbabilities.Count - 1)) { logger.Warn("Some plot probabilities will not be used (see probability-shift-times)"); } if (settings.IsDebugMode) { logger.Info("Debug mode is enabled"); } using (var game = new ForagerWindow(settings)) { // Start game logger.Debug("Running game loop"); game.Run(0, 0); } }
public static void Main(string[] args) { if (!log4net.LogManager.GetRepository().Configured) { log4net.Config.BasicConfigurator.Configure(); } log4net.ILog logger = log4net.LogManager.GetLogger("Forager.Program"); logger.Info("Starting up Forager"); var settings = new ForagerSettings() { IsDebugMode = false, ScreenWidth = DisplayDevice.Default.Width, ScreenHeight = DisplayDevice.Default.Height, Fullscreen = false, Players = 0, Port = 0, Plots = 0, TravelTime = 3, FoodRate = 3, GameSeconds = 120 }; logger.Debug("Parsing command-line options"); // Parse command-line options bool showHelp = false; var options = new OptionSet() { { "h|?|help", "Show this help message", v => showHelp = !string.IsNullOrEmpty(v) }, { "debug", "Enable debug mode (random commands can be issued with 'R')", v => settings.IsDebugMode = !string.IsNullOrEmpty(v) }, { "screen-width=", "Screen width in pixels (default: current)", v => settings.ScreenWidth = Convert.ToInt32(v) }, { "screen-height=", "Screen heigh in pixels (default: current)", v => settings.ScreenHeight = Convert.ToInt32(v) }, { "full-screen", "Enables full-screen mode", v => settings.Fullscreen = !string.IsNullOrEmpty(v) }, { "players=", "Number of players (required)", v => settings.Players = Convert.ToInt32(v) }, { "port=", "Network port of input server", v => settings.Port = Convert.ToInt32(v) }, { "data-file=", "Path to the output data file", v => settings.DataFilePath = v }, { "description=", "Text to display at the top of the screen during gameplay", v => settings.GameDescription = v }, { "plots=", "Number of plots for players to forage in [2-8] (default: 8)", v => settings.Plots = Convert.ToInt32(v) }, { "travel-time=", "Delay in seconds when traveling between plots (default: 3)", v => settings.TravelTime = Convert.ToDouble(v) }, { "food-rate=", "Number of food items given out per second (default: 3)", v => settings.FoodRate = Convert.ToInt32(v) }, { "plot-probabilities=", "Relative probabilities of plots (default: same)", v => settings.PlotProbabilities.AddRange(CLIObject.FromMultiArrayString<double>(v).Select(x => x.ToList())) }, { "game-duration=", "Number of seconds that the entire game lasts (default: 120)", v => settings.GameSeconds = Convert.ToInt32(v) }, { "probability-shift-times=", "Number of seconds before the next plot probability set is used (default: never)", v => settings.ProbabilityShiftTimes = CLIObject.FromArrayString<int>(v).ToList() } }; options.Parse(args); if (showHelp) { options.WriteOptionDescriptions(Console.Out); return; } if (settings.Players < 1) { logger.Fatal("players option is required"); return; } if (settings.Plots < 2) { settings.Plots = 8; } if (settings.PlotProbabilities.Count < 1) { logger.Debug("Assuming all plots have equal probability"); // Equal probabilities if none are given by user settings.PlotProbabilities.Add(Enumerable.Range(0, settings.Plots).Select(i => 1.0).ToList()); } else { foreach (var probabilities in settings.PlotProbabilities) { if (probabilities.Count >= settings.Plots) { continue; } var forgottenPlots = probabilities.Count - settings.Plots; logger.WarnFormat("Last {0} plot(s) are assumed to have zero probability", forgottenPlots); // Assume non-specified plots have zero probability probabilities.AddRange(Enumerable.Range(0, forgottenPlots).Select(i => 0.0).ToList()); } } if (settings.ProbabilityShiftTimes.Count < (settings.PlotProbabilities.Count - 1)) { logger.Warn("Some plot probabilities will not be used (see probability-shift-times)"); } if (settings.IsDebugMode) { logger.Info("Debug mode is enabled"); } using (var game = new ForagerWindow(settings)) { // Start game logger.Debug("Running game loop"); game.Run(0, 0); } }