From 1a220bec90f157c3290f9c906cf73dbddb733a54 Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Tue, 11 Aug 2026 14:17:36 -0400 Subject: [PATCH 01/10] Adding new project --- MathGame.ivangar/MathGame.ivangar.slnx | 3 +++ .../MathGame.ivangar/MathGame.ivangar.csproj | 10 ++++++++++ MathGame.ivangar/MathGame.ivangar/Program.cs | 1 + 3 files changed, 14 insertions(+) create mode 100644 MathGame.ivangar/MathGame.ivangar.slnx create mode 100644 MathGame.ivangar/MathGame.ivangar/MathGame.ivangar.csproj create mode 100644 MathGame.ivangar/MathGame.ivangar/Program.cs diff --git a/MathGame.ivangar/MathGame.ivangar.slnx b/MathGame.ivangar/MathGame.ivangar.slnx new file mode 100644 index 00000000..51a2997e --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar.slnx @@ -0,0 +1,3 @@ + + + diff --git a/MathGame.ivangar/MathGame.ivangar/MathGame.ivangar.csproj b/MathGame.ivangar/MathGame.ivangar/MathGame.ivangar.csproj new file mode 100644 index 00000000..ed9781c2 --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/MathGame.ivangar.csproj @@ -0,0 +1,10 @@ + + + + Exe + net10.0 + enable + enable + + + diff --git a/MathGame.ivangar/MathGame.ivangar/Program.cs b/MathGame.ivangar/MathGame.ivangar/Program.cs new file mode 100644 index 00000000..1bc52a60 --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/Program.cs @@ -0,0 +1 @@ +Console.WriteLine("Hello, World!"); From 7b3cd8e0b64f31cfa36d6cc8fa228bd0e17b5094 Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Wed, 12 Aug 2026 12:55:14 -0400 Subject: [PATCH 02/10] First draft of Math Game. Basic loop of multiple questions/validations. Add, Subtract ops. --- MathGame.ivangar/MathGame.ivangar/Game.cs | 144 +++++++++++++++++++ MathGame.ivangar/MathGame.ivangar/Program.cs | 8 +- 2 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 MathGame.ivangar/MathGame.ivangar/Game.cs diff --git a/MathGame.ivangar/MathGame.ivangar/Game.cs b/MathGame.ivangar/MathGame.ivangar/Game.cs new file mode 100644 index 00000000..d28c14a7 --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/Game.cs @@ -0,0 +1,144 @@ +namespace MathGame.ivangar +{ + public class Game + { + private readonly char[] _operators = ['+', '-', '*', '/']; + + private int _maxNumberOfQuestions = Random.Shared.Next(5, 11); + + private int _currentQuestionNumber = 1; + + private int _score = 0; + + public List GameHistory = []; + + public void Start() + { + bool continueGame = true; + + Console.WriteLine($"This game has {_maxNumberOfQuestions} questions.\n\tQuestion #{_currentQuestionNumber}\n"); + Console.WriteLine("Choose an operation and type any of the following options: +, -, *, /"); + ConsoleKeyInfo keyInfo = Console.ReadKey(); + char operation = keyInfo.KeyChar; + + while (_currentQuestionNumber < _maxNumberOfQuestions && continueGame) + { + while (!Array.Exists(_operators, o => o == operation)) + { + Console.WriteLine("\nInvalid operation selected! Please choose a valid operation from the following options: +, -, *, /."); + keyInfo = Console.ReadKey(); + operation = keyInfo.KeyChar; + } + + var (result, answer) = operation switch + { + '+' => Add(), + '-' => Subtract(), + _ => throw new InvalidOperationException("Invalid operation selected.") + }; + + ValidateAnswer(result, answer); + _currentQuestionNumber++; + + Console.WriteLine("Would you like to continue the game? (yes/no)"); + string? continueInput = Console.ReadLine(); + + continueGame = ValidateContinueGame(continueInput); + + if (continueGame) + { + Console.WriteLine($"\n\tQuestion #{_currentQuestionNumber}\n"); + Console.WriteLine("Choose another operation from any of the following options: +, -, *, /"); + keyInfo = Console.ReadKey(); + operation = keyInfo.KeyChar; + } + + } + + Console.WriteLine("\nGame Over!\n"); + PrintScore(); + PrintGameHistory(); + } + + public (int result, int answer) Add() + { + var a = Random.Shared.Next(0, 101); + var b = Random.Shared.Next(0, 101); + var result = a + b; + + Console.Write($"\nWhat is the result of:\n{a} + {b} = "); + string? answer = Console.ReadLine(); + int parsedAnswer; + + while (!int.TryParse(answer, out parsedAnswer)) + { + Console.WriteLine("Invalid input. Please enter a valid number: "); + answer = Console.ReadLine(); + } + + GameHistory.Add($"{a} + {b} = {parsedAnswer}"); + + return (result, parsedAnswer); + } + + public (int result, int answer) Subtract() + { + var a = Random.Shared.Next(0, 101); + var b = Random.Shared.Next(0, 101); + var result = a - b; + + Console.Write($"\nWhat is the result of:\n{a} - {b} = "); + string? answer = Console.ReadLine(); + int parsedAnswer; + + while (!int.TryParse(answer, out parsedAnswer)) + { + Console.WriteLine("Invalid input. Please enter a valid number: "); + answer = Console.ReadLine(); + } + + GameHistory.Add($"{a} - {b} = {parsedAnswer}"); + + return (result, parsedAnswer); + } + + public void ValidateAnswer(int result, int answer) + { + if (result == answer) + { + Console.WriteLine("Correct Answer!"); + _score++; + } + else + { + Console.WriteLine($"Incorrect Answer! The correct answer is: {result}"); + } + } + + public void PrintGameHistory() + { + Console.WriteLine("\nGame History:\n"); + foreach (var (index, operation) in GameHistory.Select((o, i) => (i, o))) + { + Console.WriteLine($"{index + 1}. {operation}"); + } + } + + public bool ValidateContinueGame(string? input) + { + while (string.IsNullOrWhiteSpace(input) || + (!string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase) && !string.Equals(input.Trim(), "no", StringComparison.OrdinalIgnoreCase))) + { + Console.WriteLine("Invalid input. Please enter 'yes' or 'no': "); + input = Console.ReadLine(); + } + return string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase); + } + + public void PrintScore() + { + decimal finalScore = Math.Round((decimal)_score * 100 / _maxNumberOfQuestions, MidpointRounding.AwayFromZero); + Console.WriteLine($"Your score is: {finalScore}%"); + } + } +} diff --git a/MathGame.ivangar/MathGame.ivangar/Program.cs b/MathGame.ivangar/MathGame.ivangar/Program.cs index 1bc52a60..0975ff9e 100644 --- a/MathGame.ivangar/MathGame.ivangar/Program.cs +++ b/MathGame.ivangar/MathGame.ivangar/Program.cs @@ -1 +1,7 @@ -Console.WriteLine("Hello, World!"); +using MathGame.ivangar; + +Console.WriteLine("Welcome to the Math Game!"); +Console.WriteLine("We are going to test your math skills!"); + +var game = new Game(); +game.Start(); From 500ed670425cbaf8e67578e4ed709c0559b8ffdc Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Thu, 13 Aug 2026 14:19:39 -0400 Subject: [PATCH 03/10] Added Menu, Menu Options & Menu Validator. Refactored Program to use menu to prompt multiple game options. --- .../MathGame.ivangar/Enums/MainMenuOptions.cs | 9 ++++ MathGame.ivangar/MathGame.ivangar/Game.cs | 36 ++++++-------- .../MathGame.ivangar/Helpers/MenuValidator.cs | 27 ++++++++++ MathGame.ivangar/MathGame.ivangar/Menu.cs | 49 +++++++++++++++++++ MathGame.ivangar/MathGame.ivangar/Program.cs | 41 ++++++++++++++-- 5 files changed, 137 insertions(+), 25 deletions(-) create mode 100644 MathGame.ivangar/MathGame.ivangar/Enums/MainMenuOptions.cs create mode 100644 MathGame.ivangar/MathGame.ivangar/Helpers/MenuValidator.cs create mode 100644 MathGame.ivangar/MathGame.ivangar/Menu.cs diff --git a/MathGame.ivangar/MathGame.ivangar/Enums/MainMenuOptions.cs b/MathGame.ivangar/MathGame.ivangar/Enums/MainMenuOptions.cs new file mode 100644 index 00000000..91e4df18 --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/Enums/MainMenuOptions.cs @@ -0,0 +1,9 @@ +namespace MathGame.ivangar.Enums +{ + public enum MainMenuItems + { + Play = 1, + Exit = 2, + History = 3 + } +} diff --git a/MathGame.ivangar/MathGame.ivangar/Game.cs b/MathGame.ivangar/MathGame.ivangar/Game.cs index d28c14a7..15101c6e 100644 --- a/MathGame.ivangar/MathGame.ivangar/Game.cs +++ b/MathGame.ivangar/MathGame.ivangar/Game.cs @@ -4,7 +4,8 @@ public class Game { private readonly char[] _operators = ['+', '-', '*', '/']; - private int _maxNumberOfQuestions = Random.Shared.Next(5, 11); + //private int _maxNumberOfQuestions = Random.Shared.Next(5, 11); + private int _maxNumberOfQuestions = 2; private int _currentQuestionNumber = 1; @@ -15,19 +16,13 @@ public class Game public void Start() { bool continueGame = true; + char operation = Menu.StartGamePrompt(_maxNumberOfQuestions, _currentQuestionNumber); - Console.WriteLine($"This game has {_maxNumberOfQuestions} questions.\n\tQuestion #{_currentQuestionNumber}\n"); - Console.WriteLine("Choose an operation and type any of the following options: +, -, *, /"); - ConsoleKeyInfo keyInfo = Console.ReadKey(); - char operation = keyInfo.KeyChar; - - while (_currentQuestionNumber < _maxNumberOfQuestions && continueGame) + while (continueGame) { while (!Array.Exists(_operators, o => o == operation)) { - Console.WriteLine("\nInvalid operation selected! Please choose a valid operation from the following options: +, -, *, /."); - keyInfo = Console.ReadKey(); - operation = keyInfo.KeyChar; + operation = Menu.PrintGameOptions(true); } var (result, answer) = operation switch @@ -40,19 +35,16 @@ public void Start() ValidateAnswer(result, answer); _currentQuestionNumber++; - Console.WriteLine("Would you like to continue the game? (yes/no)"); + if (_currentQuestionNumber > _maxNumberOfQuestions) + break; + + Console.WriteLine("\nWould you like to continue the game? (yes/no)"); string? continueInput = Console.ReadLine(); continueGame = ValidateContinueGame(continueInput); if (continueGame) - { - Console.WriteLine($"\n\tQuestion #{_currentQuestionNumber}\n"); - Console.WriteLine("Choose another operation from any of the following options: +, -, *, /"); - keyInfo = Console.ReadKey(); - operation = keyInfo.KeyChar; - } - + operation = Menu.PrintGameOptions(false, _currentQuestionNumber); } Console.WriteLine("\nGame Over!\n"); @@ -66,7 +58,7 @@ public void Start() var b = Random.Shared.Next(0, 101); var result = a + b; - Console.Write($"\nWhat is the result of:\n{a} + {b} = "); + Console.Write($"\n\nWhat is the result of:\n{a} + {b} = "); string? answer = Console.ReadLine(); int parsedAnswer; @@ -87,7 +79,7 @@ public void Start() var b = Random.Shared.Next(0, 101); var result = a - b; - Console.Write($"\nWhat is the result of:\n{a} - {b} = "); + Console.Write($"\n\nWhat is the result of:\n{a} - {b} = "); string? answer = Console.ReadLine(); int parsedAnswer; @@ -127,11 +119,13 @@ public void PrintGameHistory() public bool ValidateContinueGame(string? input) { while (string.IsNullOrWhiteSpace(input) || - (!string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase) && !string.Equals(input.Trim(), "no", StringComparison.OrdinalIgnoreCase))) + (!string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase) && + !string.Equals(input.Trim(), "no", StringComparison.OrdinalIgnoreCase))) { Console.WriteLine("Invalid input. Please enter 'yes' or 'no': "); input = Console.ReadLine(); } + return string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase); } diff --git a/MathGame.ivangar/MathGame.ivangar/Helpers/MenuValidator.cs b/MathGame.ivangar/MathGame.ivangar/Helpers/MenuValidator.cs new file mode 100644 index 00000000..d461a8e3 --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/Helpers/MenuValidator.cs @@ -0,0 +1,27 @@ + + +using MathGame.ivangar.Enums; + +namespace MathGame.ivangar.Helpers +{ + public static class MenuValidator + { + public static bool ValidateMainOptions(string? option) + { + if (string.IsNullOrEmpty(option) || string.IsNullOrWhiteSpace(option)) + { + Menu.PrintMenu(true); + return false; + } + + var validOption = Enum.TryParse(option.Trim(), ignoreCase: true, out _); + + if (!validOption) + { + Menu.PrintMenu(true); + } + + return validOption; + } + } +} diff --git a/MathGame.ivangar/MathGame.ivangar/Menu.cs b/MathGame.ivangar/MathGame.ivangar/Menu.cs new file mode 100644 index 00000000..9d649377 --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/Menu.cs @@ -0,0 +1,49 @@ +using MathGame.ivangar.Enums; + +namespace MathGame.ivangar +{ + public static class Menu + { + public static string? Intro() + { + Console.WriteLine("Welcome to the Math Game!"); + Console.WriteLine("We are going to test your math skills!"); + PrintMenu(); + return Console.ReadLine(); + } + + public static void PrintMenu(bool invalid = false) + { + if (invalid) + Console.WriteLine("Invalid input."); + + Console.WriteLine("Please choose any of the following options (you have to type the word, i.e. 'play'):\n"); + PrintMenuOptions(); + } + + public static void PrintMenuOptions() + { + foreach (MainMenuItems option in Enum.GetValues(typeof(MainMenuItems))) + Console.WriteLine($"\t{(int)option}. {option}"); + } + + public static char StartGamePrompt(int maxNumberOfQuestions, int currentQuestionNumber) + { + Console.WriteLine($"\nThis game has {maxNumberOfQuestions} questions.\n\n\tQuestion #{currentQuestionNumber}\n"); + return PrintGameOptions(); + } + + public static char PrintGameOptions(bool invalid = false, int currentQuestionNumber = -1) + { + if (invalid) + Console.Write("\nInvalid operation selected! "); + + if (currentQuestionNumber > 0) + Console.WriteLine($"\n\tQuestion #{currentQuestionNumber}\n"); + + Console.Write("Choose an operation and type any of the following options: +, -, *, / "); + ConsoleKeyInfo keyInfo = Console.ReadKey(); + return keyInfo.KeyChar; + } + } +} diff --git a/MathGame.ivangar/MathGame.ivangar/Program.cs b/MathGame.ivangar/MathGame.ivangar/Program.cs index 0975ff9e..b58d4dec 100644 --- a/MathGame.ivangar/MathGame.ivangar/Program.cs +++ b/MathGame.ivangar/MathGame.ivangar/Program.cs @@ -1,7 +1,40 @@ using MathGame.ivangar; +using MathGame.ivangar.Enums; +using MathGame.ivangar.Helpers; -Console.WriteLine("Welcome to the Math Game!"); -Console.WriteLine("We are going to test your math skills!"); +List games = []; +bool exitGame = false; +string? menuOption = Menu.Intro(); -var game = new Game(); -game.Start(); +while (true) +{ + while (!MenuValidator.ValidateMainOptions(menuOption)) + { + menuOption = Console.ReadLine(); + } + + Enum.TryParse(menuOption!.Trim(), ignoreCase: true, out MainMenuItems option); + + switch (option) + { + case MainMenuItems.Play: + var game = new Game(); + game.Start(); + break; + case MainMenuItems.History: + Console.WriteLine("PRINT HISTORY"); + break; + case MainMenuItems.Exit: + exitGame = true; + break; + } + + if (exitGame) + { + Console.WriteLine("Thank you for playing the Math Game. Have a nice day!"); + break; + } + + Menu.PrintMenu(); + menuOption = Console.ReadLine(); +} \ No newline at end of file From 248718732a372a85a9bc73d36fbb433c93627fa3 Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Tue, 18 Aug 2026 11:55:11 -0400 Subject: [PATCH 04/10] Remove user prompt for the operation option, save results in class props, Add missing operations (mult, division). --- MathGame.ivangar/MathGame.ivangar/Game.cs | 160 +++++++++++++++------- MathGame.ivangar/MathGame.ivangar/Menu.cs | 12 +- 2 files changed, 117 insertions(+), 55 deletions(-) diff --git a/MathGame.ivangar/MathGame.ivangar/Game.cs b/MathGame.ivangar/MathGame.ivangar/Game.cs index 15101c6e..f7455961 100644 --- a/MathGame.ivangar/MathGame.ivangar/Game.cs +++ b/MathGame.ivangar/MathGame.ivangar/Game.cs @@ -4,35 +4,39 @@ public class Game { private readonly char[] _operators = ['+', '-', '*', '/']; - //private int _maxNumberOfQuestions = Random.Shared.Next(5, 11); - private int _maxNumberOfQuestions = 2; + private int _maxNumberOfQuestions = Random.Shared.Next(5, 11); + //private int _maxNumberOfQuestions = 4; //USE this to test, remove before PR private int _currentQuestionNumber = 1; private int _score = 0; + private int _result; + + public int _userAnswer; + + private int _op1, _op2; + public List GameHistory = []; public void Start() { bool continueGame = true; - char operation = Menu.StartGamePrompt(_maxNumberOfQuestions, _currentQuestionNumber); + Menu.StartGamePrompt(_maxNumberOfQuestions); + var operation = GetNextOperation(); while (continueGame) { - while (!Array.Exists(_operators, o => o == operation)) + switch (operation) { - operation = Menu.PrintGameOptions(true); + case '+': Add(); break; + case '-': Subtract(); break; + case '*': Multiply(); break; + case '/': Divide(); break; } - var (result, answer) = operation switch - { - '+' => Add(), - '-' => Subtract(), - _ => throw new InvalidOperationException("Invalid operation selected.") - }; - - ValidateAnswer(result, answer); + var validAnswer = ValidateAnswer(); + UpdateGameHistory(operation, validAnswer); _currentQuestionNumber++; if (_currentQuestionNumber > _maxNumberOfQuestions) @@ -44,7 +48,7 @@ public void Start() continueGame = ValidateContinueGame(continueInput); if (continueGame) - operation = Menu.PrintGameOptions(false, _currentQuestionNumber); + operation = GetNextOperation(); } Console.WriteLine("\nGame Over!\n"); @@ -52,61 +56,69 @@ public void Start() PrintGameHistory(); } - public (int result, int answer) Add() + public void Add() { - var a = Random.Shared.Next(0, 101); - var b = Random.Shared.Next(0, 101); - var result = a + b; + _op1 = Random.Shared.Next(0, 101); + _op2 = Random.Shared.Next(0, 101); + _result = _op1 + _op2; - Console.Write($"\n\nWhat is the result of:\n{a} + {b} = "); + Console.Write($"\n\nWhat is the result of:\n{_op1} + {_op2} = "); string? answer = Console.ReadLine(); - int parsedAnswer; - while (!int.TryParse(answer, out parsedAnswer)) + while (!int.TryParse(answer, out _userAnswer)) { Console.WriteLine("Invalid input. Please enter a valid number: "); answer = Console.ReadLine(); } - - GameHistory.Add($"{a} + {b} = {parsedAnswer}"); - - return (result, parsedAnswer); } - public (int result, int answer) Subtract() + public void Subtract() { - var a = Random.Shared.Next(0, 101); - var b = Random.Shared.Next(0, 101); - var result = a - b; + _op1 = Random.Shared.Next(0, 101); + _op2 = Random.Shared.Next(0, 101); + _result = _op1 - _op2; - Console.Write($"\n\nWhat is the result of:\n{a} - {b} = "); + Console.Write($"\n\nWhat is the result of:\n{_op1} - {_op2} = "); string? answer = Console.ReadLine(); - int parsedAnswer; - while (!int.TryParse(answer, out parsedAnswer)) + while (!int.TryParse(answer, out _userAnswer)) { Console.WriteLine("Invalid input. Please enter a valid number: "); answer = Console.ReadLine(); } - - GameHistory.Add($"{a} - {b} = {parsedAnswer}"); - - return (result, parsedAnswer); } - public void ValidateAnswer(int result, int answer) + public void Multiply() { - if (result == answer) + _op1 = Random.Shared.Next(0, 101); + _op2 = Random.Shared.Next(0, 101); + _result = _op1 * _op2; + + Console.Write($"\n\nWhat is the result of:\n{_op1} * {_op2} = "); + string? answer = Console.ReadLine(); + + while (!int.TryParse(answer, out _userAnswer)) { - Console.WriteLine("Correct Answer!"); - _score++; + Console.WriteLine("Invalid input. Please enter a valid number: "); + answer = Console.ReadLine(); } - else + } + + public void Divide() + { + _op1 = Random.Shared.Next(1, 101); + _op2 = GetDivisor(); + _result = _op1 / _op2; + + Console.Write($"\n\nWhat is the result of:\n{_op1} / {_op2} = "); + string? answer = Console.ReadLine(); + + while (!int.TryParse(answer, out _userAnswer)) { - Console.WriteLine($"Incorrect Answer! The correct answer is: {result}"); + Console.WriteLine("Invalid input. Please enter a valid number: "); + answer = Console.ReadLine(); } } - public void PrintGameHistory() { Console.WriteLine("\nGame History:\n"); @@ -114,9 +126,39 @@ public void PrintGameHistory() { Console.WriteLine($"{index + 1}. {operation}"); } + + Console.WriteLine("\n\n"); } - public bool ValidateContinueGame(string? input) + public void PrintScore() + { + decimal finalScore = Math.Round((decimal)_score * 100 / _maxNumberOfQuestions, MidpointRounding.AwayFromZero); + Console.WriteLine($"Your score is: {finalScore}%"); + } + + private bool ValidateAnswer() + { + if (_result == _userAnswer) + { + Console.WriteLine("Correct Answer!"); + _score++; + return true; + } + + else + Console.WriteLine($"Incorrect Answer! The correct answer is: {_result}"); + + return false; + } + + private void UpdateGameHistory(char operation, bool validAnswer) + { + var scoreMark = validAnswer ? "Correct" : "Incorrect"; + var operationLog = $"{_op1} {operation} {_op2} = {_userAnswer,-30} {scoreMark,-20}"; + GameHistory.Add(operationLog); + } + + private bool ValidateContinueGame(string? input) { while (string.IsNullOrWhiteSpace(input) || (!string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase) && @@ -129,10 +171,34 @@ public bool ValidateContinueGame(string? input) return string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase); } - public void PrintScore() + private char GetNextOperation() { - decimal finalScore = Math.Round((decimal)_score * 100 / _maxNumberOfQuestions, MidpointRounding.AwayFromZero); - Console.WriteLine($"Your score is: {finalScore}%"); + Console.WriteLine($"\n\n\tQuestion #{_currentQuestionNumber}\n"); + return _operators[Random.Shared.Next(0, _operators.Length)]; + } + + /*Get a list of potential divisors (without remainders) and return randomly any divisor */ + private int GetDivisor() + { + if (IsPrimeNumber(_op1)) + return 1; + + var divisors = Enumerable + .Range(1, _op1) + .Where(x => _op1 % x == 0) + .ToList(); + + return divisors[Random.Shared.Next(0, divisors.Count)]; } + + private bool IsPrimeNumber(int number) + { + var primes = Enumerable.Range(2, 100) + .Where(n => !Enumerable.Range(2, (int)Math.Sqrt(n) - 1).Any(d => n % d == 0)) + .ToList(); + + return primes.Contains(number); + } + } } diff --git a/MathGame.ivangar/MathGame.ivangar/Menu.cs b/MathGame.ivangar/MathGame.ivangar/Menu.cs index 9d649377..35183264 100644 --- a/MathGame.ivangar/MathGame.ivangar/Menu.cs +++ b/MathGame.ivangar/MathGame.ivangar/Menu.cs @@ -27,23 +27,19 @@ public static void PrintMenuOptions() Console.WriteLine($"\t{(int)option}. {option}"); } - public static char StartGamePrompt(int maxNumberOfQuestions, int currentQuestionNumber) + public static void StartGamePrompt(int maxNumberOfQuestions) { - Console.WriteLine($"\nThis game has {maxNumberOfQuestions} questions.\n\n\tQuestion #{currentQuestionNumber}\n"); - return PrintGameOptions(); + Console.WriteLine($"\nThis game has {maxNumberOfQuestions} questions."); } - public static char PrintGameOptions(bool invalid = false, int currentQuestionNumber = -1) + /* TO DELETE */ + public static void PrintGameOptions(bool invalid = false, int currentQuestionNumber = -1) { if (invalid) Console.Write("\nInvalid operation selected! "); if (currentQuestionNumber > 0) Console.WriteLine($"\n\tQuestion #{currentQuestionNumber}\n"); - - Console.Write("Choose an operation and type any of the following options: +, -, *, / "); - ConsoleKeyInfo keyInfo = Console.ReadKey(); - return keyInfo.KeyChar; } } } From caa4762dc9568a337cf34cd32ce9a5003807ab3b Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Thu, 20 Aug 2026 14:33:30 -0400 Subject: [PATCH 05/10] Fix output for question read y/n chars. Create GameCenter class to control game sequence. Bring back Menu Prompt to choose an operation. --- MathGame.ivangar/MathGame.ivangar/Game.cs | 43 +++++----- .../MathGame.ivangar/GameCenter.cs | 80 +++++++++++++++++++ MathGame.ivangar/MathGame.ivangar/Menu.cs | 35 ++++++-- MathGame.ivangar/MathGame.ivangar/Program.cs | 40 +--------- 4 files changed, 131 insertions(+), 67 deletions(-) create mode 100644 MathGame.ivangar/MathGame.ivangar/GameCenter.cs diff --git a/MathGame.ivangar/MathGame.ivangar/Game.cs b/MathGame.ivangar/MathGame.ivangar/Game.cs index f7455961..abc725a7 100644 --- a/MathGame.ivangar/MathGame.ivangar/Game.cs +++ b/MathGame.ivangar/MathGame.ivangar/Game.cs @@ -19,14 +19,18 @@ public class Game public List GameHistory = []; - public void Start() + public void Play() { bool continueGame = true; - Menu.StartGamePrompt(_maxNumberOfQuestions); - var operation = GetNextOperation(); + char operation = Menu.StartGamePrompt(_maxNumberOfQuestions, _currentQuestionNumber); while (continueGame) { + while (!Array.Exists(_operators, o => o == operation)) + { + operation = Menu.PrintGameOptions(invalid: true); + } + switch (operation) { case '+': Add(); break; @@ -42,16 +46,15 @@ public void Start() if (_currentQuestionNumber > _maxNumberOfQuestions) break; - Console.WriteLine("\nWould you like to continue the game? (yes/no)"); - string? continueInput = Console.ReadLine(); - + char continueInput = Menu.ContinueGamePrompt(); continueGame = ValidateContinueGame(continueInput); if (continueGame) - operation = GetNextOperation(); + operation = Menu.PrintGameOptions(false, _currentQuestionNumber); + } - Console.WriteLine("\nGame Over!\n"); + Console.WriteLine("\n\nGame Over!\n"); PrintScore(); PrintGameHistory(); } @@ -136,6 +139,13 @@ public void PrintScore() Console.WriteLine($"Your score is: {finalScore}%"); } + public void FinishGame() + { + Console.WriteLine("\n\nGame Over!\n"); + PrintGameHistory(); + PrintScore(); + } + private bool ValidateAnswer() { if (_result == _userAnswer) @@ -158,23 +168,14 @@ private void UpdateGameHistory(char operation, bool validAnswer) GameHistory.Add(operationLog); } - private bool ValidateContinueGame(string? input) + private static bool ValidateContinueGame(char input) { - while (string.IsNullOrWhiteSpace(input) || - (!string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase) && - !string.Equals(input.Trim(), "no", StringComparison.OrdinalIgnoreCase))) + while (input != 'y' && input != 'n') { - Console.WriteLine("Invalid input. Please enter 'yes' or 'no': "); - input = Console.ReadLine(); + input = Menu.ContinueGamePrompt(invalid: true); } - return string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase); - } - - private char GetNextOperation() - { - Console.WriteLine($"\n\n\tQuestion #{_currentQuestionNumber}\n"); - return _operators[Random.Shared.Next(0, _operators.Length)]; + return input == 'y'; } /*Get a list of potential divisors (without remainders) and return randomly any divisor */ diff --git a/MathGame.ivangar/MathGame.ivangar/GameCenter.cs b/MathGame.ivangar/MathGame.ivangar/GameCenter.cs new file mode 100644 index 00000000..413974bd --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/GameCenter.cs @@ -0,0 +1,80 @@ +using MathGame.ivangar.Enums; +using MathGame.ivangar.Helpers; + +namespace MathGame.ivangar +{ + public class GameCenter + { + private readonly List _games = []; + private bool _exitGame = false; + + public void Start() + { + string? menuOption = Menu.GameIntro(); + + while (true) + { + while (!MenuValidator.ValidateMainOptions(menuOption)) + { + menuOption = Console.ReadLine(); + } + + Enum.TryParse(menuOption!.Trim(), ignoreCase: true, out MainMenuItems option); + + switch (option) + { + case MainMenuItems.Play: + PlayGame(); + break; + case MainMenuItems.History: + MathGameHistory(); + break; + case MainMenuItems.Exit: + _exitGame = true; + Exit(); + break; + } + + if (_exitGame) + break; + + Menu.PrintMenu(); + menuOption = Console.ReadLine(); + } + } + + public void PlayGame() + { + var mathGame = new Game(); + mathGame.Play(); + _games.Add(mathGame); + } + + public void MathGameHistory() + { + if (_games.Count == 0) + Console.WriteLine("\nYou don't have any registered game played.\n"); + + foreach (var (index, game) in _games.Select((g, i) => (i, g))) + { + Console.WriteLine($"\n\t\tGame #{index + 1}\n"); + game.PrintGameHistory(); + game.PrintScore(); + } + } + + public void Exit() + { + if (_games.Count != 0) + { + Console.WriteLine("\nThank you for playing the Math Game. Here is your Math Game history\n\n"); + MathGameHistory(); + } + + else + Console.WriteLine("\nThank you for playing the Math Game."); + + Console.WriteLine("\nHave a nice day!"); + } + } +} diff --git a/MathGame.ivangar/MathGame.ivangar/Menu.cs b/MathGame.ivangar/MathGame.ivangar/Menu.cs index 35183264..ac0a038b 100644 --- a/MathGame.ivangar/MathGame.ivangar/Menu.cs +++ b/MathGame.ivangar/MathGame.ivangar/Menu.cs @@ -4,9 +4,9 @@ namespace MathGame.ivangar { public static class Menu { - public static string? Intro() + public static string? GameIntro() { - Console.WriteLine("Welcome to the Math Game!"); + Console.WriteLine("\nWelcome to the Math Game!"); Console.WriteLine("We are going to test your math skills!"); PrintMenu(); return Console.ReadLine(); @@ -15,9 +15,9 @@ public static class Menu public static void PrintMenu(bool invalid = false) { if (invalid) - Console.WriteLine("Invalid input."); + Console.WriteLine("\nInvalid input."); - Console.WriteLine("Please choose any of the following options (you have to type the word, i.e. 'play'):\n"); + Console.WriteLine("\nPlease choose any of the following options (you have to type the word, i.e. 'play'):\n"); PrintMenuOptions(); } @@ -25,21 +25,40 @@ public static void PrintMenuOptions() { foreach (MainMenuItems option in Enum.GetValues(typeof(MainMenuItems))) Console.WriteLine($"\t{(int)option}. {option}"); + + Console.WriteLine("\n"); } - public static void StartGamePrompt(int maxNumberOfQuestions) + public static char StartGamePrompt(int maxNumberOfQuestions, int currentQuestionNumber) { Console.WriteLine($"\nThis game has {maxNumberOfQuestions} questions."); + return PrintGameOptions(invalid: false, currentQuestionNumber); } - /* TO DELETE */ - public static void PrintGameOptions(bool invalid = false, int currentQuestionNumber = -1) + public static char PrintGameOptions(bool invalid = false, int currentQuestionNumber = -1) { if (invalid) Console.Write("\nInvalid operation selected! "); if (currentQuestionNumber > 0) - Console.WriteLine($"\n\tQuestion #{currentQuestionNumber}\n"); + Console.WriteLine($"\n\n\tQuestion #{currentQuestionNumber}\n"); + + Console.Write("Choose an operation and type any of the following options: +, -, *, / \n"); + ConsoleKeyInfo keyInfo = Console.ReadKey(); + return keyInfo.KeyChar; + } + + public static char ContinueGamePrompt(bool invalid = false) + { + if (invalid) + Console.Write("\nInvalid input. Please enter 'y' or 'n': "); + + else + Console.Write("\nWould you like to continue the game? (y/n): "); + + ConsoleKeyInfo keyInfo = Console.ReadKey(); + char continueInput = char.ToLower(keyInfo.KeyChar); + return continueInput; } } } diff --git a/MathGame.ivangar/MathGame.ivangar/Program.cs b/MathGame.ivangar/MathGame.ivangar/Program.cs index b58d4dec..65464ce7 100644 --- a/MathGame.ivangar/MathGame.ivangar/Program.cs +++ b/MathGame.ivangar/MathGame.ivangar/Program.cs @@ -1,40 +1,4 @@ using MathGame.ivangar; -using MathGame.ivangar.Enums; -using MathGame.ivangar.Helpers; -List games = []; -bool exitGame = false; -string? menuOption = Menu.Intro(); - -while (true) -{ - while (!MenuValidator.ValidateMainOptions(menuOption)) - { - menuOption = Console.ReadLine(); - } - - Enum.TryParse(menuOption!.Trim(), ignoreCase: true, out MainMenuItems option); - - switch (option) - { - case MainMenuItems.Play: - var game = new Game(); - game.Start(); - break; - case MainMenuItems.History: - Console.WriteLine("PRINT HISTORY"); - break; - case MainMenuItems.Exit: - exitGame = true; - break; - } - - if (exitGame) - { - Console.WriteLine("Thank you for playing the Math Game. Have a nice day!"); - break; - } - - Menu.PrintMenu(); - menuOption = Console.ReadLine(); -} \ No newline at end of file +var mathGame = new GameCenter(); +mathGame.Start(); \ No newline at end of file From c7200992d64a9db717549151b20a21d497c523ba Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Thu, 20 Aug 2026 17:09:09 -0400 Subject: [PATCH 06/10] Refactor game - consolidate operations into 1 method. Add GameValidator class. --- MathGame.ivangar/MathGame.ivangar/Game.cs | 155 ++++++------------ .../MathGame.ivangar/GameCenter.cs | 2 +- MathGame.ivangar/MathGame.ivangar/Menu.cs | 2 +- .../Validators/GameValidator.cs | 30 ++++ .../{Helpers => Validators}/MenuValidator.cs | 6 +- 5 files changed, 83 insertions(+), 112 deletions(-) create mode 100644 MathGame.ivangar/MathGame.ivangar/Validators/GameValidator.cs rename MathGame.ivangar/MathGame.ivangar/{Helpers => Validators}/MenuValidator.cs (88%) diff --git a/MathGame.ivangar/MathGame.ivangar/Game.cs b/MathGame.ivangar/MathGame.ivangar/Game.cs index abc725a7..bed99ccd 100644 --- a/MathGame.ivangar/MathGame.ivangar/Game.cs +++ b/MathGame.ivangar/MathGame.ivangar/Game.cs @@ -1,28 +1,37 @@ -namespace MathGame.ivangar +using MathGame.ivangar.Validators; + +namespace MathGame.ivangar { public class Game { - private readonly char[] _operators = ['+', '-', '*', '/']; - - private int _maxNumberOfQuestions = Random.Shared.Next(5, 11); - //private int _maxNumberOfQuestions = 4; //USE this to test, remove before PR + private static readonly char[] _operators = ['+', '-', '*', '/']; - private int _currentQuestionNumber = 1; - - private int _score = 0; + private readonly int _maxNumberOfQuestions; + // State fields + private int _currentQuestionNumber; + private int _score; private int _result; + private int _op1, _op2; - public int _userAnswer; + public int UserAnswer { get; set; } - private int _op1, _op2; + public IReadOnlyList GameHistory => _gameHistory; + + private readonly List _gameHistory = new(); - public List GameHistory = []; + public Game() + { + _maxNumberOfQuestions = Random.Shared.Next(5, 11); + _currentQuestionNumber = 1; + _score = 0; + } public void Play() { bool continueGame = true; char operation = Menu.StartGamePrompt(_maxNumberOfQuestions, _currentQuestionNumber); + GameValidator validator = new GameValidator(); while (continueGame) { @@ -31,97 +40,52 @@ public void Play() operation = Menu.PrintGameOptions(invalid: true); } - switch (operation) - { - case '+': Add(); break; - case '-': Subtract(); break; - case '*': Multiply(); break; - case '/': Divide(); break; - } + PerformMathOperation(operation); - var validAnswer = ValidateAnswer(); + var validAnswer = validator.ValidateAnswer(_result, UserAnswer, ref _score); UpdateGameHistory(operation, validAnswer); _currentQuestionNumber++; if (_currentQuestionNumber > _maxNumberOfQuestions) break; - char continueInput = Menu.ContinueGamePrompt(); - continueGame = ValidateContinueGame(continueInput); + continueGame = validator.ValidateContinueGame(Menu.ContinueGamePrompt()); if (continueGame) operation = Menu.PrintGameOptions(false, _currentQuestionNumber); - } - Console.WriteLine("\n\nGame Over!\n"); - PrintScore(); - PrintGameHistory(); + FinishGame(); } - public void Add() + public void PerformMathOperation(char operation) { - _op1 = Random.Shared.Next(0, 101); - _op2 = Random.Shared.Next(0, 101); - _result = _op1 + _op2; + Random random = new(); + _op1 = operation == '/' ? random.Next(1, 101) : random.Next(0, 101); + _op2 = operation == '/' ? GetDivisor() : random.Next(0, 101); - Console.Write($"\n\nWhat is the result of:\n{_op1} + {_op2} = "); - string? answer = Console.ReadLine(); - - while (!int.TryParse(answer, out _userAnswer)) + _result = operation switch { - Console.WriteLine("Invalid input. Please enter a valid number: "); - answer = Console.ReadLine(); - } - } - - public void Subtract() - { - _op1 = Random.Shared.Next(0, 101); - _op2 = Random.Shared.Next(0, 101); - _result = _op1 - _op2; - - Console.Write($"\n\nWhat is the result of:\n{_op1} - {_op2} = "); + '+' => _op1 + _op2, + '-' => _op1 - _op2, + '*' => _op1 * _op2, + '/' => _op1 / _op2, + _ => throw new InvalidOperationException("Invalid operation") + }; + + Console.Write($"\n\nWhat is the result of:\n{_op1} {operation} {_op2} = "); string? answer = Console.ReadLine(); - while (!int.TryParse(answer, out _userAnswer)) + int parsedAnswer; // local variable + while (!int.TryParse(answer, out parsedAnswer)) { Console.WriteLine("Invalid input. Please enter a valid number: "); answer = Console.ReadLine(); } - } - - public void Multiply() - { - _op1 = Random.Shared.Next(0, 101); - _op2 = Random.Shared.Next(0, 101); - _result = _op1 * _op2; - - Console.Write($"\n\nWhat is the result of:\n{_op1} * {_op2} = "); - string? answer = Console.ReadLine(); - while (!int.TryParse(answer, out _userAnswer)) - { - Console.WriteLine("Invalid input. Please enter a valid number: "); - answer = Console.ReadLine(); - } + UserAnswer = parsedAnswer; } - public void Divide() - { - _op1 = Random.Shared.Next(1, 101); - _op2 = GetDivisor(); - _result = _op1 / _op2; - - Console.Write($"\n\nWhat is the result of:\n{_op1} / {_op2} = "); - string? answer = Console.ReadLine(); - - while (!int.TryParse(answer, out _userAnswer)) - { - Console.WriteLine("Invalid input. Please enter a valid number: "); - answer = Console.ReadLine(); - } - } public void PrintGameHistory() { Console.WriteLine("\nGame History:\n"); @@ -135,7 +99,10 @@ public void PrintGameHistory() public void PrintScore() { - decimal finalScore = Math.Round((decimal)_score * 100 / _maxNumberOfQuestions, MidpointRounding.AwayFromZero); + var numberOfQuestionsAnswered = _currentQuestionNumber - 1; + decimal finalScore = Math.Round((decimal)_score * 100 / numberOfQuestionsAnswered, MidpointRounding.AwayFromZero); + + Console.WriteLine($"You answered correctly {_score}/{numberOfQuestionsAnswered} questions."); Console.WriteLine($"Your score is: {finalScore}%"); } @@ -146,36 +113,12 @@ public void FinishGame() PrintScore(); } - private bool ValidateAnswer() - { - if (_result == _userAnswer) - { - Console.WriteLine("Correct Answer!"); - _score++; - return true; - } - - else - Console.WriteLine($"Incorrect Answer! The correct answer is: {_result}"); - - return false; - } - + #region Private Methods private void UpdateGameHistory(char operation, bool validAnswer) { var scoreMark = validAnswer ? "Correct" : "Incorrect"; - var operationLog = $"{_op1} {operation} {_op2} = {_userAnswer,-30} {scoreMark,-20}"; - GameHistory.Add(operationLog); - } - - private static bool ValidateContinueGame(char input) - { - while (input != 'y' && input != 'n') - { - input = Menu.ContinueGamePrompt(invalid: true); - } - - return input == 'y'; + var operationLog = $"{_op1} {operation} {_op2} = {UserAnswer,-30} {scoreMark,-20}"; + _gameHistory.Add(operationLog); } /*Get a list of potential divisors (without remainders) and return randomly any divisor */ @@ -192,7 +135,7 @@ private int GetDivisor() return divisors[Random.Shared.Next(0, divisors.Count)]; } - private bool IsPrimeNumber(int number) + private static bool IsPrimeNumber(int number) { var primes = Enumerable.Range(2, 100) .Where(n => !Enumerable.Range(2, (int)Math.Sqrt(n) - 1).Any(d => n % d == 0)) @@ -200,6 +143,6 @@ private bool IsPrimeNumber(int number) return primes.Contains(number); } - + #endregion } } diff --git a/MathGame.ivangar/MathGame.ivangar/GameCenter.cs b/MathGame.ivangar/MathGame.ivangar/GameCenter.cs index 413974bd..0e412e0f 100644 --- a/MathGame.ivangar/MathGame.ivangar/GameCenter.cs +++ b/MathGame.ivangar/MathGame.ivangar/GameCenter.cs @@ -1,5 +1,5 @@ using MathGame.ivangar.Enums; -using MathGame.ivangar.Helpers; +using MathGame.ivangar.Validators; namespace MathGame.ivangar { diff --git a/MathGame.ivangar/MathGame.ivangar/Menu.cs b/MathGame.ivangar/MathGame.ivangar/Menu.cs index ac0a038b..d362ce5d 100644 --- a/MathGame.ivangar/MathGame.ivangar/Menu.cs +++ b/MathGame.ivangar/MathGame.ivangar/Menu.cs @@ -43,7 +43,7 @@ public static char PrintGameOptions(bool invalid = false, int currentQuestionNum if (currentQuestionNumber > 0) Console.WriteLine($"\n\n\tQuestion #{currentQuestionNumber}\n"); - Console.Write("Choose an operation and type any of the following options: +, -, *, / \n"); + Console.Write("Choose an operation (type any of the following options: +, -, *, /): "); ConsoleKeyInfo keyInfo = Console.ReadKey(); return keyInfo.KeyChar; } diff --git a/MathGame.ivangar/MathGame.ivangar/Validators/GameValidator.cs b/MathGame.ivangar/MathGame.ivangar/Validators/GameValidator.cs new file mode 100644 index 00000000..86c053c1 --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/Validators/GameValidator.cs @@ -0,0 +1,30 @@ +namespace MathGame.ivangar.Validators +{ + public class GameValidator + { + public bool ValidateAnswer(int result, int userAnswer, ref int score) + { + if (result == userAnswer) + { + Console.WriteLine("Correct Answer!"); + score++; + return true; + } + + else + Console.WriteLine($"Incorrect Answer! The correct answer is: {result}"); + + return false; + } + + public bool ValidateContinueGame(char input) + { + while (input != 'y' && input != 'n') + { + input = Menu.ContinueGamePrompt(invalid: true); + } + + return input == 'y'; + } + } +} diff --git a/MathGame.ivangar/MathGame.ivangar/Helpers/MenuValidator.cs b/MathGame.ivangar/MathGame.ivangar/Validators/MenuValidator.cs similarity index 88% rename from MathGame.ivangar/MathGame.ivangar/Helpers/MenuValidator.cs rename to MathGame.ivangar/MathGame.ivangar/Validators/MenuValidator.cs index d461a8e3..95d3f247 100644 --- a/MathGame.ivangar/MathGame.ivangar/Helpers/MenuValidator.cs +++ b/MathGame.ivangar/MathGame.ivangar/Validators/MenuValidator.cs @@ -1,8 +1,6 @@ - +using MathGame.ivangar.Enums; -using MathGame.ivangar.Enums; - -namespace MathGame.ivangar.Helpers +namespace MathGame.ivangar.Validators { public static class MenuValidator { From bc6e9ea23619251ac378088bceb9a2411ad0a388 Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Mon, 24 Aug 2026 15:59:29 -0400 Subject: [PATCH 07/10] Add interface IGame. Add MathOperation record to represent each operation object. --- MathGame.ivangar/MathGame.ivangar/Game.cs | 46 +++++++++++-------- MathGame.ivangar/MathGame.ivangar/IGame.cs | 10 ++++ .../MathGame.ivangar/MathOperation.cs | 16 +++++++ .../Validators/GameValidator.cs | 5 +- 4 files changed, 54 insertions(+), 23 deletions(-) create mode 100644 MathGame.ivangar/MathGame.ivangar/IGame.cs create mode 100644 MathGame.ivangar/MathGame.ivangar/MathOperation.cs diff --git a/MathGame.ivangar/MathGame.ivangar/Game.cs b/MathGame.ivangar/MathGame.ivangar/Game.cs index bed99ccd..a105aee5 100644 --- a/MathGame.ivangar/MathGame.ivangar/Game.cs +++ b/MathGame.ivangar/MathGame.ivangar/Game.cs @@ -2,7 +2,7 @@ namespace MathGame.ivangar { - public class Game + public class Game : IGame { private static readonly char[] _operators = ['+', '-', '*', '/']; @@ -16,9 +16,9 @@ public class Game public int UserAnswer { get; set; } - public IReadOnlyList GameHistory => _gameHistory; + public IReadOnlyList GameHistory => _gameHistory; - private readonly List _gameHistory = new(); + private readonly List _gameHistory = new(); public Game() { @@ -41,9 +41,8 @@ public void Play() } PerformMathOperation(operation); + validator.ValidateAnswer(_result, UserAnswer, ref _score); - var validAnswer = validator.ValidateAnswer(_result, UserAnswer, ref _score); - UpdateGameHistory(operation, validAnswer); _currentQuestionNumber++; if (_currentQuestionNumber > _maxNumberOfQuestions) @@ -61,22 +60,15 @@ public void Play() public void PerformMathOperation(char operation) { Random random = new(); + _op1 = operation == '/' ? random.Next(1, 101) : random.Next(0, 101); _op2 = operation == '/' ? GetDivisor() : random.Next(0, 101); - - _result = operation switch - { - '+' => _op1 + _op2, - '-' => _op1 - _op2, - '*' => _op1 * _op2, - '/' => _op1 / _op2, - _ => throw new InvalidOperationException("Invalid operation") - }; + CalculateResult(operation); Console.Write($"\n\nWhat is the result of:\n{_op1} {operation} {_op2} = "); string? answer = Console.ReadLine(); - int parsedAnswer; // local variable + int parsedAnswer; while (!int.TryParse(answer, out parsedAnswer)) { Console.WriteLine("Invalid input. Please enter a valid number: "); @@ -84,11 +76,22 @@ public void PerformMathOperation(char operation) } UserAnswer = parsedAnswer; + + _gameHistory.Add(new MathOperation + { + OperandA = _op1, + OperandB = _op2, + Operation = operation, + UserAnswer = UserAnswer, + ScoreMark = UserAnswer == _result ? "Correct" : "Incorrect" + } + ); } public void PrintGameHistory() { Console.WriteLine("\nGame History:\n"); + foreach (var (index, operation) in GameHistory.Select((o, i) => (i, o))) { Console.WriteLine($"{index + 1}. {operation}"); @@ -114,11 +117,16 @@ public void FinishGame() } #region Private Methods - private void UpdateGameHistory(char operation, bool validAnswer) + private void CalculateResult(char operation) { - var scoreMark = validAnswer ? "Correct" : "Incorrect"; - var operationLog = $"{_op1} {operation} {_op2} = {UserAnswer,-30} {scoreMark,-20}"; - _gameHistory.Add(operationLog); + _result = operation switch + { + '+' => _op1 + _op2, + '-' => _op1 - _op2, + '*' => _op1 * _op2, + '/' => _op1 / _op2, + _ => throw new InvalidOperationException("Invalid operation") + }; } /*Get a list of potential divisors (without remainders) and return randomly any divisor */ diff --git a/MathGame.ivangar/MathGame.ivangar/IGame.cs b/MathGame.ivangar/MathGame.ivangar/IGame.cs new file mode 100644 index 00000000..8c6019df --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/IGame.cs @@ -0,0 +1,10 @@ +namespace MathGame.ivangar +{ + public interface IGame + { + void Play(); + void FinishGame(); + void PrintGameHistory(); + void PrintScore(); + } +} diff --git a/MathGame.ivangar/MathGame.ivangar/MathOperation.cs b/MathGame.ivangar/MathGame.ivangar/MathOperation.cs new file mode 100644 index 00000000..bc1dd000 --- /dev/null +++ b/MathGame.ivangar/MathGame.ivangar/MathOperation.cs @@ -0,0 +1,16 @@ +namespace MathGame.ivangar +{ + public record MathOperation + { + public int OperandA { get; init; } + public int OperandB { get; init; } + public char Operation { get; init; } + public int UserAnswer { get; init; } + public string ScoreMark { get; init; } = string.Empty; + + public override string ToString() + { + return $"{OperandA} {Operation} {OperandB} = {UserAnswer,-10} {ScoreMark,-5}"; + } + } +} diff --git a/MathGame.ivangar/MathGame.ivangar/Validators/GameValidator.cs b/MathGame.ivangar/MathGame.ivangar/Validators/GameValidator.cs index 86c053c1..bd9d3913 100644 --- a/MathGame.ivangar/MathGame.ivangar/Validators/GameValidator.cs +++ b/MathGame.ivangar/MathGame.ivangar/Validators/GameValidator.cs @@ -2,19 +2,16 @@ { public class GameValidator { - public bool ValidateAnswer(int result, int userAnswer, ref int score) + public void ValidateAnswer(int result, int userAnswer, ref int score) { if (result == userAnswer) { Console.WriteLine("Correct Answer!"); score++; - return true; } else Console.WriteLine($"Incorrect Answer! The correct answer is: {result}"); - - return false; } public bool ValidateContinueGame(char input) From 064e2ffee83125c8cd10ae1605369dd9feecaa0d Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Mon, 24 Aug 2026 16:30:08 -0400 Subject: [PATCH 08/10] optimized history log format. --- MathGame.ivangar/MathGame.ivangar/Game.cs | 4 +--- MathGame.ivangar/MathGame.ivangar/MathOperation.cs | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/MathGame.ivangar/MathGame.ivangar/Game.cs b/MathGame.ivangar/MathGame.ivangar/Game.cs index a105aee5..c79427a8 100644 --- a/MathGame.ivangar/MathGame.ivangar/Game.cs +++ b/MathGame.ivangar/MathGame.ivangar/Game.cs @@ -16,8 +16,6 @@ public class Game : IGame public int UserAnswer { get; set; } - public IReadOnlyList GameHistory => _gameHistory; - private readonly List _gameHistory = new(); public Game() @@ -92,7 +90,7 @@ public void PrintGameHistory() { Console.WriteLine("\nGame History:\n"); - foreach (var (index, operation) in GameHistory.Select((o, i) => (i, o))) + foreach (var (index, operation) in _gameHistory.Select((o, i) => (i, o))) { Console.WriteLine($"{index + 1}. {operation}"); } diff --git a/MathGame.ivangar/MathGame.ivangar/MathOperation.cs b/MathGame.ivangar/MathGame.ivangar/MathOperation.cs index bc1dd000..4a35c383 100644 --- a/MathGame.ivangar/MathGame.ivangar/MathOperation.cs +++ b/MathGame.ivangar/MathGame.ivangar/MathOperation.cs @@ -10,7 +10,8 @@ public record MathOperation public override string ToString() { - return $"{OperandA} {Operation} {OperandB} = {UserAnswer,-10} {ScoreMark,-5}"; + var leftHandSide = $"{OperandA} {Operation} {OperandB} = {UserAnswer}"; + return $"{leftHandSide,-20} {ScoreMark,-5}"; } } } From af1c024d019b3146ed164bbfff671f930a6d8ba1 Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Mon, 24 Aug 2026 16:35:32 -0400 Subject: [PATCH 09/10] Final update to Math Game --- MathGame.ivangar/MathGame.ivangar/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MathGame.ivangar/MathGame.ivangar/Program.cs b/MathGame.ivangar/MathGame.ivangar/Program.cs index 65464ce7..913acee2 100644 --- a/MathGame.ivangar/MathGame.ivangar/Program.cs +++ b/MathGame.ivangar/MathGame.ivangar/Program.cs @@ -1,4 +1,4 @@ using MathGame.ivangar; -var mathGame = new GameCenter(); -mathGame.Start(); \ No newline at end of file +var gameCenter = new GameCenter(); +gameCenter.Start(); \ No newline at end of file From 046e698f5d3f796fa48adcf799e647e8473bf0bb Mon Sep 17 00:00:00 2001 From: Ivan Garzon Date: Mon, 24 Aug 2026 18:12:36 -0400 Subject: [PATCH 10/10] use single Random instance as a member Game class --- MathGame.ivangar/MathGame.ivangar/Game.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MathGame.ivangar/MathGame.ivangar/Game.cs b/MathGame.ivangar/MathGame.ivangar/Game.cs index c79427a8..be207333 100644 --- a/MathGame.ivangar/MathGame.ivangar/Game.cs +++ b/MathGame.ivangar/MathGame.ivangar/Game.cs @@ -7,6 +7,7 @@ public class Game : IGame private static readonly char[] _operators = ['+', '-', '*', '/']; private readonly int _maxNumberOfQuestions; + private readonly Random _random; // State fields private int _currentQuestionNumber; @@ -20,7 +21,8 @@ public class Game : IGame public Game() { - _maxNumberOfQuestions = Random.Shared.Next(5, 11); + _random = new Random(); + _maxNumberOfQuestions = _random.Next(5, 11); _currentQuestionNumber = 1; _score = 0; } @@ -57,10 +59,8 @@ public void Play() public void PerformMathOperation(char operation) { - Random random = new(); - - _op1 = operation == '/' ? random.Next(1, 101) : random.Next(0, 101); - _op2 = operation == '/' ? GetDivisor() : random.Next(0, 101); + _op1 = operation == '/' ? _random.Next(1, 101) : _random.Next(0, 101); + _op2 = operation == '/' ? GetDivisor() : _random.Next(0, 101); CalculateResult(operation); Console.Write($"\n\nWhat is the result of:\n{_op1} {operation} {_op2} = "); @@ -138,7 +138,7 @@ private int GetDivisor() .Where(x => _op1 % x == 0) .ToList(); - return divisors[Random.Shared.Next(0, divisors.Count)]; + return divisors[_random.Next(0, divisors.Count)]; } private static bool IsPrimeNumber(int number)