; 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