From db11f064e9e8ca3e62f5c25c689b0b1223ed5eda Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 30 Oct 2021 23:07:50 +1100 Subject: [PATCH] Add imput routines --- 90 Tower/csharp/Tower/UI/Input.cs | 83 ++++++++++++++++++++++++++++++ 90 Tower/csharp/Tower/UI/Prompt.cs | 41 +++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 90 Tower/csharp/Tower/UI/Input.cs create mode 100644 90 Tower/csharp/Tower/UI/Prompt.cs diff --git a/90 Tower/csharp/Tower/UI/Input.cs b/90 Tower/csharp/Tower/UI/Input.cs new file mode 100644 index 00000000..9b2d3747 --- /dev/null +++ b/90 Tower/csharp/Tower/UI/Input.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; + +namespace Tower.UI +{ + // Provides input methods which emulate the BASIC interpreter's keyboard input routines + internal static class Input + { + private static void Prompt(string text = "") => Console.Write($"{text}? "); + + internal static bool ReadYesNo(string prompt, string retryPrompt) + { + var response = ReadString(prompt); + + while (true) + { + if (response.Equals("No", StringComparison.InvariantCultureIgnoreCase)) { return false; } + if (response.Equals("Yes", StringComparison.InvariantCultureIgnoreCase)) { return true; } + response = ReadString(retryPrompt); + } + } + + internal static bool TryReadNumber(Prompt prompt, out int number) + { + var message = prompt.Message; + + for (int retryCount = 0; retryCount <= prompt.RetriesAllowed; retryCount++) + { + if (retryCount > 0) { Console.WriteLine(prompt.RetryMessage); } + + if (prompt.TryValidateResponse(ReadNumber(message), out number)) { return true; } + + if (!prompt.RepeatPrompt) { message = ""; } + } + + Console.WriteLine(prompt.QuitMessage); + + number = 0; + return false; + } + + private static float ReadNumber(string prompt) + { + Prompt(prompt); + + while (true) + { + var inputValues = ReadStrings(); + + if (TryParseNumber(inputValues[0], out var number)) + { + if (inputValues.Length > 1) + { + Console.WriteLine("!Extra input ingored"); + } + + return number; + } + } + } + + private static string ReadString(string prompt) + { + var inputValues = ReadStrings(); + if (inputValues.Length > 1) + { + Console.WriteLine("!Extra input ingored"); + } + return inputValues[0]; + } + + private static string[] ReadStrings() => Console.ReadLine().Split(',', StringSplitOptions.TrimEntries); + + private static bool TryParseNumber(string text, out float number) + { + if (float.TryParse(text, out number)) { return true; } + + Console.WriteLine("!Number expected - retry input line"); + number = default; + return false; + } + } +} diff --git a/90 Tower/csharp/Tower/UI/Prompt.cs b/90 Tower/csharp/Tower/UI/Prompt.cs new file mode 100644 index 00000000..bc83f7a6 --- /dev/null +++ b/90 Tower/csharp/Tower/UI/Prompt.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Linq; +using static Tower.Resources.Strings; + +namespace Tower.UI +{ + internal class Prompt + { + public static Prompt DiskCount = + new(DiskCountPrompt, DiskCountRetry, DiskCountQuit, 1, 2, 3, 4, 5, 6, 7) { RetriesAllowed = 2 }; + + public static Prompt Disk = + new(DiskPrompt, DiskRetry, DiskQuit, 3, 5, 7, 9, 11, 13, 15) { RepeatPrompt = false }; + + public static Prompt Needle = new(NeedlePrompt, NeedleRetry, NeedleQuit, 1, 2, 3); + + private readonly HashSet _validValues; + + private Prompt(string prompt, string retryMessage, string quitMessage, params int[] validValues) + { + Message = prompt; + RetryMessage = retryMessage; + QuitMessage = quitMessage; + _validValues = validValues.ToHashSet(); + RetriesAllowed = 1; + RepeatPrompt = true; + } + + public string Message { get; } + public string RetryMessage { get; } + public string QuitMessage { get; } + public int RetriesAllowed { get; private set; } + public bool RepeatPrompt { get; private set; } + + public bool TryValidateResponse(float number, out int integer) + { + integer = (int)number; + return integer == number && _validValues.Contains(integer); + } + } +} \ No newline at end of file