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: