From 2cf4ad8a73715bb6f7120b381b82c149997a014c Mon Sep 17 00:00:00 2001 From: Joe Walter Date: Sat, 29 May 2021 15:08:32 -0400 Subject: [PATCH] Port banner to C# --- 06 Banner/csharp/banner.cs | 251 +++++++++++++++++++++++++++++++++ 06 Banner/csharp/banner.csproj | 8 ++ 06 Banner/csharp/banner.sln | 25 ++++ 3 files changed, 284 insertions(+) create mode 100644 06 Banner/csharp/banner.cs create mode 100644 06 Banner/csharp/banner.csproj create mode 100644 06 Banner/csharp/banner.sln diff --git a/06 Banner/csharp/banner.cs b/06 Banner/csharp/banner.cs new file mode 100644 index 00000000..6b0ff142 --- /dev/null +++ b/06 Banner/csharp/banner.cs @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace banner +{ + class Banner + { + private int Horizontal { get; set; } + private int Vertical { get; set; } + private bool Centered { get; set; } + private string Character { get; set; } + private string Statement { get; set; } + + // This provides a bit-ended representation of each symbol + // that can be output. Each symbol is defined by 7 parts - + // where each part is an integer value that, when converted to + // the binary representation, shows which section is filled in + // with values and which are spaces. i.e., the 'filled in' + // parts represent the actual symbol on the paper. + Dictionary letters = new Dictionary() + { + {' ', new int[] { 0, 0, 0, 0, 0, 0, 0 } }, + {'A', new int[] {505, 37, 35, 34, 35, 37, 505} }, + {'B', new int[] {512, 274, 274, 274, 274, 274, 239} }, + {'C', new int[] {125, 131, 258, 258, 258, 131, 69} }, + {'D', new int[] {512, 258, 258, 258, 258, 131, 125} }, + {'E', new int[] {512, 274, 274, 274, 274, 258, 258} }, + {'F', new int[] {512, 18, 18, 18, 18, 2, 2} }, + {'G', new int[] {125, 131, 258, 258, 290, 163, 101} }, + {'H', new int[] {512, 17, 17, 17, 17, 17, 512} }, + {'I', new int[] {258, 258, 258, 512, 258, 258, 258} }, + {'J', new int[] {65, 129, 257, 257, 257, 129, 128} }, + {'K', new int[] {512, 17, 17, 41, 69, 131, 258} }, + {'L', new int[] {512, 257, 257, 257, 257, 257, 257} }, + {'M', new int[] {512, 7, 13, 25, 13, 7, 512} }, + {'N', new int[] {512, 7, 9, 17, 33, 193, 512} }, + {'O', new int[] {125, 131, 258, 258, 258, 131, 125} }, + {'P', new int[] {512, 18, 18, 18, 18, 18, 15} }, + {'Q', new int[] {125, 131, 258, 258, 322, 131, 381} }, + {'R', new int[] {512, 18, 18, 50, 82, 146, 271} }, + {'S', new int[] {69, 139, 274, 274, 274, 163, 69} }, + {'T', new int[] {2, 2, 2, 512, 2, 2, 2} }, + {'U', new int[] {128, 129, 257, 257, 257, 129, 128} }, + {'V', new int[] {64, 65, 129, 257, 129, 65, 64} }, + {'W', new int[] {256, 257, 129, 65, 129, 257, 256} }, + {'X', new int[] {388, 69, 41, 17, 41, 69, 388} }, + {'Y', new int[] {8, 9, 17, 481, 17, 9, 8} }, + {'Z', new int[] {386, 322, 290, 274, 266, 262, 260} }, + {'0', new int[] {57, 69, 131, 258, 131, 69, 57} }, + {'1', new int[] {0, 0, 261, 259, 512, 257, 257} }, + {'2', new int[] {261, 387, 322, 290, 274, 267, 261} }, + {'3', new int[] {66, 130, 258, 274, 266, 150, 100} }, + {'4', new int[] {33, 49, 41, 37, 35, 512, 33} }, + {'5', new int[] {160, 274, 274, 274, 274, 274, 226} }, + {'6', new int[] {194, 291, 293, 297, 305, 289, 193} }, + {'7', new int[] {258, 130, 66, 34, 18, 10, 8} }, + {'8', new int[] {69, 171, 274, 274, 274, 171, 69} }, + {'9', new int[] {263, 138, 74, 42, 26, 10, 7} }, + {'?', new int[] {5, 3, 2, 354, 18, 11, 5} }, + {'*', new int[] {69, 41, 17, 512, 17, 41, 69} }, + {'=', new int[] {41, 41, 41, 41, 41, 41, 41} }, + {'!', new int[] {1, 1, 1, 384, 1, 1, 1} }, + {'.', new int[] {1, 1, 129, 449, 129, 1, 1} } + }; + + + /// + /// This displays the provided text on the screen and then waits for the user + /// to enter a integer value greater than 0. + /// + /// Text to display on the screen asking for the input + /// The integer value entered by the user + private int GetNumber(string DisplayText) + { + Console.Write(DisplayText); + string TempStr = Console.ReadLine(); + + Int32.TryParse(TempStr, out int TempInt); + + if (TempInt <= 0) + { + throw new ArgumentException($"{DisplayText} must be greater than zero"); + } + + return TempInt; + } + + /// + /// This displays the provided text on the screen and then waits for the user + /// to enter a Y or N. It cheats by just looking for a 'y' and returning that + /// as true. Anything else that the user enters is returned as false. + /// + /// Text to display on the screen asking for the input + /// Returns true or false + private bool GetBool(string DisplayText) + { + Console.Write(DisplayText); + return (Console.ReadLine().StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); + } + + /// + /// This displays the provided text on the screen and then waits for the user + /// to enter an arbitrary string. That string is then returned 'as-is'. + /// + /// Text to display on the screen asking for the input + /// The string entered by the user. + private string GetString(string DisplayText) + { + Console.Write(DisplayText); + return (Console.ReadLine().ToUpper()); + } + + /// + /// This queries the user for the various inputs needed by the program. + /// + private void GetInput() + { + Horizontal = GetNumber("Horizontal "); + Vertical = GetNumber("Vertical "); + Centered = GetBool("Centered "); + Character = GetString("Character (type 'ALL' if you want character being printed) "); + Statement = GetString("Statement "); + // We don't care about what the user enters here. This is just telling them + // to set the page in the printer. + _ = GetString("Set page "); + } + + /// + /// This prints out a single character of the banner - adding + /// a few blanks lines as a spacer between characters. + /// + private void PrintChar(char ch) + { + // In the trivial case (a space character), just print out the spaces + if (ch.Equals(' ')) + { + Console.WriteLine(new string('\n', 7 * Horizontal)); + return; + } + + // If a specific character to be printed was provided by the user, + // then user that as our ouput character - otherwise take the + // current character + char outCh = Character == "ALL" ? ch : Character[0]; + int[] letter = new int[7]; + try + { + letters[outCh].CopyTo(letter, 0); + } + catch (KeyNotFoundException) + { + throw new KeyNotFoundException($"The provided letter {outCh} was not found in the letters list"); + } + + // New int array declarations default to zeros + // numSections decides how many 'sections' need to be printed + // for a given line of each character + int[] numSections = new int[7]; + // fillInSection decides whether each 'section' of the + // character gets filled in with the character or with blanks + int[] fillInSection = new int[9]; + + // This iterates through each of the parts that make up + // each letter. Each part represents 1 * Horizontal lines + // of actual output. + for (int idx = 0; idx < 7; idx++) + { + // This uses the value in each part to decide which + // sections are empty spaces in the letter or filled in + // spaces. For each section marked with 1 in fillInSection, + // that will correspond to 1 * Vertical characters actually + // being output. + for (int exp = 8; exp >= 0; exp--) + { + if (Math.Pow(2, exp) < letter[idx]) + { + fillInSection[8 - exp] = 1; + letter[idx] -= (int)Math.Pow(2, exp); + if (letter[idx] == 1) + { + // Once we've exhausted all of the sections + // defined in this part of the letter, then + // we marked that number and break out of this + // for loop. + numSections[idx] = 8 - exp; + break; + } + } + } + + // Now that we know which sections of this part of the letter + // are filled in or spaces, we can actually create the string + // to print out. + string lineStr = ""; + + if (Centered) + lineStr += new string(' ', (int)(63 - 4.5 * Vertical) * 1 / 1 + 1); + + for (int idx2 = 0; idx2 <= numSections[idx]; idx2++) + { + lineStr = lineStr + new string(fillInSection[idx2] == 0 ? ' ' : outCh, Vertical); + } + + // Then we print that string out 1 * Horizontal number of times + for (int lineidx = 1; lineidx <= Horizontal; lineidx++) + { + Console.WriteLine(lineStr); + } + } + + // Finally, add a little spacer after each character for readability. + Console.WriteLine(new string('\n', 2 * Horizontal - 1)); + } + + /// + /// This prints the entire banner based in the parameters + /// the user provided. + /// + private void PrintBanner() + { + // Iterate through each character in the statement + foreach (char ch in Statement) + { + PrintChar(ch); + } + + // In the original version, it would print an additional 75 blank + // lines in order to feed the printer paper...don't really need this + // since we're not actually printing. + Console.WriteLine(new string('\n', 75)); + } + + /// + /// Main entry point into the banner class and handles the main loop. + /// + public void Play() + { + GetInput(); + PrintBanner(); + } + } + + class Program + { + static void Main(string[] args) + { + new Banner().Play(); + } + } +} diff --git a/06 Banner/csharp/banner.csproj b/06 Banner/csharp/banner.csproj new file mode 100644 index 00000000..c73e0d16 --- /dev/null +++ b/06 Banner/csharp/banner.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp3.1 + + + diff --git a/06 Banner/csharp/banner.sln b/06 Banner/csharp/banner.sln new file mode 100644 index 00000000..34f63984 --- /dev/null +++ b/06 Banner/csharp/banner.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31321.278 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "banner", "banner.csproj", "{9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E24FA30-F2AC-4BF3-ADFB-92D3F796561C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FF2A268C-9C4A-457F-8733-2E8931E07A1D} + EndGlobalSection +EndGlobal