Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CodeReviews.Console.MathGame.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Spectre.Console" Version="0.54.0" />
</ItemGroup>

</Project>
67 changes: 67 additions & 0 deletions Controllers/PrintController.cs
Original file line number Diff line number Diff line change
@@ -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<string> 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();
}
}
9 changes: 9 additions & 0 deletions Enums.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace CodeReviews.Console.MathGame;

internal enum Operator
{
Add,
Subtract,
Multiply,
Divide,
}
145 changes: 145 additions & 0 deletions Models/Game.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
using CodeReviews.Console.MathGame.Controllers;
using Spectre.Console;

namespace CodeReviews.Console.MathGame.Models;

internal class Game
{
readonly List<string> history = [];

readonly Dictionary<Operator, string> 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<Operator>()
.Title("Please choose one:")
.AddChoices(Enum.GetValues<Operator>())
);

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,
};
}
}
4 changes: 4 additions & 0 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using CodeReviews.Console.MathGame.Models;

Game game = new();
game.Initialize();
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# MathGame

A tiny, basic math console game.