using System; using System.IO; using System.Text; namespace STVrogue.GameLogic { /// /// Representing the configuration of a level. Methods to save an instance of this class /// to a file, and to load from a file are also provided. /// [Serializable()] public class GameConfiguration { public int rndSeed = 311223 ; public int numberOfRooms; public int maxRoomCapacity; public DungeonShapeType dungeonShape; public int initialNumberOfMonsters; public int initialNumberOfHealingPots; public int initialNumberOfRagePots; public DifficultyMode difficultyMode; /// /// Just a basic constructor. /// public GameConfiguration() { } /// /// A convenience method to get the full path leading to the root of this project's /// Solution directory. Getting this path is relevant in the following ways. The /// Console-application STVRogue will need to read a configuration file, and later /// perhaps also saved-gameplay that you want to replay. These files are to be placed /// in the "saved" sub-directory of this Solution-root directory, so that your /// STVRogue would be able to read those files when the Solution is placed in a /// different directory. You can find this "saved" directory at the same level as /// your root sln-file. /// /// Since the location of "saved" is relative to your Solution-root, you then need to /// somehow obtain the path to this root, which is what this method should do for you. /// Note that this method depends on the behavior of your build-tool, namely where it /// places your executables. But the implementation below should work for VS and Rider. /// I have not checked VScode. /// /// public static string GetSolutionRootDir() { // Could not really come up with a generic way to do this; different build tools // might place the app in different locations :| // This assumes STVRogue will be run from ProjectName/bin/Debug/netcoreapp2.1/appname DirectoryInfo projectDir = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory); string solutionDir = projectDir.Parent.Parent.Parent.Parent.FullName; return solutionDir; } /// /// This will save the configuration to a file. The file will be place in the directory /// STVrogue/saved. /// public void SaveToFile(string filename) { string o = "" + rndSeed + ":" + numberOfRooms + ":" + maxRoomCapacity + ":" + dungeonShape + ":" + initialNumberOfMonsters + ":" + initialNumberOfHealingPots + ":" + initialNumberOfRagePots + ":" + difficultyMode; //Console.WriteLine(o); string fileFullPath = Path.Combine(GetSolutionRootDir(),"saved",filename) ; Console.WriteLine((">>> Saving conf. to: " + fileFullPath)); using (StreamWriter outputFile = new StreamWriter(fileFullPath)) { outputFile.WriteLine(o); } } /// /// Create an instance of GameConfiguration by reading it from a text-file. The file is /// assumed to be located in the STVRogue/saved directory. The format of the file is /// as follows: /// /// number-of-room : maxRoomCapacity : dungeonShape : initialNumberOfMonsters : initialNumberOfHealingPots : initialNumberOfRagePots : difficultyMode /// /// In a single line; the components are separated by ":". /// /// public GameConfiguration(String filename) { string fileFullPath = Path.Combine(GetSolutionRootDir(),"saved",filename) ; Console.WriteLine((">>> Reading a game-configuration from: " + fileFullPath)); StreamReader sr = new StreamReader(fileFullPath); string input = sr.ReadLine(); sr.Close(); string[] components = input.Split(":"); rndSeed = int.Parse(components[0]); numberOfRooms = int.Parse(components[1]); maxRoomCapacity = int.Parse(components[2]); switch(components[3]) { case "LINEARshape": dungeonShape = DungeonShapeType.LINEARshape; break; case "TREEshape": dungeonShape = DungeonShapeType.TREEshape; break; default: dungeonShape = DungeonShapeType.RANDOMshape; break; } initialNumberOfMonsters = int.Parse(components[4]); initialNumberOfHealingPots = int.Parse(components[5]); initialNumberOfRagePots = int.Parse(components[6]); switch(components[7]) { case "NEWBIEmode" : difficultyMode = DifficultyMode.NEWBIEmode; break; case "ELITEmode" : difficultyMode = DifficultyMode.ELITEmode; break; default: difficultyMode = DifficultyMode.NORMALmode; break; } } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.AppendLine($"Difficulty : {difficultyMode}"); sb.AppendLine($"#monsters : {initialNumberOfMonsters}"); sb.AppendLine($"#rooms : {numberOfRooms}"); sb.AppendLine($"#dungeon-shape : {dungeonShape}"); sb.AppendLine($"max-room-capacity: {maxRoomCapacity}"); sb.AppendLine($"#heal-pots : {initialNumberOfHealingPots}"); sb.AppendLine($"#rage-pots : {initialNumberOfRagePots}"); sb.AppendLine($"Seed : {rndSeed}"); return sb.ToString(); } } }