109 lines
4.1 KiB
Plaintext
109 lines
4.1 KiB
Plaintext
; Bulls and Cows game in N8A for n808 VM
|
|||
|
|
; Enter your guesses digit by digit, you have 7 attempts
|
||
|
|
; After each guess, the game replies with bulls.cows
|
||
|
|
; (if you have 4.0, you win)
|
||
|
|
; On victory or after running out of attempts, the game
|
||
|
|
; displays the target digits and halts
|
||
|
|
; Created by Luxferre in 2025, released into public domain
|
||
|
|
|
||
|
|
; constants/variables section
|
||
|
|
#1 va
|
||
|
|
#2 vb
|
||
|
|
#3 vc
|
||
|
|
#4 vd
|
||
|
|
#10 c10
|
||
|
|
#11 counter
|
||
|
|
#12 octr
|
||
|
|
#13 ictr
|
||
|
|
#14 frac
|
||
|
|
#20 bcctr
|
||
|
|
#60 dig_0
|
||
|
|
#61 dig_1
|
||
|
|
#62 dig_2
|
||
|
|
#63 dig_3
|
||
|
|
#64 dig_4
|
||
|
|
#65 dig_5
|
||
|
|
#66 dig_6
|
||
|
|
#67 dig_7
|
||
|
|
#68 dig_8
|
||
|
|
#69 dig_9
|
||
|
|
#70 src_base ; source base address
|
||
|
|
#71 trg_base ; target base address
|
||
|
|
|
||
|
|
; constant/variable assignments
|
||
|
|
dca 10 @c10 ; constant 10
|
||
|
|
dca 0 @dig_0 ; assign digits from 0 to 9
|
||
|
|
dca 1 @dig_1
|
||
|
|
dca 2 @dig_2
|
||
|
|
dca 3 @dig_3
|
||
|
|
dca 4 @dig_4
|
||
|
|
dca 5 @dig_5
|
||
|
|
dca 6 @dig_6
|
||
|
|
dca 7 @dig_7
|
||
|
|
dca 8 @dig_8
|
||
|
|
dca 9 @dig_9
|
||
|
|
dca 60 @src_base ; set the source base address (60)
|
||
|
|
dca 80 @trg_base ; set the target base address (80)
|
||
|
|
dca 10 @frac ; prepare the @frac variable
|
||
|
|
set 0 0 @frac ; set 0.1 to @frac
|
||
|
|
|
||
|
|
; main logic
|
||
|
|
|
||
|
|
; random unique 4-digit generator (into the addresses 81..84)
|
||
|
|
|
||
|
|
dca 4 @counter ; set the counter to 4
|
||
|
|
:dsl dca 9 @va ; digit selection loop start, set the upper boundary to @va
|
||
|
|
rnd 0 @va @va ; select a random digit from 0 to 9 inclusively into @va
|
||
|
|
add @src_base @va ; add the source base address to @va
|
||
|
|
dca @vb @vb ; init @vb with its own address
|
||
|
|
ivc @va @vb ; copy the value at address in @va into @vb
|
||
|
|
dca 10 @vc ; init @vc with the constant 10
|
||
|
|
sub @vb @vc ; @vb - 10 => @vc
|
||
|
|
jeq @vc :dsl ; jump back to the digit selection if the value at @vc is 0
|
||
|
|
ica 10 @va ; set the value at the address in @va to 10
|
||
|
|
dva @counter @va ; copy the counter to @va
|
||
|
|
add @trg_base @va ; add the target base address to the counter in @va
|
||
|
|
dca @vb @vc ; copy the address of @vb into @vc
|
||
|
|
ivc @vc @va ; copy the value from @vb (address stored at @vc) to the cell address at @va
|
||
|
|
dec @counter ; decrement the counter
|
||
|
|
jgt @counter :dsl ; jump back to digit selection if it still is above zero
|
||
|
|
|
||
|
|
; player guess loop
|
||
|
|
|
||
|
|
dca 7 @counter ; set the attempt count to 7
|
||
|
|
:prm inp 91 94 ; input the guess digit by digit into loc 91..94
|
||
|
|
dca 90 @src_base ; set 90 as the new source base address
|
||
|
|
dca 0 @bcctr ; init bull/cow counter
|
||
|
|
dca 4 @octr ; init outer loop counter
|
||
|
|
:olp dca 4 @ictr ; start of the outer loop, init inner loop counter
|
||
|
|
:ilp dva @octr @va ; start of the inner loop, copy the outer counter
|
||
|
|
dva @trg_base @vb ; fetch the target base address
|
||
|
|
add @va @vb ; get the address of the target digit in @vb
|
||
|
|
dva @ictr @va ; copy the inner counter
|
||
|
|
dva @src_base @vc ; fetch the source base address
|
||
|
|
add @va @vc ; get the address of the entered digit in @vc
|
||
|
|
dca @va @va ; init @va with its own address
|
||
|
|
ivc @vb @va ; copy the target digit into @va
|
||
|
|
dca @vd @vd ; init @vd with its own address
|
||
|
|
ivc @vc @vd ; copy the entered digit into @vd
|
||
|
|
sub @vd @va ; save the digits difference into @va
|
||
|
|
jne @va :ei ; jump to the next comparator if the digits don't match
|
||
|
|
dva @ictr @vb ; load the inner counter into @vb
|
||
|
|
sub @octr @vb ; save the _counters_ difference into @vb
|
||
|
|
jne @vb :cc ; jump to the cow counter if the indices don't match
|
||
|
|
inc @bcctr ; increment the bull counter if they do
|
||
|
|
juc :ei ; skip the next instruction
|
||
|
|
:cc add @frac @bcctr ; increase the cow counter if they don't
|
||
|
|
:ei dec @ictr ; decrement the inner loop counter
|
||
|
|
jgt @ictr :ilp ; jump to the start of the inner loop if still > 0
|
||
|
|
dec @octr ; decrement the outer loop counter
|
||
|
|
jgt @octr :olp ; jump to the start of the outer loop if still > 0
|
||
|
|
out @bcctr @bcctr ; output the match result
|
||
|
|
dca 4 @va ; store the constant 4 into @va
|
||
|
|
sub @bcctr @va ; get the difference between bull/cow counter and 4
|
||
|
|
jeq @va :end ; jump to the last instruction if they match
|
||
|
|
dec @counter ; decrement the attempt counter
|
||
|
|
jgt @counter :prm ; jump to guess prompt if the counter is above 0
|
||
|
|
:end out 81 84 ; output the target number before halting
|
||
|
|
|