Skip to content
Closed
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
8 changes: 8 additions & 0 deletions MathGame/MathGame.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
3 changes: 3 additions & 0 deletions MathGame/MathGame.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Solution>
<Project Path="MathGame.csproj" />
</Solution>
58 changes: 58 additions & 0 deletions MathGame/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Math

this project was developed as part of csharp-academy challenge and doesn't represent a core or a useful business product however you can use it to play with your children and young siblings who happened to be a computer nerd but will not receive any further core update but pull requests are welcomed

this project was a real testing playground to measure what really I can do with this language keep in mind that my level is beginner by the time of writing this repo with previous experience in python and basic understanding in c++ and java (don't ever try learning java 8)

I didn't plan to make it full oop and I was gonna make a monolithic class with many many partial members but I discarded the idea and refactored everything into oop base

and to be honest I didn't planned to make it fully function TUI but I guess I love over-engineering stuff always and over think it

## to the csharp-academy mentors reviewing my project

please guide me through how to plan your project structure and what type of problems generally in programming exercise but please I want guidance on how to think not like a coder like a system designer how to make multiple components communicate with each other and lastly I want an objective brutally honest review thing I can do better based on my current knowledge thing I shouldn't have done am not aiming for praises I want to get a jop in the .net marked and it to be a key for getting outside of my home country so I want to know what wrong and what right to enhance myself

I truly appreciate your review in advance.

## AI honesty

about 60% of feature was designed and planned by me however due to the level of inexperience in debugging generally and c# specifically and to be honest I used the debugger sometimes to watch how my variables change to guess the issue and in other times I would simply trace it if it's simple and proceed in random changes till it got fix magically

however due to inexperience in code deigning and how to connect my ideas some features like dictionary, using abstract class, using interfaces and workarounds to pass the threading locks such as readline or looping to get the timer, orchestrating multiple objects through interface, using Enums, searching a better way of generating random number and shuffling them, better code optimizations and lastly as I remember how to wire your ideas into robust execution

however I'm not a big fan of copy pasting sense I learn by search , read and apply so I wrote almost all the code by hand but I used rider's built-in tools to help in code refactoring

## commit philosophy

I followed when committing Conventional Commits.Standard Commit Structure

```text
<type>[optional scope]: <description>
```

- Common Commit Types
- feat: A new feature for the user.
- fix: A bug fix for the user.
- docs: Changes to the documentation.
- style: Formatting, missing semi-colons, etc. (no production code changes).
- refactor: Refactoring production code (neither fixing a bug nor adding a feature).
- perf: Code changes that improve performance.
- test: Adding missing tests or correcting existing tests.
- build: Changes that affect the build system or external dependencies.
- ci: Changes to CI configuration files and scripts.
- chore: Other changes that don't modify src or test files.
- revert: Reverts a previous commit.

## What I discovered and learned on top of my current knowledge

- `StringBuilder` and `ConsoleKeyInfo` input combination : at least now I know a new way of processing user input alongside with `Readline()` that would not pause the user execution but sure it super hard and easy to mess things up
- How to get the user's console size and utilize it for dictating some conditions like what I did
- How to set the default value of your Properties and I learned the hard way that properties cannot be passed by reference
- `"\a"` is the `Console.Beep()` cross-platform alt
- basic understanding of Enums
- basic understanding of struct and when to use them
- basic understanding of records and its types and when to use both
- how to work with abstraction
- how to work with interfaces and use them
- how to use Random.shared
- the basics of using collection and LINQ
111 changes: 111 additions & 0 deletions MathGame/docs/planning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# project

## Requirements

- You need to create a game that **consists** of asking the player what's the result of a math question (i.e. 9 x 9 = ?), collecting the input and adding a point in case of a correct answer.

<!-- ### solution -->

- A game needs to have at least 5 questions.
- The divisions should result on INTEGERS ONLY and dividends should go from 0 to 100. Example: Your app shouldn't present the division 7/2 to the user, since it doesn't result in an integer.
- Users should be presented with a menu to choose an operation
- You should record previous games in a List and there should be an option in the menu for the user to visualize a history of previous games.
- You don't need to record results on a database. Once the program is closed the results will be deleted.

## challenges

- Try to implement levels of difficulty.
- Add a timer to track how long the user takes to finish the game.
- Create a 'Random Game' option where the players will be presented with questions from random operations
- To follow the DRY Principle, try using just one method for all games. Additionally, double check your project and try to find opportunities to achieve the same functionality with less code, avoiding repetition when possible.

## Main menu

- the window must be constantly update to much the screen (18 X 80)

```text
███╗ ███╗ █████╗ ████████╗██╗ ██╗ ██████╗ █████╗ ███╗ ███╗███████╗
████╗ ████║██╔══██╗╚══██╔══╝██║ ██║ ██╔════╝ ██╔══██╗████╗ ████║██╔════╝
██╔████╔██║███████║ ██║ ███████║ ██║ ███╗███████║██╔████╔██║█████╗
██║╚██╔╝██║██╔══██║ ██║ ██╔══██║ ██║ ██║██╔══██║██║╚██╔╝██║██╔══╝
██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║ ╚██████╔╝██║ ██║██║ ╚═╝ ██║███████╗
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ [this will take about 6 X 76]


a. Start The Game
b. History Record
c. About The Game
d. Exit



[this will be in the end of the screen]
[hint of how the user will choose] [this will take about 1 X 50]
Type your answer : [your choice] (MUST TRIM AND LOWER THE USER'INPUT) [this will take about 1 X 37]
```

### logic

- the update loop must check if window width and hight are (18 X 80) if not it will pause the execution until the user follow the instructions
- there should be an option in the menu for the user to **visualize a history of previous games**.
- there should be an option for **starting the game which** which will give the following set of question to answer
- choose a difficulty (type the Menu Keys:[a,b,c,d])
- a. easy (digits from 0 to 10)
- b. normal (digits from 0 to 100)
- c. hard (digits from 0 to 10 + TIMED 10s)
- d. insane (digits from 0 to 100 + TIMED 10s and 15s if random)
- e. impossible (digits from 0 to 100 + TIMED 5s and 10s if random)
> upon choosing the difficulty it will then show the type of operation
- choose operation
- a. addition (+)
- b. subtraction (-)
- c. multiplication (×)
- d. division (÷)
- e. random operation
> upon choosing the operation it will then choose the type of question
- choose your type of question
- a. MCQ
- b. true or false
- c. fill the gaps
- d. normal
- e. random

## setup menu

- the window of the start setup Which will define how the game will work

```text
Choose From The Following Options

choose a difficulty

a. easy (digits from 0 to 10) 4
b. normal (digits from 0 to 100)
c. hard (digits from 0 to 10 + TIMED 10s)
d. insane (digits from 0 to 100 + TIMED 10s and 15s if random operation)
e. impossible (digits from 0 to 100 + TIMED 5s and 10s if random operation) 8


Difficulty : NONE Operation : NONE Question Type : NONE


██ ██ ▄▄ ▄▄ ▄▄ ▄▄▄▄▄▄ ▄▄▄▄
██████ ██ ███▄██ ██ ███▄▄
██ ██ ██ ██ ▀██ ██ ▄▄██▀

- type a letter from [a, b, c, d, e]
- to go back to main menu [q] soft exit
- type [w] to wipe all selections
- press [ctrl+c] to hard exit


Type your answer : 23
```

### logic and design

- hight from 4 to 8 is the selection place and the maximum width is 76 the maximum that the window could reach is 23 rows and 76 columns
- add a method to wipe-out all the selection upon selection
- Add a method to print the current selection then print the user selection in a different location
- define How would you deal with q, w and general user input
- handle the input process correctly
16 changes: 16 additions & 0 deletions MathGame/src/AbstractBases/AnswerBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using MathGame.GameQuestion;

namespace MathGame.AbstractBases;

// a generic abstract class and each class name represent its purpose
public abstract class AnswerBase<T>
{
// Store the question Type Itself
public abstract GameQuestionType QuestionType {get;}



// Validate the Answer either with a string or a char
public abstract bool ValidateAnswer(T userInput);

}
11 changes: 11 additions & 0 deletions MathGame/src/AbstractBases/IQuestion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using MathGame.GameQuestion;

namespace MathGame.AbstractBases;

// this is to orchestrate all the questions in the game window
public interface IQuestion
{
GameQuestionType QuestionType { get; }
string QuestionPrompt { get; }
bool CheckAnswer(string userInput);
}
21 changes: 21 additions & 0 deletions MathGame/src/AbstractBases/QuestionBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using MathGame.GameQuestion;

namespace MathGame.AbstractBases;

// a generic abstract class and each class name represent its purpose
public abstract class QuestionBase<T>(Problem problem) : IQuestion
{
// they will hold our problem itself
protected Problem Problem = problem;
// to define the type Effectively
public abstract GameQuestionType QuestionType{get;}


// question prompt
public abstract string QuestionPrompt { get; }
// Answer Holder
public abstract AnswerBase<T> Answer{get;} // note the T must be of the same type
public abstract bool CheckAnswer(string answer);

// this method will use the Problem Object in Order to prepare the question text
}
14 changes: 14 additions & 0 deletions MathGame/src/AbstractBases/WindowBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using MathGame.GameWindows;

namespace MathGame.AbstractBases;

// A generic class to hold all the windows and unifying the handling for modularity and simplicity
public abstract class WindowBase
{

// the method to draw and construct the current window
public abstract void Render();

// method to process the user's option if they enters [a,b,c] based on the active valid options
public abstract WindowMap ProcessInput(string userInput);
}
Loading
Loading