1 '/**********************************************************************************
\r
3 ' * Copyright 2013 Adrian Lam *
\r
4 ' * Last edited 22/11/2013 *
\r
6 ' **********************************************************************************
\r
7 ' * Blackjack is free software: you can redistribute it and/or modify *
\r
8 ' * it under the terms of the GNU General Public License as published by *
\r
9 ' * the Free Software Foundation; either version 3 of the License, or *
\r
10 ' * (at your option) any later version. *
\r
12 ' * This program is distributed in the hope that it will be useful, *
\r
13 ' * but WITHOUT ANY WARRANTY; without even the implied warrranty of *
\r
14 ' * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
\r
15 ' * GNU General Public License for more details. *
\r
17 ' * You should have received a copy of the GNU General Public License *
\r
18 ' * along with this program. If not, see <http://www.gnu.org/licenses/> *
\r
20 ' **********************************************************************************/
\r
22 Public Class Blackjack
\r
24 Dim AllCards(52) As Boolean ' array to store whether each card has been dealt
\r
25 ' 1-13 is Ace to King of spades, 14-26 is Ace to King of Hearts etc
\r
27 Dim PlayerCards(5) As Integer, PlayerCardCount As Integer, PlayerCardSum As Integer, PlayerCardSoftSum As Integer
\r
29 Dim DealerCards(5) As Integer, DealerCardCount As Integer, DealerCardSum As Integer, DealerCardSoftSum As Integer
\r
31 Dim PlayerSplitCards(5) As Integer, PlayerSplitCount As Integer, PlayerSplitSum As Integer, PlayerSplitSoftSum As Integer
\r
33 Dim SplitStatus As Integer '0 when no split, 1 when playing 1st hand split, 2 when playing 2nd hand
\r
34 Dim Split1Busted As Boolean, Split2Busted As Boolean
\r
36 Private Sub Blackjack_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
\r
40 CmdDoubleDown.Hide()
\r
42 LblStatus.Text = "Enter bet amount and" & Chr(13) & Chr(10) & "click Deal to start"
\r
43 Randomize() 'Seed pseudo-random number generator
\r
52 CmdDoubleDown.Hide()
\r
54 TxtBet.ReadOnly = True
\r
55 For i = 1 To 52 Step 1
\r
58 For i = 1 To 5 Step 1
\r
60 PlayerSplitCards(i) = 0
\r
66 PlayerCardSoftSum = 0
\r
68 DealerCardSoftSum = 0
\r
69 PlayerSplitCount = 0
\r
71 PlayerSplitSoftSum = 0
\r
73 TxtPlayerCard1.Text = ""
\r
74 TxtPlayerCard1.Visible = False
\r
75 TxtPlayerCard2.Text = ""
\r
76 TxtPlayerCard2.Visible = False
\r
77 TxtPlayerCard3.Text = ""
\r
78 TxtPlayerCard3.Visible = False
\r
79 TxtPlayerCard4.Text = ""
\r
80 TxtPlayerCard4.Visible = False
\r
81 TxtPlayerCard5.Text = ""
\r
82 TxtPlayerCard5.Visible = False
\r
84 TxtSplit1.Visible = False
\r
86 TxtSplit2.Visible = False
\r
88 TxtSplit3.Visible = False
\r
90 TxtSplit4.Visible = False
\r
92 TxtSplit5.Visible = False
\r
93 TxtDealerCard1.Text = ""
\r
94 TxtDealerCard1.Visible = False
\r
95 TxtDealerCard2.Text = ""
\r
96 TxtDealerCard2.Visible = False
\r
97 TxtDealerCard3.Text = ""
\r
98 TxtDealerCard3.Visible = False
\r
99 TxtDealerCard4.Text = ""
\r
100 TxtDealerCard4.Visible = False
\r
101 TxtDealerCard5.Text = ""
\r
102 TxtDealerCard5.Visible = False
\r
103 Split1Busted = False
\r
104 Split2Busted = False
\r
107 Private Sub CmdDeal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdDeal.Click
\r
109 '''''BEGIN VALIDATION'''''
\r
110 If Val(TxtTotal.Text) <= 0 Then
\r
111 MsgBox("You have no more money! Click OK to exit program...")
\r
114 If TxtBet.Text = "" Or Not IsNumeric(TxtBet.Text) Or Int(Val(TxtBet.Text)) <= 0 Then
\r
115 MsgBox("Please enter a valid bet value")
\r
118 TxtBet.Text = CStr(Int(Val(TxtBet.Text)))
\r
119 If Val(TxtBet.Text) > Val(TxtTotal.Text) Then
\r
120 MsgBox("You don't have enough money for such a high bet! Please lower your bet value")
\r
123 '''''END VALIDATION'''''
\r
126 TxtTotal.Text = CStr(Val(TxtTotal.Text) - Val(TxtBet.Text))
\r
128 '/**********************************************************************/
\r
132 'BEGIN Deal hole card to dealer
\r
133 DealOneCard(DealerCards, DealerCardCount, DealerCardSum, DealerCardSoftSum)
\r
134 TxtDealerCard1.BackColor = Color.Gray
\r
135 TxtDealerCard1.Visible = True
\r
136 'END Deal hole card to dealer
\r
139 '/**************************************************************************/
\r
141 '''''BEGIN INSURANCE'''''
\r
142 If DealerCards(2) Mod 13 = 1 And Val(TxtTotal.Text) >= Int((Val(TxtBet.Text) + 1) / 2) Then ' If dealer's up card is Ace AND player has enough money Then
\r
143 Dim OptionIns As Integer '6=yes, 7=no
\r
144 OptionIns = MsgBox("Dealer may have blackjack, do you want insurance?", MsgBoxStyle.YesNo Or MsgBoxStyle.DefaultButton1 Or MsgBoxStyle.Exclamation)
\r
145 If OptionIns = 6 And DealerCardSum = 21 Then
\r
146 If PlayerCardSum = 21 Then
\r
147 LblStatus.Text = "Dealer and you both have blackjack, push"
\r
148 TxtTotal.Text = CStr(Int(Val(TxtBet.Text) * 5 / 2) + Val(TxtTotal.Text))
\r
150 LblStatus.Text = "Dealer has blackjack"
\r
151 TxtTotal.Text = CStr(Val(TxtTotal.Text) + Val(TxtBet.Text))
\r
153 DisplayCard(TxtDealerCard1, DealerCards(1))
\r
156 ElseIf OptionIns = 6 And DealerCardSum <> 21 Then
\r
157 LblStatus.Text = "Dealer does not have blackjack"
\r
158 TxtTotal.Text = CStr(Val(TxtTotal.Text) - Int((Val(TxtBet.Text) + 1) / 2))
\r
159 ElseIf OptionIns = 7 And DealerCardSum = 21 Then
\r
160 LblStatus.Text = "Dealer has blackjack"
\r
161 DisplayCard(TxtDealerCard1, DealerCards(1))
\r
166 '''''END INSURANCE'''''
\r
168 '''''BEGIN IF DEALER HAS BLACKJACK'''''
\r
169 If DealerCardSum = 21 Then
\r
170 If PlayerCardSum = 21 Then
\r
171 LblStatus.Text = "Dealer and you both have blackjack, push"
\r
172 TxtTotal.Text = CStr(Val(TxtTotal.Text) + Val(TxtBet.Text))
\r
174 LblStatus.Text = "Dealer has blackjack"
\r
176 DisplayCard(TxtDealerCard1, DealerCards(1))
\r
180 '''''END IF DEALER HAS BLACKJACK'''''
\r
182 '''''BEGIN IF PLAYER HAS BLACKJACK'''''
\r
183 If PlayerCardSum = 21 Then
\r
184 LblStatus.Text = "You have blackjack!"
\r
185 TxtTotal.Text = CStr(Val(TxtTotal.Text) + Int(Val(TxtBet.Text) * 5 / 2))
\r
189 '''''END IF PLAYER HAS BLACKJACK'''''
\r
191 '/**************************************************************************/
\r
195 CmdDoubleDown.Show()
\r
196 If PlayerCards(1) Mod 13 = PlayerCards(2) Mod 13 Then ' If both cards equal Then
\r
201 Function RandBetween(ByVal lower As Integer, ByVal higher As Integer) ' Returns a random integer between lower and higher inclusive
\r
202 Return Int((higher - lower + 1) * Rnd() + lower)
\r
205 Sub DisplayCard(ByRef card As TextBox, ByVal CardValue As Integer)
\r
206 Dim face As String, suit As String = "" ' Initialised to stop the complaint of Visual Studio, syntactically and logically not required
\r
208 card.BackColor = Color.White ' Set the color of the textbox to white
\r
209 If CardValue <> 0 Then
\r
210 Select Case (Int((CardValue - 1) / 13))
\r
213 card.ForeColor = Color.Black ' Set the font color to black
\r
216 card.ForeColor = Color.Red
\r
219 card.ForeColor = Color.Black
\r
222 card.ForeColor = Color.Red
\r
224 Select Case (CardValue Mod 13)
\r
234 face = CStr(CardValue Mod 13)
\r
236 card.Text = suit & Chr(13) & Chr(10) & face
\r
237 card.Visible = True
\r
241 Sub DealOneCard(ByRef PersonCards() As Integer, ByRef PersonCardCount As Integer, ByRef PersonCardSum As Integer, ByRef PersonCardSoftSum As Integer)
\r
242 Dim card As Integer
\r
244 Do ' Ensure that no cards are repeated
\r
245 card = RandBetween(1, 52)
\r
246 Loop Until Not AllCards(card)
\r
247 AllCards(card) = True
\r
249 PersonCardCount = PersonCardCount + 1
\r
250 PersonCards(PersonCardCount) = card
\r
251 PersonCardSum = PersonCardSum + (card Mod 13)
\r
252 ' Now this does not work if the card is A, J, Q or K, so the exceptions are handled below:
\r
254 If PersonCardSoftSum <> 0 Then ' If person has an ace Then
\r
255 PersonCardSoftSum = PersonCardSoftSum + (card Mod 13)
\r
258 Select Case (card Mod 13)
\r
260 PersonCardSum = PersonCardSum + 10
\r
261 If PersonCardSoftSum <> 0 Then ' If person has an ace Then
\r
262 PersonCardSoftSum = PersonCardSoftSum + 10
\r
265 PersonCardSum = PersonCardSum - 1
\r
266 If PersonCardSoftSum <> 0 Then
\r
267 PersonCardSoftSum = PersonCardSoftSum - 1
\r
270 PersonCardSum = PersonCardSum - 2
\r
271 If PersonCardSoftSum <> 0 Then
\r
272 PersonCardSoftSum = PersonCardSoftSum - 2
\r
275 PersonCardSum = PersonCardSum + 10
\r
276 If PersonCardSoftSum = 0 Then ' If person does not already have an ace Then
\r
277 PersonCardSoftSum = PersonCardSum - 10
\r
278 Else ' Person already has an ace
\r
279 PersonCardSum = PersonCardSum - 10
\r
285 DealOneCard(PlayerCards, PlayerCardCount, PlayerCardSum, PlayerCardSoftSum)
\r
286 DisplayCard(TxtPlayerCard1, PlayerCards(1))
\r
287 DisplayCard(TxtPlayerCard2, PlayerCards(2))
\r
288 DisplayCard(TxtPlayerCard3, PlayerCards(3))
\r
289 DisplayCard(TxtPlayerCard4, PlayerCards(4))
\r
290 DisplayCard(TxtPlayerCard5, PlayerCards(5))
\r
294 DealOneCard(DealerCards, DealerCardCount, DealerCardSum, DealerCardSoftSum)
\r
295 ''card 1 skipped because it is hole card
\r
296 DisplayCard(TxtDealerCard2, DealerCards(2))
\r
297 DisplayCard(TxtDealerCard3, DealerCards(3))
\r
298 DisplayCard(TxtDealerCard4, DealerCards(4))
\r
299 DisplayCard(TxtDealerCard5, DealerCards(5))
\r
302 Private Sub CmdHit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdHit.Click
\r
303 CmdDoubleDown.Hide()
\r
305 If SplitStatus = 0 Then ' If player did not split Then
\r
307 If PlayerCardSoftSum > 21 Or (PlayerCardSum > 21 And PlayerCardSoftSum = 0) Then
\r
308 LblStatus.Text = "You busted"
\r
311 ElseIf PlayerCardCount = 5 Then
\r
312 LblStatus.Text = "You win"
\r
313 TxtTotal.Text = CStr(Val(TxtTotal.Text) + 2 * Val(TxtBet.Text))
\r
316 ElseIf PlayerCardSum = 21 Or PlayerCardSoftSum = 21 Then ' Automatically stands if player reaches 21
\r
317 CmdStand.PerformClick()
\r
320 ElseIf SplitStatus = 1 Then ' ElseIf player splitted and is playing the first hand Then
\r
322 If PlayerCardSoftSum > 21 Or (PlayerCardSum > 21 And PlayerCardSoftSum = 0) Then
\r
323 LblStatus.Text = "First hand busted" & Chr(13) & Chr(10) & "Second hand (top)"
\r
324 Split1Busted = True
\r
327 SplitStatus = 2 ' Starts player on second hand
\r
328 ElseIf PlayerCardCount = 5 Then
\r
329 LblStatus.Text = "First hand win" & Chr(13) & Chr(10) & "Second hand (top)"
\r
330 SplitStatus = 2 ' Starts player on second hand
\r
331 ElseIf PlayerCardSum = 21 Or PlayerCardSoftSum = 21 Then ' Automatically stands if player reaches 21
\r
332 CmdStand.PerformClick()
\r
335 Else ' ElseIf player splitted and is playing the second hand Then
\r
337 If PlayerSplitSoftSum > 21 Or (PlayerSplitSum > 21 And PlayerSplitSoftSum = 0) Then
\r
338 LblStatus.Text = "Second hand busted"
\r
339 Split2Busted = True
\r
341 ElseIf PlayerSplitCount = 5 Then
\r
342 LblStatus.Text = LblStatus.Text & "Second hand win" & Chr(13) & Chr(10)
\r
344 ElseIf PlayerSplitSoftSum = 21 Or PlayerSplitSum = 21 Then ' Automatically stands if player reaches 21
\r
345 CmdStand.PerformClick()
\r
351 DealOneCard(PlayerSplitCards, PlayerSplitCount, PlayerSplitSum, PlayerSplitSoftSum)
\r
352 DisplayCard(TxtSplit1, PlayerSplitCards(1))
\r
353 DisplayCard(TxtSplit2, PlayerSplitCards(2))
\r
354 DisplayCard(TxtSplit3, PlayerSplitCards(3))
\r
355 DisplayCard(TxtSplit4, PlayerSplitCards(4))
\r
356 DisplayCard(TxtSplit5, PlayerSplitCards(5))
\r
359 Sub ScoreCalc(ByRef score As Integer, ByVal softsum As Integer, ByVal sum As Integer)
\r
360 If softsum > 21 Or (sum > 21 And softsum = 0) Then ' If busted Then
\r
362 ElseIf sum > 21 And softsum <> 0 Then ' ElseIf sum busted but player has an ace and softsum not busted Then
\r
369 Sub EndSplitHands()
\r
371 If Split1Busted And Split2Busted Then
\r
378 '/***********************************************************/
\r
380 Dim score1 As Integer, score2 As Integer, dealerscore As Integer
\r
382 ScoreCalc(score1, PlayerCardSoftSum, PlayerCardSum)
\r
383 ScoreCalc(score2, PlayerSplitSoftSum, PlayerSplitSum)
\r
384 ScoreCalc(dealerscore, DealerCardSoftSum, DealerCardSum)
\r
387 LblStatus.Text = "First hand busted" & Chr(13) & Chr(10)
\r
388 ElseIf score1 > dealerscore Or (score1 <> 0 And PlayerCardCount = 5) Then
\r
389 LblStatus.Text = "First hand win" & Chr(13) & Chr(10)
\r
390 TxtTotal.Text = CStr(Val(TxtTotal.Text) + 2 * Val(TxtBet.Text))
\r
391 ElseIf score1 = dealerscore Then
\r
392 LblStatus.Text = "First hand push" & Chr(13) & Chr(10)
\r
393 TxtTotal.Text = CStr(Val(TxtTotal.Text) + Val(TxtBet.Text))
\r
395 LblStatus.Text = "First hand lose" & Chr(13) & Chr(10)
\r
399 LblStatus.Text = LblStatus.Text & "Second hand busted" & Chr(13) & Chr(10)
\r
400 ElseIf score2 > dealerscore Or (score2 <> 0 And PlayerSplitCount = 5) Then
\r
401 LblStatus.Text = LblStatus.Text & "Second hand win" & Chr(13) & Chr(10)
\r
402 TxtTotal.Text = CStr(Val(TxtTotal.Text) + 2 * Val(TxtBet.Text))
\r
403 ElseIf score2 = dealerscore Then
\r
404 LblStatus.Text = LblStatus.Text & "Second hand push" & Chr(13) & Chr(10)
\r
405 TxtTotal.Text = CStr(Val(TxtTotal.Text) + Val(TxtBet.Text))
\r
407 LblStatus.Text = LblStatus.Text & "Second hand lose" & Chr(13) & Chr(10)
\r
410 If dealerscore = 0 Then
\r
411 LblStatus.Text = LblStatus.Text & "Dealer Busted" & Chr(13) & Chr(10)
\r
414 '/*********************************************************/
\r
420 DisplayCard(TxtDealerCard1, DealerCards(1)) ' Show the hole card
\r
421 While ((DealerCardSum < 17 And DealerCardSoftSum = 0) Or (DealerCardSoftSum < 17 And DealerCardSoftSum <> 0)) And DealerCardCount < 5 'While dealer has not reached 17
\r
428 TxtBet.ReadOnly = False
\r
431 CmdDoubleDown.Hide()
\r
435 Private Sub CmdStand_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdStand.Click
\r
436 If SplitStatus = 1 Then ' If player splitted and is playing first hand Then
\r
437 SplitStatus = 2 ' Starts player on second hand
\r
440 CmdDoubleDown.Hide()
\r
441 LblStatus.Text = "Second hand (top)"
\r
443 ElseIf SplitStatus = 2 Then ' ElseIf player splitted and is playing second hand Then
\r
446 Else ' player did not split
\r
449 '/*************************************************************************/
\r
451 Dim PlayerScore As Integer = 0, DealerScore As Integer = 0
\r
452 If DealerCardSum > 21 And (DealerCardSoftSum > 21 Or DealerCardSoftSum = 0) Then
\r
453 LblStatus.Text = "Dealer busted"
\r
454 TxtTotal.Text = CStr(Val(TxtTotal.Text) + 2 * Val(TxtBet.Text))
\r
457 ElseIf DealerCardSum > 21 And DealerCardSoftSum <> 0 Then
\r
458 DealerScore = DealerCardSoftSum
\r
460 DealerScore = DealerCardSum
\r
463 If PlayerCardSum > 21 Then PlayerScore = PlayerCardSoftSum Else PlayerScore = PlayerCardSum
\r
465 If PlayerScore > DealerScore Then
\r
466 LblStatus.Text = "You win"
\r
467 TxtTotal.Text = CStr(Val(TxtTotal.Text) + 2 * Val(TxtBet.Text))
\r
469 ElseIf PlayerScore = DealerScore Then
\r
470 LblStatus.Text = "Push"
\r
471 TxtTotal.Text = CStr(Val(TxtTotal.Text) + Val(TxtBet.Text))
\r
474 LblStatus.Text = "You lose"
\r
478 '/*************************************************************************/
\r
483 Private Sub CmdDoubleDown_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdDoubleDown.Click
\r
484 CmdDoubleDown.Hide()
\r
487 Dim SecondBet As String
\r
488 SecondBet = InputBox("Enter second bet value:")
\r
489 While Val(SecondBet) > Val(TxtBet.Text) Or Val(SecondBet) > Val(TxtTotal.Text) Or SecondBet = "" Or Not IsNumeric(SecondBet) Or Int(Val(SecondBet)) <= 0
\r
490 If Val(SecondBet) > Val(TxtBet.Text) Or Val(SecondBet) > Val(TxtTotal.Text) Then
\r
491 SecondBet = InputBox("Second bet too large, please enter another value:")
\r
493 SecondBet = InputBox("Please enter a correct numerical positive integral value:")
\r
496 SecondBet = CStr(Int(Val(SecondBet)))
\r
497 TxtTotal.Text = CStr(Val(TxtTotal.Text) - Val(SecondBet))
\r
502 If PlayerCardSoftSum > 21 Or (PlayerCardSum > 21 And PlayerCardSoftSum = 0) Then
\r
503 LblStatus.Text = "You busted"
\r
510 '/*******************************************************************************/
\r
512 Dim PlayerScore As Integer = 0, DealerScore As Integer = 0
\r
513 If DealerCardSum > 21 And (DealerCardSoftSum > 21 Or DealerCardSoftSum = 0) Then
\r
514 LblStatus.Text = "Dealer busted"
\r
515 TxtTotal.Text = CStr(Val(TxtTotal.Text) + 2 * Val(TxtBet.Text) + 2 * Val(SecondBet))
\r
518 ElseIf DealerCardSum > 21 And DealerCardSoftSum <> 0 Then
\r
519 DealerScore = DealerCardSoftSum
\r
521 DealerScore = DealerCardSum
\r
524 If PlayerCardSum > 21 Then PlayerScore = PlayerCardSoftSum Else PlayerScore = PlayerCardSum
\r
526 If PlayerScore > DealerScore Then
\r
527 LblStatus.Text = "You win"
\r
528 TxtTotal.Text = CStr(Val(TxtTotal.Text) + 2 * Val(TxtBet.Text) + 2 * Val(SecondBet))
\r
530 ElseIf PlayerScore = DealerScore Then
\r
531 LblStatus.Text = "Push"
\r
532 TxtTotal.Text = CStr(Val(TxtTotal.Text) + Val(TxtBet.Text) + Val(SecondBet))
\r
535 LblStatus.Text = "You lose"
\r
539 '/********************************************************************************/
\r
543 Private Sub CmdSplit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdSplit.Click
\r
545 TxtSplit1.Text = TxtPlayerCard2.Text
\r
546 TxtSplit1.Visible = True
\r
547 TxtPlayerCard2.Text = ""
\r
548 TxtPlayerCard2.Visible = False
\r
550 LblStatus.Text = "first hand (bottom)"
\r
551 SplitStatus = 1 ' Starts the player on split on first hand
\r
553 '''''BEGIN set counters'''''
\r
554 PlayerCardSum = PlayerCardSum / 2
\r
555 PlayerCardSoftSum = PlayerCardSoftSum / 2
\r
556 PlayerSplitSum = PlayerCardSum
\r
557 PlayerSplitSoftSum = PlayerCardSoftSum
\r
558 PlayerCardCount = 1
\r
559 PlayerSplitCount = 1
\r
560 PlayerSplitCards(1) = PlayerCards(2)
\r
562 '''''END set counters'''''
\r
568 CmdDoubleDown.Hide()
\r
571 Private Sub CmdRules_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdRules.Click
\r
572 '''''Open a new form with the rules on it'''''
\r
573 Dim rules As New Rules ' Declare the new form
\r
574 rules.Show() ' Show the new form
\r