ttt.asm (3934B)
1 ;;; Copyright 2021 Gerd Beuster (gerd@frombelow.net). This is free 2 ;;; software under the GNU GPL v3 license or any later version. See 3 ;;; COPYING in the root directory for details. 4 5 ;;; If we are included in boot.asm, we 6 ;;; should not set the start address 7 8 .include "os.inc" 9 10 .dsection ttt_game 11 12 .section zero_page 13 ;; This temporary variable is used all over the place 14 tmp: .word ? 15 ;; Used by win_first_diagonal and win_first_diagonal 16 empty_field: .byte ? 17 ;; Used to check for forking opportunities 18 fork_board_rows: .byte ?, ?, ? 19 fork_board_columns: .byte ?, ?, ? 20 fork_board_diagonals: .byte ?, ?, ? 21 ;; Used to pass location of board 22 ;; to subroutines. 23 board_ptr: .word ? 24 ;; Sometimes we copy stuff from one board 25 ;; to the other. For this we have to 26 ;; point to the other board. 27 other_board_ptr: .word ? 28 ;; Default board location in memory 29 main_board: .byte ?, ?, ? 30 ;; Mirrored board location in memory 31 board_mirrored: .byte ?, ?, ? 32 ;; Pointer to init subroutine of 33 ;; first player 34 player_x_init_ptr: .word ? 35 ;; Pointer to ply subroutine of 36 ;; first player 37 player_x_ply_ptr: .word ? 38 ;; Pointer to init subroutine of 39 ;; second player 40 player_o_init_ptr: .word ? 41 ;; Pointer to ply subroutine of 42 ;; first player (2 bytes) 43 player_o_ply_ptr: .word ? 44 ;; Bord rendered as ASCII art 45 board_ascii: .byte ?, ?, ?, ?, ?, ?, ?, ?, ? 46 .send zero_page 47 48 .section ttt_game 49 50 .weak 51 RUN_TESTS = false 52 .endweak 53 54 start_ttt: 55 .block 56 cld 57 jsr lfsr.init 58 .if RUN_TESTS 59 jmp game_board_test 60 .endif 61 game_loop: 62 #io.PRINTSNL '** Tic-Tac-Toe **' 63 jsr io.putnl 64 lda #piece_x 65 jsr choose_player 66 lda #piece_o 67 jsr choose_player 68 jsr play_game 69 jsr io.getc 70 jmp game_loop 71 .bend 72 73 74 choose_player: 75 .block 76 pha 77 #io.PRINTS "Choose player " 78 pla 79 pha 80 clc 81 adc #'0' 82 jsr io.putc 83 #io.PRINTSNL ':' 84 #io.PRINTSNL '1 - Human' 85 #io.PRINTSNL '2 - Computer (perfect)' 86 #io.PRINTSNL '3 - Computer (random)' 87 #io.PRINTSNL '4 - Computer vs. Computer Stress Test' 88 jsr io.getc_seed_rng 89 cmp #'q' 90 bne not_quit 91 jmp ($fffc) ; Reset 92 not_quit: 93 cmp #'1' 94 beq set_human_player 95 cmp #'2' 96 beq set_computer_perfect_player 97 cmp #'3' 98 beq set_computer_random_player 99 cmp #'4' 100 bne cont 101 jmp computer_player_test 102 cont: 103 pla 104 jmp choose_player 105 ;; Board is not initialized at 106 ;; this point. Therefore we can use 107 ;; board_ptr to store a temporary 108 ;; variable. 109 set_human_player: 110 #mem.STORE_WORD human_player_init, tmp 111 #mem.STORE_WORD human_player_ply, board_ptr 112 jmp set_player 113 set_computer_perfect_player: 114 #mem.STORE_WORD computer_perfect_init, tmp 115 #mem.STORE_WORD computer_perfect_ply, board_ptr 116 jmp set_player 117 set_computer_random_player: 118 #mem.STORE_WORD computer_random_init, tmp 119 #mem.STORE_WORD computer_random_ply, board_ptr 120 set_player: 121 pla 122 cmp #piece_x 123 bne set_second_player 124 lda tmp 125 sta player_x_init_ptr 126 lda tmp+1 127 sta player_x_init_ptr+1 128 lda board_ptr 129 sta player_x_ply_ptr 130 lda board_ptr+1 131 sta player_x_ply_ptr+1 132 rts 133 set_second_player: 134 lda tmp 135 sta player_o_init_ptr 136 lda tmp+1 137 sta player_o_init_ptr+1 138 lda board_ptr 139 sta player_o_ply_ptr 140 lda board_ptr+1 141 sta player_o_ply_ptr+1 142 rts 143 .bend 144 145 .include "board.asm" 146 .include "human_player.asm" 147 .include "computer_player.asm" 148 149 .include "board_test.asm" 150 .include "computer_player_test.asm" 151 152 end_of_code: 153 .send ttt_game 154