From 78bfcaaad5a0a577b0c03db8b8b49b689e4fa069 Mon Sep 17 00:00:00 2001 From: Mark Seilenthal <seilenthalma100744@th-nuernberg.de> Date: Sun, 15 Dec 2024 22:19:04 +0100 Subject: [PATCH] Final Commenting + Final Small Bug-Fixes --- MastermindController.cs | 151 +++++++++++++++++++++++++-------------- MastermindGame.cs | 105 ++++++++++++++------------- Program.cs | 42 +++++------ PseudoRandomGenerator.cs | 56 --------------- 4 files changed, 172 insertions(+), 182 deletions(-) delete mode 100644 PseudoRandomGenerator.cs diff --git a/MastermindController.cs b/MastermindController.cs index c1bf718..2741def 100644 --- a/MastermindController.cs +++ b/MastermindController.cs @@ -13,7 +13,7 @@ namespace Controller { private MastermindGame game; private string difficulty; - private string gammode; + private string gamemode; /// <summary> @@ -26,6 +26,7 @@ namespace Controller Console.WriteLine("Welcome to Mastermind!"); Console.WriteLine("======================"); + // User selects a game mode Console.WriteLine("Please select a Gamemode:\n"); Console.WriteLine("[S]ingle Player\n"); Console.WriteLine("[M]ultiplayer\n"); @@ -39,18 +40,18 @@ namespace Controller case "s": Console.Clear(); Console.WriteLine("You selected Singleplayer!\n"); - gammode = "s"; + gamemode = "s"; checkMenu = true; break; case "m": Console.Clear(); - gammode = "m"; + gamemode = "m"; Console.WriteLine("You selected Multiplayer!\n"); checkMenu = true; break; case "t": Console.Clear(); - gammode = "t"; + gamemode = "t"; Console.WriteLine("You selected Timer Mode!\n"); checkMenu = true; break; @@ -62,12 +63,32 @@ namespace Controller } while (!checkMenu); // User selects a difficulty + Console.WriteLine(new string('=', 30)); Console.WriteLine("Please select the difficulty you would like to play on:\n"); + Console.WriteLine(new string('-', 30)); + // Initializing temporary object to soft code + MastermindGame tmpObject = new MastermindGame("easy"); Console.WriteLine("Difficulty: \t[E]asy \nDescription: \tRecommended for beginners.\n"); + Console.WriteLine($"\t\tThe code is {tmpObject.GetCodeLength()} digits long."); + Console.WriteLine($"\t\tYou have {tmpObject.GetMaxAttempts()} attempts."); + Console.WriteLine($"\t\tDuplicates: {tmpObject.GetDuplicates()}"); + Console.WriteLine(new string('-', 30)); + + tmpObject = new MastermindGame("medium"); Console.WriteLine("Difficulty: \t[M]edium \nDescription: \tRecommended for advanced users.\n"); + Console.WriteLine($"\t\tThe code is {tmpObject.GetCodeLength()} digits long."); + Console.WriteLine($"\t\tYou have {tmpObject.GetMaxAttempts()} attempts."); + Console.WriteLine($"\t\tDuplicates: {tmpObject.GetDuplicates()}"); + Console.WriteLine(new string('-', 30)); + + tmpObject = new MastermindGame("hard"); Console.WriteLine("Difficulty: \t[H]ard \nDescription: \tRecommended for those who are looking for a challenge.\n"); - Console.WriteLine("Press \"R\" to return to the main menu. \n"); + Console.WriteLine($"\t\tThe code is {tmpObject.GetCodeLength()} digits long."); + Console.WriteLine($"\t\tYou have {tmpObject.GetMaxAttempts()} attempts."); + Console.WriteLine($"\t\tDuplicates: {tmpObject.GetDuplicates()}"); + Console.WriteLine(new string('=', 30)); + Console.WriteLine($"Press \"R\" to return to the main menu. \n"); checkMenu = false; do @@ -96,21 +117,19 @@ namespace Controller } while (!checkMenu); - switch (gammode) + switch (gamemode) { case "s": Console.Clear(); - Console.WriteLine("Sibgleplayer mode selected."); + Console.WriteLine("Singleplayer mode selected."); StartSingleplayerGame(); break; case "m": Console.Clear(); - // Implement Multiplayer functionality here Console.WriteLine("Multiplayer mode selected."); StartMultiplayerGame(); - // Placeholder, can be expanded based on the game logic for multiplayer break; case "t": Console.Clear(); @@ -121,17 +140,19 @@ namespace Controller } } + /// <summary> + /// Starts Singleplayer Game + /// </summary> private void StartSingleplayerGame() { // Starts Game Console.Clear(); Console.WriteLine($"Game starts with the difficulty: {difficulty}"); - // Load alt game or start a new one: true -> New game, false -> Load game + // Load old game or start a new one: true -> New game, false -> Load game bool newGame = UserDecision(); game = new MastermindGame(difficulty, newGame); int generatedCodeLength = game.GetCodeLength(); - bool checkMenu = false; bool breaker = false; while (game.StillHasTrials() && !breaker) @@ -139,12 +160,6 @@ namespace Controller // User input Code int[] userInput = ReadInput(generatedCodeLength); - // Debugging (Gets removed later) - foreach (int i in userInput) - { - Console.WriteLine(i); - } - game.AddAttempt(userInput); game.DisplayBoard(); @@ -170,6 +185,9 @@ namespace Controller ShowPlayAgainMenu(); } + /// <summary> + /// Starts Mulitplayer Game + /// </summary> private void StartMultiplayerGame() { Console.Clear(); @@ -252,6 +270,9 @@ namespace Controller ShowPlayAgainMenu(); } + /// <summary> + /// Starts Timer-Mode + /// </summary> private void StartTimerMode() { Console.Clear(); @@ -305,7 +326,6 @@ namespace Controller /// Reads the user input and checks if the input is valid /// </summary> /// <param name="generatedCodeLength">Specifies how long the user's code must be</param> - /// <returns></returns> public int[] ReadInput(int generatedCodeLength) { int[] input = new int[generatedCodeLength]; @@ -342,7 +362,6 @@ namespace Controller { Console.WriteLine($"Error! Please change {i} to a number between 0 and 9"); } - //Console.WriteLine($"Error! {((i == " ") ? $"Please change {i} to a number between 0 and 9" : "Please don't start and end with \" \" and also don't double it!")}"); inputCheck = false; } } @@ -368,6 +387,19 @@ namespace Controller return input; } + /// <summary> + /// Shows up when the time is over + /// </summary> + private void TimerElapsed() + { + Console.Clear(); + Console.WriteLine("Time is up! You didn't guess the code in time."); + game.SaveGame(false); + game.DeleteAutoSaveFile(); + + ShowPlayAgainMenu(); + } + /// <summary> /// Shows the play again menu on the console /// </summary> @@ -402,6 +434,36 @@ namespace Controller } } + /// <summary> + /// If the user wants to start a new game or play in his auto-saved one + /// </summary> + private static bool UserDecision() + { + if (File.Exists(MastermindGame.GetAutoSaveFilePath())) + { + while (true) + { + Console.WriteLine("An autosaved game was found. Do you want to continue playing? [Yes/No]"); + string decision = Console.ReadLine(); + decision = decision.ToLower(); + if (decision == "yes" || decision == "ye" || decision == "y") + { + return false; // bool newGame -> false + } + if (decision == "no" || decision == "n") + { + return true; // bool newGame -> true + } + Console.WriteLine("Error! Please choose by writing \"Yes\" or \"No\" "); + } + } + return true; + } + + /// <summary> + /// Prints the saved games + /// </summary> + /// <param name="numberOfGames">How many last games the user wants to see</param> public void ShowLastGames(int numberOfGames = 5) { string filePath = MastermindGame.GetSaveFilePath(); @@ -450,32 +512,13 @@ namespace Controller Program.MainMenu(true); } - private static bool UserDecision() - { - if (File.Exists(MastermindGame.GetAutoSaveFilePath())) - { - while (true) - { - Console.WriteLine("An autosaved game was found. Do you want to continue playing? [Yes/No]"); - string decision = Console.ReadLine(); - decision = decision.ToLower(); - if (decision == "yes" || decision == "ye" || decision == "y") - { - return false; // bool newGame -> false - } - if (decision == "no" || decision == "n") - { - return true; // bool newGame -> true - } - Console.WriteLine("Error! Please choose by writing \"Yes\" or \"No\" "); - } - } - return true; - } + /// <summary> + /// Saves the game to the leaderboard files + /// </summary> public void SaveLeaderboard() { string LeaderboardPath = $"mastermind_leaderboard_{difficulty}.txt"; - Console.WriteLine("Do you want to save the attampt on the leaderboard? y/n"); + Console.WriteLine("Do you want to save the attempt on the leaderboard? y/n"); string? yn = Console.ReadLine(); //string? allows for null-value if (yn != null) //"filter out" null values to avoid crash { @@ -546,7 +589,11 @@ namespace Controller } } } - public void LeaderboardDisplay() + + /// <summary> + /// Displays Leaderboard + /// </summary> + public void DisplayLeaderboard() { string leaderboardDifficulty = ""; Console.WriteLine("Please select which Leaderboard you want to see:"); @@ -567,6 +614,9 @@ namespace Controller case "h": leaderboardDifficulty = "Hard"; break; + default: + Program.ValidOption(); + break; } } string LeaderboardPath = $"mastermind_leaderboard_{leaderboardDifficulty}.txt"; @@ -606,6 +656,10 @@ namespace Controller } } + + /// <summary> + /// Used to center Text + /// </summary> static string PadCenter(string text, int newWidth, char filler) { int length = text.Length; @@ -627,16 +681,5 @@ namespace Controller return result; } - private void TimerElapsed() - { - Console.Clear(); - Console.WriteLine("Time is up! You didn't guess the code in time."); - game.SaveGame(false); - game.DeleteAutoSaveFile(); - - ShowPlayAgainMenu(); - } - - } } \ No newline at end of file diff --git a/MastermindGame.cs b/MastermindGame.cs index 0b10af9..ac5a161 100644 --- a/MastermindGame.cs +++ b/MastermindGame.cs @@ -17,17 +17,17 @@ namespace Game Green } - private int[] code; - private readonly int code_length; - private readonly bool duplicates; - private readonly bool yellowHints; - private readonly int maxAttempt; - private int currentAttempt; - private int[][] attempts; // Jagged array (array of arrays) to save attempts - private (int guess, Hints hint)[] feedback; - private bool usedTipp; - private bool showTipp; - private int timerDuration; + private int[] code; // Stores the generated code that the user has to guess + private readonly int code_length; + private readonly bool duplicates; // Flag to allow duplicates or not + private readonly bool yellowHints; // Flag to set if yellow Hints should be enabled or not + private readonly int maxAttempt; // Max Attempts a user can use + private int currentAttempt; // Counts the amount of attempts from the user + private int[][] attempts; // Jagged array (array of arrays) to save attempts with the user code + private (int guess, Hints hint)[] feedback; // Saves the hint value for the guess + private bool usedTipp; // Flag if the Tipp was already used or not + private bool showTipp; // Flag to show the Tipp + private int timerDuration; // Amount of time, depending on difficulty (For Timer-Mode) private const string saveFilePath = "mastermind_gamehistorie.txt"; // Folder structure: Mastermind/bin/Debug/net8.0 private const string autoSaveFilePath = "mastermind_autosave.txt"; @@ -37,7 +37,7 @@ namespace Game /// </summary> public MastermindGame(string difficulty) { - DifficultySetup(difficulty, out code_length, out duplicates, out yellowHints, out maxAttempt, out usedTipp); + SetupDifficulty(difficulty, out code_length, out duplicates, out yellowHints, out maxAttempt, out usedTipp); currentAttempt = 0; attempts = new int[maxAttempt][]; feedback = new (int, Hints)[code_length]; @@ -60,7 +60,7 @@ namespace Game /// </param> public MastermindGame(string difficulty, bool newGame) { - DifficultySetup(difficulty, out code_length, out duplicates, out yellowHints, out maxAttempt, out usedTipp); + SetupDifficulty(difficulty, out code_length, out duplicates, out yellowHints, out maxAttempt, out usedTipp); // Starts a new Game or loads a old save // (newGame = false -> Trys to load old game; newGame = true -> Starts a new Game) if (newGame) @@ -97,14 +97,11 @@ namespace Game AutoSaveGame(); } } - - // Debugging (Gets removed later) - foreach (int zahl in code) - { - Console.WriteLine($"{zahl} "); - } } + /// <summary> + /// Initializes arrays + /// </summary> private void SetupGame() { attempts = new int[maxAttempt][]; feedback = new (int, Hints)[code_length]; @@ -117,7 +114,10 @@ namespace Game currentAttempt = 0; } - private void DifficultySetup(string difficulty, out int code_length, out bool duplicates, out bool yellowHints, out int maxAttempt, out bool usedTipp) + /// <summary> + /// Setup important game variables + /// </summary> + private void SetupDifficulty(string difficulty, out int code_length, out bool duplicates, out bool yellowHints, out int maxAttempt, out bool usedTipp) { switch (difficulty.ToLower()) { @@ -125,25 +125,25 @@ namespace Game code_length = 4; duplicates = false; yellowHints = true; - maxAttempt = 6; + maxAttempt = 10; usedTipp = true; // No Tipp available for easy - timerDuration = 120000; // 2 minutes + timerDuration = (5 * 60000); // First number for minutes break; case "medium": code_length = 6; duplicates = false; yellowHints = true; - maxAttempt = 4; - usedTipp = false; - timerDuration = 60000; // 1 minute + maxAttempt = 8; + usedTipp = false; // Tipp available for hard + timerDuration = (5 * 60000); // First number for minutes break; case "hard": code_length = 8; duplicates = true; yellowHints = false; - maxAttempt = 3; - usedTipp = true; // No Tipp available for hard - timerDuration = 30000; // 30 seconds + maxAttempt = 8; + usedTipp = false; // Tipp available for hard + timerDuration = (10 * 60000); // First number for minutes break; default: throw new ArgumentException("Invalid difficulty level"); @@ -295,7 +295,6 @@ namespace Game } else { - Console.WriteLine("You used your Tipp"); showTipp = false; } @@ -311,6 +310,9 @@ namespace Game } } + /// <summary> + /// Random chooses a position in the code + /// </summary> private int GiveTipp() { Random rnd = new Random(); @@ -370,7 +372,7 @@ namespace Game // Shows hints Console.Write($"{"Recieved Hints:",-24}"); - for (int i = 0; i < feedback.GetLength(0); i++) + for (int i = 0; i < feedback.Length; i++) { if (feedback[i].hint == Hints.Green) { @@ -420,12 +422,6 @@ namespace Game GetHint(input); currentAttempt++; AutoSaveGame(); - - for (int i = 0; i < feedback.GetLength(0); i++) - { - Console.WriteLine($"Zahl: {feedback[i].guess}, Hinweis: {feedback[i].hint}"); - } - } /// <summary> @@ -463,7 +459,6 @@ namespace Game } catch (Exception e) { - Console.WriteLine($"Error! Something went wrong while auto-saving: {e.Message}"); ; } } @@ -569,11 +564,32 @@ namespace Game } } + /// <summary> + /// Gives back if you have attempts left or not + /// </summary> public bool StillHasTrials() { return currentAttempt < maxAttempt; } + /// <summary> + /// Fixes problemes for the mulitplayer + /// </summary> + public void ResetAttempts() + { + currentAttempt = 0; + attempts = new int[maxAttempt][]; + for (int i = 0; i < maxAttempt; i++) + { + attempts[i] = new int[code_length]; + } + } + + public void SetCode(int[] newCode) + { + code = newCode; + } + public int GetCodeLength() { return code_length; @@ -603,24 +619,11 @@ namespace Game { return code; } + public int GetUsedAtt() { return maxAttempt - currentAttempt; } - public void SetCode(int[] newCode) - { - code = newCode; - } - - public void ResetAttempts() - { - currentAttempt = 0; - attempts = new int[maxAttempt][]; - for (int i = 0; i < maxAttempt; i++) - { - attempts[i] = new int[code_length]; - } - } public int GetTimerDuration() { diff --git a/Program.cs b/Program.cs index 64848b7..fff03a5 100644 --- a/Program.cs +++ b/Program.cs @@ -1,5 +1,4 @@ using System; -using System.Data; using Controller; namespace Mastermind @@ -45,7 +44,7 @@ namespace Mastermind break; case "l": Console.Clear(); - controller.LeaderboardDisplay(); + controller.DisplayLeaderboard(); break; case "q": Console.WriteLine("Are you sure that you want to quit? Confirm with [Q] to go back to the Main menu press any other Key."); @@ -84,30 +83,31 @@ namespace Mastermind } } } - public static void MainMenu(bool menu) - { - Console.Clear(); - Console.WriteLine("\n███╗ ███╗ █████╗ ███████╗████████╗███████╗██████╗ ███╗ ███╗██╗███╗ ██╗██████╗"); - Console.WriteLine("████╗ ████║██╔â•â•â–ˆâ–ˆâ•—██╔â•â•â•â•â•â•šâ•â•â–ˆâ–ˆâ•”â•â•â•â–ˆâ–ˆâ•”â•â•â•â•â•â–ˆâ–ˆâ•”â•â•â–ˆâ–ˆâ•—████╗ ████║██║████╗ ██║██╔â•â•â–ˆâ–ˆâ•—"); - Console.WriteLine("██╔████╔██║███████║███████╗ ██║ █████╗ ██████╔â•â–ˆâ–ˆâ•”████╔██║██║██╔██╗ ██║██║ ██║"); - Console.WriteLine("██║╚██╔â•â–ˆâ–ˆâ•‘██╔â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘ ██║ ██╔â•â•â• ██╔â•â•â–ˆâ–ˆâ•—██║╚██╔â•â–ˆâ–ˆâ•‘██║██║╚██╗██║██║ ██║"); - Console.WriteLine("██║ â•šâ•â• ██║██║ ██║███████║ ██║ ███████╗██║ ██║██║ â•šâ•â• ██║██║██║ ╚████║██████╔â•"); - Console.WriteLine("â•šâ•â• â•šâ•â•â•šâ•â• â•šâ•â•â•šâ•â•â•â•â•â•â• â•šâ•â• â•šâ•â•â•â•â•â•â•â•šâ•â• â•šâ•â•â•šâ•â• â•šâ•â•â•šâ•â•â•šâ•â• â•šâ•â•â•â•â•šâ•â•â•â•â•â•"); - if (menu) - { - Console.WriteLine("\nPlease Choose:"); - Console.WriteLine("[S]tart Game"); - Console.WriteLine("[T]utorial"); - Console.WriteLine("[P]reviously saved Games"); - Console.WriteLine("[L]eaderboard"); - Console.WriteLine("[Q]uit"); - } + public static void MainMenu(bool menu) + { + Console.Clear(); + Console.WriteLine("\n███╗ ███╗ █████╗ ███████╗████████╗███████╗██████╗ ███╗ ███╗██╗███╗ ██╗██████╗"); + Console.WriteLine("████╗ ████║██╔â•â•â–ˆâ–ˆâ•—██╔â•â•â•â•â•â•šâ•â•â–ˆâ–ˆâ•”â•â•â•â–ˆâ–ˆâ•”â•â•â•â•â•â–ˆâ–ˆâ•”â•â•â–ˆâ–ˆâ•—████╗ ████║██║████╗ ██║██╔â•â•â–ˆâ–ˆâ•—"); + Console.WriteLine("██╔████╔██║███████║███████╗ ██║ █████╗ ██████╔â•â–ˆâ–ˆâ•”████╔██║██║██╔██╗ ██║██║ ██║"); + Console.WriteLine("██║╚██╔â•â–ˆâ–ˆâ•‘██╔â•â•â–ˆâ–ˆâ•‘â•šâ•â•â•â•â–ˆâ–ˆâ•‘ ██║ ██╔â•â•â• ██╔â•â•â–ˆâ–ˆâ•—██║╚██╔â•â–ˆâ–ˆâ•‘██║██║╚██╗██║██║ ██║"); + Console.WriteLine("██║ â•šâ•â• ██║██║ ██║███████║ ██║ ███████╗██║ ██║██║ â•šâ•â• ██║██║██║ ╚████║██████╔â•"); + Console.WriteLine("â•šâ•â• â•šâ•â•â•šâ•â• â•šâ•â•â•šâ•â•â•â•â•â•â• â•šâ•â• â•šâ•â•â•â•â•â•â•â•šâ•â• â•šâ•â•â•šâ•â• â•šâ•â•â•šâ•â•â•šâ•â• â•šâ•â•â•â•â•šâ•â•â•â•â•â•"); + if (menu) + { + Console.WriteLine("\nPlease Choose:"); + Console.WriteLine("[S]tart Game"); + Console.WriteLine("[T]utorial"); + Console.WriteLine("[P]reviously saved Games"); + Console.WriteLine("[L]eaderboard"); + Console.WriteLine("[Q]uit"); } + + } public static void ValidOption() { - Console.WriteLine("Please pick a valid Option."); + Console.WriteLine("Error! Please pick a valid Option."); } } diff --git a/PseudoRandomGenerator.cs b/PseudoRandomGenerator.cs deleted file mode 100644 index dd66d5b..0000000 --- a/PseudoRandomGenerator.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; - -namespace PseudoRandomGenerator -{ - /// <summary> - /// Linear Congruential Generator (LCG) for pseudo-random number generation without using the built-in Random class - /// </summary> - public class LCG - { - private long a = 1664525; // Multiplier - private long c = 1013904223; // Increment - private long m = 4294967296L; // Modulus (2^32 for a large cycle) - - private long seed; // Current state (initialized by seed) - - /// <summary> - /// Initializes the LCG with a specified seed to start sequence - /// </summary> - /// <param name="seed">Initial value for generating the sequence (e.g., DateTime.Now.Ticks)</param> - public LCG(long seed) - { - this.seed = seed; - } - - /// <summary> - /// Generates the next pseudo-random number in the sequence - /// </summary> - /// <returns>A pseudo-random number based on the internal LCG algorithm</returns> - public long Next() - { - // Update the seed using the LCG-formula - seed = (a * seed + c) % m; - return seed; - } - - /// <summary> - /// Generates a pseudo-random integer within a specified range (min, max) - /// </summary> - /// <param name="min">The inclusive lower bound of the random number</param> - /// <param name="max">The exclusive upper bound of the random number</param> - /// <returns>A pseudo-random integer between min and max</returns> - public int Next(int min, int max) - { - long nextValue = Next(); - //Checks if the number is negative - if(nextValue < 0) - { - // Adds modulo to prevent negative random numbers - nextValue += m; - } - // Map the result of Next() to the specified range - return (int)(nextValue % (max - min)) + min; - } - - } -} -- GitLab