; NumberJack: a number-only blackjack game in MU8A for the mu808 VM ; ; How to play: ; * you start with a $1000 balance ; * on each round, enter your bet ; (the game will quit if the bet is above your balance) ; * the first card of the dealer's hand will be shown ; (hands are shown with a leading 1 that you must ignore) ; (card values are: 1 is ace, 2 to 9 are "as is", 0 is 10 to K) ; * on the first turn, select 0 (stand), 1 (hit) or 2 (double) ; * on each next turn, select 0 (stand) or 1 (hit) ; * as a result of the round, the dealer's final hand will be shown ; first and then yours ; * the dealer must draw on 16 and stand on any 17 ; * player's blackjack pays 3 to 2 ; ; Created by Luxferre in 2025, released into public domain ; constants section set 10 0 51 ; set constant 10 to loc 51 set 100 0 52 ; set constant 100 to loc 52 set 13 0 53 ; upper RNG limit to loc 53 set 16 0 54 ; dealer draw limit to loc 54 set 21 0 55 ; 21 score limit to loc 55 set 12 0 56 ; 12 score limit to loc 56 set 1000 0 60 ; set $1000 initial balance set 2 0 57 ; set constant 2 to loc 57 set 36 0 58 ; set constant 36 to loc 58 set 101 0 80 ; set the first blackjack condition to loc 80 set 110 0 81 ; set the second blackjack condition to loc 81 juc :main ; jump to the main code ; subroutines section (return address is in loc 99) ; random card pulling procedure (result is in loc 2, from 0 to 9) :gcard rnd 127 53 1 ; set loc 1 to random integer between 1 and 13 div 1 51 2 ; divide it by 10 into loc 2 mdf 2 0 2 ; get the floor part of the result into the same loc 2 sub 127 2 2 ; subtract it from 1 mul 1 2 ; multiply by the random choice itself, result is in loc 2 iuc 99 ; jump to the return address in loc 99 ; score evaluation procedure ; param is in loc 1, resulting scores are in locs 2 and 3 :score set 0 0 2 ; set score1 to 0 set 0 0 8 ; set aces to 0 :slp mdf 1 51 4 ; get the current digit n of val div 1 51 1 ; divide val by 10 mdf 1 0 1 ; get the floor part into the same loc jgt 4 :scn ; skip if n > 0 fma 51 127 4 ; add 10 to n :scn fma 4 127 2 ; add n to score1 at loc 2 sub 4 127 5 ; subtract 1 from n to loc 5 jne 5 :sc2 ; skip if n != 1 inc 8 ; increment aces count at loc 8 :sc2 sub 1 127 5 ; subtract 1 from val to loc 5 jgt 5 :slp ; go to loop start if val > 1 dva 2 3 ; assign score2 (at loc 3) = score1 (at loc 2) sub 8 127 5 ; subtract 1 from aces (loc 8) jne 5 :send ; go to procedure end if aces != 1 sub 2 56 5 ; subtract 12 from the score1 value jge 5 :send ; go to procedure end if score1 >= 12 fma 51 127 3 ; add 10 to score2 if there was exactly one non-busting ace :send iuc 99 ; jump to the return address in loc 99 ; main code section ; variables: ; 60 - balance, 61 - bet, 62 - dealer's hand, 63 - player's hand, 64 - round :main out 58 58 1 ; output the dollar sign (if supported) out 60 60 0 ; output the current balance jeq 60 :end ; game over if it's zero inp 61 61 0 ; input your bet sub 60 61 60 ; subtract the bet from the balance jlt 60 :end ; game over if over balance dca :r1 99 ; set the return address juc :gcard ; call the card generation procedure :r1 fma 52 51 2 ; loc 2 <- 100 + 10 * card in loc 2 dva 2 62 ; copy the result into loc 62 dca :r2 99 ; set the return address juc :gcard ; call the card generation procedure again (in loc 2) :r2 fma 2 127 62 ; add this result into loc 62 (dealer's hand) dva 62 1 ; copy the dealer's hand as the proc parameter dca :r3 99 ; set the return address juc :score ; call the scoring procedure :r3 sub 3 55 5 ; we only have to compare score 2 to 21 jeq 5 :main ; start the loop over if we have dealer's blackjack dca :r4 99 ; set the return address juc :gcard ; call the card generation procedure :r4 fma 52 51 2 ; loc 2 <- 100 + 10 * card in loc 2 dva 2 63 ; copy the result into loc 63 (player's hand) dca :r5 99 ; set the return address juc :gcard ; call the card generation procedure again (in loc 2) :r5 fma 2 127 63 ; add this result into loc 63 (player's hand) div 62 51 5 ; get the start of the dealer's hand by dividing it by 10... mdf 5 0 5 ; and getting the floor part out 5 5 0 ; display the start of the dealer's hand set 0 0 64 ; set the round index to 0 set 0 0 9 ; set the stand flag to 0 :rnl out 63 63 0 ; start of the inner player loop, display the player's hand inp 6 6 0 ; input the action into loc 6 jeq 6 :std ; jump to stand action if 0 sub 6 127 5 ; check if 1 jeq 5 :hit ; jump to hit action if 1 sub 5 127 5 ; check if 2 jeq 5 :dbl ; jump to double action if 2 juc :skp ; jump to skip otherwise :dbl jne 64 :skp ; skip double if not the first round sub 60 61 60 ; subtract more balance mul 57 61 ; double the bet set 1 0 9 ; set the stand flag, proceed to the hit section next :hit dca :r6 99 ; set the return address juc :gcard ; call the card generation procedure :r6 fma 2 51 63 ; loc 63 <- loc 63 * 10 + card in loc 2 inc 64 ; increment the round index juc :skp ; jump to skip afterwards :std set 1 0 9 ; set the stand flag inc 64 ; increment the round index :skp dva 63 1 ; copy the current player's hand to loc 1 as a parameter dca :r7 99 ; set the return address juc :score ; call the scoring procedure :r7 sub 2 55 5 ; we only have to compare score 1 to 21 jle 5 :nob ; reloop to beginning if the player is bust out 63 63 0 ; output the player's hand juc :main ; reloop :nob jeq 9 :rnl ; repeat the inner player loop if the stand flag is 0 dva 3 72 ; copy the player score 2 to loc 72 set 0 0 9 ; set the stand flag to 0 :rnd dva 62 1 ; start the inner dealer's loop, set the scoring procedure param dca :r9 99 ; set the return address juc :score ; call the scoring procedure :r9 sub 2 55 5 ; we need to compare score 1 to 21 => loc 5 sub 3 54 6 ; we need to compare score 2 to 16 => loc 6 jgt 5 :s3 ; go to stand if score1 > 21 jgt 6 :s3 ; go to stand if score2 > 16 juc :s4 ; skip if neither :s3 juc :s5 ; jump outside to stand :s4 dca :r8 99 ; set the return address juc :gcard ; call the card generation procedure :r8 fma 2 51 62 ; loc 62 <- loc 62 * 10 + card in loc 2 jeq 9 :rnd ; repeat the inner dealer loop if the stand flag is 0 :s5 out 62 63 0 ; output both hands (dealer's first) sub 63 80 1 ; compare player hand with 101 jeq 1 :bjk ; jump to the blackjack condition if equal sub 63 81 1 ; compare player hand with 110 jeq 1 :bjk ; jump to the blackjack condition if equal sub 3 72 1 ; compare dealer score 2 and player score 2 jeq 1 :push ; push condition jlt 1 :win ; player win condition sub 2 55 1 ; compare dealer score 1 with 21 jgt 1 :win ; player win condition juc :main ; reloop to beginning :bjk div 61 57 1 ; halve the bet fma 1 127 60 ; add half the bet (for blackjack calc) :win fma 61 127 60 ; add bet first time :push fma 61 127 60 ; add bet second time juc :main ; reloop to beginning :end nnn ; just a nop label for the program end