added numberjack blackjack game
This commit is contained in:
@@ -273,12 +273,13 @@ namely:
|
|||||||
* [A simple 10-character echo test](examples/echo.mu8a) (requires both I/O
|
* [A simple 10-character echo test](examples/echo.mu8a) (requires both I/O
|
||||||
port 1 and port 2 support),
|
port 1 and port 2 support),
|
||||||
* [Bulls and Cows game](examples/moo.mu8a),
|
* [Bulls and Cows game](examples/moo.mu8a),
|
||||||
* [Lunar Lander game](examples/lunar.mu8a).
|
* [Lunar Lander game](examples/lunar.mu8a),
|
||||||
|
* [NumberJack](examples/numjack.mu8a) port of a Blackjack game, utilizing some
|
||||||
|
advanced techniques (see the comments in the beginning on how to play it).
|
||||||
|
|
||||||
You can assemble them using any of the reference assemblers provided within the
|
You can assemble them using any of the reference assemblers provided within the
|
||||||
repository, or even by hand (by numbering lines, resolving the labels and
|
repository, or even by hand (by numbering lines, resolving the labels and
|
||||||
replacing mnemonics with corresponding opcodes). The "Hellorld!" example only
|
replacing mnemonics with corresponding opcodes).
|
||||||
works on the platforms supporting I/O port 1 (character output).
|
|
||||||
|
|
||||||
If you just want to test an implementation, assembled MU8 machine code files
|
If you just want to test an implementation, assembled MU8 machine code files
|
||||||
(in the plaintext format) are stored in the `examples/assembled` subdirectory.
|
(in the plaintext format) are stored in the `examples/assembled` subdirectory.
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
1 5 1 0 50
|
||||||
|
2 5 10 0 51
|
||||||
|
3 5 100 0 52
|
||||||
|
4 5 13 0 53
|
||||||
|
5 5 16 0 54
|
||||||
|
6 5 21 0 55
|
||||||
|
7 5 12 0 56
|
||||||
|
8 5 1000 0 60
|
||||||
|
9 5 2 0 57
|
||||||
|
10 5 36 0 58
|
||||||
|
11 5 101 0 80
|
||||||
|
12 5 110 0 81
|
||||||
|
13 1 6 0 40
|
||||||
|
14 15 50 53 1
|
||||||
|
15 9 1 51 2
|
||||||
|
16 10 2 0 2
|
||||||
|
17 8 50 2 2
|
||||||
|
18 7 0 1 2
|
||||||
|
19 1 13 0 99
|
||||||
|
20 5 0 0 2
|
||||||
|
21 5 0 0 8
|
||||||
|
22 10 1 51 4
|
||||||
|
23 9 1 51 1
|
||||||
|
24 10 1 0 1
|
||||||
|
25 1 1 4 27
|
||||||
|
26 7 51 50 4
|
||||||
|
27 7 4 50 2
|
||||||
|
28 8 4 50 5
|
||||||
|
29 1 5 5 31
|
||||||
|
30 7 50 50 8
|
||||||
|
31 8 1 50 5
|
||||||
|
32 1 1 5 22
|
||||||
|
33 6 1 2 3
|
||||||
|
34 8 8 50 5
|
||||||
|
35 1 5 5 39
|
||||||
|
36 8 2 56 5
|
||||||
|
37 1 3 5 39
|
||||||
|
38 7 51 50 3
|
||||||
|
39 1 13 0 99
|
||||||
|
40 3 58 58 1
|
||||||
|
41 3 60 60 0
|
||||||
|
42 1 0 60 128
|
||||||
|
43 4 61 61 0
|
||||||
|
44 8 60 61 60
|
||||||
|
45 1 2 60 128
|
||||||
|
46 6 0 48 99
|
||||||
|
47 1 6 0 14
|
||||||
|
48 7 52 51 2
|
||||||
|
49 6 1 2 62
|
||||||
|
50 6 0 52 99
|
||||||
|
51 1 6 0 14
|
||||||
|
52 7 2 50 62
|
||||||
|
53 6 1 62 1
|
||||||
|
54 6 0 56 99
|
||||||
|
55 1 6 0 20
|
||||||
|
56 8 3 55 5
|
||||||
|
57 1 0 5 40
|
||||||
|
58 6 0 60 99
|
||||||
|
59 1 6 0 14
|
||||||
|
60 7 52 51 2
|
||||||
|
61 6 1 2 63
|
||||||
|
62 6 0 64 99
|
||||||
|
63 1 6 0 14
|
||||||
|
64 7 2 50 63
|
||||||
|
65 9 62 51 5
|
||||||
|
66 10 5 0 5
|
||||||
|
67 3 5 5 0
|
||||||
|
68 5 0 0 64
|
||||||
|
69 5 0 0 9
|
||||||
|
70 3 63 63 0
|
||||||
|
71 4 6 6 0
|
||||||
|
72 1 0 6 87
|
||||||
|
73 8 6 50 5
|
||||||
|
74 1 0 5 82
|
||||||
|
75 8 5 50 5
|
||||||
|
76 1 0 5 78
|
||||||
|
77 1 6 0 89
|
||||||
|
78 1 5 64 89
|
||||||
|
79 8 60 61 60
|
||||||
|
80 7 61 50 61
|
||||||
|
81 5 1 0 9
|
||||||
|
82 6 0 84 99
|
||||||
|
83 1 6 0 14
|
||||||
|
84 7 2 51 63
|
||||||
|
85 7 50 50 64
|
||||||
|
86 1 6 0 89
|
||||||
|
87 5 1 0 9
|
||||||
|
88 7 50 50 64
|
||||||
|
89 6 1 63 1
|
||||||
|
90 6 0 92 99
|
||||||
|
91 1 6 0 20
|
||||||
|
92 8 2 55 5
|
||||||
|
93 1 4 5 96
|
||||||
|
94 3 63 63 0
|
||||||
|
95 1 6 0 40
|
||||||
|
96 1 0 9 70
|
||||||
|
97 6 1 3 72
|
||||||
|
98 5 0 0 9
|
||||||
|
99 6 1 62 1
|
||||||
|
100 6 0 102 99
|
||||||
|
101 1 6 0 20
|
||||||
|
102 8 2 55 5
|
||||||
|
103 8 3 54 6
|
||||||
|
104 1 1 5 107
|
||||||
|
105 1 1 6 107
|
||||||
|
106 1 6 0 108
|
||||||
|
107 1 6 0 112
|
||||||
|
108 6 0 110 99
|
||||||
|
109 1 6 0 14
|
||||||
|
110 7 2 51 62
|
||||||
|
111 1 0 9 99
|
||||||
|
112 3 62 63 0
|
||||||
|
113 8 63 80 1
|
||||||
|
114 1 0 1 123
|
||||||
|
115 8 63 81 1
|
||||||
|
116 1 0 1 123
|
||||||
|
117 8 3 72 1
|
||||||
|
118 1 0 1 126
|
||||||
|
119 1 2 1 125
|
||||||
|
120 8 2 55 1
|
||||||
|
121 1 1 1 125
|
||||||
|
122 1 6 0 40
|
||||||
|
123 9 61 57 1
|
||||||
|
124 7 1 50 60
|
||||||
|
125 7 61 50 60
|
||||||
|
126 7 61 50 60
|
||||||
|
127 1 6 0 40
|
||||||
|
128 0 0 0 0
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
; 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 1 0 50 ; set constant 1 to loc 50
|
||||||
|
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 50 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 50 2 2 ; subtract it from 1
|
||||||
|
fma 0 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 50 4 ; add 10 to n
|
||||||
|
:scn fma 4 50 2 ; add n to score1 at loc 2
|
||||||
|
sub 4 50 5 ; subtract 1 from n to loc 5
|
||||||
|
jne 5 :sc2 ; skip if n != 1
|
||||||
|
fma 50 50 8 ; increment aces count at loc 8
|
||||||
|
:sc2 sub 1 50 5 ; subtract 1 from val to loc 5
|
||||||
|
jgt 5 :slp ; go to loop start if val > 1
|
||||||
|
cpy 1 2 3 ; assign score2 (at loc 3) = score1 (at loc 2)
|
||||||
|
sub 8 50 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 50 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
|
||||||
|
cpy 0 :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
|
||||||
|
cpy 1 2 62 ; copy the result into loc 62
|
||||||
|
cpy 0 :r2 99 ; set the return address
|
||||||
|
juc :gcard ; call the card generation procedure again (in loc 2)
|
||||||
|
:r2 fma 2 50 62 ; add this result into loc 62 (dealer's hand)
|
||||||
|
cpy 1 62 1 ; copy the dealer's hand as the proc parameter
|
||||||
|
cpy 0 :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
|
||||||
|
cpy 0 :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
|
||||||
|
cpy 1 2 63 ; copy the result into loc 63 (player's hand)
|
||||||
|
cpy 0 :r5 99 ; set the return address
|
||||||
|
juc :gcard ; call the card generation procedure again (in loc 2)
|
||||||
|
:r5 fma 2 50 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 50 5 ; check if 1
|
||||||
|
jeq 5 :hit ; jump to hit action if 1
|
||||||
|
sub 5 50 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
|
||||||
|
fma 61 50 61 ; double the bet
|
||||||
|
set 1 0 9 ; set the stand flag, proceed to the hit section next
|
||||||
|
:hit cpy 0 :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
|
||||||
|
fma 50 50 64 ; increment the round index
|
||||||
|
juc :skp ; jump to skip afterwards
|
||||||
|
:std set 1 0 9 ; set the stand flag
|
||||||
|
fma 50 50 64 ; increment the round index
|
||||||
|
:skp cpy 1 63 1 ; copy the current player's hand to loc 1 as a parameter
|
||||||
|
cpy 0 :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
|
||||||
|
cpy 1 3 72 ; copy the player score 2 to loc 72
|
||||||
|
set 0 0 9 ; set the stand flag to 0
|
||||||
|
:rnd cpy 1 62 1 ; start the inner dealer's loop, set the scoring procedure param
|
||||||
|
cpy 0 :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 cpy 0 :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 50 60 ; add half the bet (for blackjack calc)
|
||||||
|
:win fma 61 50 60 ; add bet first time
|
||||||
|
:push fma 61 50 60 ; add bet second time
|
||||||
|
juc :main ; reloop to beginning
|
||||||
|
:end nop 0 0 0 ; just a nop label for the program end
|
||||||
Reference in New Issue
Block a user