Tic Tac Toe game

80 views
Skip to first unread message

Austin Erickson

unread,
Apr 15, 2023, 3:04:41 PM4/15/23
to uKenbak-1
I currently have to test each section to see if they work and convert to machine code.
===================================================
// Maybe less than 128 bytes, I think 115 bytes
// The program of tic tac toe
//  1 | 2 | 3
//  ---------
//  4 | 5 | 6
//  ---------
//  7 | 8 | 9
//  write down the board on a peice of paper
// b6 lighting up means it's your turn
// You will enter a number from 1 to 9 in binary
// and push b7 for the computers turn
// b7 lighting up means it's the computers turn
// b4-b0 will give a binary number for the computers move
// known issues: I have not put in a delay for the computers response
// Scroll to the end if a opcode is unfamiliar to you
===================================================

0. Starting Animation

LDR X #008 ; Loop counter
animation_loop:
SUB X #001
ADD A #001
JPM delay
STR A 200
SHL A 1
BNE X animation_loop
LDR X #007
clear_animation:
JPM delay
STR A 200
SHL A 1
BNE X clear_animation

1. Initialize the board by setting all the locations from 301 to 311 to 0, also 300 for turn count.

LDR A #000   ;Load zero into register A
LDR B #300    ; Start of tic tac toe board
LDR X #012    ; loop counter
clear_loop:
SUB X #001      ; decrement loop counter
STR A (B),X       ;   store zero into the last address (311) first
BNE X clear_loop   ; continue looping trough 311 to 301 then continue


2. When it's the player's turn:
2a. Turn on b6 at 200 to indicate the player's turn.

clear_display:
LDR X #000
STR X 200
SET 6 200
JMP get_input

2b. Get the player's move from input register 377.

JMP get_input
user_input:
CLR 7 X
CLR 6 X
ADD A 200
AND A X
BNE clear_display
ADD A X
STR A 200
LDR A #000
STR A 377
get_input:
LDR X 377
BEQ X get_input
SFS 7 377           ;skip to next step if button 7 pressed
JMP user_input
JMP test_if_valid_input


2c. Check if the player's move is valid (i.e., a number from 1 to 9). If not, go back to step 3b.

LDR A 200            ; load stored input
SUB A #100           ; remove player flag
BEQ A get_input      ; If the result is 0, the move is not valid, go back to get_input
SUB A #012           ; subtract 012 to check if value is from 001 to 011
BPL A clear_display  ; jump to start over if greater than 011

2d. Check if the location on the board corresponding to the player's move is empty (i.e., has a value of 0). If not, go back to step 3b.

LDR B 200
ADD B #200
LDR A (B)
BNE A clear_display

2e. Update the location on the board corresponding to the player's move with the player's marker (e.g., 1 for X or 2 for O).

LDR A #010  ; load players mark into A
STR A (B)   ; store players mark to location
LDR A 300   ; Load turn count
ADD A #001  ; increment turn count
STR A 300   ; update turn count

2f. Go to Step 4 to check if the player has won.

JMP check_for_win

3. When it's the computer's turn:
3a. Turn on b7 at 200 to indicate the computer's turn.

clear_display:
LDR X #000
STR X 200
SET 7 200

3b. Generate a random move that is not already taken (i.e., has a value of 0) on the board.

computers_move:
LDR B #300        ; set B to 300 for loop
random_move:
ADD B #001        ; start at 301
LDR A (B)         ; load value at current location into A
BNE A random_move ; try another move if not available


3c. Update the location on the board corresponding to the computer's move with the computer's marker.

LDR A #001  ; load computers mark into A
STR A (B)   ; store computers mark to location
LDR A 300   ; Load turn count
ADD A #001  ; increment turn count
STR A 300   ; update turn count

3d. Check if the computer has won the game. Go to step 4.

JMP check_for_win

4. Check for Win

check_for_win:
; Check for rows
LDR A 301
AND A 302
AND A 303
BNE A end_game

LDR A 304
AND A 305
AND A 306
BNE A end_game

LDR A 307
AND A 308
AND A 309
BNE A end_game

; Check for columns
LDR A 301
AND A 304
AND A 307
BNE A end_game

LDR A 302
AND A 305
AND A 308
BNE A end_game

LDR A 303
AND A 306
AND A 309
BNE A end_game

; Check for diagonals
LDR A 301
AND A 305
AND A 309
BNE A end_game

LDR A 303
AND A 305
AND A 307
BNE A end_game

check_for_tie ;if 376 is 9 then end_game
LDR A 376
SUB A #011
BEQ A end_game

SFS 6 200       ;if player flag is set then goto computer's turn
JMP players_turn
JMP computers_turn

5. When the game ends:
5a. Display an ending LED animation using only b4,b3,b2,b1,b0 at 200.

LDR A 200    ; load the current player
AND A #300
ADD A #100   ; to light up all LED's to the right of the player
end_game_animation:
SUB A #001
STR A 200
BNE A end_game_animation

5b. Go back to step 1 to start a new game.

JMP 004  ; Jump unconditional to start

6. Subroutines
delay:      ; call by using JPM delay
return_value_stored_here:000
STR X 373         ; after the return value is stored this is the line that is executed first
LDR X #000
delay_loop:
SUB X #001
BNE X delay_loop
LDR X 373         ; get stored X from call save for X
JMP (220)

===================================================
Operations for the Kenbak-1
ADD Add
AND Logical AND
BEQ Branch if equal
BGT Branch if greater than
BMI Branch if minus
BNE Branch if not equal
BPL Branch if plus
CLR Clear bit
JPM Jump and Mark 364
JMP Jump (unconditional) 344
JEQ Jump and Mark if equal
JGT Jump and Mark if greater than
JMI Jump and Mark if minus
JNE Jump and Mark if not equal
JPL Jump and Mark if plus
LDN Load negative
LDR Load register
ORA Logical OR
ROL Rotate left
ROR Rotate right
SFC Skip if bit is Clear
SET Set bit
SFS Skip if bit is Set
SHL Shift left
SHR Shift right
STR Store register
SUB Subtract
NOP No operation
HLT Halt the program
===================================================

Austin Erickson

unread,
Apr 15, 2023, 5:27:18 PM4/15/23
to uKenbak-1
I started with the subroutines and created this radical subroutine

//Once you enter the below code in memory you can use this one line to create a delay and it will not affect your registers when it is called back.
364 220 JMD U 220 // here I'm using mem 220 for the subroutine. you can stack these for as long as a delay you would like in your program.

//place this code anywhere in memory I recumbent 220 or 320
220: 000 MARK FROM JUMP
034 204 STR A 376
134 205 STR B 375
234 206 STR X 374
223 367 LDR X #367
027 003 LDR A (P),X
223 023 LDR X #023
037 003 STR A (P),X
123 000 LDR B #000
224 003 LDR X P
203 004 ADD X 004
113 001 SUB B #001
153 002 BNE B 002
024 204 LDR A 376
124 205 LDR B 375
224 206 LDR X 374
344 377 JPD U MOD

Vicente González

unread,
Apr 16, 2023, 8:16:41 PM4/16/23
to Austin Erickson, uKenbak-1
I like your relocatable delay routine,
thanks

Virus-free.www.avast.com

--
You received this message because you are subscribed to the Google Groups "uKenbak-1" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ukenbak-1+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ukenbak-1/53b8133a-ff56-4fda-b111-d0a6dbf7404bn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages