Decoded: Rogue (1980) by Toy, Arnold, Wichman
DOS version (1983) by Mel Sibony and Jon Lane
Source file: CHASE.C
Beginner friendly, line-by-line code walkthrough by MaiZure

CHASE.C defines the basic AI procedure for monsters chasing the player

Original code:
https://britzl.github.io/roguearchive/

Original code with line numbers
http://www.maizure.org/projects/decoded-rogue/CHASE_linenum.txt



1     COMMENT
2     COMMENT
3     COMMENT
4     COMMENT
5     COMMENT
6     BLANK
7     Include the game header
8     Include the console management header
9     BLANK
10    Define a probability basis for dragons shooting flames
11    BLANK
12    Global holding the position monster is running to
13    BLANK
14    COMMENT
15    COMMENT
16    COMMENT
17    COMMENT

UPDATE MOVING MONSTERS

18    Defines runners with no arguments
19    BLOCK START - runners, each running monster takes a step
20    Declare a pointer to a monster
21    Declare a variable for distance
22    BLANK
23    Loop through all monsters on the level
24    If the monster isn't held but is running...
25    Calculate the distance between the monster and the player
26    If the monster isn't slow, is a slime with distance, or is a slow turn..
27    Allow the mosnter to make a make
28    If the monster is hasted..
29    Allow it to move
30    Update the distance after the possible move
31    If the monster is flying...
32    It gets another amonter
33    In all cases, it's time to move again
34    End check for running monster
35    End check for all monsters
36    BLOCK END - runners
37    BLANK
38    COMMENT
39    COMMENT
40    COMMENT
41    COMMENT

CHASE AI

42    Define do_chase with one argument
43    Argument 1 is a pointer to the monster doing the casing
44    BLOCK START - do_chase, set one mosnter off chasing a target
45    Declare an iterator and distance. Init a minimum distance of 2^15-1
46    Declare an unused character
47    Declare a flag for a door
48    Declare a pointer to an object
49    Declare a pointer to a room
50    Declare two pointers to rooms, one for the chasee and chaser
51    Declare a temporary coordinate
52    BLANK
53    Get the chaser's room
54    If the monster is guarding gold that's gone...
55    Chase the player
56    Find the target's room
57    If the monster isn't chasing the player...
58    Find the room of the target
59    If the target isn't in a room..
60    Don't chase at all
61    COMMENT
62    COMMENT
63    COMMENT
64    Check and grab the chase target if it's a door
65    BLANK
66    BLANK
67    COMMENT
68    COMMENT
69    COMMENT
70    COMMENT
71    COMMENT
72    Label for repeated search
73    If the chaser is not in the same room as a target and isn't in a maze..
74    BLOCK START - Find room exit
75    Loop through all the exits
76    Get the distance between the exit and the target (player)
77    If the distance is better than the min found so far...
78    Heard towards this exit
79    Match distances
80    End check for best exit
81    Repeat loop for exits
82    If this target is a door...
83    Get the passage number
84    Set door to false
85    Repeat this search
86    End check for door
87    BLOCK END - Find room exit
88    Otherwise, player is near - get the destination
89    COMMENT
90    COMMENT
91    COMMENT
92    COMMENT
93    COMMENT
94    If the monster is a Dragon or Ice monster...
95    And the monster is in the same row/column as the player...
96    Or in the same diagonal...
97    And is more than one square away...
98    But less than the maximum range of a flame/frost bolt attack...
99    and hasn't been interrupt while rolling a 20% chance...
100   START BLOCK - Shoot at the player
101   Monster stops running
102   Get the y offset
103   Get the x offset
104   Select name of attack type and FIRE!
105   Return from monster chase
106   BLOCK END - Shoot at the player
107   End of check for near/far hero
108   COMMENT
109   COMMENT
110   COMMENT
111   COMMENT
112   COMMENT
113   If we've made it this far...time to chase the player
114   If the monster is at the hero..
115   Attack the player
116   Return from chase
117   Otherwise, monster might want to pick up an object
118   Loop through all objects on the level
119   If the monster is on the object...
120   Declare a character byte
121   BLANK
122   Remove the object from the level
123   Put the object in the monster's inventory
124   Get the map character at that location..
125   ...which may be a floor or passage if we're in a room
126   If the player can see the position...
127   Draw that character on the floor
128   The monster needs a new target
129   Break from the object loop
130   End check for object position match
131   End check for objects to pick up
132   If the monster is a flytrap...
133   Return from further movement
134   COMMENT
135   COMMENT
136   COMMENT
137   If the old character in the position is not the player...
138   and it's a blank space that the player can see...
139   And the space is actually a floor...
140   Then draw the floor in the position
141   Otherwise if it's a space that the plac can't see...
142   and there's no monster there...
143   Draw the blank space again
144   Otherwise..
145   Just draw the old character that used to be there
146   End check for drawing non-player floor space
147   Get the room the chaser is currently in
148   If the monster isn't at the same position as the destination
149   BLOCK START - Update destination
150   If the destination isn't in a room...
151   Update the monster's room to the previously stored room (no null ptrs)
152   Finished with chase
153   BLOCK
154   If the room's still don't match
155   The monster needs to find a new destination
156   The monster's position is at the old destination
157   BLOCK START - Update destination  
158   BLANK
159   If the player can see the monster
160   If the target destination is a passage...
161   Invert color output to stand out
162   Draw the old character at the destination position
163   Add the monster's disguise character to the position
164   End check if the player can see the monster
165   If the player can see all monsters
166   BLOCK START - See all monsters
167   Invert color output for emphasis
168   Get the old character at the position
169   Write the monster's true symbol at the position
170   BLOCK END - See all monsters
171   In all other cases...
172   The player must have been at the position
173   If the old character was a floor and the old room is dark...
174   Draw a space
175   End extended output formats
176   BLOCK END - do_chase
177   BLANK
178   COMMENT
179   COMMENT
180   COMMENT
181   COMMENT

MONSTER VISIBILITY CHECK

182   Defines see_monst with one argument
183   Argument 1 is a pointer to a monster
184   BLOCK START - see_monst, checks if the player can see a monster
185   If the player is blind...
186   The player definitely can't see the monster - return false
187   If the monster is inivisble and the player can't see inivisible
188   The player definitely can't see the monster - return false
189   The monster is beyond the player's dark room sight distance...
190   and not in the same room or the room is dark...
191   Or the room is a maze
192   The player definitely can't see the monster - return false
193   COMMENT
194   COMMENT
195   COMMENT
196   COMMENT
197   If the player is wearing a weapon that does extra damage to this enemy..
198   And the weapon hasn't shown that power yet...
199   BLOCK START - Vorpal hint
200   Set the weapon flash flag
201   Print a hint that this weapon hates this monster
202   BLOCK END - Vorpal hint
203   If we've made it this far, the player sees the monster.
204   BLOCK END - see_monst
205   BLANK
206   COMMENT
207   COMMENT
208   COMMENT
209   COMMENT
210   COMMENT

WAKE UP A MONSTER

211   Define start_run with one argument
212   Argument 1 is a coordinate for a monster
213   BLOCK START - start_run, wakes up a monster
214   Declare a pointer to an object (monster)
215   BLANK
216   COMMENT
217   COMMENT
218   COMMENT
219   Get the monster at the input coordinate
220   If the monster exists...
221   COMMENT
222   COMMENT
223   COMMENT
224   Set the monster to run
225   Set the monster free
226   Search for a target
227   End check for monster to enable
228   If we're in debug mode...
229   Otherwise...there is no monster!
230   Send error about that
231   End check for debug mode
232   BLOCK END - start_run
233   BLANK
234   COMMENT
235   COMMENT
236   COMMENT
237   COMMENT
238   COMMENT
239   COMMENT

CHASE NEXT STEP

240   Define chase with two arguments
241   Argument 1 is the monster doing the chasing
242   Argument 2 is the coordinate of the target
243   BLOCK START - chase, finds the next step during a chase
244   Declare x and y position variables
245   Declare integers for distances
246   Declare a pointer to a game object
247   Declare a coordinate for the chasing monster
248   Declare a character
249   Initialize a counter to 1
250   BLANK
251   Get the position of the chasing monster
252   COMMENT
253   COMMENT
254   COMMENT
255   COMMENT
256   COMMENT
257   If the chaser is confused and with an 80% chance (20% if a phantom)...
258   or 50% of it's a bat
259   BLOCK START - Find a move to make
260   COMMENT
261   COMMENT
262   COMMENT
263   Get a random move and store it in ch_ret
264   Get the distance between the move and the target
265   COMMENT
266   COMMENT
267   COMMENT
268   There is a ~3% chance that...
269   The monster loses confusion state
270   BLOCK END - Find a move to make
271   COMMENT
272   COMMENT
273   COMMENT
274   COMMENT
275   Otherwise we can search for a position towards the target
276   BLOCK START - Random move one space towards target  
277   Declare target x and y positions
278   COMMENT
279   COMMENT
280   COMMENT
281   COMMENT
282   Get the distance between the chaser and target
283   Return a pointer to the chaster
284   BLANK
285   Assume next position is down one row...
286   and right one row...
287   Loop from the left of the monster to the right..
288   BLOCK START - Scan for next step by columns...
289   And loop from above the mosnter to below...
290   BLOCK START - Scan for next step by rows
291   Declare the testing coordinate
292   BLANK
293   Match to the x position (outer loop)
294   Match to the y position (inner loop)
295   If this position is off the map or an unaccessible diagonal...
296   Skip to the next position
297   Get the floor character at that position
298   If the monster is allowed to move to this position...
299   BLOCK START - Movement candidate
300   COMMENT
301   COMMENT
302   COMMENT
303   COMMENT
304   If the position has a scroll...
305   BLOCK START - Check for scare monster scroll
306   Loop through all objects on the level
307   BLOCK START - Check for scroll
308   If this object is at the test position
309   Exit loop to test scroll type
310   BLOCK END - Check for scroll
311   This is scroll is a scare monster scroll...
312   Monsters are afraid of it - skip this position
313   BLOCK END - Check for scare monster scroll
314   COMMENT
315   COMMENT
316   COMMENT
317   COMMENT
318   Get the distance between the testing position and the target
319   If the distance is less than the current distance (it's closer)...
320   BLOCK START - Choose this position
321   Set choice counter to 1
322   Set the target
323   Get the distance
324   BLOCK END - Choose this position
325   Otherwise...randomly choose a bad position <=33% of the time...
326   BLOCK START - Bad choice
327   Set the target
328   Get the distance
329   BLOCK END - Bad choice
330   BLOCK END - Movement candidate
331   BLOCK END - Scan for next step by rows
332   BLOCK END - Scan for next step by columns...
333   End of movement towards target
334   BLOCK END - chase
335   BLANK
336   COMMENT
337   COMMENT
338   COMMENT
339   COMMENT
340   COMMENT

FIND ROOM BASED ON COORDINATES

341   roomin returns a pointer to a room
342   Define roomin with one argument
343   Argument 1 is a map coordinate
344   BLOCK START - roomin, returns a room by input coordinates
345   Declare a pointer to a room (success return value)
346   Declare a pointer to a floor character
347   BLANK
348   Loop through all the rooms
349   Compare the input coordinate falls between the room left and right...
350   ...and within the top and the bottom...
351   Return that room pointer
352   Otherwise, get the floor type
353   If this is a passage...
354   Get the passage index and return it
355   Check for debug mode
356   Print out a debug message for an unknown position
357   End check for debug made
358   Increment the failure exit counter
359   Return fail
360   BLOCK END - roomin
361   BLANK
362   COMMENT
363   COMMENT
364   COMMENT
365   COMMENT

CHECK DIAGONAL MOVEMENT

366   Define diag_ok with two arguments
367   Arguments 1 and 2 are coordinates for player and target
368   BLOCK START - diag_ok, checks if diagonal movement is possible
369   If the coordinates are the same...
370   The move must be ok
371   Otherwise make sure the cardinal positions are both clear as well
372   BLOCK END - diag_ok
373   BLANK
374   COMMENT
375   COMMENT
376   COMMENT
377   COMMENT

CHECK COORDINATE VISIBILITY

378   Define cansee with two arguments
379   Arguments 1 and 2 are x and y positions on the map
380   BLOCK START - cansee, checks if player can see the input coordinates
381   Declare a pointer to a room
382   Declare coordinates
383   BLANK
384   If the player is blind...
385   They can never see anything...false
386   If the target is within the lamp distance of the player...
387   Then player can see the spot, even in a dark room
388   COMMENT
389   COMMENT
390   COMMENT
391   COMMENT
392   Set a coordinate y position with the actual y
393   Set a coordinate x potition with the actual x
394   Get the pointer to the room
395   If the player isn't in the room, then they can't see the point
396   BLOCK END - cansee
397   BLANK
398   COMMENT
399   COMMENT
400   COMMENT
401   COMMENT

FIND DESTINATION

402   find_dest returns a pointer to coordinates
403   Define find_dest with one argument
404   Argument 1 is a pointer to the target
405   BLOCK START - find_dest, returns a target destination for a chaser
406   Declare an object pointer
407   Declare a probability variable
408   Declare a pointer to a room
409   BLANK
410   If the target isn't a monster, is in the same room as player...
411   And the player can see the monster...
412   The target is the player
413   Set the room pointer to the current room
414   Loop through all objects
415   BLOCK START - Check all objects for a possible target
416   If the object is a scare monster scroll...
417   Monsters ignore it
418   If the object is in the same room and if a probability check succeeds...
419   BLOCK START - Monster goes for object
420   Loop through all the monsters
421   If sanother moster is already chasing the object...
422   Break
423   If nothing was already chasing the object...
424   Send this monster after the object
425   BLOCK END - Monster goes for object
426   BLOCK END - Check all objects for a possible target
427   Return the player's position as the target
428   BLOCK END - find_dest
429   EOF