Moved Hunt the Wumpus to more descriptive directory name.
authorAaron Taylor <ataylor@subgeniuskitty.com>
Mon, 30 Mar 2020 04:20:08 +0000 (21:20 -0700)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Mon, 30 Mar 2020 04:20:08 +0000 (21:20 -0700)
18 files changed:
examples/hunt-the-wumpus/LICENSE.txt [new file with mode: 0644]
examples/hunt-the-wumpus/Makefile [new file with mode: 0644]
examples/hunt-the-wumpus/README.txt [new file with mode: 0644]
examples/hunt-the-wumpus/wump.pvvs [new file with mode: 0644]
examples/hunt-the-wumpus/wump_conf.pvvs [new file with mode: 0644]
examples/hunt-the-wumpus/wump_game.pvvs [new file with mode: 0644]
examples/hunt-the-wumpus/wump_init.pvvs [new file with mode: 0644]
examples/hunt-the-wumpus/wump_strings.pvvs [new file with mode: 0644]
examples/hunt-the-wumpus/wump_ui.pvvs [new file with mode: 0644]
examples/wump/LICENSE.txt [deleted file]
examples/wump/Makefile [deleted file]
examples/wump/README.txt [deleted file]
examples/wump/wump.pvvs [deleted file]
examples/wump/wump_conf.pvvs [deleted file]
examples/wump/wump_game.pvvs [deleted file]
examples/wump/wump_init.pvvs [deleted file]
examples/wump/wump_strings.pvvs [deleted file]
examples/wump/wump_ui.pvvs [deleted file]

diff --git a/examples/hunt-the-wumpus/LICENSE.txt b/examples/hunt-the-wumpus/LICENSE.txt
new file mode 100644 (file)
index 0000000..d6b0400
--- /dev/null
@@ -0,0 +1,21 @@
+MIT/X Consortium License
+
+© 2018 Aaron Taylor <ataylor at subgeniuskitty dot com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/examples/hunt-the-wumpus/Makefile b/examples/hunt-the-wumpus/Makefile
new file mode 100644 (file)
index 0000000..1fec45e
--- /dev/null
@@ -0,0 +1,17 @@
+# (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
+# See LICENSE.txt file for copyright and license details.
+
+include ../config.mk
+
+all: wump
+
+wump:
+       $(CPP) $(CPP_FLAGS) -o temp.pvvs wump.pvvs
+       $(VVS_COMPILER) -i temp.pvvs -o wump.vvs
+       @rm -f temp.pvvs
+
+run: wump
+       $(VVS_INTERPRETER) -i wump.vvs
+
+clean:
+       @rm -f wump.vvs temp.pvvs
diff --git a/examples/hunt-the-wumpus/README.txt b/examples/hunt-the-wumpus/README.txt
new file mode 100644 (file)
index 0000000..c001660
--- /dev/null
@@ -0,0 +1,83 @@
+TODO LIST:
+
+  - Update README
+  - Write functions for moving wumpus, player movement, player shooting, parsing player commands.
+  - Write a function 'get highest tunnel index' for use in the 'check for pits/bats/wumpus' functions.
+  - Double-check per-file TODOs for critical tasks.
+  - Double-check #includes for all subroutines.
+  - Re-order subroutines in all files for readability.
+
+================================================================================
+
+# Subroutine Labels #
+
+NSSVTTTTTTTTSSSSSSSSN | Mark: 11111111 00000000 (wump_kill)
+NSSVTTTTTTTTSSSSSSSTN | Mark: 11111111 00000001 (kill_wump)
+NSSVTTTTTTTTSSSSSSTSN | Mark: 11111111 00000010 (no_arrows)
+NSSVTTTTTTTTSSSSSSTTN | Mark: 11111111 00000011 (shoot_self)
+NSSVTTTTTTTTSSSSSTSSN | Mark: 11111111 00000100 (jump)
+NSSVTTTTTTTTSSSSSTSTN | Mark: 11111111 00000101 (pit_kill)
+NSSVTTTTTTTTSSSSSTTSN | Mark: 11111111 00000110 (pit_survive)
+NSSVTTTTTTTTSSSSSTTTN | Mark: 11111111 00000111 (please_seed_rng)
+NSSVTTTTTTTTSSSSTSSSN | Mark: 11111111 00001000 (problem_with_yes_no_answer)
+NSSVTTTTTTTTSSSSTSSTN | Mark: 11111111 00001001 (instructions)
+NSSVTTTTTTTTSSSSTSTSN | Mark: 11111111 00001010 (cave_description)
+
+NSSVTSSSSSSSN         | MARK: 10000000 (wump)
+NSSVTSSSSSSTN         | MARK: 10000001 (set_config_values)
+NSSVTSSSSSTSN         | MARK: 10000010 (wump_init)
+NSSVTSSSSSTTN         | MARK: 10000011 (seed_rng)
+NSSVTSSSSTSSN         | MARK: 10000100 (build_cave)
+NSSVTSSSSTSTN         | MARK: 10000101 (populate_cave)
+NSSVTSSSSTTSN         | MARK: 10000110 (clear_cave_data)
+NSSVTSSSSTTTN         | MARK: 10000111 (generate_cave_hop_length)
+NSSVTSSSTSSSN         | MARK: 10001000 (get_tunnel_destination)
+NSSVTSSSTSSTN         | MARK: 10001001 (set_tunnel_destination)
+NSSVTSSSTSTSN         | MARK: 10001010 (get_random_room)
+NSSVTSSSTSTTN         | MARK: 10001011 (get_room_struct_size)
+NSSVTSSSTTSSN         | MARK: 10001100 (room_has_bats)
+NSSVTSSSTTSTN         | MARK: 10001101 (room_has_pits)
+NSSVTSSSTTTSN         | MARK: 10001110 (build_circular_tunnels)
+NSSVTSSTSSSSN         | MARK: 10010000 (set_bats)
+NSSVTSSTSSSTN         | MARK: 10010001 (set_pits)
+NSSVTSSTSSTSN         | MARK: 10010010 (reset_cave_population)
+NSSVTSSTSSTTN         | MARK: 10010011 (populate_bats)
+NSSVTSSTSTSSN         | MARK: 10010100 (populate_pits)
+NSSVTSSTSTSTN         | MARK: 10010101 (place_player)
+NSSVTSSTSTTSN         | MARK: 10010110 (build_random_tunnels)
+NSSVTSSTSTTTN         | MARK: 10010111 (get_next_tunnel_slot)
+NSSVTSSTTSSSN         | MARK: 10011000 (get_answer)
+!!!NSSVTSSTTSSTN         | MARK: 10011001 (get_line)
+NSSVTSSTTSTSN         | MARK: 10011010 (wump_loop)
+NSSVTSSTTSTTN         | MARK: 10011011 (print_cave_description)
+NSSVTSSTTTSSN         | MARK: 10011100 (are_bats_near)
+NSSVTSSTTTSTN         | MARK: 10011101 (are_pits_near)
+NSSVTSSTTTTSN         | MARK: 10011110 (is_wumpus_near)
+NSSVTSSTTTTTN         | MARK: 10011111 (is_wumpus_very_near)
+NSSVTSTSSSSSN         | MARK: 10100000 (room_has_wumpus)
+NSSVTSTSSSSTN         | MARK: 10100001 (print_room_stats)
+
+================================================================================
+
+# Heap Assignments #
+
+GAME_DATA_BASE = 0x1000
+
+GAME_DATA_BASE     = Number of rooms in cave
+GAME_DATA_BASE+001 = Number of pits
+GAME_DATA_BASE+002 = Number of bats
+GAME_DATA_BASE+003 = Number of links per room
+GAME_DATA_BASE+004 = Maximum arrow flight distance
+GAME_DATA_BASE+005 = Number of arrows
+GAME_DATA_BASE+006 = Player location
+GAME_DATA_BASE+007 = Wumpus location
+
+ROOM_DATA_BASE = 0x2000
+    Each room is structured as:
+        BASE+0 = bool:contains_pit? (valid options are 0 or 1)
+        BASE+1 = bool:contains_bat? (valid options are 0 or 1)
+        BASE+2 = int:connected room (-1 indicates no tunnel, 0 or greater is the index of the destination room)
+        ...
+        BASE+n = int:connected room (last: see 'links per room')
+
+USER_INPUT_BUFFER = 0x3000
diff --git a/examples/hunt-the-wumpus/wump.pvvs b/examples/hunt-the-wumpus/wump.pvvs
new file mode 100644 (file)
index 0000000..01284a9
--- /dev/null
@@ -0,0 +1,40 @@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Hunt the Wumpus
+@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
+@ See LICENSE.txt file for copyright and license details.
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+NSNTSSSSSSSN          | JMP > 10000000 (wump)
+
+#include <wump_init.pvvs>
+#include <wump_ui.pvvs>
+#include <wump_strings.pvvs>
+#include <stdio.pvvs>
+
+NSSVTSSSSSSSN         | MARK: 10000000 (wump)
+
+@ Initialization (build the cave, etc).
+NSTTSSSSSTSN          | JSR > 10000010 (wump_init)
+
+@ Does the user need instructions?
+A"Instructions? (y/n)\n"
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSTTSSTTSSSN          | JSR > 10011000 (get_answer)
+NTSTSSSSSSSSSSSSSSSN  | BRZ > 10000000 00000000 (skip_instructions)
+NSTTTTTTTTTSSSSTSSTN  | JSR > 11111111 00001001 (instructions)
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSSVTSSSSSSSSSSSSSSSN | MARK: 10000000 00000000 (skip_instructions)
+
+@ Print a description of the cave.
+NSTTSSTTSTTN          | JSR > 10011011 (print_cave_description)
+
+@ Main game loop
+NSSVTSSTTSTSN         | MARK: 10011010 (wump_loop)
+NSTTSTSSSSTN          | JSR > 10100001 (print_room_stats)
+A"Move or shoot? (m/s)\n"
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSTTSTSSSTSN          | JSR > 10100010 (move_or_shoot)
+NSNTSSTTSTSN          | JMP > 10011010 (wump_loop)
diff --git a/examples/hunt-the-wumpus/wump_conf.pvvs b/examples/hunt-the-wumpus/wump_conf.pvvs
new file mode 100644 (file)
index 0000000..d4bba75
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef WUMP_CONF
+#define WUMP_CONF
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
+@ See LICENSE.txt file for copyright and license details.
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ All user configurable options are contained in this file.
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   set_config_values
+@ Description:
+@   Place user-configurable values for Hunt the Wumpus on the heap.
+@   The program assumes the values are sane. (e.g. #pits < #rooms, etc)
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <heap.pvvs>
+NSSVTSSSSSSTN         | MARK: 10000001 (set_config_values)
+
+@ Number of arrows
+SSSTSTN               | PUSH +5
+
+@ Maximum arrow travel distance
+SSSTSTN               | PUSH +5
+
+@ Maximum links per room (must be >2)
+SSSTTN                | PUSH +3
+
+@ Number of bats in cave
+SSSTSN                | PUSH +2
+
+@ Number of pits in cave
+SSSTSN                | PUSH +2
+
+@ Number of rooms in cave
+SSSTSTSSN             | PUSH +20
+
+@ Push config values to heap and return.
+SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE address)
+SSSTSTN               | PUSH +5 (word count)
+NSTTTTTTN             | JSR > 11111 (spew)
+NTN                   | RTS
+
+#endif
diff --git a/examples/hunt-the-wumpus/wump_game.pvvs b/examples/hunt-the-wumpus/wump_game.pvvs
new file mode 100644 (file)
index 0000000..7d85f8d
--- /dev/null
@@ -0,0 +1,337 @@
+#ifndef WUMP_GAME
+#define WUMP_GAME
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
+@ See LICENSE.txt file for copyright and license details.
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   get_tunnel_destination
+@ Description:
+@   Returns the room number corresponding to the destination of a tunnel
+@   specified by room and slot.
+@ Call Stack:
+@   slot
+@   room_number  <-- TOS
+@ Return Stack:
+@   dst_room_number  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSSTSSSN         | MARK: 10001000 (get_tunnel_destination)
+@ The pointer we seek is:
+@ (room_number * room_struct_size) + 2 + slot + ROOM_DATA_BASE
+@ Where the '+2' accounts for the pit and bat booleans.
+NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
+TSSN                  | MULTIPLY
+SSSTSN                | PUSH +2
+TSSS                  | ADD
+TSSS                  | ADD
+SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (ROOM_DATA_BASE address)
+TSSS                  | ADD
+TTT                   | LOAD
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   get_room_struct_size
+@ Description:
+@   Returns the size in words of the data structure for a single room.
+@   For example, with 3 links plus bat and pit booleans, the size is 5 words.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   size   <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSSTSTTN         | MARK: 10001011 (get_room_struct_size)
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (GAME_DATA_BASE+3 = links_per_room address)
+TTT                   | LOAD
+SSSTSN                | PUSH +2
+TSSS                  | ADD
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   room_has_bats
+@ Description:
+@   Check if room_number contains bats.
+@   Returns 1 or 0 representing true or false.
+@ Call Stack:
+@   room_number   <-- TOS
+@ Return Stack:
+@   1 or 0   <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSSTTSSN         | MARK: 10001100 (room_has_bats)
+@ We seek the pointer:
+@   (room_number * room_struct_size) + 1 + ROOM_DATA_BASE
+@ where '+1' accounts for the offset of the bat boolean in the desired room.
+NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
+TSSN                  | MULTIPLY
+SSSTN                 | PUSH +1
+TSSS                  | ADD
+SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (GAME_DATA_BASE address)
+TSSS                  | ADD
+TTT                   | LOAD
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   room_has_pits
+@ Description:
+@   Check if room_number contains pits.
+@   Returns 1 or 0 representing true or false.
+@ Call Stack:
+@   room_number   <-- TOS
+@ Return Stack:
+@   1 or 0   <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSSTTSTN         | MARK: 10001101 (room_has_pits)
+@ We seek the pointer:
+@   (room_number * room_struct_size) + 0 + ROOM_DATA_BASE
+@ where '+0' accounts for the offset of the pit boolean in the desired room.
+NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
+TSSN                  | MULTIPLY
+SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (GAME_DATA_BASE address)
+TSSS                  | ADD
+TTT                   | LOAD
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   room_has_wumpus
+@ Description:
+@   Check if room contains wumpus.
+@   Returns 1 or 0 representing true or false.
+@ Call Stack:
+@   room_number   <-- TOS
+@ Return Stack:
+@   1 or 0   <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSTSSSSSN         | MARK: 10100000 (room_has_wumpus)
+SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (wumpus_location address)
+TTT                   | LOAD
+TSST                  | SUBTRACT
+NTSTSTSSSSSSSSSSSSSN  | BRZ > 10100000 00000000 (room_has_wumpus:true)
+SSSSN                 | PUSH 0 (false)
+NTN                   | RTS
+NSSVTSTSSSSSSSSSSSSSN | MARK: 10100000 00000000 (room_has_wumpus:true)
+SSSTN                 | PUSH 1 (true)
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   are_bats_near
+@ Description:
+@   Given a room number, checks rooms within one hop for bats.
+@   Returns 1 if bats are present or 0 if no bats.
+@ Call Stack:
+@   room_number  <-- TOS
+@ Return Stack:
+@   1 or 0  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSSTTTSSN         | MARK: 10011100 (are_bats_near)
+
+@ Prepare the stack by loading the number of links per room and decrementing.
+@ We will loop until this reaches 0 or we find bats.
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+
+@ Check one nearby room on each pass through this loop.
+@ TOS> tunnel_index, room_number
+NSSVTSSTTTSSSSSSSSSSN | MARK: 10011100 00000000 (are_bats_near:loop)
+SNS                   | DUP
+SSSTTN                | PUSH 3
+NSTTTSSN              | JSR > 1100 (deepdup)
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+NSTTSSSTTSSN          | JSR > 10001100 (room_has_bats)
+NTSTSSTTTSSSSSSSSSTN  | BRZ > 10011100 00000001 (no_bats_in_this_room)
+@ Found bats. Clean up and return.
+SNN                   | DROP
+SNN                   | DROP
+SSSTN                 | PUSH 1
+NTN                   | RTS
+NSSVTSSTTTSSSSSSSSSTN | MARK: 10011100 00000001 (no_bats_in_this_room)
+@ Test for end of loop.
+SNS                   | DUP
+NTSTSSTTTSSSSSSSSTSN  | BRZ > 10011100 00000010 (are_bats_near:loop_end)
+@ No bats found yet, but still need to check some rooms.
+@ Decrement tunnel index and loop again.
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+NSNTSSTTTSSSSSSSSSSN  | JMP > 10011100 00000000 (are_bats_near:loop)
+@ No bats found in nearby rooms. Clean up and return.
+NSSVTSSTTTSSSSSSSSTSN | MARK: 10011100 00000010 (are_bats_near:loop_end)
+SNN                   | DROP
+SNN                   | DROP
+SSSSN                 | PUSH 0
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   are_pits_near
+@ Description:
+@   Given a room number, checks rooms within one hop for pits.
+@   Returns 1 if pits are present or 0 if no pits.
+@ Call Stack:
+@   room_number  <-- TOS
+@ Return Stack:
+@   1 or 0  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSSTTTSTN         | MARK: 10011101 (are_pits_near)
+
+@ Prepare the stack by loading the number of links per room and decrementing.
+@ We will loop until this reaches 0 or we find pits.
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+
+@ Check one nearby room on each pass through this loop.
+@ TOS> tunnel_index, room_number
+NSSVTSSTTTSTSSSSSSSSN | MARK: 10011101 00000000 (are_pits_near:loop)
+SNS                   | DUP
+SSSTTN                | PUSH 3
+NSTTTSSN              | JSR > 1100 (deepdup)
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+NSTTSSSTTSTN          | JSR > 10001101 (room_has_pits)
+NTSTSSTTTSTSSSSSSSTN  | BRZ > 10011101 00000001 (no_pits_in_this_room)
+@ Found pits. Clean up and return.
+SNN                   | DROP
+SNN                   | DROP
+SSSTN                 | PUSH 1
+NTN                   | RTS
+NSSVTSSTTTSTSSSSSSSTN | MARK: 10011101 00000001 (no_pits_in_this_room)
+@ Test for end of loop.
+SNS                   | DUP
+NTSTSSTTTSTSSSSSSTSN  | BRZ > 10011101 00000010 (are_pits_near:loop_end)
+@ No pits found yet, but still need to check some rooms.
+@ Decrement tunnel index and loop again.
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+NSNTSSTTTSTSSSSSSSSN  | JMP > 10011101 00000000 (are_pits_near:loop)
+@ No pits found in nearby rooms. Clean up and return.
+NSSVTSSTTTSTSSSSSSTSN | MARK: 10011101 00000010 (are_pits_near:loop_end)
+SNN                   | DROP
+SNN                   | DROP
+SSSSN                 | PUSH 0
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   is_wumpus_very_near
+@ Description:
+@   Given a room number, checks rooms within one hop for the wumpus.
+@   Returns 1 if wumpus is present, otherwise 0.
+@ Call Stack:
+@   room_number  <-- TOS
+@ Return Stack:
+@   1 or 0  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSSTTTTTN         | MARK: 10011111 (is_wumpus_very_near)
+
+@ Prepare the stack by loading the number of links per room and decrementing.
+@ We will loop until this reaches 0 or we find the wumpus.
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+
+@ Check one nearby room on each pass through this loop.
+@ TOS> tunnel_index, room_number
+NSSVTSSTTTTTSSSSSSSSN | MARK: 10011111 00000000 (is_wumpus_very_near:loop)
+SNS                   | DUP
+SSSTTN                | PUSH 3
+NSTTTSSN              | JSR > 1100 (deepdup)
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+NSTTSTSSSSSN          | JSR > 10100000 (room_has_wumpus)
+NTSTSSTTTTTSSSSSSSTN  | BRZ > 10011111 00000001 (no_wumpus_in_this_room)
+@ Found wumpus. Clean up and return.
+SNN                   | DROP
+SNN                   | DROP
+SSSTN                 | PUSH 1
+NTN                   | RTS
+NSSVTSSTTTTTSSSSSSSTN | MARK: 10011111 00000001 (no_wumpus_in_this_room)
+@ Test for end of loop.
+SNS                   | DUP
+NTSTSSTTTTTSSSSSSTSN  | BRZ > 10011111 00000010 (is_wumpus_very_near:loop_end)
+@ No wumpus found yet, but still need to check some rooms.
+@ Decrement tunnel index and loop again.
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+NSNTSSTTTTTSSSSSSSSN  | JMP > 10011111 00000000 (is_wumpus_very_near:loop)
+@ No wumpus found in nearby rooms. Clean up and return.
+NSSVTSSTTTTTSSSSSSTSN | MARK: 10011111 00000010 (is_wumpus_very_near:loop_end)
+SNN                   | DROP
+SNN                   | DROP
+SSSSN                 | PUSH 0
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   is_wumpus_near
+@ Description:
+@   Given a room number, checks rooms within two hops for the wumpus.
+@   Returns 1 if wumpus is present, otherwise 0.
+@ Call Stack:
+@   room_number  <-- TOS
+@ Return Stack:
+@   1 or 0  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSSTTTTSN         | MARK: 10011110 (is_wumpus_near)
+
+@ Prepare the stack by loading the number of links per room and decrementing.
+@ We will loop until this reaches 0 or we find the wumpus.
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+
+@ Check one nearby room and its connecting rooms on each pass through this loop.
+@ TOS> tunnel_index, room_number
+NSSVTSSTTTTSSSSSSSSSN | MARK: 10011110 00000000 (is_wumpus_near:loop)
+SNS                   | DUP
+SSSTTN                | PUSH 3
+NSTTTSSN              | JSR > 1100 (deepdup)
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+@ TOS> tunnel_endpoint, tunnel_index, room_number
+SNS                   | DUP
+NSTTSTSSSSSN          | JSR > 10100000 (room_has_wumpus)
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+NTSTSSTTTTSSSSSSSTTN  | BRZ > 10011110 00000011 (found_wumpus_one_hop)
+NSTTSSTTTTTN          | JSR > 10011111 (is_wumpus_very_near)
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+NTSTSSTTTTSSSSSSTSSN  | BRZ > 10011110 00000100 (found_wumpus_two_hops)
+@ Test for end of loop.
+SNS                   | DUP
+NTSTSSTTTTSSSSSSSTSN  | BRZ > 10011110 00000010 (is_wumpus_near:loop_end)
+@ No wumpus found yet, but still need to check some rooms.
+@ Decrement tunnel index and loop again.
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+NSNTSSTTTTSSSSSSSSSN  | JMP > 10011110 00000000 (is_wumpus_near:loop)
+
+@ No wumpus found in nearby rooms. Clean up and return.
+NSSVTSSTTTTSSSSSSSTSN | MARK: 10011110 00000010 (is_wumpus_near:loop_end)
+SNN                   | DROP
+SNN                   | DROP
+SSSSN                 | PUSH 0
+NTN                   | RTS
+
+@ Found wumpus. Clean up and return.
+NSSVTSSTTTTSSSSSSSTTN | MARK: 10011110 00000011 (found_wumpus_one_hop)
+SNN                   | DROP
+NSSVTSSTTTTSSSSSSTSSN | MARK: 10011110 00000100 (found_wumpus_two_hops)
+SNN                   | DROP
+SNN                   | DROP
+SSSTN                 | PUSH 1
+NTN                   | RTS
+
+#endif
diff --git a/examples/hunt-the-wumpus/wump_init.pvvs b/examples/hunt-the-wumpus/wump_init.pvvs
new file mode 100644 (file)
index 0000000..9d7543d
--- /dev/null
@@ -0,0 +1,757 @@
+#ifndef WUMP_INIT
+#define WUMP_INIT
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
+@ See LICENSE.txt file for copyright and license details.
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   wump_init
+@ Description:
+@   Master function that creates a new cave, links the rooms, and populates them
+@   according to the options set by the user in wump_conf.pvvs.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stdio.pvvs>
+#include <wump_conf.pvvs>
+#include <wump_strings.pvvs>
+#include <wump_ui.pvvs>
+NSSVTSSSSSTSN         | MARK: 10000010 (wump_init)
+
+@ Load the user-configurable options.
+NSTTSSSSSSTN          | JSR > 10000001 (set_config_values)
+
+@ Seed the RNG.
+NSTTTTTTTTTSSSSSTTTN  | JSR > 11111111 00000111 (please_seed_rng)
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSTTSSSSSTTN          | JSR > 10000011 (seed_rng)
+
+@ Build the cave.
+NSTTSSSSTSSN          | JSR > 10000100 (build_cave)
+
+@ Populate the cave.
+NSTTSSSSTSTN          | JSR > 10000101 (populate_cave)
+
+@ Initialization is complete.
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   build_circular_tunnels
+@ Description:
+@   Builds a set of tunnels that ensures every room in the cave is connected.
+@   Assumes that tunnel slots 0 and 1 are set to the value -1 (unconnected).
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+#include <wump_game.pvvs>
+NSSVTSSSTTTSN         | MARK: 10001110 (build_circular_tunnels)
+
+@ Prepare TOS> current_room, hop_length
+NSTTSSSSTTTN          | JSR > 10000111 (generate_cave_hop_length)
+SSSSN                 | PUSH 0 (current room)
+
+@ Have we already built a tunnel from this room?
+@ If so, tunnel slot 0 will not be -1.
+NSSVTSSSTTTSSSSSSSSSN | MARK: 10001110 00000000 (tunnel_loop)
+SNS                   | DUP
+SSSSN                 | PUSH 0 (first tunnel slot)
+SNT                   | SWAP
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+NTTTSSSTTTSSSSSSSTSN  | BMI > 10001110 00000010
+NSNTSSSTTTSSSSSSSSTN  | JMP > 10001110 00000001 (loop_complete)
+NSSVTSSSTTTSSSSSSSTSN | MARK: 10001110 00000010
+@ No tunnel yet, so start building a tunnel.
+@ TOS> current_room, hop_length
+SNS                   | DUP
+SNS                   | DUP
+SSSTSSN               | PUSH 4
+NSTTTSSN              | JSR > 1100 (deepdup)
+TSSS                  | ADD
+SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
+TTT                   | LOAD
+TSTT                  | MODULO
+SNT                   | SWAP
+SSSSN                 | PUSH 0 (slot number)
+SNT                   | SWAP
+NSTTSSSTSSTN          | JSR > 10001001 (set_tunnel_destination)
+@ One direction of the tunnel is built. Now build the other direction.
+SNS                   | DUP
+SSSSN                 | PUSH 0 (slot number)
+SNT                   | SWAP
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+SNT                   | SWAP
+SSSTSN                | PUSH 2
+NSTTTSSN              | JSR > 1100 (deepdup)
+SSSTN                 | PUSH 1
+SNT                   | SWAP
+NSTTSSSTSSTN          | JSR > 10001001 (set_tunnel_destination)
+@ Loop again to build the next tunnel.
+NSNTSSSTTTSSSSSSSSSN  | JMP > 10001110 00000000 (tunnel_loop)
+
+@ Clean up and return
+NSSVTSSSTTTSSSSSSSSTN | MARK: 10001110 00000001 (loop_complete)
+SNN                   | DROP
+SNN                   | DROP
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   get_next_tunnel_slot
+@ Description:
+@   Returns the index of next available tunnel slot for room_num, or -1 if full.
+@ Call Stack:
+@   room_num  <-- TOS
+@ Return Stack:
+@   tunnel_index  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <wump_game.pvvs>
+NSSVTSSTSTTTN         | MARK: 10010111 (get_next_tunnel_slot)
+
+@ Build the pointer: (room_num * size_of_room_struct) + 2 + ROOM_DATA_BASE
+@ Where the '+2' skips over the 'pits' and 'bats' booleans for this room.
+NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
+TSSN                  | MULTIPLY
+SSSTSN                | PUSH 2
+TSSS                  | ADD
+SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (ROOM_DATA_BASE address)
+TSSS                  | ADD
+
+@ Save a copy of this pointer for later use when recovering the tunnel index.
+SNS                   | DUP
+
+@ Push a loop counter onto the stack.
+SSSSN                 | PUSH 0 (counter)
+SNT                   | SWAP
+
+@ Main loop - Search for an available tunnel slot.
+@ TOS> ptr_to_tunnel_slot, loop_counter, ptr_to_first_tunnel_slot
+NSSVTSSTSTTTSSSSSSSSN | MARK: 10010111 00000000 (main_loop)
+SNS                   | DUP
+TTT                   | LOAD
+NTTTSSTSTTTSSSSSSSTN  | BMI > 10010111 00000001 (found_open_slot)
+@ No match.
+@ Increment the pointer.
+SSSTN                 | PUSH 1
+TSSS                  | ADD
+@ Increment the loop counter.
+SNT                   | SWAP
+SSSTN                 | PUSH 1
+TSSS                  | ADD
+@ See if we have run out of possible tunnel slots.
+SNS                   | DUP
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (GAME_DATA_BASE+3 = links_per_room address)
+TTT                   | LOAD
+TSST                  | SUBTRACT
+NTSTSSTSTTTSSSSSSTSN  | BRZ > 10010111 00000010 (no_open_slots)
+@ There are still more slots to check. Prepare to loop again.
+SNT                   | SWAP
+NSNTSSTSTTTSSSSSSSSN  | JMP > 10010111 00000000 (main_loop)
+
+@ No available tunnel slots for this room.
+NSSVTSSTSTTTSSSSSSTSN | MARK: 10010111 00000010 (no_open_slots)
+SNN                   | DROP
+SNN                   | DROP
+SNN                   | DROP
+SSTTN                 | PUSH -1
+NTN                   | RTS
+
+@ Found an open tunnel slot.
+NSSVTSSTSTTTSSSSSSSTN | MARK: 10010111 00000001 (found_open_slot)
+@ Drop the loop counter.
+SNT                   | SWAP
+SNN                   | DROP
+@ Recover the tunnel slot index from the tunnel slot pointer.
+SNT                   | SWAP
+TSST                  | SUBTRACT
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   build_random_tunnels
+@ Description:
+@   Randomly builds tunnels between rooms until all tunnels slots are used.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <heap.pvvs>
+#include <math.pvvs>
+#include <stack.pvvs>
+NSSVTSSTSTTSN         | MARK: 10010110 (build_random_tunnels)
+
+@ Build a temporary data structure in the buffer residing at 0x3000.
+@
+@ 0x3000 contains the number of elements in an array that starts at 0x3001.
+@ Each array element is one word long and contains the index of a room
+@ with open tunnel slots.
+@
+@ This init code is here rather than a subroutine since the structure it builds
+@ is private to this function.
+@ Before looping, push the number of elements in the array (=num_rooms).
+@ Keep a copy of this number to use as a loop counter.
+SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE = num_rooms address)
+TTT                   | LOAD
+SNS                   | DUP
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+SNT                   | SWAP
+TTS                   | STORE
+@ Init loop - Populates the 'rooms with available tunnel slots' array.
+@ TOS> loop_counter
+NSSVTSSTSTTSSSSSSSTSN | MARK: 10010110 00000010 (init_loop)
+@ Populate one of the array entries.
+SNS                   | DUP
+SNS                   | DUP
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TSSS                  | ADD
+SNT                   | SWAP
+SSSTN                 | PUSH +1
+TSST                  | SUBTRACT
+TTS                   | STORE
+@ Decrement the loop counter and test for end of loop.
+SSSTN                 | PUSH +1
+TSST                  | SUBTRACT
+SNS                   | DUP
+NTSTSSTSTTSSSSSSSTTN  | BRZ > 10010110 00000011 (init_loop_end)
+NSNTSSTSTTSSSSSSSTSN  | JMP > 10010110 00000010 (init_loop)
+NSSVTSSTSTTSSSSSSSTTN | MARK: 10010110 00000011 (init_loop_end)
+SNN                   | DROP
+NSNTSSTSTTSSSSSSSSTN  | JMP > 10010110 00000001 (main_loop)
+
+@@@@@ INIT IS COMPLETE - STACK IS EMPTY @@@@@
+
+@ Build one random tunnel connection per pass through this loop.
+NSSVTSSTSTTSSSSSSSSTN | MARK: 10010110 00000001 (main_loop)
+@ Use 'random_number mod number_of_array_entries' to select a starting room.
+NSTTSSSSN             | JSR > 10000 (random)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TTT                   | LOAD
+TSTT                  | MODULO
+SSSTN                 | PUSH 1
+TSSS                  | ADD
+SNS                   | DUP
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TSSS                  | ADD
+TTT                   | LOAD
+@ TOS> start_room_num, start_array_index
+@ Now we randomly select a room for the endpoint.
+NSSVTSSTSTTSSSSSSTSSN | MARK: 10010110 00000100 (select_random_dst_room)
+NSTTSSSSN             | JSR > 10000 (random)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TTT                   | LOAD
+TSTT                  | MODULO
+SSSTN                 | PUSH 1
+TSSS                  | ADD
+SNS                   | DUP
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TSSS                  | ADD
+TTT                   | LOAD
+@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
+@ Verify the endpoint room is different from the startpoint room.
+SNS                   | DUP
+SSSTSSN               | PUSH 4
+NSTTTSSN              | JSR > 1100 (deepdup)
+TSST                  | SUBTRACT
+NTSTSSTSTTSSSSSSTSTN  | BRZ > 10010110 00000101 (rooms_matched)
+NSNTSSTSTTSSSSSSTTSN  | JMP > 10010110 00000110 (connect_rooms)
+@ The rooms matched. Drop the selected destination room and try again.
+NSSVTSSTSTTSSSSSSTSTN | MARK: 10010110 00000101 (rooms_matched)
+SNN                   | DROP
+SNN                   | DROP
+NSNTSSTSTTSSSSSSTSSN  | JMP > 10010110 00000100 (select_random_dst_room)
+@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
+@ The rooms are different. Time to build a connection between them.
+NSSVTSSTSTTSSSSSSTTSN | MARK: 10010110 00000110 (connect_rooms)
+@ First build a one-way tunnel.
+SSSTTN                | PUSH 3
+NSTTTSSN              | JSR > 1100 (deepdup)
+SSSTSN                | PUSH 2
+NSTTTSSN              | JSR > 1100 (deepdup)
+SNS                   | DUP
+NSTTSSTSTTTN          | JSR > 10010111 (get_next_tunnel_slot)
+SNT                   | SWAP
+NSTTSSSTSSTN          | JSR > 10001001 (set_tunnel_destination)
+@ Then make it a two-way tunnel.
+SNS                   | DUP
+SSSTSSN               | PUSH 4
+NSTTTSSN              | JSR > 1100 (deepdup)
+SNS                   | DUP
+NSTTSSTSTTTN          | JSR > 10010111 (get_next_tunnel_slot)
+SNT                   | SWAP
+NSTTSSSTSSTN          | JSR > 10001001 (set_tunnel_destination)
+@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
+@ If that was the last tunnel slot in either room, remove it
+@ from the 'rooms_with_available_tunnel_slots' array.
+NSTTSSTSTTTN          | JSR > 10010111 (get_next_tunnel_slot)
+NTTTSSTSTTSSSSSSTTTN  | BMI > 10010110 00000111 (remove_empty_room_1)
+SNN                   | DROP
+NSNTSSTSTTSSSSSTSSSN  | JMP > 10010110 00001000 (check_second_room)
+NSSVTSSTSTTSSSSSSTTTN | MARK: 10010110 00000111 (remove_empty_room_1)
+SNS                   | DUP
+NSTTSSTSTTSSSSSTTSSN  | JSR > 10010110 00001100 (remove_element_from_array)
+SSSTTN                | PUSH 3
+NSTTTSSN              | JSR > 1100 (deepdup)
+TSST                  | SUBTRACT
+NTTTSSTSTTSSSSSTTSTN  | BMI > 10010110 00001101 (update_second_room_index)
+NSNTSSTSTTSSSSSTSSSN  | JMP > 10010110 00001000 (check_second_room)
+NSSVTSSTSTTSSSSSTTSTN | MARK: 10010110 00001101 (update_second_room_index)
+SNT                   | SWAP
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+SNT                   | SWAP
+NSSVTSSTSTTSSSSSTSSSN | MARK: 10010110 00001000 (check_second_room)
+NSTTSSTSTTTN          | JSR > 10010111 (get_next_tunnel_slot)
+NTTTSSTSTTSSSSSTSSTN  | BMI > 10010110 00001001 (remove_empty_room_2)
+SNN                   | DROP
+NSNTSSTSTTSSSSSTSTSN  | JMP > 10010110 00001010 (main_loop_end_test)
+NSSVTSSTSTTSSSSSTSSTN | MARK: 10010110 00001001 (remove_empty_room_2)
+NSTTSSTSTTSSSSSTTSSN  | JSR > 10010110 00001100 (remove_element_from_array)
+@ If the array is now empty or only contains one room, return.
+@ Otherwise, loop again and build another random tunnel.
+NSSVTSSTSTTSSSSSTSTSN | MARK: 10010110 00001010 (main_loop_end_test)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TTT                   | LOAD
+SSSTSN                | PUSH 2
+TSST                  | SUBTRACT
+NTTTSSTSTTSSSSSTSTTN  | BMI > 10010110 00001011 (return)
+NSNTSSTSTTSSSSSSSSTN  | JMP > 10010110 00000001 (main_loop)
+NSSVTSSTSTTSSSSSTSTTN | MARK: 10010110 00001011 (return)
+NTN                   | RTS
+
+@ A private subroutine to remove one element from the temp array.
+@ Consumes the array index from TOS.
+NSSVTSSTSTTSSSSSTTSSN | MARK: 10010110 00001100 (remove_element_from_array)
+@ First, stash a copy of the array index immediately after the temporary array.
+@ This allows us to find it using the num_array_elements for use with spew
+@ after slurp has filled the stack with a variable number of elements.
+SNS                   | DUP
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TTT                   | LOAD
+TSSS                  | ADD
+SSSTN                 | PUSH 1
+TSSS                  | ADD
+SNT                   | SWAP
+TTS                   | STORE
+@ Now slurp and spew the array to delete the desired element.
+SSSTN                 | PUSH 1
+TSSS                  | ADD
+SNS                   | DUP
+@ TOS> index+1, index+1
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TTT                   | LOAD
+SNT                   | SWAP
+TSST                  | SUBTRACT
+@ Special case: deleting last element of array means no need to delete.
+SNS                   | DUP
+NTTTSSTSTTSSSSSTTTSN  | BMI > 10010110 00001110 (deleting_last_element)
+NSNTSSTSTTSSSSSTTTTN  | JMP > 10010110 00001111 (not_deleting_last_element)
+NSSVTSSTSTTSSSSSTTTSN | MARK: 10010110 00001110 (deleting_last_element)
+SNN                   | DROP
+SNN                   | DROP
+NSNTSSTSTTSSSSTSSSSN  | JMP > 10010110 00010000 (decrement_array_counter)
+NSSVTSSTSTTSSSSSTTTTN | MARK: 10010110 00001111 (not_deleting_last_element)
+SNT                   | SWAP
+@ TOS> index+1, count=num_array_elements-(index+1)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TSSS                  | ADD
+SNT                   | SWAP
+@ TOS> count=num_array_elements-(index+1), address=0x3000+index+1
+NSTTTTTSN             | JSR > 11110 (slurp)
+@ Recover the array index that we stashed on the heap.
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TTT                   | LOAD
+TSSS                  | ADD
+SSSTN                 | PUSH 1
+TSSS                  | ADD
+TTT                   | LOAD
+@ TOS> index
+SNS                   | DUP
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TSSS                  | ADD
+SNT                   | SWAP
+@ TOS> index, address=0x3000+index
+SSSTN                 | PUSH 1
+TSSS                  | ADD
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TTT                   | LOAD
+SNT                   | SWAP
+TSST                  | SUBTRACT
+@ TOS> count = num_array_elements-(index+1), address=0x3000+index
+NSTTTTTTN             | JSR > 11111 (spew)
+@ Decrement the array element counter.
+NSSVTSSTSTTSSSSTSSSSN | MARK: 10010110 00010000 (decrement_array_counter)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
+SNT                   | SWAP
+TTS                   | STORE
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   build_cave
+@ Description:
+@   Clears the cave data structure on the heap and builds new tunnels.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSSSTSSN         | MARK: 10000100 (build_cave)
+NSTTSSSSTTSN          | JSR > 10000110 (clear_cave_data)
+NSTTSSSTTTSN          | JSR > 10001110 (build_circular_tunnels)
+NSTTSSTSTTSN          | JSR > 10010110 (build_random_tunnels)
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   set_tunnel_destination
+@ Description:
+@   Sets 'slot' of 'room_number' to point to 'dst_room_number'.
+@ Call Stack:
+@   dst_room_number
+@   slot
+@   room_number  <-- TOS
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <wump_game.pvvs>
+NSSVTSSSTSSTN         | MARK: 10001001 (set_tunnel_destination)
+@ The pointer we seek is:
+@ (room_number * room_struct_size) + 2 + slot + ROOM_DATA_BASE
+@ Where the '+2' accounts for the pit and bat booleans.
+NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
+TSSN                  | MULTIPLY
+SSSTSN                | PUSH +2
+TSSS                  | ADD
+TSSS                  | ADD
+SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (ROOM_DATA_BASE address)
+TSSS                  | ADD
+SNT                   | SWAP
+TTS                   | STORE
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   generate_cave_hop_length
+@ Description:
+@   In order to ensure cave is fully connected, generate a number, 'hop_length',
+@   that is relatively prime to the number of rooms in the cave.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   hop_length
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <math.pvvs>
+NSSVTSSSSTTTN         | MARK: 10000111 (generate_cave_hop_length)
+NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
+@ Check for gcd(hop_length,num_rooms) = 1.
+SNS                   | DUP
+SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
+TTT                   | LOAD
+NSTTSSTSN             | JSR > 10010 (gcd)
+SSSTN                 | PUSH +1
+TSST                  | SUBTRACT
+NTSTSSSSTTTSSSSSSSSN  | BRZ > 10000111 00000000
+SNN                   | DROP
+NSNTSSSSTTTN          | JMP > 10000111 (generate_cave_hop_length)
+NSSVTSSSSTTTSSSSSSSSN | MARK: 10000111 00000000
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   clear_cave_data
+@ Description:
+@   Writes -1 over the entire cave data array.
+@   This ensures each room starts unconnected.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <heap.pvvs>
+#include <wump_game.pvvs>
+NSSVTSSSSTTSN         | MARK: 10000110 (clear_cave_data)
+SSTTN                 | PUSH -1 (pattern)
+SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (ROOM_DATA_BASE address)
+SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE address)
+TTT                   | LOAD
+NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
+TSSN                  | MULTIPLY
+NSTTTSSSN             | JSR > 11000 (memset)
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   get_random_room
+@ Description:
+@   Returns a valid room number
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   room_num  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <math.pvvs>
+NSSVTSSSTSTSN         | MARK: 10001010 (get_random_room)
+NSTTSSSSN             | JSR > 10000 (random)
+SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
+TTT                   | LOAD
+TSTT                  | MODULO
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   set_bats
+@ Description:
+@   Set the 'bats' boolean for a specific room.
+@ Call Stack:
+@   value (0 or 1)
+@   room_number
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <wump_game.pvvs>
+NSSVTSSTSSSSN         | MARK: 10010000 (set_bats)
+@ We seek the pointer:
+@   (room_number * room_struct_size) + 1 + ROOM_DATA_BASE
+@ where '+1' accounts for the offset of the bat boolean in the desired room.
+NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
+TSSN                  | MULTIPLY
+SSSTN                 | PUSH +1
+TSSS                  | ADD
+SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (GAME_DATA_BASE address)
+TSSS                  | ADD
+SNT                   | SWAP
+TTS                   | STORE
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   set_pits
+@ Description:
+@   Set the 'pits' boolean for a specific room.
+@ Call Stack:
+@   value (0 or 1)
+@   room_number
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <wump_game.pvvs>
+NSSVTSSTSSSTN         | MARK: 10010001 (set_pits)
+@ We seek the pointer:
+@   (room_number * room_struct_size) + 0 + ROOM_DATA_BASE
+@ where '+0' accounts for the offset of the pit boolean in the desired room.
+NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
+TSSN                  | MULTIPLY
+SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (GAME_DATA_BASE address)
+TSSS                  | ADD
+SNT                   | SWAP
+TTS                   | STORE
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   reset_cave_population
+@ Description:
+@   Remove all bats and pits from the cave.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSTSSTSN         | MARK: 10010010 (reset_cave_population)
+
+@ Clear the bat and pit booleans by setting every room to false(=0).
+@ First prepare a loop index.
+SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE+0 = number_of_rooms address)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+NSSVTSSTSSTSSSSSSSSSN | MARK: 10010010 00000000 (empty_cave_loop)
+@ Scare all the bats out of the room.
+SNS                   | DUP
+SSSSN                 | PUSH 0 (false)
+SNT                   | SWAP
+NSTTSSTSSSSN          | JSR > 10010000 (set_bats)
+@ Fill any pits.
+SNS                   | DUP
+SSSSN                 | PUSH 0 (false)
+SNT                   | SWAP
+NSTTSSTSSSTN          | JSR > 10010001 (set_pits)
+@ Decrement loop counter and test for end of loop.
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+SNS                   | DUP
+NTTTSSTSSTSSSSSSSSTN  | BMI > 10010010 00000001 (empty_cave_loop_end)
+NSNTSSTSSTSSSSSSSSSN  | JMP > 10010010 00000000 (empty_cave_loop)
+@ Loop is complete. Clean up and return.
+NSSVTSSTSSTSSSSSSSSTN | MARK: 10010010 00000001 (empty_cave_loop_end)
+SNN                   | DROP
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   populate_bats
+@ Description:
+@   Randomly place a user-defined number of bats in the cave.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <wump_game.pvvs>
+NSSVTSSTSSTTN         | MARK: 10010011 (populate_bats)
+
+@ First prepare a loop index.
+SSSTSSSSSSSSSSTSN     | PUSH 0x1002 (GAME_DATA_BASE+2 = number_of_bats address)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+@ Find a random room that does not already contain bats.
+NSSVTSSTSSTTSSSSSSTSN | MARK: 10010011 00000010 (place_bats)
+NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
+SNS                   | DUP
+NSTTSSSTTSSN          | JSR > 10001100 (room_has_bats)
+NTSTSSTSSTTSSSSSSTTN  | BRZ > 10010011 00000011 (no_bats_in_room)
+SNN                   | DROP
+NSNTSSTSSTTSSSSSSTSN  | JMP > 10010011 00000010 (place_bats)
+@ Room is empty. Place bats.
+NSSVTSSTSSTTSSSSSSTTN | MARK: 10010011 00000011 (no_bats_in_room)
+SSSTN                 | PUSH 1 (true)
+SNT                   | SWAP
+NSTTSSTSSSSN          | JSR > 10010000 (set_bats)
+@ Decrement loop counter and test for loop completion.
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+SNS                   | DUP
+NTTTSSTSSTTSSSSSTSSN  | BMI > 10010011 00000100 (place_bats_loop_end)
+NSNTSSTSSTTSSSSSSTSN  | JMP > 10010011 00000010 (place_bats)
+@ Loop is complete. Clean up and return.
+NSSVTSSTSSTTSSSSSTSSN | MARK: 10010011 00000100 (place_bats_loop_end)
+SNN                   | DROP
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   populate_pits
+@ Description:
+@   Randomly place a user-defined number of pits in the cave.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <wump_game.pvvs>
+NSSVTSSTSTSSN         | MARK: 10010100 (populate_pits)
+
+@ First prepare a loop index.
+SSSTSSSSSSSSSSSTN     | PUSH 0x1001 (GAME_DATA_BASE+1 = number_of_pits address)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+@ Find a random room that does not already contain pits.
+NSSVTSSTSTSSSSSSSSTSN | MARK: 10010100 00000010 (place_pits)
+NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
+SNS                   | DUP
+NSTTSSSTTSTN          | JSR > 10001101 (room_has_pits)
+NTSTSSTSTSSSSSSSSTTN  | BRZ > 10010100 00000011 (no_pits_in_room)
+SNN                   | DROP
+NSNTSSTSTSSSSSSSSTSN  | JMP > 10010100 00000010 (place_pits)
+@ Room is empty. Place pits.
+NSSVTSSTSTSSSSSSSSTTN | MARK: 10010100 00000011 (no_pits_in_room)
+SSSTN                 | PUSH 1 (true)
+SNT                   | SWAP
+NSTTSSTSSSTN          | JSR > 10010001 (set_pits)
+@ Decrement loop counter and test for loop completion.
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+SNS                   | DUP
+NTTTSSTSTSSSSSSSTSSN  | BMI > 10010100 00000100 (place_pits_loop_end)
+NSNTSSTSTSSSSSSSSTSN  | JMP > 10010100 00000010 (place_pits)
+@ Loop is complete. Clean up and return.
+NSSVTSSTSTSSSSSSSTSSN | MARK: 10010100 00000100 (place_pits_loop_end)
+SNN                   | DROP
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   place_player
+@ Description:
+@   Place the player in a suitable starting room.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSTSTSTN         | MARK: 10010101 (place_player)
+
+@ Find out where the wumpus is located.
+SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (GAME_DATA_BASE+7 = wumpus_room address)
+TTT                   | LOAD
+@ Place the player in a different room than the wumpus.
+NSSVTSSTSTSTSSSSSSSSN | MARK: 10010101 00000000 (place_player_loop)
+NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
+SNT                   | SWAP
+SNS                   | DUP
+SSSTTN                | PUSH 3
+NSTTTSSN              | JSR > 1100 (deepdup)
+@ TOS> rand_room, wump_room, wump_room, rand_room
+TSST                  | SUBTRACT
+NTSTSSTSTSTSSSSSSSTN  | BRZ > 10010101 00000001 (same_room)
+NSNTSSTSTSTSSSSSSTSN  | JMP > 10010101 00000010 (different_rooms)
+NSSVTSSTSTSTSSSSSSSTN | MARK: 10010101 00000001 (same_room)
+SNN                   | DROP
+NSNTSSTSTSTSSSSSSSSN  | JMP > 10010101 00000000 (place_player_loop)
+NSSVTSSTSTSTSSSSSSTSN | MARK: 10010101 00000010 (different_rooms)
+SNN                   | DROP
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (GAME_DATA_BASE+6 = player_room address)
+SNT                   | SWAP
+TTS                   | STORE
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   populate_cave
+@ Description:
+@   Populate the cave with various creatures and features.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSSSTSTN         | MARK: 10000101 (populate_cave)
+
+@ Initialize the cave to an unpopulated state.
+NSTTSSTSSTSN          | JSR > 10010010 (reset_cave_population)
+
+@ Place bats in the now-empty cave.
+NSTTSSTSSTTN          | JSR > 10010011 (populate_bats)
+
+@ Place pits in the now-empty cave.
+NSTTSSTSTSSN          | JSR > 10010100 (populate_pits)
+
+@ Place the wumpus.
+SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (GAME_DATA_BASE+7 = wumpus_room address)
+NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
+TTS                   | STORE
+
+@ Place the player.
+NSTTSSTSTSTN          | JSR > 10010101 (place_player)
+
+NTN                   | RTS
+
+#endif
diff --git a/examples/hunt-the-wumpus/wump_strings.pvvs b/examples/hunt-the-wumpus/wump_strings.pvvs
new file mode 100644 (file)
index 0000000..d8cfb69
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef WUMP_STRING
+#define WUMP_STRING
+
+@ Some text strings in this file were imported from:
+@ $NetBSD: wump.c,v 1.17 2005/02/15 12:56:20 jsm Exp $
+@ Copyright (c) 1989, 1993
+@ The Regents of the University of California.  All rights reserved.
+@
+@ Everything else is
+@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
+@ See LICENSE.txt file for copyright and license details.
+
+NSSVTTTTTTTTSSSSSSSSN | Mark: 11111111 00000000 (wump_kill)
+A"\n*ROAR* *chomp* *snurfle* *chomp*!\nMuch to the delight of the Wumpus, you walked right into his mouth,\nmaking you one of the easiest dinners he's ever had!  For you, however,\nit's a rather unpleasant death.  The only good thing is that it's been\nso long since the evil Wumpus cleaned his teeth that you immediately\npassed out from the stench!\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSSSSTN | Mark: 11111111 00000001 (kill_wump)
+A"\n*thwock!* *groan* *crash*\nA horrible roar fills the cave, and you realize, with a smile, that you\nhave slain the evil Wumpus and won the game!  You don't want to tarry for\nlong, however, because not only is the Wumpus famous, but the stench of\ndead Wumpus is also quite well known, a stench plenty enough to slay the\nmightiest adventurer at a single whiff!!\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSSSTSN | Mark: 11111111 00000010 (no_arrows)
+A"\nYou turn and look at your quiver, and realize with a sinking feeling\nthat you've just shot your last arrow (figuratively, too).  Sensing this\nwith its psychic powers, the evil Wumpus rampagees through the cave, finds\nyou, and with a mighty *ROAR* eats you alive!\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSSSTTN | Mark: 11111111 00000011 (shoot_self)
+A"\n*Thwack!*  A sudden piercing feeling informs you that the ricochet\nof your wild arrow has resulted in it wedging in your side, causing\nextreme agony.  The evil Wumpus, with its psychic powers, realizes this\nand immediately rushes to your side, not to help, alas, but to EAT YOU!\n(*CHOMP*)\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSSTSSN | Mark: 11111111 00000100 (jump)
+A"\nWith a jaunty step you enter the magic tunnel.  As you do, you\nnotice that the walls are shimmering and glowing.  Suddenly you feel\na very curious, warm sensation and find yourself in room %u!!\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSSTSTN | Mark: 11111111 00000101 (pit_kill)
+A"\n*AAAUUUUGGGGGHHHHHhhhhhhhhhh...*\nThe whistling sound and updraft as you walked into this room of the\ncave apparently wasn't enough to clue you in to the presence of the\nbottomless pit.  You have a lot of time to reflect on this error as\nyou fall many miles to the core of the earth.  Look on the bright side;\nyou can at least find out if Jules Verne was right...\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSSTTSN | Mark: 11111111 00000110 (pit_survive)
+A"\nWithout conscious thought you grab for the side of the cave and manage\nto grasp onto a rocky outcrop.  Beneath your feet stretches the limitless\ndepths of a bottomless pit!  Rock crumbles beneath your feet!\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSSTTTN | Mark: 11111111 00000111 (please_seed_rng)
+A"\n\n\n\nWelcome to Hunt the Wumpus!\n\nPlease press 16 keys to seed the RNG.\n               |\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSTSSSN | Mark: 11111111 00001000 (problem_with_input)
+A"I don't understand!\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSTSSTN | Mark: 11111111 00001001 (instructions)
+A"\n\nWelcome to the game of Hunt the Wumpus.\n\nThe Wumpus typically lives in a cave of twenty rooms, with each room having\nthree tunnels connecting it to other rooms in the cavern.  Caves may vary,\nhowever, depending on options specified when starting the game.\n\nThe game has the following hazards for intrepid adventurers to wind their\nway through:\n\n  Pits   -- If you fall into one of the bottomless pits, you find yourself\n            slung back out on the far side of the Earth and in very poor\n            shape to continue your quest since you're dead.\n\n  Bats   -- As with any other cave, the Wumpus cave has bats in residence.\n            These are a bit more potent, however, and if you stumble into\n            one of their rooms they will rush up and carry you elsewhere in\n            the cave.\n\n  Wumpus -- If you happen to walk into the room the Wumpus is in you'll find\n            that he has quite an appetite for young adventurous humans!  Not\n            recommended.\n\nThe Wumpus, by the way, is not bothered by the hazards since he has sucker\nfeet and is too big for a bat to lift.  If you try to shoot him and miss,\nthere's also a chance that he'll up and move himself into another cave,\nthough by nature the Wumpus is a sedentary creature.\n\nEach turn you may either move or shoot a crooked arrow.  Moving is done\nsimply by specifying 'm' for move and the number of the room that you'd\nlike to move down a tunnel towards.  Shooting is done similarly; indicate\nthat you'd like to shoot one of your magic arrows with an 's' for shoot,\nthen list a set of connected room numbers through which the deadly shaft\nshould fly!\n\nIf your path for the arrow is incorrect, however, it will flail about in\nthe room it can't understand and randomly pick a tunnel to continue\nthrough.  You might just end up shooting yourself in the foot if you're\nnot careful!  On the other hand, if you shoot the Wumpus you've WON!\n\nLet the hunt begin!\n"
+NTN                   | RTS
+
+NSSVTTTTTTTTSSSSTSTSN | Mark: 11111111 00001010 (cave_description)
+A"\nYou're in a cave with %u rooms and %u tunnels leading from each room.\nThere are %u bats and %u pits scattered throughout the cave, and your\nquiver holds %u custom super anti-evil Wumpus arrows. Good luck.\n\n"
+NTN                   | RTS
+
+#endif
diff --git a/examples/hunt-the-wumpus/wump_ui.pvvs b/examples/hunt-the-wumpus/wump_ui.pvvs
new file mode 100644 (file)
index 0000000..2b9c268
--- /dev/null
@@ -0,0 +1,434 @@
+#ifndef WUMP_UI
+#define WUMP_UI
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ This files contains user interface functions for Hunt the Wumpus.
+@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
+@ See LICENSE.txt file for copyright and license details.
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   seed_rng
+@ Description:
+@   Generate seed from keyboard input.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <logic.pvvs>
+NSSVTSSSSSTTN         | MARK: 10000011 (seed_rng)
+
+SSSTSSSSN             | PUSH 16 (loop counter)
+SSSSN                 | PUSH 0 (rng seed)
+
+NSSVTSSSSSTTSSSSSSSSN | MARK: 10000011 00000000 (seed_rng:main loop)
+@ Get character from user and print ASCII '.' as feedback.
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
+TNTS                  | GETCHAR
+SSSTSTTTSN            | PUSH ASCII '.'
+TNSS                  | PUTCHAR
+@ Left shift the seed by 4 bits.
+SSSTSSN               | PUSH 4 (shift count)
+NSTTSTTSTN            | JSR > 101101 (lshift)
+@ XOR seed with character from user.
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
+TTT                   | LOAD
+NSTTSTSTTN            | JSR > 101011 (xor)
+@ Decrement counter
+SNT                   | SWAP
+SSSTN                 | PUSH +1
+TSST                  | SUBTRACT
+@ Test for loop completion
+SNS                   | DUP
+NTSTSSSSSTTSSSSSSSTN  | BRZ > 10000011 00000001 (seed_rng:cleanup and return)
+SNT                   | SWAP
+NSNTSSSSSTTSSSSSSSSN  | JMP > 10000011 00000000 (seed_rng:main loop)
+
+@ Store seed, clean up and return.
+NSSVTSSSSSTTSSSSSSSTN | MARK: 10000011 00000001 (seed_rng:cleanup and return)
+SNN                   | DROP
+SSSSN                 | PUSH 0 (seed address)
+SNT                   | SWAP
+TTS                   | STORE
+SSSTSTSN              | PUSH ASCII '\n'
+SSSTSTSN              | PUSH ASCII '\n'
+TNSS                  | PUTCHAR
+TNSS                  | PUTCHAR
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   is_room_adjacent
+@ Description:
+@   Checks if 'room_number' is adjacent to the player's current room.
+@ Call Stack:
+@   room_number  <-- TOS
+@ Return Stack:
+@   (1 or 0) for true/false  <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSTSSTSSN         | MARK: 10100100 (is_room_adjacent)
+
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (ptr to number_of_tunnels_per_room)
+TTT                   | LOAD
+SSSTN                 | PUSH +1
+TSST                  | SUBTRACT
+
+@ TOS> tunnel_index, destination_room_num
+NSSVTSTSSTSSSSSSSSSSN | MARK: 10100100 00000000 (is_room_adjacent:main_loop)
+SSSTSN                | PUSH +2
+NSTTTSSN              | JSR > 1100 (deepdup)
+SSSTSN                | PUSH +2
+NSTTTSSN              | JSR > 1100 (deepdup)
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player_location)
+TTT                   | LOAD
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+TSST                  | SUBTRACT
+NTSTSTSSTSSSSSSSSSTN  | BRZ > 10100100 00000001 (is_room_adjacent:found_tunnel)
+SSSTN                 | PUSH +1
+TSST                  | SUBTRACT
+SNS                   | DUP
+NTTTSTSSTSSSSSSSSTSN  | BMI > 10100100 00000010 (is_room_adjacent:no_match)
+NSNTSTSSTSSSSSSSSSSN  | JMP > 10100100 00000000 (is_room_adjacent:main_loop)
+
+NSSVTSTSSTSSSSSSSSSTN | MARK: 10100100 00000001 (is_room_adjacent:found_tunnel)
+SNN                   | DROP
+SNN                   | DROP
+SSSTN                 | PUSH +1
+NTN                   | RTS
+
+NSSVTSTSSTSSSSSSSSTSN | MARK: 10100100 00000010 (is_room_adjacent:no_match)
+SNN                   | DROP
+SNN                   | DROP
+SSSSN                 | PUSH 0
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   move_player
+@ Description:
+@   Prompts the player for a room number. Moves to that room, checking the new
+@   environment and executing consequences (fell in a pit, etc) as appropriate.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stdio.pvvs>
+#include <convert.pvvs>
+#include <math.pvvs>
+#include <string.pvvs>
+NSSVTSTSSSTTN         | MARK: 10100011 (move_player)
+
+A"To which room do you wish to move?\n"
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer address)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer size)
+NSTTSSSTSN            | JSR > 100010 (get_user_string)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
+NSTTTSSSSN            | JSR > 110000 (atoi)
+SNN                   | DROP
+
+@ The desired room number is now on the TOS. Verify that it is valid.
+SNS                   | DUP
+NSTTSTSSTSSN          | JSR > 10100100 (is_room_adjacent)
+NTSTSTSSSTTSSSSSSSTN  | BRZ > 10100011 00000001 (invalid room number)
+NSNTSTSSSTTSSSSSSSSN  | JMP > 10100011 00000000 (valid room number)
+
+NSSVTSTSSSTTSSSSSSSTN | MARK: 10100011 00000001 (invalid room number)
+@ TOS> room_number
+SNN                   | DROP
+A"*Oof!* (you hit the wall)\n"
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSTTSSSSN             | JSR > 10000 (random)
+SSSTTSN               | PUSH 6 (chance)
+TSTT                  | MODULO
+NTSTSTSSSTTSSSSSSTSN  | BRZ > 10100011 00000010 (woke the wumpus)
+NTN                   | RTS
+NSSVTSTSSSTTSSSSSSTSN | MARK: 10100011 00000010 (woke the wumpus)
+A"Your colorful comments awaken the wumpus!\n"
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSTTSSSSN             | JSR > 10000 (random)
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (ptr to number of tunnels per room)
+TSTT                  | MODULO
+SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (ptr to wumpus location)
+TTT                   | LOAD
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (ptr to wumpus location)
+SNT                   | SWAP
+TTS                   | STORE
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
+TTT                   | LOAD
+NSTTSTSSSSSN          | JSR > 10100000 (room_has_wumpus)
+NTSTSTSSSTTSSSSSSTTN  | BRZ > 10100011 00000011 (wumpus did not move to player)
+NSTTTTTTTTTSSSSSSSSN  | JSR > 11111111 00000000 (wump_kill)
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NNN                   | DIE
+NSSVTSTSSSTTSSSSSSTTN | MARK: 10100011 00000011 (wumpus did not move to player)
+NTN                   | RTS
+
+NSSVTSTSSSTTSSSSSSSSN | MARK: 10100011 00000000 (valid room number)
+@ TOS> room_number
+@ Move player to new room
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
+SNT                   | SWAP
+TTS                   | STORE
+@ Check for wumpus in new player location
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
+TTT                   | LOAD
+NSTTSTSSSSSN          | JSR > 10100000 (room_has_wumpus)
+NTSTSTSSSTTSSSSSTSSN  | BRZ > 10100011 00000100 (no wumpus in new room)
+NSTTTTTTTTTSSSSSSSSN  | JSR > 11111111 00000000 (wump_kill)
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NNN                   | DIE
+NSSVTSTSSSTTSSSSSTSSN | MARK: 10100011 00000100 (no wumpus in new room)
+@ Check for pits in new player location
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
+TTT                   | LOAD
+NSTTSSSTTSTN          | JSR > 10001101 (room_has_pits)
+NTSTSTSSSTTSSSSSTSTN  | BRZ > 10100011 00000101 (no pits in new room)
+NSTTSSSSN             | JSR > 10000 (random)
+SSSTTSN               | PUSH 6 (chance)
+TSTT                  | MODULO
+NTSTSTSSSTTSSSSSTTSN  | BRZ > 10100011 00000110 (survived the pits)
+NSTTTTTTTTTSSSSSTSTN  | JSR > 11111111 00000101 (pit_kill)
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NNN                   | DIE
+NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (survived the pits)
+NSTTTTTTTTTSSSSSTTSN  | JSR > 11111111 00000110 (pit_survive)
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSSVTSTSSSTTSSSSSTSTN | MARK: 10100011 00000101 (no pits in new room)
+@ Check for bats in new player location
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
+TTT                   | LOAD
+NSTTSSSTTSSN          | JSR > 10001100 (room_has_bats)
+NTSTSTSSSTTSSSSSTTSN  | BRZ > 10100011 00000110 (no bats in new room)
+A"*flap*  *flap*  *flap*  (humongous bats pick you up and move you!)\n"
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSTTSSSSN             | JSR > 10000 (random)
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (ptr to number of tunnels per room)
+TSTT                  | MODULO
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
+TTT                   | LOAD
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+NSNTSTSSSTTSSSSSSSSN  | JMP > 10100011 00000000 (valid room number)
+NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (no bats in new room)
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   move_or_shoot
+@ Description:
+@   Parse user input, branching to the appropriate subroutine to move or shoot.
+@   This function does not perform any boundary checks/limits.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stdio.pvvs>
+#include <string.pvvs>
+NSSVTSTSSSTSN         | MARK: 10100010 (move_or_shoot)
+
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer address)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer size)
+NSTTSSSTSN            | JSR > 100010 (get_user_string)
+
+@ Examine the first character of the user input buffer for 'm' or 's'.
+@ If character is something else, prompt user to try again.
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
+TTT                   | LOAD
+SSSSTTSTTSTN          | PUSH 109 (ASCII 'm')
+TSST                  | SUBTRACT
+NTSTSTSSSTSSSSSSSSSN  | BRZ > 10100010 00000000 (move)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
+TTT                   | LOAD
+SSSSTTTSSTTN          | PUSH 115 (ASCII 's')
+TSST                  | SUBTRACT
+NTSTSTSSSTSSSSSSSSTN  | BRZ > 10100010 00000001 (shoot)
+NSTTTTTTTTTSSSSTSSSN  | JSR > 11111111 00001000 (problem_with_input)
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSNTSTSSSTSN          | JMP > 10100010 (move_or_shoot)
+
+@ User typed 'm'
+NSSVTSTSSSTSSSSSSSSSN | MARK: 10100010 00000000 (move)
+NSTTSTSSSTTN          | JSR > 10100011 (move_player)
+NTN                   | RTS
+
+@ User typed 's'
+NSSVTSTSSSTSSSSSSSSTN | MARK: 10100010 00000001 (shoot)
+@ TODO: JSR shoot
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   get_answer
+@ Description:
+@   Parse user input, returning 0 if user string started with 'n' or 1 if 'y'.
+@   This function does not perform any boundary checks/limits.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   (1 or 0 for True/False)   <--- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stdio.pvvs>
+#include <string.pvvs>
+NSSVTSSTTSSSN         | MARK: 10011000 (get_answer)
+
+@ TODO: Consider extending the GETCHAR instruction in VVS to indicate an empty
+@       buffer instead of blocking. This would allow a character by character
+@       check without printing a slew of retry messages if the buffer is
+@       non-empty.
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer address)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer size)
+NSTTSSSTSN            | JSR > 100010 (get_user_string)
+
+@ Examine the first character of the user input buffer for 'y' or 'n'.
+@ If character is something else, prompt user to try again.
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
+TTT                   | LOAD
+SSSSTTTTSSTN          | PUSH 121 (ASCII 'y')
+TSST                  | SUBTRACT
+NTSTSSTTSSSSSSSSSSSN  | BRZ > 10011000 00000000 (answer: yes)
+SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
+TTT                   | LOAD
+SSSSTTSTTTSN          | PUSH 110 (ASCII 'n')
+TSST                  | SUBTRACT
+NTSTSSTTSSSSSSSSSSTN  | BRZ > 10011000 00000001 (answer: no)
+NSTTTTTTTTTSSSSTSSSN  | JSR > 11111111 00001000 (problem_with_input)
+SSSSN                 | PUSH 0 (number of string substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSNTSSTTSSSN          | JMP > 10011000 (get_answer)
+
+@ User typed 'y'
+NSSVTSSTTSSSSSSSSSSSN | MARK: 10011000 00000000 (answer: yes)
+SSSTN                 | PUSH 1
+NTN                   | RTS
+
+@ User typed 'n'
+NSSVTSSTTSSSSSSSSSSTN | MARK: 10011000 00000001 (answer: no)
+SSSSN                 | PUSH 0
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   print_cave_description
+@ Description:
+@   Prints information about the cave (number of rooms, etc).
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stdio.pvvs>
+NSSVTSSTTSTTN         | MARK: 10011011 (print_cave_description)
+NSTTTTTTTTTSSSSTSTSN  | JSR > 11111111 00001010 (cave_description)
+SSSTSSSSSSSSSTSTN     | PUSH 0x1005 (number_of_arrows address)
+TTT                   | LOAD
+SSSTSSSSSSSSSSSTN     | PUSH 0x1001 (number_of_pits address)
+TTT                   | LOAD
+SSSTSSSSSSSSSSTSN     | PUSH 0x1002 (number_of_bats address)
+TTT                   | LOAD
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_tunnels address)
+TTT                   | LOAD
+SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (number_of_rooms address)
+TTT                   | LOAD
+SSSTSTN               | PUSH 5 (number of substitions)
+NSTTSSSN              | JSR > 1000 (printf)
+NTN                   | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   print_room_stats
+@ Description:
+@   Prints information about current room and hints about nearby rooms.
+@ Call Stack:
+@   <empty>
+@ Return Stack:
+@   <empty>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <wump_game.pvvs>
+#include <stdio.pvvs>
+#include <stack.pvvs>
+NSSVTSTSSSSTN         | MARK: 10100001 (print_room_stats)
+
+@ Print location and arrow quantity remaining.
+A"You are in room %u of the cave and have %u arrows remaining.\n"
+SSSTSSSSSSSSSTSTN     | PUSH 0x1005 (number_of_arrows address)
+TTT                   | LOAD
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (player_location address)
+TTT                   | LOAD
+SSSTSN                | PUSH 2 (number of substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+
+@ Print if bats/pits/wumpus nearby.
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (player_location address)
+TTT                   | LOAD
+SNS                   | DUP
+NSTTSSTTTSSN          | JSR > 10011100 (are_bats_near)
+NTSTSTSSSSTSSSSSSSSN  | BRZ > 10100001 00000000 (no_bats)
+A"*rustle* (Bats must be nearby.)\n"
+SSSSN                 | PUSH 0 (number of substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSSVTSTSSSSTSSSSSSSSN | MARK: 10100001 00000000 (no_bats)
+SNS                   | DUP
+NSTTSSTTTSTN          | JSR > 10011101 (are_pits_near)
+NTSTSTSSSSTSSSSSSSTN  | BRZ > 10100001 00000001 (no_pits)
+A"*whoosh* (You feel a draft from nearby pits.)\n"
+SSSSN                 | PUSH 0 (number of substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSSVTSTSSSSTSSSSSSSTN | MARK: 10100001 00000001 (no_pits)
+NSTTSSTTTTSN          | JSR > 10011110 (is_wumpus_near)
+NTSTSTSSSSTSSSSSSTSN  | BRZ > 10100001 00000010 (no_wumpus)
+A"*sniff* (You smell the evil Wumpus nearby!)\n"
+SSSSN                 | PUSH 0 (number of substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+NSSVTSTSSSSTSSSSSSTSN | MARK: 10100001 00000010 (no_wumpus)
+
+@ Print a list of nearby rooms.
+A"This room contains tunnels to the following rooms:"
+SSSSN                 | PUSH 0 (number of substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (player_location address)
+TTT                   | LOAD
+SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
+TTT                   | LOAD
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+@ Print one room on each pass through this loop.
+@ TOS> tunnel_index, room_number
+NSSVTSTSSSSTSSSSSSTTN | MARK: 10100001 00000011 (print_room_list_loop)
+A" %u"
+SSSTSTN               | PUSH 5
+NSTTTSSN              | JSR > 1100 (deepdup)
+SSSTTTN               | PUSH 7
+NSTTTSSN              | JSR > 1100 (deepdup)
+NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
+SSSTN                 | PUSH 1 (number of substitutions)
+NSTTSSSN              | JSR > 1000 (printf)
+@ Test for end of loop
+SNS                   | DUP
+NTSTSTSSSSTSSSSSTSSN  | BRZ > 10100001 00000100 (print_room_list_loop_end)
+SSSTN                 | PUSH 1
+TSST                  | SUBTRACT
+NSNTSTSSSSTSSSSSSTTN  | JMP > 10100001 00000011 (print_room_list_loop)
+@ Clean up and return.
+NSSVTSTSSSSTSSSSSTSSN | MARK: 10100001 00000100 (print_room_list_loop_end)
+SSSTSTSN              | PUSH 10 (ASCII '\n')
+TNSS                  | PUTCHAR
+SNN                   | DROP
+SNN                   | DROP
+NTN                   | RTS
+
+#endif
diff --git a/examples/wump/LICENSE.txt b/examples/wump/LICENSE.txt
deleted file mode 100644 (file)
index d6b0400..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT/X Consortium License
-
-© 2018 Aaron Taylor <ataylor at subgeniuskitty dot com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/examples/wump/Makefile b/examples/wump/Makefile
deleted file mode 100644 (file)
index 1fec45e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
-# See LICENSE.txt file for copyright and license details.
-
-include ../config.mk
-
-all: wump
-
-wump:
-       $(CPP) $(CPP_FLAGS) -o temp.pvvs wump.pvvs
-       $(VVS_COMPILER) -i temp.pvvs -o wump.vvs
-       @rm -f temp.pvvs
-
-run: wump
-       $(VVS_INTERPRETER) -i wump.vvs
-
-clean:
-       @rm -f wump.vvs temp.pvvs
diff --git a/examples/wump/README.txt b/examples/wump/README.txt
deleted file mode 100644 (file)
index c001660..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-TODO LIST:
-
-  - Update README
-  - Write functions for moving wumpus, player movement, player shooting, parsing player commands.
-  - Write a function 'get highest tunnel index' for use in the 'check for pits/bats/wumpus' functions.
-  - Double-check per-file TODOs for critical tasks.
-  - Double-check #includes for all subroutines.
-  - Re-order subroutines in all files for readability.
-
-================================================================================
-
-# Subroutine Labels #
-
-NSSVTTTTTTTTSSSSSSSSN | Mark: 11111111 00000000 (wump_kill)
-NSSVTTTTTTTTSSSSSSSTN | Mark: 11111111 00000001 (kill_wump)
-NSSVTTTTTTTTSSSSSSTSN | Mark: 11111111 00000010 (no_arrows)
-NSSVTTTTTTTTSSSSSSTTN | Mark: 11111111 00000011 (shoot_self)
-NSSVTTTTTTTTSSSSSTSSN | Mark: 11111111 00000100 (jump)
-NSSVTTTTTTTTSSSSSTSTN | Mark: 11111111 00000101 (pit_kill)
-NSSVTTTTTTTTSSSSSTTSN | Mark: 11111111 00000110 (pit_survive)
-NSSVTTTTTTTTSSSSSTTTN | Mark: 11111111 00000111 (please_seed_rng)
-NSSVTTTTTTTTSSSSTSSSN | Mark: 11111111 00001000 (problem_with_yes_no_answer)
-NSSVTTTTTTTTSSSSTSSTN | Mark: 11111111 00001001 (instructions)
-NSSVTTTTTTTTSSSSTSTSN | Mark: 11111111 00001010 (cave_description)
-
-NSSVTSSSSSSSN         | MARK: 10000000 (wump)
-NSSVTSSSSSSTN         | MARK: 10000001 (set_config_values)
-NSSVTSSSSSTSN         | MARK: 10000010 (wump_init)
-NSSVTSSSSSTTN         | MARK: 10000011 (seed_rng)
-NSSVTSSSSTSSN         | MARK: 10000100 (build_cave)
-NSSVTSSSSTSTN         | MARK: 10000101 (populate_cave)
-NSSVTSSSSTTSN         | MARK: 10000110 (clear_cave_data)
-NSSVTSSSSTTTN         | MARK: 10000111 (generate_cave_hop_length)
-NSSVTSSSTSSSN         | MARK: 10001000 (get_tunnel_destination)
-NSSVTSSSTSSTN         | MARK: 10001001 (set_tunnel_destination)
-NSSVTSSSTSTSN         | MARK: 10001010 (get_random_room)
-NSSVTSSSTSTTN         | MARK: 10001011 (get_room_struct_size)
-NSSVTSSSTTSSN         | MARK: 10001100 (room_has_bats)
-NSSVTSSSTTSTN         | MARK: 10001101 (room_has_pits)
-NSSVTSSSTTTSN         | MARK: 10001110 (build_circular_tunnels)
-NSSVTSSTSSSSN         | MARK: 10010000 (set_bats)
-NSSVTSSTSSSTN         | MARK: 10010001 (set_pits)
-NSSVTSSTSSTSN         | MARK: 10010010 (reset_cave_population)
-NSSVTSSTSSTTN         | MARK: 10010011 (populate_bats)
-NSSVTSSTSTSSN         | MARK: 10010100 (populate_pits)
-NSSVTSSTSTSTN         | MARK: 10010101 (place_player)
-NSSVTSSTSTTSN         | MARK: 10010110 (build_random_tunnels)
-NSSVTSSTSTTTN         | MARK: 10010111 (get_next_tunnel_slot)
-NSSVTSSTTSSSN         | MARK: 10011000 (get_answer)
-!!!NSSVTSSTTSSTN         | MARK: 10011001 (get_line)
-NSSVTSSTTSTSN         | MARK: 10011010 (wump_loop)
-NSSVTSSTTSTTN         | MARK: 10011011 (print_cave_description)
-NSSVTSSTTTSSN         | MARK: 10011100 (are_bats_near)
-NSSVTSSTTTSTN         | MARK: 10011101 (are_pits_near)
-NSSVTSSTTTTSN         | MARK: 10011110 (is_wumpus_near)
-NSSVTSSTTTTTN         | MARK: 10011111 (is_wumpus_very_near)
-NSSVTSTSSSSSN         | MARK: 10100000 (room_has_wumpus)
-NSSVTSTSSSSTN         | MARK: 10100001 (print_room_stats)
-
-================================================================================
-
-# Heap Assignments #
-
-GAME_DATA_BASE = 0x1000
-
-GAME_DATA_BASE     = Number of rooms in cave
-GAME_DATA_BASE+001 = Number of pits
-GAME_DATA_BASE+002 = Number of bats
-GAME_DATA_BASE+003 = Number of links per room
-GAME_DATA_BASE+004 = Maximum arrow flight distance
-GAME_DATA_BASE+005 = Number of arrows
-GAME_DATA_BASE+006 = Player location
-GAME_DATA_BASE+007 = Wumpus location
-
-ROOM_DATA_BASE = 0x2000
-    Each room is structured as:
-        BASE+0 = bool:contains_pit? (valid options are 0 or 1)
-        BASE+1 = bool:contains_bat? (valid options are 0 or 1)
-        BASE+2 = int:connected room (-1 indicates no tunnel, 0 or greater is the index of the destination room)
-        ...
-        BASE+n = int:connected room (last: see 'links per room')
-
-USER_INPUT_BUFFER = 0x3000
diff --git a/examples/wump/wump.pvvs b/examples/wump/wump.pvvs
deleted file mode 100644 (file)
index 01284a9..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Hunt the Wumpus
-@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
-@ See LICENSE.txt file for copyright and license details.
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-
-NSNTSSSSSSSN          | JMP > 10000000 (wump)
-
-#include <wump_init.pvvs>
-#include <wump_ui.pvvs>
-#include <wump_strings.pvvs>
-#include <stdio.pvvs>
-
-NSSVTSSSSSSSN         | MARK: 10000000 (wump)
-
-@ Initialization (build the cave, etc).
-NSTTSSSSSTSN          | JSR > 10000010 (wump_init)
-
-@ Does the user need instructions?
-A"Instructions? (y/n)\n"
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSTTSSTTSSSN          | JSR > 10011000 (get_answer)
-NTSTSSSSSSSSSSSSSSSN  | BRZ > 10000000 00000000 (skip_instructions)
-NSTTTTTTTTTSSSSTSSTN  | JSR > 11111111 00001001 (instructions)
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSSVTSSSSSSSSSSSSSSSN | MARK: 10000000 00000000 (skip_instructions)
-
-@ Print a description of the cave.
-NSTTSSTTSTTN          | JSR > 10011011 (print_cave_description)
-
-@ Main game loop
-NSSVTSSTTSTSN         | MARK: 10011010 (wump_loop)
-NSTTSTSSSSTN          | JSR > 10100001 (print_room_stats)
-A"Move or shoot? (m/s)\n"
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSTTSTSSSTSN          | JSR > 10100010 (move_or_shoot)
-NSNTSSTTSTSN          | JMP > 10011010 (wump_loop)
diff --git a/examples/wump/wump_conf.pvvs b/examples/wump/wump_conf.pvvs
deleted file mode 100644 (file)
index d4bba75..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef WUMP_CONF
-#define WUMP_CONF
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
-@ See LICENSE.txt file for copyright and license details.
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ All user configurable options are contained in this file.
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   set_config_values
-@ Description:
-@   Place user-configurable values for Hunt the Wumpus on the heap.
-@   The program assumes the values are sane. (e.g. #pits < #rooms, etc)
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <heap.pvvs>
-NSSVTSSSSSSTN         | MARK: 10000001 (set_config_values)
-
-@ Number of arrows
-SSSTSTN               | PUSH +5
-
-@ Maximum arrow travel distance
-SSSTSTN               | PUSH +5
-
-@ Maximum links per room (must be >2)
-SSSTTN                | PUSH +3
-
-@ Number of bats in cave
-SSSTSN                | PUSH +2
-
-@ Number of pits in cave
-SSSTSN                | PUSH +2
-
-@ Number of rooms in cave
-SSSTSTSSN             | PUSH +20
-
-@ Push config values to heap and return.
-SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE address)
-SSSTSTN               | PUSH +5 (word count)
-NSTTTTTTN             | JSR > 11111 (spew)
-NTN                   | RTS
-
-#endif
diff --git a/examples/wump/wump_game.pvvs b/examples/wump/wump_game.pvvs
deleted file mode 100644 (file)
index 7d85f8d..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-#ifndef WUMP_GAME
-#define WUMP_GAME
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
-@ See LICENSE.txt file for copyright and license details.
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   get_tunnel_destination
-@ Description:
-@   Returns the room number corresponding to the destination of a tunnel
-@   specified by room and slot.
-@ Call Stack:
-@   slot
-@   room_number  <-- TOS
-@ Return Stack:
-@   dst_room_number  <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSSTSSSN         | MARK: 10001000 (get_tunnel_destination)
-@ The pointer we seek is:
-@ (room_number * room_struct_size) + 2 + slot + ROOM_DATA_BASE
-@ Where the '+2' accounts for the pit and bat booleans.
-NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
-TSSN                  | MULTIPLY
-SSSTSN                | PUSH +2
-TSSS                  | ADD
-TSSS                  | ADD
-SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (ROOM_DATA_BASE address)
-TSSS                  | ADD
-TTT                   | LOAD
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   get_room_struct_size
-@ Description:
-@   Returns the size in words of the data structure for a single room.
-@   For example, with 3 links plus bat and pit booleans, the size is 5 words.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   size   <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSSTSTTN         | MARK: 10001011 (get_room_struct_size)
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (GAME_DATA_BASE+3 = links_per_room address)
-TTT                   | LOAD
-SSSTSN                | PUSH +2
-TSSS                  | ADD
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   room_has_bats
-@ Description:
-@   Check if room_number contains bats.
-@   Returns 1 or 0 representing true or false.
-@ Call Stack:
-@   room_number   <-- TOS
-@ Return Stack:
-@   1 or 0   <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSSTTSSN         | MARK: 10001100 (room_has_bats)
-@ We seek the pointer:
-@   (room_number * room_struct_size) + 1 + ROOM_DATA_BASE
-@ where '+1' accounts for the offset of the bat boolean in the desired room.
-NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
-TSSN                  | MULTIPLY
-SSSTN                 | PUSH +1
-TSSS                  | ADD
-SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (GAME_DATA_BASE address)
-TSSS                  | ADD
-TTT                   | LOAD
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   room_has_pits
-@ Description:
-@   Check if room_number contains pits.
-@   Returns 1 or 0 representing true or false.
-@ Call Stack:
-@   room_number   <-- TOS
-@ Return Stack:
-@   1 or 0   <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSSTTSTN         | MARK: 10001101 (room_has_pits)
-@ We seek the pointer:
-@   (room_number * room_struct_size) + 0 + ROOM_DATA_BASE
-@ where '+0' accounts for the offset of the pit boolean in the desired room.
-NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
-TSSN                  | MULTIPLY
-SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (GAME_DATA_BASE address)
-TSSS                  | ADD
-TTT                   | LOAD
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   room_has_wumpus
-@ Description:
-@   Check if room contains wumpus.
-@   Returns 1 or 0 representing true or false.
-@ Call Stack:
-@   room_number   <-- TOS
-@ Return Stack:
-@   1 or 0   <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSTSSSSSN         | MARK: 10100000 (room_has_wumpus)
-SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (wumpus_location address)
-TTT                   | LOAD
-TSST                  | SUBTRACT
-NTSTSTSSSSSSSSSSSSSN  | BRZ > 10100000 00000000 (room_has_wumpus:true)
-SSSSN                 | PUSH 0 (false)
-NTN                   | RTS
-NSSVTSTSSSSSSSSSSSSSN | MARK: 10100000 00000000 (room_has_wumpus:true)
-SSSTN                 | PUSH 1 (true)
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   are_bats_near
-@ Description:
-@   Given a room number, checks rooms within one hop for bats.
-@   Returns 1 if bats are present or 0 if no bats.
-@ Call Stack:
-@   room_number  <-- TOS
-@ Return Stack:
-@   1 or 0  <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stack.pvvs>
-NSSVTSSTTTSSN         | MARK: 10011100 (are_bats_near)
-
-@ Prepare the stack by loading the number of links per room and decrementing.
-@ We will loop until this reaches 0 or we find bats.
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-
-@ Check one nearby room on each pass through this loop.
-@ TOS> tunnel_index, room_number
-NSSVTSSTTTSSSSSSSSSSN | MARK: 10011100 00000000 (are_bats_near:loop)
-SNS                   | DUP
-SSSTTN                | PUSH 3
-NSTTTSSN              | JSR > 1100 (deepdup)
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-NSTTSSSTTSSN          | JSR > 10001100 (room_has_bats)
-NTSTSSTTTSSSSSSSSSTN  | BRZ > 10011100 00000001 (no_bats_in_this_room)
-@ Found bats. Clean up and return.
-SNN                   | DROP
-SNN                   | DROP
-SSSTN                 | PUSH 1
-NTN                   | RTS
-NSSVTSSTTTSSSSSSSSSTN | MARK: 10011100 00000001 (no_bats_in_this_room)
-@ Test for end of loop.
-SNS                   | DUP
-NTSTSSTTTSSSSSSSSTSN  | BRZ > 10011100 00000010 (are_bats_near:loop_end)
-@ No bats found yet, but still need to check some rooms.
-@ Decrement tunnel index and loop again.
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-NSNTSSTTTSSSSSSSSSSN  | JMP > 10011100 00000000 (are_bats_near:loop)
-@ No bats found in nearby rooms. Clean up and return.
-NSSVTSSTTTSSSSSSSSTSN | MARK: 10011100 00000010 (are_bats_near:loop_end)
-SNN                   | DROP
-SNN                   | DROP
-SSSSN                 | PUSH 0
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   are_pits_near
-@ Description:
-@   Given a room number, checks rooms within one hop for pits.
-@   Returns 1 if pits are present or 0 if no pits.
-@ Call Stack:
-@   room_number  <-- TOS
-@ Return Stack:
-@   1 or 0  <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stack.pvvs>
-NSSVTSSTTTSTN         | MARK: 10011101 (are_pits_near)
-
-@ Prepare the stack by loading the number of links per room and decrementing.
-@ We will loop until this reaches 0 or we find pits.
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-
-@ Check one nearby room on each pass through this loop.
-@ TOS> tunnel_index, room_number
-NSSVTSSTTTSTSSSSSSSSN | MARK: 10011101 00000000 (are_pits_near:loop)
-SNS                   | DUP
-SSSTTN                | PUSH 3
-NSTTTSSN              | JSR > 1100 (deepdup)
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-NSTTSSSTTSTN          | JSR > 10001101 (room_has_pits)
-NTSTSSTTTSTSSSSSSSTN  | BRZ > 10011101 00000001 (no_pits_in_this_room)
-@ Found pits. Clean up and return.
-SNN                   | DROP
-SNN                   | DROP
-SSSTN                 | PUSH 1
-NTN                   | RTS
-NSSVTSSTTTSTSSSSSSSTN | MARK: 10011101 00000001 (no_pits_in_this_room)
-@ Test for end of loop.
-SNS                   | DUP
-NTSTSSTTTSTSSSSSSTSN  | BRZ > 10011101 00000010 (are_pits_near:loop_end)
-@ No pits found yet, but still need to check some rooms.
-@ Decrement tunnel index and loop again.
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-NSNTSSTTTSTSSSSSSSSN  | JMP > 10011101 00000000 (are_pits_near:loop)
-@ No pits found in nearby rooms. Clean up and return.
-NSSVTSSTTTSTSSSSSSTSN | MARK: 10011101 00000010 (are_pits_near:loop_end)
-SNN                   | DROP
-SNN                   | DROP
-SSSSN                 | PUSH 0
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   is_wumpus_very_near
-@ Description:
-@   Given a room number, checks rooms within one hop for the wumpus.
-@   Returns 1 if wumpus is present, otherwise 0.
-@ Call Stack:
-@   room_number  <-- TOS
-@ Return Stack:
-@   1 or 0  <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stack.pvvs>
-NSSVTSSTTTTTN         | MARK: 10011111 (is_wumpus_very_near)
-
-@ Prepare the stack by loading the number of links per room and decrementing.
-@ We will loop until this reaches 0 or we find the wumpus.
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-
-@ Check one nearby room on each pass through this loop.
-@ TOS> tunnel_index, room_number
-NSSVTSSTTTTTSSSSSSSSN | MARK: 10011111 00000000 (is_wumpus_very_near:loop)
-SNS                   | DUP
-SSSTTN                | PUSH 3
-NSTTTSSN              | JSR > 1100 (deepdup)
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-NSTTSTSSSSSN          | JSR > 10100000 (room_has_wumpus)
-NTSTSSTTTTTSSSSSSSTN  | BRZ > 10011111 00000001 (no_wumpus_in_this_room)
-@ Found wumpus. Clean up and return.
-SNN                   | DROP
-SNN                   | DROP
-SSSTN                 | PUSH 1
-NTN                   | RTS
-NSSVTSSTTTTTSSSSSSSTN | MARK: 10011111 00000001 (no_wumpus_in_this_room)
-@ Test for end of loop.
-SNS                   | DUP
-NTSTSSTTTTTSSSSSSTSN  | BRZ > 10011111 00000010 (is_wumpus_very_near:loop_end)
-@ No wumpus found yet, but still need to check some rooms.
-@ Decrement tunnel index and loop again.
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-NSNTSSTTTTTSSSSSSSSN  | JMP > 10011111 00000000 (is_wumpus_very_near:loop)
-@ No wumpus found in nearby rooms. Clean up and return.
-NSSVTSSTTTTTSSSSSSTSN | MARK: 10011111 00000010 (is_wumpus_very_near:loop_end)
-SNN                   | DROP
-SNN                   | DROP
-SSSSN                 | PUSH 0
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   is_wumpus_near
-@ Description:
-@   Given a room number, checks rooms within two hops for the wumpus.
-@   Returns 1 if wumpus is present, otherwise 0.
-@ Call Stack:
-@   room_number  <-- TOS
-@ Return Stack:
-@   1 or 0  <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stack.pvvs>
-NSSVTSSTTTTSN         | MARK: 10011110 (is_wumpus_near)
-
-@ Prepare the stack by loading the number of links per room and decrementing.
-@ We will loop until this reaches 0 or we find the wumpus.
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-
-@ Check one nearby room and its connecting rooms on each pass through this loop.
-@ TOS> tunnel_index, room_number
-NSSVTSSTTTTSSSSSSSSSN | MARK: 10011110 00000000 (is_wumpus_near:loop)
-SNS                   | DUP
-SSSTTN                | PUSH 3
-NSTTTSSN              | JSR > 1100 (deepdup)
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-@ TOS> tunnel_endpoint, tunnel_index, room_number
-SNS                   | DUP
-NSTTSTSSSSSN          | JSR > 10100000 (room_has_wumpus)
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-NTSTSSTTTTSSSSSSSTTN  | BRZ > 10011110 00000011 (found_wumpus_one_hop)
-NSTTSSTTTTTN          | JSR > 10011111 (is_wumpus_very_near)
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-NTSTSSTTTTSSSSSSTSSN  | BRZ > 10011110 00000100 (found_wumpus_two_hops)
-@ Test for end of loop.
-SNS                   | DUP
-NTSTSSTTTTSSSSSSSTSN  | BRZ > 10011110 00000010 (is_wumpus_near:loop_end)
-@ No wumpus found yet, but still need to check some rooms.
-@ Decrement tunnel index and loop again.
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-NSNTSSTTTTSSSSSSSSSN  | JMP > 10011110 00000000 (is_wumpus_near:loop)
-
-@ No wumpus found in nearby rooms. Clean up and return.
-NSSVTSSTTTTSSSSSSSTSN | MARK: 10011110 00000010 (is_wumpus_near:loop_end)
-SNN                   | DROP
-SNN                   | DROP
-SSSSN                 | PUSH 0
-NTN                   | RTS
-
-@ Found wumpus. Clean up and return.
-NSSVTSSTTTTSSSSSSSTTN | MARK: 10011110 00000011 (found_wumpus_one_hop)
-SNN                   | DROP
-NSSVTSSTTTTSSSSSSTSSN | MARK: 10011110 00000100 (found_wumpus_two_hops)
-SNN                   | DROP
-SNN                   | DROP
-SSSTN                 | PUSH 1
-NTN                   | RTS
-
-#endif
diff --git a/examples/wump/wump_init.pvvs b/examples/wump/wump_init.pvvs
deleted file mode 100644 (file)
index 9d7543d..0000000
+++ /dev/null
@@ -1,757 +0,0 @@
-#ifndef WUMP_INIT
-#define WUMP_INIT
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
-@ See LICENSE.txt file for copyright and license details.
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   wump_init
-@ Description:
-@   Master function that creates a new cave, links the rooms, and populates them
-@   according to the options set by the user in wump_conf.pvvs.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stdio.pvvs>
-#include <wump_conf.pvvs>
-#include <wump_strings.pvvs>
-#include <wump_ui.pvvs>
-NSSVTSSSSSTSN         | MARK: 10000010 (wump_init)
-
-@ Load the user-configurable options.
-NSTTSSSSSSTN          | JSR > 10000001 (set_config_values)
-
-@ Seed the RNG.
-NSTTTTTTTTTSSSSSTTTN  | JSR > 11111111 00000111 (please_seed_rng)
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSTTSSSSSTTN          | JSR > 10000011 (seed_rng)
-
-@ Build the cave.
-NSTTSSSSTSSN          | JSR > 10000100 (build_cave)
-
-@ Populate the cave.
-NSTTSSSSTSTN          | JSR > 10000101 (populate_cave)
-
-@ Initialization is complete.
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   build_circular_tunnels
-@ Description:
-@   Builds a set of tunnels that ensures every room in the cave is connected.
-@   Assumes that tunnel slots 0 and 1 are set to the value -1 (unconnected).
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stack.pvvs>
-#include <wump_game.pvvs>
-NSSVTSSSTTTSN         | MARK: 10001110 (build_circular_tunnels)
-
-@ Prepare TOS> current_room, hop_length
-NSTTSSSSTTTN          | JSR > 10000111 (generate_cave_hop_length)
-SSSSN                 | PUSH 0 (current room)
-
-@ Have we already built a tunnel from this room?
-@ If so, tunnel slot 0 will not be -1.
-NSSVTSSSTTTSSSSSSSSSN | MARK: 10001110 00000000 (tunnel_loop)
-SNS                   | DUP
-SSSSN                 | PUSH 0 (first tunnel slot)
-SNT                   | SWAP
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-NTTTSSSTTTSSSSSSSTSN  | BMI > 10001110 00000010
-NSNTSSSTTTSSSSSSSSTN  | JMP > 10001110 00000001 (loop_complete)
-NSSVTSSSTTTSSSSSSSTSN | MARK: 10001110 00000010
-@ No tunnel yet, so start building a tunnel.
-@ TOS> current_room, hop_length
-SNS                   | DUP
-SNS                   | DUP
-SSSTSSN               | PUSH 4
-NSTTTSSN              | JSR > 1100 (deepdup)
-TSSS                  | ADD
-SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
-TTT                   | LOAD
-TSTT                  | MODULO
-SNT                   | SWAP
-SSSSN                 | PUSH 0 (slot number)
-SNT                   | SWAP
-NSTTSSSTSSTN          | JSR > 10001001 (set_tunnel_destination)
-@ One direction of the tunnel is built. Now build the other direction.
-SNS                   | DUP
-SSSSN                 | PUSH 0 (slot number)
-SNT                   | SWAP
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-SNT                   | SWAP
-SSSTSN                | PUSH 2
-NSTTTSSN              | JSR > 1100 (deepdup)
-SSSTN                 | PUSH 1
-SNT                   | SWAP
-NSTTSSSTSSTN          | JSR > 10001001 (set_tunnel_destination)
-@ Loop again to build the next tunnel.
-NSNTSSSTTTSSSSSSSSSN  | JMP > 10001110 00000000 (tunnel_loop)
-
-@ Clean up and return
-NSSVTSSSTTTSSSSSSSSTN | MARK: 10001110 00000001 (loop_complete)
-SNN                   | DROP
-SNN                   | DROP
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   get_next_tunnel_slot
-@ Description:
-@   Returns the index of next available tunnel slot for room_num, or -1 if full.
-@ Call Stack:
-@   room_num  <-- TOS
-@ Return Stack:
-@   tunnel_index  <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <wump_game.pvvs>
-NSSVTSSTSTTTN         | MARK: 10010111 (get_next_tunnel_slot)
-
-@ Build the pointer: (room_num * size_of_room_struct) + 2 + ROOM_DATA_BASE
-@ Where the '+2' skips over the 'pits' and 'bats' booleans for this room.
-NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
-TSSN                  | MULTIPLY
-SSSTSN                | PUSH 2
-TSSS                  | ADD
-SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (ROOM_DATA_BASE address)
-TSSS                  | ADD
-
-@ Save a copy of this pointer for later use when recovering the tunnel index.
-SNS                   | DUP
-
-@ Push a loop counter onto the stack.
-SSSSN                 | PUSH 0 (counter)
-SNT                   | SWAP
-
-@ Main loop - Search for an available tunnel slot.
-@ TOS> ptr_to_tunnel_slot, loop_counter, ptr_to_first_tunnel_slot
-NSSVTSSTSTTTSSSSSSSSN | MARK: 10010111 00000000 (main_loop)
-SNS                   | DUP
-TTT                   | LOAD
-NTTTSSTSTTTSSSSSSSTN  | BMI > 10010111 00000001 (found_open_slot)
-@ No match.
-@ Increment the pointer.
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-@ Increment the loop counter.
-SNT                   | SWAP
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-@ See if we have run out of possible tunnel slots.
-SNS                   | DUP
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (GAME_DATA_BASE+3 = links_per_room address)
-TTT                   | LOAD
-TSST                  | SUBTRACT
-NTSTSSTSTTTSSSSSSTSN  | BRZ > 10010111 00000010 (no_open_slots)
-@ There are still more slots to check. Prepare to loop again.
-SNT                   | SWAP
-NSNTSSTSTTTSSSSSSSSN  | JMP > 10010111 00000000 (main_loop)
-
-@ No available tunnel slots for this room.
-NSSVTSSTSTTTSSSSSSTSN | MARK: 10010111 00000010 (no_open_slots)
-SNN                   | DROP
-SNN                   | DROP
-SNN                   | DROP
-SSTTN                 | PUSH -1
-NTN                   | RTS
-
-@ Found an open tunnel slot.
-NSSVTSSTSTTTSSSSSSSTN | MARK: 10010111 00000001 (found_open_slot)
-@ Drop the loop counter.
-SNT                   | SWAP
-SNN                   | DROP
-@ Recover the tunnel slot index from the tunnel slot pointer.
-SNT                   | SWAP
-TSST                  | SUBTRACT
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   build_random_tunnels
-@ Description:
-@   Randomly builds tunnels between rooms until all tunnels slots are used.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <heap.pvvs>
-#include <math.pvvs>
-#include <stack.pvvs>
-NSSVTSSTSTTSN         | MARK: 10010110 (build_random_tunnels)
-
-@ Build a temporary data structure in the buffer residing at 0x3000.
-@
-@ 0x3000 contains the number of elements in an array that starts at 0x3001.
-@ Each array element is one word long and contains the index of a room
-@ with open tunnel slots.
-@
-@ This init code is here rather than a subroutine since the structure it builds
-@ is private to this function.
-@ Before looping, push the number of elements in the array (=num_rooms).
-@ Keep a copy of this number to use as a loop counter.
-SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE = num_rooms address)
-TTT                   | LOAD
-SNS                   | DUP
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-SNT                   | SWAP
-TTS                   | STORE
-@ Init loop - Populates the 'rooms with available tunnel slots' array.
-@ TOS> loop_counter
-NSSVTSSTSTTSSSSSSSTSN | MARK: 10010110 00000010 (init_loop)
-@ Populate one of the array entries.
-SNS                   | DUP
-SNS                   | DUP
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TSSS                  | ADD
-SNT                   | SWAP
-SSSTN                 | PUSH +1
-TSST                  | SUBTRACT
-TTS                   | STORE
-@ Decrement the loop counter and test for end of loop.
-SSSTN                 | PUSH +1
-TSST                  | SUBTRACT
-SNS                   | DUP
-NTSTSSTSTTSSSSSSSTTN  | BRZ > 10010110 00000011 (init_loop_end)
-NSNTSSTSTTSSSSSSSTSN  | JMP > 10010110 00000010 (init_loop)
-NSSVTSSTSTTSSSSSSSTTN | MARK: 10010110 00000011 (init_loop_end)
-SNN                   | DROP
-NSNTSSTSTTSSSSSSSSTN  | JMP > 10010110 00000001 (main_loop)
-
-@@@@@ INIT IS COMPLETE - STACK IS EMPTY @@@@@
-
-@ Build one random tunnel connection per pass through this loop.
-NSSVTSSTSTTSSSSSSSSTN | MARK: 10010110 00000001 (main_loop)
-@ Use 'random_number mod number_of_array_entries' to select a starting room.
-NSTTSSSSN             | JSR > 10000 (random)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TTT                   | LOAD
-TSTT                  | MODULO
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-SNS                   | DUP
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TSSS                  | ADD
-TTT                   | LOAD
-@ TOS> start_room_num, start_array_index
-@ Now we randomly select a room for the endpoint.
-NSSVTSSTSTTSSSSSSTSSN | MARK: 10010110 00000100 (select_random_dst_room)
-NSTTSSSSN             | JSR > 10000 (random)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TTT                   | LOAD
-TSTT                  | MODULO
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-SNS                   | DUP
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TSSS                  | ADD
-TTT                   | LOAD
-@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
-@ Verify the endpoint room is different from the startpoint room.
-SNS                   | DUP
-SSSTSSN               | PUSH 4
-NSTTTSSN              | JSR > 1100 (deepdup)
-TSST                  | SUBTRACT
-NTSTSSTSTTSSSSSSTSTN  | BRZ > 10010110 00000101 (rooms_matched)
-NSNTSSTSTTSSSSSSTTSN  | JMP > 10010110 00000110 (connect_rooms)
-@ The rooms matched. Drop the selected destination room and try again.
-NSSVTSSTSTTSSSSSSTSTN | MARK: 10010110 00000101 (rooms_matched)
-SNN                   | DROP
-SNN                   | DROP
-NSNTSSTSTTSSSSSSTSSN  | JMP > 10010110 00000100 (select_random_dst_room)
-@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
-@ The rooms are different. Time to build a connection between them.
-NSSVTSSTSTTSSSSSSTTSN | MARK: 10010110 00000110 (connect_rooms)
-@ First build a one-way tunnel.
-SSSTTN                | PUSH 3
-NSTTTSSN              | JSR > 1100 (deepdup)
-SSSTSN                | PUSH 2
-NSTTTSSN              | JSR > 1100 (deepdup)
-SNS                   | DUP
-NSTTSSTSTTTN          | JSR > 10010111 (get_next_tunnel_slot)
-SNT                   | SWAP
-NSTTSSSTSSTN          | JSR > 10001001 (set_tunnel_destination)
-@ Then make it a two-way tunnel.
-SNS                   | DUP
-SSSTSSN               | PUSH 4
-NSTTTSSN              | JSR > 1100 (deepdup)
-SNS                   | DUP
-NSTTSSTSTTTN          | JSR > 10010111 (get_next_tunnel_slot)
-SNT                   | SWAP
-NSTTSSSTSSTN          | JSR > 10001001 (set_tunnel_destination)
-@ TOS> end_room_num, end_array_index, start_room_num, start_array_index
-@ If that was the last tunnel slot in either room, remove it
-@ from the 'rooms_with_available_tunnel_slots' array.
-NSTTSSTSTTTN          | JSR > 10010111 (get_next_tunnel_slot)
-NTTTSSTSTTSSSSSSTTTN  | BMI > 10010110 00000111 (remove_empty_room_1)
-SNN                   | DROP
-NSNTSSTSTTSSSSSTSSSN  | JMP > 10010110 00001000 (check_second_room)
-NSSVTSSTSTTSSSSSSTTTN | MARK: 10010110 00000111 (remove_empty_room_1)
-SNS                   | DUP
-NSTTSSTSTTSSSSSTTSSN  | JSR > 10010110 00001100 (remove_element_from_array)
-SSSTTN                | PUSH 3
-NSTTTSSN              | JSR > 1100 (deepdup)
-TSST                  | SUBTRACT
-NTTTSSTSTTSSSSSTTSTN  | BMI > 10010110 00001101 (update_second_room_index)
-NSNTSSTSTTSSSSSTSSSN  | JMP > 10010110 00001000 (check_second_room)
-NSSVTSSTSTTSSSSSTTSTN | MARK: 10010110 00001101 (update_second_room_index)
-SNT                   | SWAP
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-SNT                   | SWAP
-NSSVTSSTSTTSSSSSTSSSN | MARK: 10010110 00001000 (check_second_room)
-NSTTSSTSTTTN          | JSR > 10010111 (get_next_tunnel_slot)
-NTTTSSTSTTSSSSSTSSTN  | BMI > 10010110 00001001 (remove_empty_room_2)
-SNN                   | DROP
-NSNTSSTSTTSSSSSTSTSN  | JMP > 10010110 00001010 (main_loop_end_test)
-NSSVTSSTSTTSSSSSTSSTN | MARK: 10010110 00001001 (remove_empty_room_2)
-NSTTSSTSTTSSSSSTTSSN  | JSR > 10010110 00001100 (remove_element_from_array)
-@ If the array is now empty or only contains one room, return.
-@ Otherwise, loop again and build another random tunnel.
-NSSVTSSTSTTSSSSSTSTSN | MARK: 10010110 00001010 (main_loop_end_test)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TTT                   | LOAD
-SSSTSN                | PUSH 2
-TSST                  | SUBTRACT
-NTTTSSTSTTSSSSSTSTTN  | BMI > 10010110 00001011 (return)
-NSNTSSTSTTSSSSSSSSTN  | JMP > 10010110 00000001 (main_loop)
-NSSVTSSTSTTSSSSSTSTTN | MARK: 10010110 00001011 (return)
-NTN                   | RTS
-
-@ A private subroutine to remove one element from the temp array.
-@ Consumes the array index from TOS.
-NSSVTSSTSTTSSSSSTTSSN | MARK: 10010110 00001100 (remove_element_from_array)
-@ First, stash a copy of the array index immediately after the temporary array.
-@ This allows us to find it using the num_array_elements for use with spew
-@ after slurp has filled the stack with a variable number of elements.
-SNS                   | DUP
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TTT                   | LOAD
-TSSS                  | ADD
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-SNT                   | SWAP
-TTS                   | STORE
-@ Now slurp and spew the array to delete the desired element.
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-SNS                   | DUP
-@ TOS> index+1, index+1
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TTT                   | LOAD
-SNT                   | SWAP
-TSST                  | SUBTRACT
-@ Special case: deleting last element of array means no need to delete.
-SNS                   | DUP
-NTTTSSTSTTSSSSSTTTSN  | BMI > 10010110 00001110 (deleting_last_element)
-NSNTSSTSTTSSSSSTTTTN  | JMP > 10010110 00001111 (not_deleting_last_element)
-NSSVTSSTSTTSSSSSTTTSN | MARK: 10010110 00001110 (deleting_last_element)
-SNN                   | DROP
-SNN                   | DROP
-NSNTSSTSTTSSSSTSSSSN  | JMP > 10010110 00010000 (decrement_array_counter)
-NSSVTSSTSTTSSSSSTTTTN | MARK: 10010110 00001111 (not_deleting_last_element)
-SNT                   | SWAP
-@ TOS> index+1, count=num_array_elements-(index+1)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TSSS                  | ADD
-SNT                   | SWAP
-@ TOS> count=num_array_elements-(index+1), address=0x3000+index+1
-NSTTTTTSN             | JSR > 11110 (slurp)
-@ Recover the array index that we stashed on the heap.
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TTT                   | LOAD
-TSSS                  | ADD
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-TTT                   | LOAD
-@ TOS> index
-SNS                   | DUP
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TSSS                  | ADD
-SNT                   | SWAP
-@ TOS> index, address=0x3000+index
-SSSTN                 | PUSH 1
-TSSS                  | ADD
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TTT                   | LOAD
-SNT                   | SWAP
-TSST                  | SUBTRACT
-@ TOS> count = num_array_elements-(index+1), address=0x3000+index
-NSTTTTTTN             | JSR > 11111 (spew)
-@ Decrement the array element counter.
-NSSVTSSTSTTSSSSTSSSSN | MARK: 10010110 00010000 (decrement_array_counter)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (BUFFER)
-SNT                   | SWAP
-TTS                   | STORE
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   build_cave
-@ Description:
-@   Clears the cave data structure on the heap and builds new tunnels.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSSSTSSN         | MARK: 10000100 (build_cave)
-NSTTSSSSTTSN          | JSR > 10000110 (clear_cave_data)
-NSTTSSSTTTSN          | JSR > 10001110 (build_circular_tunnels)
-NSTTSSTSTTSN          | JSR > 10010110 (build_random_tunnels)
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   set_tunnel_destination
-@ Description:
-@   Sets 'slot' of 'room_number' to point to 'dst_room_number'.
-@ Call Stack:
-@   dst_room_number
-@   slot
-@   room_number  <-- TOS
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <wump_game.pvvs>
-NSSVTSSSTSSTN         | MARK: 10001001 (set_tunnel_destination)
-@ The pointer we seek is:
-@ (room_number * room_struct_size) + 2 + slot + ROOM_DATA_BASE
-@ Where the '+2' accounts for the pit and bat booleans.
-NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
-TSSN                  | MULTIPLY
-SSSTSN                | PUSH +2
-TSSS                  | ADD
-TSSS                  | ADD
-SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (ROOM_DATA_BASE address)
-TSSS                  | ADD
-SNT                   | SWAP
-TTS                   | STORE
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   generate_cave_hop_length
-@ Description:
-@   In order to ensure cave is fully connected, generate a number, 'hop_length',
-@   that is relatively prime to the number of rooms in the cave.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   hop_length
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <math.pvvs>
-NSSVTSSSSTTTN         | MARK: 10000111 (generate_cave_hop_length)
-NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
-@ Check for gcd(hop_length,num_rooms) = 1.
-SNS                   | DUP
-SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
-TTT                   | LOAD
-NSTTSSTSN             | JSR > 10010 (gcd)
-SSSTN                 | PUSH +1
-TSST                  | SUBTRACT
-NTSTSSSSTTTSSSSSSSSN  | BRZ > 10000111 00000000
-SNN                   | DROP
-NSNTSSSSTTTN          | JMP > 10000111 (generate_cave_hop_length)
-NSSVTSSSSTTTSSSSSSSSN | MARK: 10000111 00000000
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   clear_cave_data
-@ Description:
-@   Writes -1 over the entire cave data array.
-@   This ensures each room starts unconnected.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <heap.pvvs>
-#include <wump_game.pvvs>
-NSSVTSSSSTTSN         | MARK: 10000110 (clear_cave_data)
-SSTTN                 | PUSH -1 (pattern)
-SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (ROOM_DATA_BASE address)
-SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE address)
-TTT                   | LOAD
-NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
-TSSN                  | MULTIPLY
-NSTTTSSSN             | JSR > 11000 (memset)
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   get_random_room
-@ Description:
-@   Returns a valid room number
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   room_num  <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <math.pvvs>
-NSSVTSSSTSTSN         | MARK: 10001010 (get_random_room)
-NSTTSSSSN             | JSR > 10000 (random)
-SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE+0 = num_rooms address)
-TTT                   | LOAD
-TSTT                  | MODULO
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   set_bats
-@ Description:
-@   Set the 'bats' boolean for a specific room.
-@ Call Stack:
-@   value (0 or 1)
-@   room_number
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <wump_game.pvvs>
-NSSVTSSTSSSSN         | MARK: 10010000 (set_bats)
-@ We seek the pointer:
-@   (room_number * room_struct_size) + 1 + ROOM_DATA_BASE
-@ where '+1' accounts for the offset of the bat boolean in the desired room.
-NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
-TSSN                  | MULTIPLY
-SSSTN                 | PUSH +1
-TSSS                  | ADD
-SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (GAME_DATA_BASE address)
-TSSS                  | ADD
-SNT                   | SWAP
-TTS                   | STORE
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   set_pits
-@ Description:
-@   Set the 'pits' boolean for a specific room.
-@ Call Stack:
-@   value (0 or 1)
-@   room_number
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <wump_game.pvvs>
-NSSVTSSTSSSTN         | MARK: 10010001 (set_pits)
-@ We seek the pointer:
-@   (room_number * room_struct_size) + 0 + ROOM_DATA_BASE
-@ where '+0' accounts for the offset of the pit boolean in the desired room.
-NSTTSSSTSTTN          | JSR > 10001011 (get_room_struct_size)
-TSSN                  | MULTIPLY
-SSSTSSSSSSSSSSSSSN    | PUSH 0x2000 (GAME_DATA_BASE address)
-TSSS                  | ADD
-SNT                   | SWAP
-TTS                   | STORE
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   reset_cave_population
-@ Description:
-@   Remove all bats and pits from the cave.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSTSSTSN         | MARK: 10010010 (reset_cave_population)
-
-@ Clear the bat and pit booleans by setting every room to false(=0).
-@ First prepare a loop index.
-SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (GAME_DATA_BASE+0 = number_of_rooms address)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-NSSVTSSTSSTSSSSSSSSSN | MARK: 10010010 00000000 (empty_cave_loop)
-@ Scare all the bats out of the room.
-SNS                   | DUP
-SSSSN                 | PUSH 0 (false)
-SNT                   | SWAP
-NSTTSSTSSSSN          | JSR > 10010000 (set_bats)
-@ Fill any pits.
-SNS                   | DUP
-SSSSN                 | PUSH 0 (false)
-SNT                   | SWAP
-NSTTSSTSSSTN          | JSR > 10010001 (set_pits)
-@ Decrement loop counter and test for end of loop.
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-SNS                   | DUP
-NTTTSSTSSTSSSSSSSSTN  | BMI > 10010010 00000001 (empty_cave_loop_end)
-NSNTSSTSSTSSSSSSSSSN  | JMP > 10010010 00000000 (empty_cave_loop)
-@ Loop is complete. Clean up and return.
-NSSVTSSTSSTSSSSSSSSTN | MARK: 10010010 00000001 (empty_cave_loop_end)
-SNN                   | DROP
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   populate_bats
-@ Description:
-@   Randomly place a user-defined number of bats in the cave.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <wump_game.pvvs>
-NSSVTSSTSSTTN         | MARK: 10010011 (populate_bats)
-
-@ First prepare a loop index.
-SSSTSSSSSSSSSSTSN     | PUSH 0x1002 (GAME_DATA_BASE+2 = number_of_bats address)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-@ Find a random room that does not already contain bats.
-NSSVTSSTSSTTSSSSSSTSN | MARK: 10010011 00000010 (place_bats)
-NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
-SNS                   | DUP
-NSTTSSSTTSSN          | JSR > 10001100 (room_has_bats)
-NTSTSSTSSTTSSSSSSTTN  | BRZ > 10010011 00000011 (no_bats_in_room)
-SNN                   | DROP
-NSNTSSTSSTTSSSSSSTSN  | JMP > 10010011 00000010 (place_bats)
-@ Room is empty. Place bats.
-NSSVTSSTSSTTSSSSSSTTN | MARK: 10010011 00000011 (no_bats_in_room)
-SSSTN                 | PUSH 1 (true)
-SNT                   | SWAP
-NSTTSSTSSSSN          | JSR > 10010000 (set_bats)
-@ Decrement loop counter and test for loop completion.
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-SNS                   | DUP
-NTTTSSTSSTTSSSSSTSSN  | BMI > 10010011 00000100 (place_bats_loop_end)
-NSNTSSTSSTTSSSSSSTSN  | JMP > 10010011 00000010 (place_bats)
-@ Loop is complete. Clean up and return.
-NSSVTSSTSSTTSSSSSTSSN | MARK: 10010011 00000100 (place_bats_loop_end)
-SNN                   | DROP
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   populate_pits
-@ Description:
-@   Randomly place a user-defined number of pits in the cave.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <wump_game.pvvs>
-NSSVTSSTSTSSN         | MARK: 10010100 (populate_pits)
-
-@ First prepare a loop index.
-SSSTSSSSSSSSSSSTN     | PUSH 0x1001 (GAME_DATA_BASE+1 = number_of_pits address)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-@ Find a random room that does not already contain pits.
-NSSVTSSTSTSSSSSSSSTSN | MARK: 10010100 00000010 (place_pits)
-NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
-SNS                   | DUP
-NSTTSSSTTSTN          | JSR > 10001101 (room_has_pits)
-NTSTSSTSTSSSSSSSSTTN  | BRZ > 10010100 00000011 (no_pits_in_room)
-SNN                   | DROP
-NSNTSSTSTSSSSSSSSTSN  | JMP > 10010100 00000010 (place_pits)
-@ Room is empty. Place pits.
-NSSVTSSTSTSSSSSSSSTTN | MARK: 10010100 00000011 (no_pits_in_room)
-SSSTN                 | PUSH 1 (true)
-SNT                   | SWAP
-NSTTSSTSSSTN          | JSR > 10010001 (set_pits)
-@ Decrement loop counter and test for loop completion.
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-SNS                   | DUP
-NTTTSSTSTSSSSSSSTSSN  | BMI > 10010100 00000100 (place_pits_loop_end)
-NSNTSSTSTSSSSSSSSTSN  | JMP > 10010100 00000010 (place_pits)
-@ Loop is complete. Clean up and return.
-NSSVTSSTSTSSSSSSSTSSN | MARK: 10010100 00000100 (place_pits_loop_end)
-SNN                   | DROP
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   place_player
-@ Description:
-@   Place the player in a suitable starting room.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSTSTSTN         | MARK: 10010101 (place_player)
-
-@ Find out where the wumpus is located.
-SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (GAME_DATA_BASE+7 = wumpus_room address)
-TTT                   | LOAD
-@ Place the player in a different room than the wumpus.
-NSSVTSSTSTSTSSSSSSSSN | MARK: 10010101 00000000 (place_player_loop)
-NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
-SNT                   | SWAP
-SNS                   | DUP
-SSSTTN                | PUSH 3
-NSTTTSSN              | JSR > 1100 (deepdup)
-@ TOS> rand_room, wump_room, wump_room, rand_room
-TSST                  | SUBTRACT
-NTSTSSTSTSTSSSSSSSTN  | BRZ > 10010101 00000001 (same_room)
-NSNTSSTSTSTSSSSSSTSN  | JMP > 10010101 00000010 (different_rooms)
-NSSVTSSTSTSTSSSSSSSTN | MARK: 10010101 00000001 (same_room)
-SNN                   | DROP
-NSNTSSTSTSTSSSSSSSSN  | JMP > 10010101 00000000 (place_player_loop)
-NSSVTSSTSTSTSSSSSSTSN | MARK: 10010101 00000010 (different_rooms)
-SNN                   | DROP
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (GAME_DATA_BASE+6 = player_room address)
-SNT                   | SWAP
-TTS                   | STORE
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   populate_cave
-@ Description:
-@   Populate the cave with various creatures and features.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-NSSVTSSSSTSTN         | MARK: 10000101 (populate_cave)
-
-@ Initialize the cave to an unpopulated state.
-NSTTSSTSSTSN          | JSR > 10010010 (reset_cave_population)
-
-@ Place bats in the now-empty cave.
-NSTTSSTSSTTN          | JSR > 10010011 (populate_bats)
-
-@ Place pits in the now-empty cave.
-NSTTSSTSTSSN          | JSR > 10010100 (populate_pits)
-
-@ Place the wumpus.
-SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (GAME_DATA_BASE+7 = wumpus_room address)
-NSTTSSSTSTSN          | JSR > 10001010 (get_random_room)
-TTS                   | STORE
-
-@ Place the player.
-NSTTSSTSTSTN          | JSR > 10010101 (place_player)
-
-NTN                   | RTS
-
-#endif
diff --git a/examples/wump/wump_strings.pvvs b/examples/wump/wump_strings.pvvs
deleted file mode 100644 (file)
index d8cfb69..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef WUMP_STRING
-#define WUMP_STRING
-
-@ Some text strings in this file were imported from:
-@ $NetBSD: wump.c,v 1.17 2005/02/15 12:56:20 jsm Exp $
-@ Copyright (c) 1989, 1993
-@ The Regents of the University of California.  All rights reserved.
-@
-@ Everything else is
-@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
-@ See LICENSE.txt file for copyright and license details.
-
-NSSVTTTTTTTTSSSSSSSSN | Mark: 11111111 00000000 (wump_kill)
-A"\n*ROAR* *chomp* *snurfle* *chomp*!\nMuch to the delight of the Wumpus, you walked right into his mouth,\nmaking you one of the easiest dinners he's ever had!  For you, however,\nit's a rather unpleasant death.  The only good thing is that it's been\nso long since the evil Wumpus cleaned his teeth that you immediately\npassed out from the stench!\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSSSSTN | Mark: 11111111 00000001 (kill_wump)
-A"\n*thwock!* *groan* *crash*\nA horrible roar fills the cave, and you realize, with a smile, that you\nhave slain the evil Wumpus and won the game!  You don't want to tarry for\nlong, however, because not only is the Wumpus famous, but the stench of\ndead Wumpus is also quite well known, a stench plenty enough to slay the\nmightiest adventurer at a single whiff!!\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSSSTSN | Mark: 11111111 00000010 (no_arrows)
-A"\nYou turn and look at your quiver, and realize with a sinking feeling\nthat you've just shot your last arrow (figuratively, too).  Sensing this\nwith its psychic powers, the evil Wumpus rampagees through the cave, finds\nyou, and with a mighty *ROAR* eats you alive!\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSSSTTN | Mark: 11111111 00000011 (shoot_self)
-A"\n*Thwack!*  A sudden piercing feeling informs you that the ricochet\nof your wild arrow has resulted in it wedging in your side, causing\nextreme agony.  The evil Wumpus, with its psychic powers, realizes this\nand immediately rushes to your side, not to help, alas, but to EAT YOU!\n(*CHOMP*)\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSSTSSN | Mark: 11111111 00000100 (jump)
-A"\nWith a jaunty step you enter the magic tunnel.  As you do, you\nnotice that the walls are shimmering and glowing.  Suddenly you feel\na very curious, warm sensation and find yourself in room %u!!\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSSTSTN | Mark: 11111111 00000101 (pit_kill)
-A"\n*AAAUUUUGGGGGHHHHHhhhhhhhhhh...*\nThe whistling sound and updraft as you walked into this room of the\ncave apparently wasn't enough to clue you in to the presence of the\nbottomless pit.  You have a lot of time to reflect on this error as\nyou fall many miles to the core of the earth.  Look on the bright side;\nyou can at least find out if Jules Verne was right...\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSSTTSN | Mark: 11111111 00000110 (pit_survive)
-A"\nWithout conscious thought you grab for the side of the cave and manage\nto grasp onto a rocky outcrop.  Beneath your feet stretches the limitless\ndepths of a bottomless pit!  Rock crumbles beneath your feet!\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSSTTTN | Mark: 11111111 00000111 (please_seed_rng)
-A"\n\n\n\nWelcome to Hunt the Wumpus!\n\nPlease press 16 keys to seed the RNG.\n               |\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSTSSSN | Mark: 11111111 00001000 (problem_with_input)
-A"I don't understand!\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSTSSTN | Mark: 11111111 00001001 (instructions)
-A"\n\nWelcome to the game of Hunt the Wumpus.\n\nThe Wumpus typically lives in a cave of twenty rooms, with each room having\nthree tunnels connecting it to other rooms in the cavern.  Caves may vary,\nhowever, depending on options specified when starting the game.\n\nThe game has the following hazards for intrepid adventurers to wind their\nway through:\n\n  Pits   -- If you fall into one of the bottomless pits, you find yourself\n            slung back out on the far side of the Earth and in very poor\n            shape to continue your quest since you're dead.\n\n  Bats   -- As with any other cave, the Wumpus cave has bats in residence.\n            These are a bit more potent, however, and if you stumble into\n            one of their rooms they will rush up and carry you elsewhere in\n            the cave.\n\n  Wumpus -- If you happen to walk into the room the Wumpus is in you'll find\n            that he has quite an appetite for young adventurous humans!  Not\n            recommended.\n\nThe Wumpus, by the way, is not bothered by the hazards since he has sucker\nfeet and is too big for a bat to lift.  If you try to shoot him and miss,\nthere's also a chance that he'll up and move himself into another cave,\nthough by nature the Wumpus is a sedentary creature.\n\nEach turn you may either move or shoot a crooked arrow.  Moving is done\nsimply by specifying 'm' for move and the number of the room that you'd\nlike to move down a tunnel towards.  Shooting is done similarly; indicate\nthat you'd like to shoot one of your magic arrows with an 's' for shoot,\nthen list a set of connected room numbers through which the deadly shaft\nshould fly!\n\nIf your path for the arrow is incorrect, however, it will flail about in\nthe room it can't understand and randomly pick a tunnel to continue\nthrough.  You might just end up shooting yourself in the foot if you're\nnot careful!  On the other hand, if you shoot the Wumpus you've WON!\n\nLet the hunt begin!\n"
-NTN                   | RTS
-
-NSSVTTTTTTTTSSSSTSTSN | Mark: 11111111 00001010 (cave_description)
-A"\nYou're in a cave with %u rooms and %u tunnels leading from each room.\nThere are %u bats and %u pits scattered throughout the cave, and your\nquiver holds %u custom super anti-evil Wumpus arrows. Good luck.\n\n"
-NTN                   | RTS
-
-#endif
diff --git a/examples/wump/wump_ui.pvvs b/examples/wump/wump_ui.pvvs
deleted file mode 100644 (file)
index 2b9c268..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-#ifndef WUMP_UI
-#define WUMP_UI
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ This files contains user interface functions for Hunt the Wumpus.
-@ (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
-@ See LICENSE.txt file for copyright and license details.
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   seed_rng
-@ Description:
-@   Generate seed from keyboard input.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <logic.pvvs>
-NSSVTSSSSSTTN         | MARK: 10000011 (seed_rng)
-
-SSSTSSSSN             | PUSH 16 (loop counter)
-SSSSN                 | PUSH 0 (rng seed)
-
-NSSVTSSSSSTTSSSSSSSSN | MARK: 10000011 00000000 (seed_rng:main loop)
-@ Get character from user and print ASCII '.' as feedback.
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
-TNTS                  | GETCHAR
-SSSTSTTTSN            | PUSH ASCII '.'
-TNSS                  | PUTCHAR
-@ Left shift the seed by 4 bits.
-SSSTSSN               | PUSH 4 (shift count)
-NSTTSTTSTN            | JSR > 101101 (lshift)
-@ XOR seed with character from user.
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
-TTT                   | LOAD
-NSTTSTSTTN            | JSR > 101011 (xor)
-@ Decrement counter
-SNT                   | SWAP
-SSSTN                 | PUSH +1
-TSST                  | SUBTRACT
-@ Test for loop completion
-SNS                   | DUP
-NTSTSSSSSTTSSSSSSSTN  | BRZ > 10000011 00000001 (seed_rng:cleanup and return)
-SNT                   | SWAP
-NSNTSSSSSTTSSSSSSSSN  | JMP > 10000011 00000000 (seed_rng:main loop)
-
-@ Store seed, clean up and return.
-NSSVTSSSSSTTSSSSSSSTN | MARK: 10000011 00000001 (seed_rng:cleanup and return)
-SNN                   | DROP
-SSSSN                 | PUSH 0 (seed address)
-SNT                   | SWAP
-TTS                   | STORE
-SSSTSTSN              | PUSH ASCII '\n'
-SSSTSTSN              | PUSH ASCII '\n'
-TNSS                  | PUTCHAR
-TNSS                  | PUTCHAR
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   is_room_adjacent
-@ Description:
-@   Checks if 'room_number' is adjacent to the player's current room.
-@ Call Stack:
-@   room_number  <-- TOS
-@ Return Stack:
-@   (1 or 0) for true/false  <-- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stack.pvvs>
-NSSVTSTSSTSSN         | MARK: 10100100 (is_room_adjacent)
-
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (ptr to number_of_tunnels_per_room)
-TTT                   | LOAD
-SSSTN                 | PUSH +1
-TSST                  | SUBTRACT
-
-@ TOS> tunnel_index, destination_room_num
-NSSVTSTSSTSSSSSSSSSSN | MARK: 10100100 00000000 (is_room_adjacent:main_loop)
-SSSTSN                | PUSH +2
-NSTTTSSN              | JSR > 1100 (deepdup)
-SSSTSN                | PUSH +2
-NSTTTSSN              | JSR > 1100 (deepdup)
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player_location)
-TTT                   | LOAD
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-TSST                  | SUBTRACT
-NTSTSTSSTSSSSSSSSSTN  | BRZ > 10100100 00000001 (is_room_adjacent:found_tunnel)
-SSSTN                 | PUSH +1
-TSST                  | SUBTRACT
-SNS                   | DUP
-NTTTSTSSTSSSSSSSSTSN  | BMI > 10100100 00000010 (is_room_adjacent:no_match)
-NSNTSTSSTSSSSSSSSSSN  | JMP > 10100100 00000000 (is_room_adjacent:main_loop)
-
-NSSVTSTSSTSSSSSSSSSTN | MARK: 10100100 00000001 (is_room_adjacent:found_tunnel)
-SNN                   | DROP
-SNN                   | DROP
-SSSTN                 | PUSH +1
-NTN                   | RTS
-
-NSSVTSTSSTSSSSSSSSTSN | MARK: 10100100 00000010 (is_room_adjacent:no_match)
-SNN                   | DROP
-SNN                   | DROP
-SSSSN                 | PUSH 0
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   move_player
-@ Description:
-@   Prompts the player for a room number. Moves to that room, checking the new
-@   environment and executing consequences (fell in a pit, etc) as appropriate.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stdio.pvvs>
-#include <convert.pvvs>
-#include <math.pvvs>
-#include <string.pvvs>
-NSSVTSTSSSTTN         | MARK: 10100011 (move_player)
-
-A"To which room do you wish to move?\n"
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer address)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer size)
-NSTTSSSTSN            | JSR > 100010 (get_user_string)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
-NSTTTSSSSN            | JSR > 110000 (atoi)
-SNN                   | DROP
-
-@ The desired room number is now on the TOS. Verify that it is valid.
-SNS                   | DUP
-NSTTSTSSTSSN          | JSR > 10100100 (is_room_adjacent)
-NTSTSTSSSTTSSSSSSSTN  | BRZ > 10100011 00000001 (invalid room number)
-NSNTSTSSSTTSSSSSSSSN  | JMP > 10100011 00000000 (valid room number)
-
-NSSVTSTSSSTTSSSSSSSTN | MARK: 10100011 00000001 (invalid room number)
-@ TOS> room_number
-SNN                   | DROP
-A"*Oof!* (you hit the wall)\n"
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSTTSSSSN             | JSR > 10000 (random)
-SSSTTSN               | PUSH 6 (chance)
-TSTT                  | MODULO
-NTSTSTSSSTTSSSSSSTSN  | BRZ > 10100011 00000010 (woke the wumpus)
-NTN                   | RTS
-NSSVTSTSSSTTSSSSSSTSN | MARK: 10100011 00000010 (woke the wumpus)
-A"Your colorful comments awaken the wumpus!\n"
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSTTSSSSN             | JSR > 10000 (random)
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (ptr to number of tunnels per room)
-TSTT                  | MODULO
-SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (ptr to wumpus location)
-TTT                   | LOAD
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-SSSTSSSSSSSSSTTTN     | PUSH 0x1007 (ptr to wumpus location)
-SNT                   | SWAP
-TTS                   | STORE
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
-TTT                   | LOAD
-NSTTSTSSSSSN          | JSR > 10100000 (room_has_wumpus)
-NTSTSTSSSTTSSSSSSTTN  | BRZ > 10100011 00000011 (wumpus did not move to player)
-NSTTTTTTTTTSSSSSSSSN  | JSR > 11111111 00000000 (wump_kill)
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NNN                   | DIE
-NSSVTSTSSSTTSSSSSSTTN | MARK: 10100011 00000011 (wumpus did not move to player)
-NTN                   | RTS
-
-NSSVTSTSSSTTSSSSSSSSN | MARK: 10100011 00000000 (valid room number)
-@ TOS> room_number
-@ Move player to new room
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
-SNT                   | SWAP
-TTS                   | STORE
-@ Check for wumpus in new player location
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
-TTT                   | LOAD
-NSTTSTSSSSSN          | JSR > 10100000 (room_has_wumpus)
-NTSTSTSSSTTSSSSSTSSN  | BRZ > 10100011 00000100 (no wumpus in new room)
-NSTTTTTTTTTSSSSSSSSN  | JSR > 11111111 00000000 (wump_kill)
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NNN                   | DIE
-NSSVTSTSSSTTSSSSSTSSN | MARK: 10100011 00000100 (no wumpus in new room)
-@ Check for pits in new player location
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
-TTT                   | LOAD
-NSTTSSSTTSTN          | JSR > 10001101 (room_has_pits)
-NTSTSTSSSTTSSSSSTSTN  | BRZ > 10100011 00000101 (no pits in new room)
-NSTTSSSSN             | JSR > 10000 (random)
-SSSTTSN               | PUSH 6 (chance)
-TSTT                  | MODULO
-NTSTSTSSSTTSSSSSTTSN  | BRZ > 10100011 00000110 (survived the pits)
-NSTTTTTTTTTSSSSSTSTN  | JSR > 11111111 00000101 (pit_kill)
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NNN                   | DIE
-NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (survived the pits)
-NSTTTTTTTTTSSSSSTTSN  | JSR > 11111111 00000110 (pit_survive)
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSSVTSTSSSTTSSSSSTSTN | MARK: 10100011 00000101 (no pits in new room)
-@ Check for bats in new player location
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
-TTT                   | LOAD
-NSTTSSSTTSSN          | JSR > 10001100 (room_has_bats)
-NTSTSTSSSTTSSSSSTTSN  | BRZ > 10100011 00000110 (no bats in new room)
-A"*flap*  *flap*  *flap*  (humongous bats pick you up and move you!)\n"
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSTTSSSSN             | JSR > 10000 (random)
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (ptr to number of tunnels per room)
-TSTT                  | MODULO
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (ptr to player location)
-TTT                   | LOAD
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-NSNTSTSSSTTSSSSSSSSN  | JMP > 10100011 00000000 (valid room number)
-NSSVTSTSSSTTSSSSSTTSN | MARK: 10100011 00000110 (no bats in new room)
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   move_or_shoot
-@ Description:
-@   Parse user input, branching to the appropriate subroutine to move or shoot.
-@   This function does not perform any boundary checks/limits.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stdio.pvvs>
-#include <string.pvvs>
-NSSVTSTSSSTSN         | MARK: 10100010 (move_or_shoot)
-
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer address)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer size)
-NSTTSSSTSN            | JSR > 100010 (get_user_string)
-
-@ Examine the first character of the user input buffer for 'm' or 's'.
-@ If character is something else, prompt user to try again.
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
-TTT                   | LOAD
-SSSSTTSTTSTN          | PUSH 109 (ASCII 'm')
-TSST                  | SUBTRACT
-NTSTSTSSSTSSSSSSSSSN  | BRZ > 10100010 00000000 (move)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
-TTT                   | LOAD
-SSSSTTTSSTTN          | PUSH 115 (ASCII 's')
-TSST                  | SUBTRACT
-NTSTSTSSSTSSSSSSSSTN  | BRZ > 10100010 00000001 (shoot)
-NSTTTTTTTTTSSSSTSSSN  | JSR > 11111111 00001000 (problem_with_input)
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSNTSTSSSTSN          | JMP > 10100010 (move_or_shoot)
-
-@ User typed 'm'
-NSSVTSTSSSTSSSSSSSSSN | MARK: 10100010 00000000 (move)
-NSTTSTSSSTTN          | JSR > 10100011 (move_player)
-NTN                   | RTS
-
-@ User typed 's'
-NSSVTSTSSSTSSSSSSSSTN | MARK: 10100010 00000001 (shoot)
-@ TODO: JSR shoot
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   get_answer
-@ Description:
-@   Parse user input, returning 0 if user string started with 'n' or 1 if 'y'.
-@   This function does not perform any boundary checks/limits.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   (1 or 0 for True/False)   <--- TOS
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stdio.pvvs>
-#include <string.pvvs>
-NSSVTSSTTSSSN         | MARK: 10011000 (get_answer)
-
-@ TODO: Consider extending the GETCHAR instruction in VVS to indicate an empty
-@       buffer instead of blocking. This would allow a character by character
-@       check without printing a slew of retry messages if the buffer is
-@       non-empty.
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer address)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (buffer size)
-NSTTSSSTSN            | JSR > 100010 (get_user_string)
-
-@ Examine the first character of the user input buffer for 'y' or 'n'.
-@ If character is something else, prompt user to try again.
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
-TTT                   | LOAD
-SSSSTTTTSSTN          | PUSH 121 (ASCII 'y')
-TSST                  | SUBTRACT
-NTSTSSTTSSSSSSSSSSSN  | BRZ > 10011000 00000000 (answer: yes)
-SSSTTSSSSSSSSSSSSN    | PUSH 0x3000 (USER_INPUT_BUFFER address)
-TTT                   | LOAD
-SSSSTTSTTTSN          | PUSH 110 (ASCII 'n')
-TSST                  | SUBTRACT
-NTSTSSTTSSSSSSSSSSTN  | BRZ > 10011000 00000001 (answer: no)
-NSTTTTTTTTTSSSSTSSSN  | JSR > 11111111 00001000 (problem_with_input)
-SSSSN                 | PUSH 0 (number of string substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSNTSSTTSSSN          | JMP > 10011000 (get_answer)
-
-@ User typed 'y'
-NSSVTSSTTSSSSSSSSSSSN | MARK: 10011000 00000000 (answer: yes)
-SSSTN                 | PUSH 1
-NTN                   | RTS
-
-@ User typed 'n'
-NSSVTSSTTSSSSSSSSSSTN | MARK: 10011000 00000001 (answer: no)
-SSSSN                 | PUSH 0
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   print_cave_description
-@ Description:
-@   Prints information about the cave (number of rooms, etc).
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <stdio.pvvs>
-NSSVTSSTTSTTN         | MARK: 10011011 (print_cave_description)
-NSTTTTTTTTTSSSSTSTSN  | JSR > 11111111 00001010 (cave_description)
-SSSTSSSSSSSSSTSTN     | PUSH 0x1005 (number_of_arrows address)
-TTT                   | LOAD
-SSSTSSSSSSSSSSSTN     | PUSH 0x1001 (number_of_pits address)
-TTT                   | LOAD
-SSSTSSSSSSSSSSTSN     | PUSH 0x1002 (number_of_bats address)
-TTT                   | LOAD
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_tunnels address)
-TTT                   | LOAD
-SSSTSSSSSSSSSSSSN     | PUSH 0x1000 (number_of_rooms address)
-TTT                   | LOAD
-SSSTSTN               | PUSH 5 (number of substitions)
-NSTTSSSN              | JSR > 1000 (printf)
-NTN                   | RTS
-
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@ Name:
-@   print_room_stats
-@ Description:
-@   Prints information about current room and hints about nearby rooms.
-@ Call Stack:
-@   <empty>
-@ Return Stack:
-@   <empty>
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-#include <wump_game.pvvs>
-#include <stdio.pvvs>
-#include <stack.pvvs>
-NSSVTSTSSSSTN         | MARK: 10100001 (print_room_stats)
-
-@ Print location and arrow quantity remaining.
-A"You are in room %u of the cave and have %u arrows remaining.\n"
-SSSTSSSSSSSSSTSTN     | PUSH 0x1005 (number_of_arrows address)
-TTT                   | LOAD
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (player_location address)
-TTT                   | LOAD
-SSSTSN                | PUSH 2 (number of substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-
-@ Print if bats/pits/wumpus nearby.
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (player_location address)
-TTT                   | LOAD
-SNS                   | DUP
-NSTTSSTTTSSN          | JSR > 10011100 (are_bats_near)
-NTSTSTSSSSTSSSSSSSSN  | BRZ > 10100001 00000000 (no_bats)
-A"*rustle* (Bats must be nearby.)\n"
-SSSSN                 | PUSH 0 (number of substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSSVTSTSSSSTSSSSSSSSN | MARK: 10100001 00000000 (no_bats)
-SNS                   | DUP
-NSTTSSTTTSTN          | JSR > 10011101 (are_pits_near)
-NTSTSTSSSSTSSSSSSSTN  | BRZ > 10100001 00000001 (no_pits)
-A"*whoosh* (You feel a draft from nearby pits.)\n"
-SSSSN                 | PUSH 0 (number of substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSSVTSTSSSSTSSSSSSSTN | MARK: 10100001 00000001 (no_pits)
-NSTTSSTTTTSN          | JSR > 10011110 (is_wumpus_near)
-NTSTSTSSSSTSSSSSSTSN  | BRZ > 10100001 00000010 (no_wumpus)
-A"*sniff* (You smell the evil Wumpus nearby!)\n"
-SSSSN                 | PUSH 0 (number of substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-NSSVTSTSSSSTSSSSSSTSN | MARK: 10100001 00000010 (no_wumpus)
-
-@ Print a list of nearby rooms.
-A"This room contains tunnels to the following rooms:"
-SSSSN                 | PUSH 0 (number of substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-SSSTSSSSSSSSSTTSN     | PUSH 0x1006 (player_location address)
-TTT                   | LOAD
-SSSTSSSSSSSSSSTTN     | PUSH 0x1003 (number_of_links_per_room address)
-TTT                   | LOAD
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-@ Print one room on each pass through this loop.
-@ TOS> tunnel_index, room_number
-NSSVTSTSSSSTSSSSSSTTN | MARK: 10100001 00000011 (print_room_list_loop)
-A" %u"
-SSSTSTN               | PUSH 5
-NSTTTSSN              | JSR > 1100 (deepdup)
-SSSTTTN               | PUSH 7
-NSTTTSSN              | JSR > 1100 (deepdup)
-NSTTSSSTSSSN          | JSR > 10001000 (get_tunnel_destination)
-SSSTN                 | PUSH 1 (number of substitutions)
-NSTTSSSN              | JSR > 1000 (printf)
-@ Test for end of loop
-SNS                   | DUP
-NTSTSTSSSSTSSSSSTSSN  | BRZ > 10100001 00000100 (print_room_list_loop_end)
-SSSTN                 | PUSH 1
-TSST                  | SUBTRACT
-NSNTSTSSSSTSSSSSSTTN  | JMP > 10100001 00000011 (print_room_list_loop)
-@ Clean up and return.
-NSSVTSTSSSSTSSSSSTSSN | MARK: 10100001 00000100 (print_room_list_loop_end)
-SSSTSTSN              | PUSH 10 (ASCII '\n')
-TNSS                  | PUTCHAR
-SNN                   | DROP
-SNN                   | DROP
-NTN                   | RTS
-
-#endif