示例#1
0
        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();
        }
示例#2
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);
            }
        }
示例#3
0
        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();
        }
示例#4
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);
            }
        }