### Author Topic: Blackjack  (Read 9604 times)

0 Members and 1 Guest are viewing this topic.

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #210 on: July 07, 2020, 11:20:19 AM »
Over on my iPad, I have a deck shuffling program which is very simple. I create a random array with numbers from 1 to 52, and these numbers serve as an index to another table that holds the card number and suit. I use graphics (UNICODE or the iPad's expanded ASCII Code) and the suit is the same size as the number.

I can bring it over to QB64 and get it to work if you are interested in it. I can even create options where you can create a shuffled array with 4 to 8 decks if you can use it.

Can shuffle be simpler than this from my last code post, from all my code that needs shuffle)?
Code: QB64: [Select]
1.     FOR i = 52 TO 2 STEP -1 'shuffle
2.         SWAP deck\$(INT(RND * i) + 1), deck\$(i)
3.

Welcome aboard George!

#### Cobalt

• Forum Resident
• Posts: 724
• At 60 I become highly radioactive!
##### Re: Blackjack
« Reply #211 on: July 07, 2020, 12:16:13 PM »
So is this like an  official  group project or what? how many different people have added actual material for this? 4-5? or am I just skim reading the wrong parts?
Granted after becoming radioactive I only have a half-life!

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #212 on: July 07, 2020, 12:44:42 PM »
So is this like an  official  group project or what? how many different people have added actual material for this? 4-5? or am I just skim reading the wrong parts?

Hi @Cobalt

Currently I am running code in which you can test your own AI. Started around reply #195. I think we have finished for awhile the beautiful graphics and audio game. (Check Best Answer for the latest on that.)

The AI should be fairly easy to write, just make a Function that returns "h" for hit or "d" for double down anything else is signal to stay.

The players() array name has been changed to p() array and the Dealers player number = nPlayers check code in next reply.

Love to get your input, if you have an idea you can just describe it and I can write it up or take a shot at your own Function.

« Last Edit: July 07, 2020, 01:13:08 PM by bplus »

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #213 on: July 07, 2020, 12:49:29 PM »
I have updated my AI tester for more AI players. Now they overlap when AI players exceed 4 or 5 but we are OK, you can mouse over a certain player and see how they are doing while the Dealer is running the game. Do try and stay out of way of the updating with your mouse.

Code: QB64: [Select]
1. ' No suits shown for cards A is Ace, J, Q, K are Jack, Queen, King, X is for 10
2. '2020-07-05 fix hit (it wasn't broken), delete line card\$ = inkey\$ before loop
3. ' force dealer to hit on 16 stay 17
4. ' ties are push
5. ' bring in double down option
6. ' fix dealer has Blackjack should tell also fix exposing 2nd card
7. ' work this towards converting to multiple AI players, so players stats are all located in PlayerType
8. ' 2020-07-06 Installed AI and mods for it
9. ' 2020-07-06 new Compact Tester with 2nd AI
10. ' 2020-07-06 start Blackjack Multi AI Tester off of Compact Tester
11. '            add in allot of code worked out in Blackjack with Bots 2019-06-07
12. '            Yes, major overhaul of last year bot code which was/is neat!
13. '            Thanks Johnno and Steve for some interesting AI ideas to try!
14. ' 2020-07-07 for Blackjack Multi AI Tester #2, I hope to do something kind of interesting with displaying players
15. '            Yes Mouse over a player you want to check on but try and stay out of way of updating.
16.
17. DEFINT A-Z
18.
19. _TITLE "Blackjack Multi AI Tester #2     Mouse over a player you want to check " ' started 2019-06-06, revisit and match functions with B+J Balckjack with audio and graphics.
20.
21. CONST nPlayers = 9 'dealer counts as the last player   this number depends on how many AI's to test
22. CONST xmax = 800, ymax = 500, margin = 4
23. CONST rank\$ = "A23456789XJQK" 'for building deck and figuring Totals
24. CONST bH = 14, bW = 20 ' box height and box width in rows and columns
25. CONST white = &HFFFFFFFF, black = &HFF000000, bc = &HFF008822, fc = &HFFCCCCFF
26.
27. TYPE PlayerType
28.     ID AS STRING '        name of bot including dealer bot
29.     Col AS INTEGER '      left corner column
30.     Row AS INTEGER '      top row
31.     FC AS _UNSIGNED LONG 'player colors are assigned in init FC are alternating Black and White
32.     BC AS _UNSIGNED LONG 'random light and dark opposite print FC
33.     Hand AS STRING '      cards are 1 char strings 10 is X
34.     Ace AS INTEGER '      flag has ace for totalling hand
35.     Bust AS INTEGER '     flag for final reckoning
36.     BJ AS INTEGER '       flag for final reckoning
37.     Total AS INTEGER '    card total of hand
38.     Chips AS _INTEGER64 ' players status
39.     SetBet AS _INTEGER64 'regular bet amount
40.     Bet AS _INTEGER64 '   players bet each round
41.
42. DIM SHARED deck\$(1 TO 52), p(1 TO nPlayers) AS PlayerType, deckIndex, round, allOut, player, blockDealer, tN AS LONG
43. SCREEN _NEWIMAGE(xmax, ymax, 32)
44. DIM i, card\$
45. ON TIMER(tN, .5) checkMouseOver
46.
47. initGame
48. 'FOR i = 1 TO nPlayers
49. '    showPlayer i
50. 'NEXT
51. TIMER(tN) ON
52.     clearPlayers 'clears screen too and shuffles deck
53.
54.     FOR i = 1 TO 2
55.         FOR player = 1 TO nPlayers 'each Player is dealt 2 cards
56.             IF player <> nPlayers THEN
57.                 IF p(player).Chips > 0 THEN
58.                     allOut = 0 'signal everyone is out of chips is false
60.                     showPlayer player
61.                     _DELAY .5
62.                 IF allOut THEN
64.                     showPlayer player
65.                     _DELAY .5
66.
67.     IF p(nPlayers).BJ = 0 THEN 'dealer does not have BJ
68.         FOR player = 1 TO nPlayers - 1
69.             showPlayer player
70.             WHILE p(player).Total < 21
71.                 SELECT CASE player ' this has to be coded for exactly all nPlayers - 1
72.                     CASE 1: card\$ = Johnno\$(player)
73.                     CASE 2: card\$ = Johnno\$(player)
74.                     CASE 3: card\$ = Steve\$(player)
75.                     CASE 4: card\$ = Steve\$(player)
76.                     CASE 5: card\$ = bplusAI\$(player)
77.                     CASE 6: card\$ = bplusAI\$(player)
78.                     CASE 7: card\$ = bplusAI2\$(player)
79.                     CASE 8: card\$ = bplusAI2\$(player)
80.                 IF card\$ = "h" THEN cp player, 13, "Hit"
81.                 IF card\$ = "d" THEN cp player, 13, "Double Down"
82.                 IF card\$ <> "h" AND card\$ <> "d" THEN cp player, 13, "Stay"
83.                 IF card\$ = "h" THEN
85.                     showPlayer player
86.                 ELSEIF card\$ = "d" AND LEN(p(player).Hand) = 2 THEN
87.                     p(player).Bet = 2 * p(player).Bet
89.                     showPlayer player
90.                 ELSE 'stayed
91.                     showPlayer player
92.
93.     blockDealer = 0
94.     showPlayer nPlayers
95.     WHILE p(nPlayers).Total < 17
96.         cp nPlayers, 11, "Dealer takes a card."
98.         showPlayer nPlayers
99.
100.     '    final Reckoning
101.     FOR player = 1 TO nPlayers - 1
102.         showPlayer player
103.         IF p(player).Total > 21 OR (p(player).Total < p(nPlayers).Total AND p(nPlayers).Total < 22) THEN
104.             cp player, 13, "Lost" + STR\$(p(player).Bet)
105.             p(player).Chips = p(player).Chips - p(player).Bet
106.             p(nPlayers).Chips = p(nPlayers).Chips + p(player).Bet
107.         ELSEIF p(player).Total = p(nPlayers).Total AND p(player).BJ = 0 THEN
108.             cp player, 13, "Push"
109.             IF p(player).BJ THEN
110.                 cp player, 13, "Win!" + STR\$(p(player).Bet + .5 * p(player).Bet)
111.                 p(player).Chips = p(player).Chips + p(player).Bet + .5 * p(player).Bet
112.                 p(nPlayers).Chips = p(nPlayers).Chips - p(player).Bet - .5 * p(player).Bet
113.                 cp player, 13, "Win!" + STR\$(p(player).Bet)
114.                 p(player).Chips = p(player).Chips + p(player).Bet
115.                 p(nPlayers).Chips = p(nPlayers).Chips - p(player).Bet
116.         IF p(player).Chips = 0 THEN cp player, 14, "Out of chips!"
117. LOOP UNTIL allOut
118.
119. SUB checkMouseOver
120.     DIM mx, my, i
121.     mx = _MOUSEX / 8 - .5 * bW: my = _MOUSEY / 16
122.     IF my >= 18 THEN
123.         FOR i = 1 TO nPlayers - 1
124.             IF ABS(mx - p(i).Col) <= .5 * bW - 1 THEN showPlayer i
125.
126. SUB clearPlayers
127.     DIM i
128.     COLOR fc, bc: CLS
129.     round = round + 1: allOut = -1
130.     FOR i = 1 TO nPlayers
131.         p(i).Hand = ""
132.         p(i).Ace = 0
133.         p(i).Total = 0
134.         p(i).BJ = 0
135.         p(i).Bust = 0
136.         'because of double down option I have to reset bet during play and set it back at each new round
137.         'make sure we aren't betting more than our chips count at least to start
138.         IF p(i).Chips < p(i).SetBet THEN p(i).Bet = p(i).Chips ELSE p(i).Bet = p(i).SetBet
139.     FOR i = 52 TO 2 STEP -1 'shuffle
140.         SWAP deck\$(INT(RND * i) + 1), deck\$(i)
141.     'deck\$(5) = "A": deck\$(10) = "J"  'check immediate show of Blackjack for dealer
142.     deckIndex = 0: blockDealer = -1
143.
144. FUNCTION bplusAI\$ (pn) ' first try
145.     SELECT CASE p(pn).Total
146.         CASE IS < 10: bplusAI\$ = "h" 'no caps!
147.         CASE 10, 11
148.             IF LEN(p(pn).Hand) = 2 THEN bplusAI\$ = "d" ELSE bplusAI\$ = "h"
149.         CASE IS < 15
150.             IF RND < .5 THEN bplusAI\$ = "h" ELSE bplusAI\$ = "whatever"
151.         CASE ELSE: bplusAI\$ = "Show me the money!"
152.
153. FUNCTION bplusAI2\$ (pN) 'after trying first want to try this make it more likely to hit on 12 than 13, 14...
154.     SELECT CASE p(pN).Total
155.         CASE IS < 10: bplusAI2\$ = "h" 'no caps!
156.         CASE 10, 11 'double down unless dealer showing an Ace which is like insurance for dealer
157.             IF LEN(p(pN).Hand) = 2 AND LEFT\$(p(nPlayers).Hand, 1) <> "A" THEN bplusAI2\$ = "d" ELSE bplusAI2\$ = "h"
158.         CASE 12: IF RND < .75 THEN bplusAI2\$ = "h" ELSE bplusAI2\$ = "whatever"
159.         CASE 13: IF RND < .5 THEN bplusAI2\$ = "h" ELSE bplusAI2\$ = "whatever"
160.         CASE 14: IF RND < .25 THEN bplusAI2\$ = "h" ELSE bplusAI2\$ = "whatever"
161.         CASE ELSE: bplusAI2\$ = "Show me the money!"
162.
163. FUNCTION Johnno\$ (pN)
164.     IF p(pN).Total = 10 OR p(pN).Total = 11 AND LEN(p(pN).Hand) = 2 THEN
165.         Johnno\$ = "d"
166.     ELSEIF p(pN).Total = 10 OR p(pN).Total = 11 AND LEN(p(pN).Hand) <> 2 THEN
167.         Johnno\$ = "h"
168.     ELSEIF 12 <= p(pN).Total AND p(pN).Total <= 15 THEN
169.         SELECT CASE LEFT\$(p(nPlayers).Hand, 1)
170.             CASE "A", "K", "Q", "J", "X", "9": Johnno\$ = "h"
171.             CASE "7", "8": IF RND < .5 THEN Johnno\$ = "h"
172.             CASE ELSE: Johnno\$ = "Hope to Bust em"
173.     ELSEIF p(pN).Total < 12 THEN
174.         Johnno\$ = "h"
175.         Johnno\$ = "Stay"
176.
177. FUNCTION Steve\$ (pN) 'how simple is this! never bust make dealer work for it
178.     IF p(pN).Total < 12 THEN Steve\$ = "h"
179.
181.     deckIndex = deckIndex + 1
182.     p(rec).Hand = p(rec).Hand + deck\$(deckIndex)
183.     IF deck\$(deckIndex) = "A" THEN p(rec).Ace = -1
184.     p(rec).Total = 0
185.     FOR i = 1 TO LEN(p(rec).Hand)
186.         IF INSTR(rank\$, MID\$(p(rec).Hand, i, 1)) > 10 THEN cv = 10 ELSE cv = INSTR(rank\$, MID\$(p(rec).Hand, i, 1))
187.         p(rec).Total = p(rec).Total + cv
188.     IF p(rec).Total < 12 AND p(rec).Ace THEN p(rec).Total = p(rec).Total + 10
189.     IF LEN(p(rec).Hand) = 2 AND p(rec).Total = 21 THEN p(rec).BJ = -1
190.     IF p(rec).Total > 21 THEN p(rec).Bust = -1
191.
192. SUB showPlayer (nPlayer)
193.     DIM i AS INTEGER, S\$
194.     COLOR p(nPlayer).FC, p(nPlayer).BC
195.     FOR i = 0 TO bH - 1 'clear our block
196.         'PRINT p(nPlayer).Row + i, p(nPlayer).Col
197.         LOCATE p(nPlayer).Row + i, p(nPlayer).Col: PRINT SPACE\$(bW);
198.     cp nPlayer, 1, "Round:" + STR\$(round)
199.     cp nPlayer, 3, p(nPlayer).ID
200.     cp nPlayer, 5, "Chips:" + STR\$(p(nPlayer).Chips)
201.     IF nPlayer <> nPlayers THEN cp nPlayer, 6, "Bet:" + STR\$(p(nPlayer).Bet)
202.     FOR i = 1 TO LEN(p(nPlayer).Hand) 'with 12 aces could get very long hands
203.         S\$ = S\$ + MID\$(p(nPlayer).Hand, i, 1) + " "
204.     cp nPlayer, 8, "___Hand___"
205.     IF nPlayer = nPlayers AND LEN(p(nPlayer).Hand) = 2 AND p(nPlayer).Total <> 21 AND blockDealer THEN
206.         S\$ = LEFT\$(S\$, 2) + "?"
207.         cp nPlayer, 9, S\$
208.         cp nPlayer, 10, "Total: ??"
209.         cp nPlayer, 9, S\$
210.         cp nPlayer, 10, "Total:" + STR\$(p(nPlayer).Total)
211.
212.     IF p(nPlayer).Bust THEN cp nPlayer, 11, "Busted"
213.     IF p(nPlayer).BJ THEN cp nPlayer, 11, "Blackjack"
214.
215. SUB initGame 'the stuff that never changes
216.     DIM i, spacer
217.     FOR i = 1 TO 52 'get deck ready
218.         deck\$(i) = MID\$(rank\$ + rank\$ + rank\$ + rank\$, i, 1)
219.
220.     'for printing in each players window area of screen = blackjack table
221.     'xmax/8 =  2*margin + bW *(nplayers -1) + spacer *(nplayer-2)
222.     spacer = ((xmax / 8) - margin - bW * (nPlayers - 1)) / (nPlayers - 2)
223.
224.     FOR i = 1 TO nPlayers
225.         IF i <> nPlayers THEN
226.                 CASE 1: p(i).ID = "Johnno 1"
227.                 CASE 2: p(i).ID = "Johnno 2"
228.                 CASE 3: p(i).ID = "Steve 1"
229.                 CASE 4: p(i).ID = "Steve 2"
230.                 CASE 5: p(i).ID = "bplus First AI 1"
231.                 CASE 6: p(i).ID = "bplus First AI 2"
232.                 CASE 7: p(i).ID = "bplus 2nd AI 1"
233.                 CASE 8: p(i).ID = "bplus 2nd AI 2"
234.             p(i).Col = margin + (i - 1) * (spacer + bW)
235.             p(i).Row = 18
236.             p(i).Chips = 100
237.             p(i).SetBet = 2
238.                 p(i).BC = _RGB32(RND * 128, RND * 128, RND * 128)
239.                 p(i).BC = _RGB32(RND * 128 + 127, RND * 128 + 127, RND * 128 + 127)
240.             p(i).ID = "Dealer"
241.             p(i).Col = (xmax / 8 - bW) / 2
242.             p(i).Row = 2
243.             p(i).Chips = -100 * (nPlayers - 1)
244.             IF i MOD 2 THEN p(i).BC = &HFF000000 ELSE p(i).BC = &HFFFFFFFF
245.         IF i MOD 2 THEN p(i).FC = &HFFFFFFFF ELSE p(i).FC = &HFF000000
246.
247.     'ask the user / YOU what e prefers for betting
248.     COLOR fc, bc: CLS
249.     cp 0, 10, "*** Blackjack Multi AI Tester ***"
250.     cp 0, 12, "Each AI bot starts with 100 chips and bets 2 each round."
251.     cp 0, 13, "Dealer must hit on 16 or less."
252.     cp 0, 14, "Blackjack pays 1.5 X the bet."
253.     cp 0, 15, "Double down option available when you get 2 cards."
254.     cp 0, 16, "It Doubles the bet and you get one more card."
255.     cp 0, 20, "press any to continue..."
256.
257. SUB cp (nPlayer, row, s AS STRING) 'center print a string on the given row
258.     IF nPlayer THEN
259.         COLOR p(nPlayer).FC, p(nPlayer).BC
260.         LOCATE p(nPlayer).Row + row, p(nPlayer).Col + (bW - LEN(s)) / 2: PRINT s;
261.         COLOR fc, bc
262.         LOCATE row, (xmax / 8 - LEN(s)) / 2: PRINT s;
263.
264.

Can't mouse over while getting a screen shot but here is a game with 8 AI bots + Dealer bot

« Last Edit: July 07, 2020, 12:55:30 PM by bplus »

#### johnno56

• Forum Resident
• Posts: 1039
• Live long and prosper.
##### Re: Blackjack
« Reply #214 on: July 07, 2020, 06:57:35 PM »
Nine hands playing from one deck. That would mean a serious amount of shuffling... lol  Ah, but then, The Dealer is supposed to perform miracles... lol

Suggestion: Increase the screen size. Place the Dealer top centre. Three players from top to bottom on both the left and right sides. The remaining two in the 'gap' along the bottom. Another layout: Dealer in the center of screen. Two players left and right and above and below the Dealer.

My other guess would be that this version is a 'concept' of controlling multiple AI and 'layout' is not relevant.... lol

I'm curious. In 'real' Blackjack, how many players can actually play, and how does the dealer determine how many 'decks' to use?
Logic is the beginning of wisdom.

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #215 on: July 07, 2020, 07:52:02 PM »
My other guess would be that this version is a 'concept' of controlling multiple AI and 'layout' is not relevant.... lol

Yeah pretty much that, an experiment. I did like how well the mouse over thing did work off a timer but...

Yeah! you know it's nice to see all the hands clearly. I could probably fit 8 comfortably or go bigger screen as you say. I've also noticed that it is nice for cards to layout from left to right without a centering function shifting them left and right.

What do you think about the dealer down at the bottom right corner, then we just work left to right, top to bottom?

You know, think about it, the dealer has to keep hitting until has at least 17. 17 to 21 is a window of... oh it's 5 cards. I've been thinking 4 because 21-17 but it is 5 cards. And yet it just drains chips from players, there must be some better strategy. The tip about looking at dealers up card was interesting intelligence and I am beginning to think double down is only good on 11 and only if dealer has lower card.

I will play around with layout and AI options.

BTW in real Blackjack the casinos set their own standards and I am pretty sure no one uses only one deck which means its possible to get a huge number of aces.
« Last Edit: July 07, 2020, 07:58:10 PM by bplus »

#### johnno56

• Forum Resident
• Posts: 1039
• Live long and prosper.
##### Re: Blackjack
« Reply #216 on: July 07, 2020, 08:45:59 PM »
Position of the Dealer... Traditionally the Dealer is at the 'head' of the table... I assume that to be the 'top' with all players within reach at the 'bottom'. The 'reach' could explain the shape of the table... The problem with 'that' layout, for the screen, would be that all the player would be side-by-side. Did you have any plans on a limit to player numbers? Knowing the limit would help in  determining the layout.

But, then again, who says that the game has to be 'traditional'? lol

I remember, during lunch breaks at work, we used to play Pontoon (or 21), and betting was a little different. There was the initial bet then if the player had 11 or less in two cards, the player could 'buy' an extra card and choose to 'hit' if more than 11. If you are after 'bleeding a player dry' then that might be the way to go... lol  Just recalled that... I know. I'm shocked as well..!! Remembering something from 4 decades ago... Shocked!

The mouse is a great idea... But, with the right kind of surgery, a neural interface could be developed for that 'hands free' feeling... But... mouse will do in a pinch... lol

Logic dictates that, if artificial intelligence can be programmed into a game, then so can artificial stupidity... It's funny but not meant as a joke. "Humor. It is a difficult concept." Star Trek: Wrath of Khan (1982)  People make 'stupid' decisions and make foolish mistakes. Then why not configure the AI to replicate the same behaviour? (throwing in a typical "Doh!" after the event) Just a thought...
Logic is the beginning of wisdom.

#### Qwerkey

• Forum Resident
• Posts: 736
##### Re: Blackjack
« Reply #217 on: July 08, 2020, 07:39:18 AM »
Congratulations @bplus & @johnno56 , what a collaboration.  In forum stats, this post is way ahead of anything else in Replies.  This will shortly be arriving in Games.

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #218 on: July 08, 2020, 12:06:15 PM »
Thanks Qwerkey,

The number of replies is most probably just chit-chat between me and Johnno, but I appreciate encouragement and help offered by Dav, Pete, Steve, George and Pete & Steve's jokes to break monotony and all positive comments QBExile, Old Moses, Ken, Ashish, Spriggsy, jack, Cobalt all showing some sort of interest even Fellippe when I mention a possible glitch between QB64 versions. 😊

I actually considered the cough and gunshots sounds for background, I already had the sounds, funny!

Special thanks to Johnno, like with Battleship, he can sure dress up my code and keep the ideas flowing for me. Really liked the splash screen specially with our Logo in the neon sign and the Dealer voice. Good eye too, I still don't know if there is difference in card set images? ha! I just used what he provided on faith.

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #219 on: July 08, 2020, 01:12:27 PM »
@Qwerkey

I will go over code and write in some more comments for myself and others for future reference. Should be ready tonight, I've got chores in afternoon.

I have already made the main loop play more efficient with the Mult-players code by setting flags for Blackjacks and Busts handling them in Final Reckoning section instead of separately right after first 2 cards.

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #220 on: July 08, 2020, 07:15:28 PM »
I have become intensely curious about Dealer Stats, the distribution of Totals 17 to 21 and over 21 Busts:
Code: QB64: [Select]
1. _TITLE "BJ Dealer Test - stats" 'b+ 2020-07-08
2. '  on distribution 17 to 21 in and 22 plus out
3.
4. CONST rank = "A23456789XJQK"
5. TYPE PlayerType
6.     ID AS STRING
7.     Hand AS STRING
8.     Ace AS INTEGER
9.     Total AS INTEGER
10.     chips AS _INTEGER64
11.     setBet AS _INTEGER64
12.     bet AS _INTEGER64
13. DIM SHARED dealer AS PlayerType, deck\$(1 TO 52), deckIndex AS INTEGER, stats(17 TO 22)
14.
15. FOR i = 1 TO 52 'get deck ready
16.     deck\$(i) = MID\$(rank\$ + rank\$ + rank\$ + rank\$, i, 1)
17.
18. WHILE _KEYDOWN(27) = 0
19.     FOR i = 52 TO 2 STEP -1 'shuffle
20.         r = INT(RND * i) + 1
21.         SWAP deck\$(r), deck\$(i)
22.     deckIndex = 0: dealer.Total = 0: rounds = rounds + 1: dealer.Hand = "": noBusts = 0: dealer.Ace = 0
23.     PRINT "Round:"; rounds
24.     WHILE dealer.Total < 17
26.         PRINT RIGHT\$(dealer.Hand, 1);
27.         _LIMIT 100
28.     PRINT , dealer.Total: PRINT
29.     IF dealer.Total > 21 THEN stats(22) = stats(22) + 1 ELSE stats(dealer.Total) = stats(dealer.Total) + 1
30.     FOR i = 17 TO 22
31.         PRINT i, stats(i), INT(stats(i) * 10000 / rounds) / 100; "%"
32.         IF i < 22 THEN noBusts = noBusts + stats(i)
33.     PRINT "     No Busts:"; noBusts, INT(noBusts * 10000 / rounds) / 100; "%"
34.     _LIMIT 10
35.
36.
38.     deckIndex = deckIndex + 2
39.     dealer.Hand = dealer.Hand + deck\$(deckIndex)
40.     IF deck\$(deckIndex) = "A" THEN dealer.Ace = -1
41.     dealer.Total = 0
42.     FOR i = 1 TO LEN(dealer.Hand)
43.         IF INSTR(rank, MID\$(dealer.Hand, i, 1)) > 10 THEN cv = 10 ELSE cv = INSTR(rank, MID\$(dealer.Hand, i, 1))
44.         dealer.Total = dealer.Total + cv
45.     IF dealer.Total < 12 AND dealer.Ace THEN dealer.Total = dealer.Total + 10
46.
47.

#### George McGinn

• Newbie
• Posts: 35
##### Re: Blackjack
« Reply #221 on: July 08, 2020, 07:35:08 PM »
Thank you.

The one I have a little bit longer, but it’s written for the techBASIC on iPad which does not have a SWAP statement.

However, I have noticed playing your blackjack game that it doesn’t quite follow basic play. I’ve noticed where the dealer has a 10 value showing, Everybody’s up to 16 should be hitting, yeah I’ve seen players stand on 13. I never a few other little things but I do understand what you’re trying to do with the AI. And it’s working pretty well so far.

I would however, chance a bust with a dealer showing a 10 value card as an up card, as I do in real life at casinos and do pretty well playing the basic strategy with some of my personal modifications.

Otherwise, you have done a great job on the coding.

Can shuffle be simpler than this from my last code post, from all my code that needs shuffle)?
Code: QB64: [Select]
1.     FOR i = 52 TO 2 STEP -1 'shuffle
2.         SWAP deck\$(INT(RND * i) + 1), deck\$(i)
3.

Welcome aboard George!
________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)

#### George McGinn

• Newbie
• Posts: 35
##### Re: Blackjack
« Reply #222 on: July 08, 2020, 07:50:13 PM »
Bbplus,

Here is the code that I have on techBASIC on my iPad. I basically do a manual swap.

The print statements are there so that when I tested it I could see what it was doing and making sure that it was not duplicating any numbers.

Near the technique is just about the same, but what I do is I first preload an array And then swap the numbers around.

The following code is NOT QB64, but it is simple enough that it it will probably run in QB64:

Code: Text: [Select]
1.
2. ! Shuffle a deck of cards, represented by an array contiaining the
3. ! ordinal number of each card.
4.
5. DIM cards(52) AS INTEGER
6.
7. FOR i = 1 TO 52
8.     cards(i) = i
9. NEXT
10.
11. j=0
12.
13. FOR i = 1 to 52
14.     PRINT "i: ";i
15.     j = INT(1 + Math.rand*52) ! This generates the random number to swap from
16.     PRINT "j: ";j
17.     temp = cards(i)                  ! Saves the card number currently at i
18.     PRINT "temp=cards(i): ";temp
19.     cards(i) = cards(j)              ! This swaps position j into i
20.     PRINT "cards(i)=cards(j): ";cards(i)
21.     cards(j) = temp                  ! This moves the value that was in i into j
22.     PRINT "cards(j)=temp: ";cards(j)
23.     PRINT
24. NEXT
25.
26. ! Print out the new deck just shuffled
27. FOR i = 1 TO 52
28.     PRINT cards(i)
29. NEXT
30.
________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #223 on: July 08, 2020, 08:06:13 PM »
Hi @George McGinn

I see you come from Steve McNeill's camp of swapping each card with any of the other 52 cards.

There is a math proof that this is not ideal and leaves slightly less than perfect random distribution (given perfect random generator but who has that?)

"https://en.wikipedia.org/wiki/Fisher–Yates_shuffle"  <<copy/paste between quotes this in browser because underline link usually fails.

Look under Naive Shuffle:

EDIT: 2 l's in Steve's last name, I noticed I missed one in George's quote. Sorry Steve.
« Last Edit: July 09, 2020, 01:04:25 AM by bplus »

#### bplus

• Forum Resident
• Posts: 6674
• b = b + ...
##### Re: Blackjack
« Reply #224 on: July 08, 2020, 08:15:22 PM »
Thank you.

The one I have a little bit longer, but it’s written for the techBASIC on iPad which does not have a SWAP statement.

However, I have noticed playing your blackjack game that it doesn’t quite follow basic play. I’ve noticed where the dealer has a 10 value showing, Everybody’s up to 16 should be hitting, yeah I’ve seen players stand on 13. I never a few other little things but I do understand what you’re trying to do with the AI. And it’s working pretty well so far.

I would however, chance a bust with a dealer showing a 10 value card as an up card, as I do in real life at casinos and do pretty well playing the basic strategy with some of my personal modifications.

Otherwise, you have done a great job on the coding.

Yeah I am testing different Stay Strategies now and 16 looks very good! A slight mod of my previous post:
Code: QB64: [Select]
1. _TITLE "BJ Dealer Test - stats" 'b+ 2020-07-08
2. '  on distribution 17 to 21 in and 22 plus out
3.
4. CONST rank = "A23456789XJQK"
5. TYPE PlayerType
6.     ID AS STRING
7.     Hand AS STRING
8.     Ace AS INTEGER
9.     Total AS INTEGER
10.     chips AS _INTEGER64
11.     setBet AS _INTEGER64
12.     bet AS _INTEGER64
13.
14. DIM SHARED stay: stay = 18 'compare stay statss 16, 17 (Dealer's), 18
15.
16. DIM SHARED dealer AS PlayerType, deck\$(1 TO 52), deckIndex AS INTEGER, stats(stay TO 22)
17.
18. FOR i = 1 TO 52 'get deck ready
19.     deck\$(i) = MID\$(rank\$ + rank\$ + rank\$ + rank\$, i, 1)
20.
21. WHILE _KEYDOWN(27) = 0
22.     FOR i = 52 TO 2 STEP -1 'shuffle
23.         r = INT(RND * i) + 1
24.         SWAP deck\$(r), deck\$(i)
25.     deckIndex = 0: dealer.Total = 0: rounds = rounds + 1: dealer.Hand = "": noBusts = 0: dealer.Ace = 0
26.     PRINT "Round:"; rounds
27.     WHILE dealer.Total < stay
29.         PRINT RIGHT\$(dealer.Hand, 1);
30.         _LIMIT 100
31.     PRINT , dealer.Total: PRINT
32.     IF dealer.Total > 21 THEN stats(22) = stats(22) + 1 ELSE stats(dealer.Total) = stats(dealer.Total) + 1
33.     FOR i = stay TO 22
34.         PRINT i, stats(i), INT(stats(i) * 10000 / rounds) / 100; "%"
35.         IF i < 22 THEN noBusts = noBusts + stats(i)
36.     PRINT "     No Busts:"; noBusts, INT(noBusts * 10000 / rounds) / 100; "%"
37.     _LIMIT 10
38.
39.
41.     IF LEN(dealer.Hand) <= 2 THEN deckIndex = deckIndex + 2 ELSE deckIndex = deckIndex + 1
42.     dealer.Hand = dealer.Hand + deck\$(deckIndex)
43.     IF deck\$(deckIndex) = "A" THEN dealer.Ace = -1
44.     dealer.Total = 0
45.     FOR i = 1 TO LEN(dealer.Hand)
46.         IF INSTR(rank, MID\$(dealer.Hand, i, 1)) > 10 THEN cv = 10 ELSE cv = INSTR(rank, MID\$(dealer.Hand, i, 1))
47.         dealer.Total = dealer.Total + cv
48.     IF dealer.Total < 12 AND dealer.Ace THEN dealer.Total = dealer.Total + 10
49.
50.

I am running stay at 18 now:

You are right! 16 looked very good compared to 17, a NO Bust rate a little over 80% compared to 72% for Stay at 17 and the percent of Totals 20 or 21 is just slightly lower for Stay at 16 (31%) than it is for stay at 17(32%) based on about 3000 trials which is a pittance I suppose.

As you can see, Stay at 18 has significantly worse Bust Rate!