001: ; smart.g 002: 003: ; alternate between scatter mode and chase mode 004: ; in scatter mode, move out from current position in a direction that depends 005: ; on the ghost number 006: ; in chase mode, move into the direction of lambda-man. 007: 008: %lastx :: [1] 009: %lasty :: [2] 010: %clkl :: [3] 011: %clkh :: [4] 012: %curmode :: [5] ; 0 = chase, 1 = scatter 013: %scatterx :: [6] 014: %scattery :: [7] 015: 016: ; clock 017: add %clkl, 8 ; clock high period 256/8 = 32 018: jgt clock_done, %clkl, 0 019: inc %clkh 020: clock_done: 021: 022: ; detect sudden jumps in position and reset the clock 023: int 3 024: int 5 025: sub a, %lastx 026: sub b, %lasty 027: add a, b 028: add a, 1 029: jlt detect_done, a, 3 030: mov %clkl, 0 031: mov %clkh, 0 032: detect_done: 033: int 3 034: int 5 035: mov %lastx, a 036: mov %lasty, b 037: 038: ; decide between chase and scatter 039: 040: ; if panic mode, scatter 041: 042: int 3 043: int 6 044: jeq scatter, a, 1 ; panic mode -> scatter 045: jeq chase, a, 2 ; invisible mode -> chase 046: ; normal mode -> scatter/chase according to clock 047: 048: ; if clock-high = 0 mod 4, scatter 049: mov c, %clkh 050: and c, 3 051: jgt chase, c, 0 052: 053: scatter: 054: jeq scatter_continue, %curmode, 1 055: mov %curmode, 1 056: mov c, %clkh 057: div c, 8 058: int 3 059: add a, c 060: mov %scatterx, a 061: div a, 2 062: mov %scattery, a 063: and %scatterx, 1 064: and %scattery, 1 065: mul %scatterx, 30 066: mul %scattery, 30 067: sub %scatterx, 15 068: sub %scattery, 15 069: int 3 070: int 1 071: add %scatterx, a 072: add %scattery, b 073: jlt clipxdone, %scatterx, 128 074: mov %scatterx, 0 075: clipxdone: 076: jlt clipydone, %scattery, 128 077: mov %scattery, 0 078: clipydone: 079: mov a, %scatterx 080: mov b, %scattery 081: int 8 082: scatter_continue: 083: mov a, %scatterx 084: mov b, %scattery 085: jmp go_to 086: 087: chase: 088: mov %curmode, 0 089: int 1 ; get lman's coordinates in A and B 090: 091: go_to: 092: mov c, a ; c = lman.x 093: mov d, b ; d = lman.y 094: int 3 ; get this ghost's index 095: int 5 096: mov e, a ; e = my.x 097: mov f, b ; f = my.y 098: 099: ; compute direction 100: 101: mov a, 1 ; alpha 102: mov b, 1 ; phi 103: mov g, c 104: sub g, e ; absx = dx = lman.x - my.x 105: mov h, f 106: sub h, d ; absy = -dy = my.y - lman.y 107: 108: jgt l1, c, e ; if lman.x =< my.x then 109: add a, 6 110: mov g, e 111: sub g, c ; absx = -dx 112: xor b, 254 ; phi := -phi 113: l1: 114: jlt l2, d, f ; if lman.y >= my.y then 115: xor a, 2 116: mov h, d 117: sub h, f ; absy = dy 118: xor b, 254 ; phi := -phi 119: 120: 121: l2: 122: ; from now on, c and d are the main and secondary direction 123: mov c, a 124: mov d, a 125: 126: jlt l3, g, h ; if absx >= absy then 127: xor b, 254 ; phi := -phi 128: l3: 129: sub c, b ; add phi for main direction 130: add d, b ; subtract phi for secondary direction 131: 132: l4: 133: div c, 2 ; main direction of lambda-man 134: div d, 2 ; secondary direction 135: and c, 3 136: and d, 3 137: 138: test: 139: int 3 140: int 5 141: mov [254], c 142: mov [255], ret1 143: mov PC, next ; get coordinates of square in direction c 144: ret1: 145: int 7 ; get square 146: jeq secondary, a, 0 ; go in main direction if not wall 147: 148: int 3 149: int 6 150: add b, 2 151: and b, 3 152: and c, 3 153: jeq secondary, b, c 154: jmp go 155: 156: secondary: 157: mov c, d ; go in secondary direction 158: 159: go: 160: and c, 3 ; reduce modulo 4 161: mov a, c 162: int 0 ; direction is in a 163: hlt 164: 165: 166: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 167: ; next a <- X, b <- Y, [254] <- DIR, [255] <- RETURN 168: ;; this function has zero bug. 169: next: 170: MUL [254], 2 171: ADD [254], 3 172: MOV H, PC 173: ADD H, [254] 174: MOV PC, H 175: SUB B, 1 ; code for 0 176: JMP next_end 177: ADD A, 1 ; code for 1 178: JMP next_end 179: ADD B, 1 ; code for 2 180: JMP next_end 181: SUB A, 1 ; code for 3 182: next_end: 183: MOV PC, [255] 184: 185: 186: 187: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 188: