Guess the number
First edition
Program tries to guess the number (1..100) by showing the guesses in A register and halting. User must set ‘guess’ field to non-zero if A is greater than the number and press Start button to continue.
MOVI B, 1 ; 00: 10000001 00000001
MOVI C, 101 ; 01: 10000010 01100101
Loop:
ADD A, B, C ; 02: 01001000 00011010
SHR A, A ; 03: 01111000 00001100
HALT ; 04: 00010000 00000000
MOVI D, guess ; 05: 10000011 iiiiiiii
OR F, D, D ; 06: 01101000 00110011
JMP NZ, Greater ; 07: 11100111 00001010
MOV B, A ; 08: 00011001 00000000
JMP Loop ; 09: 10000111 00000010
Greater:
MOV C, A ; 0a: 00011010 00000000
JMP Loop ; 0b: 10000111 00000010
Second edition
Program tries to guess the number (1..100) by showing the guesses in A register and halting. User must reset D to zero if A is less than the number and press Start button to continue.
MOVI B, 1 ; 00: 10000001 00000001
MOVI C, 101 ; 01: 10000010 01100101
Loop:
ADD A, B, C ; 02: 01001000 00011010
SHR A, A ; 03: 01111000 00001100
MOVI D, 1 ; 04: 10000011 00000001
HALT ; 05: 00010000 00000000
OR F, D, D ; 06: 01101000 00110011
JMP NZ, Greater ; 07: 11100111 00001010
MOV B, A ; 08: 00011001 00000000
JMP Loop ; 09: 10000111 00000010
Greater:
MOV C, A ; 0a: 00011010 00000000
JMP Loop ; 0b: 10000111 00000010
The subtraction game (21 game)
There are 21 matches. Two players take 1..3 matches every turn. The player who takes the last match wins. The computer is the second player.
Program ends when A=0x00 or A=0xff. In the first case the winner is computer, in the second case - you are the winner.
First edition
When the execution stops, the number of matches is in register A, and the player’s move should be encoded in the lower 8 bits of instruction at address 02 (which is the field ‘move’).
MOVI A, 21 ; 00: 10000000 00001101
Loop:
HALT ; 01: 00010000 00000000
MOVI B, move ; 02: 10000001 000000mm
SUB A, A, B ; 03: 01011000 00001001
AND C, A, 3 ; 04: 01100010 10001011
MOVI Z, C, 1 ; 05: 10010010 00000001
SUB A, A, C ; 06: 01011000 00001010
JMP Loop ; 07: 10000111 00000001
Second edition
When the execution stops, player must take the ‘matches’ - reset 1 to 2 of B, C, D registers. Every register stores 1 ‘match’ and the computer will subtract non-zero registers from A.
MOVI A, 21 ; 00: 10000000 00010101
Loop:
MOVI B, 1 ; 01: 10000001 00000001
MOVI C, 1 ; 02: 10000010 00000001
MOVI D, 1 ; 03: 10000011 00000001
HALT ; 04: 00010000 00000000
SUB A, A, B ; 05: 01011000 00001001
SUB A, A, C ; 06: 01011000 00001010
SUB A, A, D ; 07: 01011000 00001011
AND C, A, 3 ; 08: 01100010 10001011
MOVI Z, C, 1 ; 09: 10010010 00000001
SUB A, A, C ; 0a: 01011000 00001010
JC Exit ; 0b: 10110111 00001101
JNZ Loop ; 0c: 11100111 00000001
Exit:
HALT ; 0d: 00010000 00000000
Tic-tac-toe
Board is stored in the registers
Idea by DimaThenekov
But not working yet (not enough code memory)
; data storage
; o-o A: 00|000||101|
; xxo -> B: 00|110||001|
; oxx C: 00|011||100|
; move encoding
; S: 0000rrcc - row & col (1-3)
; columns are numbered from right to left
; S: xxxx
; 765x
; ba9x
; fedx
; 34 instructions
Start:
HALT
; board registers
MOVI А, 0
MOVI B, 0
MOVI C, 0
; X move
Main_loop:
; input cell number into S in the next instruction
HALT
MOVI S, 5
CALL num2reg
ADD M, M, M
ADD M, M, M
ADD M, M, M
CALL set_reg
; O move
; geting seed
XOR D, A, B
XOR D, D, C
ADD D, D, 4
O_move_loop:
ADD D, D, 1
; r=0 or c=0 are invalid values
AND F, D, 3
JMP Z, O_move_loop
SHR S, D
AND F, S, 6
JMP Z, O_move_loop
MOVI S, 0xf
AND S, S, D
CALL num2reg
SUB F, S, 2
JMP CY, O_move_row1
JMP Z, O_move_row2
O_move_row3:
AND F, C, M
JMP O_move_test
O_move_row1:
AND F, A, M
JMP O_move_test
O_move_row2:
AND F, B, M
O_move_test:
JMP NZ, O_move_loop
O_move:
CALL set_reg
JMP Main_loop
set_reg:
; M(1<<n)
; S(num of reg, 1..3)
; 31 instructions
SUB F, S, 2
JMP NC, set_reg_3
JMP Z, set_reg_2
OR A, A, M
MOV D, A
JMP check_win
set_reg_2:
OR B, B, M
MOV D, B
JMP check_win
set_reg_3:
OR C, C, M
MOV D, C
check_win:
; vertical test
AND S, A, B
AND S, S, C
JMP NZ, Start
MOV D, L
; horizontal test
MOVI S, 0x38
SUB F, D, S
JMP Z, Start
SUB F, D, 7
JMP Z, Start
; diagonal1 test
SHR S, A
AND S, S, B
SHR S, S
AND S, S, C
JMP NZ, Start
; diagonal2 test
SHR S, C
AND S, S, B
SHR S, S
AND S, S, A
JMP NZ, Start
MOV PC, L
num2reg:
; input: S register(0..f)
; output: M(1<<S mod 4)
; S(S div 4)
; 6 instructions
AND M, S, 3
SUB F, M, 3
MOVI Z M, 4
SHR S, S
SHR S, S
MOV PC, L
Board is not stored at all
Computer moves first (to the center). After that, it chooses the cell, using last human’s move. Valideness of the moves is not checked.
The order of moves always leads to the victory or tie.
Numbering of the cells:
012
783
654
@input()
{
HALT();
return INPUT();
}
@win(x)
{
PRINT(x);
PRINT(9);
PRINT(9);
HALT();
}
@check_win(m, p)
{
x = (m + 4) & 7;
if (x != p)
win(x);
}
@move_left(p)
{
m = (p - 1) & 7;
PRINT(m);
return m;
}
@main()
{
PRINT(8);
m = move_left(input());
p = input();
check_win(m, p);
// computer moved to the corner
if (Z(m & 1))
{
m = move_left(m);
p = input();
check_win(m, p);
win(m - 1); // & 7?
}
m = move_left(p);
p = input();
check_win(m, p);
m = move_left(p);
p = input();
check_win(m, p);
// tie
PRINT(9);
HALT();
}
main:
MOVI A, 8 00: 10000000 00001000
STORE A, 0x90 01: 00110000 10010000
HALT 02: 00010000 00000000
LOAD A, 0x90 03: 00100000 10010000
STORE A, 0x90 04: 00110000 10010000
CALL move_left 05: 10001111 00011100
MOV C, A 06: 00011010 00000000
CALL load 07: 10001111 00101010
CALL check_win 08: 10001111 00100000
TST C, 1 09: 01100000 10100001
JMP NZ, tie 0a: 11100111 00010010
MOV A, C 0b: 00011000 00100000
CALL move_left 0c: 10001111 00011100
MOV C, A 0d: 00011010 00000000
CALL load 0e: 10001111 00101010
CALL check_win 0f: 10001111 00100000
SUB A, C, 1 10: 01011000 10101001
JMP win 11: 10000111 00100101
tie:
MOV A, B 12: 00011000 00010000
CALL move_left 13: 10001111 00011100
CALL load 14: 10001111 00101010
CALL check_win 15: 10001111 00100000
MOV A, B 16: 00011000 00010000
CALL move_left 17: 10001111 00011100
CALL load 18: 10001111 00101010
CALL check_win 19: 10001111 00100000
MOVI A, 9 1a: 10000000 00001001
STORE A, 0x90
HALT 1b: 00010000 00000000
move_left:
SUB A, A, 1 1c: 01011000 10001001
AND A, A, 7 1d: 01100000 10001111
STORE A, 0x90 1e: 00110000 10010000
RET 1f: 00011111 01100000
check_win:
ADD A, A, 4 20: 01001000 10001100
AND A, A, 7 21: 01100000 10001111
CMP A, B 22: 01011000 00000001
JMP NZ, win 23: 11100111 00100101
RET 24: 00011111 01100000
win:
STORE A, 0x90 25: 00110000 10010000
MOVI A, 9 26: 10000000 00001001
STORE A, 0x90 27: 00110000 10010000
STORE A, 0x90 28: 00110000 10010000
HALT 29: 00010000 00000000
load:
HALT 2a: 00010000 00000000
LOAD B, 0x90 2b: 00100001 10010000
STORE B, 0x90 2c: 00110001 10010000
RET 2d: 00011111 01100000
Lonely queen
Trying to move chess queen into the lower left corner by moving it left and down.
Initial position:
800000000
700000100
600000000
500000000
400000000
300000000
200000000
100000000
012345678
@check_end(x, y, p)
{
// print field
i = 8;
while (i > 0)
{
PRINT(i);
j = 1;
while (j < 9)
{
if (i == y && j == x)
PRINT(1);
else
PRINT(0);
j += 1;
}
i -= 1;
PRINT('\n');
}
j = 0;
while (j < 9)
{
PRINT(j);
j += 1;
}
PRINT('\n');
// check game end
if (x == 1 && y == 1)
{
PRINT(p);
PRINT('\n');
HALT;
}
}
@main()
{
x = 6;
y = 7;
while (1)
{
@check_end(x, y, 2);
// player's move
do
{
a = INPUT();
b = INPUT();
}
while (a >= x || b >= y || !(a == b || !a || !b) || !(a | b));
x -= a;
y -= b;
@check_end(x, y, 1);
// computer's move
// TODO: choose move
if (x > 1)
x -= 1;
else
y -= 1;
}
}