001: ; brilliant.g 002: 003: ; a variant of smart.g 004: ; avoid entering dead-ends unless lambda-man is there 005: 006: %lastx :: [1] 007: %lasty :: [2] 008: %clkl :: [3] 009: %clkh :: [4] 010: %curmode :: [5] ; 0 = chase, 1 = scatter 011: %scatterx :: [6] 012: %scattery :: [7] 013: %principal :: [8] 014: %secondary :: [9] 015: ; declarations for follow 016: %good_dir_val :: [248] 017: %good_dir_num :: [249] 018: %current_x :: [250] 019: %current_y :: [251] 020: %current_dir :: [252] 021: 022: ; clock 023: add %clkl, 8 ; clock high period 256/8 = 32 024: jgt clock_done, %clkl, 0 025: inc %clkh 026: clock_done: 027: 028: ; detect sudden jumps in position and reset the clock 029: int 3 030: int 5 031: sub a, %lastx 032: sub b, %lasty 033: add a, b 034: add a, 1 035: jlt detect_done, a, 3 036: mov %clkl, 0 037: mov %clkh, 0 038: detect_done: 039: int 3 040: int 5 041: mov %lastx, a 042: mov %lasty, b 043: 044: ; decide between chase and scatter 045: 046: ; if panic mode, scatter 047: 048: int 3 049: int 6 050: jeq scatter, a, 1 ; panic mode -> scatter 051: jeq chase, a, 2 ; invisible mode -> chase 052: ; normal mode -> scatter/chase according to clock 053: 054: ; if clock-high = 0 mod 4, scatter 055: mov c, %clkh 056: and c, 3 057: jgt chase, c, 0 058: 059: scatter: 060: jeq scatter_continue, %curmode, 1 061: mov %curmode, 1 062: mov c, %clkh 063: div c, 8 064: int 3 065: add a, c 066: mov %scatterx, a 067: div a, 2 068: mov %scattery, a 069: and %scatterx, 1 070: and %scattery, 1 071: mul %scatterx, 30 072: mul %scattery, 30 073: sub %scatterx, 15 074: sub %scattery, 15 075: int 3 076: int 1 077: add %scatterx, a 078: add %scattery, b 079: jlt clipxdone, %scatterx, 128 080: mov %scatterx, 0 081: clipxdone: 082: jlt clipydone, %scattery, 128 083: mov %scattery, 0 084: clipydone: 085: scatter_continue: 086: mov a, %scatterx 087: mov b, %scattery 088: jmp go_to 089: 090: chase: 091: mov %curmode, 0 092: int 1 ; get lman's coordinates in A and B 093: 094: go_to: 095: mov c, a ; c = lman.x 096: mov d, b ; d = lman.y 097: int 3 ; get this ghost's index 098: int 5 099: mov e, a ; e = my.x 100: mov f, b ; f = my.y 101: 102: ; compute direction 103: 104: mov a, 1 ; alpha 105: mov b, 1 ; phi 106: mov g, c 107: sub g, e ; absx = dx = lman.x - my.x 108: mov h, f 109: sub h, d ; absy = -dy = my.y - lman.y 110: 111: jgt l1, c, e ; if lman.x =< my.x then 112: add a, 6 113: mov g, e 114: sub g, c ; absx = -dx 115: xor b, 254 ; phi := -phi 116: l1: 117: jlt l2, d, f ; if lman.y >= my.y then 118: xor a, 2 119: mov h, d 120: sub h, f ; absy = dy 121: xor b, 254 ; phi := -phi 122: 123: 124: l2: 125: ; from now on, c and d are the main and secondary direction 126: mov c, a 127: mov d, a 128: 129: jlt l3, g, h ; if absx >= absy then 130: xor b, 254 ; phi := -phi 131: l3: 132: sub c, b ; add phi for main direction 133: add d, b ; subtract phi for secondary direction 134: 135: l4: 136: div c, 2 ; main direction of lambda-man 137: div d, 2 ; secondary direction 138: and c, 3 139: and d, 3 140: test: 141: int 3 142: int 5 143: mov %principal, c 144: mov %secondary, d 145: 146: mov [254], c 147: mov [255], ret1 148: mov PC, next ; get coordinates of square in direction c 149: ret1: 150: int 7 ; get square 151: jeq secondary, a, 0 ; go in main direction if not wall 152: 153: int 3 154: int 6 ; get ghost current direction 155: add b, 2 ; reverse the direction 156: and b, 3 ; reverse the direction, cont. 157: and %principal, 3 ; clip the principal direction 158: jeq secondary, b, %principal ; check if principal direction is forbidden 159: int 3 160: int 5 161: mov %current_dir, %principal 162: mov [253], testing_if_good_path 163: mov PC, follow 164: testing_if_good_path: 165: MOV H, A 166: INT 3 167: INT 5 168: ;; MOV F, A 169: ;; MOV G, B 170: ;; MOV D, %principal 171: ;; MOV E, %secondary 172: ;; MOV C, %curmode 173: ;; int 174: jmp go ; principal direction is valid 175: 176: secondary: 177: mov %principal, %secondary ; go in secondary direction 178: 179: go: 180: and %principal, 3 ; reduce modulo 4 181: mov a, %principal 182: int 0 ; direction is in a 183: hlt 184: 185: 186: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 187: ; follow a <- X, b <- Y, %current_dir<- DIR, [253] <- RETURN 188: ; return 0 in a if it is a good choice, and something else otherwise 189: follow: 190: ;; MOV C, %current_dir ; debug 191: ;; MOV H, 42 ; debug 192: ;; int 8 ; debug 193: MOV [254], %current_dir 194: MOV [255], lfollow1 195: MOV PC, next 196: lfollow1: 197: ; we are in the first tile of the path 198: ;; MOV H, 43 199: ;; INT 8 200: MOV %good_dir_num, 0 201: MOV %current_x, a 202: MOV %current_y, b 203: 204: ; check for the presence of lambda-man 205: int 1 206: jeq checky, a, %current_x 207: jmp checkdone 208: checky: 209: jeq return_ok_lambda, b, %current_y 210: checkdone: 211: mov a, %current_x 212: mov b, %current_y 213: MOV [254], %current_dir ; prepare the call to next for current dir 214: MOV [255], lwalling0 ; prepare the call... 215: MOV PC, next 216: lwalling0: 217: ;; MOV H, 44 218: ;; INT 8 219: INT 7 220: JEQ lwalling2, A, 0 221: MOV %good_dir_val, %current_dir 222: INC %good_dir_num 223: lwalling1: 224: INC %current_dir 225: AND %current_dir, 3 226: MOV a, %current_x 227: MOV b, %current_y 228: ;; mov c, %current_dir ; debug 229: ;; mov h, 45 ; debug 230: ;; INT 8 ; debug 231: MOV [254], %current_dir ; prepare the call to next for current dir 232: MOV [255], lwalling2 ; prepare the call... 233: MOV PC, next 234: lwalling2: 235: ;; MOV H, 44 236: ;; INT 8 237: INT 7 238: JEQ lwalling3, A, 0 239: MOV %good_dir_val, %current_dir 240: INC %good_dir_num 241: lwalling3: 242: ADD %current_dir, 2 243: AND %current_dir, 3 244: MOV a, %current_x 245: MOV b, %current_y 246: MOV [254], %current_dir ; prepare the call to next for current dir 247: MOV [255], lwalling4 ; prepare the call... 248: MOV PC, next 249: lwalling4: 250: ;; MOV H, 44 251: ;; INT 8 252: INT 7 253: JEQ lwalling5, A, 0 254: MOV %good_dir_val, %current_dir 255: INC %good_dir_num 256: lwalling5: 257: JEQ not_ok, %good_dir_num, 0 258: JEQ continue, %good_dir_num, 1 259: ;return_ok_lambda: 260: return_ok: 261: MOV A,0 262: MOV PC, [253] 263: not_ok: 264: MOV A,1 265: MOV PC, [253] 266: continue: 267: MOV %current_dir, %good_dir_val 268: MOV A, %current_x 269: MOV B, %current_y 270: MOV PC, follow 271: 272: return_ok_lambda: ; debug 273: int 8 ; debug 274: jmp return_ok ; debug 275: 276: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 277: ; next a <- X, b <- Y, [254] <- DIR, [255] <- RETURN 278: ;; this function has zero bug. 279: next: 280: MUL [254], 2 281: ADD [254], 3 282: MOV H, PC 283: ADD H, [254] 284: MOV PC, H 285: SUB B, 1 ; code for 0 286: JMP next_end 287: ADD A, 1 ; code for 1 288: JMP next_end 289: ADD B, 1 ; code for 2 290: JMP next_end 291: SUB A, 1 ; code for 3 292: next_end: 293: MOV PC, [255] 294: