From d39974475798ff7598dbf74f98ea98d435fe2c30 Mon Sep 17 00:00:00 2001 From: Dknx8888 Date: Thu, 25 Jun 2026 17:33:24 -0400 Subject: [PATCH 1/9] Added the project into the review repo --- .idea/.gitignore | 15 +++++++++++++++ .idea/encodings.xml | 4 ++++ .../.idea.MathGame.Dknx8888/.idea/.gitignore | 15 +++++++++++++++ .../.idea.MathGame.Dknx8888/.idea/encodings.xml | 4 ++++ .../.idea/indexLayout.xml | 8 ++++++++ MathGame.Dknx8888/MathGame.Dknx8888.csproj | 10 ++++++++++ MathGame.Dknx8888/MathGame.Dknx8888.sln | 16 ++++++++++++++++ MathGame.Dknx8888/Program.cs | 3 +++ 8 files changed, 75 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/encodings.xml create mode 100644 MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/.gitignore create mode 100644 MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/encodings.xml create mode 100644 MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/indexLayout.xml create mode 100644 MathGame.Dknx8888/MathGame.Dknx8888.csproj create mode 100644 MathGame.Dknx8888/MathGame.Dknx8888.sln create mode 100644 MathGame.Dknx8888/Program.cs diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..0fbab21b --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,15 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/.idea.CodeReviews.Console.MathGame.iml +/projectSettingsUpdater.xml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 00000000..df87cf95 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/.gitignore b/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/.gitignore new file mode 100644 index 00000000..9a24c68e --- /dev/null +++ b/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/.gitignore @@ -0,0 +1,15 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/projectSettingsUpdater.xml +/contentModel.xml +/.idea.ConsoleApp1.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/encodings.xml b/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/encodings.xml new file mode 100644 index 00000000..df87cf95 --- /dev/null +++ b/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/indexLayout.xml b/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/indexLayout.xml new file mode 100644 index 00000000..7b08163c --- /dev/null +++ b/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/MathGame.Dknx8888/MathGame.Dknx8888.csproj b/MathGame.Dknx8888/MathGame.Dknx8888.csproj new file mode 100644 index 00000000..6c1dc922 --- /dev/null +++ b/MathGame.Dknx8888/MathGame.Dknx8888.csproj @@ -0,0 +1,10 @@ + + + + Exe + net10.0 + enable + enable + + + diff --git a/MathGame.Dknx8888/MathGame.Dknx8888.sln b/MathGame.Dknx8888/MathGame.Dknx8888.sln new file mode 100644 index 00000000..6aa3dedd --- /dev/null +++ b/MathGame.Dknx8888/MathGame.Dknx8888.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1.csproj", "{A06D9D56-E8B5-402E-BEDC-BE092E066CCE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A06D9D56-E8B5-402E-BEDC-BE092E066CCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A06D9D56-E8B5-402E-BEDC-BE092E066CCE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A06D9D56-E8B5-402E-BEDC-BE092E066CCE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A06D9D56-E8B5-402E-BEDC-BE092E066CCE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/MathGame.Dknx8888/Program.cs b/MathGame.Dknx8888/Program.cs new file mode 100644 index 00000000..e5dff12b --- /dev/null +++ b/MathGame.Dknx8888/Program.cs @@ -0,0 +1,3 @@ +// See https://aka.ms/new-console-template for more information + +Console.WriteLine("Hello, World!"); \ No newline at end of file From 5f0b9f6342c32bc73fdb6c9981a81c603645d699 Mon Sep 17 00:00:00 2001 From: Dknx8888 Date: Thu, 25 Jun 2026 17:34:51 -0400 Subject: [PATCH 2/9] Added project settings also --- .idea/indexLayout.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100644 .idea/indexLayout.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/indexLayout.xml b/.idea/indexLayout.xml new file mode 100644 index 00000000..7b08163c --- /dev/null +++ b/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 311951b10d73a42d033184a81ae65af5dd6563c2 Mon Sep 17 00:00:00 2001 From: Dknx8888 Date: Thu, 2 Jul 2026 17:48:19 -0400 Subject: [PATCH 3/9] Added menu display options for game modes and difficulties --- .../.idea.MathGame.Dknx8888/.idea/vcs.xml | 6 ++ MathGame.Dknx8888/GameMode.cs | 10 ++ MathGame.Dknx8888/GameSession.cs | 11 +++ MathGame.Dknx8888/MathGame.Dknx8888.sln | 2 +- MathGame.Dknx8888/Menu.cs | 97 +++++++++++++++++++ MathGame.Dknx8888/Program.cs | 5 +- 6 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/vcs.xml create mode 100644 MathGame.Dknx8888/GameMode.cs create mode 100644 MathGame.Dknx8888/GameSession.cs create mode 100644 MathGame.Dknx8888/Menu.cs diff --git a/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/vcs.xml b/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/vcs.xml new file mode 100644 index 00000000..6c0b8635 --- /dev/null +++ b/MathGame.Dknx8888/.idea/.idea.MathGame.Dknx8888/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/MathGame.Dknx8888/GameMode.cs b/MathGame.Dknx8888/GameMode.cs new file mode 100644 index 00000000..ddeeb598 --- /dev/null +++ b/MathGame.Dknx8888/GameMode.cs @@ -0,0 +1,10 @@ +namespace MathGame.Dknx8888; + +public enum GameMode +{ + Addition, + Subtraction, + Multiplication, + Division, + Random +} \ No newline at end of file diff --git a/MathGame.Dknx8888/GameSession.cs b/MathGame.Dknx8888/GameSession.cs new file mode 100644 index 00000000..518aedfc --- /dev/null +++ b/MathGame.Dknx8888/GameSession.cs @@ -0,0 +1,11 @@ +namespace MathGame.Dknx8888; + +public class GameSession(GameMode gameMode) +{ + private GameMode _gameMode = gameMode; + + public void Start() + { + + } +} \ No newline at end of file diff --git a/MathGame.Dknx8888/MathGame.Dknx8888.sln b/MathGame.Dknx8888/MathGame.Dknx8888.sln index 6aa3dedd..195c6325 100644 --- a/MathGame.Dknx8888/MathGame.Dknx8888.sln +++ b/MathGame.Dknx8888/MathGame.Dknx8888.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1.csproj", "{A06D9D56-E8B5-402E-BEDC-BE092E066CCE}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathGame.Dknx8888", "MathGame.Dknx8888.csproj", "{A06D9D56-E8B5-402E-BEDC-BE092E066CCE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/MathGame.Dknx8888/Menu.cs b/MathGame.Dknx8888/Menu.cs new file mode 100644 index 00000000..3f9c7a1a --- /dev/null +++ b/MathGame.Dknx8888/Menu.cs @@ -0,0 +1,97 @@ +namespace MathGame.Dknx8888; + +public class Menu +{ + public void ShowMenu() + { + var running = true; + + while (running) + { + Console.Clear(); + Console.WriteLine("Welcome to A Simple Math Game!"); + Console.WriteLine("\nCurrently selected difficulty: \n"); + Console.WriteLine("Press choose one of the options below (1-4):"); + Console.WriteLine("1. Start"); + Console.WriteLine("2. View Game History"); + Console.WriteLine("3. Choose Difficulty"); + Console.WriteLine("4. Quit"); + + var input = Console.ReadLine()?.Trim(); + + switch (input) + { + case "1": + ShowGameModes(); + break; + + case "2": + // ... + break; + + case "3": + DifficultyMenu(); + break; + + case "4": + Console.WriteLine("\nGoodbye!"); + running = false; + break; + } + } + } + + private void ShowGameModes() + { + while (true) + { + Console.Clear(); + Console.WriteLine("Choose one of the modes below (1-6):"); + Console.WriteLine("1. Addition"); + Console.WriteLine("2. Subtraction"); + Console.WriteLine("3. Multiplication"); + Console.WriteLine("4. Division"); + Console.WriteLine("5. Random"); + Console.WriteLine("6. Go Back"); + + var input = Console.ReadLine()?.Trim(); + + if (input == "6") + { + return; + } + + GameMode? gameMode = input switch + { + "1" => GameMode.Addition, + "2" => GameMode.Subtraction, + "3" => GameMode.Multiplication, + "4" => GameMode.Division, + "5" => GameMode.Random, + _ => null + }; + + if (gameMode is null) + { + continue; + } + + // Starts game here + var gameSession = new GameSession(gameMode.Value); + gameSession.Start(); + } + } + + private void DifficultyMenu() + { + while (true) + { + Console.Clear(); + Console.WriteLine("Currently Selected Difficulty: \n"); + Console.WriteLine("Please select one of the difficulties below (1-3): "); + Console.WriteLine("1. Easy (1 digit operations)"); + Console.WriteLine("2. Medium (1 digit number and 2 digit number operations)"); + Console.WriteLine("3: Hard (2 digit number operations)"); + } + } +} \ No newline at end of file diff --git a/MathGame.Dknx8888/Program.cs b/MathGame.Dknx8888/Program.cs index e5dff12b..4ffbcc5f 100644 --- a/MathGame.Dknx8888/Program.cs +++ b/MathGame.Dknx8888/Program.cs @@ -1,3 +1,4 @@ -// See https://aka.ms/new-console-template for more information +using MathGame.Dknx8888; -Console.WriteLine("Hello, World!"); \ No newline at end of file +var menu = new Menu(); +menu.ShowMenu(); \ No newline at end of file From 2ad341dfcd9f2bafafe101cbe507a987966a5576 Mon Sep 17 00:00:00 2001 From: Dknx8888 Date: Fri, 3 Jul 2026 01:04:28 -0400 Subject: [PATCH 4/9] The game session with scoring, different modes including the random mode, timer and difficulties are done. Only the history is left. --- MathGame.Dknx8888/Difficulty.cs | 8 +++ MathGame.Dknx8888/GameSession.cs | 99 +++++++++++++++++++++++++++++++- MathGame.Dknx8888/Menu.cs | 54 ++++++++++++----- 3 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 MathGame.Dknx8888/Difficulty.cs diff --git a/MathGame.Dknx8888/Difficulty.cs b/MathGame.Dknx8888/Difficulty.cs new file mode 100644 index 00000000..daa9e80c --- /dev/null +++ b/MathGame.Dknx8888/Difficulty.cs @@ -0,0 +1,8 @@ +namespace MathGame.Dknx8888; + +public enum Difficulty +{ + Easy, + Medium, + Hard +} \ No newline at end of file diff --git a/MathGame.Dknx8888/GameSession.cs b/MathGame.Dknx8888/GameSession.cs index 518aedfc..3d3d3d8e 100644 --- a/MathGame.Dknx8888/GameSession.cs +++ b/MathGame.Dknx8888/GameSession.cs @@ -1,11 +1,106 @@ +using System.Diagnostics; + namespace MathGame.Dknx8888; -public class GameSession(GameMode gameMode) +public class GameSession(GameMode gameMode, Difficulty difficulty) { - private GameMode _gameMode = gameMode; + private readonly Random _random = new(); public void Start() { + Console.Clear(); + Console.WriteLine("Please answer the following questions: "); + var count = 0; + var score = 0; + var questions = new HashSet<(int, int, GameMode)>(); + Stopwatch timer = Stopwatch.StartNew(); + while (count < 5) + { + int num1; + int num2; + GameMode selectedGameMode; + + // Handle duplicate questions + do + { + (num1, num2) = NumGen(); + + selectedGameMode = gameMode == GameMode.Random ? GetRandomGameMode() : gameMode; + + // Division handling + if (gameMode != GameMode.Division) continue; + while (num1 % num2 != 0) + { + (num1, num2) = NumGen(); + } + } while (!questions.Add((num1, num2, selectedGameMode))); // True if new q, False if already had + + var sign = selectedGameMode switch + { + GameMode.Addition => '+', + GameMode.Subtraction => '-', + GameMode.Multiplication => '*', + GameMode.Division => '/', + }; + + var correctResult = selectedGameMode switch + { + GameMode.Addition => num1 + num2, + GameMode.Subtraction => num1 - num2, + GameMode.Multiplication => num1 * num2, + GameMode.Division => num1 / num2, + }; + + Console.WriteLine($"{num1} {sign} {num2} = ?"); + + // Checking int would give the player a hint instead so nah + double playerInput; + while (!double.TryParse(Console.ReadLine()?.Trim(), out playerInput)) + { + Console.WriteLine("Please enter a valid number"); + } + + // ReSharper disable once CompareOfFloatsByEqualityOperator + if (playerInput == correctResult) + { + ++score; + Console.WriteLine("Congratulations! You are correct!"); + } + else + { + Console.WriteLine($"You are incorrect. The correct answer is {correctResult}"); + } + count++; + } + timer.Stop(); + var roundTime = timer.Elapsed.TotalSeconds; + Console.WriteLine($"Your final score is {score} out of 5!"); + Console.WriteLine($"You completed this game in {roundTime:F2} seconds."); + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(); + } + + private (int, int) NumGen() + { + return difficulty switch + { + Difficulty.Easy => (_random.Next(1, 10), _random.Next(1, 10)), + Difficulty.Medium => (_random.Next(10, 101), _random.Next(1, 10)), + Difficulty.Hard => (_random.Next(10, 101), _random.Next(10, 101)), + _ => throw new InvalidOperationException("Somehow an invalid difficulty is selected. Fix your bug.") + }; + } + + private GameMode GetRandomGameMode() + { + GameMode[] gameModes = + [ + GameMode.Addition, + GameMode.Subtraction, + GameMode.Multiplication, + GameMode.Division + ]; + return gameModes[_random.Next(gameModes.Length)]; } } \ No newline at end of file diff --git a/MathGame.Dknx8888/Menu.cs b/MathGame.Dknx8888/Menu.cs index 3f9c7a1a..4c6209cd 100644 --- a/MathGame.Dknx8888/Menu.cs +++ b/MathGame.Dknx8888/Menu.cs @@ -2,15 +2,24 @@ namespace MathGame.Dknx8888; public class Menu { + private Difficulty _difficulty = Difficulty.Easy; + + // NOTE: This is an expression-bodied property, using => not = + private string DifficultyDisplay => _difficulty switch + { + Difficulty.Easy => "Easy", + Difficulty.Medium => "Medium", + Difficulty.Hard => "Hard", + _ => throw new ArgumentOutOfRangeException() + }; + public void ShowMenu() { - var running = true; - - while (running) + while (true) { Console.Clear(); Console.WriteLine("Welcome to A Simple Math Game!"); - Console.WriteLine("\nCurrently selected difficulty: \n"); + Console.WriteLine($"\nCurrently selected difficulty: {DifficultyDisplay}\n"); Console.WriteLine("Press choose one of the options below (1-4):"); Console.WriteLine("1. Start"); Console.WriteLine("2. View Game History"); @@ -35,8 +44,7 @@ public void ShowMenu() case "4": Console.WriteLine("\nGoodbye!"); - running = false; - break; + return; } } } @@ -54,14 +62,15 @@ private void ShowGameModes() Console.WriteLine("5. Random"); Console.WriteLine("6. Go Back"); - var input = Console.ReadLine()?.Trim(); + var gameModeInput = Console.ReadLine()?.Trim(); - if (input == "6") + // Go back (exit the while loop) + if (gameModeInput == "6") { return; } - GameMode? gameMode = input switch + GameMode? gameMode = gameModeInput switch { "1" => GameMode.Addition, "2" => GameMode.Subtraction, @@ -70,14 +79,15 @@ private void ShowGameModes() "5" => GameMode.Random, _ => null }; - + + // Nothing ever happens. if (gameMode is null) { continue; } - // Starts game here - var gameSession = new GameSession(gameMode.Value); + // Starts game here (so .Value here is needed because gameMode is nullable) + var gameSession = new GameSession(gameMode.Value, _difficulty); gameSession.Start(); } } @@ -87,11 +97,27 @@ private void DifficultyMenu() while (true) { Console.Clear(); - Console.WriteLine("Currently Selected Difficulty: \n"); + Console.WriteLine($"Currently Selected Difficulty: {DifficultyDisplay}\n"); Console.WriteLine("Please select one of the difficulties below (1-3): "); - Console.WriteLine("1. Easy (1 digit operations)"); + Console.WriteLine("1. Easy (1 digit operations) - Default"); Console.WriteLine("2. Medium (1 digit number and 2 digit number operations)"); Console.WriteLine("3: Hard (2 digit number operations)"); + Console.WriteLine("4: Go Back"); + + var difficultyInput = Console.ReadLine()?.Trim(); + + if (difficultyInput == "4") + { + break; + } + + _difficulty = difficultyInput switch + { + "1" => Difficulty.Easy, + "2" => Difficulty.Medium, + "3" => Difficulty.Hard, + _ => _difficulty // Invalid keeps the selected one + }; } } } \ No newline at end of file From ee42c42433199f4f09adbff96c68aa97c6922949 Mon Sep 17 00:00:00 2001 From: Dknx8888 Date: Fri, 3 Jul 2026 01:33:52 -0400 Subject: [PATCH 5/9] Added avoiding 0 on the divisor --- MathGame.Dknx8888/GameSession.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MathGame.Dknx8888/GameSession.cs b/MathGame.Dknx8888/GameSession.cs index 3d3d3d8e..42ea6135 100644 --- a/MathGame.Dknx8888/GameSession.cs +++ b/MathGame.Dknx8888/GameSession.cs @@ -13,7 +13,7 @@ public void Start() var count = 0; var score = 0; var questions = new HashSet<(int, int, GameMode)>(); - Stopwatch timer = Stopwatch.StartNew(); + var timer = Stopwatch.StartNew(); while (count < 5) { int num1; @@ -29,7 +29,7 @@ public void Start() // Division handling if (gameMode != GameMode.Division) continue; - while (num1 % num2 != 0) + while (num1 % num2 != 0 && num2 != 0) { (num1, num2) = NumGen(); } @@ -85,8 +85,8 @@ public void Start() { return difficulty switch { - Difficulty.Easy => (_random.Next(1, 10), _random.Next(1, 10)), - Difficulty.Medium => (_random.Next(10, 101), _random.Next(1, 10)), + Difficulty.Easy => (_random.Next(0, 10), _random.Next(0, 10)), + Difficulty.Medium => (_random.Next(10, 101), _random.Next(0, 10)), Difficulty.Hard => (_random.Next(10, 101), _random.Next(10, 101)), _ => throw new InvalidOperationException("Somehow an invalid difficulty is selected. Fix your bug.") }; From 244586f3c52dbfaf917b353cfb38a16382952b7c Mon Sep 17 00:00:00 2001 From: Dknx8888 Date: Fri, 3 Jul 2026 17:48:55 -0400 Subject: [PATCH 6/9] Completing the display of gameHistory. JSON structure finished. --- MathGame.Dknx8888/GameHistory.cs | 48 ++++++++++++ MathGame.Dknx8888/GameHistoryJson.cs | 17 ++++ MathGame.Dknx8888/GameResultTemplate.cs | 22 ++++++ MathGame.Dknx8888/GameSession.cs | 62 +++++++++++++-- MathGame.Dknx8888/Menu.cs | 3 +- MathGame.Dknx8888/game-results.json | 100 ++++++++++++++++++++++++ 6 files changed, 243 insertions(+), 9 deletions(-) create mode 100644 MathGame.Dknx8888/GameHistory.cs create mode 100644 MathGame.Dknx8888/GameHistoryJson.cs create mode 100644 MathGame.Dknx8888/GameResultTemplate.cs create mode 100644 MathGame.Dknx8888/game-results.json diff --git a/MathGame.Dknx8888/GameHistory.cs b/MathGame.Dknx8888/GameHistory.cs new file mode 100644 index 00000000..7903339e --- /dev/null +++ b/MathGame.Dknx8888/GameHistory.cs @@ -0,0 +1,48 @@ +using System.Runtime.CompilerServices; +using System.Text.Json; + +namespace MathGame.Dknx8888; + +public class GameHistory +{ + private readonly JsonSerializerOptions _options = new() { WriteIndented = true }; + public void ShowHistory() + { + Console.Clear(); + + var filePath = GameHistoryJson.FilePath; + + if (!File.Exists(filePath)) + { + Console.WriteLine("No game history found."); + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(); + return; + } + + var json = File.ReadAllText(filePath); + var gameResults = JsonSerializer.Deserialize>(json, _options) ?? []; + + if (gameResults.Count == 0) + { + Console.WriteLine("No game history found."); + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(); + return; + } + + Console.WriteLine("Game History"); + Console.WriteLine("Please select a game to show more details: "); + Console.WriteLine("ID | "); + + gameResults.Reverse(); // SHow from latest + for (var i = 0; i < gameResults.Count; i++) + { + var selectedGameResult = gameResults[i]; + Console.WriteLine($"{i + 1}. "); + } + + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(); + } +} \ No newline at end of file diff --git a/MathGame.Dknx8888/GameHistoryJson.cs b/MathGame.Dknx8888/GameHistoryJson.cs new file mode 100644 index 00000000..5f933fef --- /dev/null +++ b/MathGame.Dknx8888/GameHistoryJson.cs @@ -0,0 +1,17 @@ +using System.Runtime.CompilerServices; + +namespace MathGame.Dknx8888; + +public class GameHistoryJson +{ + public static string FilePath => GetGameResultsFilePath(); + + // CallerFilePath gets the path of the source file that called this func + private static string GetGameResultsFilePath([CallerFilePath] string sourceFilePath = "") + { + var sourceDirectory = Path.GetDirectoryName(sourceFilePath) + ?? throw new InvalidOperationException("Unable to determine the source file directory."); + + return Path.Combine(sourceDirectory, "game-results.json"); + } +} \ No newline at end of file diff --git a/MathGame.Dknx8888/GameResultTemplate.cs b/MathGame.Dknx8888/GameResultTemplate.cs new file mode 100644 index 00000000..b2e128f1 --- /dev/null +++ b/MathGame.Dknx8888/GameResultTemplate.cs @@ -0,0 +1,22 @@ +namespace MathGame.Dknx8888; + +public static class GameResultTemplate +{ + public record QuestionResult ( + int Num1, + int Num2, + char Sign, + double PlayerAnswer, + int CorrectAnswer, + bool IsCorrect + ); + + public record GameResult ( + GameMode GameMode, + Difficulty Difficulty, + int Score, + double RoundTime, + List Questions, + DateTime StartTime + ); +} \ No newline at end of file diff --git a/MathGame.Dknx8888/GameSession.cs b/MathGame.Dknx8888/GameSession.cs index 42ea6135..0b23ebca 100644 --- a/MathGame.Dknx8888/GameSession.cs +++ b/MathGame.Dknx8888/GameSession.cs @@ -1,19 +1,27 @@ using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Text.Json; +using static MathGame.Dknx8888.GameResultTemplate; namespace MathGame.Dknx8888; public class GameSession(GameMode gameMode, Difficulty difficulty) { private readonly Random _random = new(); - + private readonly JsonSerializerOptions _options = new JsonSerializerOptions { WriteIndented = true }; + public void Start() { - Console.Clear(); - Console.WriteLine("Please answer the following questions: "); var count = 0; var score = 0; - var questions = new HashSet<(int, int, GameMode)>(); + HashSet<(int, int, GameMode)> questions = []; var timer = Stopwatch.StartNew(); + List questionResults = []; + List gameResults; + var startingDateTime = DateTime.Now; + + Console.Clear(); + Console.WriteLine("Please answer the following questions: "); while (count < 5) { int num1; @@ -28,8 +36,8 @@ public void Start() selectedGameMode = gameMode == GameMode.Random ? GetRandomGameMode() : gameMode; // Division handling - if (gameMode != GameMode.Division) continue; - while (num1 % num2 != 0 && num2 != 0) + if (selectedGameMode != GameMode.Division) continue; + while (num2 == 0 || num1 % num2 != 0) { (num1, num2) = NumGen(); } @@ -61,7 +69,8 @@ public void Start() } // ReSharper disable once CompareOfFloatsByEqualityOperator - if (playerInput == correctResult) + var isCorrect = playerInput == correctResult; + if (isCorrect) { ++score; Console.WriteLine("Congratulations! You are correct!"); @@ -70,6 +79,16 @@ public void Start() { Console.WriteLine($"You are incorrect. The correct answer is {correctResult}"); } + + // Add record + questionResults.Add(new QuestionResult ( + num1, + num2, + sign, + playerInput, + correctResult, + isCorrect + )); count++; } @@ -77,6 +96,33 @@ public void Start() var roundTime = timer.Elapsed.TotalSeconds; Console.WriteLine($"Your final score is {score} out of 5!"); Console.WriteLine($"You completed this game in {roundTime:F2} seconds."); + + // Save + var gameResult = new GameResult( + gameMode, + difficulty, + score, + roundTime, + questionResults, + startingDateTime + ); + + var filePath = GameHistoryJson.FilePath; + if (File.Exists(filePath)) + { + var existingJson = File.ReadAllText(filePath); + gameResults = JsonSerializer.Deserialize>(existingJson, _options) ?? []; + } + else + { + gameResults = []; + } + + gameResults.Add(gameResult); + var json = JsonSerializer.Serialize(gameResults, _options); + File.WriteAllText(filePath, json); + Console.WriteLine($"Game history saved to: {filePath}"); + Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } @@ -103,4 +149,4 @@ private GameMode GetRandomGameMode() ]; return gameModes[_random.Next(gameModes.Length)]; } -} \ No newline at end of file +} diff --git a/MathGame.Dknx8888/Menu.cs b/MathGame.Dknx8888/Menu.cs index 4c6209cd..5adef639 100644 --- a/MathGame.Dknx8888/Menu.cs +++ b/MathGame.Dknx8888/Menu.cs @@ -35,7 +35,8 @@ public void ShowMenu() break; case "2": - // ... + var gameHistory = new GameHistory(); + gameHistory.ShowHistory(); break; case "3": diff --git a/MathGame.Dknx8888/game-results.json b/MathGame.Dknx8888/game-results.json new file mode 100644 index 00000000..2ca64c1a --- /dev/null +++ b/MathGame.Dknx8888/game-results.json @@ -0,0 +1,100 @@ +[ + { + "GameMode": 1, + "Difficulty": 0, + "Score": 4, + "RoundTime": 7.6807389, + "Questions": [ + { + "Num1": 1, + "Num2": 8, + "Sign": "-", + "PlayerAnswer": -7, + "CorrectAnswer": -7, + "IsCorrect": true + }, + { + "Num1": 9, + "Num2": 7, + "Sign": "-", + "PlayerAnswer": 2, + "CorrectAnswer": 2, + "IsCorrect": true + }, + { + "Num1": 4, + "Num2": 7, + "Sign": "-", + "PlayerAnswer": -3, + "CorrectAnswer": -3, + "IsCorrect": true + }, + { + "Num1": 0, + "Num2": 9, + "Sign": "-", + "PlayerAnswer": 1, + "CorrectAnswer": -9, + "IsCorrect": false + }, + { + "Num1": 9, + "Num2": 1, + "Sign": "-", + "PlayerAnswer": 8, + "CorrectAnswer": 8, + "IsCorrect": true + } + ], + "StartTime": "2026-07-03T16:51:52.6703836-04:00" + }, + { + "GameMode": 4, + "Difficulty": 0, + "Score": 5, + "RoundTime": 7.1863017, + "Questions": [ + { + "Num1": 3, + "Num2": 4, + "Sign": "*", + "PlayerAnswer": 12, + "CorrectAnswer": 12, + "IsCorrect": true + }, + { + "Num1": 6, + "Num2": 6, + "Sign": "/", + "PlayerAnswer": 1, + "CorrectAnswer": 1, + "IsCorrect": true + }, + { + "Num1": 8, + "Num2": 2, + "Sign": "/", + "PlayerAnswer": 4, + "CorrectAnswer": 4, + "IsCorrect": true + }, + { + "Num1": 3, + "Num2": 6, + "Sign": "*", + "PlayerAnswer": 18, + "CorrectAnswer": 18, + "IsCorrect": true + }, + { + "Num1": 7, + "Num2": 1, + "Sign": "/", + "PlayerAnswer": 7, + "CorrectAnswer": 7, + "IsCorrect": true + } + ], + "StartTime": "2026-07-03T17:02:30.5309754-04:00" + } +] \ No newline at end of file From e7ef199527208fb2c6b5ceb995b7b8e92520ea8d Mon Sep 17 00:00:00 2001 From: Dknx8888 Date: Fri, 3 Jul 2026 21:10:02 -0400 Subject: [PATCH 7/9] Added the functionality of showing history and some minor bug fixes. --- MathGame.Dknx8888/GameHistory.cs | 107 +++++++++++++++++++----- MathGame.Dknx8888/GameHistoryJson.cs | 3 +- MathGame.Dknx8888/GameResultTemplate.cs | 2 +- MathGame.Dknx8888/GameSession.cs | 12 ++- MathGame.Dknx8888/game-results.json | 53 +++++++++++- 5 files changed, 149 insertions(+), 28 deletions(-) diff --git a/MathGame.Dknx8888/GameHistory.cs b/MathGame.Dknx8888/GameHistory.cs index 7903339e..c6bb1561 100644 --- a/MathGame.Dknx8888/GameHistory.cs +++ b/MathGame.Dknx8888/GameHistory.cs @@ -1,5 +1,5 @@ -using System.Runtime.CompilerServices; using System.Text.Json; +using static MathGame.Dknx8888.GameResultTemplate; namespace MathGame.Dknx8888; @@ -8,40 +8,107 @@ public class GameHistory private readonly JsonSerializerOptions _options = new() { WriteIndented = true }; public void ShowHistory() { - Console.Clear(); + while (true) + { + Console.Clear(); var filePath = GameHistoryJson.FilePath; + if (!File.Exists(filePath)) + { + EmptyHistoryError(); + return; + } - if (!File.Exists(filePath)) + var json = File.ReadAllText(filePath); + if (string.IsNullOrWhiteSpace(json)) { - Console.WriteLine("No game history found."); - Console.WriteLine("Press any key to continue..."); - Console.ReadKey(); + EmptyHistoryError(); return; } - - var json = File.ReadAllText(filePath); - var gameResults = JsonSerializer.Deserialize>(json, _options) ?? []; - + + var gameResults = JsonSerializer.Deserialize>(json, _options) ?? []; if (gameResults.Count == 0) { - Console.WriteLine("No game history found."); - Console.WriteLine("Press any key to continue..."); - Console.ReadKey(); + EmptyHistoryError(); return; } - Console.WriteLine("Game History"); - Console.WriteLine("Please select a game to show more details: "); - Console.WriteLine("ID | "); + Console.WriteLine("Game History\n"); + Console.WriteLine("Please select a game via ID (1,2, etc.) to show more details"); + Console.WriteLine("Type q to go back\n"); + Console.WriteLine($"{"ID",-4} | {"Date and Time Started",-22} | {"Score",-7} | {"Mode",-15} | {"Duration (sec)",-10}"); + Console.WriteLine(new string('-', 76)); - gameResults.Reverse(); // SHow from latest + // Show from latest (bad idea?) + // gameResults.Reverse(); for (var i = 0; i < gameResults.Count; i++) { - var selectedGameResult = gameResults[i]; - Console.WriteLine($"{i + 1}. "); + var (gameMode, _, score, duration, _, startTime) = gameResults[i]; + + Console.WriteLine($"{i + 1,-4} | {startTime,-22} | {score,-7} | {gameMode,-15} | {duration,-10:F2}"); + } + + int selectedId; + bool isValidId; + + do + { + var input = Console.ReadLine()?.Trim(); + + // while loop in GameSession.cs does not work here because of this q + if (string.Equals(input, "q", StringComparison.OrdinalIgnoreCase)) + { + return; + } + + isValidId = int.TryParse(input, out selectedId) + && selectedId >= 1 + && selectedId <= gameResults.Count; + + if (!isValidId) + { + Console.WriteLine("Please enter a valid ID number, or q to go back"); + } + } while (!isValidId); + + var selectedGameResult = gameResults[selectedId - 1]; + ShowDetails(selectedGameResult); + } + } + + private static void EmptyHistoryError() + { + Console.WriteLine("No game history found."); + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(); + } + + private static void ShowDetails(GameResult selectedGameResult) + { + var (gameMode, difficulty, score, duration, questionResults, startTime) = selectedGameResult; + + Console.Clear(); + Console.WriteLine($"Start time: {startTime}"); + Console.WriteLine($"Game mode: {gameMode}"); + Console.WriteLine($"Difficulty: {difficulty}"); + Console.WriteLine($"Duration (sec): {duration:F2}"); + Console.WriteLine($"Score: {score}/5\n"); + + // Way better idea to include id in the records + var questionId = 1; + // Mind the one spaces + Console.WriteLine($"{"Q. Number", -10} {"Result", -8} {"Question", -12} {"Your Answer", 12} {"Correct Answer", 14}"); + Console.WriteLine(new string('-', 62)); + + foreach (var questionResult in questionResults) + { + var (num1, num2, sign, playerAnswer, correctAnswer, isCorrect) = questionResult; + var correctDisplay = isCorrect ? "Right" : "Wrong"; + var questionDisplay = $"{num1} {sign} {num2}"; + + Console.WriteLine($"{questionId, -10} {correctDisplay, -8} {questionDisplay, -12} {playerAnswer, 12} {correctAnswer, 14}"); + ++questionId; } - Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } diff --git a/MathGame.Dknx8888/GameHistoryJson.cs b/MathGame.Dknx8888/GameHistoryJson.cs index 5f933fef..1a25a48b 100644 --- a/MathGame.Dknx8888/GameHistoryJson.cs +++ b/MathGame.Dknx8888/GameHistoryJson.cs @@ -2,7 +2,8 @@ namespace MathGame.Dknx8888; -public class GameHistoryJson +// Repository pattern in the future? +public static class GameHistoryJson { public static string FilePath => GetGameResultsFilePath(); diff --git a/MathGame.Dknx8888/GameResultTemplate.cs b/MathGame.Dknx8888/GameResultTemplate.cs index b2e128f1..9e422fe1 100644 --- a/MathGame.Dknx8888/GameResultTemplate.cs +++ b/MathGame.Dknx8888/GameResultTemplate.cs @@ -15,7 +15,7 @@ public record GameResult ( GameMode GameMode, Difficulty Difficulty, int Score, - double RoundTime, + double Duration, List Questions, DateTime StartTime ); diff --git a/MathGame.Dknx8888/GameSession.cs b/MathGame.Dknx8888/GameSession.cs index 0b23ebca..3040b722 100644 --- a/MathGame.Dknx8888/GameSession.cs +++ b/MathGame.Dknx8888/GameSession.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.Runtime.CompilerServices; using System.Text.Json; using static MathGame.Dknx8888.GameResultTemplate; @@ -22,6 +21,8 @@ public void Start() Console.Clear(); Console.WriteLine("Please answer the following questions: "); + + //May implement quitting in the middle of the game later while (count < 5) { int num1; @@ -49,6 +50,7 @@ public void Start() GameMode.Subtraction => '-', GameMode.Multiplication => '*', GameMode.Division => '/', + _ => throw new InvalidOperationException("Invalid game mode selected.") }; var correctResult = selectedGameMode switch @@ -57,12 +59,14 @@ public void Start() GameMode.Subtraction => num1 - num2, GameMode.Multiplication => num1 * num2, GameMode.Division => num1 / num2, + _ => throw new InvalidOperationException("Invalid game mode selected.") }; Console.WriteLine($"{num1} {sign} {num2} = ?"); // Checking int would give the player a hint instead so nah double playerInput; + // Put ReadLine in while to avoid infinite loops while (!double.TryParse(Console.ReadLine()?.Trim(), out playerInput)) { Console.WriteLine("Please enter a valid number"); @@ -93,16 +97,16 @@ public void Start() count++; } timer.Stop(); - var roundTime = timer.Elapsed.TotalSeconds; + var duration = timer.Elapsed.TotalSeconds; Console.WriteLine($"Your final score is {score} out of 5!"); - Console.WriteLine($"You completed this game in {roundTime:F2} seconds."); + Console.WriteLine($"You completed this game in {duration:F2} seconds."); // Save var gameResult = new GameResult( gameMode, difficulty, score, - roundTime, + duration, questionResults, startingDateTime ); diff --git a/MathGame.Dknx8888/game-results.json b/MathGame.Dknx8888/game-results.json index 2ca64c1a..17093909 100644 --- a/MathGame.Dknx8888/game-results.json +++ b/MathGame.Dknx8888/game-results.json @@ -3,7 +3,7 @@ "GameMode": 1, "Difficulty": 0, "Score": 4, - "RoundTime": 7.6807389, + "Duration": 7.6807389, "Questions": [ { "Num1": 1, @@ -52,7 +52,7 @@ "GameMode": 4, "Difficulty": 0, "Score": 5, - "RoundTime": 7.1863017, + "Duration": 7.1863017, "Questions": [ { "Num1": 3, @@ -96,5 +96,54 @@ } ], "StartTime": "2026-07-03T17:02:30.5309754-04:00" + }, + { + "GameMode": 4, + "Difficulty": 2, + "Score": 3, + "Duration": 40.419132, + "Questions": [ + { + "Num1": 23, + "Num2": 67, + "Sign": "*", + "PlayerAnswer": 1541, + "CorrectAnswer": 1541, + "IsCorrect": true + }, + { + "Num1": 83, + "Num2": 34, + "Sign": "-", + "PlayerAnswer": 0, + "CorrectAnswer": 49, + "IsCorrect": false + }, + { + "Num1": 62, + "Num2": 78, + "Sign": "\u002B", + "PlayerAnswer": 140, + "CorrectAnswer": 140, + "IsCorrect": true + }, + { + "Num1": 68, + "Num2": 87, + "Sign": "-", + "PlayerAnswer": 3.14156, + "CorrectAnswer": -19, + "IsCorrect": false + }, + { + "Num1": 33, + "Num2": 42, + "Sign": "\u002B", + "PlayerAnswer": 75, + "CorrectAnswer": 75, + "IsCorrect": true + } + ], + "StartTime": "2026-07-03T20:47:14.3123284-04:00" } ] \ No newline at end of file From ed8bf2b46dde201d465d1114e970d276aa10d759 Mon Sep 17 00:00:00 2001 From: Dknx8888 Date: Fri, 3 Jul 2026 21:11:40 -0400 Subject: [PATCH 8/9] Fixed a tiny comment --- MathGame.Dknx8888/GameSession.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MathGame.Dknx8888/GameSession.cs b/MathGame.Dknx8888/GameSession.cs index 3040b722..fc4c402a 100644 --- a/MathGame.Dknx8888/GameSession.cs +++ b/MathGame.Dknx8888/GameSession.cs @@ -22,7 +22,7 @@ public void Start() Console.Clear(); Console.WriteLine("Please answer the following questions: "); - //May implement quitting in the middle of the game later + // May implement quitting in the middle of the game later while (count < 5) { int num1; From 2f55c60be0c56e61ff7fac5d542569383deff896 Mon Sep 17 00:00:00 2001 From: Nick Vu Date: Fri, 3 Jul 2026 21:16:05 -0400 Subject: [PATCH 9/9] Deleted the game results file --- MathGame.Dknx8888/game-results.json | 149 ---------------------------- 1 file changed, 149 deletions(-) delete mode 100644 MathGame.Dknx8888/game-results.json diff --git a/MathGame.Dknx8888/game-results.json b/MathGame.Dknx8888/game-results.json deleted file mode 100644 index 17093909..00000000 --- a/MathGame.Dknx8888/game-results.json +++ /dev/null @@ -1,149 +0,0 @@ -[ - { - "GameMode": 1, - "Difficulty": 0, - "Score": 4, - "Duration": 7.6807389, - "Questions": [ - { - "Num1": 1, - "Num2": 8, - "Sign": "-", - "PlayerAnswer": -7, - "CorrectAnswer": -7, - "IsCorrect": true - }, - { - "Num1": 9, - "Num2": 7, - "Sign": "-", - "PlayerAnswer": 2, - "CorrectAnswer": 2, - "IsCorrect": true - }, - { - "Num1": 4, - "Num2": 7, - "Sign": "-", - "PlayerAnswer": -3, - "CorrectAnswer": -3, - "IsCorrect": true - }, - { - "Num1": 0, - "Num2": 9, - "Sign": "-", - "PlayerAnswer": 1, - "CorrectAnswer": -9, - "IsCorrect": false - }, - { - "Num1": 9, - "Num2": 1, - "Sign": "-", - "PlayerAnswer": 8, - "CorrectAnswer": 8, - "IsCorrect": true - } - ], - "StartTime": "2026-07-03T16:51:52.6703836-04:00" - }, - { - "GameMode": 4, - "Difficulty": 0, - "Score": 5, - "Duration": 7.1863017, - "Questions": [ - { - "Num1": 3, - "Num2": 4, - "Sign": "*", - "PlayerAnswer": 12, - "CorrectAnswer": 12, - "IsCorrect": true - }, - { - "Num1": 6, - "Num2": 6, - "Sign": "/", - "PlayerAnswer": 1, - "CorrectAnswer": 1, - "IsCorrect": true - }, - { - "Num1": 8, - "Num2": 2, - "Sign": "/", - "PlayerAnswer": 4, - "CorrectAnswer": 4, - "IsCorrect": true - }, - { - "Num1": 3, - "Num2": 6, - "Sign": "*", - "PlayerAnswer": 18, - "CorrectAnswer": 18, - "IsCorrect": true - }, - { - "Num1": 7, - "Num2": 1, - "Sign": "/", - "PlayerAnswer": 7, - "CorrectAnswer": 7, - "IsCorrect": true - } - ], - "StartTime": "2026-07-03T17:02:30.5309754-04:00" - }, - { - "GameMode": 4, - "Difficulty": 2, - "Score": 3, - "Duration": 40.419132, - "Questions": [ - { - "Num1": 23, - "Num2": 67, - "Sign": "*", - "PlayerAnswer": 1541, - "CorrectAnswer": 1541, - "IsCorrect": true - }, - { - "Num1": 83, - "Num2": 34, - "Sign": "-", - "PlayerAnswer": 0, - "CorrectAnswer": 49, - "IsCorrect": false - }, - { - "Num1": 62, - "Num2": 78, - "Sign": "\u002B", - "PlayerAnswer": 140, - "CorrectAnswer": 140, - "IsCorrect": true - }, - { - "Num1": 68, - "Num2": 87, - "Sign": "-", - "PlayerAnswer": 3.14156, - "CorrectAnswer": -19, - "IsCorrect": false - }, - { - "Num1": 33, - "Num2": 42, - "Sign": "\u002B", - "PlayerAnswer": 75, - "CorrectAnswer": 75, - "IsCorrect": true - } - ], - "StartTime": "2026-07-03T20:47:14.3123284-04:00" - } -] \ No newline at end of file