Option Compare Text Public Class Game ' This Dictionary holds the corresponding value for each of the variants of "YES" and "NO" we accept ' Note that the Dictionary is case-insensitive, meaning it maps "YES", "yes" and even "yEs" to True Private Shared ReadOnly YesNoResponses As New Dictionary(Of String, Boolean)(StringComparer.InvariantCultureIgnoreCase) From { {"yes", True}, {"y", True}, {"true", True}, {"t", True}, {"1", True}, {"no", False}, {"n", False}, {"false", False}, {"f", False}, {"0", False} } ReadOnly console As ConsoleAdapterBase ' The pre-initialized root branch ReadOnly root As New Branch With { .Text = "DOES IT SWIM?", .Yes = New Branch With {.Text = "FISH"}, .No = New Branch With {.Text = "BIRD"} } ''' Reduces a string or console input to True, False or Nothing. Case-insensitive. ''' Optional String to reduce via the same logic. If not passed in, will use console.ReadLine ''' ''' Returns True for a "yes" response (yes, y, true, t, 1) and False for a "no" response (no, n, false, f, 0).
''' Returns Nothing if the response doesn't match any of these. '''
Private Function GetYesNo(Optional s As String = Nothing) As Boolean? s = If(s, console.ReadLine) Dim ret As Boolean If YesNoResponses.TryGetValue(s, ret) Then Return ret Return Nothing End Function Sub New(console As ConsoleAdapterBase) If console Is Nothing Then Throw New ArgumentNullException(NameOf(console)) Me.console = console End Sub Sub BeginLoop() ' Print the program heading console.WriteCenteredLines( "ANIMAL CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") ' Print the program description console.Write( " PLAY 'GUESS THE ANIMAL' THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT. ") Do console.Write("ARE YOU THINKING OF AN ANIMAL? ") Dim response = console.ReadLine If response = "list" Then ' List all the stored animals console.Write( " ANIMALS I ALREADY KNOW ARE: ") ' We're using a ForEach extension method instead of the regular For Each loop to provide the index alongside the text root.DescendantTexts.ForEach(Sub(text, index) ' We want to move to the next line after every four animals ' But for the first animal, where the index is 0, 0 Mod 4 will also return 0 ' So we have to explicitly exclude the first animal If index > 0 AndAlso index Mod 4 = 0 Then console.WriteLine() console.Write($"{text.MaxLength(15),-15}") End Sub) console.Write( " ") Continue Do End If Dim ynResponse = GetYesNo(response) If ynResponse Is Nothing OrElse Not ynResponse Then Continue Do Dim currentBranch = root Do While Not currentBranch.IsEnd ' Branches can either be questions, or end branches ' We have to walk the questions, prompting each time for "yes" or "no" console.Write($"{currentBranch.Text} ") Do ynResponse = GetYesNo() Loop While ynResponse Is Nothing ' Depending on the answer, we'll follow either the branch at "Yes" or "No" currentBranch = If( ynResponse, currentBranch.Yes, currentBranch.No ) Loop ' Now we're at an end branch console.Write($"IS IT A {currentBranch.Text}? ") ynResponse = GetYesNo() If ynResponse Then ' Only if ynResponse = True will we go into this If Then block ' The computer guessed the animal; we can go back to the beginning of the game console.WriteLine("WHY NOT TRY ANOTHER ANIMAL?") Continue Do End If ' Get the new animal from the user console.Write("THE ANIMAL YOU WERE THINKING OF WAS A ? ") Dim newAnimal = console.ReadLine.ToUpperInvariant ' Get the question used to distinguish the new animal from the current end branch console.Write( $"PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A {newAnimal} FROM A {currentBranch.Text} ") Dim newQuestion = console.ReadLine.ToUpperInvariant ' Get the answer to that question, for the new animal ' for the old animal, the answer will be the opposite console.Write($"FOR A {newAnimal} THE ANSWER WOULD BE? ") Do ynResponse = GetYesNo() Loop While ynResponse Is Nothing ' Create the new end branch for the new animal Dim newBranch = New Branch With {.Text = newAnimal} ' Copy over the current animal to another new end branch Dim currentBranchCopy = New Branch With {.Text = currentBranch.Text} ' Make the current branch into the distinguishing question currentBranch.Text = newQuestion ' Set the Yes and No branches of the current branch according to the answer If ynResponse Then currentBranch.Yes = newBranch currentBranch.No = currentBranchCopy Else currentBranch.No = newBranch currentBranch.Yes = currentBranchCopy End If ' TODO how do we exit? Loop End Sub End Class