Reorganized wumpus, combining `wump_ui.pvvs` and `wump_game.pvvs`.
[vvhitespace] / examples / hunt-the-wumpus / wump_init.pvvs
CommitLineData
2da74194
AT
1#ifndef WUMP_INIT
2#define WUMP_INIT
3
4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
5@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
6@ See LICENSE.txt file for copyright and license details.
7@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
8
9@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
10@ Name:
11@ wump_init
12@ Description:
13@ Master function that creates a new cave, links the rooms, and populates them
14@ according to the options set by the user in wump_conf.pvvs.
15@ Call Stack:
16@ <empty>
17@ Return Stack:
18@ <empty>
19@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
20#include <stdio.pvvs>
21#include <wump_conf.pvvs>
22#include <wump_strings.pvvs>
310931d2 23#include <wump_game.pvvs>
2da74194
AT
24NSSVTSSSSSTSN | MARK: 10000010 (wump_init)
25
26@ Load the user-configurable options.
27NSTTSSSSSSTN | JSR > 10000001 (set_config_values)
28
29@ Seed the RNG.
30NSTTTTTTTTTSSSSSTTTN | JSR > 11111111 00000111 (please_seed_rng)
31SSSSN | PUSH 0 (number of string substitutions)
32NSTTSSSN | JSR > 1000 (printf)
33NSTTSSSSSTTN | JSR > 10000011 (seed_rng)
34
35@ Build the cave.
36NSTTSSSSTSSN | JSR > 10000100 (build_cave)
37
38@ Populate the cave.
39NSTTSSSSTSTN | JSR > 10000101 (populate_cave)
40
41@ Initialization is complete.
42NTN | RTS
43
44@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
45@ Name:
46@ build_circular_tunnels
47@ Description:
48@ Builds a set of tunnels that ensures every room in the cave is connected.
49@ Assumes that tunnel slots 0 and 1 are set to the value -1 (unconnected).
50@ Call Stack:
51@ <empty>
52@ Return Stack:
53@ <empty>
54@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
55#include <stack.pvvs>
56#include <wump_game.pvvs>
57NSSVTSSSTTTSN | MARK: 10001110 (build_circular_tunnels)
58
59@ Prepare TOS> current_room, hop_length
60NSTTSSSSTTTN | JSR > 10000111 (generate_cave_hop_length)
61SSSSN | PUSH 0 (current room)
62
63@ Have we already built a tunnel from this room?
64@ If so, tunnel slot 0 will not be -1.
65NSSVTSSSTTTSSSSSSSSSN | MARK: 10001110 00000000 (tunnel_loop)
66SNS | DUP
67SSSSN | PUSH 0 (first tunnel slot)
68SNT | SWAP
69NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination)
70NTTTSSSTTTSSSSSSSTSN | BMI > 10001110 00000010
71NSNTSSSTTTSSSSSSSSTN | JMP > 10001110 00000001 (loop_complete)
72NSSVTSSSTTTSSSSSSSTSN | MARK: 10001110 00000010
73@ No tunnel yet, so start building a tunnel.
74@ TOS> current_room, hop_length
75SNS | DUP
76SNS | DUP
77SSSTSSN | PUSH 4
78NSTTTSSN | JSR > 1100 (deepdup)
79TSSS | ADD
80SSSTSSSSSSSSSSSSN | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
81TTT | LOAD
82TSTT | MODULO
83SNT | SWAP
84SSSSN | PUSH 0 (slot number)
85SNT | SWAP
86NSTTSSSTSSTN | JSR > 10001001 (set_tunnel_destination)
87@ One direction of the tunnel is built. Now build the other direction.
88SNS | DUP
89SSSSN | PUSH 0 (slot number)
90SNT | SWAP
91NSTTSSSTSSSN | JSR > 10001000 (get_tunnel_destination)
92SNT | SWAP
93SSSTSN | PUSH 2
94NSTTTSSN | JSR > 1100 (deepdup)
95SSSTN | PUSH 1
96SNT | SWAP
97NSTTSSSTSSTN | JSR > 10001001 (set_tunnel_destination)
98@ Loop again to build the next tunnel.
99NSNTSSSTTTSSSSSSSSSN | JMP > 10001110 00000000 (tunnel_loop)
100
101@ Clean up and return
102NSSVTSSSTTTSSSSSSSSTN | MARK: 10001110 00000001 (loop_complete)
103SNN | DROP
104SNN | DROP
105NTN | RTS
106
107@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
108@ Name:
109@ get_next_tunnel_slot
110@ Description:
111@ Returns the index of next available tunnel slot for room_num, or -1 if full.
112@ Call Stack:
113@ room_num <-- TOS
114@ Return Stack:
115@ tunnel_index <-- TOS
116@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
117#include <wump_game.pvvs>
118NSSVTSSTSTTTN | MARK: 10010111 (get_next_tunnel_slot)
119
120@ Build the pointer: (room_num * size_of_room_struct) + 2 + ROOM_DATA_BASE
121@ Where the '+2' skips over the 'pits' and 'bats' booleans for this room.
122NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size)
123TSSN | MULTIPLY
124SSSTSN | PUSH 2
125TSSS | ADD
126SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (ROOM_DATA_BASE address)
127TSSS | ADD
128
129@ Save a copy of this pointer for later use when recovering the tunnel index.
130SNS | DUP
131
132@ Push a loop counter onto the stack.
133SSSSN | PUSH 0 (counter)
134SNT | SWAP
135
136@ Main loop - Search for an available tunnel slot.
137@ TOS> ptr_to_tunnel_slot, loop_counter, ptr_to_first_tunnel_slot
138NSSVTSSTSTTTSSSSSSSSN | MARK: 10010111 00000000 (main_loop)
139SNS | DUP
140TTT | LOAD
141NTTTSSTSTTTSSSSSSSTN | BMI > 10010111 00000001 (found_open_slot)
142@ No match.
143@ Increment the pointer.
144SSSTN | PUSH 1
145TSSS | ADD
146@ Increment the loop counter.
147SNT | SWAP
148SSSTN | PUSH 1
149TSSS | ADD
150@ See if we have run out of possible tunnel slots.
151SNS | DUP
152SSSTSSSSSSSSSSTTN | PUSH 0x1003 (GAME_DATA_BASE+3 = links_per_room address)
153TTT | LOAD
154TSST | SUBTRACT
155NTSTSSTSTTTSSSSSSTSN | BRZ > 10010111 00000010 (no_open_slots)
156@ There are still more slots to check. Prepare to loop again.
157SNT | SWAP
158NSNTSSTSTTTSSSSSSSSN | JMP > 10010111 00000000 (main_loop)
159
160@ No available tunnel slots for this room.
161NSSVTSSTSTTTSSSSSSTSN | MARK: 10010111 00000010 (no_open_slots)
162SNN | DROP
163SNN | DROP
164SNN | DROP
165SSTTN | PUSH -1
166NTN | RTS
167
168@ Found an open tunnel slot.
169NSSVTSSTSTTTSSSSSSSTN | MARK: 10010111 00000001 (found_open_slot)
170@ Drop the loop counter.
171SNT | SWAP
172SNN | DROP
173@ Recover the tunnel slot index from the tunnel slot pointer.
174SNT | SWAP
175TSST | SUBTRACT
176NTN | RTS
177
178@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
179@ Name:
180@ build_random_tunnels
181@ Description:
182@ Randomly builds tunnels between rooms until all tunnels slots are used.
183@ Call Stack:
184@ <empty>
185@ Return Stack:
186@ <empty>
187@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
188#include <heap.pvvs>
189#include <math.pvvs>
190#include <stack.pvvs>
191NSSVTSSTSTTSN | MARK: 10010110 (build_random_tunnels)
192
193@ Build a temporary data structure in the buffer residing at 0x3000.
194@
195@ 0x3000 contains the number of elements in an array that starts at 0x3001.
196@ Each array element is one word long and contains the index of a room
197@ with open tunnel slots.
198@
199@ This init code is here rather than a subroutine since the structure it builds
200@ is private to this function.
201@ Before looping, push the number of elements in the array (=num_rooms).
202@ Keep a copy of this number to use as a loop counter.
203SSSTSSSSSSSSSSSSN | PUSH 0x1000 (GAME_DATA_BASE = num_rooms address)
204TTT | LOAD
205SNS | DUP
206SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
207SNT | SWAP
208TTS | STORE
209@ Init loop - Populates the 'rooms with available tunnel slots' array.
210@ TOS> loop_counter
211NSSVTSSTSTTSSSSSSSTSN | MARK: 10010110 00000010 (init_loop)
212@ Populate one of the array entries.
213SNS | DUP
214SNS | DUP
215SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
216TSSS | ADD
217SNT | SWAP
218SSSTN | PUSH +1
219TSST | SUBTRACT
220TTS | STORE
221@ Decrement the loop counter and test for end of loop.
222SSSTN | PUSH +1
223TSST | SUBTRACT
224SNS | DUP
225NTSTSSTSTTSSSSSSSTTN | BRZ > 10010110 00000011 (init_loop_end)
226NSNTSSTSTTSSSSSSSTSN | JMP > 10010110 00000010 (init_loop)
227NSSVTSSTSTTSSSSSSSTTN | MARK: 10010110 00000011 (init_loop_end)
228SNN | DROP
229NSNTSSTSTTSSSSSSSSTN | JMP > 10010110 00000001 (main_loop)
230
231@@@@@ INIT IS COMPLETE - STACK IS EMPTY @@@@@
232
233@ Build one random tunnel connection per pass through this loop.
234NSSVTSSTSTTSSSSSSSSTN | MARK: 10010110 00000001 (main_loop)
235@ Use 'random_number mod number_of_array_entries' to select a starting room.
83a8624e 236NSTTSSTTN | JSR > 10011 (fastrand)
2da74194
AT
237SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
238TTT | LOAD
239TSTT | MODULO
240SSSTN | PUSH 1
241TSSS | ADD
242SNS | DUP
243SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
244TSSS | ADD
245TTT | LOAD
246@ TOS> start_room_num, start_array_index
247@ Now we randomly select a room for the endpoint.
248NSSVTSSTSTTSSSSSSTSSN | MARK: 10010110 00000100 (select_random_dst_room)
83a8624e 249NSTTSSTTN | JSR > 10011 (fastrand)
2da74194
AT
250SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
251TTT | LOAD
252TSTT | MODULO
253SSSTN | PUSH 1
254TSSS | ADD
255SNS | DUP
256SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
257TSSS | ADD
258TTT | LOAD
259@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
260@ Verify the endpoint room is different from the startpoint room.
261SNS | DUP
262SSSTSSN | PUSH 4
263NSTTTSSN | JSR > 1100 (deepdup)
264TSST | SUBTRACT
265NTSTSSTSTTSSSSSSTSTN | BRZ > 10010110 00000101 (rooms_matched)
266NSNTSSTSTTSSSSSSTTSN | JMP > 10010110 00000110 (connect_rooms)
267@ The rooms matched. Drop the selected destination room and try again.
268NSSVTSSTSTTSSSSSSTSTN | MARK: 10010110 00000101 (rooms_matched)
269SNN | DROP
270SNN | DROP
271NSNTSSTSTTSSSSSSTSSN | JMP > 10010110 00000100 (select_random_dst_room)
272@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
273@ The rooms are different. Time to build a connection between them.
274NSSVTSSTSTTSSSSSSTTSN | MARK: 10010110 00000110 (connect_rooms)
275@ First build a one-way tunnel.
276SSSTTN | PUSH 3
277NSTTTSSN | JSR > 1100 (deepdup)
278SSSTSN | PUSH 2
279NSTTTSSN | JSR > 1100 (deepdup)
280SNS | DUP
281NSTTSSTSTTTN | JSR > 10010111 (get_next_tunnel_slot)
282SNT | SWAP
283NSTTSSSTSSTN | JSR > 10001001 (set_tunnel_destination)
284@ Then make it a two-way tunnel.
285SNS | DUP
286SSSTSSN | PUSH 4
287NSTTTSSN | JSR > 1100 (deepdup)
288SNS | DUP
289NSTTSSTSTTTN | JSR > 10010111 (get_next_tunnel_slot)
290SNT | SWAP
291NSTTSSSTSSTN | JSR > 10001001 (set_tunnel_destination)
292@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
293@ If that was the last tunnel slot in either room, remove it
294@ from the 'rooms_with_available_tunnel_slots' array.
295NSTTSSTSTTTN | JSR > 10010111 (get_next_tunnel_slot)
296NTTTSSTSTTSSSSSSTTTN | BMI > 10010110 00000111 (remove_empty_room_1)
297SNN | DROP
298NSNTSSTSTTSSSSSTSSSN | JMP > 10010110 00001000 (check_second_room)
299NSSVTSSTSTTSSSSSSTTTN | MARK: 10010110 00000111 (remove_empty_room_1)
300SNS | DUP
301NSTTSSTSTTSSSSSTTSSN | JSR > 10010110 00001100 (remove_element_from_array)
302SSSTTN | PUSH 3
303NSTTTSSN | JSR > 1100 (deepdup)
304TSST | SUBTRACT
305NTTTSSTSTTSSSSSTTSTN | BMI > 10010110 00001101 (update_second_room_index)
306NSNTSSTSTTSSSSSTSSSN | JMP > 10010110 00001000 (check_second_room)
307NSSVTSSTSTTSSSSSTTSTN | MARK: 10010110 00001101 (update_second_room_index)
308SNT | SWAP
309SSSTN | PUSH 1
310TSST | SUBTRACT
311SNT | SWAP
312NSSVTSSTSTTSSSSSTSSSN | MARK: 10010110 00001000 (check_second_room)
313NSTTSSTSTTTN | JSR > 10010111 (get_next_tunnel_slot)
314NTTTSSTSTTSSSSSTSSTN | BMI > 10010110 00001001 (remove_empty_room_2)
315SNN | DROP
316NSNTSSTSTTSSSSSTSTSN | JMP > 10010110 00001010 (main_loop_end_test)
317NSSVTSSTSTTSSSSSTSSTN | MARK: 10010110 00001001 (remove_empty_room_2)
318NSTTSSTSTTSSSSSTTSSN | JSR > 10010110 00001100 (remove_element_from_array)
319@ If the array is now empty or only contains one room, return.
320@ Otherwise, loop again and build another random tunnel.
321NSSVTSSTSTTSSSSSTSTSN | MARK: 10010110 00001010 (main_loop_end_test)
322SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
323TTT | LOAD
324SSSTSN | PUSH 2
325TSST | SUBTRACT
326NTTTSSTSTTSSSSSTSTTN | BMI > 10010110 00001011 (return)
327NSNTSSTSTTSSSSSSSSTN | JMP > 10010110 00000001 (main_loop)
328NSSVTSSTSTTSSSSSTSTTN | MARK: 10010110 00001011 (return)
329NTN | RTS
330
331@ A private subroutine to remove one element from the temp array.
332@ Consumes the array index from TOS.
333NSSVTSSTSTTSSSSSTTSSN | MARK: 10010110 00001100 (remove_element_from_array)
334@ First, stash a copy of the array index immediately after the temporary array.
335@ This allows us to find it using the num_array_elements for use with spew
336@ after slurp has filled the stack with a variable number of elements.
337SNS | DUP
338SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
339SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
340TTT | LOAD
341TSSS | ADD
342SSSTN | PUSH 1
343TSSS | ADD
344SNT | SWAP
345TTS | STORE
346@ Now slurp and spew the array to delete the desired element.
347SSSTN | PUSH 1
348TSSS | ADD
349SNS | DUP
350@ TOS> index+1, index+1
351SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
352TTT | LOAD
353SNT | SWAP
354TSST | SUBTRACT
355@ Special case: deleting last element of array means no need to delete.
356SNS | DUP
357NTTTSSTSTTSSSSSTTTSN | BMI > 10010110 00001110 (deleting_last_element)
358NSNTSSTSTTSSSSSTTTTN | JMP > 10010110 00001111 (not_deleting_last_element)
359NSSVTSSTSTTSSSSSTTTSN | MARK: 10010110 00001110 (deleting_last_element)
360SNN | DROP
361SNN | DROP
362NSNTSSTSTTSSSSTSSSSN | JMP > 10010110 00010000 (decrement_array_counter)
363NSSVTSSTSTTSSSSSTTTTN | MARK: 10010110 00001111 (not_deleting_last_element)
364SNT | SWAP
365@ TOS> index+1, count=num_array_elements-(index+1)
366SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
367TSSS | ADD
368SNT | SWAP
369@ TOS> count=num_array_elements-(index+1), address=0x3000+index+1
370NSTTTTTSN | JSR > 11110 (slurp)
371@ Recover the array index that we stashed on the heap.
372SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
373SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
374TTT | LOAD
375TSSS | ADD
376SSSTN | PUSH 1
377TSSS | ADD
378TTT | LOAD
379@ TOS> index
380SNS | DUP
381SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
382TSSS | ADD
383SNT | SWAP
384@ TOS> index, address=0x3000+index
385SSSTN | PUSH 1
386TSSS | ADD
387SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
388TTT | LOAD
389SNT | SWAP
390TSST | SUBTRACT
391@ TOS> count = num_array_elements-(index+1), address=0x3000+index
392NSTTTTTTN | JSR > 11111 (spew)
393@ Decrement the array element counter.
394NSSVTSSTSTTSSSSTSSSSN | MARK: 10010110 00010000 (decrement_array_counter)
395SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
396TTT | LOAD
397SSSTN | PUSH 1
398TSST | SUBTRACT
399SSSTTSSSSSSSSSSSSN | PUSH 0x3000 (BUFFER)
400SNT | SWAP
401TTS | STORE
402NTN | RTS
403
404@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
405@ Name:
406@ build_cave
407@ Description:
408@ Clears the cave data structure on the heap and builds new tunnels.
409@ Call Stack:
410@ <empty>
411@ Return Stack:
412@ <empty>
413@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
414NSSVTSSSSTSSN | MARK: 10000100 (build_cave)
415NSTTSSSSTTSN | JSR > 10000110 (clear_cave_data)
416NSTTSSSTTTSN | JSR > 10001110 (build_circular_tunnels)
417NSTTSSTSTTSN | JSR > 10010110 (build_random_tunnels)
418NTN | RTS
419
420@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
421@ Name:
422@ set_tunnel_destination
423@ Description:
424@ Sets 'slot' of 'room_number' to point to 'dst_room_number'.
425@ Call Stack:
426@ dst_room_number
427@ slot
428@ room_number <-- TOS
429@ Return Stack:
430@ <empty>
431@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
432#include <wump_game.pvvs>
433NSSVTSSSTSSTN | MARK: 10001001 (set_tunnel_destination)
434@ The pointer we seek is:
435@ (room_number * room_struct_size) + 2 + slot + ROOM_DATA_BASE
436@ Where the '+2' accounts for the pit and bat booleans.
437NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size)
438TSSN | MULTIPLY
439SSSTSN | PUSH +2
440TSSS | ADD
441TSSS | ADD
442SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (ROOM_DATA_BASE address)
443TSSS | ADD
444SNT | SWAP
445TTS | STORE
446NTN | RTS
447
448@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
449@ Name:
450@ generate_cave_hop_length
451@ Description:
452@ In order to ensure cave is fully connected, generate a number, 'hop_length',
453@ that is relatively prime to the number of rooms in the cave.
454@ Call Stack:
455@ <empty>
456@ Return Stack:
457@ hop_length
458@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
459#include <math.pvvs>
460NSSVTSSSSTTTN | MARK: 10000111 (generate_cave_hop_length)
461NSTTSSSTSTSN | JSR > 10001010 (get_random_room)
462@ Check for gcd(hop_length,num_rooms) = 1.
463SNS | DUP
464SSSTSSSSSSSSSSSSN | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
465TTT | LOAD
466NSTTSSTSN | JSR > 10010 (gcd)
467SSSTN | PUSH +1
468TSST | SUBTRACT
469NTSTSSSSTTTSSSSSSSSN | BRZ > 10000111 00000000
470SNN | DROP
471NSNTSSSSTTTN | JMP > 10000111 (generate_cave_hop_length)
472NSSVTSSSSTTTSSSSSSSSN | MARK: 10000111 00000000
473NTN | RTS
474
475@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
476@ Name:
477@ clear_cave_data
478@ Description:
479@ Writes -1 over the entire cave data array.
480@ This ensures each room starts unconnected.
481@ Call Stack:
482@ <empty>
483@ Return Stack:
484@ <empty>
485@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
486#include <heap.pvvs>
487#include <wump_game.pvvs>
488NSSVTSSSSTTSN | MARK: 10000110 (clear_cave_data)
489SSTTN | PUSH -1 (pattern)
490SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (ROOM_DATA_BASE address)
491SSSTSSSSSSSSSSSSN | PUSH 0x1000 (GAME_DATA_BASE address)
492TTT | LOAD
493NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size)
494TSSN | MULTIPLY
495NSTTTSSSN | JSR > 11000 (memset)
496NTN | RTS
497
498@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
499@ Name:
500@ get_random_room
501@ Description:
502@ Returns a valid room number
503@ Call Stack:
504@ <empty>
505@ Return Stack:
506@ room_num <-- TOS
507@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
508#include <math.pvvs>
509NSSVTSSSTSTSN | MARK: 10001010 (get_random_room)
83a8624e 510NSTTSSTTN | JSR > 10011 (fastrand)
2da74194
AT
511SSSTSSSSSSSSSSSSN | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
512TTT | LOAD
513TSTT | MODULO
514NTN | RTS
515
516@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
517@ Name:
518@ set_bats
519@ Description:
520@ Set the 'bats' boolean for a specific room.
521@ Call Stack:
522@ value (0 or 1)
523@ room_number
524@ Return Stack:
525@ <empty>
526@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
527#include <wump_game.pvvs>
528NSSVTSSTSSSSN | MARK: 10010000 (set_bats)
529@ We seek the pointer:
530@ (room_number * room_struct_size) + 1 + ROOM_DATA_BASE
531@ where '+1' accounts for the offset of the bat boolean in the desired room.
532NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size)
533TSSN | MULTIPLY
534SSSTN | PUSH +1
535TSSS | ADD
536SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (GAME_DATA_BASE address)
537TSSS | ADD
538SNT | SWAP
539TTS | STORE
540NTN | RTS
541
542@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
543@ Name:
544@ set_pits
545@ Description:
546@ Set the 'pits' boolean for a specific room.
547@ Call Stack:
548@ value (0 or 1)
549@ room_number
550@ Return Stack:
551@ <empty>
552@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
553#include <wump_game.pvvs>
554NSSVTSSTSSSTN | MARK: 10010001 (set_pits)
555@ We seek the pointer:
556@ (room_number * room_struct_size) + 0 + ROOM_DATA_BASE
557@ where '+0' accounts for the offset of the pit boolean in the desired room.
558NSTTSSSTSTTN | JSR > 10001011 (get_room_struct_size)
559TSSN | MULTIPLY
560SSSTSSSSSSSSSSSSSN | PUSH 0x2000 (GAME_DATA_BASE address)
561TSSS | ADD
562SNT | SWAP
563TTS | STORE
564NTN | RTS
565
566@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
567@ Name:
568@ reset_cave_population
569@ Description:
570@ Remove all bats and pits from the cave.
571@ Call Stack:
572@ <empty>
573@ Return Stack:
574@ <empty>
575@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
576NSSVTSSTSSTSN | MARK: 10010010 (reset_cave_population)
577
578@ Clear the bat and pit booleans by setting every room to false(=0).
579@ First prepare a loop index.
580SSSTSSSSSSSSSSSSN | PUSH 0x1000 (GAME_DATA_BASE+0 = number_of_rooms address)
581TTT | LOAD
582SSSTN | PUSH 1
583TSST | SUBTRACT
584NSSVTSSTSSTSSSSSSSSSN | MARK: 10010010 00000000 (empty_cave_loop)
585@ Scare all the bats out of the room.
586SNS | DUP
587SSSSN | PUSH 0 (false)
588SNT | SWAP
589NSTTSSTSSSSN | JSR > 10010000 (set_bats)
590@ Fill any pits.
591SNS | DUP
592SSSSN | PUSH 0 (false)
593SNT | SWAP
594NSTTSSTSSSTN | JSR > 10010001 (set_pits)
595@ Decrement loop counter and test for end of loop.
596SSSTN | PUSH 1
597TSST | SUBTRACT
598SNS | DUP
599NTTTSSTSSTSSSSSSSSTN | BMI > 10010010 00000001 (empty_cave_loop_end)
600NSNTSSTSSTSSSSSSSSSN | JMP > 10010010 00000000 (empty_cave_loop)
601@ Loop is complete. Clean up and return.
602NSSVTSSTSSTSSSSSSSSTN | MARK: 10010010 00000001 (empty_cave_loop_end)
603SNN | DROP
604NTN | RTS
605
606@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
607@ Name:
608@ populate_bats
609@ Description:
610@ Randomly place a user-defined number of bats in the cave.
611@ Call Stack:
612@ <empty>
613@ Return Stack:
614@ <empty>
615@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
616#include <wump_game.pvvs>
617NSSVTSSTSSTTN | MARK: 10010011 (populate_bats)
618
619@ First prepare a loop index.
620SSSTSSSSSSSSSSTSN | PUSH 0x1002 (GAME_DATA_BASE+2 = number_of_bats address)
621TTT | LOAD
622SSSTN | PUSH 1
623TSST | SUBTRACT
624@ Find a random room that does not already contain bats.
625NSSVTSSTSSTTSSSSSSTSN | MARK: 10010011 00000010 (place_bats)
626NSTTSSSTSTSN | JSR > 10001010 (get_random_room)
627SNS | DUP
628NSTTSSSTTSSN | JSR > 10001100 (room_has_bats)
629NTSTSSTSSTTSSSSSSTTN | BRZ > 10010011 00000011 (no_bats_in_room)
630SNN | DROP
631NSNTSSTSSTTSSSSSSTSN | JMP > 10010011 00000010 (place_bats)
632@ Room is empty. Place bats.
633NSSVTSSTSSTTSSSSSSTTN | MARK: 10010011 00000011 (no_bats_in_room)
634SSSTN | PUSH 1 (true)
635SNT | SWAP
636NSTTSSTSSSSN | JSR > 10010000 (set_bats)
637@ Decrement loop counter and test for loop completion.
638SSSTN | PUSH 1
639TSST | SUBTRACT
640SNS | DUP
641NTTTSSTSSTTSSSSSTSSN | BMI > 10010011 00000100 (place_bats_loop_end)
642NSNTSSTSSTTSSSSSSTSN | JMP > 10010011 00000010 (place_bats)
643@ Loop is complete. Clean up and return.
644NSSVTSSTSSTTSSSSSTSSN | MARK: 10010011 00000100 (place_bats_loop_end)
645SNN | DROP
646NTN | RTS
647
648@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
649@ Name:
650@ populate_pits
651@ Description:
652@ Randomly place a user-defined number of pits in the cave.
653@ Call Stack:
654@ <empty>
655@ Return Stack:
656@ <empty>
657@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
658#include <wump_game.pvvs>
659NSSVTSSTSTSSN | MARK: 10010100 (populate_pits)
660
661@ First prepare a loop index.
662SSSTSSSSSSSSSSSTN | PUSH 0x1001 (GAME_DATA_BASE+1 = number_of_pits address)
663TTT | LOAD
664SSSTN | PUSH 1
665TSST | SUBTRACT
666@ Find a random room that does not already contain pits.
667NSSVTSSTSTSSSSSSSSTSN | MARK: 10010100 00000010 (place_pits)
668NSTTSSSTSTSN | JSR > 10001010 (get_random_room)
669SNS | DUP
670NSTTSSSTTSTN | JSR > 10001101 (room_has_pits)
671NTSTSSTSTSSSSSSSSTTN | BRZ > 10010100 00000011 (no_pits_in_room)
672SNN | DROP
673NSNTSSTSTSSSSSSSSTSN | JMP > 10010100 00000010 (place_pits)
674@ Room is empty. Place pits.
675NSSVTSSTSTSSSSSSSSTTN | MARK: 10010100 00000011 (no_pits_in_room)
676SSSTN | PUSH 1 (true)
677SNT | SWAP
678NSTTSSTSSSTN | JSR > 10010001 (set_pits)
679@ Decrement loop counter and test for loop completion.
680SSSTN | PUSH 1
681TSST | SUBTRACT
682SNS | DUP
683NTTTSSTSTSSSSSSSTSSN | BMI > 10010100 00000100 (place_pits_loop_end)
684NSNTSSTSTSSSSSSSSTSN | JMP > 10010100 00000010 (place_pits)
685@ Loop is complete. Clean up and return.
686NSSVTSSTSTSSSSSSSTSSN | MARK: 10010100 00000100 (place_pits_loop_end)
687SNN | DROP
688NTN | RTS
689
690@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
691@ Name:
692@ place_player
693@ Description:
694@ Place the player in a suitable starting room.
695@ Call Stack:
696@ <empty>
697@ Return Stack:
698@ <empty>
699@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
700NSSVTSSTSTSTN | MARK: 10010101 (place_player)
701
702@ Find out where the wumpus is located.
703SSSTSSSSSSSSSTTTN | PUSH 0x1007 (GAME_DATA_BASE+7 = wumpus_room address)
704TTT | LOAD
705@ Place the player in a different room than the wumpus.
706NSSVTSSTSTSTSSSSSSSSN | MARK: 10010101 00000000 (place_player_loop)
707NSTTSSSTSTSN | JSR > 10001010 (get_random_room)
708SNT | SWAP
709SNS | DUP
710SSSTTN | PUSH 3
711NSTTTSSN | JSR > 1100 (deepdup)
712@ TOS> rand_room, wump_room, wump_room, rand_room
713TSST | SUBTRACT
714NTSTSSTSTSTSSSSSSSTN | BRZ > 10010101 00000001 (same_room)
715NSNTSSTSTSTSSSSSSTSN | JMP > 10010101 00000010 (different_rooms)
716NSSVTSSTSTSTSSSSSSSTN | MARK: 10010101 00000001 (same_room)
717SNN | DROP
718NSNTSSTSTSTSSSSSSSSN | JMP > 10010101 00000000 (place_player_loop)
719NSSVTSSTSTSTSSSSSSTSN | MARK: 10010101 00000010 (different_rooms)
720SNN | DROP
721SSSTSSSSSSSSSTTSN | PUSH 0x1006 (GAME_DATA_BASE+6 = player_room address)
722SNT | SWAP
723TTS | STORE
724NTN | RTS
725
726@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
727@ Name:
728@ populate_cave
729@ Description:
730@ Populate the cave with various creatures and features.
731@ Call Stack:
732@ <empty>
733@ Return Stack:
734@ <empty>
735@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
736NSSVTSSSSTSTN | MARK: 10000101 (populate_cave)
737
738@ Initialize the cave to an unpopulated state.
739NSTTSSTSSTSN | JSR > 10010010 (reset_cave_population)
740
741@ Place bats in the now-empty cave.
742NSTTSSTSSTTN | JSR > 10010011 (populate_bats)
743
744@ Place pits in the now-empty cave.
745NSTTSSTSTSSN | JSR > 10010100 (populate_pits)
746
747@ Place the wumpus.
748SSSTSSSSSSSSSTTTN | PUSH 0x1007 (GAME_DATA_BASE+7 = wumpus_room address)
749NSTTSSSTSTSN | JSR > 10001010 (get_random_room)
750TTS | STORE
751
752@ Place the player.
753NSTTSSTSTSTN | JSR > 10010101 (place_player)
754
755NTN | RTS
756
757#endif