using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { /// /// Asks the user to guess a number between a certain range and then guesses that number in the fewest possible guesses /// public class NumberGuesser { #region Public Properties /// /// The largest number we ask the user to guess, between 0 and this number /// public int MaximumNumber { get; set; } /// /// The current number of guesses the computer has had /// public int CurrentNumberOfGuesses { get; private set; } /// /// The current known minimum number the user is thinking of /// public int CurrentGuessMinimum { get; private set; } /// /// The current known maximum number the user is thinking of /// public int CurrentGuessMaximum { get; private set; } #endregion #region .ctor /// /// Default constructor /// public NumberGuesser() { // Set default maximum number this.MaximumNumber = 100; } #endregion #region Public Methods /// /// Asks the user to think of a number between 0 and the maximum number /// public void InformUser() { // Ask user to think of a number between 0 and MaximumNumber Console.WriteLine($"I want you to think of a number between 0 and { this.MaximumNumber }. Ok?"); Console.ReadLine(); } /// /// Asks the user a series of questions to discover the number they are thinking of /// public void DiscoverNumber() { // Clear variables to their initial values before a discovery this.CurrentNumberOfGuesses = 0; this.CurrentGuessMinimum = 0; this.CurrentGuessMaximum = this.MaximumNumber / 2; // While the guess isn't the same as the known maximum value while (this.CurrentGuessMinimum != this.CurrentGuessMaximum) { // Increase guess amount (by 1) this.CurrentNumberOfGuesses++; // Ask the user if their number is between the guess range Console.WriteLine($"Is your number between { this.CurrentGuessMinimum } and { this.CurrentGuessMaximum}?"); string response = Console.ReadLine(); // If the user confirmed their number is within the current range... if (response?.ToLower().FirstOrDefault() == 'y') { // We know the number is between guessFrom and guessTo // So set the new maximum number this.MaximumNumber = this.CurrentGuessMaximum; // Change the next guess range to be half of the new maximum range this.CurrentGuessMaximum = this.CurrentGuessMaximum - (this.CurrentGuessMaximum - this.CurrentGuessMinimum) / 2; } // The number is greater than guessMax and less than or equal to max else { // The new minimum is one above the old maximum this.CurrentGuessMinimum = this.CurrentGuessMaximum + 1; // Guess the bottom half of the new range int remainingDifference = this.MaximumNumber - this.CurrentGuessMaximum; // Set the guess max to half way between the guessMin and max // NOTE: Math.Ceiling will round up the remaining difference to 2, if the difference is 3 this.CurrentGuessMaximum += (int)Math.Ceiling(remainingDifference / 2f); } // If we only have 2 numbers left, guess one of them if (this.CurrentGuessMinimum + 1 == this.MaximumNumber) { // Increase guess amount (by 1) this.CurrentNumberOfGuesses++; // Ask the user if their number is the lower number Console.WriteLine($"Is your number { this.CurrentGuessMinimum }?"); response = Console.ReadLine(); // If the user confirmed their number is the lower number... if (response?.ToLower().FirstOrDefault() == 'y') { break; } else { // That means the number must be the higher of the two this.CurrentGuessMinimum = this.MaximumNumber; break; } } } } /// /// Annouces the number the user was thinking of and the number of guesses it took /// public void AnnounceResults() { // Tell the user their number Console.WriteLine($"** Your number is { this.CurrentGuessMinimum } **"); // Let the user know how many guesses it took Console.WriteLine($"Guessed in { this.CurrentNumberOfGuesses } guesses"); Console.ReadLine(); } #endregion } }