public static void Main(string[] args) { if (!log4net.LogManager.GetRepository().Configured) { log4net.Config.BasicConfigurator.Configure(); } log4net.ILog logger = log4net.LogManager.GetLogger("Flatland.Program"); logger.Info("Starting up Flatland"); var settings = new FlatlandSettings() { IsDebugMode = false, ScreenWidth = DisplayDevice.Default.Width, ScreenHeight = DisplayDevice.Default.Height, Fullscreen = false, Tiles = 0, Players = 0, Port = 0, PlayerSort = PlayerSort.Random, CollisionBehavior = CollisionBehavior.Allow, GameType = FlatlandGameType.Normal }; 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) }, { "tiles=", "Number of tiles in a row or column (default: maximum)", v => settings.Tiles = Convert.ToInt32(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 }, { "player-sort=", "Initial arrangement of players (Random, SpreadOut, Clustered)", v => settings.PlayerSort = (PlayerSort)Enum.Parse(typeof(PlayerSort), v) }, { "collision-behavior=", "Behavior for when players collide (Block, Allow)", v => settings.CollisionBehavior = (CollisionBehavior)Enum.Parse(typeof(CollisionBehavior), v) }, { "team-info=", "Information about a team in the format [Index,Theme,MoveSeconds,Kind,Wrap] (Kind = Normal, Predator, Prey)", v => settings.Teams.AddRange(CLIObject.FromString<FlatlandTeamInfo>(v, "TeamIndex", "ThemeName", "MoveSeconds", "Kind", "WrappedMovement", "ScoringSystem")) }, { "fixed-tiles=", "List of fixed tiles in the format [X1,Y1][X2,Y2]...", v => settings.FixedTiles.UnionWith(CLIObject.FromString<FixedTile>(v, "X", "Y")) }, { "description=", "Text to display at the top of the screen during gameplay", v => settings.GameDescription = v }, { "game-type=", "Type of Flatland game to play (Normal, NQueens)", v => settings.GameType = (FlatlandGameType)Enum.Parse(typeof(FlatlandGameType), v) } }; options.Parse(args); if (showHelp) { options.WriteOptionDescriptions(Console.Out); return; } if (settings.Players < 1) { logger.Fatal("players option is required"); return; } if (settings.Teams.Count < 1) { logger.Fatal("at least team one is required"); return; } else { // Set team names based on index foreach (var team in settings.Teams) { team.TeamName = ((char)(((int)'A') + team.TeamIndex)).ToString(); team.Theme = Themes.GetTheme((ThemeColor)Enum.Parse(typeof(ThemeColor), team.ThemeName)); } } // Calculate number of pixels var requestedPixels = settings.Tiles * settings.Tiles; if (requestedPixels < settings.Players) { settings.Tiles = (int)Math.Ceiling(Math.Sqrt(settings.Players)); logger.WarnFormat("Setting number of tiles to {0}x{0} to accomodate players", settings.Tiles); } // Make sure there are enough tiles for all players if ((settings.CollisionBehavior == CollisionBehavior.Block) && (((settings.Tiles * settings.Tiles) - settings.FixedTiles.Count) < settings.Players)) { logger.Fatal("Not enough tiles for players!"); return; } if (settings.IsDebugMode) { logger.Info("Debug mode is enabled"); } using (var game = new FlatlandWindow(settings)) { // Start game logger.Debug("Running game loop"); game.Run(0, 0); } }
public FlatlandWindow(FlatlandSettings settings) : base(settings.ScreenWidth, settings.ScreenHeight, GraphicsMode.Default, "Flatland", settings.Fullscreen ? GameWindowFlags.Fullscreen : 0) { logger.Info("Initializing Flatland 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 textureBasePath = Path.Combine(basePath, Path.Combine("etc", "player_images")); var playerImageCount = Directory.GetFiles(textureBasePath, "*.png").Length; if (Settings.Players > playerImageCount) { logger.WarnFormat("Too few player images are present, only allowing {0} players", playerImageCount); Settings.Players = playerImageCount; } pixelCount = Settings.Tiles * Settings.Tiles; // Calculate pixel and board sizes CalculateSizesAndLoadFonts(); // Load textures logger.DebugFormat("Loading textures from {0}", textureBasePath); playerTextureIds = Textures.LoadPlayers(textureBasePath, Settings.Players).ToArray(); // Create players players.AddRange(Enumerable.Range(0, Settings.Players) .Select(i => new Player(i)) ); bool assignRandomTeams = true; if (Settings.GameType == FlatlandGameType.OnePrey) { bool preyAssigned = false; var preyTeam = Settings.Teams.FirstOrDefault(t => t.Kind == FlatlandTeamKind.Prey); var predatorTeam = Settings.Teams.FirstOrDefault(t => t.Kind == FlatlandTeamKind.Predator); if ((preyTeam == null) || (predatorTeam == null)) { logger.Error("Prey and predator teams are required for One Prey game. Assigning teams randomly..."); assignRandomTeams = true; } else { // Choose a random person to be the prey foreach (var player in players.OrderBy(p => rand.Next())) { if (!preyAssigned) { player.Team = preyTeam; player.SetBoxTheme(preyTeam.Theme); player.IsPredator = false; player.IsPrey = true; preyAssigned = true; } else { player.Team = predatorTeam; player.SetBoxTheme(predatorTeam.Theme); player.IsPredator = true; player.IsPrey = false; preyAssigned = true; } } // for each player assignRandomTeams = false; } } // if game type is One Prey if (assignRandomTeams) { // Assign teams in order (players order will be random, but first teams get priority) var teamPlayerQueue = new Queue<Player>(players.OrderBy(p => rand.Next())); var orderedTeams = Settings.Teams.OrderBy(t => t.TeamIndex).ToList(); int teamIndex = 0; while (teamPlayerQueue.Count > 0) { var team = orderedTeams[teamIndex]; var player = teamPlayerQueue.Dequeue(); player.Team = team; player.SetBoxTheme(team.Theme); player.IsPredator = (team.Kind == FlatlandTeamKind.Predator); player.IsPrey = (team.Kind == FlatlandTeamKind.Prey); teamIndex = (teamIndex + 1) % orderedTeams.Count; } } // Only show team names if there's more than one Settings.ShowTeamNames = (Settings.Teams.Count > 1); // Place players on the board SetupPlayerSort(); // Output settings and initial player positions if (dataWriter != null) { dataWriter.WriteStartDocument(); dataWriter.WriteHashSingle("Version", FlatlandSettings.FileVersion); dataWriter.WriteLine(); dataWriter.WriteStartList("Settings"); dataWriter.WriteHashSingle("Description", Settings.GameDescription); dataWriter.WriteHashSingle("Players", players.Count); dataWriter.WriteHashSingle("Size", string.Format("{0}x{0}", Settings.Tiles)); dataWriter.WriteHashSingle("Collision Behavior", Settings.CollisionBehavior); dataWriter.WriteHashSingle("Game Type", Settings.GameType); if (Settings.Teams.Count > 0) { dataWriter.WriteStartList("Teams"); dataWriter.WriteComment("team number, theme, move seconds, kind, wrap, scoring system"); foreach (var team in Settings.Teams) { dataWriter.WriteText (string.Format("{0}, {1}, {2}, {3}, {4}, {5}", team.TeamIndex, team.ThemeName, team.MoveSeconds, team.Kind, team.WrappedMovement, team.ScoringSystem)); } dataWriter.WriteEndList(); } dataWriter.WriteEndList(); dataWriter.WriteLine(); dataWriter.WriteStartList("Player Information"); dataWriter.WriteComment("player, x, y, team"); foreach (var player in players) { dataWriter.WriteText(string.Format("{0}, {1}, {2}, {3}", player.Id, player.TileLeft, player.TileTop, player.Team.TeamName)); } dataWriter.WriteEndList(); dataWriter.WriteLine(); dataWriter.WriteStartList("Moves"); dataWriter.WriteComment("time in milliseconds, Move, player, x, y"); dataWriter.WriteComment("time in milliseconds, Eat, predator, prey"); } // 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); } } inputTimer.Start(); }
public static void Main(string[] args) { if (!log4net.LogManager.GetRepository().Configured) { log4net.Config.BasicConfigurator.Configure(); } log4net.ILog logger = log4net.LogManager.GetLogger("Flatland.Program"); logger.Info("Starting up Flatland"); var settings = new FlatlandSettings() { IsDebugMode = false, ScreenWidth = DisplayDevice.Default.Width, ScreenHeight = DisplayDevice.Default.Height, Fullscreen = false, Tiles = 0, Players = 0, Port = 0, PlayerSort = PlayerSort.Random, CollisionBehavior = CollisionBehavior.Allow, GameType = FlatlandGameType.Normal }; 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) }, { "tiles=", "Number of tiles in a row or column (default: maximum)", v => settings.Tiles = Convert.ToInt32(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 }, { "player-sort=", "Initial arrangement of players (Random, SpreadOut, Clustered)", v => settings.PlayerSort = (PlayerSort)Enum.Parse(typeof(PlayerSort), v) }, { "collision-behavior=", "Behavior for when players collide (Block, Allow)", v => settings.CollisionBehavior = (CollisionBehavior)Enum.Parse(typeof(CollisionBehavior), v) }, { "team-info=", "Information about a team in the format [Index,Theme,MoveSeconds,Kind,Wrap] (Kind = Normal, Predator, Prey)", v => settings.Teams.AddRange(CLIObject.FromString <FlatlandTeamInfo>(v, "TeamIndex", "ThemeName", "MoveSeconds", "Kind", "WrappedMovement", "ScoringSystem")) }, { "fixed-tiles=", "List of fixed tiles in the format [X1,Y1][X2,Y2]...", v => settings.FixedTiles.UnionWith(CLIObject.FromString <FixedTile>(v, "X", "Y")) }, { "description=", "Text to display at the top of the screen during gameplay", v => settings.GameDescription = v }, { "game-type=", "Type of Flatland game to play (Normal, NQueens)", v => settings.GameType = (FlatlandGameType)Enum.Parse(typeof(FlatlandGameType), v) } }; options.Parse(args); if (showHelp) { options.WriteOptionDescriptions(Console.Out); return; } if (settings.Players < 1) { logger.Fatal("players option is required"); return; } if (settings.Teams.Count < 1) { logger.Fatal("at least team one is required"); return; } else { // Set team names based on index foreach (var team in settings.Teams) { team.TeamName = ((char)(((int)'A') + team.TeamIndex)).ToString(); team.Theme = Themes.GetTheme((ThemeColor)Enum.Parse(typeof(ThemeColor), team.ThemeName)); } } // Calculate number of pixels var requestedPixels = settings.Tiles * settings.Tiles; if (requestedPixels < settings.Players) { settings.Tiles = (int)Math.Ceiling(Math.Sqrt(settings.Players)); logger.WarnFormat("Setting number of tiles to {0}x{0} to accomodate players", settings.Tiles); } // Make sure there are enough tiles for all players if ((settings.CollisionBehavior == CollisionBehavior.Block) && (((settings.Tiles * settings.Tiles) - settings.FixedTiles.Count) < settings.Players)) { logger.Fatal("Not enough tiles for players!"); return; } if (settings.IsDebugMode) { logger.Info("Debug mode is enabled"); } using (var game = new FlatlandWindow(settings)) { // Start game logger.Debug("Running game loop"); game.Run(0, 0); } }