From dfc50358b089a5a3d3eea300aa8dc108651b4447 Mon Sep 17 00:00:00 2001 From: James Curran Date: Fri, 19 Feb 2021 23:27:33 -0500 Subject: [PATCH] Added 05 Bagels for C# --- .gitignore | 16 +-- 05 Bagels/csharp/BagelNumber.cs | 121 +++++++++++++++++ 05 Bagels/csharp/Bagels.csproj | 13 ++ 05 Bagels/csharp/Game.cs | 124 ++++++++++++++++++ 05 Bagels/csharp/GameBase.cs | 39 ++++++ 05 Bagels/csharp/Program.cs | 14 ++ .../basic-computer-games-dot-net.sln | 12 ++ 7 files changed, 327 insertions(+), 12 deletions(-) create mode 100644 05 Bagels/csharp/BagelNumber.cs create mode 100644 05 Bagels/csharp/Bagels.csproj create mode 100644 05 Bagels/csharp/Game.cs create mode 100644 05 Bagels/csharp/GameBase.cs create mode 100644 05 Bagels/csharp/Program.cs diff --git a/.gitignore b/.gitignore index 53e00acd..6d177f9e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,4 @@ -################################################################################ -# This .gitignore file was automatically created by Microsoft(R) Visual Studio. -################################################################################ - -/01 Acey Ducey/csharp/obj -/47 Hi-Lo/csharp/obj -/.vs -/33 Dice/csharp/obj -/01 Acey Ducey/csharp/.vs/AceyDucey -/01 Acey Ducey/csharp/bin/Debug/netcoreapp3.1 -/33 Dice/csharp/bin/Debug/net5.0 -/basic-computer-games-dot-net/.vs/basic-computer-games-dot-net/v16 +/**/obj/ +/**/.vs/ +/**/bin/ +/**/*.user diff --git a/05 Bagels/csharp/BagelNumber.cs b/05 Bagels/csharp/BagelNumber.cs new file mode 100644 index 00000000..2fd660e9 --- /dev/null +++ b/05 Bagels/csharp/BagelNumber.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace BasicComputerGames.Bagels +{ + public enum BagelValidation + { + Valid, + WrongLength, + NotUnique, + NonDigit + }; + public class BagelNumber + { + private static readonly Random Rnd = new Random(); + + private readonly int[] _digits; + public override string ToString() + { + return String.Join('-', _digits); + } + + public static BagelNumber CreateSecretNumber(int numDigits) + { + if (numDigits < 3 || numDigits > 9) + throw new ArgumentOutOfRangeException(nameof(numDigits), + "Number of digits must be between 3 and 9, inclusive"); + + var digits = GetDigits(numDigits); + return new BagelNumber(digits); + } + + + + public static BagelValidation IsValid(string number, int length) + { + if (number.Length != length) + return BagelValidation.WrongLength; + + if (!number.All(Char.IsDigit)) + return BagelValidation.NonDigit; + + if (new HashSet(number).Count != length) + return BagelValidation.NotUnique; + + return BagelValidation.Valid; + } + + public BagelNumber(string number) + { + if (number.Any(d => !Char.IsDigit(d))) + throw new ArgumentException("Number must be all unique digits", nameof(number)); + + _digits = number.Select(d => d - '0').ToArray(); + } + + //public BagelNumber(long number) + //{ + // var digits = new List(); + // if (number >= 1E10) + // throw new ArgumentOutOfRangeException(nameof(number), "Number can be no more than 9 digits"); + + // while (number > 0) + // { + // long num = number / 10; + // int digit = (int)(number - (num * 10)); + // number = num; + // digits.Add(digit); + // } + + // _digits = digits.ToArray(); + //} + + public BagelNumber(int[] digits) + { + _digits = digits; + } + + private static int[] GetDigits(int numDigits) + { + int[] digits = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + Shuffle(digits); + return digits.Take(numDigits).ToArray(); + + } + + private static void Shuffle(int[] digits) + { + for (int i = digits.Length - 1; i > 0; --i) + { + int pos = Rnd.Next(i); + var t = digits[i]; + digits[i] = digits[pos]; + digits[pos] = t; + } + + } + + public (int pico, int fermi) CompareTo(BagelNumber other) + { + int pico = 0; + int fermi = 0; + for (int i = 0; i < _digits.Length; i++) + { + for (int j = 0; j < other._digits.Length; j++) + { + if (_digits[i] == other._digits[j]) + { + if (i == j) + ++fermi; + else + ++pico; + } + } + } + + return (pico, fermi); + } + } +} \ No newline at end of file diff --git a/05 Bagels/csharp/Bagels.csproj b/05 Bagels/csharp/Bagels.csproj new file mode 100644 index 00000000..68fa11ec --- /dev/null +++ b/05 Bagels/csharp/Bagels.csproj @@ -0,0 +1,13 @@ + + + + Exe + net5.0 + BasicComputerGames.Bagels + + + + + + + diff --git a/05 Bagels/csharp/Game.cs b/05 Bagels/csharp/Game.cs new file mode 100644 index 00000000..f6885464 --- /dev/null +++ b/05 Bagels/csharp/Game.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace BasicComputerGames.Bagels +{ + public class Game : GameBase + { + public void GameLoop() + { + DisplayIntroText(); + int points = 0; + do + { + var result =PlayRound(); + if (result) + ++points; + } while (TryAgain()); + + Console.WriteLine(); + Console.WriteLine($"A {points} point Bagels buff!!"); + Console.WriteLine("Hope you had fun. Bye."); + } + + private const int Length = 3; + private const int MaxGuesses = 20; + + private bool PlayRound() + { + var secret = BagelNumber.CreateSecretNumber(Length); + Console.WriteLine("O.K. I have a number in mind."); + for (int guessNo = 1; guessNo <= MaxGuesses; ++guessNo) + { + string strGuess; + BagelValidation isValid; + do + { + Console.WriteLine($"Guess #{guessNo}"); + strGuess = Console.ReadLine(); + isValid = BagelNumber.IsValid(strGuess, Length); + PrintError(isValid); + } while (isValid != BagelValidation.Valid); + + var guess = new BagelNumber(strGuess); + var fermi = 0; + var pico = 0; + (pico, fermi) = secret.CompareTo(guess); + if(pico + fermi == 0) + Console.Write("BAGELS!"); + else if (fermi == Length) + { + Console.WriteLine("You got it!"); + return true; + } + else + { + PrintList("Pico ", pico); + PrintList("Fermi ", fermi); + } + Console.WriteLine(); + } + + Console.WriteLine("Oh, well."); + Console.WriteLine($"That's {MaxGuesses} guesses. My Number was {secret}"); + + return false; + + } + + private void PrintError(BagelValidation isValid) + { + switch (isValid) + { + case BagelValidation.NonDigit: + Console.WriteLine("What?"); + break; + + case BagelValidation.NotUnique: + Console.WriteLine("Oh, I forgot to tell you that the number I have in mind has no two digits the same."); + break; + + case BagelValidation.WrongLength: + Console.WriteLine($"Try guessing a {Length}-digit number."); + break; + + case BagelValidation.Valid: + break; + } + } + + private void PrintList(string msg, int repeat) + { + for(int i=0; i + /// Prompt the player to try again, and wait for them to press Y or N. + /// + /// Returns true if the player wants to try again, false if they have finished playing. + protected bool TryAgain() + { + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine("Would you like to try again? (Press 'Y' for yes or 'N' for no)"); + + Console.ForegroundColor = ConsoleColor.Yellow; + Console.Write("> "); + + char pressedKey; + // Keep looping until we get a recognised input + do + { + // Read a key, don't display it on screen + ConsoleKeyInfo key = Console.ReadKey(true); + // Convert to upper-case so we don't need to care about capitalisation + pressedKey = Char.ToUpper(key.KeyChar); + // Is this a key we recognise? If not, keep looping + } while (pressedKey != 'Y' && pressedKey != 'N'); + // Display the result on the screen + Console.WriteLine(pressedKey); + + // Return true if the player pressed 'Y', false for anything else. + return (pressedKey == 'Y'); + } + + } +} \ No newline at end of file diff --git a/05 Bagels/csharp/Program.cs b/05 Bagels/csharp/Program.cs new file mode 100644 index 00000000..5dd0949a --- /dev/null +++ b/05 Bagels/csharp/Program.cs @@ -0,0 +1,14 @@ +namespace BasicComputerGames.Bagels +{ + public class Program + { + public static void Main(string[] args) + { + // Create an instance of our main Game class + var game = new Game(); + + // Call its GameLoop function. This will play the game endlessly in a loop until the player chooses to quit. + game.GameLoop(); + } + } +} diff --git a/basic-computer-games-dot-net/basic-computer-games-dot-net.sln b/basic-computer-games-dot-net/basic-computer-games-dot-net.sln index a5b03908..f32f088d 100644 --- a/basic-computer-games-dot-net/basic-computer-games-dot-net.sln +++ b/basic-computer-games-dot-net/basic-computer-games-dot-net.sln @@ -21,6 +21,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{04298E EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "hi-lo", "..\47 Hi-Lo\csharp\hi-lo.csproj", "{9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "05 Bagels", "05 Bagels", "{946C0E7C-8A83-4C7F-9959-1AF0AEF4A027}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{91DA95EE-DD42-4AEC-A886-07F834061BFC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bagels", "..\05 Bagels\csharp\Bagels.csproj", "{DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +45,10 @@ Global {9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B8FB4D6-EB62-47CC-A89D-96D330E96FF6}.Release|Any CPU.Build.0 = Release|Any CPU + {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -50,6 +60,8 @@ Global {26D086DE-0BBD-4A18-AC63-2476A7DB52D3} = {AC302ACD-C3B2-460D-BA1A-0A511C36A848} {04298EE8-0EF3-475C-9427-E04C267BBEFB} = {A2BC8E4A-B977-46A6-B897-7E675ACB96F0} {9B8FB4D6-EB62-47CC-A89D-96D330E96FF6} = {04298EE8-0EF3-475C-9427-E04C267BBEFB} + {91DA95EE-DD42-4AEC-A886-07F834061BFC} = {946C0E7C-8A83-4C7F-9959-1AF0AEF4A027} + {DC32ED10-ACEA-4B09-8B2A-54E1F7277C0A} = {91DA95EE-DD42-4AEC-A886-07F834061BFC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {703D538E-7F20-4DD0-A3DD-7BBE36AC82AF}