|
| 1 | +using System.Globalization; |
| 2 | +using mathgame.GameModes; |
| 3 | +using mathgame.Model; |
| 4 | + |
| 5 | +namespace mathgame.GameManager; |
| 6 | + |
| 7 | +/// <summary> |
| 8 | +/// Manages the main game flow, including menus, gameplay, and highscore persistence. |
| 9 | +/// </summary> |
| 10 | +public class GameManager |
| 11 | +{ |
| 12 | + /// <summary> |
| 13 | + /// List of all players who have played the game. |
| 14 | + /// </summary> |
| 15 | + private static List<Player> players = new List<Player>(); |
| 16 | + |
| 17 | + /// <summary> |
| 18 | + /// Indicates whether the game is currently running. |
| 19 | + /// </summary> |
| 20 | + private static bool GameIsRunning = true; |
| 21 | + |
| 22 | + /// <summary> |
| 23 | + /// Initializes a new instance of the GameManager class. |
| 24 | + /// Loads existing highscores, displays the main menu, and saves highscores on exit. |
| 25 | + /// </summary> |
| 26 | + public GameManager() |
| 27 | + { |
| 28 | + LoadGame(); |
| 29 | + MainMenu(); |
| 30 | + SaveHighscore(players); |
| 31 | + } |
| 32 | + |
| 33 | + /// <summary> |
| 34 | + /// Displays the main menu and handles user navigation between game options. |
| 35 | + /// Allows the user to play the game, view highscores, or quit. |
| 36 | + /// </summary> |
| 37 | + private static void MainMenu() |
| 38 | + { |
| 39 | + while (true) |
| 40 | + { |
| 41 | + Console.Clear(); |
| 42 | + |
| 43 | + Console.WriteLine("Welcome to the math game"); |
| 44 | + Console.WriteLine("Choose one of the options by numbers shown:"); |
| 45 | + Console.WriteLine("1. Play the game"); |
| 46 | + Console.WriteLine("2. Highscore"); |
| 47 | + Console.WriteLine("3. Quit the game"); |
| 48 | + //intercepts the entry of the key so it doesn't show on the screen |
| 49 | + ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true); |
| 50 | + char input = keyInfo.KeyChar; |
| 51 | + switch (input) |
| 52 | + { |
| 53 | + case '1': |
| 54 | + PlayGame(); |
| 55 | + break; |
| 56 | + case '2': |
| 57 | + ShowHighscore(players); |
| 58 | + break; |
| 59 | + case '3': |
| 60 | + SaveHighscore(players); |
| 61 | + ExitGame(GameIsRunning); |
| 62 | + break; |
| 63 | + } |
| 64 | + Console.ReadKey(); |
| 65 | + } |
| 66 | + } |
| 67 | + |
| 68 | + /// <summary> |
| 69 | + /// Prompts the user to select a math operation and starts the corresponding game mode. |
| 70 | + /// Creates a new Player instance, executes the selected game, and adds the result to the players list. |
| 71 | + /// </summary> |
| 72 | + private static void PlayGame() |
| 73 | + { |
| 74 | + Console.Clear(); |
| 75 | + Console.WriteLine("Choose an operation (press a number key):"); |
| 76 | + Console.WriteLine("1. Multiplication"); |
| 77 | + Console.WriteLine("2. Division"); |
| 78 | + Console.WriteLine("3. Addition"); |
| 79 | + Console.WriteLine("4. Subtraction"); |
| 80 | + ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true); |
| 81 | + char input = keyInfo.KeyChar; |
| 82 | + |
| 83 | + Console.Clear(); |
| 84 | + switch (input) |
| 85 | + { |
| 86 | + case '1': |
| 87 | + players.Add(new MultiplicationGame().Play(new Player())); |
| 88 | + GameEnd(players.Last()); |
| 89 | + break; |
| 90 | + case '2': |
| 91 | + players.Add(new DivisionGame().Play(new Player())); |
| 92 | + GameEnd(players.Last()); |
| 93 | + break; |
| 94 | + case '3': |
| 95 | + players.Add(new AdditionGame().Play(new Player())); |
| 96 | + GameEnd(players.Last()); |
| 97 | + break; |
| 98 | + case '4': |
| 99 | + players.Add(new SubtractionGame().Play(new Player())); |
| 100 | + GameEnd(players.Last()); |
| 101 | + break; |
| 102 | + default: |
| 103 | + break; |
| 104 | + } |
| 105 | + } |
| 106 | + /// <summary> |
| 107 | + /// Saves current highscore from the last loaded highscore text file with the new players |
| 108 | + /// Overwrites the previous content with this one as a csv |
| 109 | + /// </summary> |
| 110 | + private static void SaveHighscore(List<Player> players) |
| 111 | + { |
| 112 | + using StreamWriter writer = new StreamWriter("Highscore.txt", false); // false = overwrite |
| 113 | + foreach (var player in players) |
| 114 | + { |
| 115 | + // save them as name, points, date |
| 116 | + writer.WriteLine($"{player.GetName()}, {player.GetPoints()}, {player.GetDate()}, {player.GetMinutesTaken()}:{(player.GetSecondsTaken() > 0 ? player.GetSecondsTaken().ToString("D2") : "00")}"); |
| 117 | + } |
| 118 | + |
| 119 | + } |
| 120 | + /// <summary> |
| 121 | + /// Loads existing highscore data from a text file. |
| 122 | + /// Creates the highscore file if it doesn't exist. |
| 123 | + /// </summary> |
| 124 | + private static void LoadGame() |
| 125 | + { |
| 126 | + string currentDir = Directory.GetCurrentDirectory(); |
| 127 | + Console.WriteLine(currentDir); |
| 128 | + |
| 129 | + bool exists = File.Exists("Highscore.txt"); |
| 130 | + if (exists == false) |
| 131 | + { |
| 132 | + // could have used File.WriteAllText, but that's not clear cut as file.Create |
| 133 | + using(File.Create("Highscore.txt")){}; |
| 134 | + } |
| 135 | + else |
| 136 | + { |
| 137 | + List<string> highscore = File.ReadAllLines("Highscore.txt").ToList(); |
| 138 | + |
| 139 | + // the second line is the content of the table, separated by comma |
| 140 | + foreach (var line in highscore) |
| 141 | + { |
| 142 | + if (line.Contains(',')) |
| 143 | + { |
| 144 | + string[] playerstats = line.Split(','); |
| 145 | + if ( |
| 146 | + !DateTime.TryParseExact( |
| 147 | + playerstats[2].Trim(), |
| 148 | + "yyyy-MM-ddTHH:mm:ss", |
| 149 | + CultureInfo.InvariantCulture, |
| 150 | + DateTimeStyles.None, |
| 151 | + out DateTime parsedDate |
| 152 | + ) |
| 153 | + ) |
| 154 | + { |
| 155 | + throw new ArgumentException( |
| 156 | + "Invalid date format for Player in Method Loadgame" |
| 157 | + ); |
| 158 | + } |
| 159 | + players.Add(new Player(playerstats[0], playerstats[1], parsedDate)); |
| 160 | + } |
| 161 | + } |
| 162 | + Console.WriteLine($"The file was succesfully loaded: {players.Count} entries."); |
| 163 | + } |
| 164 | + |
| 165 | + } |
| 166 | + |
| 167 | +/// <summary> |
| 168 | +/// When game ends, asks the user to enter name. Is anonymous by default |
| 169 | +/// Inserts name, points, date and time it took to finish the game mode |
| 170 | +/// </summary> |
| 171 | + private static void GameEnd(Player player) |
| 172 | + { |
| 173 | + Console.WriteLine("What's your name? (Press Enter to stay anonymous)"); |
| 174 | + string name = Console.ReadLine() ?? "Anonymous"; |
| 175 | + player.SetName(String.IsNullOrWhiteSpace(name) ? "Anonymous" : name); |
| 176 | + |
| 177 | + while (true) |
| 178 | + { |
| 179 | + Console.WriteLine($"Is \"{player.GetName()}\" correct?"); |
| 180 | + Console.WriteLine("[Y]es [N]o"); |
| 181 | + ConsoleKeyInfo key = Console.ReadKey(); |
| 182 | + if (key.KeyChar == 'Y' || key.KeyChar == 'y') |
| 183 | + break; |
| 184 | + else if (key.KeyChar == 'N' || key.KeyChar == 'n') |
| 185 | + { |
| 186 | + Console.WriteLine( |
| 187 | + "\nPlease enter your name (or press Enter to stay anonymous):" |
| 188 | + ); |
| 189 | + name = Console.ReadLine() ?? "Anonymous"; |
| 190 | + player.SetName(String.IsNullOrWhiteSpace(name) ? "Anonymous" : name); |
| 191 | + } |
| 192 | + } |
| 193 | + Console.WriteLine("Game over! Thank you for playing."); |
| 194 | + // Optionally: Show highscore or update leaderboard here |
| 195 | + } |
| 196 | + |
| 197 | + /// <summary> |
| 198 | + /// shows highscore by using the currently loaded players List |
| 199 | + /// </summary> |
| 200 | + private static void ShowHighscore(List<Player> players) |
| 201 | + { |
| 202 | + Console.Clear(); |
| 203 | + Console.WriteLine("\t\t---HighScore---"); |
| 204 | + Console.WriteLine("Name:\tPoints:\tDate:\t\t\tTime Taken:"); |
| 205 | + Console.WriteLine("-----------------------------------------------------"); |
| 206 | + |
| 207 | + if (players.Count == 0) |
| 208 | + { |
| 209 | + Console.WriteLine("\tNo entries in the table"); |
| 210 | + } |
| 211 | + else |
| 212 | + { |
| 213 | + foreach (var player in players) |
| 214 | + { |
| 215 | + Console.WriteLine($"{player.GetName()}\t{player.GetPoints()}\t{player.GetDate()}\t{player.GetMinutesTaken()}:{player.GetSecondsTaken()}"); |
| 216 | + } |
| 217 | + } |
| 218 | + Console.WriteLine("Press any key to return..."); |
| 219 | + } |
| 220 | + ///<summary> |
| 221 | + /// Game stops, everyone goes home. |
| 222 | + /// </summary> |
| 223 | + private static bool ExitGame(bool GameRunning) |
| 224 | + { |
| 225 | + Console.Clear(); |
| 226 | + Console.WriteLine("Thanks for playing!"); |
| 227 | + Thread.Sleep(500); |
| 228 | + Environment.Exit(exitCode: 0); |
| 229 | + return !GameRunning; |
| 230 | + } |
| 231 | +} |
0 commit comments