Files
basic-computer-games/01_Acey_Ducey/vbnet/AceyDucey.vb
0phios 961c762145 Update AceyDucey.vb
- reduce nested do/loop and if/else statements by utilizing subs and functions.
2022-01-21 14:19:16 -04:00

243 lines
8.4 KiB
VB.net

Public Class AceyDucey
''' <summary>
''' Create a single instance of the Random class to be used
''' throughout the program.
''' </summary>
Private ReadOnly Property Rnd As New Random()
''' <summary>
''' Define a varaible to store the the player balance. <br/>
''' Defaults to 0
''' </summary>
''' <remarks>
''' Since <see cref="Integer"/> is a value type, and no value
''' has been explicitly set, the default value of the type is used.
''' </remarks>
Private _balance As Integer
Public Sub New()
DisplayIntroduction()
End Sub
''' <summary>
''' Play multiple games of Acey Ducey until the player chooses to quit.
''' </summary>
Public Sub Play()
Do
PlayGame()
Loop While TryAgain() 'Loop (play again) based on the Boolean value returned by TryAgain
Console.WriteLine("O.K., HOPE YOU HAD FUN!")
End Sub
''' <summary>
''' Play a game of Acey Ducey, which ends when the player balance reaches 0
''' </summary>
Private Sub PlayGame()
_balance = 100 'At the start of the game, set the player balance to 100
Console.WriteLine()
Console.WriteLine($"YOU NOW HAVE {_balance} DOLLARS.")
Do
PlayTurn()
Loop While _balance > 0 'Continue playing while the user has a balance
Console.WriteLine()
Console.WriteLine("SORRY, FRIEND, BUT YOU BLEW YOUR WAD.")
End Sub
''' <summary>
''' Play one turn of Acey Ducey
''' </summary>
''' <remarks>
''' A turn consists of displaying to cards, making a wager
''' and determining the result (win/lose)
''' </remarks>
Private Sub PlayTurn()
Console.WriteLine()
Console.WriteLine("HERE ARE YOUR NEXT TWO CARDS: ")
Dim cards = GetOrderedCards()
For Each card In cards
DisplayCard(card)
Next
Dim wager As Integer = GetWager()
Dim finalCard As Integer = GetCard()
If wager = 0 Then
Console.WriteLine("CHICKEN!!")
Return
End If
DisplayCard(finalCard)
Console.WriteLine()
'''Check if the value of the final card is between the first and second cards.
'''
'''The use of AndAlso is used to short-circuit the evaluation of the IF condition.
'''Short-circuiting means that both sides of the condition do not need to be
'''evaluated. In this case, if the left criteria returns FALSE, the right criteria
'''is ignored and the evaluation result is returned as FALSE.
'''
'''This works because AndAlso requires both condition to return TRUE in order to be
'''evaluated as TRUE. If the first condition is FALSE we already know the evaluation result.
If finalCard >= cards.First() AndAlso finalCard <= cards.Last() Then
Console.WriteLine("YOU WIN!!!")
_balance += wager 'Condensed version of _balance = _balance + wager
Else
Console.WriteLine("SORRY, YOU LOSE.")
_balance -= wager 'Condensed version of _balance = _balance - wager
End If
End Sub
''' <summary>
''' Get two cards in ascending order
''' </summary>
''' <remarks>
''' The original version generates two cards (A and B)
''' If A is greater than or equal to B, both cards are regenerated.
''' <br/><br/>
''' This version generates the two cards, but only regenerates A
''' if A is equal to B. The cards are then returned is ascending order,
''' ensuring that A is less than B (maintaining the original end result)
''' </remarks>
Private Function GetOrderedCards() As Integer()
'''When declaring fixed size arrays in VB.NET you declare the MAX INDEX of the array
'''and NOT the SIZE (number of elements) of the array.
'''As such, card(1) gives you and array with index 0 and index 1, which means
'''the array stores two elements and not one
Dim cards(1) As Integer
cards(0) = GetCard()
cards(1) = GetCard()
'Perform this action as long as the first card is equal to the second card
While cards(0) = cards(1)
cards(0) = GetCard()
End While
Array.Sort(cards) 'Sort the values in ascending order
Return cards
End Function
''' <summary>
''' Get a random number (card) ranked 2 to 14
''' </summary>
Private Function GetCard() As Integer
Return Rnd.Next(2, 15)
End Function
''' <summary>
''' Display the face value of the card
''' </summary>
Private Sub DisplayCard(card As Integer)
Dim output As String
Select Case card
Case 2 To 10
output = card.ToString()
Case 11
output = "JACK"
Case 12
output = "QUEEN"
Case 13
output = "KING"
Case 14
output = "ACE"
Case Else
Throw New ArgumentOutOfRangeException(NameOf(card), "Value must be between 2 and 14")
End Select
Console.WriteLine(output)
End Sub
''' <summary>
''' Prompt the user to make a bet
''' </summary>
''' <remarks>
''' The function will not return until a valid bet is made. <br/>
''' <see cref="Int32.TryParse(String, ByRef Integer)"/> is used to validate that the user input is a valid <see cref="Integer"/>
''' </remarks>
Private Function GetWager() As Integer
Dim wager As Integer
Do
Console.WriteLine()
Console.Write("WHAT IS YOUR BET? ")
Dim input As String = Console.ReadLine()
'''Determine if the user input is an Integer
'''If it is an Integer, store the value in the variable wager
If Not Integer.TryParse(input, wager) Then
Console.WriteLine("SORRY, I DID'T QUITE GET THAT.")
Continue Do 'restart the loop
End If
'Prevent the user from betting more than their current balance
If _balance < wager Then
Console.WriteLine("SORRY, MY FRIEND, BUT YOU BET TOO MUCH.")
Console.WriteLine($"YOU HAVE ONLY {_balance} DOLLARS TO BET.")
Continue Do 'restart the loop
End If
'Prevent the user from betting negative values
If wager < 0 Then
Console.WriteLine("FUNNY GUY! YOU CANNOT MAKE A NEGATIVE BET.")
Continue Do 'restart the loop
End If
Exit Do 'If we get to this line, exit the loop as all above validations passed
Loop
Return wager
End Function
''' <summary>
''' Prompt the user to try again
''' </summary>
''' <remarks>
''' This function will not return until a valid reponse is given
''' </remarks>
Private Function TryAgain() As Boolean
Dim response As String
Do
Console.Write("TRY AGAIN (YES OR NO) ")
response = Console.ReadLine()
If response.Equals("YES", StringComparison.OrdinalIgnoreCase) Then Return True
If response.Equals("NO", StringComparison.OrdinalIgnoreCase) Then Return False
Console.WriteLine("SORRY, I DID'T QUITE GET THAT.")
Loop
End Function
''' <summary>
''' Display the opening title and instructions
''' </summary>
''' <remarks>
''' Refer to
''' <see href="https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/strings/interpolated-strings">
''' Interpolated Strings
''' </see> documentation for the use of $ and { } with strings
''' </remarks>
Private Sub DisplayIntroduction()
Console.WriteLine($"{Space((Console.WindowWidth \ 2) - 10)}ACEY DUCEY CARD GAME")
Console.WriteLine($"{Space((Console.WindowWidth \ 2) - 21)}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
Console.WriteLine("")
Console.WriteLine("")
Console.WriteLine("ACEY-DUCEY IS PLAYED IN THE FOLLOWING MANNER")
Console.WriteLine("THE DEALER (COMPUTER) DEALS TWO CARDS FACE UP")
Console.WriteLine("YOU HAVE AN OPTION TO BET OR NOT BET DEPENDING")
Console.WriteLine("ON WHETHER OR NOT YOU FEEL THE CARD WILL HAVE")
Console.WriteLine("A VALUE BETWEEN THE FIRST TWO.")
Console.WriteLine("IF YOU DO NOT WANT TO BET, INPUT A 0")
Console.WriteLine("")
End Sub
End Class