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..5eb15e02
--- /dev/null
+++ b/Models/Game.cs
@@ -0,0 +1,145 @@
+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;
+
+ 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)
+ {
+ bool isGameOver = false;
+
+ if (playerScore >= winningScore)
+ {
+ isGameOver = true;
+ history.Add("Win");
+ AnsiConsole.MarkupLine($"[green]Congratulations. You won![/]");
+ }
+
+ if (playerScore <= losingScore)
+ {
+ isGameOver = true;
+ history.Add("Loss");
+ AnsiConsole.MarkupLine($"[red]You lost... :([/]");
+ }
+
+ PrintController.Pause();
+
+ return isGameOver;
+ }
+
+ 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.