From 688058956242e2530963f6a28fb920f036c44823 Mon Sep 17 00:00:00 2001 From: CrystalMoogle Date: Sun, 16 Jul 2023 15:13:43 +0100 Subject: [PATCH] Refactor code to make Game its own Class to split from UI dedicated functions. --- BlackjackGUI/Form1.vb | 294 ------------------ ...rm1.Designer.vb => GameWindow.Designer.vb} | 6 +- BlackjackGUI/{Form1.resx => GameWindow.resx} | 0 BlackjackGUI/GameWindow.vb | 58 ++++ .../My Project/Application.Designer.vb | 2 +- BlackjackGUI/Utilities.vb | 30 ++ BlackjackGUI/game.vb | 191 ++++++++++++ BlackjackGUI/player.vb | 28 ++ 8 files changed, 311 insertions(+), 298 deletions(-) delete mode 100644 BlackjackGUI/Form1.vb rename BlackjackGUI/{Form1.Designer.vb => GameWindow.Designer.vb} (99%) rename BlackjackGUI/{Form1.resx => GameWindow.resx} (100%) create mode 100644 BlackjackGUI/GameWindow.vb create mode 100644 BlackjackGUI/Utilities.vb create mode 100644 BlackjackGUI/game.vb create mode 100644 BlackjackGUI/player.vb diff --git a/BlackjackGUI/Form1.vb b/BlackjackGUI/Form1.vb deleted file mode 100644 index 32a65b5..0000000 --- a/BlackjackGUI/Form1.vb +++ /dev/null @@ -1,294 +0,0 @@ -Public Class Form1 - Inherits Form - - Dim player As New Player() - Dim dealer As New Dealer() - Dim deck As New List(Of String) - Dim gameRunning As Boolean = True - Private Sub StartGame_Click(sender As Object, e As EventArgs) Handles StartGame.Click - PlayGame() - End Sub - Private Sub HitButton_Click(sender As Object, e As EventArgs) Handles HitButton.Click - If gameRunning And player.hand.Count < 5 And player.ingame Then - DealCard(player) - CheckPlayer(player) - End If - End Sub - - Private Sub StandButton_Click(sender As Object, e As EventArgs) Handles StandButton.Click - If gameRunning And player.ingame Then - player.ingame = False - DealerTurn() - End If - End Sub - Private Sub ResetCards() - Dim pictureBoxes() As PictureBox = {PlayerCard1, PlayerCard2, PlayerCard3, PlayerCard4, PlayerCard5, PlayerCard6, PlayerCard7, PlayerCard8, PlayerCard9, PlayerCard10} - For Each box In pictureBoxes - box.Image = Nothing - Next - End Sub - Sub PlayGame() - InitGame() - End Sub - Sub InitGame() - ResetCards() - WinMessage.ResetText() - HitButton.Enabled = True - StandButton.Enabled = True - StartGame.Enabled = False - gameRunning = True - player.Start() - dealer.Start() - CreateDeck() - DealCard(player) - DealCard(dealer, isDealer:=True) - DealCard(player) - DealCard(dealer, isDealer:=True, hide:=True) - GetTotal(dealer) - CheckPlayer(dealer, True) - CheckPlayer(player) - End Sub - Sub CreateDeck() - deck.Clear() - Dim nums As String() = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"} - Dim suits As String() = {"Hearts", "Diamonds", "Spades", "Clubs"} - For Each s As String In suits - For Each n As String In nums - deck.Add(n + " of " + s) - Next - Next - Shuffle(deck) - End Sub - Sub Shuffle(deck) - Dim max As Integer = deck.Count - 1 - Dim random As New Random() - For x As Integer = 0 To max - Dim rand As Integer = random.Next(0, max) - Dim temp As String = deck(x) - deck(x) = deck(rand) - deck(rand) = temp - Next - End Sub - Sub DealCard(player, Optional suppress = False, Optional isDealer = False, Optional hide = False) - Dim card = deck(0) - player.hand.Add(card) - deck.RemoveAt(0) - GetTotal(player, hide) - Dim cardNumber As String = If(isDealer, (player.hand.count + 5).ToString(), player.hand.count) - Dim pictureBox As PictureBox - Try - pictureBox = CType(Me.Controls.Find("PlayerCard" + cardNumber, True).First(), PictureBox) - If hide Then - pictureBox.Image = My.Resources.blue - player.hidden = card - Else - pictureBox.Image = GetCardImage(card) - End If - SetTotalLabels() - Catch ex As Exception - WinMessage.Text = "Error: " + ex.Message - EndGame() - End Try - End Sub - Sub GetTotal(player, Optional hide = False) - If hide Then - Exit Sub - End If - Dim cards As List(Of String) = player.hand - If cards.Count = 0 Then - player.total = 0 - Return - End If - Dim t As Integer = 0 - Dim a As Integer = 0 - For Each x As String In cards - Dim card As String = x - Dim num As String = card.Split(" "c)(0) - If num = "K" Or num = "Q" Or num = "J" Then - num = 10 - End If - If num = "A" Then - num = 11 - a += 1 - End If - num = Integer.Parse(num) - t += num - Next - While (a > 0 And t > 21) - a -= 1 - t = t - 10 - End While - player.total = t - End Sub - Sub SetTotalLabels() - Dim dealerLabelTotal As String = DealerTotal.Text.Split(": ")(0) - Dim playerLabelTotal As String = PlayerTotal.Text.Split(": ")(0) - DealerTotal.Text = dealerLabelTotal + ": " + dealer.total.ToString() - PlayerTotal.Text = playerLabelTotal + ": " + player.total.ToString() - - End Sub - Sub CheckPlayer(playerToCheck, Optional peek = False) - If Not peek Then - If playerToCheck.total = 21 And playerToCheck.hand.count = 2 Then - playerToCheck.winType = WinCondition.Blackjack - playerToCheck.ingame = False - dealer.ingame = False - DealerTurn() - ElseIf playerToCheck.total > 21 Then - playerToCheck.winType = WinCondition.Bust - playerToCheck.ingame = False - DealerTurn() - ElseIf playerToCheck.total < 22 And playerToCheck.hand.count = 5 Then - playerToCheck.winType = WinCondition.FiveCard - playerToCheck.ingame = False - dealer.ingame = False - DealerTurn() - End If - If playerToCheck.total = 21 Then - playerToCheck.ingame = False - DealerTurn() - End If - Else - If playerToCheck.total = 21 And playerToCheck.hand.count = 2 Then - playerToCheck.winType = WinCondition.Blackjack - playerToCheck.ingame = False - player.ingame = False - DealerTurn() - End If - End If - - End Sub - Sub DealerTurn() - PlayerCard7.Image = GetCardImage(dealer.hidden) - GetTotal(dealer) - SetTotalLabels() - If player.winType = WinCondition.Bust Then - CheckGame() - Exit Sub - End If - If dealer.ingame And dealer.hand.Count < 5 Then - If dealer.total = 21 And dealer.hand.Count = 2 Then - dealer.winType = WinCondition.Blackjack - dealer.ingame = False - ElseIf dealer.total > 21 Then - dealer.winType = WinCondition.Bust - player.ingame = False - ElseIf dealer.total < dealer.limit Then - DealCard(dealer, isDealer:=True) - DealerTurn() - Else - dealer.winType = WinCondition.NormalWin - End If - End If - CheckGame() - End Sub - Sub CheckGame() - WinMessage.Text = GetResults() - EndGame() - End Sub - Sub EndGame() - HitButton.Enabled = False - StandButton.Enabled = False - StartGame.Enabled = True - End Sub - Function GetResults() - If dealer.winType = WinCondition.Blackjack Then - If player.winType = WinCondition.Blackjack Then - PrintCurrentGame() - Return "Player ties with Blackjack!" - Else - PrintCurrentGame() - Return "Dealer wins with Blackjack!" - End If - End If - If player.winType = WinCondition.Blackjack Then - PrintCurrentGame() - Return "Player wins with Blackjack!" - End If - If player.winType = WinCondition.FiveCard Then - PrintCurrentGame() - Return "Player wins with Five Card Charlie!" - End If - If player.winType = WinCondition.Bust Then - PrintCurrentGame() - Return "Player busts!" - End If - If dealer.winType = WinCondition.Bust Then - PrintCurrentGame() - Return "Dealer busts!" - End If - If player.total > dealer.total Then - PrintCurrentGame() - Return "Player wins with total of " + player.total.ToString() + "!" - End If - If player.total = dealer.total Then - PrintCurrentGame() - Return "Tie!" - End If - If player.total < dealer.total Then - PrintCurrentGame() - Return "Dealer wins with total of " + dealer.total.ToString() + "!" - End If - PrintCurrentGame() - Return "error" - End Function - Function GetCardImage(card) As Image - Dim num As String = card.split(" ")(0) - Dim suit As String = card.split(" ")(2) - Select Case num - Case "K" - num = "king" - Case "Q" - num = "queen" - Case "J" - num = "jack" - Case "A" - num = "ace" - End Select - - Dim img As String = suit + "_" + num - Return My.Resources.ResourceManager.GetObject(img.ToLower()) - End Function - Sub PrintCurrentGame() - Console.WriteLine("Dealer Hand: " + String.Join(", ", dealer.hand) + " Total: " + dealer.total.ToString()) - Console.WriteLine("Player Hand: " + String.Join(", ", player.hand) + " Total: " + player.total.ToString()) - End Sub - - -End Class - -Public Class Player - Private _winCondition As WinCondition - Public Property hand As New List(Of String) - Public Property total As Integer - Public Property ingame As Boolean - Public Property winType - Get - Return _winCondition - End Get - Set - _winCondition = Value - End Set - End Property - - Sub Start() - hand.Clear() - total = 0 - ingame = True - winType = WinCondition.NormalWin - - End Sub -End Class -Public Class Dealer - Inherits Player - - Public Property limit As Integer = 17 - Public Property hidden As String -End Class - -Enum WinCondition - Bust - NormalWin - FiveCard - Blackjack -End Enum \ No newline at end of file diff --git a/BlackjackGUI/Form1.Designer.vb b/BlackjackGUI/GameWindow.Designer.vb similarity index 99% rename from BlackjackGUI/Form1.Designer.vb rename to BlackjackGUI/GameWindow.Designer.vb index f416f41..6eec7d7 100644 --- a/BlackjackGUI/Form1.Designer.vb +++ b/BlackjackGUI/GameWindow.Designer.vb @@ -1,5 +1,5 @@  -Partial Class Form1 +Partial Class GameWindow Inherits System.Windows.Forms.Form 'Form overrides dispose to clean up the component list. @@ -230,7 +230,7 @@ Partial Class Form1 WinMessage.Size = New Size(0, 30) WinMessage.TabIndex = 15 ' - ' Form1 + ' GameWindow ' AutoScaleMode = AutoScaleMode.Inherit ClientSize = New Size(1264, 681) @@ -251,7 +251,7 @@ Partial Class Form1 Controls.Add(StandButton) Controls.Add(HitButton) MinimumSize = New Size(1280, 720) - Name = "Form1" + Name = "GameWindow" StartPosition = FormStartPosition.CenterScreen Text = "Blackjack" CType(PlayerCard1, ComponentModel.ISupportInitialize).EndInit() diff --git a/BlackjackGUI/Form1.resx b/BlackjackGUI/GameWindow.resx similarity index 100% rename from BlackjackGUI/Form1.resx rename to BlackjackGUI/GameWindow.resx diff --git a/BlackjackGUI/GameWindow.vb b/BlackjackGUI/GameWindow.vb new file mode 100644 index 0000000..ebe944a --- /dev/null +++ b/BlackjackGUI/GameWindow.vb @@ -0,0 +1,58 @@ +Public Class GameWindow + Private WithEvents game As Game + Private Sub StartGame_Click(sender As Object, e As EventArgs) Handles StartGame.Click + game = New Game() + game.Start() + End Sub + Private Sub HitButton_Click(sender As Object, e As EventArgs) Handles HitButton.Click + game.Hit() + End Sub + + Private Sub StandButton_Click(sender As Object, e As EventArgs) Handles StandButton.Click + game.Stand() + End Sub + Private Sub OnResetUI() Handles game.ResetUI + Dim pictureBoxes() As PictureBox = {PlayerCard1, PlayerCard2, PlayerCard3, PlayerCard4, PlayerCard5, PlayerCard6, PlayerCard7, PlayerCard8, PlayerCard9, PlayerCard10} + For Each box In pictureBoxes + box.Image = Nothing + Next + WinMessage.ResetText() + HitButton.Enabled = True + StandButton.Enabled = True + StartGame.Enabled = False + End Sub + + Private Sub OnCardDealt(card As String, cardNumber As String, hide As Boolean) Handles game.CardDealt + Dim pictureBox As PictureBox + Debug.Print(cardNumber) + Try + pictureBox = CType(Me.Controls.Find("PlayerCard" + cardNumber, True).First(), PictureBox) + If hide Then + pictureBox.Image = My.Resources.blue + Else + pictureBox.Image = Utilities.GetCardImage(card) + End If + Catch ex As Exception + EndGame("Error: " + ex.Message) + End Try + End Sub + + Private Sub SetTotalLabels(playerTotalAmount, dealerTotalAmount) Handles game.SetTotalLabels + Dim dealerLabelTotal As String = DealerTotal.Text.Split(": ")(0) + Dim playerLabelTotal As String = PlayerTotal.Text.Split(": ")(0) + DealerTotal.Text = dealerLabelTotal + ": " + dealerTotalAmount.ToString() + PlayerTotal.Text = playerLabelTotal + ": " + playerTotalAmount.ToString() + End Sub + + Private Sub ShowDealerCard(card) Handles game.ShowDealerCard + PlayerCard7.Image = Utilities.GetCardImage(card) + End Sub + Private Sub EndGame(message) Handles game.EndGame + WinMessage.Text = message + HitButton.Enabled = False + StandButton.Enabled = False + StartGame.Enabled = True + End Sub + + +End Class \ No newline at end of file diff --git a/BlackjackGUI/My Project/Application.Designer.vb b/BlackjackGUI/My Project/Application.Designer.vb index 007b31f..d94e675 100644 --- a/BlackjackGUI/My Project/Application.Designer.vb +++ b/BlackjackGUI/My Project/Application.Designer.vb @@ -31,7 +31,7 @@ Namespace My Protected Overrides Sub OnCreateMainForm() - Me.MainForm = Form1 + Me.MainForm = GameWindow End Sub End Class End Namespace diff --git a/BlackjackGUI/Utilities.vb b/BlackjackGUI/Utilities.vb new file mode 100644 index 0000000..796ddfc --- /dev/null +++ b/BlackjackGUI/Utilities.vb @@ -0,0 +1,30 @@ +Public Class Utilities + Public Shared Function Shuffle(list) + Dim max As Integer = list.Count - 1 + Dim random As New Random() + For x As Integer = 0 To max + Dim rand As Integer = random.Next(0, max) + Dim temp As String = list(x) + list(x) = list(rand) + list(rand) = temp + Next + Return list + End Function + Public Shared Function GetCardImage(card) As Image + Dim num As String = card.split(" ")(0) + Dim suit As String = card.split(" ")(2) + Select Case num + Case "K" + num = "king" + Case "Q" + num = "queen" + Case "J" + num = "jack" + Case "A" + num = "ace" + End Select + + Dim img As String = suit + "_" + num + Return My.Resources.ResourceManager.GetObject(img.ToLower()) + End Function +End Class \ No newline at end of file diff --git a/BlackjackGUI/game.vb b/BlackjackGUI/game.vb new file mode 100644 index 0000000..4949fd9 --- /dev/null +++ b/BlackjackGUI/game.vb @@ -0,0 +1,191 @@ +Public Class Game + Public Event ResetUI() + Public Event CardDealt(card, cardNumber, hide) + Public Event SetTotalLabels(playerTotal, dealerTotal) + Public Event ShowDealerCard(card) + Public Event EndGame(winMessage) + + Private player As Player + Private dealer As Dealer + Private deck As New List(Of String) + + Public Sub Start() + + Init() + player.Start() + dealer.Start() + DealCard(player) + DealCard(dealer, isDealer:=True) + DealCard(player) + DealCard(dealer, isDealer:=True, hide:=True) + CheckPlayer(player) + CheckPlayer(dealer, True) + End Sub + Sub Init() + player = New Player() + dealer = New Dealer() + deck = CreateDeck() + RaiseEvent ResetUI() + End Sub + Sub DealCard(playerDealt, Optional isDealer = False, Optional hide = False) + Dim card As String = deck(0) + playerDealt.hand.Add(card) + deck.RemoveAt(0) + GetTotal(playerDealt, hide) + If hide Then + playerDealt.hidden = card + End If + Dim cardNumber As String = If(isDealer, (playerDealt.hand.Count + 5).ToString(), playerDealt.hand.Count) + + RaiseEvent CardDealt(card, cardNumber, hide) + RaiseEvent SetTotalLabels(player.total, dealer.total) + End Sub + Sub GetTotal(playerToCheck, Optional hide = False) + If hide Then + Exit Sub + End If + Dim cards As List(Of String) = playerToCheck.hand + If cards.Count = 0 Then + playerToCheck.total = 0 + Return + End If + Dim total As Integer = 0 + Dim aceTotal As Integer = 0 + For Each card As String In cards + Dim num As String = card.Split(" "c)(0) + If num = "K" Or num = "Q" Or num = "J" Then + num = 10 + End If + If num = "A" Then + num = 11 + aceTotal += 1 + End If + num = Integer.Parse(num) + total += num + Next + While (aceTotal > 0 And total > 21) + aceTotal -= 1 + total -= 10 + End While + playerToCheck.total = total + End Sub + Sub CheckPlayer(playerToCheck, Optional peek = False) + If playerToCheck.total = 21 And playerToCheck.hand.count = 2 And peek Then + playerToCheck.winType = WinCondition.Blackjack + playerToCheck.ingame = False + player.ingame = False + DealerTurn() + Exit Sub + End If + If playerToCheck.total = 21 And playerToCheck.hand.count = 2 Then + playerToCheck.winType = WinCondition.Blackjack + playerToCheck.ingame = False + dealer.ingame = False + DealerTurn() + ElseIf playerToCheck.total > 21 Then + playerToCheck.winType = WinCondition.Bust + playerToCheck.ingame = False + DealerTurn() + ElseIf playerToCheck.total < 22 And playerToCheck.hand.count = 5 Then + playerToCheck.winType = WinCondition.FiveCard + playerToCheck.ingame = False + dealer.ingame = False + DealerTurn() + End If + If playerToCheck.total = 21 Then + playerToCheck.ingame = False + DealerTurn() + End If + + End Sub + Sub DealerTurn() + GetTotal(dealer) + RaiseEvent SetTotalLabels(player.total, dealer.total) + RaiseEvent ShowDealerCard(dealer.hidden) + If player.winType = WinCondition.Bust Then + CheckGame() + Exit Sub + End If + If dealer.ingame And dealer.hand.Count < 5 Then + If dealer.total = 21 And dealer.hand.Count = 2 Then + dealer.winType = WinCondition.Blackjack + dealer.ingame = False + ElseIf dealer.total > 21 Then + dealer.winType = WinCondition.Bust + player.ingame = False + ElseIf dealer.total < dealer.limit Then + DealCard(dealer, isDealer:=True) + DealerTurn() + Else + dealer.winType = WinCondition.NormalWin + End If + End If + CheckGame() + End Sub + Sub Hit() + If player.hand.Count < 5 And player.ingame Then + DealCard(player) + CheckPlayer(player) + End If + End Sub + Sub Stand() + If player.ingame Then + player.ingame = False + DealerTurn() + End If + End Sub + Sub CheckGame() + Dim winMessage As String = GetResults() + RaiseEvent EndGame(winMessage) + End Sub + Function GetResults() + If dealer.winType = WinCondition.Blackjack Then + If player.winType = WinCondition.Blackjack Then + Return "Player ties with Blackjack!" + Else + Return "Dealer wins with Blackjack!" + End If + End If + If player.winType = WinCondition.Blackjack Then + Return "Player wins with Blackjack!" + End If + If player.winType = WinCondition.FiveCard Then + Return "Player wins with Five Card Charlie!" + End If + If player.winType = WinCondition.Bust Then + Return "Player busts!" + End If + If dealer.winType = WinCondition.Bust Then + Return "Dealer busts!" + End If + If player.total > dealer.total Then + Return "Player wins with total of " + player.total.ToString() + "!" + End If + If player.total = dealer.total Then + Return "Tie!" + End If + If player.total < dealer.total Then + Return "Dealer wins with total of " + dealer.total.ToString() + "!" + End If + Return "error" + End Function + Function CreateDeck() + deck.Clear() + Dim nums As String() = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"} + Dim suits As String() = {"Hearts", "Diamonds", "Spades", "Clubs"} + For Each s As String In suits + For Each n As String In nums + deck.Add(n + " of " + s) + Next + Next + Return Utilities.Shuffle(deck) + End Function + +End Class + +Public Enum WinCondition + Bust + NormalWin + FiveCard + Blackjack +End Enum \ No newline at end of file diff --git a/BlackjackGUI/player.vb b/BlackjackGUI/player.vb new file mode 100644 index 0000000..3b36963 --- /dev/null +++ b/BlackjackGUI/player.vb @@ -0,0 +1,28 @@ +Public Class Player + Private _winCondition As WinCondition + Public Property hand As New List(Of String) + Public Property total As Integer + Public Property ingame As Boolean + Public Property winType + Get + Return _winCondition + End Get + Set + _winCondition = Value + End Set + End Property + + Sub Start() + hand.Clear() + total = 0 + ingame = True + winType = WinCondition.NormalWin + + End Sub +End Class +Public Class Dealer + Inherits Player + + Public Property limit As Integer = 17 + Public Property hidden As String +End Class