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
10 changes: 10 additions & 0 deletions mantpaa.MathGame/MathGame.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

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

</Project>
24 changes: 24 additions & 0 deletions mantpaa.MathGame/MathGame.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathGame", "MathGame.csproj", "{8E44D313-4A8D-F5FA-1FB5-C00DA569A7BD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8E44D313-4A8D-F5FA-1FB5-C00DA569A7BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E44D313-4A8D-F5FA-1FB5-C00DA569A7BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E44D313-4A8D-F5FA-1FB5-C00DA569A7BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E44D313-4A8D-F5FA-1FB5-C00DA569A7BD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BA2070F0-AF12-4B1E-BF4A-511581206CBF}
EndGlobalSection
EndGlobal
46 changes: 46 additions & 0 deletions mantpaa.MathGame/Models/GameData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
namespace MathGame.Models;

internal class GameData
{
private int score;
private double avgTimePerQuestion;
private int difficultyLevel;
private Question[] questions;

public GameData(int score, int difficultyLevel, Question[] questions)
{
this.score = score;

this.difficultyLevel = difficultyLevel;
this.questions = questions;
this.avgTimePerQuestion = CalculateAvgTimePerQuestion();
}

public override string ToString()
{
string returnString = "";
foreach (var question in questions)
{
returnString += $"Equation: {question.Equation} = ?, Answer: {question.Answer}, Expected answer: {question.ExpectedAnswer}, Time spent: {((question.TimeSpentSeconds) >= 0 ? (question.TimeSpentSeconds) : "N/A")} seconds.\n";
}
returnString += "".PadLeft(Console.BufferWidth, '-') + "\n";
returnString += $"Score: {score}, Difficulty level: {difficultyLevel}, Average time per question: {avgTimePerQuestion} seconds.";
return returnString;
}

private double CalculateAvgTimePerQuestion()
{
int totalTime = 0;
int questionsAnswered = 0;
foreach (var question in questions)
{
if (question.TimeSpentSeconds >= 0)
{
totalTime += question.TimeSpentSeconds;
questionsAnswered++;
}
}

return questionsAnswered > 0 ? (double)totalTime / questionsAnswered : 0;
}
}
204 changes: 204 additions & 0 deletions mantpaa.MathGame/Models/GameEngine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
using System.Diagnostics;

namespace MathGame.Models;

internal class GameEngine
{
string[] operators = new string[] { "+", "-", "*", "/" };
List<GameData> gameHistory = new List<GameData>();
int difficulty = 1;
GameType gameType = GameType.Addition;

public void PlayGame()
{
GameData gameData;

int score = 0;


Console.WriteLine("Starting the game! Answer the following questions:");
Console.WriteLine("To give up, type 'exit'.");

Question[] questions = InitializeGame(difficulty);
for (int i = 0; i < questions.Length; i++)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

Console.WriteLine($"Question {i + 1}: {questions[i].Equation}");
string? userAnswer = Console.ReadLine();
stopwatch.Stop();

if (userAnswer != null && userAnswer.ToLower() == "exit")
{
Console.WriteLine("Exiting the game. Goodbye!");
break;
}

if (userAnswer != null)
{
questions[i].Answer = userAnswer;
questions[i].TimeSpentSeconds = stopwatch.Elapsed.Seconds;
if (userAnswer == questions[i].ExpectedAnswer)
{
Console.WriteLine("Correct!");
score++;
}
else
{
Console.WriteLine($"Wrong! The correct answer is {questions[i].ExpectedAnswer}");
}
}
}
gameData = new GameData(score, difficulty, questions);

gameHistory.Add(gameData);
}

public void ViewGameHistory()
{
Console.WriteLine("Score history:");
for (int i = 0; i < gameHistory.Count; i++)
{
Console.WriteLine($"Game {i + 1}:\n{gameHistory[i].ToString()}\n");
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
Console.Clear();
}

public void ChangeDifficulty()
{
string? input;
Console.WriteLine("Current difficulty level: " + difficulty);
Console.WriteLine("Enter new difficulty level (1-3):");
input = Console.ReadLine();

while (input == null || !new string[] { "1", "2", "3" }.Contains(input))
{

Console.WriteLine("Invalid input, try again.");
input = Console.ReadLine();
}

difficulty = int.Parse(input);
}
public void ChangeQuestionType()
{
string? input;
Console.WriteLine("Enter question type:\na - addition\ns - subtraction\nm - multiplication\nd - division\nr - random!");
input = Console.ReadLine();

while (input == null || !new string[] { "a", "s", "m", "d", "r" }.Contains(input.ToLower()))
{
Console.WriteLine("Invalid input, try again.");
input = Console.ReadLine();
}

switch (input.ToLower())
{
case "a":
gameType = GameType.Addition;
break;
case "s":
gameType = GameType.Subtraction;
break;
case "m":
gameType = GameType.Multiplication;
break;
case "d":
gameType = GameType.Division;
break;
case "r":
gameType = GameType.Random;
break;
}
}
private Question[] InitializeGame(int difficultyLevel)
{
Random random = new Random();
string[] operatorValue = new string[] { "+", "-", "*", "/" }; // 0:+, 1: -, 2: *, 3: / : GameType enum values correspond to these indices.
int questionsToAsk = 5;
Question[] questions = new Question[questionsToAsk];
for (int i = 0; i < questionsToAsk; i++)
{
string op = "+";

if (gameType == GameType.Random)
{
op = GetOperator(random);
}
else
{
op = operatorValue[(int) gameType];
}

questions[i] = CreateQuestion(op, difficultyLevel, random);
}

return questions;
}

private Question CreateQuestion(string op, int difficultyLevel, Random random)
{
if (op == "/")
{
int dividend = 1;
int divisor = 1;
bool valid = false;
while (valid == false)
{
dividend = random.Next(0, 101);
int minValue = (difficultyLevel > 1) ? 2 : 1; // disallow division by 1 for higher difficulties.
divisor = random.Next(minValue, (dividend > minValue) ? dividend : minValue +1); // Ensure maxval is larger than minval
if (dividend % divisor == 0)
{
valid = true;
}
}

string equation = $"{dividend} / {divisor}";
string expectedAnswer = (dividend / divisor).ToString();
return new Question(equation, "", expectedAnswer);
}

else if (new string[] {"+", "*", "-" }.Contains(op))
{
int num1 = random.Next(1, 10 * difficultyLevel);
int num2 = random.Next(1, 10 * difficultyLevel);
string equation = $"{num1} {op} {num2}";
string expectedAnswer = "";
if (op == "+")
expectedAnswer = (num1 + num2).ToString();
else if (op == "-")
expectedAnswer = (num1 - num2).ToString();
else if (op == "*")
expectedAnswer = (num1 * num2).ToString();
else
expectedAnswer = "issue occured";

return new Question(equation, "", expectedAnswer);
}

else
{
throw new InvalidDataException("Invalid operator: " + op);
}
}

// Pick a random operator for the question, to help randomize the questions a bit more.
private string GetOperator(Random random)
{
int val = random.Next(0, operators.Length);
return operators[val];
}

enum GameType
{
Addition,
Subtraction,
Multiplication,
Division,
Random
}
}
18 changes: 18 additions & 0 deletions mantpaa.MathGame/Models/Question.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace MathGame.Models;

internal class Question
{
public string Equation { get; set; }
public string Answer { get; set; }

public string ExpectedAnswer { get; set; }

public int TimeSpentSeconds { get; set; } = -1; // Todo: better value?
public Question(string equation, string answer, string expectedAnswer)
{
Equation = equation;
Answer = answer;
ExpectedAnswer = expectedAnswer;
}

}
53 changes: 53 additions & 0 deletions mantpaa.MathGame/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using MathGame.Models;

namespace MathGame;

public static class MathGame
{
public static void Main()
{
GameEngine gameEngine = new GameEngine();

string input = "";
do
{
Console.WriteLine("Math game!\n" +
"Press the number to choose a menu option.\n"+
"1. Play game\n"+
"2. See history.\n"+
"3. Change difficulty(1-3).\n"+
"4. Change question type\n"
+"Exit to exit.");
string? userInput = Console.ReadLine();

if (userInput != null)
{
input = userInput.ToLower();
switch (input)
{
case "1":
gameEngine.PlayGame();
break;
case "2":
gameEngine.ViewGameHistory();
break;
case "3":
gameEngine.ChangeDifficulty();
break;
case "4":
gameEngine.ChangeQuestionType();
break;
case "exit":
Console.WriteLine("Exiting the game. Goodbye!");
break;
default:
Console.WriteLine("Invalid input, try again.");
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
Console.Clear();
break;
}
}
} while (input != "exit");
}
}