From 0155e9a909cdc92ad356d4668bd99b1df0088ffa Mon Sep 17 00:00:00 2001 From: anon Date: Thu, 5 Feb 2026 17:51:46 -0600 Subject: [PATCH 1/6] initial commit --- CodeReviews.Console.MathGame.csproj | 14 +++ Controllers/PrintController.cs | 67 +++++++++++++ Enums.cs | 9 ++ Models/Game.cs | 144 ++++++++++++++++++++++++++++ Program.cs | 4 + README.md | 3 + 6 files changed, 241 insertions(+) create mode 100644 CodeReviews.Console.MathGame.csproj create mode 100644 Controllers/PrintController.cs create mode 100644 Enums.cs create mode 100644 Models/Game.cs create mode 100644 Program.cs create mode 100644 README.md diff --git a/CodeReviews.Console.MathGame.csproj b/CodeReviews.Console.MathGame.csproj new file mode 100644 index 00000000..aa8486be --- /dev/null +++ b/CodeReviews.Console.MathGame.csproj @@ -0,0 +1,14 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + diff --git a/Controllers/PrintController.cs b/Controllers/PrintController.cs new file mode 100644 index 00000000..34ab77eb --- /dev/null +++ b/Controllers/PrintController.cs @@ -0,0 +1,67 @@ +using Spectre.Console; + +namespace CodeReviews.Console.MathGame.Controllers; + +internal static class PrintController +{ + internal static void Welcome() + { + AnsiConsole.Clear(); + AnsiConsole.MarkupLine("[blue]***********************************************[/]"); + AnsiConsole.MarkupLine("[blue]*** Welcome to the Tiny Math Game ***[/]"); + AnsiConsole.MarkupLine("[blue]***********************************************[/]"); + AnsiConsole.WriteLine("What would you like to do?"); + AnsiConsole.MarkupLine("[green]y: play game[/]"); + AnsiConsole.MarkupLine("[red]n: exit game[/]"); + AnsiConsole.MarkupLine("[yellow]h: view history[/]"); + } + + internal static void PresentRules(int winningScore, int losingScore) + { + AnsiConsole.Clear(); + AnsiConsole.MarkupLine("[yellow]**************************************[/]"); + AnsiConsole.MarkupLine("[yellow]*** Tiny Math Game Rules ***[/]"); + AnsiConsole.MarkupLine("[yellow]**************************************[/]"); + AnsiConsole.WriteLine(); + AnsiConsole.MarkupLine(" - Answer [green]correctly[/] and earn 1 point."); + AnsiConsole.MarkupLine(" - Answer [red]incorrectly[/] and lose 1 point."); + AnsiConsole.MarkupLine($" - To win, reach {winningScore} points."); + AnsiConsole.MarkupLine($" - You will lose if you reach {losingScore} points."); + AnsiConsole.WriteLine(); + Pause(); + } + + internal static void Pause() + { + AnsiConsole.Markup("[blue]Press any key to continue.[/] "); + System.Console.ReadKey(); + } + + internal static void PrintHistory(List history) + { + if (history.Count < 1) + { + AnsiConsole.MarkupLine("You haven't played any games!"); + Pause(); + return; + } + + AnsiConsole.Clear(); + AnsiConsole.MarkupLine("[yellow]******************************[/]"); + AnsiConsole.MarkupLine("[yellow]*** Play History ***[/]"); + AnsiConsole.MarkupLine("[yellow]******************************[/]"); + + var table = new Table(); + + table.AddColumn("[blue]Game[/]"); + table.AddColumn("[blue]Result[/]"); + + for (int i = 0; i < history.Count; i += 1) + { + table.AddRow($"{i + 1}", $"{history[i]}"); + } + + AnsiConsole.Write(table); + Pause(); + } +} diff --git a/Enums.cs b/Enums.cs new file mode 100644 index 00000000..3fcfbeaa --- /dev/null +++ b/Enums.cs @@ -0,0 +1,9 @@ +namespace CodeReviews.Console.MathGame; + +internal enum Operator +{ + Add, + Subtract, + Multiply, + Divide, +} diff --git a/Models/Game.cs b/Models/Game.cs new file mode 100644 index 00000000..96701b96 --- /dev/null +++ b/Models/Game.cs @@ -0,0 +1,144 @@ +using CodeReviews.Console.MathGame.Controllers; +using Spectre.Console; + +namespace CodeReviews.Console.MathGame.Models; + +internal class Game +{ + readonly List history = []; + + readonly Dictionary operatorMap = new() + { + { Operator.Add, "+" }, + { Operator.Subtract, "-" }, + { Operator.Divide, "/" }, + { Operator.Multiply, "*" }, + }; + + internal void Initialize() + { + bool keepPlaying = true; + string playerAnswer = String.Empty; + + while (keepPlaying) + { + PrintController.Welcome(); + + string? playerInput = System.Console.ReadLine(); + + switch (playerInput!.ToLower()) + { + case "y": + Play(); + break; + case "n": + keepPlaying = false; + break; + case "h": + PrintController.PrintHistory(history); + break; + default: + AnsiConsole.WriteLine("Your input was not understood. Please try again."); + break; + } + } + + AnsiConsole.WriteLine("Thank you for playing. Goodbye!"); + } + + internal void Play(int winningScore = 5, int losingScore = -3) + { + int playerScore = 0; + + PrintController.PresentRules(winningScore, losingScore); + + while (true) + { + AnsiConsole.Clear(); + + var choice = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Please choose one:") + .AddChoices(Enum.GetValues()) + ); + + int operand1 = Random.Shared.Next(0, 100); + int operand2 = Random.Shared.Next(0, 100); + + if (choice == Operator.Divide) + { + while (operand1 <= operand2 || operand1 % operand2 != 0) + { + operand1 = Random.Shared.Next(0, 100); + operand2 = Random.Shared.Next(1, 100); + } + } + + string question = $"{operand1} {operatorMap[choice]} {operand2} = "; + + AnsiConsole.Write(question); + + string? playerAnswer = System.Console.ReadLine(); + + while (!int.TryParse(playerAnswer, out int _)) + { + AnsiConsole.WriteLine($"Your answer was not understood. Please try again."); + PrintController.Pause(); + AnsiConsole.Clear(); + AnsiConsole.Write(question); + playerAnswer = System.Console.ReadLine(); + } + + if (Convert.ToInt32(playerAnswer) == CalculateAnswer(choice, operand1, operand2)) + { + playerScore += 1; + AnsiConsole.MarkupLine($"[green]Correct![/]"); + } + else + { + playerScore -= 1; + AnsiConsole.MarkupLine($"[yellow]Incorrect...[/]"); + } + + AnsiConsole.WriteLine($"Your score: {playerScore}"); + + if (GameOver(playerScore, winningScore, losingScore)) + { + break; + } + } + } + + internal bool GameOver(int playerScore, int winningScore, int losingScore) + { + if (playerScore >= winningScore) + { + history.Add("Win"); + AnsiConsole.MarkupLine($"[green]Congratulations. You won![/]"); + return true; + } + + if (playerScore <= losingScore) + { + history.Add("Loss"); + AnsiConsole.MarkupLine($"[red]You lost... :([/]"); + return true; + } + + PrintController.Pause(); + + return false; + } + + internal static int CalculateAnswer(Operator op, int operand1, int operand2) + { + return op switch + { + Operator.Add => operand1 + operand2, + Operator.Subtract => operand1 - operand2, + Operator.Divide => operand1 / operand2, + Operator.Multiply => operand1 * operand2, + _ => 0, + }; + } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 00000000..1cf259f0 --- /dev/null +++ b/Program.cs @@ -0,0 +1,4 @@ +using CodeReviews.Console.MathGame.Models; + +Game game = new(); +game.Initialize(); diff --git a/README.md b/README.md new file mode 100644 index 00000000..971fb0d0 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# MathGame + +A tiny, basic math console game. From 534f453cac708173357fb578d061558074ddd556 Mon Sep 17 00:00:00 2001 From: anon Date: Thu, 5 Feb 2026 18:00:53 -0600 Subject: [PATCH 2/6] fixes missing pause after game over --- Models/Game.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Models/Game.cs b/Models/Game.cs index 96701b96..d1b3f496 100644 --- a/Models/Game.cs +++ b/Models/Game.cs @@ -111,23 +111,25 @@ internal void Play(int winningScore = 5, int losingScore = -3) internal bool GameOver(int playerScore, int winningScore, int losingScore) { + bool isGameOver = false; + if (playerScore >= winningScore) { + isGameOver = true; history.Add("Win"); AnsiConsole.MarkupLine($"[green]Congratulations. You won![/]"); - return true; } if (playerScore <= losingScore) { + isGameOver = true; history.Add("Loss"); AnsiConsole.MarkupLine($"[red]You lost... :([/]"); - return true; } PrintController.Pause(); - return false; + return isGameOver; } internal static int CalculateAnswer(Operator op, int operand1, int operand2) From 12358a5ce5e0adc0bf07bfc6726fb4f1c0654d67 Mon Sep 17 00:00:00 2001 From: anon Date: Thu, 5 Feb 2026 18:04:54 -0600 Subject: [PATCH 3/6] removes unused variable --- Models/Game.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Models/Game.cs b/Models/Game.cs index d1b3f496..5eb15e02 100644 --- a/Models/Game.cs +++ b/Models/Game.cs @@ -18,7 +18,6 @@ internal class Game internal void Initialize() { bool keepPlaying = true; - string playerAnswer = String.Empty; while (keepPlaying) { From b4136313351e03f7aa00f886ab4accdbacf10f3e Mon Sep 17 00:00:00 2001 From: jlong Date: Mon, 9 Feb 2026 19:59:09 -0600 Subject: [PATCH 4/6] adds random option --- Controllers/PrintController.cs | 7 +++-- Enums.cs | 3 +- Models/Game.cs | 31 +++++++++++++++---- Program.cs | 2 +- ...e.MathGame.csproj => mathGame.qua9k.csproj | 0 5 files changed, 32 insertions(+), 11 deletions(-) rename CodeReviews.Console.MathGame.csproj => mathGame.qua9k.csproj (100%) diff --git a/Controllers/PrintController.cs b/Controllers/PrintController.cs index 34ab77eb..df484a51 100644 --- a/Controllers/PrintController.cs +++ b/Controllers/PrintController.cs @@ -10,10 +10,11 @@ internal static void Welcome() AnsiConsole.MarkupLine("[blue]***********************************************[/]"); AnsiConsole.MarkupLine("[blue]*** Welcome to the Tiny Math Game ***[/]"); AnsiConsole.MarkupLine("[blue]***********************************************[/]"); - AnsiConsole.WriteLine("What would you like to do?"); - AnsiConsole.MarkupLine("[green]y: play game[/]"); - AnsiConsole.MarkupLine("[red]n: exit game[/]"); + AnsiConsole.WriteLine("\nWhat would you like to do?"); + AnsiConsole.MarkupLine("\n[green]p: play game[/]"); + AnsiConsole.MarkupLine("[red]x: exit game[/]"); AnsiConsole.MarkupLine("[yellow]h: view history[/]"); + AnsiConsole.Write("\nPlease make a choice: "); } internal static void PresentRules(int winningScore, int losingScore) diff --git a/Enums.cs b/Enums.cs index 3fcfbeaa..13cfb977 100644 --- a/Enums.cs +++ b/Enums.cs @@ -1,4 +1,4 @@ -namespace CodeReviews.Console.MathGame; +namespace mathGame.qua9k; internal enum Operator { @@ -6,4 +6,5 @@ internal enum Operator Subtract, Multiply, Divide, + Random, } diff --git a/Models/Game.cs b/Models/Game.cs index 5eb15e02..90a31b5f 100644 --- a/Models/Game.cs +++ b/Models/Game.cs @@ -1,7 +1,7 @@ using CodeReviews.Console.MathGame.Controllers; using Spectre.Console; -namespace CodeReviews.Console.MathGame.Models; +namespace mathGame.qua9k.Models; internal class Game { @@ -13,6 +13,7 @@ internal class Game { Operator.Subtract, "-" }, { Operator.Divide, "/" }, { Operator.Multiply, "*" }, + { Operator.Random, "?" }, }; internal void Initialize() @@ -23,14 +24,14 @@ internal void Initialize() { PrintController.Welcome(); - string? playerInput = System.Console.ReadLine(); + string? playerInput = Console.ReadLine(); switch (playerInput!.ToLower()) { - case "y": + case "p": Play(); break; - case "n": + case "x": keepPlaying = false; break; case "h": @@ -64,6 +65,11 @@ internal void Play(int winningScore = 5, int losingScore = -3) int operand1 = Random.Shared.Next(0, 100); int operand2 = Random.Shared.Next(0, 100); + if (choice == Operator.Random) + { + choice = GetRandomOperator(choice); + } + if (choice == Operator.Divide) { while (operand1 <= operand2 || operand1 % operand2 != 0) @@ -77,7 +83,7 @@ internal void Play(int winningScore = 5, int losingScore = -3) AnsiConsole.Write(question); - string? playerAnswer = System.Console.ReadLine(); + string? playerAnswer = Console.ReadLine(); while (!int.TryParse(playerAnswer, out int _)) { @@ -85,7 +91,7 @@ internal void Play(int winningScore = 5, int losingScore = -3) PrintController.Pause(); AnsiConsole.Clear(); AnsiConsole.Write(question); - playerAnswer = System.Console.ReadLine(); + playerAnswer = Console.ReadLine(); } if (Convert.ToInt32(playerAnswer) == CalculateAnswer(choice, operand1, operand2)) @@ -142,4 +148,17 @@ internal static int CalculateAnswer(Operator op, int operand1, int operand2) _ => 0, }; } + + internal static Operator GetRandomOperator(Operator choice) + { + Random random = new(); + + while (choice == Operator.Random) + { + int i = random.Next(0, Enum.GetNames().Length); + choice = (Operator)i; + } + + return choice; + } } diff --git a/Program.cs b/Program.cs index 1cf259f0..be440338 100644 --- a/Program.cs +++ b/Program.cs @@ -1,4 +1,4 @@ -using CodeReviews.Console.MathGame.Models; +using mathGame.qua9k.Models; Game game = new(); game.Initialize(); diff --git a/CodeReviews.Console.MathGame.csproj b/mathGame.qua9k.csproj similarity index 100% rename from CodeReviews.Console.MathGame.csproj rename to mathGame.qua9k.csproj From 15e3cabd4d3c093513b16ac7bb131b2935c1172c Mon Sep 17 00:00:00 2001 From: jlong Date: Mon, 9 Feb 2026 21:09:52 -0600 Subject: [PATCH 5/6] uses raw string literals in print controller --- Controllers/PrintController.cs | 67 ++++++++++++++++++++++------------ Models/Game.cs | 26 +++++++------ 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/Controllers/PrintController.cs b/Controllers/PrintController.cs index df484a51..1867490f 100644 --- a/Controllers/PrintController.cs +++ b/Controllers/PrintController.cs @@ -1,44 +1,56 @@ using Spectre.Console; -namespace CodeReviews.Console.MathGame.Controllers; +namespace mathGame.qua9k.Controllers; internal static class PrintController { internal static void Welcome() { AnsiConsole.Clear(); - AnsiConsole.MarkupLine("[blue]***********************************************[/]"); - AnsiConsole.MarkupLine("[blue]*** Welcome to the Tiny Math Game ***[/]"); - AnsiConsole.MarkupLine("[blue]***********************************************[/]"); - AnsiConsole.WriteLine("\nWhat would you like to do?"); - AnsiConsole.MarkupLine("\n[green]p: play game[/]"); - AnsiConsole.MarkupLine("[red]x: exit game[/]"); - AnsiConsole.MarkupLine("[yellow]h: view history[/]"); - AnsiConsole.Write("\nPlease make a choice: "); + + AnsiConsole.MarkupLine( + """ + [blue]***********************************************[/] + [blue]*** Welcome to the Tiny Math Game ***[/] + [blue]***********************************************[/] + + What would you like to do? + + [green]p: play game[/] + [red]x: exit game[/] + [yellow]h: view history[/] + + """ + ); + AnsiConsole.Write("Please make a choice: "); } internal static void PresentRules(int winningScore, int losingScore) { AnsiConsole.Clear(); - AnsiConsole.MarkupLine("[yellow]**************************************[/]"); - AnsiConsole.MarkupLine("[yellow]*** Tiny Math Game Rules ***[/]"); - AnsiConsole.MarkupLine("[yellow]**************************************[/]"); - AnsiConsole.WriteLine(); - AnsiConsole.MarkupLine(" - Answer [green]correctly[/] and earn 1 point."); - AnsiConsole.MarkupLine(" - Answer [red]incorrectly[/] and lose 1 point."); - AnsiConsole.MarkupLine($" - To win, reach {winningScore} points."); - AnsiConsole.MarkupLine($" - You will lose if you reach {losingScore} points."); - AnsiConsole.WriteLine(); + AnsiConsole.MarkupLine( + $""" + [yellow]********************************************[/] + [yellow]***** Tiny Math Game Rules *****[/] + [yellow]********************************************[/] + + - Answer [green]correctly[/] and earn 1 point. + - Answer [red]incorrectly[/] and lose 1 point. + - To win, reach {winningScore} points. + - You will lose if you reach {losingScore} points. + + """ + ); Pause(); } internal static void Pause() { AnsiConsole.Markup("[blue]Press any key to continue.[/] "); - System.Console.ReadKey(); + Console.ReadKey(); } - internal static void PrintHistory(List history) + internal static void PrintHistory(List<(string Result, string PlayTime)> history) { if (history.Count < 1) { @@ -48,21 +60,28 @@ internal static void PrintHistory(List history) } AnsiConsole.Clear(); - AnsiConsole.MarkupLine("[yellow]******************************[/]"); - AnsiConsole.MarkupLine("[yellow]*** Play History ***[/]"); - AnsiConsole.MarkupLine("[yellow]******************************[/]"); + AnsiConsole.MarkupLine( + """ + [yellow]*********************************************[/] + [yellow]********** Play History ***********[/] + [yellow]*********************************************[/] + + """ + ); var table = new Table(); table.AddColumn("[blue]Game[/]"); table.AddColumn("[blue]Result[/]"); + table.AddColumn("[blue]Play Time[/]"); for (int i = 0; i < history.Count; i += 1) { - table.AddRow($"{i + 1}", $"{history[i]}"); + table.AddRow($"{i + 1}", $"{history[i].Result}", $"{history[i].PlayTime}"); } AnsiConsole.Write(table); + AnsiConsole.Write(""); Pause(); } } diff --git a/Models/Game.cs b/Models/Game.cs index 90a31b5f..a70a68b4 100644 --- a/Models/Game.cs +++ b/Models/Game.cs @@ -1,11 +1,11 @@ -using CodeReviews.Console.MathGame.Controllers; +using mathGame.qua9k.Controllers; using Spectre.Console; namespace mathGame.qua9k.Models; internal class Game { - readonly List history = []; + readonly List<(string Result, string PlayTime)> history = []; readonly Dictionary operatorMap = new() { @@ -38,7 +38,6 @@ internal void Initialize() PrintController.PrintHistory(history); break; default: - AnsiConsole.WriteLine("Your input was not understood. Please try again."); break; } } @@ -48,6 +47,9 @@ internal void Initialize() internal void Play(int winningScore = 5, int losingScore = -3) { + System.Timers.Timer timer = new(1000); + timer.Start(); + int playerScore = 0; PrintController.PresentRules(winningScore, losingScore); @@ -114,27 +116,29 @@ internal void Play(int winningScore = 5, int losingScore = -3) } } + // [[todo]] :: get timer value internal bool GameOver(int playerScore, int winningScore, int losingScore) { - bool isGameOver = false; + bool playerWon = playerScore >= winningScore; + bool playerLost = playerScore <= losingScore; - if (playerScore >= winningScore) + if (playerWon) { - isGameOver = true; - history.Add("Win"); + (string Result, string PlayTime) t = ("Win", "0"); + history.Add(t); AnsiConsole.MarkupLine($"[green]Congratulations. You won![/]"); } - if (playerScore <= losingScore) + if (playerLost) { - isGameOver = true; - history.Add("Loss"); + (string Result, string PlayTime) t = ("Loss", "0"); + history.Add(t); AnsiConsole.MarkupLine($"[red]You lost... :([/]"); } PrintController.Pause(); - return isGameOver; + return playerWon || playerLost; } internal static int CalculateAnswer(Operator op, int operand1, int operand2) From d4d7ae301e55cdc2a8b989970d444c2ecf7ed02d Mon Sep 17 00:00:00 2001 From: jlong Date: Tue, 10 Feb 2026 15:57:24 -0600 Subject: [PATCH 6/6] timer is working --- Controllers/PrintController.cs | 2 +- Models/Game.cs | 58 ++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/Controllers/PrintController.cs b/Controllers/PrintController.cs index 1867490f..12cc2022 100644 --- a/Controllers/PrintController.cs +++ b/Controllers/PrintController.cs @@ -73,7 +73,7 @@ internal static void PrintHistory(List<(string Result, string PlayTime)> history table.AddColumn("[blue]Game[/]"); table.AddColumn("[blue]Result[/]"); - table.AddColumn("[blue]Play Time[/]"); + table.AddColumn("[blue]Play Time (Seconds)[/]"); for (int i = 0; i < history.Count; i += 1) { diff --git a/Models/Game.cs b/Models/Game.cs index a70a68b4..c4924c5c 100644 --- a/Models/Game.cs +++ b/Models/Game.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using mathGame.qua9k.Controllers; using Spectre.Console; @@ -47,9 +48,7 @@ internal void Initialize() internal void Play(int winningScore = 5, int losingScore = -3) { - System.Timers.Timer timer = new(1000); - timer.Start(); - + var stopwatch = Stopwatch.StartNew(); int playerScore = 0; PrintController.PresentRules(winningScore, losingScore); @@ -108,37 +107,42 @@ internal void Play(int winningScore = 5, int losingScore = -3) } AnsiConsole.WriteLine($"Your score: {playerScore}"); + PrintController.Pause(); + + bool playerWon = playerScore >= winningScore; + bool playerLost = playerScore <= losingScore; + bool isGameOver = playerWon || playerLost; - if (GameOver(playerScore, winningScore, losingScore)) + if (isGameOver) { - break; - } - } - } + stopwatch.Stop(); - // [[todo]] :: get timer value - internal bool GameOver(int playerScore, int winningScore, int losingScore) - { - bool playerWon = playerScore >= winningScore; - bool playerLost = playerScore <= losingScore; + (string Result, string PlayTime) t = ( + "", + Convert.ToString(stopwatch.ElapsedMilliseconds / 1000) + ); - if (playerWon) - { - (string Result, string PlayTime) t = ("Win", "0"); - history.Add(t); - AnsiConsole.MarkupLine($"[green]Congratulations. You won![/]"); - } + if (playerWon) + { + t.Result = "Won"; + AnsiConsole.Clear(); + AnsiConsole.MarkupLine($"[green]Congratulations. You won![/]"); + } - if (playerLost) - { - (string Result, string PlayTime) t = ("Loss", "0"); - history.Add(t); - AnsiConsole.MarkupLine($"[red]You lost... :([/]"); - } + if (playerLost) + { + t.Result = "Loss"; + AnsiConsole.Clear(); + AnsiConsole.MarkupLine($"[red]You lost... :([/]"); + } - PrintController.Pause(); + history.Add(t); - return playerWon || playerLost; + PrintController.Pause(); + + break; + } + } } internal static int CalculateAnswer(Operator op, int operand1, int operand2)