From 3f34adad3b6596b3a99175b071f83e70a5e0d594 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 28 Feb 2023 19:46:50 -0500 Subject: [PATCH 001/213] Move pylint suppressions inline. --- Makefile | 3 +-- make_dungeon.py | 2 +- make_graph.py | 2 +- tests/coverage_dungeon.py | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 59f7e4e..4e5f331 100644 --- a/Makefile +++ b/Makefile @@ -140,6 +140,5 @@ CSUPPRESSIONS = --suppress=missingIncludeSystem --suppress=invalidscanf cppcheck: cppcheck -I. --template gcc --enable=all $(CSUPPRESSIONS) *.[ch] -PYSUPPRESSIONS = line-too-long,invalid-name,missing-function-docstring,too-many-lines,too-many-branches,global-statement,multiple-imports,too-many-locals,too-many-statements,too-many-nested-blocks,no-else-return,raise-missing-from,redefined-outer-name,consider-using-in,dict-iter-missing-items pylint: - @pylint --score=n --disable=$(PYSUPPRESSIONS) *.py */*.py + @pylint --score=n *.py */*.py diff --git a/make_dungeon.py b/make_dungeon.py index 5eb7dee..c7c9b75 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -11,7 +11,7 @@ Copyright (c) 2017 by Eric S. Raymond SPDX-License-Identifier: BSD-2-clause """ -# pylint: disable=consider-using-f-string +# pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,too-many-branches,global-statement,multiple-imports,too-many-locals,too-many-statements,too-many-nested-blocks,no-else-return,raise-missing-from,redefined-outer-name import sys, yaml diff --git a/make_graph.py b/make_graph.py index 16ebcba..b9124d6 100755 --- a/make_graph.py +++ b/make_graph.py @@ -14,7 +14,7 @@ Make a DOT graph of Colossal Cave. # Copyright (c) 2017 by Eric S. Raymond # SPDX-License-Identifier: BSD-2-clause -# pylint: disable=consider-using-f-string +# pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,multiple-imports,redefined-outer-name import sys, getopt, yaml diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index bbab99b..c2ccabe 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -12,7 +12,7 @@ even if the checkfile search doesn't find them. Typically this will because they emit a templated message that can't be regression-tested by equality. """ -# pylint: disable=consider-using-f-string +# pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,redefined-outer-name import os import sys From 94e7cc65050ddfd04a8a1606f8899c7e5be496e8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 1 Mar 2023 13:04:53 -0500 Subject: [PATCH 002/213] Address Gitlab isse #62: Comment typos. --- actions.c | 4 ++-- advent.h | 2 +- main.c | 12 ++++++------ misc.c | 6 +++--- saveresume.c | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/actions.c b/actions.c index a2105f8..c09331a 100644 --- a/actions.c +++ b/actions.c @@ -1,5 +1,5 @@ /* - * Actions for the duneon-running code. + * Actions for the dungeon-running code. * * Copyright (c) 1977, 2005 by Will Crowther and Don Woods * Copyright (c) 2017 by Eric S. Raymond @@ -929,7 +929,7 @@ static phase_codes_t light(verb_t verb, obj_t obj) } static phase_codes_t listen(void) -/* Listen. Intransitive only. Print stuff based on object sound proprties. */ +/* Listen. Intransitive only. Print stuff based on object sound properties. */ { bool soundlatch = false; vocab_t sound = locations[game.loc].sound; diff --git a/advent.h b/advent.h index a2c1eb0..a68613b 100644 --- a/advent.h +++ b/advent.h @@ -13,7 +13,7 @@ #define LCG_M 1048576L #define LINESIZE 1024 -#define TOKLEN 5 // # sigificant characters in a token */ +#define TOKLEN 5 // # outputting characters in a token */ #define NDWARVES 6 // number of dwarves #define PIRATE NDWARVES // must be NDWARVES-1 when zero-origin #define DALTLC LOC_NUGGET // alternate dwarf location diff --git a/main.c b/main.c index f74bd8f..1bdc64c 100644 --- a/main.c +++ b/main.c @@ -97,7 +97,7 @@ int main(int argc, char *argv[]) } } - /* copy inncation line part after switches */ + /* copy invocation line part after switches */ settings.argc = argc - optind; settings.argv = argv + optind; settings.optind = 0; @@ -139,8 +139,8 @@ int main(int argc, char *argv[]) char *myreadline(const char *prompt) { /* - * This function isbn't required for gameplay, readline() straight - * up would suffice for tat. It's where we interpret command-line + * This function isn't required for gameplay, readline() straight + * up would suffice for that. It's where we interpret command-line * logfiles for testing purposes. */ /* Normal case - no script arguments */ @@ -1048,10 +1048,10 @@ static void listobjects(void) static bool preprocess_command(command_t *command) /* Pre-processes a command input to see if we need to tease out a few specific cases: * - "enter water" or "enter stream": - * wierd specific case that gets the user wet, and then kicks us back to get another command + * weird specific case that gets the user wet, and then kicks us back to get another command * - : * Irregular form of input, but should be allowed. We switch back to form for - * furtherprocessing. + * further processing. * - "grate": * If in location with grate, we move to that grate. If we're in a number of other places, * we move to the entrance. @@ -1222,7 +1222,7 @@ static bool do_command() if (closecheck() ) return true; - /* loop until all words in command are procesed */ + /* loop until all words in command are processed */ while (command.state == PREPROCESSED ) { command.state = PROCESSING; diff --git a/misc.c b/misc.c index 7365fbf..f8aa9de 100644 --- a/misc.c +++ b/misc.c @@ -1,5 +1,5 @@ /* - * I/O and support riutines. + * I/O and support routines. * * Copyright (c) 1977, 2005 by Will Crowther and Don Woods * Copyright (c) 2017 by Eric S. Raymond @@ -411,7 +411,7 @@ static bool is_valid_int(const char *str) if (!*str) return false; // LCOV_EXCL_LINE - // Check for non-digit chars in the rest of the stirng. + // Check for non-digit chars in the rest of the string. while (*str) { if (!isdigit(*str)) return false; @@ -476,7 +476,7 @@ static void get_vocab_metadata(const char* word, vocab_t* id, word_type_t* type) static void tokenize(char* raw, command_t *cmd) { /* - * Be caereful about modifing this. We do not want to nuke the + * Be careful about modifying this. We do not want to nuke the * the speech part or ID from the previous turn. */ memset(&cmd->word[0].raw, '\0', sizeof(cmd->word[0].raw)); diff --git a/saveresume.c b/saveresume.c index b5205d3..25757c4 100644 --- a/saveresume.c +++ b/saveresume.c @@ -143,8 +143,8 @@ int restore(FILE* fp) bool is_valid(struct game_t valgame) { /* Save files can be roughly grouped into three groups: - * With valid, reaceable state, with valid, but unreachable - * state and with invaild state. We check that state is + * With valid, reacheable state, with valid, but unreachable + * state and with invalid state. We check that state is * valid: no states are outside minimal or maximal value */ From 17782cab6754a39822d36254c6c8daff4d18af6a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 1 Mar 2023 13:52:54 -0500 Subject: [PATCH 003/213] Another comment typo fix. --- misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc.c b/misc.c index f8aa9de..b2ad688 100644 --- a/misc.c +++ b/misc.c @@ -490,7 +490,7 @@ static void tokenize(char* raw, command_t *cmd) /* (ESR) In oldstyle mode, simulate the uppercasing and truncating * effect on raw tokens of packing them into sixbit characters, 5 * to a 32-bit word. This is something the FORTRAN version did - * becuse archaic FORTRAN had no string types. Don Wood's + * because archaic FORTRAN had no string types. Don Wood's * mechanical translation of 2.5 to C retained the packing and * thus this misfeature. * From 1f644a1d7d441a24bfc6df7271e028f08c125d40 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 1 Mar 2023 14:01:44 -0500 Subject: [PATCH 004/213] Don't crap out on failed diff. --- tests/tapdiffer | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/tapdiffer b/tests/tapdiffer index b529a39..3ddd629 100755 --- a/tests/tapdiffer +++ b/tests/tapdiffer @@ -16,7 +16,6 @@ trap 'rm /tmp/tapdiff$$' EXIT HUP INT QUIT TERM if diff --text -u ${checkfile} - >/tmp/tapdiff$$ then echo "ok - ${legend}" - exit 0 else echo "not ok - ${checkfile}: ${legend}" if [ ! "${QUIET}" = 1 ] @@ -25,7 +24,6 @@ else sed Date: Wed, 1 Mar 2023 16:03:13 -0500 Subject: [PATCH 005/213] Comment typo fix. --- notes.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes.adoc b/notes.adoc index 68ea03d..bc8db58 100644 --- a/notes.adoc +++ b/notes.adoc @@ -62,7 +62,7 @@ Bug fixes: bridge spans the fissure." (timeless present). * A few minor typos have been corrected: absence of capitalization on - "Swiss" and "Persian", inconsistent selling of "imbedded" vs. "embedded", + "Swiss" and "Persian", inconsistent spelling of "imbedded" vs. "embedded", "eying" for "eyeing". "thresholds" for "threshholds". * Under odd circumstances (dropping rug or vase outdoors) the game could From 426684fec2c4b61ae3e1eb6c709fca61f0e5753f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 1 Mar 2023 17:46:13 -0500 Subject: [PATCH 006/213] Increase retrigressiveness of oldstyle a bit. --- actions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions.c b/actions.c index c09331a..a831d97 100644 --- a/actions.c +++ b/actions.c @@ -226,7 +226,7 @@ static phase_codes_t bigwords(vocab_t id) } } else { fum: - if (game.loc == LOC_GIANTROOM) { + if (game.loc == LOC_GIANTROOM || settings.oldstyle) { rspeak(START_OVER); } else { /* This is new behavior in Open Adventure - sounds better when From dfff80faa8b5cf4cd286fee2d1ef5eebcdb49829 Mon Sep 17 00:00:00 2001 From: "Rob Swindell (on Debian Linux)" Date: Thu, 2 Mar 2023 19:44:47 -0800 Subject: [PATCH 007/213] Add optional auto-save/restore feature using -a option To enable use with online Bulletin Board Systems (BBSes) where users may be disconnected unexpectedly, but would naturally want to resume playing their same game, added support for an optional save game path/filename to be specified on the command-line (very similar to "-r "), except this save/restore file is: 1. automatically loaded/restored if it exists 2. automatically created when starting a new game 3. automatically updated when exiting a game for any reason 4. cannot be changed to a different path/filename by the user Since a BBS server program can be expected to send a SIGHUP or SIGTERM to the game process upon user disconnection (or timeout), those signals are caught and a graceful termination will occur which saves the current game state. Build with ADVENT_AUTOSAVE defined to enable this option. BUG: The 'info' command still reports the save/suspend/pause commands as valid, though they are not when this build option is used (same is true of ADVENT_NOSAVE, and that doesn't apparently bother anyone). --- Makefile | 1 + advent.h | 3 +++ main.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- saveresume.c | 4 ++-- score.c | 3 +++ 5 files changed, 57 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 4e5f331..38139de 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ # Makefile for the open-source release of adventure 2.5 # To build with save/resume disabled, pass CFLAGS="-DADVENT_NOSAVE" +# To build with auto-save/resume enabled, pass CFLAGS="-D ADVENT_AUTOSAVE" VERS=$(shell sed -n = mxscor && game.trnluz != 0) rspeak(TOOK_LONG); From ac0c5fc024792193286bc6cfbdca5fc08241bfc8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 3 Mar 2023 17:18:00 -0500 Subject: [PATCH 008/213] Document -a option. --- NEWS | 3 +++ advent.adoc | 2 ++ 2 files changed, 5 insertions(+) diff --git a/NEWS b/NEWS index 2f99d6a..65c6cc5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,8 @@ = Open Adventure project news = +Repository head:: + Added BBS option for BBS door systems. + 1.13: 2023-02-28:: Fixed slightly buggy emission of end-of-game messages on a win. diff --git a/advent.adoc b/advent.adoc index fa69ddc..d2b60d6 100644 --- a/advent.adoc +++ b/advent.adoc @@ -42,6 +42,8 @@ There have been no gameplay changes. -r:: Restore game from specified file +-a:: Load from specified file and autosave to it on exit or signal. + -o:: Old-style. Restores original interface, no prompt or line editing. Also ignores new-school one-letter commands l, x, g, z, i. Also case-smashes and truncates unrecognized text when echoed. From 643656fcc35838d3e8b6e819fa8b1f9c4adda88c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 4 Mar 2023 19:48:17 -0500 Subject: [PATCH 009/213] Complain to user on save/resume.restore when it's disabled. --- adventure.yaml | 1 + notes.adoc | 4 ++++ saveresume.c | 15 +++++++++------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/adventure.yaml b/adventure.yaml index cb577bd..32c7d8b 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -3173,6 +3173,7 @@ arbitrary_messages: !!omap To achieve the next higher rating would be a neat trick! Congratulations!! - OFF_SCALE: 'You just went off my scale!!' +- SAVERESUME_DISABLED: 'Save abd resume are disabled.' - RESUME_HELP: 'To resume your Adventure, start a new game and then say "RESUME".' # This message is not currently used #- TABLE_SPACE: |- diff --git a/notes.adoc b/notes.adoc index bc8db58..9dfc9cd 100644 --- a/notes.adoc +++ b/notes.adoc @@ -126,6 +126,10 @@ tamper-proofing saves when everyone has the source code. A -r command-line option has been added. When it is given (with a file path argument) it is functionally equivalent to a RESTORE command. +The game can be built in a mode that entirely disables save/resume, or +thart autosaves only on a termination signal (for use in BBS doort +systems). There is a new nmessage to inform the user about this. + == Translation == The 2.5 code was a mechanical C translation of a FORTRAN original. diff --git a/saveresume.c b/saveresume.c index ad9f844..d668543 100644 --- a/saveresume.c +++ b/saveresume.c @@ -60,10 +60,11 @@ int suspend(void) /* Suspend. Offer to save things in a file, but charging * some points (so can't win by using saved games to retry * battles or to start over after learning zzword). - * If ADVENT_NOSAVE is defined, do nothing instead. */ + * If ADVENT_NOSAVE is defined, gripe instead. */ #if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE - return GO_UNKNOWN; + rspeak(SAVERESUME_DISABLED) + return GO_TOP; #endif FILE *fp = NULL; @@ -91,10 +92,11 @@ int suspend(void) int resume(void) { /* Resume. Read a suspended game back from a file. - * If ADVENT_NOSAVE is defined, do nothing instead. */ + * If ADVENT_NOSAVE is defined, gripe instead. */ #if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE - return GO_UNKNOWN; + rspeak(SAVERESUME_DISABLED) + return GO_TOP; #endif FILE *fp = NULL; @@ -125,9 +127,10 @@ int restore(FILE* fp) { /* Read and restore game state from file, assuming * sane initial state. - * If ADVENT_NOSAVE is defined, do nothing instead. */ + * If ADVENT_NOSAVE is defined, gripe instead. */ #ifdef ADVENT_NOSAVE - return GO_UNKNOWN; + rspeak(SAVERESUME_DISABLED) + return GO_TOP; #endif IGNORE(fread(&save, sizeof(struct save_t), 1, fp)); From a01c08385c0ce32976b94a10019576c348aa53bc Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 4 Mar 2023 19:58:57 -0500 Subject: [PATCH 010/213] Prevent a spurious coverage error. --- tests/coverage_dungeon.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index c2ccabe..288b1c0 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -7,9 +7,10 @@ various strings contained are present within the test check files. The default HTML output is appropriate for use with Gitlab CI. You can override it with a command-line argument. -The DANGLING list is for actions that should be considered always found -even if the checkfile search doesn't find them. Typically this will because -they emit a templated message that can't be regression-tested by equality. +The DANGLING lists are for actions and messages that should be +considered always found even if the checkfile search doesn't find them. +Typically this will because an action emit a templated message that +can't be regression-tested by equality. """ # pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,redefined-outer-name @@ -23,7 +24,8 @@ TEST_DIR = "." YAML_PATH = "../adventure.yaml" HTML_TEMPLATE_PATH = "../templates/coverage_dungeon.html.tpl" DEFAULT_HTML_OUTPUT_PATH = "../coverage/adventure.yaml.html" -DANGLING = ["ACT_VERSION"] +DANGLING_ACTIONS = ["ACT_VERSION"] +DANGLING_MESSAGES = ["SAVERESUME_DISABLED"] STDOUT_REPORT_CATEGORY = " {name:.<19}: {percent:5.1f}% covered ({covered} of {total})\n" @@ -156,7 +158,7 @@ def arb_coverage(arb_msgs, text, report): if name not in report["messages"]: report["messages"][name] = {"covered" : False} report["total"] += 1 - if not report["messages"][name]["covered"] and search(message, text): + if not report["messages"][name]["covered"] and search(message, text) or name in DANGLING_MESSAGES: report["messages"][name]["covered"] = True report["covered"] += 1 @@ -166,7 +168,7 @@ def actions_coverage(items, text, report): if name not in report["messages"]: report["messages"][name] = {"covered" : False} report["total"] += 1 - if not report["messages"][name]["covered"] and (search(item["message"], text) or name in DANGLING): + if not report["messages"][name]["covered"] and (search(item["message"], text) or name in DANGLING_ACTIONS): report["messages"][name]["covered"] = True report["covered"] += 1 From 1121bb8aa58c23e9ed872b23ec831247fc867b76 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 4 Mar 2023 20:16:07 -0500 Subject: [PATCH 011/213] NEWS and notes.adoc update. --- NEWS | 4 ++-- notes.adoc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 65c6cc5..bed01bc 100644 --- a/NEWS +++ b/NEWS @@ -1,13 +1,13 @@ = Open Adventure project news = Repository head:: - Added BBS option for BBS door systems. + Added -a option for BBS door systems. 1.13: 2023-02-28:: Fixed slightly buggy emission of end-of-game messages on a win. 1.12: 2023-02-06:: - The bug and todo list has been cleared. + The bug and todo list has been cleared; project declared finished. Correctness has been systematically tested against the 1995 code. Typo fixes and documentation polishing. diff --git a/notes.adoc b/notes.adoc index 9dfc9cd..9a96003 100644 --- a/notes.adoc +++ b/notes.adoc @@ -196,7 +196,7 @@ messages with the objects that conceptually own them. We consider this project finished. All issues and TODOs have been cleared, behavior has been carefully checked against original ADVENT, no future demand for new features is expected, and the test suite has -100% code coverage. If the toolchain bit-rots out from under it, -we will fix that. +100% code coverage. If new bugs appear the toolchain bit-rots out +from under underneath, we will fix those problems. // end From 1efd1027f72e643537c8781bb1b44f9ba97c5409 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 4 Mar 2023 20:26:13 -0500 Subject: [PATCH 012/213] Add test for interspersed non-motion command amidst magic words. --- tests/foobug.chk | 1702 ++++++++++++++++++++++++++++++++++++++++++++++ tests/foobug.log | 296 ++++++++ 2 files changed, 1998 insertions(+) create mode 100644 tests/foobug.chk create mode 100644 tests/foobug.log diff --git a/tests/foobug.chk b/tests/foobug.chk new file mode 100644 index 0000000..ead29b1 --- /dev/null +++ b/tests/foobug.chk @@ -0,0 +1,1702 @@ + +Welcome to Adventure!! Would you like instructions? + +> no + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed 1318612053 + +Seed set to 1318612053 + +You're in front of building. + +> e + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plove + +>>Foof!<< + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +There is an emerald here the size of a plover's egg! + +> get emerald + +OK + +> w + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> drop emerald + +OK + +> e + +You're in Plover Room. + +> ne + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> get pyramid + +OK + +> s + +You're in Plover Room. + +> plove + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> drop pyramid + +OK + +> get lamp + +OK + +> get water + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There are bars of silver here! + +> d + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> bedquilt + +You are in Bedquilt, a long east/west passage with holes everywhere. +To explore at random select north, south, up, or down. + +> w + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +> e + +You are in the Soft Room. The walls are covered with heavy curtains, +the floor with a thick pile carpet. Moss covers the ceiling. + +A small velvet pillow lies on the floor. + +> take pillow + +OK + +> w + +You're in Swiss Cheese Room. + +> oriental + +This is the Oriental Room. Ancient oriental cave drawings cover the +walls. A gently sloping passage leads upward to the north, another +passage leads se, and a hands and knees crawl leads west. + +There is a delicate, precious, ming vase here! + +> take vase + +OK + +> n + +You are following a wide path around the outer edge of a large cavern. +Far below, through a heavy white mist, strange splashing noises can be +heard. The mist rises up through a fissure in the ceiling. The path +exits to the south and west. + +> w + +You are in an alcove. A small nw path seems to widen after a short +distance. An extremely tight tunnel leads east. It looks like a very +tight squeeze. An eerie light can be seen at the other end. + +There is an emerald here the size of a plover's egg! + +> take emerald + +OK + +> nw + +You're in misty cavern. + +> s + +You're in Oriental Room. + +> se + +You're in Swiss Cheese Room. + +> w + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +> w + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a tiny little plant in the pit, murmuring "water, water, ..." + +> water plant + +The plant spurts into furious growth for a few seconds. + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> u + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> e + +You're at east end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You are at the bottom of the eastern pit in the Twopit Room. There is +a small pool of oil in one corner of the pit. + +> fill bottle + +Your bottle is now full of oil. + +> u + +You're at east end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> e + +You're in Swiss Cheese Room. + +> ne + +You're in Bedquilt. + +> e + +You are at a complex junction. A low hands and knees passage from the +north joins a higher crawl from the east to make a walking passage +going west. There is also a large room above. The air is damp here. + +> u + +You are in a large room full of dusty rocks. There is a big hole in +the floor. There are cracks everywhere, and a passage leading east. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> n + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop pillow + +OK + +> drop vase + +The vase is now resting, delicately, on a velvet pillow. + +> drop bottle + +OK + +> drop emerald + +OK + +> xyzzy + +>>Foof!<< + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> e + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> take cage + +OK + +> pit + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> drop rod + +OK + +> e + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> take bird + +OK + +> w + +You're at top of small pit. + +A three foot black rod with a rusty star on an end lies nearby. + +Rough stone steps lead down the pit. + +> drop bird + +OK + +> take rod + +OK + +> wave rod + +The bird flies about agitatedly for a moment, then disappears through +the crack. It reappears shortly, carrying in its beak a jade +necklace, which it drops at your feet. + +> take necklace + +OK + +> drop rod + +OK + +> take bird + +OK + +> d + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> s + +This is a low room with a crude note on the wall. The note says, +"You won't get it up the steps". + +There is a large sparkling nugget of gold here! + +> take nugget + +OK + +> n + +You're in Hall of Mists. + +> n + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A huge green fierce snake bars the way! + +> drop bird + +The little bird attacks the green snake, and in an astounding flurry +drives the snake away. + +> take bird + +OK + +> sw + +You are in a secret canyon which here runs e/w. It crosses over a +very tight canyon 15 feet below. If you go down you may not be able +to get back up. + +> w + +You are in a secret canyon which exits to the north and east. + +A huge green fierce dragon bars the way! + +The dragon is sprawled out on a Persian rug!! + +> kill dragon + +With what? Your bare hands? + +> yes + +Congratulations! You have just vanquished a dragon with your bare +hands! (Unbelievable, isn't it?) + +You are in a secret canyon which exits to the north and east. + +There is a Persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. + +> drink blood + +Your head buzzes strangely for a moment. + +> take rug + +OK + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +You're in Hall of Mt King. + +> n + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> take bars + +OK + +> n + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +There is an emerald here the size of a plover's egg! + +There is a bottle of oil here. + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop cage + +OK + +> drop necklace + +OK + +> drop nugget + +OK + +> drop bars + +OK + +> drop rug + +OK + +> xyzzy + +>>Foof!<< + +You're in debris room. + +> pit + +You're at top of small pit. + +A three foot black rod with a rusty star on an end lies nearby. + +Rough stone steps lead down the pit. + +> take rod + +OK + +> d + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +A crystal bridge now spans the fissure. + +> w + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> take diamonds + +OK + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of the Hall of Mists. A low wide crawl +continues west and another goes north. To the south is a little +passage 6 feet off the floor. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the east end of a very long hall apparently without side +chambers. To the east a low wide crawl slants up. To the north a +round two foot hole slants down. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of a very long featureless hall. The hall +joins up with a narrow north/south passage. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisting little passages, all different. + +> e + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisting passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +Dead end + +There is a massive and somewhat battered vending machine here. The +instructions on it read: "Drop coins here to receive fresh batteries." + +> hit machine + +As you strike the vending machine, it pivots backward along with a +section of wall, revealing a dark passage leading south. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a long, rough-hewn, north/south corridor. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a large chamber with passages to the west and north. + +A formidable ogre bars the northern exit. + +> kill ogre + +The ogre, who despite his bulk is quite agile, easily dodges your +attack. He seems almost amused by your puny effort. + +One sharp nasty knife is thrown at you! + +The ogre, distracted by your rush, is struck by the knife. With a +blood-curdling yell he turns and bounds after the dwarf, who flees +in panic. You are left alone in the room. + +> n + +You are in the ogre's storeroom. The only exit is to the south. + +There is an enormous ruby here! + +> take ruby + +OK + +> s + +You are in a large chamber with passages to the west and north. + +> w + +You are in a long, rough-hewn, north/south corridor. + +> n + +Dead end + +There is a massive vending machine here, swung back to reveal a +southward passage. + +> n + +You are in a little maze of twisting passages, all different. + +> sw + +You are in a maze of twisting little passages, all different. + +> w + +You are in a maze of twisty little passages, all different. + +> d + +You're at west end of long hall. + +> n + +You are at a crossover of a high n/s passage and a low e/w one. + +> e + +You are in the west side chamber of the Hall of the Mountain King. +A passage continues west and up here. + +There are many coins here! + +> take coins + +OK + +> e + +You're in Hall of Mt King. + +> s + +You are in the south side chamber. + +There is precious jewelry here! + +> take jewelry + +OK + +> n + +You're in Hall of Mt King. + +> e + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're at west end of Hall of Mists. + +> s + +You are in a maze of twisty little passages, all alike. + +> e + +Out from the shadows behind you pounces a bearded pirate! "Har, har," +he chortles, "I'll just take all this booty and hide it away with me +chest deep in the maze!" He snatches your treasure and vanishes into +the gloom. + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> n + +You are in a maze of twisty little passages, all alike. + +> e + +You are on the brink of a thirty foot pit with a massive orange column +down one wall. You could climb down here but you could not get back +up. The maze continues at this level. + +> e + +You are in a maze of twisty little passages, all alike. + +> nw + +Dead end + +There is an enormous ruby here! + +There are many coins here! + +There is precious jewelry here! + +There are diamonds here! + +The pirate's treasure chest is here! + +> drop rod + +OK + +> take jewelry + +OK + +> take chest + +OK + +> take ruby + +OK + +> take diamonds + +OK + +> take coins + +OK + +> se + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all alike. + +> w + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all alike. + +> s + +There is a threatening little dwarf in the room with you! + +You're at brink of pit. + +> d + +You're in bird chamber. + +> debris + +You're in debris room. + +> xyzzy + +>>Foof!<< + +You're inside building. + +There is a Persian rug spread out on the floor! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a small wicker cage discarded nearby. + +There is a little bird in the cage. + +There is an emerald here the size of a plover's egg! + +There is a bottle of oil here. + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> off + +Your lamp is now off. + +> drop coins + +OK + +> drop diamonds + +OK + +> drop jewelry + +OK + +> drop chest + +OK + +> drop lamp + +OK + +> take rug + +OK + +> take emerald + +OK + +> take cage + +OK + +> take bottle + +OK + +> w + +You're in front of building. + +> s + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> w + +You are wandering aimlessly through the forest. + +> drop bird + +OK + +> listen + +The bird is singing to you in gratitude for your having returned it to +its home. In return, it informs you of a magic word which it thinks +you may find useful somewhere near the Hall of Mists. The magic word +changes frequently, but for now the bird believes it is "N'BEH". You +thank the bird for this information, and it flies off into the forest. + +> drop cage + +OK + +> n + +You are wandering aimlessly through the forest. + +Your keen eye spots a severed leporine appendage lying on the ground. + +> take appendage + +OK + +> n + +You are wandering aimlessly through the forest. + +> e + +You are wandering aimlessly through the forest. + +> n + +You are wandering aimlessly through the forest. + +> n + +The forest thins out here to reveal a steep cliff. There is no way +down, but a small ledge can be seen to the west across the chasm. + +A small urn is embedded in the rock. + +> fill urn + +Your bottle is now empty and the urn is full of oil. + +> light urn + +The urn is now lit. + +> rub urn + +As you rub the urn, there is a flash of light and a genie appears. +His aspect is stern as he advises: "One who wouldst traffic in +precious stones must first learn to recognize the signals thereof." +He wrests the urn from the stone, leaving a small cavity. Turning to +face you again, he fixes you with a steely eye and intones: "Caution!" +Genie and urn vanish in a cloud of amber smoke. The smoke condenses +to form a rare amber gemstone, resting in the cavity in the rock. + +> drop rug + +OK + +> take amber + +OK + +> drop emerald + +The gem fits easily into the cavity. + +The Persian rug stiffens and rises a foot or so off the ground. + +> fly + +You board the Persian rug, which promptly whisks you across the chasm. +You have time for a fleeting glimpse of a two thousand foot drop to a +mighty river; then you find yourself on the other side. + +You are on a small ledge on one face of a sheer cliff. There are no +paths away from the ledge. Across the chasm is a small clearing +surrounded by forest. + +There is a Persian rug here, hovering in mid-air! + +A brilliant blue star sapphire is here! + +> take sapphire + +OK + +> fly + +The rug ferries you back across the chasm. + +You're at cliff. + +There is an emerald resting in a small cavity in the rock! + +There is a Persian rug here, hovering in mid-air! + +> take emerald + +OK + +> drop ruby + +The gem fits easily into the cavity. + +The Persian rug settles gently to the ground. + +> take rug + +OK + +> take ruby + +OK + +> e + +You are wandering aimlessly through the forest. + +> s + +You are wandering aimlessly through the forest. + +> e + +You have walked up a hill, still in the forest. The road slopes back +down the other side of the hill. There is a building in the distance. + +> e + +You're in front of building. + +> e + +You are inside a building, a well house for a large spring. + +There is a shiny brass lamp nearby. + +The pirate's treasure chest is here! + +There is precious jewelry here! + +There are diamonds here! + +There are many coins here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop emerald + +OK + +> drop ruby + +OK + +> drop amber + +OK + +> drop rug + +OK + +> drop sapphire + +OK + +> fill bottle + +Your bottle is now full of water. + +> take lamp + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +There is a little axe here. + +> s + +You're in n/s passage above e/w passage. + +> s + +You're in Hall of Mt King. + +> sw + +You're in secret e/w canyon above tight canyon. + +> w + +You are in a secret canyon which exits to the north and east. + +The body of a huge green dead dragon is lying off to one side. + +> n + +You are in a secret n/s canyon above a large room. + +> reservoir + +You are at the edge of a large underground reservoir. An opaque cloud +of white mist fills the room and rises rapidly upward. The lake is +fed by a stream, which tumbles out of a hole in the wall about 10 feet +overhead and splashes noisily into the water somewhere within the +mist. There is a passage going back toward the south. + +> n'beh + +The waters have parted to form a narrow path across the reservoir. + +> n + +You are walking across the bottom of the reservoir. Walls of water +rear up on either side. The roar of the water cascading past is +nearly deafening, and the mist is so thick you can barely see. + +> n + +You are at the northern edge of the reservoir. A northwest passage +leads sharply up from here. + +The waters have parted to form a narrow path across the reservoir. + +> u + +You are scrambling along a treacherously steep, rocky passage. + +> u + +You are on a very steep incline, which widens at it goes upward. + +> u + +You are at the base of a nearly vertical cliff. There are some +slim footholds which would enable you to climb up, but it looks +extremely dangerous. Here at the base of the cliff lie the remains +of several earlier adventurers who apparently failed to make it. + +> u + +You are climbing along a nearly vertical cliff. + +> u + +Just as you reach the top, your foot slips on a loose rock and you +make one last desperate grab. Your luck holds, as does your grip. +With an enormous heave, you lift yourself to the ledge above. + +You are on a small ledge at the top of a nearly vertical cliff. +There is a low crawl leading off to the northeast. + +> ne + +You have reached a dead end. + +There is a richly-carved ebony statuette here! + +> take statuette + +OK + +> sw + +You're at top of cliff. + +> d + +You are climbing along a nearly vertical cliff. + +> d + +You're at base of cliff. + +> d + +You are on a very steep incline, which widens at it goes upward. + +> d + +You are scrambling along a treacherously steep, rocky passage. + +> d + +You're north of reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You're at bottom of reservoir. + +> s + +You're at reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You are in a north/south canyon about 25 feet across. The floor is +covered by white mist seeping in from the north. The walls extend +upward for well over 100 feet. Suspended from some unseen point far +above you, an enormous two-sided mirror is hanging parallel to and +midway between the canyon walls. (The mirror is obviously provided +for the use of the dwarves who, as you know, are extremely vain.) A +small window can be seen in either wall, some fifty feet up. + +> s + +You are in a secret n/s canyon above a large room. + +> d + +You are in a large low circular chamber whose floor is an immense slab +fallen from the ceiling (Slab Room). East and west there once were +large passages, but they are now filled with boulders. Low small +passages go north and south, and the south one quickly bends west +around the boulders. + +> s + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> water plant + +The plant grows explosively, almost filling the bottom of the pit. + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> u + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> e + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in east pit. + +> fill bottle + +Your bottle is now full of oil. + +> u + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You are in a long, narrow corridor stretching out of sight to the +west. At the eastern end is a hole through which you can see a +profusion of leaves. + +> w + +You are in the Giant Room. The ceiling here is too high up for your +lamp to show it. Cavernous passages lead east, north, and south. On +the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. + +There is a large nest here, full of golden eggs! + +> take eggs + +OK + +> n + +You are at one end of an immense north/south passage. + +The way north is barred by a massive, rusty, iron door. + +> oil door + +The oil has freed up the hinges so that the door will now move, +although it requires some effort. + +> drop bottle + +OK + +> n + +You are in a magnificent cavern with a rushing stream, which cascades +over a sparkling waterfall into a roaring whirlpool which disappears +through a hole in the floor. Passages exit to the south and west. + +There is a jewel-encrusted trident here! + +> take trident + +OK + +> w + +You are at the top of a steep incline above a large room. You could +climb down here, but you would not be able to climb up. There is a +passage leading back to the north. + +> d + +You are in a large low room. Crawls lead north, se, and sw. + +> bedquilt + +You're in Bedquilt. + +> e + +You're at complex junction. + +> n + +You're in a large room carved out of sedimentary rock. The floor and +walls are littered with bits of shells embedded in the stone. A +shallow passage proceeds downward, and a somewhat steeper one leads +up. A low hands and knees passage enters from the south. + +There is an enormous clam here with its shell tightly closed. + +> open clam + +A glistening pearl falls out of the clam and rolls away. Goodness, +this must really be an oyster. (I never was very good at identifying +bivalves.) Whatever it is, it has now snapped shut again. + +> d + +You are in a long sloping corridor with ragged sharp walls. + +> d + +You are in a cul-de-sac about eight feet across. + +Off to one side lies a glistening pearl! + +> take pearl + +OK + +> shell + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> s + +You're at complex junction. + +> u + +You're in dusty rock room. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +A brilliant blue star sapphire is here! + +There is a Persian rug spread out on the floor! + +There is a rare amber gemstone here! + +There is an enormous ruby here! + +There is an emerald here the size of a plover's egg! + +The pirate's treasure chest is here! + +There is precious jewelry here! + +There are diamonds here! + +There are many coins here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop trident + +OK + +> drop pearl + +OK + +> drop statuette + +OK + +> drop appendage + +OK + +> take keys + +OK + +> take food + +OK + +> plugh + +>>Foof!<< + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +There is a little axe here. + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> d + +You're in dirty passage. + +> bedquilt + +You're in Bedquilt. + +> w + +You're in Swiss Cheese Room. + +> oriental + +You're in Oriental Room. + +> w + +You're in large low room. + +> sw + +You are in a long winding corridor sloping out of sight in both +directions. + +> u + +You are on one side of a large, deep chasm. A heavy white mist rising +up from below obscures all view of the far side. A sw path leads away +from the chasm into a winding corridor. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> throw eggs + +The troll catches your treasure and scurries away out of sight. + +> ne + +You are on the far side of the chasm. A ne path leads away from the +chasm on this side. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> barren + +You are standing at the entrance to a large, barren room. A notice +above the entrance reads: "Caution! Bear in room!" + +> e + +You are inside a barren room. The center of the room is completely +empty except for some dust. Marks in the dust lead away toward the +far end of the room. The only exit is the way you came in. + +There is a ferocious cave bear eyeing you from the far end of the room! + +The bear is locked to the wall with a golden chain! + +> throw food + +The bear eagerly wolfs down your food, after which he seems to calm +down considerably and even becomes rather friendly. + +> unlock chain + +The chain is now unlocked. + +> take chain + +OK + +> take bear + +OK + +> fork + +You are being followed by a very large, tame bear. + +The path forks here. The left fork leads northeast. A dull rumbling +seems to get louder in that direction. The right fork leads southeast +down a gentle slope. The main corridor enters from the west. + +> ne + +You are being followed by a very large, tame bear. + +The walls are quite warm here. From the north can be heard a steady +roar, so loud that the entire cave seems to be trembling. Another +passage leads south, and a low crawl goes east. + +> fee + +OK + +> fie + +OK + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +You are being followed by a very large, tame bear. + +The walls are quite warm here. From the north can be heard a steady +roar, so loud that the entire cave seems to be trembling. Another +passage leads south, and a low crawl goes east. + +> foe + +OK + +> foo + +Done! + + +You scored 311 out of a possible 430, using 291 turns. + +You have reached "Junior Master" status. + +To achieve the next higher rating, you need 10 more points. diff --git a/tests/foobug.log b/tests/foobug.log new file mode 100644 index 0000000..49c25df --- /dev/null +++ b/tests/foobug.log @@ -0,0 +1,296 @@ +## Test interpersing commands amidst magic words +# Check for "Done" or "Nothing happens." in game output. +no +seed 1318612053 +e +plugh +plove +get emerald +w +drop emerald +e +ne +get pyramid +s +plove +plugh +drop pyramid +get lamp +get water +plugh +on +s +d +bedquilt +w +e +take pillow +w +oriental +take vase +n +w +take emerald +nw +s +se +w +w +d +water plant +u +e +d +fill bottle +u +e +ne +e +u +e +u +n +plugh +drop pillow +drop vase +drop bottle +drop emerald +xyzzy +take rod +e +take cage +pit +drop rod +e +take bird +w +drop bird +take rod +wave rod +take necklace +drop rod +take bird +d +s +take nugget +n +n +drop bird +take bird +sw +w +kill dragon +yes +drink blood +take rug +e +e +n +take bars +n +plugh +drop cage +drop necklace +drop nugget +drop bars +drop rug +xyzzy +pit +take rod +d +w +wave rod +w +take diamonds +w +w +w +s +s +e +s +hit machine +s +s +kill ogre +n +take ruby +s +w +n +n +sw +w +d +n +e +take coins +e +s +take jewelry +n +e +w +w +w +s +e +s +s +s +n +e +e +nw +drop rod +take jewelry +take chest +take ruby +take diamonds +take coins +se +w +s +d +debris +xyzzy +off +drop coins +drop diamonds +drop jewelry +drop chest +drop lamp +take rug +take emerald +take cage +take bottle +w +s +w +drop bird +listen +drop cage +n +take appendage +n +e +n +n +fill urn +light urn +rub urn +drop rug +take amber +drop emerald +fly +take sapphire +fly +take emerald +drop ruby +take rug +take ruby +e +s +e +e +e +drop emerald +drop ruby +drop amber +drop rug +drop sapphire +fill bottle +take lamp +plugh +on +s +s +sw +w +n +reservoir +n'beh +n +n +u +u +u +u +u +ne +take statuette +sw +d +d +d +d +d +s +s +s +s +d +s +d +water plant +u +e +d +fill bottle +u +w +d +climb +w +take eggs +n +oil door +drop bottle +n +take trident +w +d +bedquilt +e +n +open clam +d +d +take pearl +shell +s +u +e +u +n +plugh +drop trident +drop pearl +drop statuette +drop appendage +take keys +take food +plugh +s +d +bedquilt +w +oriental +w +sw +u +throw eggs +ne +barren +e +throw food +unlock chain +take chain +take bear +fork +ne +fee +fie +look +foe +foo From 12d39ef72b25fc8137818718782934e01da88c9c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 6 Mar 2023 12:23:40 -0500 Subject: [PATCH 013/213] Improve Makefile recipe for coverage testing. --- Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 38139de..eebc68c 100644 --- a/Makefile +++ b/Makefile @@ -65,10 +65,12 @@ cheat: $(CHEAT_OBJS) dungeon.o check: advent cheat cd tests; $(MAKE) --quiet +# Requires gcov, lcov, libasan6, and libubsan1 +# The last two are Ubuntu names, might vary onb other distributions. # After this, run your browser on coverage/open-adventure/index.html # to see coverage results. Browse coverage/adventure.yaml.html # to see symbol coverage over the YAML file. -coverage: debug +coverage: clean debug cd tests; $(MAKE) coverage --quiet .SUFFIXES: .adoc .html .6 @@ -129,6 +131,11 @@ linty: CCFLAGS += -Winit-self linty: CCFLAGS += -Wpointer-arith linty: advent cheat +# These seem to be more modeern options for enabling coverage testing. +# Documenting them here in case a future version bump disables --coverage. +#debug: CCFLAGS += -ftest-coverage +#debug: CCFLAGS += -fprofile-arcs + debug: CCFLAGS += -O0 debug: CCFLAGS += --coverage debug: CCFLAGS += -ggdb From f911e4245357c9049ae3bd171922bdb33e4e8f84 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 6 Mar 2023 23:41:07 -0500 Subject: [PATCH 014/213] Eliminate some forwards. --- main.c | 263 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 130 insertions(+), 133 deletions(-) diff --git a/main.c b/main.c index c536600..94f2b45 100644 --- a/main.c +++ b/main.c @@ -47,139 +47,6 @@ static void sig_handler(int signo) } // LCOV_EXCL_STOP -/* - * MAIN PROGRAM - * - * Adventure (rev 2: 20 treasures) - * History: Original idea & 5-treasure version (adventures) by Willie Crowther - * 15-treasure version (adventure) by Don Woods, April-June 1977 - * 20-treasure version (rev 2) by Don Woods, August 1978 - * Errata fixed: 78/12/25 - * Revived 2017 as Open Adventure. - */ - -static bool do_command(void); -static bool do_move(void); - -int main(int argc, char *argv[]) -{ - int ch; - - /* Options. */ - -#if defined ADVENT_AUTOSAVE - const char* opts = "l:oa:"; - const char* usage = "Usage: %s [-l logfilename] [-o] [-a filename] [script...]\n"; - FILE *rfp = NULL; - const char* autosave_filename = NULL; -#elif !defined ADVENT_NOSAVE - const char* opts = "l:or:"; - const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n"; - FILE *rfp = NULL; -#else - const char* opts = "l:o"; - const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n"; -#endif - while ((ch = getopt(argc, argv, opts)) != EOF) { - switch (ch) { - case 'l': - settings.logfp = fopen(optarg, "w"); - if (settings.logfp == NULL) - fprintf(stderr, - "advent: can't open logfile %s for write\n", - optarg); - signal(SIGINT, sig_handler); - break; - case 'o': - settings.oldstyle = true; - settings.prompt = false; - break; -#ifdef ADVENT_AUTOSAVE - case 'a': - rfp = fopen(optarg, READ_MODE); - autosave_filename = optarg; - signal(SIGHUP, sig_handler); - signal(SIGTERM, sig_handler); - break; -#elif !defined ADVENT_NOSAVE - case 'r': - rfp = fopen(optarg, "r"); - if (rfp == NULL) - fprintf(stderr, - "advent: can't open save file %s for read\n", - optarg); - break; -#endif - default: - fprintf(stderr, - usage, argv[0]); - fprintf(stderr, - " -l create a log file of your game named as specified'\n"); - fprintf(stderr, - " -o 'oldstyle' (no prompt, no command editing, displays 'Initialising...')\n"); -#if defined ADVENT_AUTOSAVE - fprintf(stderr, - " -a automatic save/restore from specified saved game file\n"); -#elif !defined ADVENT_NOSAVE - fprintf(stderr, - " -r restore from specified saved game file\n"); -#endif - exit(EXIT_FAILURE); - break; - } - } - - /* copy invocation line part after switches */ - settings.argc = argc - optind; - settings.argv = argv + optind; - settings.optind = 0; - - /* Initialize game variables */ - int seedval = initialise(); - -#if !defined ADVENT_NOSAVE - if (!rfp) { - game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); - if (game.novice) - game.limit = NOVICELIMIT; - } else { - restore(rfp); -#if defined ADVENT_AUTOSAVE - score(scoregame); -#endif - } -#if defined ADVENT_AUTOSAVE - if (autosave_filename != NULL) { - if ((autosave_fp = fopen(autosave_filename, WRITE_MODE)) == NULL) { - perror(autosave_filename); - return EXIT_FAILURE; - } - autosave(); - } -#endif -#else - game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); - if (game.novice) - game.limit = NOVICELIMIT; -#endif - - if (settings.logfp) - fprintf(settings.logfp, "seed %d\n", seedval); - - /* interpret commands until EOF or interrupt */ - for (;;) { - // if we're supposed to move, move - if (!do_move()) - continue; - - // get command - if (!do_command()) - break; - } - /* show score and exit */ - terminate(quitgame); -} - char *myreadline(const char *prompt) { /* @@ -1365,4 +1232,134 @@ static bool do_command() return true; } +/* + * MAIN PROGRAM + * + * Adventure (rev 2: 20 treasures) + * History: Original idea & 5-treasure version (adventures) by Willie Crowther + * 15-treasure version (adventure) by Don Woods, April-June 1977 + * 20-treasure version (rev 2) by Don Woods, August 1978 + * Errata fixed: 78/12/25 + * Revived 2017 as Open Adventure. + */ + +int main(int argc, char *argv[]) +{ + int ch; + + /* Options. */ + +#if defined ADVENT_AUTOSAVE + const char* opts = "l:oa:"; + const char* usage = "Usage: %s [-l logfilename] [-o] [-a filename] [script...]\n"; + FILE *rfp = NULL; + const char* autosave_filename = NULL; +#elif !defined ADVENT_NOSAVE + const char* opts = "l:or:"; + const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n"; + FILE *rfp = NULL; +#else + const char* opts = "l:o"; + const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n"; +#endif + while ((ch = getopt(argc, argv, opts)) != EOF) { + switch (ch) { + case 'l': + settings.logfp = fopen(optarg, "w"); + if (settings.logfp == NULL) + fprintf(stderr, + "advent: can't open logfile %s for write\n", + optarg); + signal(SIGINT, sig_handler); + break; + case 'o': + settings.oldstyle = true; + settings.prompt = false; + break; +#ifdef ADVENT_AUTOSAVE + case 'a': + rfp = fopen(optarg, READ_MODE); + autosave_filename = optarg; + signal(SIGHUP, sig_handler); + signal(SIGTERM, sig_handler); + break; +#elif !defined ADVENT_NOSAVE + case 'r': + rfp = fopen(optarg, "r"); + if (rfp == NULL) + fprintf(stderr, + "advent: can't open save file %s for read\n", + optarg); + break; +#endif + default: + fprintf(stderr, + usage, argv[0]); + fprintf(stderr, + " -l create a log file of your game named as specified'\n"); + fprintf(stderr, + " -o 'oldstyle' (no prompt, no command editing, displays 'Initialising...')\n"); +#if defined ADVENT_AUTOSAVE + fprintf(stderr, + " -a automatic save/restore from specified saved game file\n"); +#elif !defined ADVENT_NOSAVE + fprintf(stderr, + " -r restore from specified saved game file\n"); +#endif + exit(EXIT_FAILURE); + break; + } + } + + /* copy invocation line part after switches */ + settings.argc = argc - optind; + settings.argv = argv + optind; + settings.optind = 0; + + /* Initialize game variables */ + int seedval = initialise(); + +#if !defined ADVENT_NOSAVE + if (!rfp) { + game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); + if (game.novice) + game.limit = NOVICELIMIT; + } else { + restore(rfp); +#if defined ADVENT_AUTOSAVE + score(scoregame); +#endif + } +#if defined ADVENT_AUTOSAVE + if (autosave_filename != NULL) { + if ((autosave_fp = fopen(autosave_filename, WRITE_MODE)) == NULL) { + perror(autosave_filename); + return EXIT_FAILURE; + } + autosave(); + } +#endif +#else + game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); + if (game.novice) + game.limit = NOVICELIMIT; +#endif + + if (settings.logfp) + fprintf(settings.logfp, "seed %d\n", seedval); + + /* interpret commands until EOF or interrupt */ + for (;;) { + // if we're supposed to move, move + if (!do_move()) + continue; + + // get command + if (!do_command()) + break; + } + /* show score and exit */ + terminate(quitgame); +} + /* end */ From e1ce7d6b6a02e19f0a15ae8fc61a44060843dcc4 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 6 Mar 2023 23:51:52 -0500 Subject: [PATCH 015/213] Documentation polishing. --- NEWS | 3 ++- advent.adoc | 21 ++++++++++++--------- notes.adoc | 7 ++++++- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index bed01bc..8e588fa 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ Repository head:: Added -a option for BBS door systems. + -o reverts to the old message on some failed magic words. 1.13: 2023-02-28:: Fixed slightly buggy emission of end-of-game messages on a win. @@ -17,7 +18,7 @@ Repository head:: 1.10: 2022-04-06:: Fixed a bug that manifested after two "fly rug" commands - third one fails. - Fix some giltches in processing fee fie foe foo. + Fix some glitches in processing fee fie foe foo. Correct some object start states and reading-related glitches in the endgame. 1.9: 2020-08-27:: diff --git a/advent.adoc b/advent.adoc index d2b60d6..6257e6c 100644 --- a/advent.adoc +++ b/advent.adoc @@ -8,7 +8,7 @@ advent - Colossal Cave Adventure *advent* [-l logfile] [-o] [-r savefile] [script...] == DESCRIPTION == -The original Colossal Cave Adventure from 1976-77 was the origin of all +The original Colossal Cave Adventure from 1976-1977 was the origin of all later text adventures, dungeon-crawl (computer) games, and computer-hosted roleplaying games. @@ -18,19 +18,21 @@ adventure". To learn more about the changes since the 350-point original, type 'news' at the command prompt. There is an 'adventure' in the BSD games package that is a C port by -Jim Gillogly of the 1976 ancestor of this game. To avoid a name +Jim Gillogly of the Don Woods's 1977 version of this game. To avoid a name collision, this game builds as 'advent', reflecting the fact that the PDP-10 on which the game originally ran limited filenames to 6 characters. This version is released as open source with the permission and encouragement of the original authors. -Unlike the original, this version supports use of your arrow keys to edit -your command line in place. Basic Emacs keystrokes are supported, and -your up/down arrows access a command history. +Unlike the original, this version has a command prompt and supports +use of your arrow keys to edit your command line in place. Basic +Emacs keystrokes are supported, and your up/down arrows access a +command history. -Otherwise, the "version" command is about the only way to tell you're not -running Don's original. +Some minor bugs and message typos have been fixed. Otherwise, the +"version" command is almost the only way to tell you're not running +Don's 1977 version. To exit the game, type Ctrl-D (EOF). @@ -44,12 +46,13 @@ There have been no gameplay changes. -a:: Load from specified file and autosave to it on exit or signal. --o:: Old-style. Restores original interface, no prompt or line editing. +-o:: Old-style. Reverts some minor cosmetic fixes in game + messages. Restores original interface, no prompt or line editing. Also ignores new-school one-letter commands l, x, g, z, i. Also case-smashes and truncates unrecognized text when echoed. Normally, game input is taken from standard input. If script file -arguments are given, input is taken fron them instead. A script file +arguments are given, input is taken from them instead. A script file argument of '-' is taken as a directive to read from standard input. == BUGS == diff --git a/notes.adoc b/notes.adoc index 9a96003..45b3cd3 100644 --- a/notes.adoc +++ b/notes.adoc @@ -54,6 +54,7 @@ Bug fixes: * Behavior when saying the giant's magic words outside his room wasn't quite correct - the game responded as though the player were in the room ("...can't you read?"). The new message is "Nothing happens." + The -o option reverts this change. * Attempting to extinguish an unlit urn caused it to lose its oil. @@ -66,7 +67,7 @@ Bug fixes: "eying" for "eyeing". "thresholds" for "threshholds". * Under odd circumstances (dropping rug or vase outdoors) the game could - say "floor" when it should say "ground" (or "dirt", or something). + formerly say "floor" when it should say "ground" (or "dirt", or something). Bugs (accidental changes that don't seem worth the effort to fix): @@ -98,6 +99,7 @@ that random events (dwarf & pirate appearances, the bird's magic word) will be reproducible. A "version" command has been added. This has no effect on gameplay. + The text displayed by the "news" command has been updated. A -l command-line option has been added. When this is given (with a @@ -166,6 +168,9 @@ afl (American Fuzzy Lop). We've found and fixed some crashers in our new code (which occasionally uses malloc(3)), but none as yet in Don's old code (which didn't). +After version 1.11, correctness was carefully checked against the +behavior of a binary from before the big refactoring. + The code falls short of being fully modern C in the following ways: From 8d409c6b3b911746df45aed2d88db1b37232bbff Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 7 Mar 2023 07:56:04 -0500 Subject: [PATCH 016/213] Add a comment to the code that fixes the inventory-count bug. --- misc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/misc.c b/misc.c index b2ad688..d047602 100644 --- a/misc.c +++ b/misc.c @@ -617,6 +617,13 @@ void carry(obj_t object, loc_t where) return; game.place[object] = CARRIED; + /* + * Without this conditional your inventory is overcounted + * when you pick up the bird while it's caged. This fixes + * a cosmetic bug in the original. + * + * Possibly this check should be skipped whwn oldstyle is on. + */ if (object != BIRD) ++game.holdng; } @@ -641,7 +648,7 @@ void drop(obj_t object, loc_t where) if (game.place[object] == CARRIED) if (object != BIRD) /* The bird has to be weightless. This ugly hack (and the - * corresponding code in the drop function) brought to you + * corresponding code in the carry function) brought to you * by the fact that when the bird is caged, we need to be able * to either 'take bird' or 'take cage' and have the right thing * happen. From 98b95e92ee960fce037097bc64100824578bbbf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Andersson?= Date: Wed, 8 Mar 2023 18:15:51 +0100 Subject: [PATCH 017/213] Another typo fix. --- adventure.yaml | 4 ++-- cheat.c | 2 +- history.adoc | 4 ++-- make_graph.py | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/adventure.yaml b/adventure.yaml index 32c7d8b..76e6b1c 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -2755,7 +2755,7 @@ locations: !!omap You are on a small ledge at the top of a nearly vertical cliff. There is a low crawl leading off to the northeast. short: 'You''re at top of cliff.' - maptag: 'Cliftop' + maptag: 'Clifftop' conditions: {DEEP: true} travel: [ {verbs: [CLIMB, DOWN], action: [goto, LOC_CLIFFACE]}, @@ -3173,7 +3173,7 @@ arbitrary_messages: !!omap To achieve the next higher rating would be a neat trick! Congratulations!! - OFF_SCALE: 'You just went off my scale!!' -- SAVERESUME_DISABLED: 'Save abd resume are disabled.' +- SAVERESUME_DISABLED: 'Save and resume are disabled.' - RESUME_HELP: 'To resume your Adventure, start a new game and then say "RESUME".' # This message is not currently used #- TABLE_SPACE: |- diff --git a/cheat.c b/cheat.c index 92500e4..df9ab5b 100644 --- a/cheat.c +++ b/cheat.c @@ -1,7 +1,7 @@ /* * 'cheat' is a tool for generating save game files to test states that ought * not happen. It leverages chunks of advent, mostly initialize() and - * savefile(), so we know we're always outputing save files that advent + * savefile(), so we know we're always outputting save files that advent * can import. * * Copyright (c) 1977, 2005 by Will Crowther and Don Woods diff --git a/history.adoc b/history.adoc index 6f86fac..ea237e9 100644 --- a/history.adoc +++ b/history.adoc @@ -163,9 +163,9 @@ even as primitive as Adventure's. - [[[SN]]] http://www.digitalhumanities.org/dhq/vol/1/2/000009/000009.html[Digital - Humanties Quarterly] + Humanities Quarterly] -- [[[DND]]] https://en.wikipedia.org/wiki/Dnd_(video_game)[dnd (ivdeo game)] +- [[[DND]]] https://en.wikipedia.org/wiki/Dnd_(video_game)[dnd (video game)] - [[[WUMPUS]]] https://en.wikipedia.org/wiki/Hunt_the_Wumpus[Hunt The Wumpus] diff --git a/make_graph.py b/make_graph.py index b9124d6..62ac68b 100755 --- a/make_graph.py +++ b/make_graph.py @@ -5,7 +5,7 @@ usage: make-graph.py [-a] -d] [-m] [-s] Make a DOT graph of Colossal Cave. -a = emit graph of entire dungeon --d = emit graoh of mazw all different +-d = emit graph of maze all different -f = emit graph of forest locations -m = emit graph of maze all alike -s = emit graph of non-forest surface locations @@ -70,7 +70,7 @@ def roomlabel(loc): return description # A forwarder is a location that you can't actually stop in - when you go there -# it ships some message (which is the point) then shifts you to a nexr location. +# it ships some message (which is the point) then shifts you to a next location. # A forwarder has a zero-length array of notion verbs in its travel section. # # Here is an example forwarder declaration: @@ -97,7 +97,7 @@ def forward(loc): return loc def reveal(objname): - "Should this object be revealed when mappinmg?" + "Should this object be revealed when mapping?" if "OBJ_" in objname: return False if objname == "VEND": @@ -148,8 +148,8 @@ if __name__ == "__main__": startlocs[location] = [objname] # Compute reachability, using forwards. - # Dictionary ke6y is (from, to) iff its a valid link, - # value is correspoinding motion verbs. + # Dictionary key is (from, to) iff its a valid link, + # value is corresponding motion verbs. links = {} nodes = [] for (loc, attrs) in db["locations"]: From 83c32598be7a7a92fdf75d240212e7aeceb6c2d0 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 8 Mar 2023 21:54:45 -0500 Subject: [PATCH 018/213] Partially address Gitlsb issue #64: Coverage summary looks wrong --- tests/coverage_dungeon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index 288b1c0..d484193 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -147,7 +147,7 @@ def threshold_coverage(classes, text, report): # property for name, item in enumerate(classes): if name not in report["messages"]: - report["messages"][name] = {"covered" : "False"} + report["messages"][name] = {"covered" : False} report["total"] += 1 if not report["messages"][name]["covered"] and search(item["message"], text): report["messages"][name]["covered"] = True From f53476f82624231425cf381906952ecabbdb52d7 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 8 Mar 2023 22:55:12 -0500 Subject: [PATCH 019/213] Complete fix of GitLab issue #64: Coverage summary looks wrong --- tests/coverage_dungeon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index d484193..80102e3 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -158,7 +158,7 @@ def arb_coverage(arb_msgs, text, report): if name not in report["messages"]: report["messages"][name] = {"covered" : False} report["total"] += 1 - if not report["messages"][name]["covered"] and search(message, text) or name in DANGLING_MESSAGES: + if not report["messages"][name]["covered"] and (search(message, text) or name in DANGLING_MESSAGES): report["messages"][name]["covered"] = True report["covered"] += 1 From 643eab4e9cb1309db10418f0788865a8312ddc5e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 9 Mar 2023 08:54:20 -0500 Subject: [PATCH 020/213] Use $(advent) rather than advent where needed. --- tests/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index d188e70..1bd9311 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -73,11 +73,11 @@ savecheck: savegames @$(ECHO) "TEST cheat: Fail to save to invalid path" @$(PARDIR)/cheat -o / 2> /tmp/coverage_cheat_badoutput | true @$(ECHO) "TEST advent: Start with invalid file with -r" - @advent -r /badfilename < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1 + @$(advent) -r /badfilename < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1 @$(ECHO) "TEST advent: Start with invalid file with -l" - @advent -l / < pitfall.log > /tmp/coverage_advent_logfail 2>&1 || exit 1 + @$(advent) -l / < pitfall.log > /tmp/coverage_advent_logfail 2>&1 || exit 1 @$(ECHO) "TEST advent: Test -r with valid input" - @advent -r thousand_saves.adv < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1 + @$(advent) -r thousand_saves.adv < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1 @rm -f /tmp/coverage* coverage: check From 8f527fb4332e8a200713545eb45ae5181bad4ade Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 9 Mar 2023 10:19:34 -0500 Subject: [PATCH 021/213] Fix whitespace glitch. --- tests/coverage_dungeon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index 80102e3..e615239 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -7,7 +7,7 @@ various strings contained are present within the test check files. The default HTML output is appropriate for use with Gitlab CI. You can override it with a command-line argument. -The DANGLING lists are for actions and messages that should be +The DANGLING lists are for actions and messages that should be considered always found even if the checkfile search doesn't find them. Typically this will because an action emit a templated message that can't be regression-tested by equality. From 3971a61ab0d8b4142578e3e772b6680520c3806a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 9 Mar 2023 10:16:22 -0500 Subject: [PATCH 022/213] Ready to ship 1.14. --- NEWS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8e588fa..96daed0 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ = Open Adventure project news = -Repository head:: +1.14: 2023-03-09:: Added -a option for BBS door systems. -o reverts to the old message on some failed magic words. + Typo fixes and documentation polishing. 1.13: 2023-02-28:: Fixed slightly buggy emission of end-of-game messages on a win. From b125fe7b2ad09754364f8bef1f3d72a5837c7b82 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 10 Mar 2023 16:43:27 -0500 Subject: [PATCH 023/213] Fix interrupted-magic-words cosmetic bug. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C patch by Torbjörn Andersson. --- NEWS | 3 +++ actions.c | 12 +++++++----- main.c | 6 ++++++ tests/foobug.chk | 4 ++-- tests/foobug.log | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 96daed0..6e432f6 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,8 @@ = Open Adventure project news = +Repository head:: + Commands in magic-word sequence now interrupt it, as in original. + 1.14: 2023-03-09:: Added -a option for BBS door systems. -o reverts to the old message on some failed magic words. diff --git a/actions.c b/actions.c index a831d97..4c2fcdb 100644 --- a/actions.c +++ b/actions.c @@ -192,11 +192,13 @@ static phase_codes_t bigwords(vocab_t id) * word we've got. Last word zips the eggs back to the giant room (unless * already there). */ { - if ((game.foobar == WORD_EMPTY && id == FEE) || - (game.foobar == FEE && id == FIE) || - (game.foobar == FIE && id == FOE) || - (game.foobar == FOE && id == FOO) || - (game.foobar == FOE && id == FUM)) { + int foobar = abs(game.foobar); + + if ((foobar == WORD_EMPTY && id == FEE) || + (foobar == FEE && id == FIE) || + (foobar == FIE && id == FOE) || + (foobar == FOE && id == FOO) || + (foobar == FOE && id == FUM)) { game.foobar = id; if ((id != FOO) && (id != FUM)) { rspeak(OK_MAN); diff --git a/main.c b/main.c index 94f2b45..371b3b6 100644 --- a/main.c +++ b/main.c @@ -1125,6 +1125,12 @@ static bool do_command() if (!get_command_input(&command)) return false; + /* Every input, check "foobar" flag. If zero, nothing's going + * on. If pos, make neg. If neg, he skipped a word, so make it + * zero. + */ + game.foobar = (game.foobar > WORD_EMPTY) ? -game.foobar : WORD_EMPTY; + ++game.turns; preprocess_command(&command); } diff --git a/tests/foobug.chk b/tests/foobug.chk index ead29b1..046b820 100644 --- a/tests/foobug.chk +++ b/tests/foobug.chk @@ -1688,11 +1688,11 @@ passage leads south, and a low crawl goes east. > foe -OK +Nothing happens. > foo -Done! +Nothing happens. You scored 311 out of a possible 430, using 291 turns. diff --git a/tests/foobug.log b/tests/foobug.log index 49c25df..8ff35b8 100644 --- a/tests/foobug.log +++ b/tests/foobug.log @@ -1,5 +1,5 @@ ## Test interpersing commands amidst magic words -# Check for "Done" or "Nothing happens." in game output. +# Check for "Nothing happens." in game output indicatung sequence interrupt. no seed 1318612053 e From fe8a82927c86441425635f34079d2323c92957a1 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 10 Mar 2023 17:17:38 -0500 Subject: [PATCH 024/213] Document a bugfix. --- notes.adoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/notes.adoc b/notes.adoc index 45b3cd3..3b3428e 100644 --- a/notes.adoc +++ b/notes.adoc @@ -71,9 +71,6 @@ Bug fixes: Bugs (accidental changes that don't seem worth the effort to fix): -* Commands that are not moves (e.g. "look" and "inven") can be used - during fee fie fo foo without breaking recognition of the sequence. - * Bird starts uncaged in the endgame. Enhancements: From 71f05c456766111b31c13a78420d2f0bb9b95416 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 11 Mar 2023 09:35:26 -0500 Subject: [PATCH 025/213] Bugfix: bird starts caged in endgame. Turns out the code of put() had been modified ibcorrectly, but the bug was masked in all but a few cases, noe of which would be encountered in normal gameplay. A test to ensure this bug does noit recur has been added. --- misc.c | 2 +- notes.adoc | 4 - tests/birdsnakewake.chk | 2 +- tests/endobjects.chk | 3 +- tests/saveresume.4.chk | 16 +- tests/takebird.chk | 2084 +++++++++++++++++++++++++++++++++++++++ tests/takebird.log | 351 +++++++ 7 files changed, 2445 insertions(+), 17 deletions(-) create mode 100644 tests/takebird.chk create mode 100644 tests/takebird.log diff --git a/misc.c b/misc.c index d047602..0bcfb26 100644 --- a/misc.c +++ b/misc.c @@ -602,7 +602,7 @@ loc_t put(obj_t object, loc_t where, int pval) * negated game.prop values for the repository objects. */ { move(object, where); - return STASHED(pval); + return (-1) - pval;; } void carry(obj_t object, loc_t where) diff --git a/notes.adoc b/notes.adoc index 3b3428e..65971f8 100644 --- a/notes.adoc +++ b/notes.adoc @@ -69,10 +69,6 @@ Bug fixes: * Under odd circumstances (dropping rug or vase outdoors) the game could formerly say "floor" when it should say "ground" (or "dirt", or something). -Bugs (accidental changes that don't seem worth the effort to fix): - -* Bird starts uncaged in the endgame. - Enhancements: By default, advent issues "> " as a command prompt. This feature diff --git a/tests/birdsnakewake.chk b/tests/birdsnakewake.chk index 68f99d4..361cbf7 100644 --- a/tests/birdsnakewake.chk +++ b/tests/birdsnakewake.chk @@ -2930,7 +2930,7 @@ OK > take bird -OK +You are already carrying it! > free bird diff --git a/tests/endobjects.chk b/tests/endobjects.chk index 1f06db5..42132d3 100644 --- a/tests/endobjects.chk +++ b/tests/endobjects.chk @@ -2435,11 +2435,12 @@ OK You are currently holding the following: Wicker cage +Little bird in cage Small bottle > get bird -OK +You are already carrying it! > inven diff --git a/tests/saveresume.4.chk b/tests/saveresume.4.chk index 260cbf3..1643c43 100644 --- a/tests/saveresume.4.chk +++ b/tests/saveresume.4.chk @@ -10,19 +10,15 @@ down a gully. > resume Can't open file y, try again. -You're at sw end. - -The grate is locked. +You're in front of building. > blast -There is a loud explosion, and a twenty-foot hole appears in the far -wall, burying the dwarves in the rubble. You march through the hole -and find yourself in the main office, where a cheering band of -friendly elves carry the conquering adventurer off into the sunset. +Blasting requires dynamite. -You scored 423 out of a possible 430, using 468 turns. -Your score puts you in Master Adventurer Class A. +You scored 32 out of a possible 430, using 2 turns. -To achieve the next higher rating, you need 4 more points. +You are obviously a rank amateur. Better luck next time. + +To achieve the next higher rating, you need 14 more points. diff --git a/tests/takebird.chk b/tests/takebird.chk new file mode 100644 index 0000000..d69f094 --- /dev/null +++ b/tests/takebird.chk @@ -0,0 +1,2084 @@ + +Welcome to Adventure!! Would you like instructions? + +> no + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed 1318612053 + +Seed set to 1318612053 + +You're in front of building. + +> e + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plove + +>>Foof!<< + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +There is an emerald here the size of a plover's egg! + +> get emerald + +OK + +> w + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> drop emerald + +OK + +> e + +You're in Plover Room. + +> ne + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> get pyramid + +OK + +> s + +You're in Plover Room. + +> plove + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> drop pyramid + +OK + +> get lamp + +OK + +> get water + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There are bars of silver here! + +> d + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> bedquilt + +You are in Bedquilt, a long east/west passage with holes everywhere. +To explore at random select north, south, up, or down. + +> w + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +> e + +You are in the Soft Room. The walls are covered with heavy curtains, +the floor with a thick pile carpet. Moss covers the ceiling. + +A small velvet pillow lies on the floor. + +> take pillow + +OK + +> w + +You're in Swiss Cheese Room. + +> oriental + +This is the Oriental Room. Ancient oriental cave drawings cover the +walls. A gently sloping passage leads upward to the north, another +passage leads se, and a hands and knees crawl leads west. + +There is a delicate, precious, ming vase here! + +> take vase + +OK + +> n + +You are following a wide path around the outer edge of a large cavern. +Far below, through a heavy white mist, strange splashing noises can be +heard. The mist rises up through a fissure in the ceiling. The path +exits to the south and west. + +> w + +You are in an alcove. A small nw path seems to widen after a short +distance. An extremely tight tunnel leads east. It looks like a very +tight squeeze. An eerie light can be seen at the other end. + +There is an emerald here the size of a plover's egg! + +> take emerald + +OK + +> nw + +You're in misty cavern. + +> s + +You're in Oriental Room. + +> se + +You're in Swiss Cheese Room. + +> w + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +> w + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a tiny little plant in the pit, murmuring "water, water, ..." + +> water plant + +The plant spurts into furious growth for a few seconds. + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> u + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> e + +You're at east end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You are at the bottom of the eastern pit in the Twopit Room. There is +a small pool of oil in one corner of the pit. + +> fill bottle + +Your bottle is now full of oil. + +> u + +You're at east end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> e + +You're in Swiss Cheese Room. + +> ne + +You're in Bedquilt. + +> e + +You are at a complex junction. A low hands and knees passage from the +north joins a higher crawl from the east to make a walking passage +going west. There is also a large room above. The air is damp here. + +> u + +You are in a large room full of dusty rocks. There is a big hole in +the floor. There are cracks everywhere, and a passage leading east. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> n + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop pillow + +OK + +> drop vase + +The vase is now resting, delicately, on a velvet pillow. + +> drop bottle + +OK + +> drop emerald + +OK + +> xyzzy + +>>Foof!<< + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> e + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> take cage + +OK + +> pit + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> drop rod + +OK + +> e + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> take bird + +OK + +> w + +You're at top of small pit. + +A three foot black rod with a rusty star on an end lies nearby. + +Rough stone steps lead down the pit. + +> drop bird + +OK + +> take rod + +OK + +> wave rod + +The bird flies about agitatedly for a moment, then disappears through +the crack. It reappears shortly, carrying in its beak a jade +necklace, which it drops at your feet. + +> take necklace + +OK + +> drop rod + +OK + +> take bird + +OK + +> d + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> s + +This is a low room with a crude note on the wall. The note says, +"You won't get it up the steps". + +There is a large sparkling nugget of gold here! + +> take nugget + +OK + +> n + +You're in Hall of Mists. + +> n + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A huge green fierce snake bars the way! + +> drop bird + +The little bird attacks the green snake, and in an astounding flurry +drives the snake away. + +> take bird + +OK + +> sw + +You are in a secret canyon which here runs e/w. It crosses over a +very tight canyon 15 feet below. If you go down you may not be able +to get back up. + +> w + +You are in a secret canyon which exits to the north and east. + +A huge green fierce dragon bars the way! + +The dragon is sprawled out on a Persian rug!! + +> kill dragon + +With what? Your bare hands? + +> yes + +Congratulations! You have just vanquished a dragon with your bare +hands! (Unbelievable, isn't it?) + +You are in a secret canyon which exits to the north and east. + +There is a Persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. + +> drink blood + +Your head buzzes strangely for a moment. + +> take rug + +OK + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +You're in Hall of Mt King. + +> n + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> take bars + +OK + +> n + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +There is an emerald here the size of a plover's egg! + +There is a bottle of oil here. + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop cage + +OK + +> drop necklace + +OK + +> drop nugget + +OK + +> drop bars + +OK + +> drop rug + +OK + +> xyzzy + +>>Foof!<< + +You're in debris room. + +> pit + +You're at top of small pit. + +A three foot black rod with a rusty star on an end lies nearby. + +Rough stone steps lead down the pit. + +> take rod + +OK + +> d + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +A crystal bridge now spans the fissure. + +> w + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> take diamonds + +OK + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of the Hall of Mists. A low wide crawl +continues west and another goes north. To the south is a little +passage 6 feet off the floor. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the east end of a very long hall apparently without side +chambers. To the east a low wide crawl slants up. To the north a +round two foot hole slants down. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of a very long featureless hall. The hall +joins up with a narrow north/south passage. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisting little passages, all different. + +> e + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisting passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +Dead end + +There is a massive and somewhat battered vending machine here. The +instructions on it read: "Drop coins here to receive fresh batteries." + +> hit machine + +As you strike the vending machine, it pivots backward along with a +section of wall, revealing a dark passage leading south. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a long, rough-hewn, north/south corridor. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a large chamber with passages to the west and north. + +A formidable ogre bars the northern exit. + +> kill ogre + +The ogre, who despite his bulk is quite agile, easily dodges your +attack. He seems almost amused by your puny effort. + +One sharp nasty knife is thrown at you! + +The ogre, distracted by your rush, is struck by the knife. With a +blood-curdling yell he turns and bounds after the dwarf, who flees +in panic. You are left alone in the room. + +> n + +You are in the ogre's storeroom. The only exit is to the south. + +There is an enormous ruby here! + +> take ruby + +OK + +> s + +You are in a large chamber with passages to the west and north. + +> w + +You are in a long, rough-hewn, north/south corridor. + +> n + +Dead end + +There is a massive vending machine here, swung back to reveal a +southward passage. + +> n + +You are in a little maze of twisting passages, all different. + +> sw + +You are in a maze of twisting little passages, all different. + +> w + +You are in a maze of twisty little passages, all different. + +> d + +You're at west end of long hall. + +> n + +You are at a crossover of a high n/s passage and a low e/w one. + +> e + +You are in the west side chamber of the Hall of the Mountain King. +A passage continues west and up here. + +There are many coins here! + +> take coins + +OK + +> e + +You're in Hall of Mt King. + +> s + +You are in the south side chamber. + +There is precious jewelry here! + +> take jewelry + +OK + +> n + +You're in Hall of Mt King. + +> e + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're at west end of Hall of Mists. + +> s + +You are in a maze of twisty little passages, all alike. + +> e + +Out from the shadows behind you pounces a bearded pirate! "Har, har," +he chortles, "I'll just take all this booty and hide it away with me +chest deep in the maze!" He snatches your treasure and vanishes into +the gloom. + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> n + +You are in a maze of twisty little passages, all alike. + +> e + +You are on the brink of a thirty foot pit with a massive orange column +down one wall. You could climb down here but you could not get back +up. The maze continues at this level. + +> e + +You are in a maze of twisty little passages, all alike. + +> nw + +Dead end + +There is an enormous ruby here! + +There are many coins here! + +There is precious jewelry here! + +There are diamonds here! + +The pirate's treasure chest is here! + +> drop rod + +OK + +> take jewelry + +OK + +> take chest + +OK + +> take ruby + +OK + +> take diamonds + +OK + +> take coins + +OK + +> se + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all alike. + +> w + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all alike. + +> s + +There is a threatening little dwarf in the room with you! + +You're at brink of pit. + +> d + +You're in bird chamber. + +> debris + +You're in debris room. + +> xyzzy + +>>Foof!<< + +You're inside building. + +There is a Persian rug spread out on the floor! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a small wicker cage discarded nearby. + +There is a little bird in the cage. + +There is an emerald here the size of a plover's egg! + +There is a bottle of oil here. + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> off + +Your lamp is now off. + +> drop coins + +OK + +> drop diamonds + +OK + +> drop jewelry + +OK + +> drop chest + +OK + +> drop lamp + +OK + +> take rug + +OK + +> take emerald + +OK + +> take cage + +OK + +> take bottle + +OK + +> w + +You're in front of building. + +> s + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> w + +You are wandering aimlessly through the forest. + +> drop bird + +OK + +> listen + +The bird is singing to you in gratitude for your having returned it to +its home. In return, it informs you of a magic word which it thinks +you may find useful somewhere near the Hall of Mists. The magic word +changes frequently, but for now the bird believes it is "N'BEH". You +thank the bird for this information, and it flies off into the forest. + +> drop cage + +OK + +> n + +You are wandering aimlessly through the forest. + +Your keen eye spots a severed leporine appendage lying on the ground. + +> take appendage + +OK + +> n + +You are wandering aimlessly through the forest. + +> e + +You are wandering aimlessly through the forest. + +> n + +You are wandering aimlessly through the forest. + +> n + +The forest thins out here to reveal a steep cliff. There is no way +down, but a small ledge can be seen to the west across the chasm. + +A small urn is embedded in the rock. + +> fill urn + +Your bottle is now empty and the urn is full of oil. + +> light urn + +The urn is now lit. + +> rub urn + +As you rub the urn, there is a flash of light and a genie appears. +His aspect is stern as he advises: "One who wouldst traffic in +precious stones must first learn to recognize the signals thereof." +He wrests the urn from the stone, leaving a small cavity. Turning to +face you again, he fixes you with a steely eye and intones: "Caution!" +Genie and urn vanish in a cloud of amber smoke. The smoke condenses +to form a rare amber gemstone, resting in the cavity in the rock. + +> drop rug + +OK + +> take amber + +OK + +> drop emerald + +The gem fits easily into the cavity. + +The Persian rug stiffens and rises a foot or so off the ground. + +> fly + +You board the Persian rug, which promptly whisks you across the chasm. +You have time for a fleeting glimpse of a two thousand foot drop to a +mighty river; then you find yourself on the other side. + +You are on a small ledge on one face of a sheer cliff. There are no +paths away from the ledge. Across the chasm is a small clearing +surrounded by forest. + +There is a Persian rug here, hovering in mid-air! + +A brilliant blue star sapphire is here! + +> take sapphire + +OK + +> fly + +The rug ferries you back across the chasm. + +You're at cliff. + +There is an emerald resting in a small cavity in the rock! + +There is a Persian rug here, hovering in mid-air! + +> take emerald + +OK + +> drop ruby + +The gem fits easily into the cavity. + +The Persian rug settles gently to the ground. + +> take rug + +OK + +> take ruby + +OK + +> e + +You are wandering aimlessly through the forest. + +> s + +You are wandering aimlessly through the forest. + +> e + +You have walked up a hill, still in the forest. The road slopes back +down the other side of the hill. There is a building in the distance. + +> e + +You're in front of building. + +> e + +You are inside a building, a well house for a large spring. + +There is a shiny brass lamp nearby. + +The pirate's treasure chest is here! + +There is precious jewelry here! + +There are diamonds here! + +There are many coins here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop emerald + +OK + +> drop ruby + +OK + +> drop amber + +OK + +> drop rug + +OK + +> drop sapphire + +OK + +> fill bottle + +Your bottle is now full of water. + +> take lamp + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +There is a little axe here. + +> s + +You're in n/s passage above e/w passage. + +> s + +You're in Hall of Mt King. + +> sw + +You're in secret e/w canyon above tight canyon. + +> w + +You are in a secret canyon which exits to the north and east. + +The body of a huge green dead dragon is lying off to one side. + +> n + +You are in a secret n/s canyon above a large room. + +> reservoir + +You are at the edge of a large underground reservoir. An opaque cloud +of white mist fills the room and rises rapidly upward. The lake is +fed by a stream, which tumbles out of a hole in the wall about 10 feet +overhead and splashes noisily into the water somewhere within the +mist. There is a passage going back toward the south. + +> n'beh + +The waters have parted to form a narrow path across the reservoir. + +> n + +You are walking across the bottom of the reservoir. Walls of water +rear up on either side. The roar of the water cascading past is +nearly deafening, and the mist is so thick you can barely see. + +> n + +You are at the northern edge of the reservoir. A northwest passage +leads sharply up from here. + +The waters have parted to form a narrow path across the reservoir. + +> u + +You are scrambling along a treacherously steep, rocky passage. + +> u + +You are on a very steep incline, which widens at it goes upward. + +> u + +You are at the base of a nearly vertical cliff. There are some +slim footholds which would enable you to climb up, but it looks +extremely dangerous. Here at the base of the cliff lie the remains +of several earlier adventurers who apparently failed to make it. + +> u + +You are climbing along a nearly vertical cliff. + +> u + +Just as you reach the top, your foot slips on a loose rock and you +make one last desperate grab. Your luck holds, as does your grip. +With an enormous heave, you lift yourself to the ledge above. + +You are on a small ledge at the top of a nearly vertical cliff. +There is a low crawl leading off to the northeast. + +> ne + +You have reached a dead end. + +There is a richly-carved ebony statuette here! + +> take statuette + +OK + +> sw + +You're at top of cliff. + +> d + +You are climbing along a nearly vertical cliff. + +> d + +You're at base of cliff. + +> d + +You are on a very steep incline, which widens at it goes upward. + +> d + +You are scrambling along a treacherously steep, rocky passage. + +> d + +You're north of reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You're at bottom of reservoir. + +> s + +You're at reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You are in a north/south canyon about 25 feet across. The floor is +covered by white mist seeping in from the north. The walls extend +upward for well over 100 feet. Suspended from some unseen point far +above you, an enormous two-sided mirror is hanging parallel to and +midway between the canyon walls. (The mirror is obviously provided +for the use of the dwarves who, as you know, are extremely vain.) A +small window can be seen in either wall, some fifty feet up. + +> s + +You are in a secret n/s canyon above a large room. + +> d + +You are in a large low circular chamber whose floor is an immense slab +fallen from the ceiling (Slab Room). East and west there once were +large passages, but they are now filled with boulders. Low small +passages go north and south, and the south one quickly bends west +around the boulders. + +> s + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> water plant + +The plant grows explosively, almost filling the bottom of the pit. + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> u + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> e + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in east pit. + +> fill bottle + +Your bottle is now full of oil. + +> u + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You are in a long, narrow corridor stretching out of sight to the +west. At the eastern end is a hole through which you can see a +profusion of leaves. + +> w + +You are in the Giant Room. The ceiling here is too high up for your +lamp to show it. Cavernous passages lead east, north, and south. On +the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. + +There is a large nest here, full of golden eggs! + +> take eggs + +OK + +> n + +You are at one end of an immense north/south passage. + +The way north is barred by a massive, rusty, iron door. + +> oil door + +The oil has freed up the hinges so that the door will now move, +although it requires some effort. + +> drop bottle + +OK + +> n + +You are in a magnificent cavern with a rushing stream, which cascades +over a sparkling waterfall into a roaring whirlpool which disappears +through a hole in the floor. Passages exit to the south and west. + +There is a jewel-encrusted trident here! + +> take trident + +OK + +> w + +You are at the top of a steep incline above a large room. You could +climb down here, but you would not be able to climb up. There is a +passage leading back to the north. + +> d + +You are in a large low room. Crawls lead north, se, and sw. + +> bedquilt + +You're in Bedquilt. + +> e + +You're at complex junction. + +> n + +You're in a large room carved out of sedimentary rock. The floor and +walls are littered with bits of shells embedded in the stone. A +shallow passage proceeds downward, and a somewhat steeper one leads +up. A low hands and knees passage enters from the south. + +There is an enormous clam here with its shell tightly closed. + +> open clam + +A glistening pearl falls out of the clam and rolls away. Goodness, +this must really be an oyster. (I never was very good at identifying +bivalves.) Whatever it is, it has now snapped shut again. + +> d + +You are in a long sloping corridor with ragged sharp walls. + +> d + +You are in a cul-de-sac about eight feet across. + +Off to one side lies a glistening pearl! + +> take pearl + +OK + +> shell + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> s + +You're at complex junction. + +> u + +You're in dusty rock room. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +A brilliant blue star sapphire is here! + +There is a Persian rug spread out on the floor! + +There is a rare amber gemstone here! + +There is an enormous ruby here! + +There is an emerald here the size of a plover's egg! + +The pirate's treasure chest is here! + +There is precious jewelry here! + +There are diamonds here! + +There are many coins here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop trident + +OK + +> drop pearl + +OK + +> drop statuette + +OK + +> drop appendage + +OK + +> take keys + +OK + +> take food + +OK + +> plugh + +>>Foof!<< + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +There is a little axe here. + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> d + +You're in dirty passage. + +> bedquilt + +You're in Bedquilt. + +> w + +You're in Swiss Cheese Room. + +> oriental + +You're in Oriental Room. + +> w + +You're in large low room. + +> sw + +You are in a long winding corridor sloping out of sight in both +directions. + +> u + +You are on one side of a large, deep chasm. A heavy white mist rising +up from below obscures all view of the far side. A sw path leads away +from the chasm into a winding corridor. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> throw eggs + +The troll catches your treasure and scurries away out of sight. + +> ne + +You are on the far side of the chasm. A ne path leads away from the +chasm on this side. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> barren + +You are standing at the entrance to a large, barren room. A notice +above the entrance reads: "Caution! Bear in room!" + +> e + +You are inside a barren room. The center of the room is completely +empty except for some dust. Marks in the dust lead away toward the +far end of the room. The only exit is the way you came in. + +There is a ferocious cave bear eyeing you from the far end of the room! + +The bear is locked to the wall with a golden chain! + +> throw food + +The bear eagerly wolfs down your food, after which he seems to calm +down considerably and even becomes rather friendly. + +> unlock chain + +The chain is now unlocked. + +> take chain + +OK + +> take bear + +OK + +> fork + +You are being followed by a very large, tame bear. + +The path forks here. The left fork leads northeast. A dull rumbling +seems to get louder in that direction. The right fork leads southeast +down a gentle slope. The main corridor enters from the west. + +> ne + +You are being followed by a very large, tame bear. + +The walls are quite warm here. From the north can be heard a steady +roar, so loud that the entire cave seems to be trembling. Another +passage leads south, and a low crawl goes east. + +> fee + +OK + +> fie + +OK + +> foe + +OK + +> foo + +Done! + +> e + +You are being followed by a very large, tame bear. + +You are in a small chamber filled with large boulders. The walls are +very warm, causing the air in the room to be almost stifling from the +heat. The only exit is a crawl heading west, through which is coming +a low rumbling. + +There are rare spices here! + +> take spices + +OK + +> fork + +You are being followed by a very large, tame bear. + +You're at fork in path. + +> w + +You are being followed by a very large, tame bear. + +You're in a long east/west corridor. A faint rumbling noise can be +heard in the distance. + +> w + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +The troll steps out from beneath the bridge and blocks your way. + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> release bear + +The bear lumbers toward the troll, who lets out a startled shriek and +scurries away. The bear soon gives up the pursuit and wanders back. + +> sw + +You're on sw side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +You're in sloping corridor. + +> d + +You're in large low room. + +> se + +You're in Oriental Room. + +> se + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +> w + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You're in narrow corridor. + +> w + +You're in Giant Room. + +There is a large nest here, full of golden eggs! + +> take eggs + +OK + +> n + +You are at one end of an immense north/south passage. + +There is an empty bottle here. + +The way north leads through a massive, rusty, iron door. + +> n + +You're in cavern with waterfall. + +> w + +You're at steep incline above large room. + +> d + +You're in large low room. + +> bedquilt + +You're in Bedquilt. + +> e + +You're at complex junction. + +> u + +You're in dusty rock room. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a richly-carved ebony statuette here! + +Off to one side lies a glistening pearl! + +There is a jewel-encrusted trident here! + +A brilliant blue star sapphire is here! + +There is a Persian rug spread out on the floor! + +There is a rare amber gemstone here! + +There is an enormous ruby here! + +There is an emerald here the size of a plover's egg! + +The pirate's treasure chest is here! + +There is precious jewelry here! + +There are diamonds here! + +There are many coins here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +> drop eggs + +OK + +> drop chain + +OK + +> drop spices + +OK + +> plugh + +>>Foof!<< + +You're at "Y2". + +A hollow voice says "PLUGH". + +There is a little axe here. + +> s + +You're in n/s passage above e/w passage. + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> n + +A sepulchral voice reverberating through the cave, says, "Cave closing +soon. All adventurers exit immediately through main office." + +You're at "Y2". + +There is a little axe here. + +> plugh + +A mysterious recorded voice groans into life and announces: + "This exit is closed. Please leave via main office." + +You're at "Y2". + +There is a little axe here. + +> s + +You're in n/s passage above e/w passage. + +> d + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> w + +You're in dusty rock room. + +> d + +You're at complex junction. + +> e + +You are in an anteroom leading to a large passage to the east. Small +passages go west and up. The remnants of recent digging are evident. +A sign in midair here says "Cave under construction beyond this point. +Proceed at own risk. [Witt Construction Company]" + +There are a few recent issues of "Spelunker Today" magazine here. + +> take magazine + +OK + +> e + +You are at Witt's End. Passages lead off in *ALL* directions. + +> drop magazine + +OK + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +The sepulchral voice intones, "The cave is now closed." As the echoes +fade, there is a blinding flash of light (and a small puff of orange +smoke). . . . As your eyes refocus, you look around and find... + +You are at the northeast end of an immense room, even larger than the +Giant Room. It appears to be a repository for the "Adventure" +program. Massive torches far overhead bathe the room with smoky +yellow light. Scattered about you can be seen a pile of bottles (all +of them empty), a nursery of young beanstalks murmuring quietly, a bed +of oysters, a bundle of black rods with rusty stars on their ends, and +a collection of brass lanterns. Off to one side a great many dwarves +are sleeping on the floor, snoring loudly. A notice nearby reads: "Do +not disturb the dwarves!" An immense mirror is hanging against one +wall, and stretches to the other end of the room, where various other +sundry objects can be glimpsed dimly in the distance. + +> sw + +You are at the southwest end of the repository. To one side is a pit +full of fierce green snakes. On the other side is a row of small +wicker cages, each of which contains a little sulking bird. In one +corner is a bundle of black rods with rusty marks on their ends. A +large number of velvet pillows are scattered about on the floor. A +vast mirror stretches off to the northeast. At your feet is a large +steel grate, next to which is a sign that reads, "Treasure Vault. +Keys in main office." + +The grate is locked. + +> take bird + +OK + + +You scored 391 out of a possible 430, using 345 turns. + +Your score puts you in Master Adventurer Class B. + +To achieve the next higher rating, you need 20 more points. diff --git a/tests/takebird.log b/tests/takebird.log new file mode 100644 index 0000000..b2f5f70 --- /dev/null +++ b/tests/takebird.log @@ -0,0 +1,351 @@ +## Verify that bird starts caged in endgame +no +seed 1318612053 +e +plugh +plove +get emerald +w +drop emerald +e +ne +get pyramid +s +plove +plugh +drop pyramid +get lamp +get water +plugh +on +s +d +bedquilt +w +e +take pillow +w +oriental +take vase +n +w +take emerald +nw +s +se +w +w +d +water plant +u +e +d +fill bottle +u +e +ne +e +u +e +u +n +plugh +drop pillow +drop vase +drop bottle +drop emerald +xyzzy +take rod +e +take cage +pit +drop rod +e +take bird +w +drop bird +take rod +wave rod +take necklace +drop rod +take bird +d +s +take nugget +n +n +drop bird +take bird +sw +w +kill dragon +yes +drink blood +take rug +e +e +n +take bars +n +plugh +drop cage +drop necklace +drop nugget +drop bars +drop rug +xyzzy +pit +take rod +d +w +wave rod +w +take diamonds +w +w +w +s +s +e +s +hit machine +s +s +kill ogre +n +take ruby +s +w +n +n +sw +w +d +n +e +take coins +e +s +take jewelry +n +e +w +w +w +s +e +s +s +s +n +e +e +nw +drop rod +take jewelry +take chest +take ruby +take diamonds +take coins +se +w +s +d +debris +xyzzy +off +drop coins +drop diamonds +drop jewelry +drop chest +drop lamp +take rug +take emerald +take cage +take bottle +w +s +w +drop bird +listen +drop cage +n +take appendage +n +e +n +n +fill urn +light urn +rub urn +drop rug +take amber +drop emerald +fly +take sapphire +fly +take emerald +drop ruby +take rug +take ruby +e +s +e +e +e +drop emerald +drop ruby +drop amber +drop rug +drop sapphire +fill bottle +take lamp +plugh +on +s +s +sw +w +n +reservoir +n'beh +n +n +u +u +u +u +u +ne +take statuette +sw +d +d +d +d +d +s +s +s +s +d +s +d +water plant +u +e +d +fill bottle +u +w +d +climb +w +take eggs +n +oil door +drop bottle +n +take trident +w +d +bedquilt +e +n +open clam +d +d +take pearl +shell +s +u +e +u +n +plugh +drop trident +drop pearl +drop statuette +drop appendage +take keys +take food +plugh +s +d +bedquilt +w +oriental +w +sw +u +throw eggs +ne +barren +e +throw food +unlock chain +take chain +take bear +fork +ne +fee +fie +foe +foo +e +take spices +fork +w +w +sw +release bear +sw +sw +d +se +se +w +w +d +climb +w +take eggs +n +n +w +d +bedquilt +e +u +e +u +n +plugh +drop eggs +drop chain +drop spices +plugh +s +look +look +n +plugh +s +d +w +d +e +take magazine +e +drop magazine +look +look +look +look +look +look +look +sw +# Good response "OK". +# Buggy response: "You can catch the bird, but you cannot carry it." +take bird From b7bf85904d00488f6902036d03e9db664b68de89 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 11 Mar 2023 09:41:07 -0500 Subject: [PATCH 026/213] Fix a formal-type glitch. --- advent.h | 2 +- misc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/advent.h b/advent.h index bf27d9b..8cecf31 100644 --- a/advent.h +++ b/advent.h @@ -233,7 +233,7 @@ extern bool silent_yes_or_no(void); extern bool yes_or_no(const char*, const char*, const char*); extern void juggle(obj_t); extern void move(obj_t, loc_t); -extern loc_t put(obj_t, int, int); +extern loc_t put(obj_t, loc_t, int); extern void carry(obj_t, loc_t); extern void drop(obj_t, loc_t); extern int atdwrf(loc_t); diff --git a/misc.c b/misc.c index 0bcfb26..691d771 100644 --- a/misc.c +++ b/misc.c @@ -602,7 +602,7 @@ loc_t put(obj_t object, loc_t where, int pval) * negated game.prop values for the repository objects. */ { move(object, where); - return (-1) - pval;; + return (-1) - pval;; // Needs to stay sinchronized with STASHED } void carry(obj_t object, loc_t where) From ba3248224eb2b6a1e5098c788bd2029444d5140a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 11 Mar 2023 10:29:38 -0500 Subject: [PATCH 027/213] Add C coverage exclsion required by unbreaking the property setter. --- saveresume.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saveresume.c b/saveresume.c index d668543..05e12b7 100644 --- a/saveresume.c +++ b/saveresume.c @@ -230,7 +230,7 @@ bool is_valid(struct game_t valgame) case VASE: case CHAIN: if (valgame.prop[obj] == 2) // There are multiple different states, but it's convenient to clump them together - continue; + continue; // LCOV_EXCL_LINE /* FALLTHRU */ case BEAR: if (valgame.prop[BEAR] == CONTENTED_BEAR || valgame.prop[BEAR] == BEAR_DEAD) From 1652df4540a1de0678b6d572310861b07d701299 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 11 Mar 2023 10:40:01 -0500 Subject: [PATCH 028/213] Add ANSI prototype, --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 371b3b6..7a6c6c8 100644 --- a/main.c +++ b/main.c @@ -1074,7 +1074,7 @@ static bool do_move(void) return true; } -static bool do_command() +static bool do_command(void) /* Get and execute a command */ { static command_t command; From 569a39aa7c4429c27f074b86a71c1d540491d19f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 11 Mar 2023 10:58:38 -0500 Subject: [PATCH 029/213] Drop an attempt to pacify cppcheck that's no longer needed. --- misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc.c b/misc.c index 691d771..c6733d5 100644 --- a/misc.c +++ b/misc.c @@ -221,7 +221,7 @@ static char* get_input(void) // Print a blank line printf("\n"); - char* input = ""; + char* input; for (;;) { input = myreadline(input_prompt); From 04df0ce64c3d7413daaa19e19f476430768cccac Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 06:39:57 -0400 Subject: [PATCH 030/213] Add message and bailout on invalid save. Note: save/resume still fails at saveresume.4 at this revision. --- adventure.yaml | 14 +++++++------- saveresume.c | 5 ++++- tests/saveresume.4.chk | 18 ++++++------------ 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/adventure.yaml b/adventure.yaml index 76e6b1c..b246498 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -3189,13 +3189,13 @@ arbitrary_messages: !!omap save file format, and this program uses Version %d.%d. You must find an instance using that other version in order to resume that Adventure. # This message is not currently used -#- SAVE_TAMPERING: |- -# A dark fog creeps in to surround you. From somewhere in the fog you -# hear a stern voice. "This Adventure has been tampered with! You have -# been dabbling in magic, knowing not the havoc you might cause thereby. -# Leave at once, before you do irrevocable harm!" The fog thickens, -# until at last you can see nothing at all. Your vision then clears, -# and you find yourself back in The Real World. +- SAVE_TAMPERING: |- + A dark fog creeps in to surround you. From somewhere in the fog you + hear a stern voice. "This Adventure has been tampered with! You have + been dabbling in magic, knowing not the havoc you might cause thereby. + Leave at once, before you do irrevocable harm!" The fog thickens, + until at last you can see nothing at all. Your vision then clears, + and you find yourself back in The Real World. - TWIST_TURN: |- Sorry, but the path twisted and turned so much that I can't figure out which way to go to get back. diff --git a/saveresume.c b/saveresume.c index 05e12b7..c9278a4 100644 --- a/saveresume.c +++ b/saveresume.c @@ -137,7 +137,10 @@ int restore(FILE* fp) fclose(fp); if (save.version != VRSION) { rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), VRSION / 10, MOD(VRSION, 10)); - } else if (is_valid(save.game)) { + } else if (!is_valid(save.game)) { + rspeak(SAVE_TAMPERING); + exit(EXIT_SUCCESS); + } else { game = save.game; } return GO_TOP; diff --git a/tests/saveresume.4.chk b/tests/saveresume.4.chk index 1643c43..1280b2b 100644 --- a/tests/saveresume.4.chk +++ b/tests/saveresume.4.chk @@ -10,15 +10,9 @@ down a gully. > resume Can't open file y, try again. -You're in front of building. - -> blast - -Blasting requires dynamite. - - -You scored 32 out of a possible 430, using 2 turns. - -You are obviously a rank amateur. Better luck next time. - -To achieve the next higher rating, you need 14 more points. +A dark fog creeps in to surround you. From somewhere in the fog you +hear a stern voice. "This Adventure has been tampered with! You have +been dabbling in magic, knowing not the havoc you might cause thereby. +Leave at once, before you do irrevocable harm!" The fog thickens, +until at last you can see nothing at all. Your vision then clears, +and you find yourself back in The Real World. From 0ffb2978016618ce2ac500a098de7566d0b37add Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 10:03:43 -0400 Subject: [PATCH 031/213] Relax the savefile validity check a little. There was a very old bug, probably predating the OpenAdventure port, that would poke a stashed value of -1 into the snake object if you did a save in endgame, and then fail the savefile validation on resume. This was masked for a long time by a bug in put() just fixed a couple of revisions ago. --- advent.h | 4 ++-- saveresume.c | 3 ++- tests/saveresume.4.chk | 22 ++++++++++++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/advent.h b/advent.h index 8cecf31..4d1c9f3 100644 --- a/advent.h +++ b/advent.h @@ -32,7 +32,7 @@ #define WRITE_MODE "wb" // b is not needed for POSIX but harmless /* Special object-state values - integers > 0 are object-specific */ -#define STATE_NOTFOUND -1 // 'Not found" state of treasures */ +#define STATE_NOTFOUND -1 // 'Not found" state of treasures #define STATE_FOUND 0 // After discovered, before messed with #define STATE_IN_CAVITY 1 // State value common to all gemstones @@ -42,7 +42,7 @@ /* Map a state property value to a negative range, where the object cannot be * picked up but the value can be recovered later. Avoid colliding with -1, - * which has its own meaning. */ + * which has its own meaning as STATE_NOTFOUND. */ #define STASHED(obj) (-1 - game.prop[obj]) #define PROMPT "> " diff --git a/saveresume.c b/saveresume.c index c9278a4..af71b5e 100644 --- a/saveresume.c +++ b/saveresume.c @@ -219,7 +219,8 @@ bool is_valid(struct game_t valgame) /* Check that properties of objects aren't beyond expected */ for (obj_t obj = 0; obj <= NOBJECTS; obj++) { - if (valgame.prop[obj] < STATE_NOTFOUND || valgame.prop[obj] > 1) { + /* Magic number -2 allows a STASHED version of state 1 */ + if (valgame.prop[obj] < -2 || valgame.prop[obj] > 1) { switch (obj) { case RUG: case DRAGON: diff --git a/tests/saveresume.4.chk b/tests/saveresume.4.chk index 1280b2b..260cbf3 100644 --- a/tests/saveresume.4.chk +++ b/tests/saveresume.4.chk @@ -10,9 +10,19 @@ down a gully. > resume Can't open file y, try again. -A dark fog creeps in to surround you. From somewhere in the fog you -hear a stern voice. "This Adventure has been tampered with! You have -been dabbling in magic, knowing not the havoc you might cause thereby. -Leave at once, before you do irrevocable harm!" The fog thickens, -until at last you can see nothing at all. Your vision then clears, -and you find yourself back in The Real World. +You're at sw end. + +The grate is locked. + +> blast + +There is a loud explosion, and a twenty-foot hole appears in the far +wall, burying the dwarves in the rubble. You march through the hole +and find yourself in the main office, where a cheering band of +friendly elves carry the conquering adventurer off into the sunset. + +You scored 423 out of a possible 430, using 468 turns. + +Your score puts you in Master Adventurer Class A. + +To achieve the next higher rating, you need 4 more points. From 7723f3fc1a23cc3b77e62dd8cc702c104ae46ab5 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 10:11:52 -0400 Subject: [PATCH 032/213] Add coverage exception now that SAVE_TAMPERING is back. --- tests/coverage_dungeon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index e615239..1f27838 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -25,7 +25,7 @@ YAML_PATH = "../adventure.yaml" HTML_TEMPLATE_PATH = "../templates/coverage_dungeon.html.tpl" DEFAULT_HTML_OUTPUT_PATH = "../coverage/adventure.yaml.html" DANGLING_ACTIONS = ["ACT_VERSION"] -DANGLING_MESSAGES = ["SAVERESUME_DISABLED"] +DANGLING_MESSAGES = ["SAVERESUME_DISABLED", "SAVE_TAMPERING"] STDOUT_REPORT_CATEGORY = " {name:.<19}: {percent:5.1f}% covered ({covered} of {total})\n" From 282842c4a9e9af52e8e7e95260b40af5e5ebee0e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 11:15:04 -0400 Subject: [PATCH 033/213] Whitespace trimming of save and resume names. --- saveresume.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/saveresume.c b/saveresume.c index af71b5e..afd04d3 100644 --- a/saveresume.c +++ b/saveresume.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -55,6 +56,25 @@ int savefile(FILE *fp, int32_t version) } /* Suspend and resume */ + +char *strip(char *name) +{ + // Trim leading whitespace + while(isspace((unsigned char)*name)) + name++; // LCOV_EXCL_LINE + if(*name != '\0') { + // Trim trailing whitespace; + // might be left there by autocomplete + char *end = name + strlen(name) - 1; + while(end > name && isspace((unsigned char)*end)) + end--; + // Write new null terminator character + end[1] = '\0'; + } + + return name; +} + int suspend(void) { /* Suspend. Offer to save things in a file, but charging @@ -77,7 +97,10 @@ int suspend(void) char* name = myreadline("\nFile name: "); if (name == NULL) return GO_TOP; - fp = fopen(name, WRITE_MODE); + name = strip(name); + if (strlen(name) == 0) + return GO_TOP; // LCOV_EXCL_LINE + fp = fopen(strip(name), WRITE_MODE); if (fp == NULL) printf("Can't open file %s, try again.\n", name); free(name); @@ -109,12 +132,12 @@ int resume(void) while (fp == NULL) { char* name = myreadline("\nFile name: "); - // Autocomplete can leave the input with an extra trailing space. - if (name != NULL && strlen(name) > 0 && name[strlen(name) - 1] == ' ') - name[strlen(name) - 1] = '\0'; if (name == NULL) return GO_TOP; - fp = fopen(name, READ_MODE); + name = strip(name); + if (strlen(name) == 0) + return GO_TOP; // LCOV_EXCL_LINE + fp = fopen(name, READ_MODE); if (fp == NULL) printf("Can't open file %s, try again.\n", name); free(name); @@ -138,8 +161,8 @@ int restore(FILE* fp) if (save.version != VRSION) { rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), VRSION / 10, MOD(VRSION, 10)); } else if (!is_valid(save.game)) { - rspeak(SAVE_TAMPERING); - exit(EXIT_SUCCESS); + rspeak(SAVE_TAMPERING); // LCOV_EXCL_LINE + exit(EXIT_SUCCESS); // LCOV_EXCL_LINE } else { game = save.game; } From ca5b6975dcb7cc88e74ed85faecb4d792a2a4faf Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 12:41:13 -0400 Subject: [PATCH 034/213] NEWS update. --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 6e432f6..3692be2 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ Repository head:: Commands in magic-word sequence now interrupt it, as in original. + Bug fix for bird not starting caged in endgame. 1.14: 2023-03-09:: Added -a option for BBS door systems. From db8ca5eb2685ef5b215f7a8470ba36d088047bb1 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 12:58:11 -0400 Subject: [PATCH 035/213] Documentation polishing. --- notes.adoc | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/notes.adoc b/notes.adoc index 65971f8..2d61074 100644 --- a/notes.adoc +++ b/notes.adoc @@ -64,7 +64,7 @@ Bug fixes: * A few minor typos have been corrected: absence of capitalization on "Swiss" and "Persian", inconsistent spelling of "imbedded" vs. "embedded", - "eying" for "eyeing". "thresholds" for "threshholds". + "eying" for "eyeing", "thresholds" for "threshholds". * Under odd circumstances (dropping rug or vase outdoors) the game could formerly say "floor" when it should say "ground" (or "dirt", or something). @@ -116,14 +116,24 @@ FORTRAN-derived code that formerly implemented the save/restore functions; without C's fread(3)/fwrite() and structs it was necessarily pretty ugly by modern standards. Encryption and checksumming have been discarded - it's pointless to try -tamper-proofing saves when everyone has the source code. +tamper-proofing saves when everyone has the source code. However +the game still integrity-checks savefiles on resume. + +Save and resume filenames are stripped of leading and trailing +whitespace before processing. A -r command-line option has been added. When it is given (with a file path argument) it is functionally equivalent to a RESTORE command. -The game can be built in a mode that entirely disables save/resume, or -thart autosaves only on a termination signal (for use in BBS doort -systems). There is a new nmessage to inform the user about this. +An -a command-line option has been added (comditionally on +ADVENT_AUTOSAVE) for use in BBS door systems. When this option is +given, the game roads from the specified filename argument on startup +and saves to it on quit or a received signal. There is a new nmessage +to inform the user about this. + +The game can be built in a mode that entirely disables save/resume +(-DADVENT_NOSAVE). If the game had been built this way, a diagnostic is +emitted if you try to save or resume. == Translation == From 47c3d14a11c379e0c3ddf1bbff2c7149208416dc Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 17:14:18 -0400 Subject: [PATCH 036/213] Comment polishing. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index eebc68c..0f82c4a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Makefile for the open-source release of adventure 2.5 # To build with save/resume disabled, pass CFLAGS="-DADVENT_NOSAVE" -# To build with auto-save/resume enabled, pass CFLAGS="-D ADVENT_AUTOSAVE" +# To build with auto-save/resume enabled, pass CFLAGS="-DADVENT_AUTOSAVE" VERS=$(shell sed -n Date: Sun, 12 Mar 2023 17:21:15 -0400 Subject: [PATCH 037/213] Cleann up scratchfile after tesrs. --- tests/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index 1bd9311..fb03fdb 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -93,7 +93,7 @@ buildchecks: savegames OPTS=`sed -n /#options:/s///p <$${file}.log`; \ advent $$OPTS <$${file}.log >$${file}.chk 2>&1 || exit 1; \ done; \ - echo "inven" | advent isofoo.log /dev/stdin >multifile.chk + echo "inven" | advent isofoo.log /dev/stdin >multifile.chk; \ rm -f scratch.tmp RUN_TARGETS=$(TESTLOADS:%=run-regress-%) @@ -108,6 +108,7 @@ multifile-regress: TEST_TARGETS = $(RUN_TARGETS) multifile-regress tap: count $(TEST_TARGETS) + rm -f scratch.tmp count: @echo 1..$(words $(TEST_TARGETS)) From 5929a68b88ee9a244f5b12d08ead6a6692deb32d Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 17:37:58 -0400 Subject: [PATCH 038/213] Real test coverage dor SAVE_TAMPERING. --- saveresume.c | 4 ++-- tests/Makefile | 2 ++ tests/coverage_dungeon.py | 2 +- tests/savetamper.chk | 17 +++++++++++++++++ tests/savetamper.log | 4 ++++ 5 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 tests/savetamper.chk create mode 100644 tests/savetamper.log diff --git a/saveresume.c b/saveresume.c index afd04d3..c53ee49 100644 --- a/saveresume.c +++ b/saveresume.c @@ -161,8 +161,8 @@ int restore(FILE* fp) if (save.version != VRSION) { rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), VRSION / 10, MOD(VRSION, 10)); } else if (!is_valid(save.game)) { - rspeak(SAVE_TAMPERING); // LCOV_EXCL_LINE - exit(EXIT_SUCCESS); // LCOV_EXCL_LINE + rspeak(SAVE_TAMPERING); + exit(EXIT_SUCCESS); } else { game = save.game; } diff --git a/tests/Makefile b/tests/Makefile index fb03fdb..e33e684 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -52,6 +52,8 @@ savegames: @$(PARDIR)/cheat -d -900 -o cheat_numdie.adv > /tmp/cheat_numdie @$(ECHO) "cheat: Generate save file with -1000 deaths" @$(PARDIR)/cheat -d -1000 -o cheat_numdie1000.adv > /tmp/cheat_numdie1000 + @$(ECHO) "cheat: Generate tamper-detection test" + @$(PARDIR)/cheat -d 2000 -o cheat_savetamper.adv > /tmp/cheat_savetamper @$(ECHO) "cheat: Generate save file with version -1337" @$(PARDIR)/cheat -v -1337 -o resume_badversion.adv > /tmp/cheat_badversion @$(ECHO) "cheat: Generate save file 1000 saves" diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index 1f27838..e615239 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -25,7 +25,7 @@ YAML_PATH = "../adventure.yaml" HTML_TEMPLATE_PATH = "../templates/coverage_dungeon.html.tpl" DEFAULT_HTML_OUTPUT_PATH = "../coverage/adventure.yaml.html" DANGLING_ACTIONS = ["ACT_VERSION"] -DANGLING_MESSAGES = ["SAVERESUME_DISABLED", "SAVE_TAMPERING"] +DANGLING_MESSAGES = ["SAVERESUME_DISABLED"] STDOUT_REPORT_CATEGORY = " {name:.<19}: {percent:5.1f}% covered ({covered} of {total})\n" diff --git a/tests/savetamper.chk b/tests/savetamper.chk new file mode 100644 index 0000000..88f86f7 --- /dev/null +++ b/tests/savetamper.chk @@ -0,0 +1,17 @@ + +Welcome to Adventure!! Would you like instructions? + +> n + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> resume + +A dark fog creeps in to surround you. From somewhere in the fog you +hear a stern voice. "This Adventure has been tampered with! You have +been dabbling in magic, knowing not the havoc you might cause thereby. +Leave at once, before you do irrevocable harm!" The fog thickens, +until at last you can see nothing at all. Your vision then clears, +and you find yourself back in The Real World. diff --git a/tests/savetamper.log b/tests/savetamper.log new file mode 100644 index 0000000..e62dfbe --- /dev/null +++ b/tests/savetamper.log @@ -0,0 +1,4 @@ +## Resume from artificial "corrupted" save +n +resume +cheat_savetamper.adv From 17840d0e158e47e6dba3d62b4b8cdcf97071d924 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 12 Mar 2023 17:59:10 -0400 Subject: [PATCH 039/213] Comment polishing. --- adventure.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/adventure.yaml b/adventure.yaml index b246498..ab91969 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -24,7 +24,7 @@ # long: Long description, always shown on first encounter. # short: Short description. If none, use long description. # maptag: Tag for mapping, not used by the game itself. -# Only used if the "short" property in !!null. +# Only used if the "short" property is !!null. # conditions: A dictionary of attributes # LIT Light # OILY If FLUID flag is on: true for oil, false for water @@ -3188,7 +3188,6 @@ arbitrary_messages: !!omap I'm sorry, but that Adventure was begun using Version %d.%d of the save file format, and this program uses Version %d.%d. You must find an instance using that other version in order to resume that Adventure. -# This message is not currently used - SAVE_TAMPERING: |- A dark fog creeps in to surround you. From somewhere in the fog you hear a stern voice. "This Adventure has been tampered with! You have From 9b89dd2829c4d8315f35e2d80b44542c3f2b4115 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 14 Mar 2023 11:35:57 -0400 Subject: [PATCH 040/213] Experimental test production. --- tests/Makefile | 10 +++++++++- tests/oldfilter | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100755 tests/oldfilter diff --git a/tests/Makefile b/tests/Makefile index e33e684..8ea00c6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -36,7 +36,7 @@ check: savecheck .SUFFIXES: .chk clean: - rm -fr *~ adventure.text *.adv scratch.tmp + rm -fr *~ *.adv scratch.tmp *.ochk # Show summary lines for all tests. testlist: @@ -114,4 +114,12 @@ tap: count $(TEST_TARGETS) count: @echo 1..$(words $(TEST_TARGETS)) +# The following machinery tests the gane against a binary made from the advent430 branch +# The diff file produced has new spellings in it. + +ancient: + for x in *.log; do stem=$${x%.log}; echo $${stem}; ./advent430 <$${stem}.log | ./oldfilter >$${stem}.ochk; done + for x in *.log; do stem=$${x%.log}; diff -u $${stem}.chk $${stem}.log; done + rm *.ochk + # end diff --git a/tests/oldfilter b/tests/oldfilter new file mode 100755 index 0000000..a321792 --- /dev/null +++ b/tests/oldfilter @@ -0,0 +1,17 @@ +#!/bin/sh +# +# Filter the output from advent430 to make it compatible with +# newer ones +sed \ + -e '/ *$/s///' \ + -e '/bridge now spans the fissure/s//bridge spans the fissure/' \ + -e '/imbedded/s//embedded/' \ + -e '/persian/s//Persian/' \ + -e '/swiss/s//Swiss/' \ + -e '/eying/s//eyeing/' \ + -e '/swiss/s//Swiss/' \ + -e '/thresholds/s//threshholds/' \ + + +#end + From 786832210eba05e5fbc926b2ed850acb599c53ef Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 14 Mar 2023 12:51:26 -0400 Subject: [PATCH 041/213] Magic-number elimination. --- init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.c b/init.c index 9333df3..b890fba 100644 --- a/init.c +++ b/init.c @@ -95,7 +95,7 @@ int initialise(void) game.tally = game.tally - game.prop[treasure]; } } - game.conds = setbit(11); + game.conds = setbit(COND_HBASE); return seedval; } From 87855f8124b47fa530457b8b32f4f0a173be28b4 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 14 Mar 2023 12:52:35 -0400 Subject: [PATCH 042/213] Avoid a compiler warning. --- saveresume.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saveresume.c b/saveresume.c index c53ee49..b90595b 100644 --- a/saveresume.c +++ b/saveresume.c @@ -57,7 +57,7 @@ int savefile(FILE *fp, int32_t version) /* Suspend and resume */ -char *strip(char *name) +static char *strip(char *name) { // Trim leading whitespace while(isspace((unsigned char)*name)) From f07b3ba2d4af0b4178a43cf81c5ed0b3e074e53f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 16 Mar 2023 07:43:17 -0400 Subject: [PATCH 043/213] Address GitLab issue #66: Missing couple of ; in saveresume.c --- saveresume.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/saveresume.c b/saveresume.c index b90595b..575b11f 100644 --- a/saveresume.c +++ b/saveresume.c @@ -83,7 +83,7 @@ int suspend(void) * If ADVENT_NOSAVE is defined, gripe instead. */ #if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE - rspeak(SAVERESUME_DISABLED) + rspeak(SAVERESUME_DISABLED); return GO_TOP; #endif FILE *fp = NULL; @@ -118,7 +118,7 @@ int resume(void) * If ADVENT_NOSAVE is defined, gripe instead. */ #if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE - rspeak(SAVERESUME_DISABLED) + rspeak(SAVERESUME_DISABLED); return GO_TOP; #endif FILE *fp = NULL; From f5d15ab1f242249ed292235396ac659f6e48935e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 16 Mar 2023 08:32:59 -0400 Subject: [PATCH 044/213] Tapify output of cheat. --- cheat.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/cheat.c b/cheat.c index df9ab5b..ef9b014 100644 --- a/cheat.c +++ b/cheat.c @@ -21,6 +21,7 @@ int main(int argc, char *argv[]) char *savefilename = NULL; int version = 0; FILE *fp = NULL; + char *tapmessage = NULL; // Initialize game variables initialise(); @@ -31,14 +32,15 @@ int main(int argc, char *argv[]) game.saved = 1; /* Options. */ - const char* opts = "d:l:s:t:v:o:"; + const char* opts = "d:l:s:t:v:o:m:"; const char* usage = "Usage: %s [-d numdie] [-s numsaves] [-v version] -o savefilename \n" " -d number of deaths. Signed integer.\n" " -l lifetime of lamp in turns. Signed integer.\n" " -s number of saves. Signed integer.\n" " -t number of turns. Signed integer.\n" " -v version number of save format.\n" - " -o required. File name of save game to write.\n"; + " -o required. File name of save game to write.\n" + " -m specify message for YAP output\n"; while ((ch = getopt(argc, argv, opts)) != EOF) { switch (ch) { @@ -65,6 +67,9 @@ int main(int argc, char *argv[]) case 'o': savefilename = optarg; break; + case 'm': + tapmessage = optarg; + break; default: fprintf(stderr, usage, argv[0]); @@ -75,26 +80,33 @@ int main(int argc, char *argv[]) // Save filename required; the point of cheat is to generate save file if (savefilename == NULL) { - fprintf(stderr, - usage, argv[0]); - fprintf(stderr, - "ERROR: filename required\n"); - exit(EXIT_FAILURE); + if (tapmessage != NULL) { + printf("not ok - %s: filename required\n", tapmessage); + } else { + printf("not ok - filename required\n"); + exit(EXIT_FAILURE); + } } fp = fopen(savefilename, WRITE_MODE); if (fp == NULL) { - fprintf(stderr, - "Can't open file %s. Exiting.\n", savefilename); - exit(EXIT_FAILURE); + if (tapmessage != NULL) { + printf("not ok - %s: can't open file %s. Exiting.\n", tapmessage, savefilename); + } else { + printf("not ok - can't open file %s.\n", savefilename); + exit(EXIT_FAILURE); + } } savefile(fp, version); fclose(fp); - printf("cheat: %s created.\n", savefilename); - + if (tapmessage != NULL) { + printf("ok - %s\n", tapmessage); + } else { + printf("cheat: %s created.\n", savefilename); + } return EXIT_SUCCESS; } From 9758883ea24c7eb5e4a339b6e2427862c1457add Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 16 Mar 2023 08:51:57 -0400 Subject: [PATCH 045/213] More TAPification. --- tests/Makefile | 52 +++++++++++++++++++++++++++++------------------ tests/outcheck.sh | 5 +++++ 2 files changed, 37 insertions(+), 20 deletions(-) create mode 100755 tests/outcheck.sh diff --git a/tests/Makefile b/tests/Makefile index 8ea00c6..c0a9b0c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -47,40 +47,52 @@ listcheck: done # Generate bogus savegames. -savegames: - @$(ECHO) "cheat: Generate save file with -900 deaths" +sgame1: @$(PARDIR)/cheat -d -900 -o cheat_numdie.adv > /tmp/cheat_numdie - @$(ECHO) "cheat: Generate save file with -1000 deaths" + @./outcheck.sh "cheat: Generate save file with -900 deaths" +sgame2: @$(PARDIR)/cheat -d -1000 -o cheat_numdie1000.adv > /tmp/cheat_numdie1000 - @$(ECHO) "cheat: Generate tamper-detection test" + @./outcheck.sh "cheat: Generate save file with -1000 deaths" +sgame3: @$(PARDIR)/cheat -d 2000 -o cheat_savetamper.adv > /tmp/cheat_savetamper - @$(ECHO) "cheat: Generate save file with version -1337" + @./outcheck.sh "cheat: Generate tamper-detection test" +sgame4: @$(PARDIR)/cheat -v -1337 -o resume_badversion.adv > /tmp/cheat_badversion - @$(ECHO) "cheat: Generate save file 1000 saves" + @./outcheck.sh "cheat: Generate save file with version -1337" +sgame5: @$(PARDIR)/cheat -s -1000 -o thousand_saves.adv > /tmp/cheat_1000saves - @$(ECHO) "cheat: Generate save file 1000 turns" + @./outcheck.sh "cheat: Generate save file 1000 saves" +sgame6: @$(PARDIR)/cheat -t -1000 -o thousand_saves.adv > /tmp/cheat_1000turns - @$(ECHO) "cheat: Generate save file 1000 turns" + @./outcheck.sh "cheat: Generate save file 1000 turns" +sgame7: @$(PARDIR)/cheat -l -1000 -o thousand_lamp.adv > /tmp/cheat_1000lamp - @rm -f /tmp/cheat* + @./outcheck.sh "cheat: Generate save file 1000 turns" +SGAMES = sgame1 sgame2 sgame3 sgame4 sgame5 sgame6 sgame7 # Force coverage of cheat edgecases -savecheck: savegames - @$(ECHO) "TEST cheat: Bogus option for save file generation" +scheck1: @$(PARDIR)/cheat -QqQ 2> /tmp/coverage_cheat_batopt | true - @$(ECHO) "TEST cheat: No save file specified" + @./outcheck.sh "cheat: bogus option for save file generation" +scheck2: @$(PARDIR)/cheat 2>/dev/null | true - @$(ECHO) "TEST cheat: Fail to save because we omit -o" + @./outcheck.sh "cheat: No save file specified" +scheck3: @$(PARDIR)/cheat -d 1 2> /tmp/coverage_cheat_nooutput | true - @$(ECHO) "TEST cheat: Fail to save to invalid path" + @./outcheck.sh "cheat: doesn't save because we omit -o" +scheck4: @$(PARDIR)/cheat -o / 2> /tmp/coverage_cheat_badoutput | true - @$(ECHO) "TEST advent: Start with invalid file with -r" + @./outcheck.sh "cheat: doesn't save to invalid path" +scheck5: @$(advent) -r /badfilename < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1 - @$(ECHO) "TEST advent: Start with invalid file with -l" + @./outcheck.sh "cheat: doesn't start with invalid file with -r" +scheck6: @$(advent) -l / < pitfall.log > /tmp/coverage_advent_logfail 2>&1 || exit 1 - @$(ECHO) "TEST advent: Test -r with valid input" + @./outcheck.sh "cheat: doesn't start with invalid file passed to -l" +scheck7: @$(advent) -r thousand_saves.adv < pitfall.log > /tmp/coverage_advent_readfail 2>&1 || exit 1 - @rm -f /tmp/coverage* + @./outcheck.sh "test -r with valid input" +SCHECKS = scheck1 scheck2 scheck3 scheck4 scheck5 scheck6 scheck7 coverage: check lcov -t "advent" -o $(PARDIR)/advent.info -c -d $(PARDIR) --gcov-tool=$(GCOV) @@ -107,10 +119,10 @@ $(RUN_TARGETS): run-regress-%: %.log multifile-regress: @(echo "inven" | advent isofoo.log /dev/stdin) | tapdiffer "multifile: multiple-file test" multifile.chk -TEST_TARGETS = $(RUN_TARGETS) multifile-regress +TEST_TARGETS = $(SGAMES) $(SCHECKS) $(RUN_TARGETS) multifile-regress tap: count $(TEST_TARGETS) - rm -f scratch.tmp + @rm -f scratch.tmp /tmp/coverage* /tmp/cheat* count: @echo 1..$(words $(TEST_TARGETS)) diff --git a/tests/outcheck.sh b/tests/outcheck.sh new file mode 100755 index 0000000..e46979f --- /dev/null +++ b/tests/outcheck.sh @@ -0,0 +1,5 @@ +#! /bin/sh +case $? in + 0) echo "ok - $1 succeeded";; + *) echo "not ok - $1 failed";; +esac From 9fdbe733156e521443268ea49e1016d909df5643 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 16 Mar 2023 10:15:47 -0400 Subject: [PATCH 046/213] Revert "Tapify output of cheat." There was a better way. --- cheat.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/cheat.c b/cheat.c index ef9b014..df9ab5b 100644 --- a/cheat.c +++ b/cheat.c @@ -21,7 +21,6 @@ int main(int argc, char *argv[]) char *savefilename = NULL; int version = 0; FILE *fp = NULL; - char *tapmessage = NULL; // Initialize game variables initialise(); @@ -32,15 +31,14 @@ int main(int argc, char *argv[]) game.saved = 1; /* Options. */ - const char* opts = "d:l:s:t:v:o:m:"; + const char* opts = "d:l:s:t:v:o:"; const char* usage = "Usage: %s [-d numdie] [-s numsaves] [-v version] -o savefilename \n" " -d number of deaths. Signed integer.\n" " -l lifetime of lamp in turns. Signed integer.\n" " -s number of saves. Signed integer.\n" " -t number of turns. Signed integer.\n" " -v version number of save format.\n" - " -o required. File name of save game to write.\n" - " -m specify message for YAP output\n"; + " -o required. File name of save game to write.\n"; while ((ch = getopt(argc, argv, opts)) != EOF) { switch (ch) { @@ -67,9 +65,6 @@ int main(int argc, char *argv[]) case 'o': savefilename = optarg; break; - case 'm': - tapmessage = optarg; - break; default: fprintf(stderr, usage, argv[0]); @@ -80,33 +75,26 @@ int main(int argc, char *argv[]) // Save filename required; the point of cheat is to generate save file if (savefilename == NULL) { - if (tapmessage != NULL) { - printf("not ok - %s: filename required\n", tapmessage); - } else { - printf("not ok - filename required\n"); - exit(EXIT_FAILURE); - } + fprintf(stderr, + usage, argv[0]); + fprintf(stderr, + "ERROR: filename required\n"); + exit(EXIT_FAILURE); } fp = fopen(savefilename, WRITE_MODE); if (fp == NULL) { - if (tapmessage != NULL) { - printf("not ok - %s: can't open file %s. Exiting.\n", tapmessage, savefilename); - } else { - printf("not ok - can't open file %s.\n", savefilename); - exit(EXIT_FAILURE); - } + fprintf(stderr, + "Can't open file %s. Exiting.\n", savefilename); + exit(EXIT_FAILURE); } savefile(fp, version); fclose(fp); - if (tapmessage != NULL) { - printf("ok - %s\n", tapmessage); - } else { - printf("cheat: %s created.\n", savefilename); - } + printf("cheat: %s created.\n", savefilename); + return EXIT_SUCCESS; } From 8fd3eb8b92433c0e201637899206e3c08a1b40bd Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 16 Mar 2023 10:18:56 -0400 Subject: [PATCH 047/213] Testing simplification. --- tests/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index c0a9b0c..90120ef 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -29,9 +29,7 @@ TESTLOADS := $(shell ls -1 *.log | sed '/.log/s///' | sort) check: savecheck @make tap | tapview - @echo "=== No diff output is good news." @-advent -x 2>/dev/null || exit 0 # Get usage message into coverage tests - @-advent -l /dev/null /dev/null .SUFFIXES: .chk From b044e9ab422ef7501c5ce98ec39eb89e2f142c5e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 21 Mar 2023 14:07:04 -0400 Subject: [PATCH 048/213] Move in the direction of being able to do ancient regression tests. --- tests/Makefile | 22 +++++++++++++++------- tests/newfilter | 8 ++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) create mode 100755 tests/newfilter diff --git a/tests/Makefile b/tests/Makefile index 90120ef..347b0f9 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -34,7 +34,7 @@ check: savecheck .SUFFIXES: .chk clean: - rm -fr *~ *.adv scratch.tmp *.ochk + rm -fr *~ *.adv scratch.tmp *.ochk advent430 adventure.data # Show summary lines for all tests. testlist: @@ -124,12 +124,20 @@ tap: count $(TEST_TARGETS) count: @echo 1..$(words $(TEST_TARGETS)) -# The following machinery tests the gane against a binary made from the advent430 branch -# The diff file produced has new spellings in it. +# The following machinery tests the gane against a binary made from +# the advent430 branch To use it, switch to that branch, build the +# binary, sand run it once to generate adventure.data, then switch +# back to master leaving advent430 and adventure.data in place (make +# clean does not remove them). +# +# The diff file produced has corrected spellings in it. That's what oldfilter +# is for, to massage out the orioginal dpellings and avoid noise diffs. +# Diffs in amount of whitespace and trailing whitespace are ignored -ancient: - for x in *.log; do stem=$${x%.log}; echo $${stem}; ./advent430 <$${stem}.log | ./oldfilter >$${stem}.ochk; done - for x in *.log; do stem=$${x%.log}; diff -u $${stem}.chk $${stem}.log; done - rm *.ochk +ancient: $(SGAMES) + @if [ -f ../advent430 ]; then cp ../advent430 ../adventure.data .; else echo "advent430 nonexistent"; exit 1; fi + @for x in *.log; do stem=$${x%.log}; echo $${stem}; ./advent430 <$${stem}.log | ./oldfilter >$${stem}.ochk; done + @for x in *.log; do stem=$${x%.log}; ./newfilter <$${stem}.chk | diff -ubZ $${stem}.ochk -; done + @rm *.ochk advent430 adventure.data # end diff --git a/tests/newfilter b/tests/newfilter new file mode 100755 index 0000000..dca9f05 --- /dev/null +++ b/tests/newfilter @@ -0,0 +1,8 @@ +#!/bin/sh +# +# Filter the output from Open Adventure versions to make it compatible with +# the filtered versions of logs made from advent430. +sed \ + -e '/bridge now spans the fissure/s//bridge spans the fissure/' \ + +# end From 327efd3678b973ecb348d18001aa6f2e99906303 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 21 Mar 2023 20:57:03 -0400 Subject: [PATCH 049/213] Test cleanup. --- tests/eggs_done.chk | 2 +- tests/eggs_done.log | 4 ++-- tests/eggs_vanish.chk | 2 +- tests/eggs_vanish.log | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/eggs_done.chk b/tests/eggs_done.chk index baa766f..70dcf03 100644 --- a/tests/eggs_done.chk +++ b/tests/eggs_done.chk @@ -1167,7 +1167,7 @@ You're in Giant Room. There is a large nest here, full of golden eggs! -> g egg +> take egg OK diff --git a/tests/eggs_done.log b/tests/eggs_done.log index 1d600f0..2384789 100644 --- a/tests/eggs_done.log +++ b/tests/eggs_done.log @@ -184,11 +184,11 @@ w d climb w -g egg +take egg n fee fie foe foo look -inven \ No newline at end of file +inven diff --git a/tests/eggs_vanish.chk b/tests/eggs_vanish.chk index 5f84bfc..2fe0579 100644 --- a/tests/eggs_vanish.chk +++ b/tests/eggs_vanish.chk @@ -399,7 +399,7 @@ the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. There is a large nest here, full of golden eggs! -> g +> take OK diff --git a/tests/eggs_vanish.log b/tests/eggs_vanish.log index 452335d..b14fb72 100644 --- a/tests/eggs_vanish.log +++ b/tests/eggs_vanish.log @@ -59,7 +59,7 @@ d water plant climb w -g +take n fee fie @@ -67,4 +67,4 @@ foe foo # go south, east to arrive at LOC_CAVEIN for coverage s -e \ No newline at end of file +e From a006bdd2724a262acdd5b79596526d069114a336 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 21 Mar 2023 23:25:43 -0400 Subject: [PATCH 050/213] TAPify the ancient-diffs report. --- tests/Makefile | 4 ++-- tests/tapdiffer | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 347b0f9..f2addb9 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -136,8 +136,8 @@ count: ancient: $(SGAMES) @if [ -f ../advent430 ]; then cp ../advent430 ../adventure.data .; else echo "advent430 nonexistent"; exit 1; fi - @for x in *.log; do stem=$${x%.log}; echo $${stem}; ./advent430 <$${stem}.log | ./oldfilter >$${stem}.ochk; done - @for x in *.log; do stem=$${x%.log}; ./newfilter <$${stem}.chk | diff -ubZ $${stem}.ochk -; done + @-for x in *.log; do stem=$${x%.log}; echo $${stem}; ./advent430 <$${stem}.log | ./oldfilter >$${stem}.ochk; done + @-(for x in *.log; do stem=$${x%.log}; legend=$$(sed -n '/^## /s///p' <$$x 2>/dev/null || echo "(no description)"); ./newfilter <$${stem}.chk | tapdiffer -w "$${legend}" $${stem}.ochk; done; echo 1..$(words $(shell ls *.log))) | tapview @rm *.ochk advent430 adventure.data # end diff --git a/tests/tapdiffer b/tests/tapdiffer index 3ddd629..f48bcc3 100755 --- a/tests/tapdiffer +++ b/tests/tapdiffer @@ -8,12 +8,20 @@ # A nonempty diff is shipped as a TAP YAML block following "not ok" # unless QUIET=1 in the environment. # +if [ "$1" = "-w" ] +then + diffopts=-ubZ + shift +else + diffopts=-u +fi + legend=$1 checkfile=$2 trap 'rm /tmp/tapdiff$$' EXIT HUP INT QUIT TERM -if diff --text -u ${checkfile} - >/tmp/tapdiff$$ +if diff --text "${diffopts}" ${checkfile} - >/tmp/tapdiff$$ then echo "ok - ${legend}" else From 07a0f066ba7e67f774ed1e1f7d06daebf1f46e18 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 21 Mar 2023 23:57:36 -0400 Subject: [PATCH 051/213] Quoting fixes in the YAML. --- adventure.yaml | 6 +++--- tests/cheatresume.chk | 4 ++-- tests/specials.chk | 2 +- tests/win430.chk | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/adventure.yaml b/adventure.yaml index ab91969..84ec1cb 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -3227,10 +3227,10 @@ classes: message: 'All of Adventuredom gives tribute to you, Adventurer Grandmaster!' - threshold: 9999 message: |- - 'Adventuredom stands in awe -- you have now joined the ranks of the + Adventuredom stands in awe -- you have now joined the ranks of the W O R L D C H A M P I O N A D V E N T U R E R S ! It may interest you to know that the Dungeon-Master himself has, to - my knowledge, never achieved this threshold in fewer than 330 turns.' + my knowledge, never achieved this threshold in fewer than 330 turns. turn_thresholds: - threshold: 350 @@ -4144,7 +4144,7 @@ actions: !!omap message: |- Mist is a white vapor, usually water, seen from time to time in caverns. It can be found anywhere but is frequently a sign of a deep - pit leading down to water.' + pit leading down to water. words: ['mist'] noaction: true - FBOMB: diff --git a/tests/cheatresume.chk b/tests/cheatresume.chk index 5ca8d1b..08c1263 100644 --- a/tests/cheatresume.chk +++ b/tests/cheatresume.chk @@ -18,10 +18,10 @@ Now let's see you do it without suspending in mid-Adventure. You scored 9031 out of a possible 430, using 0 turns. -'Adventuredom stands in awe -- you have now joined the ranks of the +Adventuredom stands in awe -- you have now joined the ranks of the W O R L D C H A M P I O N A D V E N T U R E R S ! It may interest you to know that the Dungeon-Master himself has, to -my knowledge, never achieved this threshold in fewer than 330 turns.' +my knowledge, never achieved this threshold in fewer than 330 turns. To achieve the next higher rating would be a neat trick! Congratulations!! diff --git a/tests/specials.chk b/tests/specials.chk index 1b207d0..75f457e 100644 --- a/tests/specials.chk +++ b/tests/specials.chk @@ -73,7 +73,7 @@ I'm as confused as you are. Mist is a white vapor, usually water, seen from time to time in caverns. It can be found anywhere but is frequently a sign of a deep -pit leading down to water.' +pit leading down to water. > fuck diff --git a/tests/win430.chk b/tests/win430.chk index a8e15a6..0a7e9c8 100644 --- a/tests/win430.chk +++ b/tests/win430.chk @@ -2099,10 +2099,10 @@ friendly elves carry the conquering adventurer off into the sunset. You scored 430 out of a possible 430, using 349 turns. -'Adventuredom stands in awe -- you have now joined the ranks of the +Adventuredom stands in awe -- you have now joined the ranks of the W O R L D C H A M P I O N A D V E N T U R E R S ! It may interest you to know that the Dungeon-Master himself has, to -my knowledge, never achieved this threshold in fewer than 330 turns.' +my knowledge, never achieved this threshold in fewer than 330 turns. To achieve the next higher rating would be a neat trick! Congratulations!! From 4fa3d4d758fc99a3afc6af9269e3f214a8151a85 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 22 Mar 2023 06:36:03 -0400 Subject: [PATCH 052/213] Test cleanup and reconvilation with advent430. --- tests/boulder2.chk | 4 ++-- tests/boulder2.log | 6 +++--- tests/hint_jade.chk | 6 +++--- tests/hint_jade.log | 6 +++--- tests/oldfilter | 7 +++++-- tests/pirate_spotted.chk | 6 +++--- tests/pirate_spotted.log | 6 +++--- tests/reach_ledge_short.chk | 2 +- tests/reach_ledge_short.log | 2 +- tests/troll_returns.chk | 4 ++-- tests/troll_returns.log | 4 ++-- 11 files changed, 28 insertions(+), 25 deletions(-) diff --git a/tests/boulder2.chk b/tests/boulder2.chk index cdd7dbb..9430308 100644 --- a/tests/boulder2.chk +++ b/tests/boulder2.chk @@ -984,7 +984,7 @@ There is a huge beanstalk growing out of the west pit up to the hole. You are at the bottom of the eastern pit in the Twopit Room. There is a small pool of oil in one corner of the pit. -> g oil +> get oil Your bottle is now full of oil. @@ -1351,7 +1351,7 @@ You're in Giant Room. There is a large nest here, full of golden eggs! -> g +> get OK diff --git a/tests/boulder2.log b/tests/boulder2.log index ad4acd4..b52c757 100644 --- a/tests/boulder2.log +++ b/tests/boulder2.log @@ -156,7 +156,7 @@ u drop appen e d -g oil +get oil u w d @@ -220,7 +220,7 @@ w d climb w -g +get n take bottl n @@ -239,4 +239,4 @@ fork ne e out -e \ No newline at end of file +e diff --git a/tests/hint_jade.chk b/tests/hint_jade.chk index f16accf..fc9233b 100644 --- a/tests/hint_jade.chk +++ b/tests/hint_jade.chk @@ -962,7 +962,7 @@ There is a huge beanstalk growing out of the west pit up to the hole. You are at the bottom of the eastern pit in the Twopit Room. There is a small pool of oil in one corner of the pit. -> g oil +> get oil Your bottle is now full of oil. @@ -1325,7 +1325,7 @@ You're in Giant Room. There is a large nest here, full of golden eggs! -> g +> get OK @@ -1545,7 +1545,7 @@ There is a huge beanstalk growing out of the west pit up to the hole. You're in east pit. -> g oil +> get oil Your bottle is now full of oil. diff --git a/tests/hint_jade.log b/tests/hint_jade.log index d5550d0..58a44fe 100644 --- a/tests/hint_jade.log +++ b/tests/hint_jade.log @@ -151,7 +151,7 @@ u drop appen e d -g oil +get oil u w d @@ -214,7 +214,7 @@ w d climb w -g +get n take bottl n @@ -249,7 +249,7 @@ se se w d -g oil +get oil u w w diff --git a/tests/oldfilter b/tests/oldfilter index a321792..fcda48e 100755 --- a/tests/oldfilter +++ b/tests/oldfilter @@ -9,8 +9,11 @@ sed \ -e '/persian/s//Persian/' \ -e '/swiss/s//Swiss/' \ -e '/eying/s//eyeing/' \ - -e '/swiss/s//Swiss/' \ - -e '/thresholds/s//threshholds/' \ + -e '/threshhold/s//threshold/' \ + -e '/NAGGING/s//nagging/' \ + -e '/DOING/s//doing/' \ + -e '/SOMETHING/s//something/' \ + -e '/EW/s//ew/' \ #end diff --git a/tests/pirate_spotted.chk b/tests/pirate_spotted.chk index 5cfc3c4..b57d7e7 100644 --- a/tests/pirate_spotted.chk +++ b/tests/pirate_spotted.chk @@ -984,7 +984,7 @@ There is a huge beanstalk growing out of the west pit up to the hole. You are at the bottom of the eastern pit in the Twopit Room. There is a small pool of oil in one corner of the pit. -> g oil +> get oil Your bottle is now full of oil. @@ -1351,7 +1351,7 @@ You're in Giant Room. There is a large nest here, full of golden eggs! -> g +> get OK @@ -1547,7 +1547,7 @@ There is a huge beanstalk growing out of the west pit up to the hole. You're in east pit. -> g oil +> get oil Your bottle is now full of oil. diff --git a/tests/pirate_spotted.log b/tests/pirate_spotted.log index 1eeca5d..0c6512a 100644 --- a/tests/pirate_spotted.log +++ b/tests/pirate_spotted.log @@ -156,7 +156,7 @@ u drop appen e d -g oil +get oil u w d @@ -220,7 +220,7 @@ w d climb w -g +get n take bottl n @@ -250,7 +250,7 @@ se se w d -g oil +get oil u e w diff --git a/tests/reach_ledge_short.chk b/tests/reach_ledge_short.chk index c5e083e..d6f8175 100644 --- a/tests/reach_ledge_short.chk +++ b/tests/reach_ledge_short.chk @@ -1333,7 +1333,7 @@ There is a huge beanstalk growing out of the west pit up to the hole. You're in east pit. -> g oil +> get oil Your bottle is now full of oil. diff --git a/tests/reach_ledge_short.log b/tests/reach_ledge_short.log index a121333..2c33a04 100644 --- a/tests/reach_ledge_short.log +++ b/tests/reach_ledge_short.log @@ -214,7 +214,7 @@ se se west d -g oil +get oil u west west diff --git a/tests/troll_returns.chk b/tests/troll_returns.chk index b4d7c2e..6b597d9 100644 --- a/tests/troll_returns.chk +++ b/tests/troll_returns.chk @@ -748,7 +748,7 @@ There is a huge beanstalk growing out of the west pit up to the hole. You are at the bottom of the eastern pit in the Twopit Room. There is a small pool of oil in one corner of the pit. -> g oil +> get oil Your bottle is now full of oil. @@ -803,7 +803,7 @@ You're in Giant Room. There is a large nest here, full of golden eggs! -> g +> take OK diff --git a/tests/troll_returns.log b/tests/troll_returns.log index 2b93a30..2697faf 100644 --- a/tests/troll_returns.log +++ b/tests/troll_returns.log @@ -119,7 +119,7 @@ water plant u e d -g oil +get oil u w d @@ -128,7 +128,7 @@ w n oil door s -g +take n n w From fefd2a19fb93dcb55eac5fefa5d5ab8d5c66c5ee Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 22 Mar 2023 06:40:03 -0400 Subject: [PATCH 053/213] Remove redundant test. --- tests/seedcrash.chk | 1306 ------------------------------------------- tests/seedcrash.log | 225 -------- 2 files changed, 1531 deletions(-) delete mode 100644 tests/seedcrash.chk delete mode 100644 tests/seedcrash.log diff --git a/tests/seedcrash.chk b/tests/seedcrash.chk deleted file mode 100644 index 1f10129..0000000 --- a/tests/seedcrash.chk +++ /dev/null @@ -1,1306 +0,0 @@ - -Welcome to Adventure!! Would you like instructions? - -> n - -You are standing at the end of a road before a small brick building. -Around you is a forest. A small stream flows out of the building and -down a gully. - -> seed 1635997320 - -Seed set to 1635997320 - -You're in front of building. - -> in - -You are inside a building, a well house for a large spring. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -There is food here. - -There is a bottle of water here. - -> take lamp - -OK - -> xyzzy - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> take rod - -OK - -> e - -You are crawling over cobbles in a low passage. There is a dim light -at the east end of the passage. - -There is a small wicker cage discarded nearby. - -> take cage - -OK - -> w - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You are in a debris room filled with stuff washed in from the surface. -A low wide passage with cobbles becomes plugged with mud and debris -here, but an awkward canyon leads upward and west. In the mud someone -has scrawled, "MAGIC WORD XYZZY". - -> w - -You are in an awkward sloping east/west canyon. - -> w - -You are in a splendid chamber thirty feet high. The walls are frozen -rivers of orange stone. An awkward canyon and a good passage exit -from east and west sides of the chamber. - -A cheerful little bird is sitting here singing. - -> drop rod - -OK - -> take bird - -OK - -> take rod - -OK - -> w - -At your feet is a small pit breathing traces of white mist. An east -passage ends here except for a small crack leading on. - -Rough stone steps lead down the pit. - -> free bird - -OK - -> wave rod - -The bird flies about agitatedly for a moment, then disappears through -the crack. It reappears shortly, carrying in its beak a jade -necklace, which it drops at your feet. - -> drop rod - -OK - -> take bird - -OK - -> take jade - -OK - -> e - -You're in bird chamber. - -> e - -You are in an awkward sloping east/west canyon. - -> e - -You're in debris room. - -> off - -Your lamp is now off. - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> xyzzy - ->>Foof!<< - -You're inside building. - -There are some keys on the ground here. - -There is food here. - -There is a bottle of water here. - -> drop jade - -OK - -> xyzzy - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You're in debris room. - -> w - -You are in an awkward sloping east/west canyon. - -> w - -You're in bird chamber. - -> w - -You're at top of small pit. - -A three foot black rod with a rusty star on an end lies nearby. - -Rough stone steps lead down the pit. - -> take rod - -OK - -> d - -You are at one end of a vast hall stretching forward out of sight to -the west. There are openings to either side. Nearby, a wide stone -staircase leads downward. The hall is filled with wisps of white mist -swaying to and fro almost as if alive. A cold wind blows up the -staircase. There is a passage at the top of a dome behind you. - -Rough stone steps lead up the dome. - -> w - -You are on the east bank of a fissure slicing clear across the hall. -The mist is quite thick here, and the fissure is too wide to jump. - -> wave rod - -The bird flies agitatedly about the cage. - -A crystal bridge now spans the fissure. - -> drop rod - -OK - -> e - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> n - -You are in the Hall of the Mountain King, with passages off in all -directions. - -A huge green fierce snake bars the way! - -> free bird - -The little bird attacks the green snake, and in an astounding flurry -drives the snake away. - -> take bird - -OK - -> s - -You are in the south side chamber. - -There is precious jewelry here! - -> take jewelry - -OK - -> n - -You're in Hall of Mt King. - -> sw - -You are in a secret canyon which here runs e/w. It crosses over a -very tight canyon 15 feet below. If you go down you may not be able -to get back up. - -> w - -You are in a secret canyon which exits to the north and east. - -A huge green fierce dragon bars the way! - -The dragon is sprawled out on a Persian rug!! - -> feed dragon - -There's nothing here it wants to eat (except perhaps you). - -> kill dragon - -With what? Your bare hands? - -> yes - -Congratulations! You have just vanquished a dragon with your bare -hands! (Unbelievable, isn't it?) - -You are in a secret canyon which exits to the north and east. - -There is a Persian rug spread out on the floor! - -The blood-specked body of a huge green dead dragon lies to one side. - -> drink blood - -Your head buzzes strangely for a moment. - -> take rug - -OK - -> e - -You're in secret e/w canyon above tight canyon. - -> e - -You're in Hall of Mt King. - -> n - -You are in a low n/s passage at a hole in the floor. The hole goes -down to an e/w passage. - -There are bars of silver here! - -> take silver - -OK - -> n - -You are in a large room, with a passage to the south, a passage to the -west, and a wall of broken rock to the east. There is a large "Y2" on -a rock in the room's center. - -> off - -Your lamp is now off. - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> plugh - ->>Foof!<< - -You're inside building. - -A precious jade necklace has been dropped here! - -There are some keys on the ground here. - -There is food here. - -There is a bottle of water here. - -> drop jewelry - -OK - -> drop rug - -OK - -> drop silver - -OK - -> out - -You're in front of building. - -> s - -You are in a valley in the forest beside a stream tumbling along a -rocky bed. - -> w - -You are wandering aimlessly through the forest. - -> n - -You are wandering aimlessly through the forest. - -Your keen eye spots a severed leporine appendage lying on the ground. - -> take appendage - -OK - -> free bird - -OK - -> drop cage - -OK - -> listen - -The bird is singing to you in gratitude for your having returned it to -its home. In return, it informs you of a magic word which it thinks -you may find useful somewhere near the Hall of Mists. The magic word -changes frequently, but for now the bird believes it is "F'UNJ". You -thank the bird for this information, and it flies off into the forest. - -> s - -You are wandering aimlessly through the forest. - -> s - -You're in valley. - -> n - -You're in front of building. - -> in - -You're inside building. - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is precious jewelry here! - -A precious jade necklace has been dropped here! - -There are some keys on the ground here. - -There is food here. - -There is a bottle of water here. - -> take water - -OK - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You're at "Y2". - -> plover - ->>Foof!<< - -You're in a small chamber lit by an eerie green light. An extremely -narrow tunnel exits to the west. A dark corridor leads ne. - -There is an emerald here the size of a plover's egg! - -> ne - -You're in the dark-room. A corridor leading south is the only exit. - -A massive stone tablet embedded in the wall reads: -"Congratulations on bringing light into the dark-room!" - -There is a platinum pyramid here, 8 inches on a side! - -> take pyramid - -OK - -> s - -You're in Plover Room. - -There is an emerald here the size of a plover's egg! - -> plover - ->>Foof!<< - -You're at "Y2". - -A hollow voice says "PLUGH". - -> s - -You're in n/s passage above e/w passage. - -> d - -A little dwarf just walked around a corner, saw you, threw a little -axe at you which missed, cursed, and ran away. - -You are in a dirty broken passage. To the east is a crawl. To the -west is a large passage. Above you is a hole to another passage. - -There is a little axe here. - -> take axe - -OK - -> u - -There is a threatening little dwarf in the room with you! - -You're in n/s passage above e/w passage. - -> s - -There is a threatening little dwarf in the room with you! - -You're in Hall of Mt King. - -> up - -There is a threatening little dwarf in the room with you! - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> w - -There is a threatening little dwarf in the room with you! - -You're on east bank of fissure. - -A three foot black rod with a rusty star on an end lies nearby. - -A crystal bridge spans the fissure. - -> w - -There is a threatening little dwarf in the room with you! - -You are on the west side of the fissure in the Hall of Mists. - -There are diamonds here! - -A crystal bridge spans the fissure. - -> w - -There is a threatening little dwarf in the room with you! - -You are at the west end of the Hall of Mists. A low wide crawl -continues west and another goes north. To the south is a little -passage 6 feet off the floor. - -> w - -There are 2 threatening little dwarves in the room with you. - -One sharp nasty knife is thrown at you! - -It misses! - -You are at the east end of a very long hall apparently without side -chambers. To the east a low wide crawl slants up. To the north a -round two foot hole slants down. - -> throw axe - -You killed a little dwarf. The body vanishes in a cloud of greasy -black smoke. - -There is a threatening little dwarf in the room with you! - -One sharp nasty knife is thrown at you! - -It misses! - -You're at east end of long hall. - -There is a little axe here. - -> take axe - -OK - -> w - -There is a threatening little dwarf in the room with you! - -You are at the west end of a very long featureless hall. The hall -joins up with a narrow north/south passage. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a maze of twisty little passages, all different. - -> sw - -There is a threatening little dwarf in the room with you! - -You are in a little maze of twisty passages, all different. - -> se - -There is a threatening little dwarf in the room with you! - -You are in a little maze of twisting passages, all different. - -> s - -There is a threatening little dwarf in the room with you! - -Dead end - -There is a massive and somewhat battered vending machine here. The -instructions on it read: "Drop coins here to receive fresh batteries." - -> kill machine - -As you strike the vending machine, it pivots backward along with a -section of wall, revealing a dark passage leading south. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a long, rough-hewn, north/south corridor. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a large chamber with passages to the west and north. - -A formidable ogre bars the northern exit. - -> kill ogre - -The ogre, who despite his bulk is quite agile, easily dodges your -attack. He seems almost amused by your puny effort. - -One sharp nasty knife is thrown at you! - -The ogre, distracted by your rush, is struck by the knife. With a -blood-curdling yell he turns and bounds after the dwarf, who flees -in panic. You are left alone in the room. - -> n - -You are in the ogre's storeroom. The only exit is to the south. - -There is an enormous ruby here! - -> take ruby - -OK - -> s - -You are in a large chamber with passages to the west and north. - -> w - -You are in a long, rough-hewn, north/south corridor. - -> n - -Dead end - -There is a massive vending machine here, swung back to reveal a -southward passage. - -> n - -You are in a little maze of twisting passages, all different. - -> n - -You are in a little maze of twisty passages, all different. - -> nw - -You are in a maze of twisty little passages, all different. - -> d - -You're at west end of long hall. - -> e - -You're at east end of long hall. - -> e - -You're at west end of Hall of Mists. - -> e - -You're on west bank of fissure. - -There are diamonds here! - -A crystal bridge spans the fissure. - -> take diamonds - -OK - -> e - -You're on east bank of fissure. - -A three foot black rod with a rusty star on an end lies nearby. - -A crystal bridge spans the fissure. - -> e - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> drop bottle - -OK - -> s - -This is a low room with a crude note on the wall. The note says, -"You won't get it up the steps". - -There is a large sparkling nugget of gold here! - -> take gold - -OK - -> n - -You're in Hall of Mists. - -There is a bottle of water here. - -> n - -You're in Hall of Mt King. - -> n - -You're in n/s passage above e/w passage. - -> n - -You're at "Y2". - -> off - -Your lamp is now off. - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> plugh - ->>Foof!<< - -You're inside building. - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is precious jewelry here! - -A precious jade necklace has been dropped here! - -There are some keys on the ground here. - -There is food here. - -> drop gold - -OK - -> drop diamonds - -OK - -> drop pyramid - -OK - -> drop ruby - -OK - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -A hollow voice says "PLUGH". - -> on - -Your lamp is now on. - -You're at "Y2". - -> s - -You're in n/s passage above e/w passage. - -> s - -You are in the Hall of the Mountain King, with passages off in all -directions. - -> u - -There is a threatening little dwarf in the room with you! - -You are at one end of a vast hall stretching forward out of sight to -the west. There are openings to either side. Nearby, a wide stone -staircase leads downward. The hall is filled with wisps of white mist -swaying to and fro almost as if alive. A cold wind blows up the -staircase. There is a passage at the top of a dome behind you. - -There is a bottle of water here. - -Rough stone steps lead up the dome. - -> take water - -OK - -> throw axe - -You killed a little dwarf. - -You're in Hall of Mists. - -There is a little axe here. - -Rough stone steps lead up the dome. - -> take axe - -OK - -> n - -You're in Hall of Mt King. - -> n - -You are in a low n/s passage at a hole in the floor. The hole goes -down to an e/w passage. - -> d - -You're in dirty passage. - -> bedquilt - -You are in Bedquilt, a long east/west passage with holes everywhere. -To explore at random select north, south, up, or down. - -> slab - -You are in a large low circular chamber whose floor is an immense slab -fallen from the ceiling (Slab Room). East and west there once were -large passages, but they are now filled with boulders. Low small -passages go north and south, and the south one quickly bends west -around the boulders. - -> s - -You are at the west end of the Twopit Room. There is a large hole in -the wall above the pit at this end of the room. - -> d - -You are at the bottom of the western pit in the Twopit Room. There is -a large hole in the wall about 25 feet above you. - -There is a tiny little plant in the pit, murmuring "water, water, ..." - -> water plant - -The plant spurts into furious growth for a few seconds. - -You're in west pit. - -There is a 12-foot-tall beanstalk stretching up out of the pit, -bellowing "WATER!! WATER!!" - -> u - -You're at west end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> w - -You're in Slab Room. - -> u - -You are in a secret n/s canyon above a large room. - -> reservoir - -You are at the edge of a large underground reservoir. An opaque cloud -of white mist fills the room and rises rapidly upward. The lake is -fed by a stream, which tumbles out of a hole in the wall about 10 feet -overhead and splashes noisily into the water somewhere within the -mist. There is a passage going back toward the south. - -> F'UNJ - -The waters have parted to form a narrow path across the reservoir. - -> n - -You are walking across the bottom of the reservoir. Walls of water -rear up on either side. The roar of the water cascading past is -nearly deafening, and the mist is so thick you can barely see. - -> n - -You are at the northern edge of the reservoir. A northwest passage -leads sharply up from here. - -The waters have parted to form a narrow path across the reservoir. - -> nw - -You are scrambling along a treacherously steep, rocky passage. - -> u - -You are on a very steep incline, which widens at it goes upward. - -> u - -You are at the base of a nearly vertical cliff. There are some -slim footholds which would enable you to climb up, but it looks -extremely dangerous. Here at the base of the cliff lie the remains -of several earlier adventurers who apparently failed to make it. - -> u - -You are climbing along a nearly vertical cliff. - -> u - -Just as you reach the top, your foot slips on a loose rock and you -make one last desperate grab. Your luck holds, as does your grip. -With an enormous heave, you lift yourself to the ledge above. - -You are on a small ledge at the top of a nearly vertical cliff. -There is a low crawl leading off to the northeast. - -> ne - -You have reached a dead end. - -There is a richly-carved ebony statuette here! - -> take ebony - -OK - -> sw - -You're at top of cliff. - -> d - -You are climbing along a nearly vertical cliff. - -> d - -You're at base of cliff. - -> d - -You are on a very steep incline, which widens at it goes upward. - -> d - -You are scrambling along a treacherously steep, rocky passage. - -> d - -You're north of reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> take water - -Your bottle is now full of water. - -> s - -You're at bottom of reservoir. - -> s - -You're at reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> s - -You are in a north/south canyon about 25 feet across. The floor is -covered by white mist seeping in from the north. The walls extend -upward for well over 100 feet. Suspended from some unseen point far -above you, an enormous two-sided mirror is hanging parallel to and -midway between the canyon walls. (The mirror is obviously provided -for the use of the dwarves who, as you know, are extremely vain.) A -small window can be seen in either wall, some fifty feet up. - -> s - -You are in a secret n/s canyon above a large room. - -> d - -You're in Slab Room. - -> s - -You're at west end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> d - -You're in west pit. - -There is a 12-foot-tall beanstalk stretching up out of the pit, -bellowing "WATER!! WATER!!" - -> water plant - -The plant grows explosively, almost filling the bottom of the pit. - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> u - -You're at west end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> e - -You are at the east end of the Twopit Room. The floor here is -littered with thin rock slabs, which make it easy to descend the pits. -There is a path here bypassing the pits to connect passages from east -and west. There are holes all over, but the only big one is on the -wall directly over the west pit where you can't get to it. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You are at the bottom of the eastern pit in the Twopit Room. There is -a small pool of oil in one corner of the pit. - -> get oil - -Your bottle is now full of oil. - -> u - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> w - -You're at west end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> climb - -You clamber up the plant and scurry through the hole at the top. - -You are in a long, narrow corridor stretching out of sight to the -west. At the eastern end is a hole through which you can see a -profusion of leaves. - -> w - -You are in the Giant Room. The ceiling here is too high up for your -lamp to show it. Cavernous passages lead east, north, and south. On -the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. - -There is a large nest here, full of golden eggs! - -> n - -You are at one end of an immense north/south passage. - -The way north is barred by a massive, rusty, iron door. - -> oil door - -The oil has freed up the hinges so that the door will now move, -although it requires some effort. - -> drop bottle - -OK - -> drop appendage - -OK - -> n - -You are in a magnificent cavern with a rushing stream, which cascades -over a sparkling waterfall into a roaring whirlpool which disappears -through a hole in the floor. Passages exit to the south and west. - -There is a jewel-encrusted trident here! - -> take trident - -OK - -> w - -You are at the top of a steep incline above a large room. You could -climb down here, but you would not be able to climb up. There is a -passage leading back to the north. - -> d - -You are in a large low room. Crawls lead north, se, and sw. - -> se - -This is the Oriental Room. Ancient oriental cave drawings cover the -walls. A gently sloping passage leads upward to the north, another -passage leads se, and a hands and knees crawl leads west. - -There is a delicate, precious, ming vase here! - -> n - -You are following a wide path around the outer edge of a large cavern. -Far below, through a heavy white mist, strange splashing noises can be -heard. The mist rises up through a fissure in the ceiling. The path -exits to the south and west. - -> w - -You are in an alcove. A small nw path seems to widen after a short -distance. An extremely tight tunnel leads east. It looks like a very -tight squeeze. An eerie light can be seen at the other end. - -> inven - -You are currently holding the following: -Brass lantern -Dwarf's axe -Jeweled trident -Ebony statuette - -> drop trident - -OK - -> drop ebony - -OK - -> drop axe - -OK - -> drop lantern - -OK - -> e - -You're in Plover Room. - -There is an emerald here the size of a plover's egg! - -> take emerald - -OK - -> w - -You're in alcove. - -There is a lamp shining nearby. - -There is a little axe here. - -There is a richly-carved ebony statuette here! - -There is a jewel-encrusted trident here! - -> take lamp - -OK - -> take axe - -OK - -> take ebony - -OK - -> take trident - -OK - -> nw - -You're in misty cavern. - -> s - -You're in Oriental Room. - -There is a delicate, precious, ming vase here! - -> take vase - -OK - -> se - -You are in a room whose walls resemble Swiss cheese. Obvious passages -go west, east, ne, and nw. Part of the room is occupied by a large -bedrock block. - -> e - -You are in the Soft Room. The walls are covered with heavy curtains, -the floor with a thick pile carpet. Moss covers the ceiling. - -A small velvet pillow lies on the floor. - -> take pillow - -OK - -> w - -You're in Swiss Cheese Room. - -> ne - -You're in Bedquilt. - -> e - -You are at a complex junction. A low hands and knees passage from the -north joins a higher crawl from the east to make a walking passage -going west. There is also a large room above. The air is damp here. - -> n - -You're in a large room carved out of sedimentary rock. The floor and -walls are littered with bits of shells embedded in the stone. A -shallow passage proceeds downward, and a somewhat steeper one leads -up. A low hands and knees passage enters from the south. - -There is an enormous clam here with its shell tightly closed. - -> n - -There is no way to go that direction. - -You're in Shell Room. - -There is an enormous clam here with its shell tightly closed. - -> seed 1635997320 - -Seed set to 1635997320 - -You're in Shell Room. - -There is an enormous clam here with its shell tightly closed. - -> n - -There is no way to go that direction. - -You're in Shell Room. - -There is an enormous clam here with its shell tightly closed. - -> - -> - -> - -> - - -You scored 179 out of a possible 430, using 216 turns. - -You may now consider yourself a "Seasoned Adventurer". - -To achieve the next higher rating, you need 72 more points. diff --git a/tests/seedcrash.log b/tests/seedcrash.log deleted file mode 100644 index 7f364cc..0000000 --- a/tests/seedcrash.log +++ /dev/null @@ -1,225 +0,0 @@ -## This crashed advent before the control path after seed was fixed. -n -seed 1635997320 -in -take lamp -xyzzy -take rod -e -take cage -w -on -w -w -drop rod -take bird -take rod -w -free bird -wave rod -drop rod -take bird -take jade -e -e -e -off -xyzzy -drop jade -xyzzy -on -w -w -w -take rod -d -w -wave rod -drop rod -e -n -free bird -take bird -s -take jewelry -n -sw -w -feed dragon -kill dragon -yes -drink blood -take rug -e -e -n -take silver -n -off -plugh -drop jewelry -drop rug -drop silver -out -s -w -n -take appendage -free bird -drop cage -listen -s -s -n -in -take water -plugh -on -plover -ne -take pyramid -s -plover -s -d -take axe -u -s -up -w -w -w -w -throw axe -take axe -w -s -sw -se -s -kill machine -s -s -kill ogre -n -take ruby -s -w -n -n -n -nw -d -e -e -e -take diamonds -e -e -drop bottle -s -take gold -n -n -n -n -off -plugh -drop gold -drop diamonds -drop pyramid -drop ruby -plugh -on -s -s -u -take water -throw axe -take axe -n -n -d -bedquilt -slab -s -d -water plant -u -w -u -reservoir -F'UNJ -n -n -nw -u -u -u -u -ne -take ebony -sw -d -d -d -d -d -take water -s -s -s -s -d -s -d -water plant -u -e -d -get oil -u -w -d -climb -w -n -oil door -drop bottle -drop appendage -n -take trident -w -d -se -n -w -inven -drop trident -drop ebony -drop axe -drop lantern -e -take emerald -w -take lamp -take axe -take ebony -take trident -nw -s -take vase -se -e -take pillow -w -ne -e -n -n -seed 1635997320 -n - - - - From 1ffb81b70bae8025df0ff5c1218589ae16390437 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 22 Mar 2023 10:30:10 -0400 Subject: [PATCH 054/213] YAML markup fix. --- adventure.yaml | 2 +- tests/hint_jade.chk | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/adventure.yaml b/adventure.yaml index 84ec1cb..8dfd1c8 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -2107,7 +2107,7 @@ locations: !!omap ] - LOC_LIMESTONE: description: - long: + long: |- You are walking along a gently sloping north/south passage lined with oddly shaped limestone formations. short: 'You''re in limestone passage.' diff --git a/tests/hint_jade.chk b/tests/hint_jade.chk index fc9233b..446cc33 100644 --- a/tests/hint_jade.chk +++ b/tests/hint_jade.chk @@ -1424,7 +1424,8 @@ down a gentle slope. The main corridor enters from the west. You are being followed by a very large, tame bear. -You are walking along a gently sloping north/south passage lined with oddly shaped limestone formations. +You are walking along a gently sloping north/south passage lined with +oddly shaped limestone formations. > fork From 1e05134b477b817ebe5032ee74b1832b21bb8e1e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 22 Mar 2023 17:03:50 -0400 Subject: [PATCH 055/213] Minor fix to prompt generation. --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 7a6c6c8..b318cd0 100644 --- a/main.c +++ b/main.c @@ -82,9 +82,9 @@ char *myreadline(const char *prompt) } else { char *ln = fgets(buf, LINESIZE, settings.scriptfp); if (ln != NULL) { - fputs(PROMPT, stdout); + fputs(prompt, stdout); fputs(ln, stdout); - return ln; + return ln; } } } From 5f7ce870405316959d22ea4750e87c26f53fb416 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 22 Mar 2023 17:09:14 -0400 Subject: [PATCH 056/213] Change prompt generation to be more compatible with the advent430 branch. --- main.c | 9 +++++++-- tests/axebear.chk | 2 +- tests/axeorama.chk | 2 +- tests/barehands.chk | 2 +- tests/bigfail.chk | 2 +- tests/birdweight.chk | 2 +- tests/boulder2.chk | 2 +- tests/carrybird.chk | 2 +- tests/carryfreebird.chk | 2 +- tests/cheatresume.chk | 2 +- tests/cheatresume2.chk | 2 +- tests/domefail.chk | 2 +- tests/dragon_secret5.chk | 2 +- tests/dropcagedbird.chk | 2 +- tests/dwarf_alternative.chk | 1 + tests/eggs_done.chk | 2 +- tests/eggs_vanish.chk | 2 +- tests/fail_hint_maze.chk | 2 +- tests/fail_hint_ogre.chk | 2 +- tests/fail_hint_ogre2.chk | 2 +- tests/fail_hint_woods.chk | 2 +- tests/fillfail.chk | 2 +- tests/fillvase.chk | 2 +- tests/flyback.chk | 2 +- tests/foobug.chk | 2 +- tests/footslip.chk | 2 +- tests/gemstates.chk | 2 +- tests/goback.chk | 2 +- tests/hint_dark.chk | 2 +- tests/hint_grate.chk | 2 +- tests/hint_jade.chk | 2 +- tests/hint_snake.chk | 2 +- tests/hint_urn.chk | 2 +- tests/hint_witt.chk | 2 +- tests/illformed.chk | 1 + tests/intransitivecarry.chk | 2 +- tests/isofoo.chk | 2 +- tests/issue36.chk | 2 +- tests/issue37.chk | 2 +- tests/lampdim.chk | 2 +- tests/lampdim2.chk | 2 +- tests/lockchain.chk | 1 + tests/logopt.chk | 2 +- tests/mazealldiff.chk | 2 +- tests/mazehint.chk | 2 +- tests/notrident.chk | 2 +- tests/ogre_no_dwarves.chk | 2 +- tests/ogrehint.chk | 2 +- tests/oilplant.chk | 2 +- tests/panic.chk | 2 +- tests/panic2.chk | 2 +- tests/pirate_carry.chk | 2 +- tests/pirate_pyramid.chk | 2 +- tests/pirate_spotted.chk | 2 +- tests/plover.chk | 2 +- tests/reach_ledge_short.chk | 2 +- tests/reach_noclimb.chk | 2 +- tests/reach_planttop.chk | 2 +- tests/reincarnate.chk | 2 +- tests/resumefail.chk | 3 ++- tests/resumefail2.chk | 2 +- tests/savefail.chk | 3 ++- tests/saveresumeopt.chk | 2 +- tests/snake_food.chk | 2 +- tests/softroom.chk | 2 +- tests/specials.chk | 2 +- tests/takebird.chk | 2 +- tests/tall.chk | 2 +- tests/trident.chk | 2 +- tests/troll_returns.chk | 2 +- tests/urntest.chk | 2 +- tests/urntest2.chk | 2 +- tests/urntest3.chk | 2 +- tests/vending.chk | 2 +- tests/water_plant2.chk | 2 +- tests/weirdbird.chk | 2 +- tests/weirddwarf.chk | 2 +- tests/wittsend.chk | 2 +- tests/woodshint.chk | 2 +- 79 files changed, 87 insertions(+), 77 deletions(-) diff --git a/main.c b/main.c index b318cd0..f83c4e0 100644 --- a/main.c +++ b/main.c @@ -55,8 +55,13 @@ char *myreadline(const char *prompt) * logfiles for testing purposes. */ /* Normal case - no script arguments */ - if (settings.argc == 0) - return readline(prompt); + if (settings.argc == 0) { + char *ln = readline(prompt); + if (ln == NULL) { + fputs(prompt, stdout); + } + return ln; + } char *buf = malloc(LINESIZE + 1); for (;;) { diff --git a/tests/axebear.chk b/tests/axebear.chk index 7cff028..ba465c2 100644 --- a/tests/axebear.chk +++ b/tests/axebear.chk @@ -1631,7 +1631,7 @@ There is a little axe lying beside the bear. The bear is locked to the wall with a golden chain! - +> You scored 251 out of a possible 430, using 271 turns. You have reached "Junior Master" status. diff --git a/tests/axeorama.chk b/tests/axeorama.chk index 741ac50..fbb1d7b 100644 --- a/tests/axeorama.chk +++ b/tests/axeorama.chk @@ -652,7 +652,7 @@ mist. A notice posted on the bridge reads, "Stop! Pay troll!" A burly troll stands by the bridge and insists you throw him a treasure before you may cross. - +> You scored 105 out of a possible 430, using 109 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/barehands.chk b/tests/barehands.chk index 38b0c05..f94685f 100644 --- a/tests/barehands.chk +++ b/tests/barehands.chk @@ -307,7 +307,7 @@ The blood-specked body of a huge green dead dragon lies to one side. For crying out loud, the poor thing is already dead! - +> You scored 77 out of a possible 430, using 49 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/bigfail.chk b/tests/bigfail.chk index eebea66..8084d1c 100644 --- a/tests/bigfail.chk +++ b/tests/bigfail.chk @@ -2537,7 +2537,7 @@ best start wrapping this up. OK - +> You scored 207 out of a possible 430, using 416 turns. You may now consider yourself a "Seasoned Adventurer". diff --git a/tests/birdweight.chk b/tests/birdweight.chk index 0df99e6..24f0904 100644 --- a/tests/birdweight.chk +++ b/tests/birdweight.chk @@ -456,7 +456,7 @@ attack. He seems almost amused by your puny effort. OK - +> You scored 61 out of a possible 430, using 81 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/boulder2.chk b/tests/boulder2.chk index 9430308..87aee68 100644 --- a/tests/boulder2.chk +++ b/tests/boulder2.chk @@ -1479,7 +1479,7 @@ You're in Chamber of Boulders. There are rare spices here! - +> You scored 119 out of a possible 430, using 238 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/carrybird.chk b/tests/carrybird.chk index 7f3b931..55f6ac9 100644 --- a/tests/carrybird.chk +++ b/tests/carrybird.chk @@ -75,7 +75,7 @@ You can catch the bird, but you cannot carry it. The little bird is now dead. Its body disappears. - +> You scored 32 out of a possible 430, using 10 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/carryfreebird.chk b/tests/carryfreebird.chk index dcaf64b..870ea4b 100644 --- a/tests/carryfreebird.chk +++ b/tests/carryfreebird.chk @@ -327,7 +327,7 @@ The bird eyes you suspiciously and flutters away. A moment later you feel something wet land on your head, but upon looking up you can see no sign of the culprit. - +> You scored 113 out of a possible 430, using 57 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/cheatresume.chk b/tests/cheatresume.chk index 08c1263..a56a78b 100644 --- a/tests/cheatresume.chk +++ b/tests/cheatresume.chk @@ -13,7 +13,7 @@ You are standing at the end of a road before a small brick building. Around you is a forest. A small stream flows out of the building and down a gully. - +> Now let's see you do it without suspending in mid-Adventure. You scored 9031 out of a possible 430, using 0 turns. diff --git a/tests/cheatresume2.chk b/tests/cheatresume2.chk index d698a26..af3648c 100644 --- a/tests/cheatresume2.chk +++ b/tests/cheatresume2.chk @@ -13,7 +13,7 @@ You are standing at the end of a road before a small brick building. Around you is a forest. A small stream flows out of the building and down a gully. - +> Now let's see you do it without suspending in mid-Adventure. You scored 10031 out of a possible 430, using 0 turns. diff --git a/tests/domefail.chk b/tests/domefail.chk index 000995b..961b8c5 100644 --- a/tests/domefail.chk +++ b/tests/domefail.chk @@ -166,7 +166,7 @@ The dome is unclimbable. You're in Hall of Mists. - +> You scored 63 out of a possible 430, using 24 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/dragon_secret5.chk b/tests/dragon_secret5.chk index 1d5e121..b469f27 100644 --- a/tests/dragon_secret5.chk +++ b/tests/dragon_secret5.chk @@ -246,7 +246,7 @@ There is a Persian rug spread out on the floor! The blood-specked body of a huge green dead dragon lies to one side. - +> You scored 65 out of a possible 430, using 32 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/dropcagedbird.chk b/tests/dropcagedbird.chk index b5c64e6..5f382a3 100644 --- a/tests/dropcagedbird.chk +++ b/tests/dropcagedbird.chk @@ -150,7 +150,7 @@ A huge green fierce snake bars the way! There's nothing here it wants to eat (except perhaps you). - +> You scored 59 out of a possible 430, using 25 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/dwarf_alternative.chk b/tests/dwarf_alternative.chk index 5fcaf06..d9adb04 100644 --- a/tests/dwarf_alternative.chk +++ b/tests/dwarf_alternative.chk @@ -58,3 +58,4 @@ Oh dear, you seem to have gotten yourself killed. I might be able to help you out, but I've never really done this before. Do you want me to try to reincarnate you? +> \ No newline at end of file diff --git a/tests/eggs_done.chk b/tests/eggs_done.chk index 70dcf03..4e85042 100644 --- a/tests/eggs_done.chk +++ b/tests/eggs_done.chk @@ -1223,7 +1223,7 @@ Wicker cage Black rod Small bottle - +> You scored 77 out of a possible 430, using 190 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/eggs_vanish.chk b/tests/eggs_vanish.chk index 2fe0579..256ac5e 100644 --- a/tests/eggs_vanish.chk +++ b/tests/eggs_vanish.chk @@ -435,7 +435,7 @@ There is a large nest here, full of golden eggs! The passage here is blocked by a recent cave-in. - +> You scored 67 out of a possible 430, using 66 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/fail_hint_maze.chk b/tests/fail_hint_maze.chk index 9973218..46b0aa7 100644 --- a/tests/fail_hint_maze.chk +++ b/tests/fail_hint_maze.chk @@ -436,7 +436,7 @@ OK OK - +> You scored 59 out of a possible 430, using 93 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/fail_hint_ogre.chk b/tests/fail_hint_ogre.chk index 71a9d72..4d300b7 100644 --- a/tests/fail_hint_ogre.chk +++ b/tests/fail_hint_ogre.chk @@ -1638,7 +1638,7 @@ OK OK - +> You scored 77 out of a possible 430, using 263 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/fail_hint_ogre2.chk b/tests/fail_hint_ogre2.chk index 28b673e..3437b22 100644 --- a/tests/fail_hint_ogre2.chk +++ b/tests/fail_hint_ogre2.chk @@ -394,7 +394,7 @@ You are in a large chamber with passages to the west and north. A formidable ogre bars the northern exit. - +> You scored 63 out of a possible 430, using 56 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/fail_hint_woods.chk b/tests/fail_hint_woods.chk index 990cf8e..ca5ac5e 100644 --- a/tests/fail_hint_woods.chk +++ b/tests/fail_hint_woods.chk @@ -109,7 +109,7 @@ OK OK - +> You scored 32 out of a possible 430, using 25 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/fillfail.chk b/tests/fillfail.chk index fd3d096..11f58eb 100644 --- a/tests/fillfail.chk +++ b/tests/fillfail.chk @@ -57,7 +57,7 @@ You can't fill that. Your bottle is already full. - +> You scored 32 out of a possible 430, using 10 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/fillvase.chk b/tests/fillvase.chk index 5d8c889..cbbeea4 100644 --- a/tests/fillvase.chk +++ b/tests/fillvase.chk @@ -1463,7 +1463,7 @@ A small velvet pillow lies on the ground. You can't be serious! - +> You scored 191 out of a possible 430, using 241 turns. You may now consider yourself a "Seasoned Adventurer". diff --git a/tests/flyback.chk b/tests/flyback.chk index 2d8750e..a60fe97 100644 --- a/tests/flyback.chk +++ b/tests/flyback.chk @@ -2040,7 +2040,7 @@ A brilliant blue star sapphire is here! > - +> You scored 257 out of a possible 430, using 337 turns. You have reached "Junior Master" status. diff --git a/tests/foobug.chk b/tests/foobug.chk index 046b820..c121eb8 100644 --- a/tests/foobug.chk +++ b/tests/foobug.chk @@ -1694,7 +1694,7 @@ Nothing happens. Nothing happens. - +> You scored 311 out of a possible 430, using 291 turns. You have reached "Junior Master" status. diff --git a/tests/footslip.chk b/tests/footslip.chk index ef2f595..a9f28d3 100644 --- a/tests/footslip.chk +++ b/tests/footslip.chk @@ -796,7 +796,7 @@ There is food here. > - +> You scored 61 out of a possible 430, using 121 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/gemstates.chk b/tests/gemstates.chk index db58aa4..8739f93 100644 --- a/tests/gemstates.chk +++ b/tests/gemstates.chk @@ -2145,7 +2145,7 @@ There is a ruby resting in a small cavity in the rock! There is a Persian rug spread out on the floor! - +> You scored 271 out of a possible 430, using 365 turns. You have reached "Junior Master" status. diff --git a/tests/goback.chk b/tests/goback.chk index 27d0cb8..fb6eb0f 100644 --- a/tests/goback.chk +++ b/tests/goback.chk @@ -2527,7 +2527,7 @@ best start wrapping this up. OK - +> You scored 207 out of a possible 430, using 413 turns. You may now consider yourself a "Seasoned Adventurer". diff --git a/tests/hint_dark.chk b/tests/hint_dark.chk index cee6051..1a95bf8 100644 --- a/tests/hint_dark.chk +++ b/tests/hint_dark.chk @@ -150,7 +150,7 @@ There is a way to explore that region without having to worry about falling into a pit. None of the objects available is immediately useful in discovering the secret. - +> You scored 54 out of a possible 430, using 27 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/hint_grate.chk b/tests/hint_grate.chk index 652b639..fa7d80d 100644 --- a/tests/hint_grate.chk +++ b/tests/hint_grate.chk @@ -83,7 +83,7 @@ The grate is very solid and has a hardened steel lock. You cannot enter without a key, and there are no keys nearby. I would recommend looking elsewhere for the keys. - +> You scored 30 out of a possible 430, using 10 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/hint_jade.chk b/tests/hint_jade.chk index 446cc33..e8d9f81 100644 --- a/tests/hint_jade.chk +++ b/tests/hint_jade.chk @@ -1849,7 +1849,7 @@ Do you want the hint? Once you've found all the other treasures, it is no longer possible to locate the one you're now missing. - +> You scored 91 out of a possible 430, using 297 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/hint_snake.chk b/tests/hint_snake.chk index 78ca80f..d5a1c44 100644 --- a/tests/hint_snake.chk +++ b/tests/hint_snake.chk @@ -192,7 +192,7 @@ You can't kill the snake, or drive it away, or avoid it, or anything like that. There is a way to get by, but you don't have the necessary resources right now. - +> You scored 55 out of a possible 430, using 25 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/hint_urn.chk b/tests/hint_urn.chk index d51adc1..63b7542 100644 --- a/tests/hint_urn.chk +++ b/tests/hint_urn.chk @@ -74,7 +74,7 @@ Do you want the hint? This section is quite advanced. Find the cave first. - +> You scored 30 out of a possible 430, using 11 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/hint_witt.chk b/tests/hint_witt.chk index 5afca9f..315f402 100644 --- a/tests/hint_witt.chk +++ b/tests/hint_witt.chk @@ -2430,7 +2430,7 @@ Do you want the hint? Don't go west. - +> You scored 339 out of a possible 430, using 397 turns. Your score puts you in Master Adventurer Class C. diff --git a/tests/illformed.chk b/tests/illformed.chk index e18fbf9..2f9cad3 100644 --- a/tests/illformed.chk +++ b/tests/illformed.chk @@ -697,3 +697,4 @@ I am prepared to give you a hint, but it will cost you 2 points. Do you want the hint? +> \ No newline at end of file diff --git a/tests/intransitivecarry.chk b/tests/intransitivecarry.chk index 510a9bd..4fe9674 100644 --- a/tests/intransitivecarry.chk +++ b/tests/intransitivecarry.chk @@ -35,7 +35,7 @@ OK OK - +> You scored 32 out of a possible 430, using 5 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/isofoo.chk b/tests/isofoo.chk index 1c0cbaf..23f17a7 100644 --- a/tests/isofoo.chk +++ b/tests/isofoo.chk @@ -11,7 +11,7 @@ down a gully. Nothing happens. - +> You scored 32 out of a possible 430, using 1 turn. You are obviously a rank amateur. Better luck next time. diff --git a/tests/issue36.chk b/tests/issue36.chk index 412f019..99d82df 100644 --- a/tests/issue36.chk +++ b/tests/issue36.chk @@ -33,7 +33,7 @@ Get what? OK - +> You scored 32 out of a possible 430, using 3 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/issue37.chk b/tests/issue37.chk index 6d8772b..4aa9320 100644 --- a/tests/issue37.chk +++ b/tests/issue37.chk @@ -32,7 +32,7 @@ OK You are currently holding the following: Tasty food - +> You scored 32 out of a possible 430, using 4 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/lampdim.chk b/tests/lampdim.chk index 2ea31c6..cfbb010 100644 --- a/tests/lampdim.chk +++ b/tests/lampdim.chk @@ -2508,7 +2508,7 @@ There is a message scrawled in the dust in a flowery script, reading: There is a massive vending machine here, swung back to reveal a southward passage. - +> You scored 343 out of a possible 430, using 406 turns. Your score puts you in Master Adventurer Class C. diff --git a/tests/lampdim2.chk b/tests/lampdim2.chk index bd6215a..740e719 100644 --- a/tests/lampdim2.chk +++ b/tests/lampdim2.chk @@ -2595,7 +2595,7 @@ It is now pitch dark. If you proceed you will likely fall into a pit. Your lamp has run out of power. - +> You scored 368 out of a possible 430, using 423 turns. Your score puts you in Master Adventurer Class C. diff --git a/tests/lockchain.chk b/tests/lockchain.chk index 791991f..ff334a2 100644 --- a/tests/lockchain.chk +++ b/tests/lockchain.chk @@ -1888,3 +1888,4 @@ Oh dear, you seem to have gotten yourself killed. I might be able to help you out, but I've never really done this before. Do you want me to try to reincarnate you? +> \ No newline at end of file diff --git a/tests/logopt.chk b/tests/logopt.chk index 4defeae..e48c318 100644 --- a/tests/logopt.chk +++ b/tests/logopt.chk @@ -21,7 +21,7 @@ There is a bottle of water here. > - +> You scored 32 out of a possible 430, using 1 turn. You are obviously a rank amateur. Better luck next time. diff --git a/tests/mazealldiff.chk b/tests/mazealldiff.chk index 87aeb0d..00168a4 100644 --- a/tests/mazealldiff.chk +++ b/tests/mazealldiff.chk @@ -2509,7 +2509,7 @@ You are in a maze of little twisty passages, all different. You are in a twisting little maze of passages, all different. - +> You scored 343 out of a possible 430, using 409 turns. Your score puts you in Master Adventurer Class C. diff --git a/tests/mazehint.chk b/tests/mazehint.chk index 0d00119..5c72b61 100644 --- a/tests/mazehint.chk +++ b/tests/mazehint.chk @@ -618,7 +618,7 @@ Do you want the hint? You can make the passages look less alike by dropping things. - +> You scored 71 out of a possible 430, using 113 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/notrident.chk b/tests/notrident.chk index 8e08825..88a8d6d 100644 --- a/tests/notrident.chk +++ b/tests/notrident.chk @@ -1316,7 +1316,7 @@ You're at brink of small pit. > - +> You scored 179 out of a possible 430, using 224 turns. You may now consider yourself a "Seasoned Adventurer". diff --git a/tests/ogre_no_dwarves.chk b/tests/ogre_no_dwarves.chk index dff2bc5..37492fa 100644 --- a/tests/ogre_no_dwarves.chk +++ b/tests/ogre_no_dwarves.chk @@ -152,7 +152,7 @@ A formidable ogre bars the northern exit. The ogre, who despite his bulk is quite agile, easily dodges your attack. He seems almost amused by your puny effort. - +> You scored 59 out of a possible 430, using 23 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/ogrehint.chk b/tests/ogrehint.chk index dbb8d8f..9391193 100644 --- a/tests/ogrehint.chk +++ b/tests/ogrehint.chk @@ -720,7 +720,7 @@ Brass lantern Leporine appendage Platinum pyramid - +> You scored 101 out of a possible 430, using 108 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/oilplant.chk b/tests/oilplant.chk index 2f74824..167a3b7 100644 --- a/tests/oilplant.chk +++ b/tests/oilplant.chk @@ -1146,7 +1146,7 @@ The plant indignantly shakes the oil off its leaves and asks, "Water?" You can't be serious! - +> You scored 185 out of a possible 430, using 187 turns. You may now consider yourself a "Seasoned Adventurer". diff --git a/tests/panic.chk b/tests/panic.chk index bd23880..e44e632 100644 --- a/tests/panic.chk +++ b/tests/panic.chk @@ -2631,7 +2631,7 @@ The grate is locked. A mysterious recorded voice groans into life and announces: "This exit is closed. Please leave via main office." - +> You scored 365 out of a possible 430, using 422 turns. Your score puts you in Master Adventurer Class C. diff --git a/tests/panic2.chk b/tests/panic2.chk index ac42e46..db66581 100644 --- a/tests/panic2.chk +++ b/tests/panic2.chk @@ -2592,7 +2592,7 @@ A mysterious recorded voice groans into life and announces: You're at "Y2". - +> You scored 365 out of a possible 430, using 414 turns. Your score puts you in Master Adventurer Class C. diff --git a/tests/pirate_carry.chk b/tests/pirate_carry.chk index f2e7893..72b1681 100644 --- a/tests/pirate_carry.chk +++ b/tests/pirate_carry.chk @@ -316,7 +316,7 @@ You are on the west side of the fissure in the Hall of Mists. A crystal bridge spans the fissure. - +> You scored 67 out of a possible 430, using 43 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/pirate_pyramid.chk b/tests/pirate_pyramid.chk index a7ac101..873cdaa 100644 --- a/tests/pirate_pyramid.chk +++ b/tests/pirate_pyramid.chk @@ -356,7 +356,7 @@ You are currently holding the following: Brass lantern Wicker cage - +> You scored 69 out of a possible 430, using 50 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/pirate_spotted.chk b/tests/pirate_spotted.chk index b57d7e7..e8fad72 100644 --- a/tests/pirate_spotted.chk +++ b/tests/pirate_spotted.chk @@ -1839,7 +1839,7 @@ You're in Hall of Mists. Rough stone steps lead up the dome. - +> You scored 123 out of a possible 430, using 295 turns. You have achieved the rating: "Experienced Adventurer". diff --git a/tests/plover.chk b/tests/plover.chk index 67e58af..c59ae86 100644 --- a/tests/plover.chk +++ b/tests/plover.chk @@ -1169,7 +1169,7 @@ Egg-sized emerald It is now pitch dark. If you proceed you will likely fall into a pit. - +> You scored 169 out of a possible 430, using 187 turns. You have achieved the rating: "Experienced Adventurer". diff --git a/tests/reach_ledge_short.chk b/tests/reach_ledge_short.chk index d6f8175..7e57aa1 100644 --- a/tests/reach_ledge_short.chk +++ b/tests/reach_ledge_short.chk @@ -1475,7 +1475,7 @@ There is a Persian rug here, hovering in mid-air! A brilliant blue star sapphire is here! - +> You scored 81 out of a possible 430, using 237 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/reach_noclimb.chk b/tests/reach_noclimb.chk index 0a06bd0..6f42d7c 100644 --- a/tests/reach_noclimb.chk +++ b/tests/reach_noclimb.chk @@ -170,7 +170,7 @@ You're in west pit. There is a tiny little plant in the pit, murmuring "water, water, ..." - +> You scored 59 out of a possible 430, using 24 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/reach_planttop.chk b/tests/reach_planttop.chk index 8009e1f..c19c9d2 100644 --- a/tests/reach_planttop.chk +++ b/tests/reach_planttop.chk @@ -387,7 +387,7 @@ You're at west end of Twopit Room. The top of a 12-foot-tall beanstalk is poking out of the west pit. - +> You scored 63 out of a possible 430, using 50 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/reincarnate.chk b/tests/reincarnate.chk index c8a8842..edaaf8a 100644 --- a/tests/reincarnate.chk +++ b/tests/reincarnate.chk @@ -143,7 +143,7 @@ There is food here. There is a bottle of water here. - +> You scored 47 out of a possible 430, using 18 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/resumefail.chk b/tests/resumefail.chk index 7be9b12..976fcc9 100644 --- a/tests/resumefail.chk +++ b/tests/resumefail.chk @@ -24,9 +24,10 @@ Is this acceptable? OK Can't open file /badfilename, try again. +File name: You're in front of building. - +> You scored 32 out of a possible 430, using 1 turn. You are obviously a rank amateur. Better luck next time. diff --git a/tests/resumefail2.chk b/tests/resumefail2.chk index 756c094..931c72d 100644 --- a/tests/resumefail2.chk +++ b/tests/resumefail2.chk @@ -16,7 +16,7 @@ using that other version in order to resume that Adventure. You're in front of building. - +> You scored 32 out of a possible 430, using 1 turn. You are obviously a rank amateur. Better luck next time. diff --git a/tests/savefail.chk b/tests/savefail.chk index de89a53..0f005a2 100644 --- a/tests/savefail.chk +++ b/tests/savefail.chk @@ -25,9 +25,10 @@ Is this acceptable? OK Can't open file /, try again. +File name: You're in front of building. - +> You scored 27 out of a possible 430, using 1 turn. You are obviously a rank amateur. Better luck next time. diff --git a/tests/saveresumeopt.chk b/tests/saveresumeopt.chk index bc08d9b..6e8ead0 100644 --- a/tests/saveresumeopt.chk +++ b/tests/saveresumeopt.chk @@ -1,7 +1,7 @@ You're in front of building. - +> You scored 27 out of a possible 430, using 2 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/snake_food.chk b/tests/snake_food.chk index 96f6900..56e73b3 100644 --- a/tests/snake_food.chk +++ b/tests/snake_food.chk @@ -151,7 +151,7 @@ Set of keys Brass lantern Wicker cage - +> You scored 57 out of a possible 430, using 22 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/softroom.chk b/tests/softroom.chk index cc168f3..3e9c86d 100644 --- a/tests/softroom.chk +++ b/tests/softroom.chk @@ -1350,7 +1350,7 @@ There is a delicate, precious, ming vase here! > - +> You scored 191 out of a possible 430, using 223 turns. You may now consider yourself a "Seasoned Adventurer". diff --git a/tests/specials.chk b/tests/specials.chk index 75f457e..0606117 100644 --- a/tests/specials.chk +++ b/tests/specials.chk @@ -131,7 +131,7 @@ can now save a game and resume it at once (formerly you had to wait a while first), but it now costs you a few points each time you save the game. Saved games are now stored in much smaller files than before. - +> You scored 32 out of a possible 430, using 15 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/takebird.chk b/tests/takebird.chk index d69f094..6c6b64d 100644 --- a/tests/takebird.chk +++ b/tests/takebird.chk @@ -2076,7 +2076,7 @@ The grate is locked. OK - +> You scored 391 out of a possible 430, using 345 turns. Your score puts you in Master Adventurer Class B. diff --git a/tests/tall.chk b/tests/tall.chk index d962f77..05f456b 100644 --- a/tests/tall.chk +++ b/tests/tall.chk @@ -1024,7 +1024,7 @@ seems to open up. The canyon runs into a mass of boulders -- dead end. - +> You scored 77 out of a possible 430, using 163 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/trident.chk b/tests/trident.chk index 37de9fe..c27ef42 100644 --- a/tests/trident.chk +++ b/tests/trident.chk @@ -1420,7 +1420,7 @@ Your lamp is now on. You're at "Y2". - +> You scored 167 out of a possible 430, using 231 turns. You have achieved the rating: "Experienced Adventurer". diff --git a/tests/troll_returns.chk b/tests/troll_returns.chk index 6b597d9..6715126 100644 --- a/tests/troll_returns.chk +++ b/tests/troll_returns.chk @@ -912,7 +912,7 @@ mist. A notice posted on the bridge reads, "Stop! Pay troll!" A burly troll stands by the bridge and insists you throw him a treasure before you may cross. - +> You scored 75 out of a possible 430, using 140 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/urntest.chk b/tests/urntest.chk index 0ca8748..8724f9d 100644 --- a/tests/urntest.chk +++ b/tests/urntest.chk @@ -2105,7 +2105,7 @@ A small urn full of oil is embedded in the rock. If you mean to use the Persian rug, it does not appear inclined to cooperate. - +> You scored 265 out of a possible 430, using 358 turns. You have reached "Junior Master" status. diff --git a/tests/urntest2.chk b/tests/urntest2.chk index 25de76b..8f8e9cc 100644 --- a/tests/urntest2.chk +++ b/tests/urntest2.chk @@ -2030,7 +2030,7 @@ There is nothing here with which to fill it. The urn is now dark. - +> You scored 267 out of a possible 430, using 344 turns. You have reached "Junior Master" status. diff --git a/tests/urntest3.chk b/tests/urntest3.chk index 1c95ae3..34c30e7 100644 --- a/tests/urntest3.chk +++ b/tests/urntest3.chk @@ -2015,7 +2015,7 @@ You are wandering aimlessly through the forest. There is nothing here with which to fill the bottle. - +> You scored 267 out of a possible 430, using 340 turns. You have reached "Junior Master" status. diff --git a/tests/vending.chk b/tests/vending.chk index 6e67b28..4f837bc 100644 --- a/tests/vending.chk +++ b/tests/vending.chk @@ -305,7 +305,7 @@ Attack what? The vending machine swings back to block the passage. - +> You scored 75 out of a possible 430, using 56 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/water_plant2.chk b/tests/water_plant2.chk index 1cbf119..bc1efe3 100644 --- a/tests/water_plant2.chk +++ b/tests/water_plant2.chk @@ -602,7 +602,7 @@ The top of a 12-foot-tall beanstalk is poking out of the west pit. What do you want to do with the water? - +> You scored 65 out of a possible 430, using 85 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/weirdbird.chk b/tests/weirdbird.chk index 52f5eb7..c583787 100644 --- a/tests/weirdbird.chk +++ b/tests/weirdbird.chk @@ -218,7 +218,7 @@ You're outside grate. The grate is open. - +> You scored 30 out of a possible 430, using 37 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/weirddwarf.chk b/tests/weirddwarf.chk index 1d73e0e..0216bc5 100644 --- a/tests/weirddwarf.chk +++ b/tests/weirddwarf.chk @@ -514,7 +514,7 @@ With what? Your bare hands? Feed what? - +> You scored 103 out of a possible 430, using 88 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/wittsend.chk b/tests/wittsend.chk index dcd9bd4..b92cf2f 100644 --- a/tests/wittsend.chk +++ b/tests/wittsend.chk @@ -2628,7 +2628,7 @@ It is now pitch dark. If you proceed you will likely fall into a pit. You're in Plover Room. - +> You scored 342 out of a possible 430, using 423 turns. Your score puts you in Master Adventurer Class C. diff --git a/tests/woodshint.chk b/tests/woodshint.chk index c26d471..7ea7cdd 100644 --- a/tests/woodshint.chk +++ b/tests/woodshint.chk @@ -314,7 +314,7 @@ You are wandering aimlessly through the forest. You're at end of road. - +> You scored 30 out of a possible 430, using 45 turns. You are obviously a rank amateur. Better luck next time. From e3fbac804bdde46f940d35854abb4d20a1f4daf0 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 22 Mar 2023 20:39:36 -0400 Subject: [PATCH 057/213] Reconciliation with advent430. --- tests/newfilter | 2 ++ tests/oldfilter | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/newfilter b/tests/newfilter index dca9f05..9ae3da7 100755 --- a/tests/newfilter +++ b/tests/newfilter @@ -4,5 +4,7 @@ # the filtered versions of logs made from advent430. sed \ -e '/bridge now spans the fissure/s//bridge spans the fissure/' \ + -e '/ground/s//surface/' \ + -e '/floor/s//surface/' \ # end diff --git a/tests/oldfilter b/tests/oldfilter index fcda48e..fce8298 100755 --- a/tests/oldfilter +++ b/tests/oldfilter @@ -14,6 +14,8 @@ sed \ -e '/DOING/s//doing/' \ -e '/SOMETHING/s//something/' \ -e '/EW/s//ew/' \ + -e '/ground/s//surface/' \ + -e '/floor/s//surface/' \ #end From 2070db3a2a2332bb85aa9de739c9ff6c1101719b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 22 Mar 2023 21:20:24 -0400 Subject: [PATCH 058/213] Test simplification - we don't care about the difference in processing blank lines. --- tests/water_plant2.chk | 58 ++++++++++++++++++++++++------------------ tests/water_plant2.log | 1 - 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/tests/water_plant2.chk b/tests/water_plant2.chk index bc1efe3..9ec91c8 100644 --- a/tests/water_plant2.chk +++ b/tests/water_plant2.chk @@ -392,14 +392,6 @@ You are in the south side chamber. There is precious jewelry here! -> - -I don't know how to apply that word here. - -You are in the south side chamber. - -There is precious jewelry here! - > s There is no way to go that direction. @@ -448,8 +440,6 @@ There are bars of silver here! You're at "Y2". -A hollow voice says "PLUGH". - There is a little axe here. > d @@ -556,8 +546,6 @@ Your bottle is now full of water. > s -There is a threatening little dwarf in the room with you! - You are in a north/south canyon about 25 feet across. The floor is covered by white mist seeping in from the north. The walls extend upward for well over 100 feet. Suspended from some unseen point far @@ -568,7 +556,27 @@ small window can be seen in either wall, some fifty feet up. > s -A little dwarf with a big knife blocks your way. +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are in a secret n/s canyon above a large room. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a secret canyon which exits to the north and east. + +There is a Persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. + +> d + +There is no way to go that direction. There is a threatening little dwarf in the room with you! @@ -576,34 +584,34 @@ One sharp nasty knife is thrown at you! It misses! -You're in Mirror Canyon. +You are in a secret canyon which exits to the north and east. + +There is a Persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. > s -There is a threatening little dwarf in the room with you! - -You are in a secret n/s canyon above a large room. - -> d +There is no way to go that direction. There is a threatening little dwarf in the room with you! -You're in Slab Room. +One sharp nasty knife is thrown at you! -> s +It misses! -There is a threatening little dwarf in the room with you! +You are in a secret canyon which exits to the north and east. -You're at west end of Twopit Room. +There is a Persian rug spread out on the floor! -The top of a 12-foot-tall beanstalk is poking out of the west pit. +The blood-specked body of a huge green dead dragon lies to one side. > water plant What do you want to do with the water? > -You scored 65 out of a possible 430, using 85 turns. +You scored 65 out of a possible 430, using 84 turns. Your score qualifies you as a novice class adventurer. diff --git a/tests/water_plant2.log b/tests/water_plant2.log index 0136f1e..16fa346 100644 --- a/tests/water_plant2.log +++ b/tests/water_plant2.log @@ -56,7 +56,6 @@ s s u w - s w s From dc8b19bcdc00586af906af4147855662efb5287e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 23 Mar 2023 05:38:26 -0400 Subject: [PATCH 059/213] Implement NOCOMPARE magic. --- tests/Makefile | 18 +++++++++++++++--- tests/birdweight.log | 1 + tests/endobjects.log | 1 + tests/resumefail.log | 3 ++- tests/resumefail2.log | 3 ++- tests/savefail.log | 3 ++- tests/saveresume.3.log | 3 ++- tests/saveresume.4.log | 1 + tests/specials.log | 1 + 9 files changed, 27 insertions(+), 7 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index f2addb9..8d61d27 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -133,11 +133,23 @@ count: # The diff file produced has corrected spellings in it. That's what oldfilter # is for, to massage out the orioginal dpellings and avoid noise diffs. # Diffs in amount of whitespace and trailing whitespace are ignored - +# +# A magic comment of NOCOMPARE in a log file excludes it from this comparison. +# First use of this is to avoid a spurious mismatch on the news text. +TAPFILTER=tapview ancient: $(SGAMES) @if [ -f ../advent430 ]; then cp ../advent430 ../adventure.data .; else echo "advent430 nonexistent"; exit 1; fi - @-for x in *.log; do stem=$${x%.log}; echo $${stem}; ./advent430 <$${stem}.log | ./oldfilter >$${stem}.ochk; done - @-(for x in *.log; do stem=$${x%.log}; legend=$$(sed -n '/^## /s///p' <$$x 2>/dev/null || echo "(no description)"); ./newfilter <$${stem}.chk | tapdiffer -w "$${legend}" $${stem}.ochk; done; echo 1..$(words $(shell ls *.log))) | tapview + @-(for x in *.log; do \ + stem=$${x%.log}; \ + legend=$$(sed -n '/^## /s///p' <$$x 2>/dev/null || echo "(no description)"); \ + if grep NOCOMPARE $$x >/dev/null; \ + then echo "not ok - $${stem}.ochk: $${legend} # SKIP"; \ + else \ + ./advent430 <$${stem}.log | oldfilter >$${stem}.ochk; \ + ./newfilter <$${stem}.chk | tapdiffer -w "$${stem}: $${legend}" $${stem}.ochk; \ + fi; \ + done; \ + echo 1..$(words $(shell ls *.log))) | $(TAPFILTER) @rm *.ochk advent430 adventure.data # end diff --git a/tests/birdweight.log b/tests/birdweight.log index bc07eb6..80cc3a6 100644 --- a/tests/birdweight.log +++ b/tests/birdweight.log @@ -1,5 +1,6 @@ ## Verify that the bird is weightless in inventory # Checks fix for GitLab issue #40 +#NOCOMPARE Bird was not weightless in cage in advent430 so this test is invalid. n #seed 687800971 seed 976729036 diff --git a/tests/endobjects.log b/tests/endobjects.log index e532df0..6bec970 100644 --- a/tests/endobjects.log +++ b/tests/endobjects.log @@ -1,5 +1,6 @@ ### Check that water is unavailable in endgame # Addresses GitLab issue #55: in endgame, some object starting states are incorrect +#NOCOMPARE Bird was not weightless in cade in advent430, this test depends on that. no seed 11247848 no diff --git a/tests/resumefail.log b/tests/resumefail.log index 053b05f..1e1fdb5 100644 --- a/tests/resumefail.log +++ b/tests/resumefail.log @@ -1,6 +1,7 @@ ## Resume from invalid filename +#NOCOMPARE advent430 crashes on resume fom invalid filename and we don't care. n seed 1240742801 resume y -/badfilename \ No newline at end of file +/badfilename diff --git a/tests/resumefail2.log b/tests/resumefail2.log index 2754454..7aaac36 100644 --- a/tests/resumefail2.log +++ b/tests/resumefail2.log @@ -1,4 +1,5 @@ -## Resume from from generated save with version mismatch error +## Resume from from generated save with version mismatch error +#NOCOMPARE Reveals a bug in advent430 handling of saves with invalid versions. n resume y diff --git a/tests/savefail.log b/tests/savefail.log index f907d99..c598d19 100644 --- a/tests/savefail.log +++ b/tests/savefail.log @@ -1,6 +1,7 @@ ## Save right after starting to invalid filename +#NOCOMPARE advent430 crashes on save to invalid filename and we don't care. n seed 1240742801 save y -/ \ No newline at end of file +/ diff --git a/tests/saveresume.3.log b/tests/saveresume.3.log index 13ed0be..f199c64 100644 --- a/tests/saveresume.3.log +++ b/tests/saveresume.3.log @@ -1,5 +1,6 @@ ## Almost win, then save # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 +#NOCOMPARE seems to reveal a bug in advent430 n seed 1838473132 in @@ -473,4 +474,4 @@ sw save y saveresume_win.adv -y \ No newline at end of file +y diff --git a/tests/saveresume.4.log b/tests/saveresume.4.log index caa8098..883d098 100644 --- a/tests/saveresume.4.log +++ b/tests/saveresume.4.log @@ -1,6 +1,7 @@ ## Resume, then win # Here to get class threshold of 426 # Note, savefile name has trailing space +#NOCOMPARE Reveals that advent430 does not resume in endgame gracefully. n resume y diff --git a/tests/specials.log b/tests/specials.log index 2891691..4784faf 100644 --- a/tests/specials.log +++ b/tests/specials.log @@ -1,4 +1,5 @@ ## Test special words +#NOCOMPARE The news text has changed n thank shazam From 4eccfa127cb9f212c9b6ad0ff96ff26588f24e85 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 09:24:12 -0400 Subject: [PATCH 060/213] Document a bugfix and isolate it in a test. --- notes.adoc | 2 ++ tests/breakmirror.chk | 8 ++++---- tests/breakmirror.log | 7 ++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/notes.adoc b/notes.adoc index 2d61074..f5116bc 100644 --- a/notes.adoc +++ b/notes.adoc @@ -51,6 +51,8 @@ Bug fixes: * Oyster was readable after first gotten even when not carried. +* Response to an attempt to unlock the oyster while carrying it was incorrect. + * Behavior when saying the giant's magic words outside his room wasn't quite correct - the game responded as though the player were in the room ("...can't you read?"). The new message is "Nothing happens." diff --git a/tests/breakmirror.chk b/tests/breakmirror.chk index 2581648..faf0008 100644 --- a/tests/breakmirror.chk +++ b/tests/breakmirror.chk @@ -2934,14 +2934,14 @@ Huh? Huh? -> unlock oyster - -I advise you to put down the oyster before opening it. >WRENCH!< - > drop oyster OK +> unlock oyster + +You don't have anything strong enough to open the oyster. + > take oyster OK diff --git a/tests/breakmirror.log b/tests/breakmirror.log index 12b14e8..d93b075 100644 --- a/tests/breakmirror.log +++ b/tests/breakmirror.log @@ -467,14 +467,16 @@ e e cave e -# Everything to here is from endgame428 +# Everything to here is from endgame428, +# except we drop the oyster before trying +# to unlock it rather than after. attack take oyster find oyster lock lock oyster -unlock oyster drop oyster +unlock oyster take oyster read oyster y @@ -482,4 +484,3 @@ sw attack bird find bird break mirror - From a5eeb0b2bc62d70902d3c44b077a5ddec6361b44 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 09:33:01 -0400 Subject: [PATCH 061/213] Add a useful warning to the tests makefile --- tests/Makefile | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 8d61d27..8cf9e7e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -92,6 +92,9 @@ scheck7: @./outcheck.sh "test -r with valid input" SCHECKS = scheck1 scheck2 scheck3 scheck4 scheck5 scheck6 scheck7 +# Don't run this from here, you'll get ctyptic warnings and no good result +# if the advent binary wasn't built with covrage flags. Do "make clean covetage" +# from the top-level directory. coverage: check lcov -t "advent" -o $(PARDIR)/advent.info -c -d $(PARDIR) --gcov-tool=$(GCOV) genhtml -o $(PARDIR)/coverage/ $(PARDIR)/advent.info @@ -124,18 +127,20 @@ tap: count $(TEST_TARGETS) count: @echo 1..$(words $(TEST_TARGETS)) -# The following machinery tests the gane against a binary made from +# The following machinery tests the game against a binary made from # the advent430 branch To use it, switch to that branch, build the -# binary, sand run it once to generate adventure.data, then switch -# back to master leaving advent430 and adventure.data in place (make -# clean does not remove them). +# binary, run it once to generate adventure.data, then switch back to +# master leaving advent430 and adventure.data in place (make clean +# does not remove them). # # The diff file produced has corrected spellings in it. That's what oldfilter # is for, to massage out the orioginal dpellings and avoid noise diffs. # Diffs in amount of whitespace and trailing whitespace are ignored # # A magic comment of NOCOMPARE in a log file excludes it from this comparison. -# First use of this is to avoid a spurious mismatch on the news text. +# making it a skipped test in the TAP view. First use of this was to avoid a +# spurious mismatch on the news text. Other uses avoid spurios mismatches due +# to bug fixes. TAPFILTER=tapview ancient: $(SGAMES) @if [ -f ../advent430 ]; then cp ../advent430 ../adventure.data .; else echo "advent430 nonexistent"; exit 1; fi From cbb5572b214621ccbbac653a46f711a8d5944cc0 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 10:55:56 -0400 Subject: [PATCH 062/213] Clean up some tests, adding newlines at EOF where they're missing. The advent430 command interpreter accidentally accepted input lines with no trailing newline. Thus, these files produced spurious mismatches. --- tests/dropcagedbird.log | 2 +- tests/fail_hint_woods.log | 2 +- tests/flyback.chk | 2 -- tests/flyback.log | 1 - tests/hint_dark.log | 2 +- tests/hint_witt.log | 2 +- tests/pirate_carry.log | 2 +- tests/reach_noclimb.log | 2 +- tests/reach_planttop.log | 2 +- tests/saveresumeopt.log | 1 + tests/tall.log | 2 +- tests/woodshint.log | 2 +- 12 files changed, 10 insertions(+), 12 deletions(-) diff --git a/tests/dropcagedbird.log b/tests/dropcagedbird.log index ba90580..c7adca1 100644 --- a/tests/dropcagedbird.log +++ b/tests/dropcagedbird.log @@ -25,4 +25,4 @@ take bird drop cage d d -feed snake \ No newline at end of file +feed snake diff --git a/tests/fail_hint_woods.log b/tests/fail_hint_woods.log index 5c37435..3df72f4 100644 --- a/tests/fail_hint_woods.log +++ b/tests/fail_hint_woods.log @@ -24,4 +24,4 @@ z z z z -z \ No newline at end of file +z diff --git a/tests/flyback.chk b/tests/flyback.chk index a60fe97..04b658c 100644 --- a/tests/flyback.chk +++ b/tests/flyback.chk @@ -2038,8 +2038,6 @@ There is a Persian rug here, hovering in mid-air! A brilliant blue star sapphire is here! -> - > You scored 257 out of a possible 430, using 337 turns. diff --git a/tests/flyback.log b/tests/flyback.log index b849cc8..c4335de 100644 --- a/tests/flyback.log +++ b/tests/flyback.log @@ -340,4 +340,3 @@ drop emerald fly rug fly rug fly rug - diff --git a/tests/hint_dark.log b/tests/hint_dark.log index b522b90..ddc9bc9 100644 --- a/tests/hint_dark.log +++ b/tests/hint_dark.log @@ -29,4 +29,4 @@ z z z y -y \ No newline at end of file +y diff --git a/tests/hint_witt.log b/tests/hint_witt.log index fd2a4f2..bafb070 100644 --- a/tests/hint_witt.log +++ b/tests/hint_witt.log @@ -400,4 +400,4 @@ n n n y -y \ No newline at end of file +y diff --git a/tests/pirate_carry.log b/tests/pirate_carry.log index c84b393..0ba55c4 100644 --- a/tests/pirate_carry.log +++ b/tests/pirate_carry.log @@ -44,4 +44,4 @@ e u w wave rod -w \ No newline at end of file +w diff --git a/tests/reach_noclimb.log b/tests/reach_noclimb.log index 42af7c5..59768ea 100644 --- a/tests/reach_noclimb.log +++ b/tests/reach_noclimb.log @@ -24,4 +24,4 @@ w w w d -climb \ No newline at end of file +climb diff --git a/tests/reach_planttop.log b/tests/reach_planttop.log index bbdf94b..730ea1b 100644 --- a/tests/reach_planttop.log +++ b/tests/reach_planttop.log @@ -50,4 +50,4 @@ s s d water plant -climb \ No newline at end of file +climb diff --git a/tests/saveresumeopt.log b/tests/saveresumeopt.log index af159ff..f5256c2 100644 --- a/tests/saveresumeopt.log +++ b/tests/saveresumeopt.log @@ -1,2 +1,3 @@ ## Simple quit +#NOCOMPARE New feature, -r option #options: -r saveresume.adv diff --git a/tests/tall.log b/tests/tall.log index 19081c6..eaebfad 100644 --- a/tests/tall.log +++ b/tests/tall.log @@ -164,4 +164,4 @@ e s n n -w \ No newline at end of file +w diff --git a/tests/woodshint.log b/tests/woodshint.log index 6db609a..4472b49 100644 --- a/tests/woodshint.log +++ b/tests/woodshint.log @@ -63,4 +63,4 @@ n n n w -n \ No newline at end of file +n From 65f221e03f21f367dd35fda1d7d0cf83018d11fb Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 10:59:42 -0400 Subject: [PATCH 063/213] Add a more carefully factored test... ...so we can exclude the part advent430 won't pass. --- tests/oysterbug.chk | 2930 +++++++++++++++++++++++++++++++++++++++++++ tests/oysterbug.log | 472 +++++++ 2 files changed, 3402 insertions(+) create mode 100644 tests/oysterbug.chk create mode 100644 tests/oysterbug.log diff --git a/tests/oysterbug.chk b/tests/oysterbug.chk new file mode 100644 index 0000000..871b185 --- /dev/null +++ b/tests/oysterbug.chk @@ -0,0 +1,2930 @@ + +Welcome to Adventure!! Would you like instructions? + +> n + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed 1838473132 + +Seed set to 1838473132 + +You're in front of building. + +> in + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> take lamp + +OK + +> xyzzy + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> e + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> take cage + +OK + +> w + +You're in debris room. + +> w + +You are in an awkward sloping east/west canyon. + +> w + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> drop rod + +OK + +> take bird + +OK + +> take rod + +OK + +> w + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> free bird + +OK + +> wave rod + +The bird flies about agitatedly for a moment, then disappears through +the crack. It reappears shortly, carrying in its beak a jade +necklace, which it drops at your feet. + +> take necklace + +OK + +> drop rod + +OK + +> take bird + +OK + +> take rod + +OK + +> d + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> d + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A huge green fierce snake bars the way! + +> free bird + +The little bird attacks the green snake, and in an astounding flurry +drives the snake away. + +> drop rod + +OK + +> drop cage + +OK + +> take cage + +OK + +> take bird + +OK + +> w + +You are in the west side chamber of the Hall of the Mountain King. +A passage continues west and up here. + +There are many coins here! + +> take coins + +OK + +> e + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> s + +You are in the south side chamber. + +There is precious jewelry here! + +> take jewelry + +OK + +> n + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> up + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> s + +This is a low room with a crude note on the wall. The note says, +"You won't get it up the steps". + +There is a large sparkling nugget of gold here! + +> take gold + +OK + +> n + +You're in Hall of Mists. + +> d + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> n + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There are bars of silver here! + +> n + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> plugh + +>>Foof!<< + +You're inside building. + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> extinguish lamp + +Your lamp is now off. + +> drop coins + +OK + +> drop jewelry + +OK + +> drop necklace + +OK + +> drop gold + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +> s + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> take silver + +OK + +> s + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> sw + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You are in a secret canyon which here runs e/w. It crosses over a +very tight canyon 15 feet below. If you go down you may not be able +to get back up. + +There is a little axe here. + +> take axe + +OK + +> w + +You are in a secret canyon which exits to the north and east. + +A huge green fierce dragon bars the way! + +The dragon is sprawled out on a Persian rug!! + +> kill dragon + +With what? Your bare hands? + +> yes + +Congratulations! You have just vanquished a dragon with your bare +hands! (Unbelievable, isn't it?) + +You are in a secret canyon which exits to the north and east. + +There is a Persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. + +> drink blood + +Your head buzzes strangely for a moment. + +> take rug + +OK + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A three foot black rod with a rusty star on an end lies nearby. + +> up + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> d + +There is a threatening little dwarf in the room with you! + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> n + +There is a threatening little dwarf in the room with you! + +You're in n/s passage above e/w passage. + +> n + +There is a threatening little dwarf in the room with you! + +You're at "Y2". + +A hollow voice says "PLUGH". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> inven + +You are currently holding the following: +Brass lantern +Wicker cage +Little bird in cage +Dwarf's axe +Bars of silver +Persian rug + +> drop rug + +OK + +> drop silver + +OK + +> out + +You're in front of building. + +> s + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> w + +You are wandering aimlessly through the forest. + +> n + +You are wandering aimlessly through the forest. + +Your keen eye spots a severed leporine appendage lying on the ground. + +> take appendage + +OK + +> free bird + +OK + +> drop cage + +OK + +> listen + +The bird is singing to you in gratitude for your having returned it to +its home. In return, it informs you of a magic word which it thinks +you may find useful somewhere near the Hall of Mists. The magic word +changes frequently, but for now the bird believes it is "H'CFL". You +thank the bird for this information, and it flies off into the forest. + +> s + +You are wandering aimlessly through the forest. + +> s + +You're in valley. + +> n + +You're in front of building. + +> in + +You're inside building. + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> take water + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +> plover + +>>Foof!<< + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +There is an emerald here the size of a plover's egg! + +> ne + +You're in the dark-room. A corridor leading south is the only exit. + +A massive stone tablet embedded in the wall reads: +"Congratulations on bringing light into the dark-room!" + +There is a platinum pyramid here, 8 inches on a side! + +> take pyramid + +OK + +> s + +You're in Plover Room. + +There is an emerald here the size of a plover's egg! + +> plover + +>>Foof!<< + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You're in n/s passage above e/w passage. + +> s + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> up + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +A crystal bridge now spans the fissure. + +> drop rod + +OK + +> west + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> take diamonds + +OK + +> w + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are at the west end of the Hall of Mists. A low wide crawl +continues west and another goes north. To the south is a little +passage 6 feet off the floor. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the east end of a very long hall apparently without side +chambers. To the east a low wide crawl slants up. To the north a +round two foot hole slants down. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of a very long featureless hall. The hall +joins up with a narrow north/south passage. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all different. + +> sw + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisty passages, all different. + +> se + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisting passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +Dead end + +There is a massive and somewhat battered vending machine here. The +instructions on it read: "Drop coins here to receive fresh batteries." + +> kill machine + +As you strike the vending machine, it pivots backward along with a +section of wall, revealing a dark passage leading south. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a long, rough-hewn, north/south corridor. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a large chamber with passages to the west and north. + +A formidable ogre bars the northern exit. + +> kill ogre + +The ogre, who despite his bulk is quite agile, easily dodges your +attack. He seems almost amused by your puny effort. + +One sharp nasty knife is thrown at you! + +The ogre, distracted by your rush, is struck by the knife. With a +blood-curdling yell he turns and bounds after the dwarf, who flees +in panic. You are left alone in the room. + +> n + +You are in the ogre's storeroom. The only exit is to the south. + +There is an enormous ruby here! + +> take ruby + +OK + +> s + +You are in a large chamber with passages to the west and north. + +> w + +You are in a long, rough-hewn, north/south corridor. + +> n + +Dead end + +There is a massive vending machine here, swung back to reveal a +southward passage. + +> n + +You are in a little maze of twisting passages, all different. + +> n + +You are in a little maze of twisty passages, all different. + +> nw + +You are in a maze of twisty little passages, all different. + +> d + +You're at west end of long hall. + +> e + +You're at east end of long hall. + +> e + +You're at west end of Hall of Mists. + +> e + +You're on west bank of fissure. + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A three foot black rod with a rusty star on an end lies nearby. + +A crystal bridge spans the fissure. + +> e + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> throw axe + +You killed a little dwarf. The body vanishes in a cloud of greasy +black smoke. + +You're in Hall of Mists. + +There is a little axe here. + +Rough stone steps lead up the dome. + +> take axe + +OK + +> n + +You're in Hall of Mt King. + +> n + +You're in n/s passage above e/w passage. + +> n + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +> drop ruby + +OK + +> drop diamonds + +OK + +> drop pyramid + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> s + +You're in Hall of Mt King. + +> u + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> n + +You are in the Hall of the Mountain King, with passages off in all +directions. + +> n + +You're in n/s passage above e/w passage. + +> d + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> bedquilt + +There is a threatening little dwarf in the room with you! + +You are in Bedquilt, a long east/west passage with holes everywhere. +To explore at random select north, south, up, or down. + +> throw axe + +You killed a little dwarf. + +You're in Bedquilt. + +There is a little axe here. + +> take axe + +OK + +> slab + +You are in a large low circular chamber whose floor is an immense slab +fallen from the ceiling (Slab Room). East and west there once were +large passages, but they are now filled with boulders. Low small +passages go north and south, and the south one quickly bends west +around the boulders. + +> s + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a tiny little plant in the pit, murmuring "water, water, ..." + +> water plant + +The plant spurts into furious growth for a few seconds. + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> u + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> w + +You're in Slab Room. + +> u + +You are in a secret n/s canyon above a large room. + +> reservoir + +You are at the edge of a large underground reservoir. An opaque cloud +of white mist fills the room and rises rapidly upward. The lake is +fed by a stream, which tumbles out of a hole in the wall about 10 feet +overhead and splashes noisily into the water somewhere within the +mist. There is a passage going back toward the south. + +> H'CFL + +The waters have parted to form a narrow path across the reservoir. + +> n + +You are walking across the bottom of the reservoir. Walls of water +rear up on either side. The roar of the water cascading past is +nearly deafening, and the mist is so thick you can barely see. + +> n + +You are at the northern edge of the reservoir. A northwest passage +leads sharply up from here. + +The waters have parted to form a narrow path across the reservoir. + +> nw + +You are scrambling along a treacherously steep, rocky passage. + +> u + +You are on a very steep incline, which widens at it goes upward. + +> u + +You are at the base of a nearly vertical cliff. There are some +slim footholds which would enable you to climb up, but it looks +extremely dangerous. Here at the base of the cliff lie the remains +of several earlier adventurers who apparently failed to make it. + +> u + +You are climbing along a nearly vertical cliff. + +> u + +Just as you reach the top, your foot slips on a loose rock and you +make one last desperate grab. Your luck holds, as does your grip. +With an enormous heave, you lift yourself to the ledge above. + +You are on a small ledge at the top of a nearly vertical cliff. +There is a low crawl leading off to the northeast. + +> ne + +You have reached a dead end. + +There is a richly-carved ebony statuette here! + +> take ebony + +OK + +> sw + +You're at top of cliff. + +> d + +You are climbing along a nearly vertical cliff. + +> d + +You're at base of cliff. + +> d + +You are on a very steep incline, which widens at it goes upward. + +> d + +You are scrambling along a treacherously steep, rocky passage. + +> d + +You're north of reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> take water + +Your bottle is now full of water. + +> s + +You're at bottom of reservoir. + +> s + +You're at reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You are in a north/south canyon about 25 feet across. The floor is +covered by white mist seeping in from the north. The walls extend +upward for well over 100 feet. Suspended from some unseen point far +above you, an enormous two-sided mirror is hanging parallel to and +midway between the canyon walls. (The mirror is obviously provided +for the use of the dwarves who, as you know, are extremely vain.) A +small window can be seen in either wall, some fifty feet up. + +> break mirror + +It is too far up for you to reach. + +> s + +You are in a secret n/s canyon above a large room. + +> d + +You're in Slab Room. + +> s + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> water plant + +The plant grows explosively, almost filling the bottom of the pit. + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> u + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> drop appendage + +OK + +> e + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You are at the bottom of the eastern pit in the Twopit Room. There is +a small pool of oil in one corner of the pit. + +> get oil + +Your bottle is now full of oil. + +> + +> u + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You are in a long, narrow corridor stretching out of sight to the +west. At the eastern end is a hole through which you can see a +profusion of leaves. + +> w + +You are in the Giant Room. The ceiling here is too high up for your +lamp to show it. Cavernous passages lead east, north, and south. On +the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. + +There is a large nest here, full of golden eggs! + +> n + +You are at one end of an immense north/south passage. + +The way north is barred by a massive, rusty, iron door. + +> unlock + +The door is extremely rusty and refuses to open. + +> oil door + +The oil has freed up the hinges so that the door will now move, +although it requires some effort. + +> drop bottle + +OK + +> n + +You are in a magnificent cavern with a rushing stream, which cascades +over a sparkling waterfall into a roaring whirlpool which disappears +through a hole in the floor. Passages exit to the south and west. + +There is a jewel-encrusted trident here! + +> take trident + +OK + +> w + +You are at the top of a steep incline above a large room. You could +climb down here, but you would not be able to climb up. There is a +passage leading back to the north. + +> d + +You are in a large low room. Crawls lead north, se, and sw. + +> se + +This is the Oriental Room. Ancient oriental cave drawings cover the +walls. A gently sloping passage leads upward to the north, another +passage leads se, and a hands and knees crawl leads west. + +There is a delicate, precious, ming vase here! + +> n + +You are following a wide path around the outer edge of a large cavern. +Far below, through a heavy white mist, strange splashing noises can be +heard. The mist rises up through a fissure in the ceiling. The path +exits to the south and west. + +> w + +You are in an alcove. A small nw path seems to widen after a short +distance. An extremely tight tunnel leads east. It looks like a very +tight squeeze. An eerie light can be seen at the other end. + +> drop trident + +OK + +> drop ebony + +OK + +> drop axe + +OK + +> drop lantern + +OK + +> e + +You're in Plover Room. + +There is an emerald here the size of a plover's egg! + +> take emerald + +OK + +> w + +You're in alcove. + +There is a lamp shining nearby. + +There is a little axe here. + +There is a richly-carved ebony statuette here! + +There is a jewel-encrusted trident here! + +> take lamp + +OK + +> take axe + +OK + +> take ebony + +OK + +> take trident + +OK + +> nw + +You're in misty cavern. + +> s + +You're in Oriental Room. + +There is a delicate, precious, ming vase here! + +> take vase + +OK + +> se + +There is a threatening little dwarf in the room with you! + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +> throw axe + +You killed a little dwarf. + +You're in Swiss Cheese Room. + +There is a little axe here. + +> take axe + +OK + +> e + +You are in the Soft Room. The walls are covered with heavy curtains, +the floor with a thick pile carpet. Moss covers the ceiling. + +A small velvet pillow lies on the floor. + +> take pillow + +OK + +> w + +You're in Swiss Cheese Room. + +> drop axe + +OK + +> ne + +You're in Bedquilt. + +> e + +You are at a complex junction. A low hands and knees passage from the +north joins a higher crawl from the east to make a walking passage +going west. There is also a large room above. The air is damp here. + +> n + +You're in a large room carved out of sedimentary rock. The floor and +walls are littered with bits of shells embedded in the stone. A +shallow passage proceeds downward, and a somewhat steeper one leads +up. A low hands and knees passage enters from the south. + +There is an enormous clam here with its shell tightly closed. + +> open clam + +A glistening pearl falls out of the clam and rolls away. Goodness, +this must really be an oyster. (I never was very good at identifying +bivalves.) Whatever it is, it has now snapped shut again. + +> s + +You're at complex junction. + +> u + +You are in a large room full of dusty rocks. There is a big hole in +the floor. There are cracks everywhere, and a passage leading east. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +You're at "Y2". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You are inside a building, a well house for a large spring. + +There is a platinum pyramid here, 8 inches on a side! + +There are diamonds here! + +There is an enormous ruby here! + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +> drop pillow + +OK + +> drop vase + +The vase is now resting, delicately, on a velvet pillow. + +> drop trident + +OK + +> drop emerald + +OK + +> drop ebony + +OK + +> take keys + +OK + +> take food + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +A hollow voice says "PLUGH". + +> on + +Your lamp is now on. + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You're in n/s passage above e/w passage. + +> d + +You're in dirty passage. + +> w + +You're in dusty rock room. + +> d + +You're at complex junction. + +> n + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> d + +You are in a long sloping corridor with ragged sharp walls. + +> d + +You are in a cul-de-sac about eight feet across. + +Off to one side lies a glistening pearl! + +> take pearl + +OK + +> u + +You are in a long sloping corridor with ragged sharp walls. + +> u + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> s + +You're at complex junction. + +> w + +You're in Bedquilt. + +> w + +You're in Swiss Cheese Room. + +There is a little axe here. + +> w + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You're in narrow corridor. + +> w + +You're in Giant Room. + +There is a large nest here, full of golden eggs! + +> get eggs + +OK + +> n + +You are at one end of an immense north/south passage. + +There is an empty bottle here. + +The way north leads through a massive, rusty, iron door. + +> take bottle + +OK + +> n + +You're in cavern with waterfall. + +> w + +You're at steep incline above large room. + +> d + +You're in large low room. + +> sw + +You are in a long winding corridor sloping out of sight in both +directions. + +> u + +You are on one side of a large, deep chasm. A heavy white mist rising +up from below obscures all view of the far side. A sw path leads away +from the chasm into a winding corridor. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> toss eggs + +The troll catches your treasure and scurries away out of sight. + +> ne + +You are on the far side of the chasm. A ne path leads away from the +chasm on this side. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> ne + +You're in a long east/west corridor. A faint rumbling noise can be +heard in the distance. + +> barren + +You are standing at the entrance to a large, barren room. A notice +above the entrance reads: "Caution! Bear in room!" + +> in + +You are inside a barren room. The center of the room is completely +empty except for some dust. Marks in the dust lead away toward the +far end of the room. The only exit is the way you came in. + +There is a ferocious cave bear eyeing you from the far end of the room! + +The bear is locked to the wall with a golden chain! + +> feed bear + +The bear eagerly wolfs down your food, after which he seems to calm +down considerably and even becomes rather friendly. + +> unlock + +The chain is now unlocked. + +> unlock chain + +It was already unlocked. + +> take chain + +OK + +> take bear + +OK + +> fork + +You are being followed by a very large, tame bear. + +The path forks here. The left fork leads northeast. A dull rumbling +seems to get louder in that direction. The right fork leads southeast +down a gentle slope. The main corridor enters from the west. + +> ne + +You are being followed by a very large, tame bear. + +The walls are quite warm here. From the north can be heard a steady +roar, so loud that the entire cave seems to be trembling. Another +passage leads south, and a low crawl goes east. + +> e + +You are being followed by a very large, tame bear. + +You are in a small chamber filled with large boulders. The walls are +very warm, causing the air in the room to be almost stifling from the +heat. The only exit is a crawl heading west, through which is coming +a low rumbling. + +There are rare spices here! + +> take spices + +OK + +> drop keys + +OK + +> fork + +You are being followed by a very large, tame bear. + +You're at fork in path. + +> w + +You are being followed by a very large, tame bear. + +You're in corridor. + +> w + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +The troll steps out from beneath the bridge and blocks your way. + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> free bear + +The bear lumbers toward the troll, who lets out a startled shriek and +scurries away. The bear soon gives up the pursuit and wanders back. + +> inven + +You are currently holding the following: +Brass lantern +Small bottle +Glistening pearl +Rare spices +Golden chain + +> sw + +You're on sw side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +You're in sloping corridor. + +> d + +You're in large low room. + +> se + +You're in Oriental Room. + +> se + +You're in Swiss Cheese Room. + +There is a little axe here. + +> w + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in east pit. + +> get oil + +Your bottle is now full of oil. + +> up + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> e + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +There is a little axe here. + +> take axe + +OK + +> w + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You're in narrow corridor. + +> w + +You're in Giant Room. + +> fee + +OK + +> fie + +OK + +> foe + +OK + +> foo + +There is a large nest here, full of golden eggs! + +> take eggs + +OK + +> s + +You're in narrow corridor. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> u + +You're at west end of Twopit Room. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're in Slab Room. + +> u + +You are in a secret n/s canyon above a large room. + +> s + +You are in a secret canyon which exits to the north and east. + +The body of a huge green dead dragon is lying off to one side. + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +You're in Hall of Mt King. + +> n + +You're in n/s passage above e/w passage. + +> n + +You're at "Y2". + +A hollow voice says "PLUGH". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There is a richly-carved ebony statuette here! + +There is an emerald here the size of a plover's egg! + +There is a jewel-encrusted trident here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are diamonds here! + +There is an enormous ruby here! + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +> drop eggs + +OK + +> drop pearl + +OK + +> drop spices + +OK + +> drop chain + +OK + +> take rug + +OK + +> take ruby + +OK + +> take emerald + +OK + +> out + +You're in front of building. + +> w + +You have walked up a hill, still in the forest. The road slopes back +down the other side of the hill. There is a building in the distance. + +> n + +You are wandering aimlessly through the forest. + +> n + +You are wandering aimlessly through the forest. + +> n + +The forest thins out here to reveal a steep cliff. There is no way +down, but a small ledge can be seen to the west across the chasm. + +A small urn is embedded in the rock. + +> inven + +You are currently holding the following: +Brass lantern +Small bottle +Oil in the bottle +Dwarf's axe +Egg-sized emerald +Persian rug +Giant ruby + +> fill urn + +Your bottle is now empty and the urn is full of oil. + +> light urn + +The urn is now lit. + +> rub urn + +As you rub the urn, there is a flash of light and a genie appears. +His aspect is stern as he advises: "One who wouldst traffic in +precious stones must first learn to recognize the signals thereof." +He wrests the urn from the stone, leaving a small cavity. Turning to +face you again, he fixes you with a steely eye and intones: "Caution!" +Genie and urn vanish in a cloud of amber smoke. The smoke condenses +to form a rare amber gemstone, resting in the cavity in the rock. + +> take amber + +OK + +> drop rug + +OK + +> drop emerald + +The gem fits easily into the cavity. + +The Persian rug stiffens and rises a foot or so off the ground. + +> fly rug + +You board the Persian rug, which promptly whisks you across the chasm. +You have time for a fleeting glimpse of a two thousand foot drop to a +mighty river; then you find yourself on the other side. + +You are on a small ledge on one face of a sheer cliff. There are no +paths away from the ledge. Across the chasm is a small clearing +surrounded by forest. + +There is a Persian rug here, hovering in mid-air! + +A brilliant blue star sapphire is here! + +> take sapphire + +OK + +> fly rug + +The rug ferries you back across the chasm. + +You're at cliff. + +There is an emerald resting in a small cavity in the rock! + +There is a Persian rug here, hovering in mid-air! + +> take emerald + +OK + +> drop ruby + +The gem fits easily into the cavity. + +The Persian rug settles gently to the ground. + +> take rug + +OK + +> drop bottle + +OK + +> take ruby + +OK + +> e + +You are wandering aimlessly through the forest. + +> s + +You are wandering aimlessly through the forest. + +> e + +You're at hill in road. + +> e + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> in + +Tsk! A wizard wouldn't have to take 350 turns. This is going to cost +you a couple of points. + +You're inside building. + +There is a golden chain lying in a heap on the floor! + +There are rare spices here! + +Off to one side lies a glistening pearl! + +There is a large nest here, full of golden eggs! + +There is a richly-carved ebony statuette here! + +There is a jewel-encrusted trident here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are diamonds here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +> drop ruby + +OK + +> drop sapphire + +OK + +> drop amber + +OK + +> drop rug + +OK + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +You are inside a building, a well house for a large spring. + +There is a Persian rug spread out on the floor! + +There is a rare amber gemstone here! + +A brilliant blue star sapphire is here! + +There is an enormous ruby here! + +There is a golden chain lying in a heap on the floor! + +There are rare spices here! + +Off to one side lies a glistening pearl! + +There is a large nest here, full of golden eggs! + +There is a richly-carved ebony statuette here! + +There is a jewel-encrusted trident here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are diamonds here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> s + +You're in Hall of Mt King. + +> u + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +Out from the shadows behind you pounces a bearded pirate! "Har, har," +he chortles, "I'll just take all this booty and hide it away with me +chest deep in the maze!" He snatches your treasure and vanishes into +the gloom. + +You're on east bank of fissure. + +A three foot black rod with a rusty star on an end lies nearby. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're at west end of Hall of Mists. + +> s + +You are in a maze of twisty little passages, all alike. + +> e + +You are in a maze of twisty little passages, all alike. + +> s + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are in a maze of twisty little passages, all alike. + +> throw axe + +You killed a little dwarf. + +You are in a maze of twisty little passages, all alike. + +There is a little axe here. + +> take axe + +OK + +> s + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> n + +You are in a maze of twisty little passages, all alike. + +> e + +You are on the brink of a thirty foot pit with a massive orange column +down one wall. You could climb down here but you could not get back +up. The maze continues at this level. + +> e + +You are in a maze of twisty little passages, all alike. + +> nw + +Dead end + +There is an emerald here the size of a plover's egg! + +The pirate's treasure chest is here! + +> take emerald + +OK + +> take chest + +OK + +> se + +You are in a maze of twisty little passages, all alike. + +> n + +You're at brink of pit. + +> d + +You're in bird chamber. + +> e + +You are in an awkward sloping east/west canyon. + +> e + +You're in debris room. + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> xyzzy + +>>Foof!<< + +You're inside building. + +There is a Persian rug spread out on the floor! + +There is a rare amber gemstone here! + +A brilliant blue star sapphire is here! + +There is an enormous ruby here! + +There is a golden chain lying in a heap on the floor! + +There are rare spices here! + +Off to one side lies a glistening pearl! + +There is a large nest here, full of golden eggs! + +There is a richly-carved ebony statuette here! + +There is a jewel-encrusted trident here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are diamonds here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +> drop emerald + +OK + +> drop chest + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You're in n/s passage above e/w passage. + +> d + +Your lamp is getting dim. You'd best start wrapping this up, unless +you can find some fresh batteries. I seem to recall there's a vending +machine in the maze. Bring some coins with you. + +You're in dirty passage. + +> w + +You're in dusty rock room. + +> d + +You're at complex junction. + +> e + +You are in an anteroom leading to a large passage to the east. Small +passages go west and up. The remnants of recent digging are evident. +A sign in midair here says "Cave under construction beyond this point. +Proceed at own risk. [Witt Construction Company]" + +There are a few recent issues of "Spelunker Today" magazine here. + +> take magazine + +OK + +> e + +You are at Witt's End. Passages lead off in *ALL* directions. + +> drop magazine + +OK + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You're at Witt's End. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You have crawled around in some little holes and wound up back in the +main passage. + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> e + +You're in anteroom. + +> u + +You are at a complex junction. A low hands and knees passage from the +north joins a higher crawl from the east to make a walking passage +going west. There is also a large room above. The air is damp here. + +> u + +A sepulchral voice reverberating through the cave, says, "Cave closing +soon. All adventurers exit immediately through main office." + +You're in dusty rock room. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +You're at "Y2". + +> plover + +>>Foof!<< + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +Your lamp has run out of power. + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> e + +There is no way to go that direction. + +You're in Plover Room. + +> cave + +I need more detailed instructions to do that. + +You're in Plover Room. + +> e + +The sepulchral voice intones, "The cave is now closed." As the echoes +fade, there is a blinding flash of light (and a small puff of orange +smoke). . . . As your eyes refocus, you look around and find... + +You are at the northeast end of an immense room, even larger than the +Giant Room. It appears to be a repository for the "Adventure" +program. Massive torches far overhead bathe the room with smoky +yellow light. Scattered about you can be seen a pile of bottles (all +of them empty), a nursery of young beanstalks murmuring quietly, a bed +of oysters, a bundle of black rods with rusty stars on their ends, and +a collection of brass lanterns. Off to one side a great many dwarves +are sleeping on the floor, snoring loudly. A notice nearby reads: "Do +not disturb the dwarves!" An immense mirror is hanging against one +wall, and stretches to the other end of the room, where various other +sundry objects can be glimpsed dimly in the distance. + +> take oyster + +OK + +Interesting. There seems to be something written on the underside of +the oyster. + +> unlock oyster + +I advise you to put down the oyster before opening it. >WRENCH!< + +> +You scored 389 out of a possible 430, using 466 turns. + +Your score puts you in Master Adventurer Class B. + +To achieve the next higher rating, you need 22 more points. diff --git a/tests/oysterbug.log b/tests/oysterbug.log new file mode 100644 index 0000000..07e15ff --- /dev/null +++ b/tests/oysterbug.log @@ -0,0 +1,472 @@ +# Demonstrate fix of buggy response to unlocking oyster while carrying it. +#NOCOMPARE This fixes a bug in advent430 +n +seed 1838473132 +in +take lamp +xyzzy +on +take rod +e +take cage +w +w +w +drop rod +take bird +take rod +w +free bird +wave rod +take necklace +drop rod +take bird +take rod +d +d +free bird +drop rod +drop cage +take cage +take bird +w +take coins +e +s +take jewelry +n +up +s +take gold +n +d +n +n +plugh +extinguish lamp +drop coins +drop jewelry +drop necklace +drop gold +plugh +on +s +take silver +s +sw +take axe +w +kill dragon +yes +drink blood +take rug +e +e +up +d +n +n +off +plugh +inven +drop rug +drop silver +out +s +w +n +take appendage +free bird +drop cage +listen +s +s +n +in +take water +plugh +on +plover +ne +take pyramid +s +plover +s +s +take rod +up +w +wave rod +drop rod +west +take diamonds +w +w +w +s +sw +se +s +kill machine +s +s +kill ogre +n +take ruby +s +w +n +n +n +nw +d +e +e +e +e +e +throw axe +take axe +n +n +n +off +plugh +drop ruby +drop diamonds +drop pyramid +plugh +on +s +s +u +n +n +d +bedquilt +throw axe +take axe +slab +s +d +water plant +u +w +u +reservoir +H'CFL +n +n +nw +u +u +u +u +ne +take ebony +sw +d +d +d +d +d +take water +s +s +s +break mirror +s +d +s +d +water plant +u +drop appendage +e +d +get oil + +u +w +d +climb +w +n +unlock +oil door +drop bottle +n +take trident +w +d +se +n +w +drop trident +drop ebony +drop axe +drop lantern +e +take emerald +w +take lamp +take axe +take ebony +take trident +nw +s +take vase +se +throw axe +take axe +e +take pillow +w +drop axe +ne +e +n +open clam +s +u +e +u +n +off +plugh +drop pillow +drop vase +drop trident +drop emerald +drop ebony +take keys +take food +plugh +on +s +d +w +d +n +d +d +take pearl +u +u +s +w +w +w +w +d +climb +w +get eggs +n +take bottle +n +w +d +sw +u +toss eggs +ne +ne +barren +in +feed bear +unlock +unlock chain +take chain +take bear +fork +ne +e +take spices +drop keys +fork +w +w +sw +free bear +inven +sw +sw +d +se +se +w +d +get oil +up +e +take axe +w +w +d +climb +w +fee +fie +foe +foo +take eggs +s +d +u +w +u +s +e +e +n +n +off +plugh +drop eggs +drop pearl +drop spices +drop chain +take rug +take ruby +take emerald +out +w +n +n +n +inven +fill urn +light urn +rub urn +take amber +drop rug +drop emerald +fly rug +take sapphire +fly rug +take emerald +drop ruby +take rug +drop bottle +take ruby +e +s +e +e +in +drop ruby +drop sapphire +drop amber +drop rug +look +plugh +on +s +s +u +w +w +w +s +e +s +throw axe +take axe +s +s +n +e +e +nw +take emerald +take chest +se +n +d +e +e +off +xyzzy +drop emerald +drop chest +plugh +on +s +d +w +d +e +take magazine +e +drop magazine +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +u +u +e +u +n +plover +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +cave +e +take oyster +unlock oyster From c80162b4678cf5d95c70feb93d951aa115c2521b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 12:15:30 -0400 Subject: [PATCH 064/213] More test cleanup to converge with advent430 branch. --- tests/carrybird.chk | 6 +----- tests/carrybird.log | 3 +-- tests/dwarf_alternative.chk | 10 +++++++++- tests/dwarf_alternative.log | 1 + tests/flyback.log | 1 + tests/hint_urn.log | 3 ++- tests/hint_witt.log | 1 + tests/lampdim2.log | 2 +- tests/lampdim3.log | 2 +- tests/lockchain.chk | 10 +++++++++- tests/lockchain.log | 1 + tests/ogre_no_dwarves.log | 2 +- tests/reach_ledge_short.log | 2 +- 13 files changed, 30 insertions(+), 14 deletions(-) diff --git a/tests/carrybird.chk b/tests/carrybird.chk index 55f6ac9..5b4b1de 100644 --- a/tests/carrybird.chk +++ b/tests/carrybird.chk @@ -51,10 +51,6 @@ has scrawled, "MAGIC WORD XYZZY". A three foot black rod with a rusty star on an end lies nearby. -> eat grate - -I see no grate here. - > w You are in an awkward sloping east/west canyon. @@ -76,7 +72,7 @@ You can catch the bird, but you cannot carry it. The little bird is now dead. Its body disappears. > -You scored 32 out of a possible 430, using 10 turns. +You scored 32 out of a possible 430, using 9 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/carrybird.log b/tests/carrybird.log index 5f79548..d57736c 100644 --- a/tests/carrybird.log +++ b/tests/carrybird.log @@ -6,9 +6,8 @@ take lamp rub lamp xyzzy on -eat grate w w take bird # test intransitive attack on bird -attack \ No newline at end of file +attack diff --git a/tests/dwarf_alternative.chk b/tests/dwarf_alternative.chk index d9adb04..1dae06b 100644 --- a/tests/dwarf_alternative.chk +++ b/tests/dwarf_alternative.chk @@ -58,4 +58,12 @@ Oh dear, you seem to have gotten yourself killed. I might be able to help you out, but I've never really done this before. Do you want me to try to reincarnate you? -> \ No newline at end of file +> n + +OK + +You scored 51 out of a possible 430, using 7 turns. + +Your score qualifies you as a novice class adventurer. + +To achieve the next higher rating, you need 70 more points. diff --git a/tests/dwarf_alternative.log b/tests/dwarf_alternative.log index 69a0619..590cb59 100644 --- a/tests/dwarf_alternative.log +++ b/tests/dwarf_alternative.log @@ -8,3 +8,4 @@ w w d d +n diff --git a/tests/flyback.log b/tests/flyback.log index c4335de..059054e 100644 --- a/tests/flyback.log +++ b/tests/flyback.log @@ -1,4 +1,5 @@ ## Test fix for issue #51: rug flying is broken +#NOCOMPARE Behavior differs due to a bug fix. n seed 1838473132 in diff --git a/tests/hint_urn.log b/tests/hint_urn.log index 8154e71..926bc7d 100644 --- a/tests/hint_urn.log +++ b/tests/hint_urn.log @@ -1,4 +1,5 @@ ## Elicit hint for dealing with urn (fuzzed) +#NOCOMPARE Policy decision - no point in emulating advent430's extra \n here n seed 1495951709 u @@ -13,4 +14,4 @@ z z z y -y \ No newline at end of file +y diff --git a/tests/hint_witt.log b/tests/hint_witt.log index bafb070..6127dd5 100644 --- a/tests/hint_witt.log +++ b/tests/hint_witt.log @@ -1,4 +1,5 @@ ## Hint for Witt's End +#NOCOMPARE Policy decision - no point in emulating advent430's extra \n here n seed 1635997320 in diff --git a/tests/lampdim2.log b/tests/lampdim2.log index 7004519..14a615e 100644 --- a/tests/lampdim2.log +++ b/tests/lampdim2.log @@ -426,4 +426,4 @@ n s n s -lamp on \ No newline at end of file +lamp on diff --git a/tests/lampdim3.log b/tests/lampdim3.log index cb8ba7a..18f7e47 100644 --- a/tests/lampdim3.log +++ b/tests/lampdim3.log @@ -432,4 +432,4 @@ n s n up -down \ No newline at end of file +down diff --git a/tests/lockchain.chk b/tests/lockchain.chk index ff334a2..5645019 100644 --- a/tests/lockchain.chk +++ b/tests/lockchain.chk @@ -1888,4 +1888,12 @@ Oh dear, you seem to have gotten yourself killed. I might be able to help you out, but I've never really done this before. Do you want me to try to reincarnate you? -> \ No newline at end of file +> n + +OK + +You scored 219 out of a possible 430, using 328 turns. + +You may now consider yourself a "Seasoned Adventurer". + +To achieve the next higher rating, you need 32 more points. diff --git a/tests/lockchain.log b/tests/lockchain.log index a9db9e6..bf9cd99 100644 --- a/tests/lockchain.log +++ b/tests/lockchain.log @@ -334,3 +334,4 @@ s listen n jump +n diff --git a/tests/ogre_no_dwarves.log b/tests/ogre_no_dwarves.log index 1d5b269..fe51b51 100644 --- a/tests/ogre_no_dwarves.log +++ b/tests/ogre_no_dwarves.log @@ -23,4 +23,4 @@ s kill machine s s -attack \ No newline at end of file +attack diff --git a/tests/reach_ledge_short.log b/tests/reach_ledge_short.log index 2c33a04..49c0f02 100644 --- a/tests/reach_ledge_short.log +++ b/tests/reach_ledge_short.log @@ -238,4 +238,4 @@ take amber drop rug drop emera fly -e \ No newline at end of file +e From ff46cf7faccbc8a887c033c34681c526ca740747 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 16:04:36 -0400 Subject: [PATCH 065/213] Add -d option --- advent.h | 1 + main.c | 9 ++++++--- misc.c | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/advent.h b/advent.h index 4d1c9f3..8a31a9c 100644 --- a/advent.h +++ b/advent.h @@ -200,6 +200,7 @@ struct settings_t { int argc; int optind; FILE *scriptfp; + int debug; }; typedef struct { diff --git a/main.c b/main.c index f83c4e0..ab23ad9 100644 --- a/main.c +++ b/main.c @@ -1261,20 +1261,23 @@ int main(int argc, char *argv[]) /* Options. */ #if defined ADVENT_AUTOSAVE - const char* opts = "l:oa:"; + const char* opts = "dl:oa:"; const char* usage = "Usage: %s [-l logfilename] [-o] [-a filename] [script...]\n"; FILE *rfp = NULL; const char* autosave_filename = NULL; #elif !defined ADVENT_NOSAVE - const char* opts = "l:or:"; + const char* opts = "dl:or:"; const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n"; FILE *rfp = NULL; #else - const char* opts = "l:o"; + const char* opts = "dl:o"; const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n"; #endif while ((ch = getopt(argc, argv, opts)) != EOF) { switch (ch) { + case 'd': + settings.debug +=1; + break; case 'l': settings.logfp = fopen(optarg, "w"); if (settings.logfp == NULL) diff --git a/misc.c b/misc.c index c6733d5..34d045c 100644 --- a/misc.c +++ b/misc.c @@ -699,7 +699,7 @@ bool tstbit(int mask, int bit) } void set_seed(int32_t seedval) -/* Set the LCG seed */ +/* Set the LCG1 seed */ { game.lcg_x = seedval % LCG_M; if (game.lcg_x < 0) { @@ -718,6 +718,9 @@ static int32_t get_next_lcg_value(void) { int32_t old_x = game.lcg_x; game.lcg_x = (LCG_A * game.lcg_x + LCG_C) % LCG_M; + if (settings.debug) { + printf("# random %d\n", old_x); + } return old_x; } From 77ac2f157045d04e44a068f3790cbfbdf0c0ef15 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 18:16:43 -0400 Subject: [PATCH 066/213] Coverage exclusions for -d. --- main.c | 6 +++--- misc.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index ab23ad9..d4539b1 100644 --- a/main.c +++ b/main.c @@ -1275,9 +1275,9 @@ int main(int argc, char *argv[]) #endif while ((ch = getopt(argc, argv, opts)) != EOF) { switch (ch) { - case 'd': - settings.debug +=1; - break; + case 'd': // LCOV_EXCL_LINE + settings.debug +=1; // LCOV_EXCL_LINE + break; // LCOV_EXCL_LINE case 'l': settings.logfp = fopen(optarg, "w"); if (settings.logfp == NULL) diff --git a/misc.c b/misc.c index 34d045c..c2512cb 100644 --- a/misc.c +++ b/misc.c @@ -719,7 +719,7 @@ static int32_t get_next_lcg_value(void) int32_t old_x = game.lcg_x; game.lcg_x = (LCG_A * game.lcg_x + LCG_C) % LCG_M; if (settings.debug) { - printf("# random %d\n", old_x); + printf("# random %d\n", old_x); // LCOV_EXCL_LINE } return old_x; } From ef180a0731632c0e912b66f2fd82b22220a56319 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 18:17:30 -0400 Subject: [PATCH 067/213] Truncatte bigfail test because the RNG gets confused by resurrection. --- tests/bigfail.chk | 740 +--------------------------------------------- tests/bigfail.log | 138 +-------- 2 files changed, 4 insertions(+), 874 deletions(-) diff --git a/tests/bigfail.chk b/tests/bigfail.chk index 8084d1c..df15f38 100644 --- a/tests/bigfail.chk +++ b/tests/bigfail.chk @@ -1800,746 +1800,12 @@ Oh dear, you seem to have gotten yourself killed. I might be able to help you out, but I've never really done this before. Do you want me to try to reincarnate you? -> yes - -All right. But don't blame me if something goes wr...... - --- POOF!! --- -You are engulfed in a cloud of orange smoke. Coughing and gasping, -you emerge from the smoke and find.... - -You're inside building. - -There is a richly-carved ebony statuette here! - -There is an emerald here the size of a plover's egg! - -There is a jewel-encrusted trident here! - -There is a platinum pyramid here, 8 inches on a side! - -There are diamonds here! - -There is an enormous ruby here! - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -> inven - -You're not carrying anything. - -> out - -You're in front of building. - -There is a shiny brass lamp nearby. - -> take lamp +> n OK -> light lamp - -Your lamp is now on. - -> in - -You're inside building. - -There is a richly-carved ebony statuette here! - -There is an emerald here the size of a plover's egg! - -There is a jewel-encrusted trident here! - -There is a platinum pyramid here, 8 inches on a side! - -There are diamonds here! - -There is an enormous ruby here! - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -> plugh - ->>Foof!<< - -You're at "Y2". - -> s - -You're in n/s passage above e/w passage. - -> d - -You're in dirty passage. - -> bedquilt - -You're in Bedquilt. - -> n - -You're in large low room. - -> sw - -You're in sloping corridor. - -> up - -You're on sw side of chasm. - -There is a little axe here. - -There are many coins here! - -Off to one side lies a glistening pearl! - -There is a golden chain lying in a heap on the floor! - -The wreckage of a bridge (and a dead bear) can be seen at the bottom -of the chasm. - -The troll is nowhere to be seen. - -> over - -There is no longer any way across the chasm. - -You're on sw side of chasm. - -There is a little axe here. - -There are many coins here! - -Off to one side lies a glistening pearl! - -There is a golden chain lying in a heap on the floor! - -The wreckage of a bridge (and a dead bear) can be seen at the bottom -of the chasm. - -The troll is nowhere to be seen. - -> feed bear - -Don't be ridiculous! - -> attack bear - -For crying out loud, the poor thing is already dead! - -> take coins - -OK - -> take axe - -OK - -> sw - -You're in sloping corridor. - -> d - -You're in large low room. - -> se - -You're in Oriental Room. - -The floor is littered with worthless shards of pottery. - -> se - -You're in Swiss Cheese Room. - -> ne - -You are in Bedquilt, a long east/west passage with holes everywhere. -To explore at random select north, south, up, or down. - -> e - -You're at complex junction. - -> up - -You're in dusty rock room. - -> e - -You're in dirty passage. - -> up - -You are in a low n/s passage at a hole in the floor. The hole goes -down to an e/w passage. - -> s - -You're in Hall of Mt King. - -> up - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> w - -You're on east bank of fissure. - -A three foot black rod with a rusty star on an end lies nearby. - -A crystal bridge spans the fissure. - -> take rod - -OK - -> wave rod - -The crystal bridge has vanished! - -> across - -There is no way across the fissure. - -You're on east bank of fissure. - -> wave rod - -A crystal bridge now spans the fissure. - -> across - -You're on west bank of fissure. - -A crystal bridge spans the fissure. - -> w - -You're at west end of Hall of Mists. - -> w - -You're at east end of long hall. - -> w - -You're at west end of long hall. - -> s - -You are in a maze of twisty little passages, all different. - -> s - -You are in a maze of twisting little passages, all different. - -> sw - -You are in a twisting little maze of passages, all different. - -> se - -You are in a twisting maze of little passages, all different. - -> s - -You are in a little maze of twisting passages, all different. - -> s - -Dead end - -There is a massive vending machine here, swung back to reveal a -southward passage. - -> drop coins - -There are fresh batteries here. - -> look - -Sorry, but I am not allowed to give more detail. I will repeat the -long description of your location. - -Dead end - -There are fresh batteries here. - -There is a massive vending machine here, swung back to reveal a -southward passage. - -> n - -Your lamp is getting dim. I'm taking the liberty of replacing the -batteries. - -You are in a little maze of twisting passages, all different. - -> z - -OK - -> z - -Tsk! A wizard wouldn't have to take 350 turns. This is going to cost -you a couple of points. - -OK - -> z - -OK - -> z - -OK - -> s - -Dead end - -Some worn-out batteries have been discarded nearby. - -There is a massive vending machine here, swung back to reveal a -southward passage. - -> take batteries - -OK - -> n - -You are in a little maze of twisting passages, all different. - -> back - -Sorry, but the path twisted and turned so much that I can't figure -out which way to go to get back. - -You are in a little maze of twisting passages, all different. - -> n - -You are in a little maze of twisty passages, all different. - -> nw - -You are in a maze of twisty little passages, all different. - -> d - -You're at west end of long hall. - -> drink - -Drink what? - -> e - -You're at east end of long hall. - -> e - -You're at west end of Hall of Mists. - -> n - -You have crawled through a very low wide passage parallel to and north -of the Hall of Mists. - -You're on west bank of fissure. - -A crystal bridge spans the fissure. - -> w - -You're at west end of Hall of Mists. - -> w - -You're at east end of long hall. - -> n - -You are at a crossover of a high n/s passage and a low e/w one. - -> e - -You're in the west side chamber. - -> d - -There is no way to go that direction. - -You're in the west side chamber. - -> e - -You're in Hall of Mt King. - -> u - -There is a threatening little dwarf in the room with you! - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> throw axe - -You killed a little dwarf. - -You are at one end of a vast hall stretching forward out of sight to -the west. There are openings to either side. Nearby, a wide stone -staircase leads downward. The hall is filled with wisps of white mist -swaying to and fro almost as if alive. A cold wind blows up the -staircase. There is a passage at the top of a dome behind you. - -There is a little axe here. - -Rough stone steps lead up the dome. - -> d - -You're in Hall of Mt King. - -> n - -You're in n/s passage above e/w passage. - -> d - -You are in a dirty broken passage. To the east is a crawl. To the -west is a large passage. Above you is a hole to another passage. - -> e - -You are on the brink of a small clean climbable pit. A crawl leads -west. - -> d - -You are in the bottom of a small pit with a little stream, which -enters and exits through tiny slits. - -> listen - -The stream is gurgling placidly. - -> u - -You're at brink of small pit. - -> w - -You're in dirty passage. - -> bedquilt - -You're in Bedquilt. - -> z - -OK - -> z - -OK - -> z - -OK - -> n - -You have crawled around in some little holes and wound up back in the -main passage. - -You're in Bedquilt. - -> n - -You have crawled around in some little holes and wound up back in the -main passage. - -You're in Bedquilt. - -> n - -You have crawled around in some little holes and wound up back in the -main passage. - -You're in Bedquilt. - -> n - -You are in a secret canyon at a junction of three canyons, bearing -north, south, and se. The north one is as tall as the other two -combined. - -> w - -There is no way to go that direction. - -You're at junction of three secret canyons. - -> n - -You're at a low window overlooking a huge pit, which extends up out of -sight. A floor is indistinctly visible over 50 feet below. Traces of -white mist cover the floor of the pit, becoming thicker to the left. -Marks in the dust around the window would seem to indicate that -someone has been here recently. Directly across the pit from you and -25 feet away there is a similar window looking into a lighted room. A -shadowy figure can be seen there peering back at you. - -The shadowy figure seems to be trying to attract your attention. - -> w - -You're at junction of three secret canyons. - -> s - -You are in a secret n/s canyon above a sizable passage. - -> s - -A large stalactite extends from the roof and almost reaches the floor -below. You could climb down it, and jump from it to the floor, but -having done so you would be unable to reach it to climb back up. - -> n - -You are in a secret n/s canyon above a sizable passage. - -> s - -There are faint rustling noises from the darkness behind you. - -You're at top of stalactite. - -> n - -You are in a secret n/s canyon above a sizable passage. - -> n - -You're at junction of three secret canyons. - -> n - -You're at window on pit. - -The shadowy figure seems to be trying to attract your attention. - -> jump - -You are at the bottom of the pit with a broken neck. - -You clumsy oaf, you've done it again! I don't know how long I can -keep this up. Do you want me to try reincarnating you again? - -> y - -Okay, now where did I put my orange smoke?.... >POOF!< -Everything disappears in a dense cloud of orange smoke. - -You're inside building. - -There is a richly-carved ebony statuette here! - -There is an emerald here the size of a plover's egg! - -There is a jewel-encrusted trident here! - -There is a platinum pyramid here, 8 inches on a side! - -There are diamonds here! - -There is an enormous ruby here! - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -> out - -You are standing at the end of a road before a small brick building. -Around you is a forest. A small stream flows out of the building and -down a gully. - -There is a shiny brass lamp nearby. - -> take lamp - -OK - -> in - -You're inside building. - -There is a richly-carved ebony statuette here! - -There is an emerald here the size of a plover's egg! - -There is a jewel-encrusted trident here! - -There is a platinum pyramid here, 8 inches on a side! - -There are diamonds here! - -There is an enormous ruby here! - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -> downstream - -The stream flows out through a pair of 1 foot diameter sewer pipes. -It would be advisable to use the exit. - -You are inside a building, a well house for a large spring. - -There is a richly-carved ebony statuette here! - -There is an emerald here the size of a plover's egg! - -There is a jewel-encrusted trident here! - -There is a platinum pyramid here, 8 inches on a side! - -There are diamonds here! - -There is an enormous ruby here! - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on lamp - -Your lamp is now on. - -You are in a large room, with a passage to the south, a passage to the -west, and a wall of broken rock to the east. There is a large "Y2" on -a rock in the room's center. - -> w - -You're at a low window overlooking a huge pit, which extends up out of -sight. A floor is indistinctly visible over 50 feet below. Traces of -white mist cover the floor of the pit, becoming thicker to the right. -Marks in the dust around the window would seem to indicate that -someone has been here recently. Directly across the pit from you and -25 feet away there is a similar window looking into a lighted room. A -shadowy figure can be seen there peering back at you. - -The shadowy figure seems to be trying to attract your attention. - -> e - -You're at "Y2". - -> s - -You're in n/s passage above e/w passage. - -> s - -You're in Hall of Mt King. - -> e - -You're in Hall of Mists. - -There is a little axe here. - -Rough stone steps lead up the dome. - -> take axe - -OK - -> listen - -The wind whistles coldly past your ears. - -> score - -You have garnered 207 out of a possible 430 points, using 413 turns. - -> inven - -You are currently holding the following: -Brass lantern -Dwarf's axe - -> waste 2443 - -Game limit is now 27 - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> z - -Your lamp is getting dim, and you're out of spare batteries. You'd -best start wrapping this up. - -OK - -> -You scored 207 out of a possible 430, using 416 turns. +You scored 223 out of a possible 430, using 303 turns. You may now consider yourself a "Seasoned Adventurer". -To achieve the next higher rating, you need 44 more points. +To achieve the next higher rating, you need 28 more points. diff --git a/tests/bigfail.log b/tests/bigfail.log index a839f1c..121cd09 100644 --- a/tests/bigfail.log +++ b/tests/bigfail.log @@ -310,141 +310,5 @@ sw free bear take bear sw -yes -inven -out -take lamp -light lamp -in -plugh -s -d -bedquilt n -sw -up -over -feed bear -attack bear -# We'll need these when the game times out -take coins -take axe -# Back to fissure to vanish the bridge and then test OVER -sw -d -se -se -ne -e -up -e -up -s -up -w -take rod -wave rod -across -# Next, buy batteries but don't take them. -wave rod -across -w -w -w -s -s -sw -se -s -s -drop coins -look -n -z -z -z -z -# Battery warning happens here. -s -take batteries -# We now have 2500 more turns of life. Into the maze... -n -# Show that trying to back up in the maze fails -back -n -nw -d -# Out of maze. Drink where nothing is eligible. -drink -e -e -# PARALLEL1 coverage -n -# If we go to hall of mists we'll meet a killer dwarf with the drop on us -#e -#e -w -w -n -e -d -e -u -throw axe -d -n -d -# Coverage of LOC_SMALLPIT and LOC_SMALLPITBRINK -e -d -listen -u -w -# Coverage of LOC_THREEJUNCTION, LOC_WINDOW2, LOC_SECRET2, LOC_TOPSTALACTITE, -# LOC_NECKBROKE. Only accessible via stalactite from big maze or by random -# exit from Bedquilt. -bedquilt -z -z -z -n -n -n -n -# In secret canyon -w -n -w -s -# LOC_TOPSTALACTITE -s -n -s -n -n -n -jump -y -# Reincarnation, cover LOC_SEWER -out -take lamp -in -downstream -plugh -on lamp -# Cover WINDOW1 -w -e -# Retrieve axe -s -s -e -take axe -listen -# At Hall of Mists -score -inven -# Timewarp forward to test exhaustion of replacement batteries -waste 2443 -z -# MISSING_BATTERIES is uttered +quit From 74c3158f42e203b9633e5df50ba05c662c6433f4 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 29 Mar 2023 22:05:27 -0400 Subject: [PATCH 068/213] Add more NOCOMPARE exclusions due to version skew. --- tests/cheatresume.log | 1 + tests/cheatresume2.log | 1 + tests/saveresume.1.log | 1 + tests/saveresume.2.log | 1 + tests/savetamper.log | 1 + 5 files changed, 5 insertions(+) diff --git a/tests/cheatresume.log b/tests/cheatresume.log index 45d8df2..13ed78d 100644 --- a/tests/cheatresume.log +++ b/tests/cheatresume.log @@ -1,4 +1,5 @@ ## Resume from absurd save file with numdie = -900 +#NOCOMPARE Can't compare to asvent430 die to version skew n resume cheat_numdie.adv diff --git a/tests/cheatresume2.log b/tests/cheatresume2.log index 614c692..2843862 100644 --- a/tests/cheatresume2.log +++ b/tests/cheatresume2.log @@ -1,5 +1,6 @@ ## Resume from absurd save file with numdie = -1000 # generating "off my scale" score threshold message +#NOCOMPARE Can't compare to asvent430 die to version skew n resume cheat_numdie1000.adv diff --git a/tests/saveresume.1.log b/tests/saveresume.1.log index fffe43f..ceaf6bb 100644 --- a/tests/saveresume.1.log +++ b/tests/saveresume.1.log @@ -1,4 +1,5 @@ ## Save right after starting +#NOCOMPARE Can't compare to asvent430 die to version skew n seed 1240742801 save diff --git a/tests/saveresume.2.log b/tests/saveresume.2.log index 7ceb5dd..da629be 100644 --- a/tests/saveresume.2.log +++ b/tests/saveresume.2.log @@ -1,4 +1,5 @@ ## Resume and then quit +#NOCOMPARE Can't compate to asvent430 die to version skew n in resume diff --git a/tests/savetamper.log b/tests/savetamper.log index e62dfbe..e6b763f 100644 --- a/tests/savetamper.log +++ b/tests/savetamper.log @@ -1,4 +1,5 @@ ## Resume from artificial "corrupted" save +#NOCOMPARE Can't compare to asvent430 die to version skew n resume cheat_savetamper.adv From 872b94f9274724e256a77cff8e2e1eff0b664ff4 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 30 Mar 2023 00:05:13 -0400 Subject: [PATCH 069/213] Factor out most of illformed that doesn't cause advent430 problems. --- tests/illformed2.chk | 557 +++++++++++++++++++++++++++++++++++++++++++ tests/illformed2.log | 136 +++++++++++ tests/oldfilter | 10 +- 3 files changed, 701 insertions(+), 2 deletions(-) create mode 100644 tests/illformed2.chk create mode 100644 tests/illformed2.log diff --git a/tests/illformed2.chk b/tests/illformed2.chk new file mode 100644 index 0000000..2d02768 --- /dev/null +++ b/tests/illformed2.chk @@ -0,0 +1,557 @@ + +Welcome to Adventure!! Would you like instructions? + +> n + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed 1635997320 + +Seed set to 1635997320 + +You're in front of building. + +> back + +You can't get there from here. + +You're in front of building. + +> say axe + +Okay, "axe". + +> say rub + +Okay, "rub". + +> say grate + +Okay, "grate". + +> _ + +Sorry, I don't know the word "_". + +> back + +Sorry, but I no longer seem to remember how it was you got here. + +You're in front of building. + +> 23 + +Sorry, I don't know the word "23". + +> say F'UNJ + +Nothing happens. + +> in + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> keys + +What do you want to do with the keys? + +> throw food + +You aren't carrying it! + +> nothing food + +OK + +> calm food + +I'm game. Would you care to explain how? + +> walk food + +Where? + +> score food + +Huh? + +> foo food + +I don't know how. + +> brief food + +On what? + +> blast food + +Blasting requires dynamite. + +> find grate + +I can only tell you what you see as you move about and manipulate +things. I cannot tell you where remote things are. + +> light food + +I'm afraid I don't understand. + +> lock food + +I don't know how to lock or unlock such a thing. + +> unlock food + +I don't know how to lock or unlock such a thing. + +> extinguish food + +I'm afraid I don't understand. + +> suspend food + +Huh? + +> resume food + +Huh? + +> crawl + +Which way? + +You're inside building. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> out + +You're in front of building. + +> stream + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> lock + +There is nothing here with a lock! + +> take water + +You have nothing in which to carry it. + +> blast + +Blasting requires dynamite. + +> building + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> cave + +I don't know where the cave is, but hereabouts no stream can run on +the surface for long. I would try the stream. + +You're in front of building. + +> enter stream + +Your feet are now wet. + +> try three words + +Please stick to 1- and 2-word commands. + +> listen + +The stream is gurgling placidly. + +> carry + +Carry what? + +> forward + +I am unsure how you are facing. Use compass points or nearby objects. + +You're in front of building. + +> eat + +Eat what? + +> drink + +You have taken a drink from the stream. The water tastes strongly of +minerals, but is not unpleasant. It is extremely cold. + +> throw keys + +I see no keys here. + +> find keys + +I can only tell you what you see as you move about and manipulate +things. I cannot tell you where remote things are. + +> inven keys + +I can only tell you what you see as you move about and manipulate +things. I cannot tell you where remote things are. + +> nothing + +OK + +> in + +You're inside building. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> listen + +The stream is gurgling placidly. + +> find keys + +I believe what you want is right here with you. + +> unlock keys + +You can't unlock the keys. + +> find foo + +Nothing happens. + +> find bar + +Sorry, I don't know the word "bar". + +> carry + +Carry what? + +> blast + +Blasting requires dynamite. + +> take bottle + +OK + +> find bottle + +You are already carrying it! + +> drink water + +The bottle of water is now empty. + +> fill bottle + +Your bottle is now full of water. + +> throw axe + +I see no axe here. + +> throw knife + +I see no knife here. + +> lock + +There is nothing here with a lock! + +> unlock + +There is nothing here with a lock! + +> throw + +Throw what? + +> attack + +There is nothing here to attack. + +> unlock chain + +I see no chain here. + +> fill urn + +I see no urn here. + +> eat keys + +Don't be ridiculous! + +> discard keys + +You aren't carrying it! + +> drink keys + +Don't be ridiculous! + +> off keys + +I'm afraid I don't understand. + +> break keys + +It is beyond your power to do that. + +> wake keys + +Don't be ridiculous! + +> take keys + +OK + +> feed keys + +I'm game. Would you care to explain how? + +> fly keys + +I'm game. Would you care to explain how? + +> pour keys + +You can't pour that. + +> throw keys + +OK + +> foo up + +There is no way to go that direction. + +You're inside building. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +> get + +Get what? + +> food + +OK + +> eat food + +Thank you, it was delicious! + +> drink blood + +I see no blood here. + +> drink keys + +Don't be ridiculous! + +> light keys + +I'm afraid I don't understand. + +> brief + +Okay, from now on I'll only describe a place in full the first time +you come to it. To get the full description, say "look". + +> frob grate + +Sorry, I don't know the word "frob". + +> read grate + +I see no grate here. + +> pour bottle + +Your bottle is empty and the ground is wet. + +> fill bottle + +Your bottle is now full of water. + +> building + +I don't know how to apply that word here. + +You're inside building. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +> on + +Your lamp is now on. + +> pour bottle + +Your bottle is empty and the ground is wet. + +> xyzzy + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> take rod + +OK + +> wave rod + +Nothing happens. + +> listen + +All is silent. + +> quit + +Do you really want to quit now? + +> n + +OK + +> read + +Read what? + +> look + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> go back + +>>Foof!<< + +You're inside building. + +There are some keys on the ground here. + +There is a lamp shining nearby. + +> fuck + +Watch it! + +> walk + +Where? + +> fly + +Though you flap your arms furiously, it is to no avail. + +> say boo + +Okay, "boo". + +> score + +You have garnered 32 out of a possible 430 points, using 102 turns. + +> z + +OK + +> score + +You have garnered 32 out of a possible 430 points, using 104 turns. + +> quit keys + +Huh? + +> out + +You're in front of building. + +> s + +You're in valley. + +> s + +At your feet all the water of the stream splashes into a 2-inch slit +in the rock. Downstream the streambed is bare rock. + +> down + +You don't fit through a two-inch slit! + +You're at slit in streambed. + +> s + +You are in a 20-foot depression floored with bare dirt. Set into the +dirt is a strong steel grate mounted in concrete. A dry streambed +leads into the depression. + +The grate is locked. + +> in + +You can't go through a locked steel grate! + +You're outside grate. + +The grate is locked. + +> seed -123 + +Seed set to -123 + +You're outside grate. + +The grate is locked. + +> +You scored 32 out of a possible 430, using 111 turns. + +You are obviously a rank amateur. Better luck next time. + +To achieve the next higher rating, you need 14 more points. diff --git a/tests/illformed2.log b/tests/illformed2.log new file mode 100644 index 0000000..5e83e6a --- /dev/null +++ b/tests/illformed2.log @@ -0,0 +1,136 @@ +## Test for various cases not found in walkthroughs (advent430-compatible). +# Commented-out lines cause troble in advent430 +n +seed 1635997320 +back +# Next three lines were buggy +say axe +say rub +say grate +_ +back +#eat grate +23 +#eat building +#in +# Z'ZZZ Word correct, but does nothing +say F'UNJ +# Say bigwords when giant isn't around +#say fee +#say fie +#say foe +#say fum +in +keys +throw food +nothing food +calm food +walk food +score food +foo food +brief food +blast food +find grate +light food +lock food +unlock food +extinguish food +suspend food +resume food +crawl +out +stream +lock +take water +blast +building +cave +enter stream +try three words +listen +carry +forward +eat +drink +throw keys +find keys +inven keys +nothing +in +listen +find keys +unlock keys +find foo +find bar +carry +blast +take bottle +find bottle +drink water +fill bottle +throw axe +throw knife +lock +unlock +throw +attack +unlock chain +fill urn +eat keys +discard keys +drink keys +off keys +break keys +wake keys +take keys +feed keys +fly keys +pour keys +throw keys +foo up +get +food +eat food +drink blood +drink keys +light keys +brief +frob grate +read grate +#grate +pour bottle +fill bottle +building +on +pour bottle +xyzzy +take rod +wave rod +listen +quit +n +read +look +#l +#x +#i +#news +go back +fuck +walk +fly +say boo +score +z +score +quit keys +out +s +s +down +s +in +seed -123 +#no +#quit +#yes diff --git a/tests/oldfilter b/tests/oldfilter index fce8298..c834e5f 100755 --- a/tests/oldfilter +++ b/tests/oldfilter @@ -10,10 +10,16 @@ sed \ -e '/swiss/s//Swiss/' \ -e '/eying/s//eyeing/' \ -e '/threshhold/s//threshold/' \ - -e '/NAGGING/s//nagging/' \ + -e '/AXE/s//axe/' \ + -e '/BAR/s//bar/' \ + -e '/BOO/s//boo/' \ -e '/DOING/s//doing/' \ - -e '/SOMETHING/s//something/' \ -e '/EW/s//ew/' \ + -e '/FROB/s//frob/' \ + -e '/GRATE/s//grate/' \ + -e '/NAGGING/s//nagging/' \ + -e '/RUB/s//rub/' \ + -e '/SOMETHING/s//something/' \ -e '/ground/s//surface/' \ -e '/floor/s//surface/' \ From 30a98cc9164c7edea2744dac2100d2aa667903cd Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 30 Mar 2023 00:54:13 -0400 Subject: [PATCH 070/213] Factor out the test of the bare word "seed". --- tests/illformed.chk | 18 ++++++------------ tests/illformed.log | 1 - tests/seedless.chk | 21 +++++++++++++++++++++ tests/seedless.log | 4 ++++ 4 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 tests/seedless.chk create mode 100644 tests/seedless.log diff --git a/tests/illformed.chk b/tests/illformed.chk index 2f9cad3..7d8bdae 100644 --- a/tests/illformed.chk +++ b/tests/illformed.chk @@ -73,19 +73,11 @@ Sorry, but I no longer seem to remember how it was you got here. You're in front of building. -> seed - -This command requires a numeric argument. - -You're in front of building. - > waste This command requires a numeric argument. -You are standing at the end of a road before a small brick building. -Around you is a forest. A small stream flows out of the building and -down a gully. +You're in front of building. > eat grate @@ -238,7 +230,9 @@ There is a bottle of water here. > out -You're in front of building. +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. > stream @@ -622,7 +616,7 @@ Okay, "boo". > score -You have garnered 27 out of a possible 430 points, using 118 turns. +You have garnered 27 out of a possible 430 points, using 117 turns. > z @@ -630,7 +624,7 @@ OK > score -You have garnered 27 out of a possible 430 points, using 120 turns. +You have garnered 27 out of a possible 430 points, using 119 turns. > quit keys diff --git a/tests/illformed.log b/tests/illformed.log index 59315fe..08fef09 100644 --- a/tests/illformed.log +++ b/tests/illformed.log @@ -13,7 +13,6 @@ say rub say grate _ back -seed waste eat grate 23 diff --git a/tests/seedless.chk b/tests/seedless.chk new file mode 100644 index 0000000..d921b5f --- /dev/null +++ b/tests/seedless.chk @@ -0,0 +1,21 @@ + +Welcome to Adventure!! Would you like instructions? + +> n + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed + +This command requires a numeric argument. + +You're in front of building. + +> +You scored 32 out of a possible 430, using 1 turn. + +You are obviously a rank amateur. Better luck next time. + +To achieve the next higher rating, you need 14 more points. diff --git a/tests/seedless.log b/tests/seedless.log new file mode 100644 index 0000000..7c219f6 --- /dev/null +++ b/tests/seedless.log @@ -0,0 +1,4 @@ +# Check that argumentless seed command throws an error +#NOCOMPARE The word "seed" alone is mot recognized in advent430 +n +seed From 2c8aa9668c1ae198266975c0b4bf06fe31e5fd74 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 30 Mar 2023 08:46:35 -0400 Subject: [PATCH 071/213] Add explanatory comments to two tests. --- tests/illformed.log | 1 + tests/illformed2.log | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/illformed.log b/tests/illformed.log index 08fef09..b3964f1 100644 --- a/tests/illformed.log +++ b/tests/illformed.log @@ -25,6 +25,7 @@ say fee say fie say foe say fum +# Meant to evoke "I don't know in from out here." in keys throw food diff --git a/tests/illformed2.log b/tests/illformed2.log index 5e83e6a..c03110f 100644 --- a/tests/illformed2.log +++ b/tests/illformed2.log @@ -20,6 +20,7 @@ say F'UNJ #say fie #say foe #say fum +# Meant to evoke "I don't know in from out here." in keys throw food From 3af590e972c9c5804d39b5a3beb2b48275acb18f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 30 Mar 2023 20:09:10 -0400 Subject: [PATCH 072/213] Trim the illformed test. Still 100% coverage. --- tests/illformed.chk | 541 +------------------------------------------- tests/illformed.log | 114 +--------- 2 files changed, 6 insertions(+), 649 deletions(-) diff --git a/tests/illformed.chk b/tests/illformed.chk index 7d8bdae..76c1d17 100644 --- a/tests/illformed.chk +++ b/tests/illformed.chk @@ -153,542 +153,9 @@ There is a bottle of water here. What do you want to do with the keys? -> throw food +> +You scored 27 out of a possible 430, using 20 turns. -You aren't carrying it! +You are obviously a rank amateur. Better luck next time. -> nothing food - -OK - -> calm food - -I'm game. Would you care to explain how? - -> walk food - -Where? - -> score food - -Huh? - -> foo food - -I don't know how. - -> brief food - -On what? - -> blast food - -Blasting requires dynamite. - -> find grate - -I can only tell you what you see as you move about and manipulate -things. I cannot tell you where remote things are. - -> light food - -I'm afraid I don't understand. - -> lock food - -I don't know how to lock or unlock such a thing. - -> unlock food - -I don't know how to lock or unlock such a thing. - -> extinguish food - -I'm afraid I don't understand. - -> suspend food - -Huh? - -> resume food - -Huh? - -> crawl - -Which way? - -You're inside building. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -There is food here. - -There is a bottle of water here. - -> out - -You are standing at the end of a road before a small brick building. -Around you is a forest. A small stream flows out of the building and -down a gully. - -> stream - -You are in a valley in the forest beside a stream tumbling along a -rocky bed. - -> lock - -There is nothing here with a lock! - -> take water - -You have nothing in which to carry it. - -> blast - -Blasting requires dynamite. - -> building - -You're in front of building. - -> cave - -I don't know where the cave is, but hereabouts no stream can run on -the surface for long. I would try the stream. - -You're in front of building. - -> enter stream - -Your feet are now wet. - -> try three words - -Please stick to 1- and 2-word commands. - -> listen - -The stream is gurgling placidly. - -> carry - -Carry what? - -> forward - -I am unsure how you are facing. Use compass points or nearby objects. - -You're in front of building. - -> eat - -Eat what? - -> drink - -You have taken a drink from the stream. The water tastes strongly of -minerals, but is not unpleasant. It is extremely cold. - -> throw keys - -I see no keys here. - -> find keys - -I can only tell you what you see as you move about and manipulate -things. I cannot tell you where remote things are. - -> inven keys - -I can only tell you what you see as you move about and manipulate -things. I cannot tell you where remote things are. - -> nothing - -OK - -> in - -You're inside building. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -There is food here. - -There is a bottle of water here. - -> listen - -The stream is gurgling placidly. - -> find keys - -I believe what you want is right here with you. - -> unlock keys - -You can't unlock the keys. - -> find foo - -Nothing happens. - -> find bar - -Sorry, I don't know the word "bar". - -> carry - -Carry what? - -> blast - -Blasting requires dynamite. - -> take bottle - -OK - -> find bottle - -You are already carrying it! - -> drink water - -The bottle of water is now empty. - -> fill bottle - -Your bottle is now full of water. - -> throw axe - -I see no axe here. - -> throw knife - -I see no knife here. - -> lock - -There is nothing here with a lock! - -> unlock - -There is nothing here with a lock! - -> throw - -Throw what? - -> attack - -There is nothing here to attack. - -> unlock chain - -I see no chain here. - -> fill urn - -I see no urn here. - -> eat keys - -Don't be ridiculous! - -> discard keys - -You aren't carrying it! - -> drink keys - -Don't be ridiculous! - -> off keys - -I'm afraid I don't understand. - -> break keys - -It is beyond your power to do that. - -> wake keys - -Don't be ridiculous! - -> take keys - -OK - -> feed keys - -I'm game. Would you care to explain how? - -> fly keys - -I'm game. Would you care to explain how? - -> pour keys - -You can't pour that. - -> throw keys - -OK - -> foo up - -There is no way to go that direction. - -You are inside a building, a well house for a large spring. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -There is food here. - -> get - -Get what? - -> food - -OK - -> eat food - -Thank you, it was delicious! - -> drink blood - -I see no blood here. - -> drink keys - -Don't be ridiculous! - -> light keys - -I'm afraid I don't understand. - -> brief - -Okay, from now on I'll only describe a place in full the first time -you come to it. To get the full description, say "look". - -> frob grate - -Sorry, I don't know the word "frob". - -> read grate - -I see no grate here. - -> grate - -I don't know how to apply that word here. - -You're inside building. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -> pour bottle - -Your bottle is empty and the ground is wet. - -> fill bottle - -Your bottle is now full of water. - -> building - -I don't know how to apply that word here. - -You're inside building. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -> on - -Your lamp is now on. - -> pour bottle - -Your bottle is empty and the ground is wet. - -> xyzzy - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> take rod - -OK - -> wave rod - -Nothing happens. - -> listen - -All is silent. - -> quit - -Do you really want to quit now? - -> n - -OK - -> read - -Read what? - -> look - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> l - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> x - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> i - -You are currently holding the following: -Black rod -Small bottle - -> news - -Open Adventure is an author-approved open-source release of -Version 2.5 with, as yet, no gameplay changes. -Version 2.5 was essentially the same as Version II; the cave and the -hazards therein are unchanged, and top score is still 430 points. -There are a few more hints, especially for some of the more obscure -puzzles. There are a few minor bugfixes and cosmetic changes. You -can now save a game and resume it at once (formerly you had to wait a -while first), but it now costs you a few points each time you save the -game. Saved games are now stored in much smaller files than before. - -> go back - ->>Foof!<< - -You're inside building. - -There are some keys on the ground here. - -There is a lamp shining nearby. - -> fuck - -Watch it! - -> walk - -Where? - -> fly - -Though you flap your arms furiously, it is to no avail. - -> say boo - -Okay, "boo". - -> score - -You have garnered 27 out of a possible 430 points, using 117 turns. - -> z - -OK - -> score - -You have garnered 27 out of a possible 430 points, using 119 turns. - -> quit keys - -Huh? - -> out - -You're in front of building. - -> s - -You're in valley. - -> s - -At your feet all the water of the stream splashes into a 2-inch slit -in the rock. Downstream the streambed is bare rock. - -> down - -You don't fit through a two-inch slit! - -You're at slit in streambed. - -> s - -You are in a 20-foot depression floored with bare dirt. Set into the -dirt is a strong steel grate mounted in concrete. A dry streambed -leads into the depression. - -The grate is locked. - -> in - -You can't go through a locked steel grate! - -You're outside grate. - -The grate is locked. - -> seed -123 - -Seed set to -123 - -You're outside grate. - -The grate is locked. - -> no - -OK - -Are you trying to get into the cave? - -> quit - -Please answer the question. - -Are you trying to get into the cave? - -> yes - -I am prepared to give you a hint, but it will cost you 2 points. - -Do you want the hint? - -> \ No newline at end of file +To achieve the next higher rating, you need 19 more points. diff --git a/tests/illformed.log b/tests/illformed.log index b3964f1..537dd8e 100644 --- a/tests/illformed.log +++ b/tests/illformed.log @@ -1,4 +1,5 @@ ## Test for various cases not found in walkthroughs. +#NOCOMPARE This is busted under advent430 -- see comments within. foo y @@ -13,6 +14,7 @@ say rub say grate _ back +# advent430 doesn't have this command waste eat grate 23 @@ -28,115 +30,3 @@ say fum # Meant to evoke "I don't know in from out here." in keys -throw food -nothing food -calm food -walk food -score food -foo food -brief food -blast food -find grate -light food -lock food -unlock food -extinguish food -suspend food -resume food -crawl -out -stream -lock -take water -blast -building -cave -enter stream -try three words -listen -carry -forward -eat -drink -throw keys -find keys -inven keys -nothing -in -listen -find keys -unlock keys -find foo -find bar -carry -blast -take bottle -find bottle -drink water -fill bottle -throw axe -throw knife -lock -unlock -throw -attack -unlock chain -fill urn -eat keys -discard keys -drink keys -off keys -break keys -wake keys -take keys -feed keys -fly keys -pour keys -throw keys -foo up -get -food -eat food -drink blood -drink keys -light keys -brief -frob grate -read grate -grate -pour bottle -fill bottle -building -on -pour bottle -xyzzy -take rod -wave rod -listen -quit -n -read -look -l -x -i -news -go back -fuck -walk -fly -say boo -score -z -score -quit keys -out -s -s -down -s -in -seed -123 -no -quit -yes From 7af84921697cf43aef286832bac55484fe293255 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 1 Apr 2023 08:46:44 -0400 Subject: [PATCH 073/213] Add a warning comment. --- tests/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Makefile b/tests/Makefile index 8cf9e7e..04f2da5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -141,6 +141,11 @@ count: # making it a skipped test in the TAP view. First use of this was to avoid a # spurious mismatch on the news text. Other uses avoid spurios mismatches due # to bug fixes. +# +# When adding more tests, bear in mind that any game that continues after a +# resurrection will need a NOCOMPARE. At some point in the forward port, +# resurrection was accidentally changed in a way that messed wil the LCG chain. +# TAPFILTER=tapview ancient: $(SGAMES) @if [ -f ../advent430 ]; then cp ../advent430 ../adventure.data .; else echo "advent430 nonexistent"; exit 1; fi From 0d2332573ba4572a0f651f69d1f303c7a82ffaf6 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 1 Apr 2023 10:47:49 -0400 Subject: [PATCH 074/213] Tweak a fuzzed test fotr advent430 compability. 100% coverage. --- tests/reach_ledge_short.chk | 812 ++++++++++-------------------------- tests/reach_ledge_short.log | 2 +- 2 files changed, 222 insertions(+), 592 deletions(-) diff --git a/tests/reach_ledge_short.chk b/tests/reach_ledge_short.chk index 7e57aa1..7c02c64 100644 --- a/tests/reach_ledge_short.chk +++ b/tests/reach_ledge_short.chk @@ -555,11 +555,9 @@ The ogre, distracted by your rush, is struck by the knife. With a blood-curdling yell he turns and bounds after the dwarf, who flees in panic. You are left alone in the room. -> +> z -I don't know how to apply that word here. - -You are in a large chamber with passages to the west and north. +OK > s @@ -622,10 +620,6 @@ A crystal bridge spans the fissure. There is a threatening little dwarf in the room with you! -One sharp nasty knife is thrown at you! - -It misses! - You are at one end of a vast hall stretching forward out of sight to the west. There are openings to either side. Nearby, a wide stone staircase leads downward. The hall is filled with wisps of white mist @@ -657,12 +651,20 @@ A cheerful little bird is sitting here singing. > n +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + You're in n/s passage above e/w passage. There are bars of silver here! > n +There is a threatening little dwarf in the room with you! + You are in a large room, with a passage to the south, a passage to the west, and a wall of broken rock to the east. There is a large "Y2" on a rock in the room's center. @@ -693,14 +695,14 @@ There is food here. It is now pitch dark. If you proceed you will likely fall into a pit. +A hollow voice says "PLUGH". + > on Your lamp is now on. You're at "Y2". -A hollow voice says "PLUGH". - > s You are in a low n/s passage at a hole in the floor. The hole goes @@ -716,12 +718,20 @@ A cheerful little bird is sitting here singing. > u +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + You're in Hall of Mists. Rough stone steps lead up the dome. > n +There is a threatening little dwarf in the room with you! + You are in the Hall of the Mountain King, with passages off in all directions. @@ -729,12 +739,16 @@ A cheerful little bird is sitting here singing. > n +There is a threatening little dwarf in the room with you! + You're in n/s passage above e/w passage. There are bars of silver here! > d +There is a threatening little dwarf in the room with you! + You are in a dirty broken passage. To the east is a crawl. To the west is a large passage. Above you is a hole to another passage. @@ -747,7 +761,13 @@ To explore at random select north, south, up, or down. > throw axe -You killed a little dwarf. +You attack a little dwarf, but he dodges out of the way. + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! You're in Bedquilt. @@ -755,10 +775,12 @@ There is a little axe here. > take -OK +Take what? > slab +There is a threatening little dwarf in the room with you! + You are in a large low circular chamber whose floor is an immense slab fallen from the ceiling (Slab Room). East and west there once were large passages, but they are now filled with boulders. Low small @@ -767,11 +789,15 @@ around the boulders. > s +There is a threatening little dwarf in the room with you! + You are at the west end of the Twopit Room. There is a large hole in the wall above the pit at this end of the room. > d +There is a threatening little dwarf in the room with you! + You are at the bottom of the western pit in the Twopit Room. There is a large hole in the wall about 25 feet above you. @@ -781,6 +807,12 @@ There is a tiny little plant in the pit, murmuring "water, water, ..." The plant spurts into furious growth for a few seconds. +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + You're in west pit. There is a 12-foot-tall beanstalk stretching up out of the pit, @@ -788,20 +820,28 @@ bellowing "WATER!! WATER!!" > u +There is a threatening little dwarf in the room with you! + You're at west end of Twopit Room. The top of a 12-foot-tall beanstalk is poking out of the west pit. > west +There is a threatening little dwarf in the room with you! + You're in Slab Room. > u +There is a threatening little dwarf in the room with you! + You are in a secret n/s canyon above a large room. > reser +There is a threatening little dwarf in the room with you! + You are at the edge of a large underground reservoir. An opaque cloud of white mist fills the room and rises rapidly upward. The lake is fed by a stream, which tumbles out of a hole in the wall about 10 feet @@ -814,12 +854,16 @@ The waters have parted to form a narrow path across the reservoir. > n +There is a threatening little dwarf in the room with you! + You are walking across the bottom of the reservoir. Walls of water rear up on either side. The roar of the water cascading past is nearly deafening, and the mist is so thick you can barely see. > n +There is a threatening little dwarf in the room with you! + You are at the northern edge of the reservoir. A northwest passage leads sharply up from here. @@ -827,14 +871,20 @@ The waters have parted to form a narrow path across the reservoir. > u +There is a threatening little dwarf in the room with you! + You are scrambling along a treacherously steep, rocky passage. > u +There is a threatening little dwarf in the room with you! + You are on a very steep incline, which widens at it goes upward. > u +There is a threatening little dwarf in the room with you! + You are at the base of a nearly vertical cliff. There are some slim footholds which would enable you to climb up, but it looks extremely dangerous. Here at the base of the cliff lie the remains @@ -842,642 +892,222 @@ of several earlier adventurers who apparently failed to make it. > u +There is a threatening little dwarf in the room with you! + You are climbing along a nearly vertical cliff. > e There is no way to go that direction. -You are climbing along a nearly vertical cliff. - -> w - -There is no way to go that direction. - -You are climbing along a nearly vertical cliff. - -> d - -You're at base of cliff. - -> d - -You are on a very steep incline, which widens at it goes upward. - -> d - -You are scrambling along a treacherously steep, rocky passage. - -> d - -You're north of reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> d - -There is no way to go that direction. - -You're north of reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> take water - -Your bottle is now full of water. - -> s - -You're at bottom of reservoir. - -> s - -You're at reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> s - -You are in a north/south canyon about 25 feet across. The floor is -covered by white mist seeping in from the north. The walls extend -upward for well over 100 feet. Suspended from some unseen point far -above you, an enormous two-sided mirror is hanging parallel to and -midway between the canyon walls. (The mirror is obviously provided -for the use of the dwarves who, as you know, are extremely vain.) A -small window can be seen in either wall, some fifty feet up. - -> s - -You are in a secret n/s canyon above a large room. - -> d - -You're in Slab Room. - -> s - -You're at west end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> d - -You're in west pit. - -There is a 12-foot-tall beanstalk stretching up out of the pit, -bellowing "WATER!! WATER!!" - -> water plant - -The plant grows explosively, almost filling the bottom of the pit. - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> u - -You're at west end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> e - -You are at the east end of the Twopit Room. The floor here is -littered with thin rock slabs, which make it easy to descend the pits. -There is a path here bypassing the pits to connect passages from east -and west. There are holes all over, but the only big one is on the -wall directly over the west pit where you can't get to it. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You are at the bottom of the eastern pit in the Twopit Room. There is -a small pool of oil in one corner of the pit. - -> get oil - -Your bottle is now full of oil. - -> u - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> west - -You're at west end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> climb - -You clamber up the plant and scurry through the hole at the top. - -You are in a long, narrow corridor stretching out of sight to the -west. At the eastern end is a hole through which you can see a -profusion of leaves. - -> west - -You are in the Giant Room. The ceiling here is too high up for your -lamp to show it. Cavernous passages lead east, north, and south. On -the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. - -There is a large nest here, full of golden eggs! - -> n - -You are at one end of an immense north/south passage. - -The way north is barred by a massive, rusty, iron door. - -> oil door - -The oil has freed up the hinges so that the door will now move, -although it requires some effort. - -> drop bottl - -OK - -> n - -You are in a magnificent cavern with a rushing stream, which cascades -over a sparkling waterfall into a roaring whirlpool which disappears -through a hole in the floor. Passages exit to the south and west. - -There is a jewel-encrusted trident here! - -> west - -You are at the top of a steep incline above a large room. You could -climb down here, but you would not be able to climb up. There is a -passage leading back to the north. - -> d - -You are in a large low room. Crawls lead north, se, and sw. - -> se - -This is the Oriental Room. Ancient oriental cave drawings cover the -walls. A gently sloping passage leads upward to the north, another -passage leads se, and a hands and knees crawl leads west. - -There is a delicate, precious, ming vase here! - -> n - -You are following a wide path around the outer edge of a large cavern. -Far below, through a heavy white mist, strange splashing noises can be -heard. The mist rises up through a fissure in the ceiling. The path -exits to the south and west. - -> west - -You are in an alcove. A small nw path seems to widen after a short -distance. An extremely tight tunnel leads east. It looks like a very -tight squeeze. An eerie light can be seen at the other end. - -> drop axe - -OK - -> drop lante - -OK - -> e - -You're in Plover Room. - -There is an emerald here the size of a plover's egg! - -> take emera - -OK - -> west - -You're in alcove. - -There is a lamp shining nearby. - -There is a little axe here. - -> take lamp - -OK - -> take - -OK - -> nw - -You're in misty cavern. - -> s - -You're in Oriental Room. - -There is a delicate, precious, ming vase here! - -> e - -There is no way to go that direction. - -You're in Oriental Room. - -There is a delicate, precious, ming vase here! - -> se - There is a threatening little dwarf in the room with you! -You are in a room whose walls resemble Swiss cheese. Obvious passages -go west, east, ne, and nw. Part of the room is occupied by a large -bedrock block. +One sharp nasty knife is thrown at you! -> throw axe +It gets you! -You killed a little dwarf. - -You're in Swiss Cheese Room. - -There is a little axe here. - -> e - -You are in the Soft Room. The walls are covered with heavy curtains, -the floor with a thick pile carpet. Moss covers the ceiling. - -A small velvet pillow lies on the floor. - -> west - -You're in Swiss Cheese Room. - -There is a little axe here. - -> d - -There is no way to go that direction. - -You're in Swiss Cheese Room. - -There is a little axe here. - -> ne - -You're in Bedquilt. - -> e - -You are at a complex junction. A low hands and knees passage from the -north joins a higher crawl from the east to make a walking passage -going west. There is also a large room above. The air is damp here. - -> u - -You are in a large room full of dusty rocks. There is a big hole in -the floor. There are cracks everywhere, and a passage leading east. - -> e - -You're in dirty passage. - -> u - -You're in n/s passage above e/w passage. - -There are bars of silver here! - -> n - -You're at "Y2". - -> plugh - ->>Foof!<< - -You are inside a building, a well house for a large spring. - -There is a Persian rug spread out on the floor! - -There are some keys on the ground here. - -There is food here. - -> take key - -OK - -> take food - -OK - -> plugh - ->>Foof!<< - -You're at "Y2". - -> s - -You're in n/s passage above e/w passage. - -There are bars of silver here! - -> d - -You're in dirty passage. - -> west - -You're in dusty rock room. - -> d - -You're at complex junction. - -> n - -You're in a large room carved out of sedimentary rock. The floor and -walls are littered with bits of shells embedded in the stone. A -shallow passage proceeds downward, and a somewhat steeper one leads -up. A low hands and knees passage enters from the south. - -There is an enormous clam here with its shell tightly closed. - -> d - -You are in a long sloping corridor with ragged sharp walls. - -> d - -You are in a cul-de-sac about eight feet across. - -> u - -You are in a long sloping corridor with ragged sharp walls. - -> u - -You're in Shell Room. - -There is an enormous clam here with its shell tightly closed. - -> s - -You're at complex junction. - -> west - -You're in Bedquilt. - -> west - -You're in Swiss Cheese Room. - -There is a little axe here. - -> west - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> west - -You are at the west end of the Twopit Room. There is a large hole in -the wall above the pit at this end of the room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You are at the bottom of the western pit in the Twopit Room. There is -a large hole in the wall about 25 feet above you. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> climb - -You clamber up the plant and scurry through the hole at the top. - -You're in narrow corridor. - -> west - -You're in Giant Room. - -There is a large nest here, full of golden eggs! - -> n - -You are at one end of an immense north/south passage. - -There is an empty bottle here. - -The way north leads through a massive, rusty, iron door. - -> take bottl - -OK - -> n - -You're in cavern with waterfall. - -There is a jewel-encrusted trident here! +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? > w -You're at steep incline above large room. +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? > d -You're in large low room. +Please answer the question. -> se - -You're in Oriental Room. - -There is a delicate, precious, ming vase here! - -> se - -You are in a room whose walls resemble Swiss cheese. Obvious passages -go west, east, ne, and nw. Part of the room is occupied by a large -bedrock block. - -There is a little axe here. - -> west - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? > d -You're in east pit. +Please answer the question. -> get oil +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? -Your bottle is now full of oil. +> d -> u +Please answer the question. -You're at east end of Twopit Room. +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? -There is a huge beanstalk growing out of the west pit up to the hole. +> d -> west +Please answer the question. -You're at west end of Twopit Room. +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? -There is a huge beanstalk growing out of the west pit up to the hole. +> d -> west +Please answer the question. -You're in Slab Room. +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? -> u +> take water -You are in a secret n/s canyon above a large room. +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? > s -You are in a secret canyon which exits to the north and east. +Please answer the question. -The blood-specked body of a huge green dead dragon lies to one side. +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> s + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> s + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> s + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> d + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> s + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> d + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> water plant + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> u + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? > e -You're in secret e/w canyon above tight canyon. +Please answer the question. -> e +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? -You're in Hall of Mt King. +> d -A cheerful little bird is sitting here singing. +Please answer the question. -> n +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? -You're in n/s passage above e/w passage. +> get oil -There are bars of silver here! +Please answer the question. -> n +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? -You're at "Y2". +> u -> plugh +Please answer the question. ->>Foof!<< - -You're inside building. - -There is a Persian rug spread out on the floor! - -> take - -OK - -> out - -You're in front of building. +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? > west -You have walked up a hill, still in the forest. The road slopes back -down the other side of the hill. There is a building in the distance. +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> d + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> climb + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? + +> west + +Please answer the question. + +Oh dear, you seem to have gotten yourself killed. I might be able to +help you out, but I've never really done this before. Do you want me +to try to reincarnate you? > n -You are wandering aimlessly through the forest. - -> n - -You are wandering aimlessly through the forest. - -> n - -The forest thins out here to reveal a steep cliff. There is no way -down, but a small ledge can be seen to the west across the chasm. - -A small urn is embedded in the rock. - -> fill urn - -Your bottle is now empty and the urn is full of oil. - -> light - -The urn is now lit. - -> rub urn - -As you rub the urn, there is a flash of light and a genie appears. -His aspect is stern as he advises: "One who wouldst traffic in -precious stones must first learn to recognize the signals thereof." -He wrests the urn from the stone, leaving a small cavity. Turning to -face you again, he fixes you with a steely eye and intones: "Caution!" -Genie and urn vanish in a cloud of amber smoke. The smoke condenses -to form a rare amber gemstone, resting in the cavity in the rock. - -> take amber - OK -> drop rug - -OK - -> drop emera - -The gem fits easily into the cavity. - -The Persian rug stiffens and rises a foot or so off the ground. - -> fly - -You board the Persian rug, which promptly whisks you across the chasm. -You have time for a fleeting glimpse of a two thousand foot drop to a -mighty river; then you find yourself on the other side. - -You are on a small ledge on one face of a sheer cliff. There are no -paths away from the ledge. Across the chasm is a small clearing -surrounded by forest. - -There is a Persian rug here, hovering in mid-air! - -A brilliant blue star sapphire is here! - -> e - -There is no way to go that direction. - -You're on ledge. - -There is a Persian rug here, hovering in mid-air! - -A brilliant blue star sapphire is here! - -> -You scored 81 out of a possible 430, using 237 turns. +You scored 79 out of a possible 430, using 128 turns. Your score qualifies you as a novice class adventurer. -To achieve the next higher rating, you need 40 more points. +To achieve the next higher rating, you need 42 more points. diff --git a/tests/reach_ledge_short.log b/tests/reach_ledge_short.log index 49c0f02..a0acfc6 100644 --- a/tests/reach_ledge_short.log +++ b/tests/reach_ledge_short.log @@ -83,7 +83,7 @@ kill machi s s kill ogre - +z s west n From 97a69d8cbd2a3f57d3df419a8c881593d7643470 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 1 Apr 2023 11:01:28 -0400 Subject: [PATCH 075/213] Merge two NOCOMPARE tests. --- tests/illformed.chk | 10 +++++++++- tests/illformed.log | 2 ++ tests/seedless.chk | 21 --------------------- tests/seedless.log | 4 ---- 4 files changed, 11 insertions(+), 26 deletions(-) delete mode 100644 tests/seedless.chk delete mode 100644 tests/seedless.log diff --git a/tests/illformed.chk b/tests/illformed.chk index 76c1d17..7366d49 100644 --- a/tests/illformed.chk +++ b/tests/illformed.chk @@ -79,6 +79,14 @@ This command requires a numeric argument. You're in front of building. +> seed + +This command requires a numeric argument. + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + > eat grate I see no grate here. @@ -154,7 +162,7 @@ There is a bottle of water here. What do you want to do with the keys? > -You scored 27 out of a possible 430, using 20 turns. +You scored 27 out of a possible 430, using 21 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/illformed.log b/tests/illformed.log index 537dd8e..c86b874 100644 --- a/tests/illformed.log +++ b/tests/illformed.log @@ -16,6 +16,8 @@ _ back # advent430 doesn't have this command waste +# seed should cause a compint when argumentless, +seed eat grate 23 eat building diff --git a/tests/seedless.chk b/tests/seedless.chk deleted file mode 100644 index d921b5f..0000000 --- a/tests/seedless.chk +++ /dev/null @@ -1,21 +0,0 @@ - -Welcome to Adventure!! Would you like instructions? - -> n - -You are standing at the end of a road before a small brick building. -Around you is a forest. A small stream flows out of the building and -down a gully. - -> seed - -This command requires a numeric argument. - -You're in front of building. - -> -You scored 32 out of a possible 430, using 1 turn. - -You are obviously a rank amateur. Better luck next time. - -To achieve the next higher rating, you need 14 more points. diff --git a/tests/seedless.log b/tests/seedless.log deleted file mode 100644 index 7c219f6..0000000 --- a/tests/seedless.log +++ /dev/null @@ -1,4 +0,0 @@ -# Check that argumentless seed command throws an error -#NOCOMPARE The word "seed" alone is mot recognized in advent430 -n -seed From f95442b310dac867caa7eb0d02cef436edf8fa63 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 1 Apr 2023 11:34:46 -0400 Subject: [PATCH 076/213] Test comment typo fixes. --- tests/endobjects.log | 2 +- tests/resumefail.log | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/endobjects.log b/tests/endobjects.log index 6bec970..96e9fd8 100644 --- a/tests/endobjects.log +++ b/tests/endobjects.log @@ -1,6 +1,6 @@ ### Check that water is unavailable in endgame # Addresses GitLab issue #55: in endgame, some object starting states are incorrect -#NOCOMPARE Bird was not weightless in cade in advent430, this test depends on that. +#NOCOMPARE Bird was not weightless in cage in advent430, this test depends on that. no seed 11247848 no diff --git a/tests/resumefail.log b/tests/resumefail.log index 1e1fdb5..e7944ef 100644 --- a/tests/resumefail.log +++ b/tests/resumefail.log @@ -1,5 +1,5 @@ ## Resume from invalid filename -#NOCOMPARE advent430 crashes on resume fom invalid filename and we don't care. +#NOCOMPARE advent430 crashes on resume from invalid filename and we don't care. n seed 1240742801 resume From 59a5afb72e4981ab370437c0f4b950f1d4424aa3 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 1 Apr 2023 16:58:52 -0400 Subject: [PATCH 077/213] Improve advent430 comparisons. --- tests/Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 04f2da5..1593b69 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -134,7 +134,7 @@ count: # does not remove them). # # The diff file produced has corrected spellings in it. That's what oldfilter -# is for, to massage out the orioginal dpellings and avoid noise diffs. +# is for, to massage out the original dpellings and avoid noise diffs. # Diffs in amount of whitespace and trailing whitespace are ignored # # A magic comment of NOCOMPARE in a log file excludes it from this comparison. @@ -146,8 +146,10 @@ count: # resurrection will need a NOCOMPARE. At some point in the forward port, # resurrection was accidentally changed in a way that messed wil the LCG chain. # +# The *.chk files need not be up-to-date for this to work. +# TAPFILTER=tapview -ancient: $(SGAMES) +oldcompare: $(SGAMES) @if [ -f ../advent430 ]; then cp ../advent430 ../adventure.data .; else echo "advent430 nonexistent"; exit 1; fi @-(for x in *.log; do \ stem=$${x%.log}; \ @@ -156,10 +158,11 @@ ancient: $(SGAMES) then echo "not ok - $${stem}.ochk: $${legend} # SKIP"; \ else \ ./advent430 <$${stem}.log | oldfilter >$${stem}.ochk; \ - ./newfilter <$${stem}.chk | tapdiffer -w "$${stem}: $${legend}" $${stem}.ochk; \ + ../advent <$${stem}.log >$${stem}.log-new; \ + ./newfilter <$${stem}.log-new | tapdiffer -w "$${stem}: $${legend}" $${stem}.ochk; \ fi; \ done; \ echo 1..$(words $(shell ls *.log))) | $(TAPFILTER) - @rm *.ochk advent430 adventure.data + @rm *.ochk rm *-new advent430 adventure.data # end From e49fb5f3673be6b0bf3c407499229b1f5eeacd04 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 1 Apr 2023 18:14:25 -0400 Subject: [PATCH 078/213] Close out oldcompare. At this revision all test logs either pass checkfile comparison against advent439 or have a NOCOMPARE comment explaining why they don't pass, turning into a TAP skip. 100% coverage. --- tests/Makefile | 6 +++++- tests/barehands.log | 1 + tests/cheatresume.log | 2 +- tests/cheatresume2.log | 2 +- tests/fail_hint_ogre.log | 1 + tests/flyback.log | 2 +- tests/goback.log | 1 + tests/oldstyle.log | 1 + tests/oysterbug.log | 2 +- tests/saveresume.1.log | 2 +- tests/saveresume.2.log | 2 +- tests/saveresume.3.log | 2 +- tests/savetamper.log | 2 +- tests/water_plant2.log | 1 + tests/woodshint.log | 1 + 15 files changed, 19 insertions(+), 9 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 1593b69..7e17443 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -163,6 +163,10 @@ oldcompare: $(SGAMES) fi; \ done; \ echo 1..$(words $(shell ls *.log))) | $(TAPFILTER) - @rm *.ochk rm *-new advent430 adventure.data + @rm *.ochk *-new advent430 adventure.data + +# List all NOMPARE tests. +residuals: + @grep -n NOCOMPARE *.log # end diff --git a/tests/barehands.log b/tests/barehands.log index 72fc3de..233c325 100644 --- a/tests/barehands.log +++ b/tests/barehands.log @@ -1,4 +1,5 @@ ## Get to dragon, refuse to use bare hands +#NOCOMPARE Fails due uninteresting difference in whitespace process. # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1635997320 diff --git a/tests/cheatresume.log b/tests/cheatresume.log index 13ed78d..4d0121c 100644 --- a/tests/cheatresume.log +++ b/tests/cheatresume.log @@ -1,5 +1,5 @@ ## Resume from absurd save file with numdie = -900 -#NOCOMPARE Can't compare to asvent430 die to version skew +#NOCOMPARE Can't compare to asvent430 due to version skew n resume cheat_numdie.adv diff --git a/tests/cheatresume2.log b/tests/cheatresume2.log index 2843862..6458654 100644 --- a/tests/cheatresume2.log +++ b/tests/cheatresume2.log @@ -1,6 +1,6 @@ ## Resume from absurd save file with numdie = -1000 # generating "off my scale" score threshold message -#NOCOMPARE Can't compare to asvent430 die to version skew +#NOCOMPARE Can't compare to asvent430 due to version skew n resume cheat_numdie1000.adv diff --git a/tests/fail_hint_ogre.log b/tests/fail_hint_ogre.log index c26ecbb..f75fd79 100644 --- a/tests/fail_hint_ogre.log +++ b/tests/fail_hint_ogre.log @@ -1,4 +1,5 @@ ## Qualify for ogre hint but fail due to dwarves dead (fuzzed) +#NOCOMPARE Fails due uninteresting difference in whitespace process. n seed 1838473132 in diff --git a/tests/flyback.log b/tests/flyback.log index 059054e..d0db54b 100644 --- a/tests/flyback.log +++ b/tests/flyback.log @@ -1,4 +1,4 @@ -## Test fix for issue #51: rug flying is broken +## Test fix for issue 51: rug flying is broken #NOCOMPARE Behavior differs due to a bug fix. n seed 1838473132 diff --git a/tests/goback.log b/tests/goback.log index 2915836..490ed7a 100644 --- a/tests/goback.log +++ b/tests/goback.log @@ -1,6 +1,7 @@ ## Test many nonlethal failure conditions # This variant elicits the prompt to go back for batteries # See comments in this log +#NOCOMPARE Relies on "waste" n seed 1838473132 in diff --git a/tests/oldstyle.log b/tests/oldstyle.log index a70456d..4711df0 100644 --- a/tests/oldstyle.log +++ b/tests/oldstyle.log @@ -1,5 +1,6 @@ ## Simple quit #options: -o +#NOCOMPARE Comment not interpreted by advent430 n i l diff --git a/tests/oysterbug.log b/tests/oysterbug.log index 07e15ff..0310c97 100644 --- a/tests/oysterbug.log +++ b/tests/oysterbug.log @@ -1,5 +1,5 @@ # Demonstrate fix of buggy response to unlocking oyster while carrying it. -#NOCOMPARE This fixes a bug in advent430 +#NOCOMPARE This fails due to a known bug in advent430 n seed 1838473132 in diff --git a/tests/saveresume.1.log b/tests/saveresume.1.log index ceaf6bb..77a20ce 100644 --- a/tests/saveresume.1.log +++ b/tests/saveresume.1.log @@ -1,5 +1,5 @@ ## Save right after starting -#NOCOMPARE Can't compare to asvent430 die to version skew +#NOCOMPARE Can't compare to asvent430 due to version skew n seed 1240742801 save diff --git a/tests/saveresume.2.log b/tests/saveresume.2.log index da629be..23dcc9e 100644 --- a/tests/saveresume.2.log +++ b/tests/saveresume.2.log @@ -1,5 +1,5 @@ ## Resume and then quit -#NOCOMPARE Can't compate to asvent430 die to version skew +#NOCOMPARE Can't compate to asvent430 due to version skew n in resume diff --git a/tests/saveresume.3.log b/tests/saveresume.3.log index f199c64..fd7be6f 100644 --- a/tests/saveresume.3.log +++ b/tests/saveresume.3.log @@ -1,6 +1,6 @@ ## Almost win, then save # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 -#NOCOMPARE seems to reveal a bug in advent430 +#NOCOMPARE Seems to reveal a bug in advent430's save function. n seed 1838473132 in diff --git a/tests/savetamper.log b/tests/savetamper.log index e6b763f..f86e977 100644 --- a/tests/savetamper.log +++ b/tests/savetamper.log @@ -1,5 +1,5 @@ ## Resume from artificial "corrupted" save -#NOCOMPARE Can't compare to asvent430 die to version skew +#NOCOMPARE Can't compare to asvent430 due to version skew n resume cheat_savetamper.adv diff --git a/tests/water_plant2.log b/tests/water_plant2.log index 16fa346..4f39d8f 100644 --- a/tests/water_plant2.log +++ b/tests/water_plant2.log @@ -1,4 +1,5 @@ ## Check that pour correctly switches among plant states (fuzzed) +#NOCOMPARE Behavior differs due to a parser bug fix. n seed 183847312 in diff --git a/tests/woodshint.log b/tests/woodshint.log index 4472b49..6052028 100644 --- a/tests/woodshint.log +++ b/tests/woodshint.log @@ -1,4 +1,5 @@ ## Test hinting logic - elicit forest hint +#NOCOMPARE Behavior differs due to a parser bug fix. # Also some tests of intransitive-verb cases n seed 2099333241 From 54927c33e548c58080232f43584bdd8cbcea068d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Andersson?= Date: Sat, 1 Apr 2023 10:39:21 +0200 Subject: [PATCH 079/213] Spelling fixes --- saveresume.c | 2 +- tests/Makefile | 10 +++++----- tests/coverage_dungeon.py | 4 ++-- tests/foobug.log | 4 ++-- tests/pitfall.log | 2 +- tests/saveresume.1.log | 2 +- tests/saveresume.2.log | 2 +- tests/savetamper.log | 2 +- tests/weirdbird.log | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/saveresume.c b/saveresume.c index 575b11f..dedb5bb 100644 --- a/saveresume.c +++ b/saveresume.c @@ -172,7 +172,7 @@ int restore(FILE* fp) bool is_valid(struct game_t valgame) { /* Save files can be roughly grouped into three groups: - * With valid, reacheable state, with valid, but unreachable + * With valid, reachable state, with valid, but unreachable * state and with invalid state. We check that state is * valid: no states are outside minimal or maximal value */ diff --git a/tests/Makefile b/tests/Makefile index 7e17443..7087e69 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,4 @@ -# Test-suite makefile for opeb-adventure +# Test-suite makefile for open-adventure # Use absolute path so tests that change working directory still use # scripts from parent directory. Note that using $PWD seems to fail @@ -92,8 +92,8 @@ scheck7: @./outcheck.sh "test -r with valid input" SCHECKS = scheck1 scheck2 scheck3 scheck4 scheck5 scheck6 scheck7 -# Don't run this from here, you'll get ctyptic warnings and no good result -# if the advent binary wasn't built with covrage flags. Do "make clean covetage" +# Don't run this from here, you'll get cryptic warnings and no good result +# if the advent binary wasn't built with coverage flags. Do "make clean coverage" # from the top-level directory. coverage: check lcov -t "advent" -o $(PARDIR)/advent.info -c -d $(PARDIR) --gcov-tool=$(GCOV) @@ -134,12 +134,12 @@ count: # does not remove them). # # The diff file produced has corrected spellings in it. That's what oldfilter -# is for, to massage out the original dpellings and avoid noise diffs. +# is for, to massage out the original spellings and avoid noise diffs. # Diffs in amount of whitespace and trailing whitespace are ignored # # A magic comment of NOCOMPARE in a log file excludes it from this comparison. # making it a skipped test in the TAP view. First use of this was to avoid a -# spurious mismatch on the news text. Other uses avoid spurios mismatches due +# spurious mismatch on the news text. Other uses avoid spurious mismatches due # to bug fixes. # # When adding more tests, bear in mind that any game that continues after a diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index e615239..c583ffb 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -99,7 +99,7 @@ def obj_coverage(objects, text, report): def loc_coverage(locations, text, report): # locations have a long and a short description, that each have to - # be checked seperately + # be checked separately for name, loc in locations: desc = loc["description"] if name not in report["messages"]: @@ -173,7 +173,7 @@ def actions_coverage(items, text, report): report["covered"] += 1 def coverage_report(db, check_file_contents): - # Create report for each catagory, including total items, number of items + # Create report for each category, including total items, number of items # covered, and a list of the covered messages report = {} for name in db.keys(): diff --git a/tests/foobug.log b/tests/foobug.log index 8ff35b8..8e3dc8f 100644 --- a/tests/foobug.log +++ b/tests/foobug.log @@ -1,5 +1,5 @@ -## Test interpersing commands amidst magic words -# Check for "Nothing happens." in game output indicatung sequence interrupt. +## Test interspersing commands amidst magic words +# Check for "Nothing happens." in game output indicating sequence interrupt. no seed 1318612053 e diff --git a/tests/pitfall.log b/tests/pitfall.log index 6c5adc7..6532713 100644 --- a/tests/pitfall.log +++ b/tests/pitfall.log @@ -1,5 +1,5 @@ ## Death by pitfall -# Die 3 times so we can cover all the opituary messages +# Die 3 times so we can cover all the obituary messages n seed 780351908 enter building diff --git a/tests/saveresume.1.log b/tests/saveresume.1.log index 77a20ce..45945ce 100644 --- a/tests/saveresume.1.log +++ b/tests/saveresume.1.log @@ -1,5 +1,5 @@ ## Save right after starting -#NOCOMPARE Can't compare to asvent430 due to version skew +#NOCOMPARE Can't compare to advent430 due to version skew n seed 1240742801 save diff --git a/tests/saveresume.2.log b/tests/saveresume.2.log index 23dcc9e..71db28c 100644 --- a/tests/saveresume.2.log +++ b/tests/saveresume.2.log @@ -1,5 +1,5 @@ ## Resume and then quit -#NOCOMPARE Can't compate to asvent430 due to version skew +#NOCOMPARE Can't compare to advent430 due to version skew n in resume diff --git a/tests/savetamper.log b/tests/savetamper.log index f86e977..0396e99 100644 --- a/tests/savetamper.log +++ b/tests/savetamper.log @@ -1,5 +1,5 @@ ## Resume from artificial "corrupted" save -#NOCOMPARE Can't compare to asvent430 due to version skew +#NOCOMPARE Can't compare to advent430 due to version skew n resume cheat_savetamper.adv diff --git a/tests/weirdbird.log b/tests/weirdbird.log index 78ae7de..37f4a36 100644 --- a/tests/weirdbird.log +++ b/tests/weirdbird.log @@ -36,7 +36,7 @@ take bird get rod wave rod attack bird -# Also, test grare as a motion verb. +# Also, test grate as a motion verb. grate up n From 40a4acb8680e86c503cac1f9f08d23b88f68cd68 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 2 Apr 2023 07:41:49 -0400 Subject: [PATCH 080/213] Comment typo fixes. --- tests/cheatresume.log | 2 +- tests/cheatresume2.log | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cheatresume.log b/tests/cheatresume.log index 4d0121c..96c442a 100644 --- a/tests/cheatresume.log +++ b/tests/cheatresume.log @@ -1,5 +1,5 @@ ## Resume from absurd save file with numdie = -900 -#NOCOMPARE Can't compare to asvent430 due to version skew +#NOCOMPARE Can't compare to advent430 due to version skew n resume cheat_numdie.adv diff --git a/tests/cheatresume2.log b/tests/cheatresume2.log index 6458654..f317d82 100644 --- a/tests/cheatresume2.log +++ b/tests/cheatresume2.log @@ -1,6 +1,6 @@ ## Resume from absurd save file with numdie = -1000 # generating "off my scale" score threshold message -#NOCOMPARE Can't compare to asvent430 due to version skew +#NOCOMPARE Can't compare to advent430 due to version skew n resume cheat_numdie1000.adv From 7dc3482c5b4ab8e0bc44b3c553fdcd4e527b3736 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 2 Apr 2023 10:23:07 -0400 Subject: [PATCH 081/213] Start building a better test load for micwords. --- tests/foofum.log | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/foofum.log b/tests/foofum.log index f713fc7..801884a 100644 --- a/tests/foofum.log +++ b/tests/foofum.log @@ -1,4 +1,37 @@ ## Test processing of fee fie foe fum +# +# How thry're supposed to work: +# +# 1. The word "fum", from the famous phrase, "fee fie foe fum" is treated +# as a red herring for the player and is handled differently in the +# logic of the game +# +# 2. Each word of the magic phrase and the word "fum" can be preceded by +# the word "say", so "say fee", "say fie", etc. will work, as +# well. For "say fum", 'Okay, "FUM"' should NOT be the response, +# similar to what is seen when other non-magic words are uttered with +# "say" +# +# 3. The sequence is triggered by the first word "fee" only. If any of +# the other words of the phrase or "fum" are said before "fee", +# "nothing happens" +# +# 4. The phrase "fee fie foe foo" must be entered as four separate +# commands, in order, without interruption. A move, like "east" or a +# non-move, like "look", are both considered interruptions +# +# 5. Once the sequence has begun, if any of the words of the phrase, +# including a second "fee", are said out of order, or "fum" is spoken at +# all during the sequence, the player is admonished for not being able +# to read. The assumption here is the player at some point in the time +# had previously read the phrase, but then messes up the order and/or +# thinks "fum" was a part of the phrase when they attempt to speak +# it. The player then must say "fee" again to restart the sequence. And +# to clarify, a second "fee" in the sequence triggers the admonishment, +# it does not restart the sequence +# +# Now that we're at the Giant's Room, actual testing can start +# n seed 1838473132 in @@ -302,6 +335,7 @@ w d climb w +# We're at Giant Room fee fie foe From 34516ecf395123e8877ea79552e4833ca0e03c2e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 2 Apr 2023 10:42:10 -0400 Subject: [PATCH 082/213] Test name change, --- tests/magicwords.chk | 1837 ++++++++++++++++++++++++++++++++++++++++++ tests/magicwords.log | 344 ++++++++ 2 files changed, 2181 insertions(+) create mode 100644 tests/magicwords.chk create mode 100644 tests/magicwords.log diff --git a/tests/magicwords.chk b/tests/magicwords.chk new file mode 100644 index 0000000..6424ad7 --- /dev/null +++ b/tests/magicwords.chk @@ -0,0 +1,1837 @@ + +Welcome to Adventure!! Would you like instructions? + +> n + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed 1838473132 + +Seed set to 1838473132 + +You're in front of building. + +> in + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> take lamp + +OK + +> xyzzy + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> e + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> take cage + +OK + +> w + +You're in debris room. + +> w + +You are in an awkward sloping east/west canyon. + +> w + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> drop rod + +OK + +> take bird + +OK + +> take rod + +OK + +> w + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> free bird + +OK + +> wave rod + +The bird flies about agitatedly for a moment, then disappears through +the crack. It reappears shortly, carrying in its beak a jade +necklace, which it drops at your feet. + +> take necklace + +OK + +> drop rod + +OK + +> take bird + +OK + +> take rod + +OK + +> d + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> d + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A huge green fierce snake bars the way! + +> free bird + +The little bird attacks the green snake, and in an astounding flurry +drives the snake away. + +> drop rod + +OK + +> drop cage + +OK + +> take cage + +OK + +> take bird + +OK + +> w + +You are in the west side chamber of the Hall of the Mountain King. +A passage continues west and up here. + +There are many coins here! + +> take coins + +OK + +> e + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> s + +You are in the south side chamber. + +There is precious jewelry here! + +> take jewelry + +OK + +> n + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> up + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> s + +This is a low room with a crude note on the wall. The note says, +"You won't get it up the steps". + +There is a large sparkling nugget of gold here! + +> take gold + +OK + +> n + +You're in Hall of Mists. + +> d + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> n + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There are bars of silver here! + +> n + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> plugh + +>>Foof!<< + +You're inside building. + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> extinguish lamp + +Your lamp is now off. + +> drop coins + +OK + +> drop jewelry + +OK + +> drop necklace + +OK + +> drop gold + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +> s + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> take silver + +OK + +> s + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> sw + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You are in a secret canyon which here runs e/w. It crosses over a +very tight canyon 15 feet below. If you go down you may not be able +to get back up. + +There is a little axe here. + +> take axe + +OK + +> w + +You are in a secret canyon which exits to the north and east. + +A huge green fierce dragon bars the way! + +The dragon is sprawled out on a Persian rug!! + +> kill dragon + +With what? Your bare hands? + +> yes + +Congratulations! You have just vanquished a dragon with your bare +hands! (Unbelievable, isn't it?) + +You are in a secret canyon which exits to the north and east. + +There is a Persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. + +> drink blood + +Your head buzzes strangely for a moment. + +> take rug + +OK + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A three foot black rod with a rusty star on an end lies nearby. + +> up + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> d + +There is a threatening little dwarf in the room with you! + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> n + +There is a threatening little dwarf in the room with you! + +You're in n/s passage above e/w passage. + +> n + +There is a threatening little dwarf in the room with you! + +You're at "Y2". + +A hollow voice says "PLUGH". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> inven + +You are currently holding the following: +Brass lantern +Wicker cage +Little bird in cage +Dwarf's axe +Bars of silver +Persian rug + +> drop rug + +OK + +> drop silver + +OK + +> out + +You're in front of building. + +> s + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> w + +You are wandering aimlessly through the forest. + +> n + +You are wandering aimlessly through the forest. + +Your keen eye spots a severed leporine appendage lying on the ground. + +> take appendage + +OK + +> free bird + +OK + +> drop cage + +OK + +> listen + +The bird is singing to you in gratitude for your having returned it to +its home. In return, it informs you of a magic word which it thinks +you may find useful somewhere near the Hall of Mists. The magic word +changes frequently, but for now the bird believes it is "H'CFL". You +thank the bird for this information, and it flies off into the forest. + +> s + +You are wandering aimlessly through the forest. + +> s + +You're in valley. + +> n + +You're in front of building. + +> in + +You're inside building. + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> take water + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +> plover + +>>Foof!<< + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +There is an emerald here the size of a plover's egg! + +> ne + +You're in the dark-room. A corridor leading south is the only exit. + +A massive stone tablet embedded in the wall reads: +"Congratulations on bringing light into the dark-room!" + +There is a platinum pyramid here, 8 inches on a side! + +> take pyramid + +OK + +> s + +You're in Plover Room. + +There is an emerald here the size of a plover's egg! + +> plover + +>>Foof!<< + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You're in n/s passage above e/w passage. + +> s + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> up + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +A crystal bridge now spans the fissure. + +> drop rod + +OK + +> west + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> take diamonds + +OK + +> w + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are at the west end of the Hall of Mists. A low wide crawl +continues west and another goes north. To the south is a little +passage 6 feet off the floor. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the east end of a very long hall apparently without side +chambers. To the east a low wide crawl slants up. To the north a +round two foot hole slants down. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of a very long featureless hall. The hall +joins up with a narrow north/south passage. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all different. + +> sw + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisty passages, all different. + +> se + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisting passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +Dead end + +There is a massive and somewhat battered vending machine here. The +instructions on it read: "Drop coins here to receive fresh batteries." + +> kill machine + +As you strike the vending machine, it pivots backward along with a +section of wall, revealing a dark passage leading south. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a long, rough-hewn, north/south corridor. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a large chamber with passages to the west and north. + +A formidable ogre bars the northern exit. + +> kill ogre + +The ogre, who despite his bulk is quite agile, easily dodges your +attack. He seems almost amused by your puny effort. + +One sharp nasty knife is thrown at you! + +The ogre, distracted by your rush, is struck by the knife. With a +blood-curdling yell he turns and bounds after the dwarf, who flees +in panic. You are left alone in the room. + +> n + +You are in the ogre's storeroom. The only exit is to the south. + +There is an enormous ruby here! + +> take ruby + +OK + +> s + +You are in a large chamber with passages to the west and north. + +> w + +You are in a long, rough-hewn, north/south corridor. + +> n + +Dead end + +There is a massive vending machine here, swung back to reveal a +southward passage. + +> n + +You are in a little maze of twisting passages, all different. + +> n + +You are in a little maze of twisty passages, all different. + +> nw + +You are in a maze of twisty little passages, all different. + +> d + +You're at west end of long hall. + +> e + +You're at east end of long hall. + +> e + +You're at west end of Hall of Mists. + +> e + +You're on west bank of fissure. + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A three foot black rod with a rusty star on an end lies nearby. + +A crystal bridge spans the fissure. + +> e + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> throw axe + +You killed a little dwarf. The body vanishes in a cloud of greasy +black smoke. + +You're in Hall of Mists. + +There is a little axe here. + +Rough stone steps lead up the dome. + +> take axe + +OK + +> n + +You're in Hall of Mt King. + +> n + +You're in n/s passage above e/w passage. + +> n + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +> drop ruby + +OK + +> drop diamonds + +OK + +> drop pyramid + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> s + +You're in Hall of Mt King. + +> u + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> n + +You are in the Hall of the Mountain King, with passages off in all +directions. + +> n + +You're in n/s passage above e/w passage. + +> d + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> bedquilt + +There is a threatening little dwarf in the room with you! + +You are in Bedquilt, a long east/west passage with holes everywhere. +To explore at random select north, south, up, or down. + +> throw axe + +You killed a little dwarf. + +You're in Bedquilt. + +There is a little axe here. + +> take axe + +OK + +> slab + +You are in a large low circular chamber whose floor is an immense slab +fallen from the ceiling (Slab Room). East and west there once were +large passages, but they are now filled with boulders. Low small +passages go north and south, and the south one quickly bends west +around the boulders. + +> s + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a tiny little plant in the pit, murmuring "water, water, ..." + +> water plant + +The plant spurts into furious growth for a few seconds. + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> u + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> w + +You're in Slab Room. + +> u + +You are in a secret n/s canyon above a large room. + +> reservoir + +You are at the edge of a large underground reservoir. An opaque cloud +of white mist fills the room and rises rapidly upward. The lake is +fed by a stream, which tumbles out of a hole in the wall about 10 feet +overhead and splashes noisily into the water somewhere within the +mist. There is a passage going back toward the south. + +> H'CFL + +The waters have parted to form a narrow path across the reservoir. + +> n + +You are walking across the bottom of the reservoir. Walls of water +rear up on either side. The roar of the water cascading past is +nearly deafening, and the mist is so thick you can barely see. + +> n + +You are at the northern edge of the reservoir. A northwest passage +leads sharply up from here. + +The waters have parted to form a narrow path across the reservoir. + +> nw + +You are scrambling along a treacherously steep, rocky passage. + +> u + +You are on a very steep incline, which widens at it goes upward. + +> u + +You are at the base of a nearly vertical cliff. There are some +slim footholds which would enable you to climb up, but it looks +extremely dangerous. Here at the base of the cliff lie the remains +of several earlier adventurers who apparently failed to make it. + +> u + +You are climbing along a nearly vertical cliff. + +> u + +Just as you reach the top, your foot slips on a loose rock and you +make one last desperate grab. Your luck holds, as does your grip. +With an enormous heave, you lift yourself to the ledge above. + +You are on a small ledge at the top of a nearly vertical cliff. +There is a low crawl leading off to the northeast. + +> ne + +You have reached a dead end. + +There is a richly-carved ebony statuette here! + +> take ebony + +OK + +> sw + +You're at top of cliff. + +> d + +You are climbing along a nearly vertical cliff. + +> d + +You're at base of cliff. + +> d + +You are on a very steep incline, which widens at it goes upward. + +> d + +You are scrambling along a treacherously steep, rocky passage. + +> d + +You're north of reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> take water + +Your bottle is now full of water. + +> s + +You're at bottom of reservoir. + +> s + +You're at reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You are in a north/south canyon about 25 feet across. The floor is +covered by white mist seeping in from the north. The walls extend +upward for well over 100 feet. Suspended from some unseen point far +above you, an enormous two-sided mirror is hanging parallel to and +midway between the canyon walls. (The mirror is obviously provided +for the use of the dwarves who, as you know, are extremely vain.) A +small window can be seen in either wall, some fifty feet up. + +> s + +You are in a secret n/s canyon above a large room. + +> d + +You're in Slab Room. + +> s + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> water plant + +The plant grows explosively, almost filling the bottom of the pit. + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> u + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> drop appendage + +OK + +> e + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You are at the bottom of the eastern pit in the Twopit Room. There is +a small pool of oil in one corner of the pit. + +> get oil + +Your bottle is now full of oil. + +> + +> u + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You are in a long, narrow corridor stretching out of sight to the +west. At the eastern end is a hole through which you can see a +profusion of leaves. + +> w + +You are in the Giant Room. The ceiling here is too high up for your +lamp to show it. Cavernous passages lead east, north, and south. On +the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. + +There is a large nest here, full of golden eggs! + +> n + +You are at one end of an immense north/south passage. + +The way north is barred by a massive, rusty, iron door. + +> oil door + +The oil has freed up the hinges so that the door will now move, +although it requires some effort. + +> drop bottle + +OK + +> n + +You are in a magnificent cavern with a rushing stream, which cascades +over a sparkling waterfall into a roaring whirlpool which disappears +through a hole in the floor. Passages exit to the south and west. + +There is a jewel-encrusted trident here! + +> take trident + +OK + +> w + +You are at the top of a steep incline above a large room. You could +climb down here, but you would not be able to climb up. There is a +passage leading back to the north. + +> d + +You are in a large low room. Crawls lead north, se, and sw. + +> se + +This is the Oriental Room. Ancient oriental cave drawings cover the +walls. A gently sloping passage leads upward to the north, another +passage leads se, and a hands and knees crawl leads west. + +There is a delicate, precious, ming vase here! + +> n + +You are following a wide path around the outer edge of a large cavern. +Far below, through a heavy white mist, strange splashing noises can be +heard. The mist rises up through a fissure in the ceiling. The path +exits to the south and west. + +> w + +You are in an alcove. A small nw path seems to widen after a short +distance. An extremely tight tunnel leads east. It looks like a very +tight squeeze. An eerie light can be seen at the other end. + +> drop trident + +OK + +> drop ebony + +OK + +> drop axe + +OK + +> drop lantern + +OK + +> e + +You're in Plover Room. + +There is an emerald here the size of a plover's egg! + +> take emerald + +OK + +> w + +You're in alcove. + +There is a lamp shining nearby. + +There is a little axe here. + +There is a richly-carved ebony statuette here! + +There is a jewel-encrusted trident here! + +> take lamp + +OK + +> take axe + +OK + +> take ebony + +OK + +> take trident + +OK + +> nw + +You're in misty cavern. + +> s + +You're in Oriental Room. + +There is a delicate, precious, ming vase here! + +> take vase + +OK + +> se + +There is a threatening little dwarf in the room with you! + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +> throw axe + +You killed a little dwarf. + +You're in Swiss Cheese Room. + +There is a little axe here. + +> take axe + +OK + +> e + +You are in the Soft Room. The walls are covered with heavy curtains, +the floor with a thick pile carpet. Moss covers the ceiling. + +A small velvet pillow lies on the floor. + +> take pillow + +OK + +> w + +You're in Swiss Cheese Room. + +> drop axe + +OK + +> ne + +You're in Bedquilt. + +> e + +You are at a complex junction. A low hands and knees passage from the +north joins a higher crawl from the east to make a walking passage +going west. There is also a large room above. The air is damp here. + +> n + +You're in a large room carved out of sedimentary rock. The floor and +walls are littered with bits of shells embedded in the stone. A +shallow passage proceeds downward, and a somewhat steeper one leads +up. A low hands and knees passage enters from the south. + +There is an enormous clam here with its shell tightly closed. + +> open clam + +A glistening pearl falls out of the clam and rolls away. Goodness, +this must really be an oyster. (I never was very good at identifying +bivalves.) Whatever it is, it has now snapped shut again. + +> s + +You're at complex junction. + +> u + +You are in a large room full of dusty rocks. There is a big hole in +the floor. There are cracks everywhere, and a passage leading east. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +You're at "Y2". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You are inside a building, a well house for a large spring. + +There is a platinum pyramid here, 8 inches on a side! + +There are diamonds here! + +There is an enormous ruby here! + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +> drop pillow + +OK + +> drop vase + +The vase is now resting, delicately, on a velvet pillow. + +> drop trident + +OK + +> drop emerald + +OK + +> drop ebony + +OK + +> take keys + +OK + +> take food + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +A hollow voice says "PLUGH". + +> on + +Your lamp is now on. + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You're in n/s passage above e/w passage. + +> d + +You're in dirty passage. + +> w + +You're in dusty rock room. + +> d + +You're at complex junction. + +> n + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> d + +You are in a long sloping corridor with ragged sharp walls. + +> d + +You are in a cul-de-sac about eight feet across. + +Off to one side lies a glistening pearl! + +> take pearl + +OK + +> u + +You are in a long sloping corridor with ragged sharp walls. + +> u + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> s + +You're at complex junction. + +> w + +You're in Bedquilt. + +> w + +You're in Swiss Cheese Room. + +There is a little axe here. + +> w + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You're in narrow corridor. + +> w + +You're in Giant Room. + +There is a large nest here, full of golden eggs! + +> get eggs + +OK + +> n + +You are at one end of an immense north/south passage. + +There is an empty bottle here. + +The way north leads through a massive, rusty, iron door. + +> take bottle + +OK + +> n + +You're in cavern with waterfall. + +> w + +You're at steep incline above large room. + +> d + +You're in large low room. + +> sw + +You are in a long winding corridor sloping out of sight in both +directions. + +> u + +You are on one side of a large, deep chasm. A heavy white mist rising +up from below obscures all view of the far side. A sw path leads away +from the chasm into a winding corridor. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> toss eggs + +The troll catches your treasure and scurries away out of sight. + +> ne + +You are on the far side of the chasm. A ne path leads away from the +chasm on this side. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> ne + +You're in a long east/west corridor. A faint rumbling noise can be +heard in the distance. + +> barren + +You are standing at the entrance to a large, barren room. A notice +above the entrance reads: "Caution! Bear in room!" + +> in + +You are inside a barren room. The center of the room is completely +empty except for some dust. Marks in the dust lead away toward the +far end of the room. The only exit is the way you came in. + +There is a ferocious cave bear eyeing you from the far end of the room! + +The bear is locked to the wall with a golden chain! + +> feed bear + +The bear eagerly wolfs down your food, after which he seems to calm +down considerably and even becomes rather friendly. + +> unlock chain + +The chain is now unlocked. + +> take chain + +OK + +> take bear + +OK + +> fork + +You are being followed by a very large, tame bear. + +The path forks here. The left fork leads northeast. A dull rumbling +seems to get louder in that direction. The right fork leads southeast +down a gentle slope. The main corridor enters from the west. + +> ne + +You are being followed by a very large, tame bear. + +The walls are quite warm here. From the north can be heard a steady +roar, so loud that the entire cave seems to be trembling. Another +passage leads south, and a low crawl goes east. + +> e + +You are being followed by a very large, tame bear. + +You are in a small chamber filled with large boulders. The walls are +very warm, causing the air in the room to be almost stifling from the +heat. The only exit is a crawl heading west, through which is coming +a low rumbling. + +There are rare spices here! + +> take spices + +OK + +> drop keys + +OK + +> fork + +You are being followed by a very large, tame bear. + +You're at fork in path. + +> w + +You are being followed by a very large, tame bear. + +You're in corridor. + +> w + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +The troll steps out from beneath the bridge and blocks your way. + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> free bear + +The bear lumbers toward the troll, who lets out a startled shriek and +scurries away. The bear soon gives up the pursuit and wanders back. + +> inven + +You are currently holding the following: +Brass lantern +Small bottle +Glistening pearl +Rare spices +Golden chain + +> sw + +You're on sw side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +You're in sloping corridor. + +> d + +You're in large low room. + +> se + +You're in Oriental Room. + +> se + +You're in Swiss Cheese Room. + +There is a little axe here. + +> w + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in east pit. + +> get oil + +Your bottle is now full of oil. + +> up + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> e + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +There is a little axe here. + +> take axe + +OK + +> w + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You're in narrow corridor. + +> w + +You're in Giant Room. + +> fee + +OK + +> fie + +OK + +> foe + +OK + +> fum + +What's the matter, can't you read? Now you'd best start over. + +> quit + +Do you really want to quit now? + +> yes + +OK + +You scored 253 out of a possible 430, using 304 turns. + +You have reached "Junior Master" status. + +To achieve the next higher rating, you need 68 more points. diff --git a/tests/magicwords.log b/tests/magicwords.log new file mode 100644 index 0000000..801884a --- /dev/null +++ b/tests/magicwords.log @@ -0,0 +1,344 @@ +## Test processing of fee fie foe fum +# +# How thry're supposed to work: +# +# 1. The word "fum", from the famous phrase, "fee fie foe fum" is treated +# as a red herring for the player and is handled differently in the +# logic of the game +# +# 2. Each word of the magic phrase and the word "fum" can be preceded by +# the word "say", so "say fee", "say fie", etc. will work, as +# well. For "say fum", 'Okay, "FUM"' should NOT be the response, +# similar to what is seen when other non-magic words are uttered with +# "say" +# +# 3. The sequence is triggered by the first word "fee" only. If any of +# the other words of the phrase or "fum" are said before "fee", +# "nothing happens" +# +# 4. The phrase "fee fie foe foo" must be entered as four separate +# commands, in order, without interruption. A move, like "east" or a +# non-move, like "look", are both considered interruptions +# +# 5. Once the sequence has begun, if any of the words of the phrase, +# including a second "fee", are said out of order, or "fum" is spoken at +# all during the sequence, the player is admonished for not being able +# to read. The assumption here is the player at some point in the time +# had previously read the phrase, but then messes up the order and/or +# thinks "fum" was a part of the phrase when they attempt to speak +# it. The player then must say "fee" again to restart the sequence. And +# to clarify, a second "fee" in the sequence triggers the admonishment, +# it does not restart the sequence +# +# Now that we're at the Giant's Room, actual testing can start +# +n +seed 1838473132 +in +take lamp +xyzzy +on +take rod +e +take cage +w +w +w +drop rod +take bird +take rod +w +free bird +wave rod +take necklace +drop rod +take bird +take rod +d +d +free bird +drop rod +drop cage +take cage +take bird +w +take coins +e +s +take jewelry +n +up +s +take gold +n +d +n +n +plugh +extinguish lamp +drop coins +drop jewelry +drop necklace +drop gold +plugh +on +s +take silver +s +sw +take axe +w +kill dragon +yes +drink blood +take rug +e +e +up +d +n +n +off +plugh +inven +drop rug +drop silver +out +s +w +n +take appendage +free bird +drop cage +listen +s +s +n +in +take water +plugh +on +plover +ne +take pyramid +s +plover +s +s +take rod +up +w +wave rod +drop rod +west +take diamonds +w +w +w +s +sw +se +s +kill machine +s +s +kill ogre +n +take ruby +s +w +n +n +n +nw +d +e +e +e +e +e +throw axe +take axe +n +n +n +off +plugh +drop ruby +drop diamonds +drop pyramid +plugh +on +s +s +u +n +n +d +bedquilt +throw axe +take axe +slab +s +d +water plant +u +w +u +reservoir +H'CFL +n +n +nw +u +u +u +u +ne +take ebony +sw +d +d +d +d +d +take water +s +s +s +s +d +s +d +water plant +u +drop appendage +e +d +get oil + +u +w +d +climb +w +n +oil door +drop bottle +n +take trident +w +d +se +n +w +drop trident +drop ebony +drop axe +drop lantern +e +take emerald +w +take lamp +take axe +take ebony +take trident +nw +s +take vase +se +throw axe +take axe +e +take pillow +w +drop axe +ne +e +n +open clam +s +u +e +u +n +off +plugh +drop pillow +drop vase +drop trident +drop emerald +drop ebony +take keys +take food +plugh +on +s +d +w +d +n +d +d +take pearl +u +u +s +w +w +w +w +d +climb +w +get eggs +n +take bottle +n +w +d +sw +u +toss eggs +ne +ne +barren +in +feed bear +unlock chain +take chain +take bear +fork +ne +e +take spices +drop keys +fork +w +w +sw +free bear +inven +sw +sw +d +se +se +w +d +get oil +up +e +take axe +w +w +d +climb +w +# We're at Giant Room +fee +fie +foe +fum +quit +yes From 9c6219a27d7967c4eea64702c9c0366c420c8e4c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 2 Apr 2023 11:54:37 -0400 Subject: [PATCH 083/213] The oldcompare production no longer requires savefiles. --- tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index 7087e69..8076802 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -149,7 +149,7 @@ count: # The *.chk files need not be up-to-date for this to work. # TAPFILTER=tapview -oldcompare: $(SGAMES) +oldcompare: @if [ -f ../advent430 ]; then cp ../advent430 ../adventure.data .; else echo "advent430 nonexistent"; exit 1; fi @-(for x in *.log; do \ stem=$${x%.log}; \ From d9ddf4d80500271c1d6673648e8df2ea7968e897 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 2 Apr 2023 16:03:42 -0400 Subject: [PATCH 084/213] Consolidate all magicwords tests into one file. 100% coverage. --- tests/Makefile | 4 +- tests/foobug.chk | 1702 -------------------------------------- tests/foobug.log | 296 ------- tests/foofum.chk | 1837 ------------------------------------------ tests/foofum.log | 344 -------- tests/illformed.chk | 18 +- tests/illformed.log | 5 - tests/illformed2.chk | 10 +- tests/illformed2.log | 1 - tests/isofoo.chk | 19 - tests/isofoo.log | 3 - tests/magicwords.chk | 67 +- tests/magicwords.log | 25 +- tests/multifile.chk | 38 +- 14 files changed, 115 insertions(+), 4254 deletions(-) delete mode 100644 tests/foobug.chk delete mode 100644 tests/foobug.log delete mode 100644 tests/foofum.chk delete mode 100644 tests/foofum.log delete mode 100644 tests/isofoo.chk delete mode 100644 tests/isofoo.log diff --git a/tests/Makefile b/tests/Makefile index 8076802..2f547a0 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -108,7 +108,7 @@ buildchecks: savegames OPTS=`sed -n /#options:/s///p <$${file}.log`; \ advent $$OPTS <$${file}.log >$${file}.chk 2>&1 || exit 1; \ done; \ - echo "inven" | advent isofoo.log /dev/stdin >multifile.chk; \ + echo "inven" | advent issue36.log /dev/stdin >multifile.chk; \ rm -f scratch.tmp RUN_TARGETS=$(TESTLOADS:%=run-regress-%) @@ -118,7 +118,7 @@ $(RUN_TARGETS): run-regress-%: %.log $(advent) $$OPTS <$< | tapdiffer "$<: $${legend}" "$${test}.chk") multifile-regress: - @(echo "inven" | advent isofoo.log /dev/stdin) | tapdiffer "multifile: multiple-file test" multifile.chk + @(echo "inven" | advent issue36.log /dev/stdin) | tapdiffer "multifile: multiple-file test" multifile.chk TEST_TARGETS = $(SGAMES) $(SCHECKS) $(RUN_TARGETS) multifile-regress diff --git a/tests/foobug.chk b/tests/foobug.chk deleted file mode 100644 index c121eb8..0000000 --- a/tests/foobug.chk +++ /dev/null @@ -1,1702 +0,0 @@ - -Welcome to Adventure!! Would you like instructions? - -> no - -You are standing at the end of a road before a small brick building. -Around you is a forest. A small stream flows out of the building and -down a gully. - -> seed 1318612053 - -Seed set to 1318612053 - -You're in front of building. - -> e - -You are inside a building, a well house for a large spring. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -There is food here. - -There is a bottle of water here. - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> plove - ->>Foof!<< - -You're in a small chamber lit by an eerie green light. An extremely -narrow tunnel exits to the west. A dark corridor leads ne. - -There is an emerald here the size of a plover's egg! - -> get emerald - -OK - -> w - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> drop emerald - -OK - -> e - -You're in Plover Room. - -> ne - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> get pyramid - -OK - -> s - -You're in Plover Room. - -> plove - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> plugh - ->>Foof!<< - -You're inside building. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -There is food here. - -There is a bottle of water here. - -> drop pyramid - -OK - -> get lamp - -OK - -> get water - -OK - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You are in a large room, with a passage to the south, a passage to the -west, and a wall of broken rock to the east. There is a large "Y2" on -a rock in the room's center. - -A hollow voice says "PLUGH". - -> s - -You are in a low n/s passage at a hole in the floor. The hole goes -down to an e/w passage. - -There are bars of silver here! - -> d - -You are in a dirty broken passage. To the east is a crawl. To the -west is a large passage. Above you is a hole to another passage. - -> bedquilt - -You are in Bedquilt, a long east/west passage with holes everywhere. -To explore at random select north, south, up, or down. - -> w - -You are in a room whose walls resemble Swiss cheese. Obvious passages -go west, east, ne, and nw. Part of the room is occupied by a large -bedrock block. - -> e - -You are in the Soft Room. The walls are covered with heavy curtains, -the floor with a thick pile carpet. Moss covers the ceiling. - -A small velvet pillow lies on the floor. - -> take pillow - -OK - -> w - -You're in Swiss Cheese Room. - -> oriental - -This is the Oriental Room. Ancient oriental cave drawings cover the -walls. A gently sloping passage leads upward to the north, another -passage leads se, and a hands and knees crawl leads west. - -There is a delicate, precious, ming vase here! - -> take vase - -OK - -> n - -You are following a wide path around the outer edge of a large cavern. -Far below, through a heavy white mist, strange splashing noises can be -heard. The mist rises up through a fissure in the ceiling. The path -exits to the south and west. - -> w - -You are in an alcove. A small nw path seems to widen after a short -distance. An extremely tight tunnel leads east. It looks like a very -tight squeeze. An eerie light can be seen at the other end. - -There is an emerald here the size of a plover's egg! - -> take emerald - -OK - -> nw - -You're in misty cavern. - -> s - -You're in Oriental Room. - -> se - -You're in Swiss Cheese Room. - -> w - -You are at the east end of the Twopit Room. The floor here is -littered with thin rock slabs, which make it easy to descend the pits. -There is a path here bypassing the pits to connect passages from east -and west. There are holes all over, but the only big one is on the -wall directly over the west pit where you can't get to it. - -> w - -You are at the west end of the Twopit Room. There is a large hole in -the wall above the pit at this end of the room. - -> d - -You are at the bottom of the western pit in the Twopit Room. There is -a large hole in the wall about 25 feet above you. - -There is a tiny little plant in the pit, murmuring "water, water, ..." - -> water plant - -The plant spurts into furious growth for a few seconds. - -You're in west pit. - -There is a 12-foot-tall beanstalk stretching up out of the pit, -bellowing "WATER!! WATER!!" - -> u - -You're at west end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> e - -You're at east end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> d - -You are at the bottom of the eastern pit in the Twopit Room. There is -a small pool of oil in one corner of the pit. - -> fill bottle - -Your bottle is now full of oil. - -> u - -You're at east end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> e - -You're in Swiss Cheese Room. - -> ne - -You're in Bedquilt. - -> e - -You are at a complex junction. A low hands and knees passage from the -north joins a higher crawl from the east to make a walking passage -going west. There is also a large room above. The air is damp here. - -> u - -You are in a large room full of dusty rocks. There is a big hole in -the floor. There are cracks everywhere, and a passage leading east. - -> e - -You're in dirty passage. - -> u - -You're in n/s passage above e/w passage. - -There are bars of silver here! - -> n - -A little dwarf just walked around a corner, saw you, threw a little -axe at you which missed, cursed, and ran away. - -You're at "Y2". - -There is a little axe here. - -> plugh - ->>Foof!<< - -You're inside building. - -There is a platinum pyramid here, 8 inches on a side! - -There are some keys on the ground here. - -There is food here. - -> drop pillow - -OK - -> drop vase - -The vase is now resting, delicately, on a velvet pillow. - -> drop bottle - -OK - -> drop emerald - -OK - -> xyzzy - ->>Foof!<< - -You are in a debris room filled with stuff washed in from the surface. -A low wide passage with cobbles becomes plugged with mud and debris -here, but an awkward canyon leads upward and west. In the mud someone -has scrawled, "MAGIC WORD XYZZY". - -A three foot black rod with a rusty star on an end lies nearby. - -> take rod - -OK - -> e - -You are crawling over cobbles in a low passage. There is a dim light -at the east end of the passage. - -There is a small wicker cage discarded nearby. - -> take cage - -OK - -> pit - -At your feet is a small pit breathing traces of white mist. An east -passage ends here except for a small crack leading on. - -Rough stone steps lead down the pit. - -> drop rod - -OK - -> e - -You are in a splendid chamber thirty feet high. The walls are frozen -rivers of orange stone. An awkward canyon and a good passage exit -from east and west sides of the chamber. - -A cheerful little bird is sitting here singing. - -> take bird - -OK - -> w - -You're at top of small pit. - -A three foot black rod with a rusty star on an end lies nearby. - -Rough stone steps lead down the pit. - -> drop bird - -OK - -> take rod - -OK - -> wave rod - -The bird flies about agitatedly for a moment, then disappears through -the crack. It reappears shortly, carrying in its beak a jade -necklace, which it drops at your feet. - -> take necklace - -OK - -> drop rod - -OK - -> take bird - -OK - -> d - -You are at one end of a vast hall stretching forward out of sight to -the west. There are openings to either side. Nearby, a wide stone -staircase leads downward. The hall is filled with wisps of white mist -swaying to and fro almost as if alive. A cold wind blows up the -staircase. There is a passage at the top of a dome behind you. - -Rough stone steps lead up the dome. - -> s - -This is a low room with a crude note on the wall. The note says, -"You won't get it up the steps". - -There is a large sparkling nugget of gold here! - -> take nugget - -OK - -> n - -You're in Hall of Mists. - -> n - -You are in the Hall of the Mountain King, with passages off in all -directions. - -A huge green fierce snake bars the way! - -> drop bird - -The little bird attacks the green snake, and in an astounding flurry -drives the snake away. - -> take bird - -OK - -> sw - -You are in a secret canyon which here runs e/w. It crosses over a -very tight canyon 15 feet below. If you go down you may not be able -to get back up. - -> w - -You are in a secret canyon which exits to the north and east. - -A huge green fierce dragon bars the way! - -The dragon is sprawled out on a Persian rug!! - -> kill dragon - -With what? Your bare hands? - -> yes - -Congratulations! You have just vanquished a dragon with your bare -hands! (Unbelievable, isn't it?) - -You are in a secret canyon which exits to the north and east. - -There is a Persian rug spread out on the floor! - -The blood-specked body of a huge green dead dragon lies to one side. - -> drink blood - -Your head buzzes strangely for a moment. - -> take rug - -OK - -> e - -You're in secret e/w canyon above tight canyon. - -> e - -You're in Hall of Mt King. - -> n - -You're in n/s passage above e/w passage. - -There are bars of silver here! - -> take bars - -OK - -> n - -You're at "Y2". - -There is a little axe here. - -> plugh - ->>Foof!<< - -You're inside building. - -There is an emerald here the size of a plover's egg! - -There is a bottle of oil here. - -There is a delicate, precious, ming vase here! - -A small velvet pillow lies on the floor. - -There is a platinum pyramid here, 8 inches on a side! - -There are some keys on the ground here. - -There is food here. - -> drop cage - -OK - -> drop necklace - -OK - -> drop nugget - -OK - -> drop bars - -OK - -> drop rug - -OK - -> xyzzy - ->>Foof!<< - -You're in debris room. - -> pit - -You're at top of small pit. - -A three foot black rod with a rusty star on an end lies nearby. - -Rough stone steps lead down the pit. - -> take rod - -OK - -> d - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> w - -You are on the east bank of a fissure slicing clear across the hall. -The mist is quite thick here, and the fissure is too wide to jump. - -> wave rod - -A crystal bridge now spans the fissure. - -> w - -You are on the west side of the fissure in the Hall of Mists. - -There are diamonds here! - -A crystal bridge spans the fissure. - -> take diamonds - -OK - -> w - -There is a threatening little dwarf in the room with you! - -You are at the west end of the Hall of Mists. A low wide crawl -continues west and another goes north. To the south is a little -passage 6 feet off the floor. - -> w - -There is a threatening little dwarf in the room with you! - -You are at the east end of a very long hall apparently without side -chambers. To the east a low wide crawl slants up. To the north a -round two foot hole slants down. - -> w - -There is a threatening little dwarf in the room with you! - -You are at the west end of a very long featureless hall. The hall -joins up with a narrow north/south passage. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a maze of twisty little passages, all different. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a maze of twisting little passages, all different. - -> e - -There is a threatening little dwarf in the room with you! - -You are in a little maze of twisting passages, all different. - -> s - -There is a threatening little dwarf in the room with you! - -Dead end - -There is a massive and somewhat battered vending machine here. The -instructions on it read: "Drop coins here to receive fresh batteries." - -> hit machine - -As you strike the vending machine, it pivots backward along with a -section of wall, revealing a dark passage leading south. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a long, rough-hewn, north/south corridor. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a large chamber with passages to the west and north. - -A formidable ogre bars the northern exit. - -> kill ogre - -The ogre, who despite his bulk is quite agile, easily dodges your -attack. He seems almost amused by your puny effort. - -One sharp nasty knife is thrown at you! - -The ogre, distracted by your rush, is struck by the knife. With a -blood-curdling yell he turns and bounds after the dwarf, who flees -in panic. You are left alone in the room. - -> n - -You are in the ogre's storeroom. The only exit is to the south. - -There is an enormous ruby here! - -> take ruby - -OK - -> s - -You are in a large chamber with passages to the west and north. - -> w - -You are in a long, rough-hewn, north/south corridor. - -> n - -Dead end - -There is a massive vending machine here, swung back to reveal a -southward passage. - -> n - -You are in a little maze of twisting passages, all different. - -> sw - -You are in a maze of twisting little passages, all different. - -> w - -You are in a maze of twisty little passages, all different. - -> d - -You're at west end of long hall. - -> n - -You are at a crossover of a high n/s passage and a low e/w one. - -> e - -You are in the west side chamber of the Hall of the Mountain King. -A passage continues west and up here. - -There are many coins here! - -> take coins - -OK - -> e - -You're in Hall of Mt King. - -> s - -You are in the south side chamber. - -There is precious jewelry here! - -> take jewelry - -OK - -> n - -You're in Hall of Mt King. - -> e - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> w - -You're on east bank of fissure. - -A crystal bridge spans the fissure. - -> w - -You're on west bank of fissure. - -A crystal bridge spans the fissure. - -> w - -You're at west end of Hall of Mists. - -> s - -You are in a maze of twisty little passages, all alike. - -> e - -Out from the shadows behind you pounces a bearded pirate! "Har, har," -he chortles, "I'll just take all this booty and hide it away with me -chest deep in the maze!" He snatches your treasure and vanishes into -the gloom. - -You are in a maze of twisty little passages, all alike. - -> s - -You are in a maze of twisty little passages, all alike. - -> s - -You are in a maze of twisty little passages, all alike. - -> s - -You are in a maze of twisty little passages, all alike. - -> n - -You are in a maze of twisty little passages, all alike. - -> e - -You are on the brink of a thirty foot pit with a massive orange column -down one wall. You could climb down here but you could not get back -up. The maze continues at this level. - -> e - -You are in a maze of twisty little passages, all alike. - -> nw - -Dead end - -There is an enormous ruby here! - -There are many coins here! - -There is precious jewelry here! - -There are diamonds here! - -The pirate's treasure chest is here! - -> drop rod - -OK - -> take jewelry - -OK - -> take chest - -OK - -> take ruby - -OK - -> take diamonds - -OK - -> take coins - -OK - -> se - -There is a threatening little dwarf in the room with you! - -You are in a maze of twisty little passages, all alike. - -> w - -There is a threatening little dwarf in the room with you! - -You are in a maze of twisty little passages, all alike. - -> s - -There is a threatening little dwarf in the room with you! - -You're at brink of pit. - -> d - -You're in bird chamber. - -> debris - -You're in debris room. - -> xyzzy - ->>Foof!<< - -You're inside building. - -There is a Persian rug spread out on the floor! - -There are bars of silver here! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is a small wicker cage discarded nearby. - -There is a little bird in the cage. - -There is an emerald here the size of a plover's egg! - -There is a bottle of oil here. - -There is a delicate, precious, ming vase here! - -A small velvet pillow lies on the floor. - -There is a platinum pyramid here, 8 inches on a side! - -There are some keys on the ground here. - -There is food here. - -> off - -Your lamp is now off. - -> drop coins - -OK - -> drop diamonds - -OK - -> drop jewelry - -OK - -> drop chest - -OK - -> drop lamp - -OK - -> take rug - -OK - -> take emerald - -OK - -> take cage - -OK - -> take bottle - -OK - -> w - -You're in front of building. - -> s - -You are in a valley in the forest beside a stream tumbling along a -rocky bed. - -> w - -You are wandering aimlessly through the forest. - -> drop bird - -OK - -> listen - -The bird is singing to you in gratitude for your having returned it to -its home. In return, it informs you of a magic word which it thinks -you may find useful somewhere near the Hall of Mists. The magic word -changes frequently, but for now the bird believes it is "N'BEH". You -thank the bird for this information, and it flies off into the forest. - -> drop cage - -OK - -> n - -You are wandering aimlessly through the forest. - -Your keen eye spots a severed leporine appendage lying on the ground. - -> take appendage - -OK - -> n - -You are wandering aimlessly through the forest. - -> e - -You are wandering aimlessly through the forest. - -> n - -You are wandering aimlessly through the forest. - -> n - -The forest thins out here to reveal a steep cliff. There is no way -down, but a small ledge can be seen to the west across the chasm. - -A small urn is embedded in the rock. - -> fill urn - -Your bottle is now empty and the urn is full of oil. - -> light urn - -The urn is now lit. - -> rub urn - -As you rub the urn, there is a flash of light and a genie appears. -His aspect is stern as he advises: "One who wouldst traffic in -precious stones must first learn to recognize the signals thereof." -He wrests the urn from the stone, leaving a small cavity. Turning to -face you again, he fixes you with a steely eye and intones: "Caution!" -Genie and urn vanish in a cloud of amber smoke. The smoke condenses -to form a rare amber gemstone, resting in the cavity in the rock. - -> drop rug - -OK - -> take amber - -OK - -> drop emerald - -The gem fits easily into the cavity. - -The Persian rug stiffens and rises a foot or so off the ground. - -> fly - -You board the Persian rug, which promptly whisks you across the chasm. -You have time for a fleeting glimpse of a two thousand foot drop to a -mighty river; then you find yourself on the other side. - -You are on a small ledge on one face of a sheer cliff. There are no -paths away from the ledge. Across the chasm is a small clearing -surrounded by forest. - -There is a Persian rug here, hovering in mid-air! - -A brilliant blue star sapphire is here! - -> take sapphire - -OK - -> fly - -The rug ferries you back across the chasm. - -You're at cliff. - -There is an emerald resting in a small cavity in the rock! - -There is a Persian rug here, hovering in mid-air! - -> take emerald - -OK - -> drop ruby - -The gem fits easily into the cavity. - -The Persian rug settles gently to the ground. - -> take rug - -OK - -> take ruby - -OK - -> e - -You are wandering aimlessly through the forest. - -> s - -You are wandering aimlessly through the forest. - -> e - -You have walked up a hill, still in the forest. The road slopes back -down the other side of the hill. There is a building in the distance. - -> e - -You're in front of building. - -> e - -You are inside a building, a well house for a large spring. - -There is a shiny brass lamp nearby. - -The pirate's treasure chest is here! - -There is precious jewelry here! - -There are diamonds here! - -There are many coins here! - -There are bars of silver here! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is a delicate, precious, ming vase here! - -A small velvet pillow lies on the floor. - -There is a platinum pyramid here, 8 inches on a side! - -There are some keys on the ground here. - -There is food here. - -> drop emerald - -OK - -> drop ruby - -OK - -> drop amber - -OK - -> drop rug - -OK - -> drop sapphire - -OK - -> fill bottle - -Your bottle is now full of water. - -> take lamp - -OK - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You're at "Y2". - -There is a little axe here. - -> s - -You're in n/s passage above e/w passage. - -> s - -You're in Hall of Mt King. - -> sw - -You're in secret e/w canyon above tight canyon. - -> w - -You are in a secret canyon which exits to the north and east. - -The body of a huge green dead dragon is lying off to one side. - -> n - -You are in a secret n/s canyon above a large room. - -> reservoir - -You are at the edge of a large underground reservoir. An opaque cloud -of white mist fills the room and rises rapidly upward. The lake is -fed by a stream, which tumbles out of a hole in the wall about 10 feet -overhead and splashes noisily into the water somewhere within the -mist. There is a passage going back toward the south. - -> n'beh - -The waters have parted to form a narrow path across the reservoir. - -> n - -You are walking across the bottom of the reservoir. Walls of water -rear up on either side. The roar of the water cascading past is -nearly deafening, and the mist is so thick you can barely see. - -> n - -You are at the northern edge of the reservoir. A northwest passage -leads sharply up from here. - -The waters have parted to form a narrow path across the reservoir. - -> u - -You are scrambling along a treacherously steep, rocky passage. - -> u - -You are on a very steep incline, which widens at it goes upward. - -> u - -You are at the base of a nearly vertical cliff. There are some -slim footholds which would enable you to climb up, but it looks -extremely dangerous. Here at the base of the cliff lie the remains -of several earlier adventurers who apparently failed to make it. - -> u - -You are climbing along a nearly vertical cliff. - -> u - -Just as you reach the top, your foot slips on a loose rock and you -make one last desperate grab. Your luck holds, as does your grip. -With an enormous heave, you lift yourself to the ledge above. - -You are on a small ledge at the top of a nearly vertical cliff. -There is a low crawl leading off to the northeast. - -> ne - -You have reached a dead end. - -There is a richly-carved ebony statuette here! - -> take statuette - -OK - -> sw - -You're at top of cliff. - -> d - -You are climbing along a nearly vertical cliff. - -> d - -You're at base of cliff. - -> d - -You are on a very steep incline, which widens at it goes upward. - -> d - -You are scrambling along a treacherously steep, rocky passage. - -> d - -You're north of reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> s - -You're at bottom of reservoir. - -> s - -You're at reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> s - -You are in a north/south canyon about 25 feet across. The floor is -covered by white mist seeping in from the north. The walls extend -upward for well over 100 feet. Suspended from some unseen point far -above you, an enormous two-sided mirror is hanging parallel to and -midway between the canyon walls. (The mirror is obviously provided -for the use of the dwarves who, as you know, are extremely vain.) A -small window can be seen in either wall, some fifty feet up. - -> s - -You are in a secret n/s canyon above a large room. - -> d - -You are in a large low circular chamber whose floor is an immense slab -fallen from the ceiling (Slab Room). East and west there once were -large passages, but they are now filled with boulders. Low small -passages go north and south, and the south one quickly bends west -around the boulders. - -> s - -You're at west end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> d - -You're in west pit. - -There is a 12-foot-tall beanstalk stretching up out of the pit, -bellowing "WATER!! WATER!!" - -> water plant - -The plant grows explosively, almost filling the bottom of the pit. - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> u - -You're at west end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> e - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You're in east pit. - -> fill bottle - -Your bottle is now full of oil. - -> u - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> w - -You're at west end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> climb - -You clamber up the plant and scurry through the hole at the top. - -You are in a long, narrow corridor stretching out of sight to the -west. At the eastern end is a hole through which you can see a -profusion of leaves. - -> w - -You are in the Giant Room. The ceiling here is too high up for your -lamp to show it. Cavernous passages lead east, north, and south. On -the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. - -There is a large nest here, full of golden eggs! - -> take eggs - -OK - -> n - -You are at one end of an immense north/south passage. - -The way north is barred by a massive, rusty, iron door. - -> oil door - -The oil has freed up the hinges so that the door will now move, -although it requires some effort. - -> drop bottle - -OK - -> n - -You are in a magnificent cavern with a rushing stream, which cascades -over a sparkling waterfall into a roaring whirlpool which disappears -through a hole in the floor. Passages exit to the south and west. - -There is a jewel-encrusted trident here! - -> take trident - -OK - -> w - -You are at the top of a steep incline above a large room. You could -climb down here, but you would not be able to climb up. There is a -passage leading back to the north. - -> d - -You are in a large low room. Crawls lead north, se, and sw. - -> bedquilt - -You're in Bedquilt. - -> e - -You're at complex junction. - -> n - -You're in a large room carved out of sedimentary rock. The floor and -walls are littered with bits of shells embedded in the stone. A -shallow passage proceeds downward, and a somewhat steeper one leads -up. A low hands and knees passage enters from the south. - -There is an enormous clam here with its shell tightly closed. - -> open clam - -A glistening pearl falls out of the clam and rolls away. Goodness, -this must really be an oyster. (I never was very good at identifying -bivalves.) Whatever it is, it has now snapped shut again. - -> d - -You are in a long sloping corridor with ragged sharp walls. - -> d - -You are in a cul-de-sac about eight feet across. - -Off to one side lies a glistening pearl! - -> take pearl - -OK - -> shell - -You're in Shell Room. - -There is an enormous oyster here with its shell tightly closed. - -> s - -You're at complex junction. - -> u - -You're in dusty rock room. - -> e - -You're in dirty passage. - -> u - -You're in n/s passage above e/w passage. - -> n - -You're at "Y2". - -There is a little axe here. - -> plugh - ->>Foof!<< - -You're inside building. - -A brilliant blue star sapphire is here! - -There is a Persian rug spread out on the floor! - -There is a rare amber gemstone here! - -There is an enormous ruby here! - -There is an emerald here the size of a plover's egg! - -The pirate's treasure chest is here! - -There is precious jewelry here! - -There are diamonds here! - -There are many coins here! - -There are bars of silver here! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is a delicate, precious, ming vase here! - -A small velvet pillow lies on the floor. - -There is a platinum pyramid here, 8 inches on a side! - -There are some keys on the ground here. - -There is food here. - -> drop trident - -OK - -> drop pearl - -OK - -> drop statuette - -OK - -> drop appendage - -OK - -> take keys - -OK - -> take food - -OK - -> plugh - ->>Foof!<< - -You are in a large room, with a passage to the south, a passage to the -west, and a wall of broken rock to the east. There is a large "Y2" on -a rock in the room's center. - -There is a little axe here. - -> s - -You are in a low n/s passage at a hole in the floor. The hole goes -down to an e/w passage. - -> d - -You're in dirty passage. - -> bedquilt - -You're in Bedquilt. - -> w - -You're in Swiss Cheese Room. - -> oriental - -You're in Oriental Room. - -> w - -You're in large low room. - -> sw - -You are in a long winding corridor sloping out of sight in both -directions. - -> u - -You are on one side of a large, deep chasm. A heavy white mist rising -up from below obscures all view of the far side. A sw path leads away -from the chasm into a winding corridor. - -A rickety wooden bridge extends across the chasm, vanishing into the -mist. A notice posted on the bridge reads, "Stop! Pay troll!" - -A burly troll stands by the bridge and insists you throw him a -treasure before you may cross. - -> throw eggs - -The troll catches your treasure and scurries away out of sight. - -> ne - -You are on the far side of the chasm. A ne path leads away from the -chasm on this side. - -A rickety wooden bridge extends across the chasm, vanishing into the -mist. A notice posted on the bridge reads, "Stop! Pay troll!" - -The troll is nowhere to be seen. - -> barren - -You are standing at the entrance to a large, barren room. A notice -above the entrance reads: "Caution! Bear in room!" - -> e - -You are inside a barren room. The center of the room is completely -empty except for some dust. Marks in the dust lead away toward the -far end of the room. The only exit is the way you came in. - -There is a ferocious cave bear eyeing you from the far end of the room! - -The bear is locked to the wall with a golden chain! - -> throw food - -The bear eagerly wolfs down your food, after which he seems to calm -down considerably and even becomes rather friendly. - -> unlock chain - -The chain is now unlocked. - -> take chain - -OK - -> take bear - -OK - -> fork - -You are being followed by a very large, tame bear. - -The path forks here. The left fork leads northeast. A dull rumbling -seems to get louder in that direction. The right fork leads southeast -down a gentle slope. The main corridor enters from the west. - -> ne - -You are being followed by a very large, tame bear. - -The walls are quite warm here. From the north can be heard a steady -roar, so loud that the entire cave seems to be trembling. Another -passage leads south, and a low crawl goes east. - -> fee - -OK - -> fie - -OK - -> look - -Sorry, but I am not allowed to give more detail. I will repeat the -long description of your location. - -You are being followed by a very large, tame bear. - -The walls are quite warm here. From the north can be heard a steady -roar, so loud that the entire cave seems to be trembling. Another -passage leads south, and a low crawl goes east. - -> foe - -Nothing happens. - -> foo - -Nothing happens. - -> -You scored 311 out of a possible 430, using 291 turns. - -You have reached "Junior Master" status. - -To achieve the next higher rating, you need 10 more points. diff --git a/tests/foobug.log b/tests/foobug.log deleted file mode 100644 index 8e3dc8f..0000000 --- a/tests/foobug.log +++ /dev/null @@ -1,296 +0,0 @@ -## Test interspersing commands amidst magic words -# Check for "Nothing happens." in game output indicating sequence interrupt. -no -seed 1318612053 -e -plugh -plove -get emerald -w -drop emerald -e -ne -get pyramid -s -plove -plugh -drop pyramid -get lamp -get water -plugh -on -s -d -bedquilt -w -e -take pillow -w -oriental -take vase -n -w -take emerald -nw -s -se -w -w -d -water plant -u -e -d -fill bottle -u -e -ne -e -u -e -u -n -plugh -drop pillow -drop vase -drop bottle -drop emerald -xyzzy -take rod -e -take cage -pit -drop rod -e -take bird -w -drop bird -take rod -wave rod -take necklace -drop rod -take bird -d -s -take nugget -n -n -drop bird -take bird -sw -w -kill dragon -yes -drink blood -take rug -e -e -n -take bars -n -plugh -drop cage -drop necklace -drop nugget -drop bars -drop rug -xyzzy -pit -take rod -d -w -wave rod -w -take diamonds -w -w -w -s -s -e -s -hit machine -s -s -kill ogre -n -take ruby -s -w -n -n -sw -w -d -n -e -take coins -e -s -take jewelry -n -e -w -w -w -s -e -s -s -s -n -e -e -nw -drop rod -take jewelry -take chest -take ruby -take diamonds -take coins -se -w -s -d -debris -xyzzy -off -drop coins -drop diamonds -drop jewelry -drop chest -drop lamp -take rug -take emerald -take cage -take bottle -w -s -w -drop bird -listen -drop cage -n -take appendage -n -e -n -n -fill urn -light urn -rub urn -drop rug -take amber -drop emerald -fly -take sapphire -fly -take emerald -drop ruby -take rug -take ruby -e -s -e -e -e -drop emerald -drop ruby -drop amber -drop rug -drop sapphire -fill bottle -take lamp -plugh -on -s -s -sw -w -n -reservoir -n'beh -n -n -u -u -u -u -u -ne -take statuette -sw -d -d -d -d -d -s -s -s -s -d -s -d -water plant -u -e -d -fill bottle -u -w -d -climb -w -take eggs -n -oil door -drop bottle -n -take trident -w -d -bedquilt -e -n -open clam -d -d -take pearl -shell -s -u -e -u -n -plugh -drop trident -drop pearl -drop statuette -drop appendage -take keys -take food -plugh -s -d -bedquilt -w -oriental -w -sw -u -throw eggs -ne -barren -e -throw food -unlock chain -take chain -take bear -fork -ne -fee -fie -look -foe -foo diff --git a/tests/foofum.chk b/tests/foofum.chk deleted file mode 100644 index 6424ad7..0000000 --- a/tests/foofum.chk +++ /dev/null @@ -1,1837 +0,0 @@ - -Welcome to Adventure!! Would you like instructions? - -> n - -You are standing at the end of a road before a small brick building. -Around you is a forest. A small stream flows out of the building and -down a gully. - -> seed 1838473132 - -Seed set to 1838473132 - -You're in front of building. - -> in - -You are inside a building, a well house for a large spring. - -There are some keys on the ground here. - -There is a shiny brass lamp nearby. - -There is food here. - -There is a bottle of water here. - -> take lamp - -OK - -> xyzzy - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You are in a debris room filled with stuff washed in from the surface. -A low wide passage with cobbles becomes plugged with mud and debris -here, but an awkward canyon leads upward and west. In the mud someone -has scrawled, "MAGIC WORD XYZZY". - -A three foot black rod with a rusty star on an end lies nearby. - -> take rod - -OK - -> e - -You are crawling over cobbles in a low passage. There is a dim light -at the east end of the passage. - -There is a small wicker cage discarded nearby. - -> take cage - -OK - -> w - -You're in debris room. - -> w - -You are in an awkward sloping east/west canyon. - -> w - -You are in a splendid chamber thirty feet high. The walls are frozen -rivers of orange stone. An awkward canyon and a good passage exit -from east and west sides of the chamber. - -A cheerful little bird is sitting here singing. - -> drop rod - -OK - -> take bird - -OK - -> take rod - -OK - -> w - -At your feet is a small pit breathing traces of white mist. An east -passage ends here except for a small crack leading on. - -Rough stone steps lead down the pit. - -> free bird - -OK - -> wave rod - -The bird flies about agitatedly for a moment, then disappears through -the crack. It reappears shortly, carrying in its beak a jade -necklace, which it drops at your feet. - -> take necklace - -OK - -> drop rod - -OK - -> take bird - -OK - -> take rod - -OK - -> d - -You are at one end of a vast hall stretching forward out of sight to -the west. There are openings to either side. Nearby, a wide stone -staircase leads downward. The hall is filled with wisps of white mist -swaying to and fro almost as if alive. A cold wind blows up the -staircase. There is a passage at the top of a dome behind you. - -Rough stone steps lead up the dome. - -> d - -You are in the Hall of the Mountain King, with passages off in all -directions. - -A huge green fierce snake bars the way! - -> free bird - -The little bird attacks the green snake, and in an astounding flurry -drives the snake away. - -> drop rod - -OK - -> drop cage - -OK - -> take cage - -OK - -> take bird - -OK - -> w - -You are in the west side chamber of the Hall of the Mountain King. -A passage continues west and up here. - -There are many coins here! - -> take coins - -OK - -> e - -You're in Hall of Mt King. - -A three foot black rod with a rusty star on an end lies nearby. - -> s - -You are in the south side chamber. - -There is precious jewelry here! - -> take jewelry - -OK - -> n - -You're in Hall of Mt King. - -A three foot black rod with a rusty star on an end lies nearby. - -> up - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> s - -This is a low room with a crude note on the wall. The note says, -"You won't get it up the steps". - -There is a large sparkling nugget of gold here! - -> take gold - -OK - -> n - -You're in Hall of Mists. - -> d - -You're in Hall of Mt King. - -A three foot black rod with a rusty star on an end lies nearby. - -> n - -You are in a low n/s passage at a hole in the floor. The hole goes -down to an e/w passage. - -There are bars of silver here! - -> n - -You are in a large room, with a passage to the south, a passage to the -west, and a wall of broken rock to the east. There is a large "Y2" on -a rock in the room's center. - -A hollow voice says "PLUGH". - -> plugh - ->>Foof!<< - -You're inside building. - -There are some keys on the ground here. - -There is food here. - -There is a bottle of water here. - -> extinguish lamp - -Your lamp is now off. - -> drop coins - -OK - -> drop jewelry - -OK - -> drop necklace - -OK - -> drop gold - -OK - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You're at "Y2". - -> s - -You're in n/s passage above e/w passage. - -There are bars of silver here! - -> take silver - -OK - -> s - -You're in Hall of Mt King. - -A three foot black rod with a rusty star on an end lies nearby. - -> sw - -A little dwarf just walked around a corner, saw you, threw a little -axe at you which missed, cursed, and ran away. - -You are in a secret canyon which here runs e/w. It crosses over a -very tight canyon 15 feet below. If you go down you may not be able -to get back up. - -There is a little axe here. - -> take axe - -OK - -> w - -You are in a secret canyon which exits to the north and east. - -A huge green fierce dragon bars the way! - -The dragon is sprawled out on a Persian rug!! - -> kill dragon - -With what? Your bare hands? - -> yes - -Congratulations! You have just vanquished a dragon with your bare -hands! (Unbelievable, isn't it?) - -You are in a secret canyon which exits to the north and east. - -There is a Persian rug spread out on the floor! - -The blood-specked body of a huge green dead dragon lies to one side. - -> drink blood - -Your head buzzes strangely for a moment. - -> take rug - -OK - -> e - -You're in secret e/w canyon above tight canyon. - -> e - -You are in the Hall of the Mountain King, with passages off in all -directions. - -A three foot black rod with a rusty star on an end lies nearby. - -> up - -There is a threatening little dwarf in the room with you! - -One sharp nasty knife is thrown at you! - -It misses! - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> d - -There is a threatening little dwarf in the room with you! - -You're in Hall of Mt King. - -A three foot black rod with a rusty star on an end lies nearby. - -> n - -There is a threatening little dwarf in the room with you! - -You're in n/s passage above e/w passage. - -> n - -There is a threatening little dwarf in the room with you! - -You're at "Y2". - -A hollow voice says "PLUGH". - -> off - -Your lamp is now off. - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> plugh - ->>Foof!<< - -You're inside building. - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -There are many coins here! - -There are some keys on the ground here. - -There is food here. - -There is a bottle of water here. - -> inven - -You are currently holding the following: -Brass lantern -Wicker cage -Little bird in cage -Dwarf's axe -Bars of silver -Persian rug - -> drop rug - -OK - -> drop silver - -OK - -> out - -You're in front of building. - -> s - -You are in a valley in the forest beside a stream tumbling along a -rocky bed. - -> w - -You are wandering aimlessly through the forest. - -> n - -You are wandering aimlessly through the forest. - -Your keen eye spots a severed leporine appendage lying on the ground. - -> take appendage - -OK - -> free bird - -OK - -> drop cage - -OK - -> listen - -The bird is singing to you in gratitude for your having returned it to -its home. In return, it informs you of a magic word which it thinks -you may find useful somewhere near the Hall of Mists. The magic word -changes frequently, but for now the bird believes it is "H'CFL". You -thank the bird for this information, and it flies off into the forest. - -> s - -You are wandering aimlessly through the forest. - -> s - -You're in valley. - -> n - -You're in front of building. - -> in - -You're inside building. - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -There are many coins here! - -There are some keys on the ground here. - -There is food here. - -There is a bottle of water here. - -> take water - -OK - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You're at "Y2". - -> plover - ->>Foof!<< - -You're in a small chamber lit by an eerie green light. An extremely -narrow tunnel exits to the west. A dark corridor leads ne. - -There is an emerald here the size of a plover's egg! - -> ne - -You're in the dark-room. A corridor leading south is the only exit. - -A massive stone tablet embedded in the wall reads: -"Congratulations on bringing light into the dark-room!" - -There is a platinum pyramid here, 8 inches on a side! - -> take pyramid - -OK - -> s - -You're in Plover Room. - -There is an emerald here the size of a plover's egg! - -> plover - ->>Foof!<< - -You're at "Y2". - -A hollow voice says "PLUGH". - -> s - -You're in n/s passage above e/w passage. - -> s - -You're in Hall of Mt King. - -A three foot black rod with a rusty star on an end lies nearby. - -> take rod - -OK - -> up - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> w - -You are on the east bank of a fissure slicing clear across the hall. -The mist is quite thick here, and the fissure is too wide to jump. - -> wave rod - -A crystal bridge now spans the fissure. - -> drop rod - -OK - -> west - -You are on the west side of the fissure in the Hall of Mists. - -There are diamonds here! - -A crystal bridge spans the fissure. - -> take diamonds - -OK - -> w - -There is a threatening little dwarf in the room with you! - -One sharp nasty knife is thrown at you! - -It misses! - -You are at the west end of the Hall of Mists. A low wide crawl -continues west and another goes north. To the south is a little -passage 6 feet off the floor. - -> w - -There is a threatening little dwarf in the room with you! - -You are at the east end of a very long hall apparently without side -chambers. To the east a low wide crawl slants up. To the north a -round two foot hole slants down. - -> w - -There is a threatening little dwarf in the room with you! - -You are at the west end of a very long featureless hall. The hall -joins up with a narrow north/south passage. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a maze of twisty little passages, all different. - -> sw - -There is a threatening little dwarf in the room with you! - -You are in a little maze of twisty passages, all different. - -> se - -There is a threatening little dwarf in the room with you! - -You are in a little maze of twisting passages, all different. - -> s - -There is a threatening little dwarf in the room with you! - -Dead end - -There is a massive and somewhat battered vending machine here. The -instructions on it read: "Drop coins here to receive fresh batteries." - -> kill machine - -As you strike the vending machine, it pivots backward along with a -section of wall, revealing a dark passage leading south. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a long, rough-hewn, north/south corridor. - -> s - -There is a threatening little dwarf in the room with you! - -You are in a large chamber with passages to the west and north. - -A formidable ogre bars the northern exit. - -> kill ogre - -The ogre, who despite his bulk is quite agile, easily dodges your -attack. He seems almost amused by your puny effort. - -One sharp nasty knife is thrown at you! - -The ogre, distracted by your rush, is struck by the knife. With a -blood-curdling yell he turns and bounds after the dwarf, who flees -in panic. You are left alone in the room. - -> n - -You are in the ogre's storeroom. The only exit is to the south. - -There is an enormous ruby here! - -> take ruby - -OK - -> s - -You are in a large chamber with passages to the west and north. - -> w - -You are in a long, rough-hewn, north/south corridor. - -> n - -Dead end - -There is a massive vending machine here, swung back to reveal a -southward passage. - -> n - -You are in a little maze of twisting passages, all different. - -> n - -You are in a little maze of twisty passages, all different. - -> nw - -You are in a maze of twisty little passages, all different. - -> d - -You're at west end of long hall. - -> e - -You're at east end of long hall. - -> e - -You're at west end of Hall of Mists. - -> e - -You're on west bank of fissure. - -A crystal bridge spans the fissure. - -> e - -You're on east bank of fissure. - -A three foot black rod with a rusty star on an end lies nearby. - -A crystal bridge spans the fissure. - -> e - -There is a threatening little dwarf in the room with you! - -One sharp nasty knife is thrown at you! - -It misses! - -You are at one end of a vast hall stretching forward out of sight to -the west. There are openings to either side. Nearby, a wide stone -staircase leads downward. The hall is filled with wisps of white mist -swaying to and fro almost as if alive. A cold wind blows up the -staircase. There is a passage at the top of a dome behind you. - -Rough stone steps lead up the dome. - -> throw axe - -You killed a little dwarf. The body vanishes in a cloud of greasy -black smoke. - -You're in Hall of Mists. - -There is a little axe here. - -Rough stone steps lead up the dome. - -> take axe - -OK - -> n - -You're in Hall of Mt King. - -> n - -You're in n/s passage above e/w passage. - -> n - -You are in a large room, with a passage to the south, a passage to the -west, and a wall of broken rock to the east. There is a large "Y2" on -a rock in the room's center. - -A hollow voice says "PLUGH". - -> off - -Your lamp is now off. - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> plugh - ->>Foof!<< - -You're inside building. - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -There are many coins here! - -There are some keys on the ground here. - -There is food here. - -> drop ruby - -OK - -> drop diamonds - -OK - -> drop pyramid - -OK - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> on - -Your lamp is now on. - -You're at "Y2". - -A hollow voice says "PLUGH". - -> s - -You are in a low n/s passage at a hole in the floor. The hole goes -down to an e/w passage. - -> s - -You're in Hall of Mt King. - -> u - -You're in Hall of Mists. - -Rough stone steps lead up the dome. - -> n - -You are in the Hall of the Mountain King, with passages off in all -directions. - -> n - -You're in n/s passage above e/w passage. - -> d - -You are in a dirty broken passage. To the east is a crawl. To the -west is a large passage. Above you is a hole to another passage. - -> bedquilt - -There is a threatening little dwarf in the room with you! - -You are in Bedquilt, a long east/west passage with holes everywhere. -To explore at random select north, south, up, or down. - -> throw axe - -You killed a little dwarf. - -You're in Bedquilt. - -There is a little axe here. - -> take axe - -OK - -> slab - -You are in a large low circular chamber whose floor is an immense slab -fallen from the ceiling (Slab Room). East and west there once were -large passages, but they are now filled with boulders. Low small -passages go north and south, and the south one quickly bends west -around the boulders. - -> s - -You are at the west end of the Twopit Room. There is a large hole in -the wall above the pit at this end of the room. - -> d - -You are at the bottom of the western pit in the Twopit Room. There is -a large hole in the wall about 25 feet above you. - -There is a tiny little plant in the pit, murmuring "water, water, ..." - -> water plant - -The plant spurts into furious growth for a few seconds. - -You're in west pit. - -There is a 12-foot-tall beanstalk stretching up out of the pit, -bellowing "WATER!! WATER!!" - -> u - -You're at west end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> w - -You're in Slab Room. - -> u - -You are in a secret n/s canyon above a large room. - -> reservoir - -You are at the edge of a large underground reservoir. An opaque cloud -of white mist fills the room and rises rapidly upward. The lake is -fed by a stream, which tumbles out of a hole in the wall about 10 feet -overhead and splashes noisily into the water somewhere within the -mist. There is a passage going back toward the south. - -> H'CFL - -The waters have parted to form a narrow path across the reservoir. - -> n - -You are walking across the bottom of the reservoir. Walls of water -rear up on either side. The roar of the water cascading past is -nearly deafening, and the mist is so thick you can barely see. - -> n - -You are at the northern edge of the reservoir. A northwest passage -leads sharply up from here. - -The waters have parted to form a narrow path across the reservoir. - -> nw - -You are scrambling along a treacherously steep, rocky passage. - -> u - -You are on a very steep incline, which widens at it goes upward. - -> u - -You are at the base of a nearly vertical cliff. There are some -slim footholds which would enable you to climb up, but it looks -extremely dangerous. Here at the base of the cliff lie the remains -of several earlier adventurers who apparently failed to make it. - -> u - -You are climbing along a nearly vertical cliff. - -> u - -Just as you reach the top, your foot slips on a loose rock and you -make one last desperate grab. Your luck holds, as does your grip. -With an enormous heave, you lift yourself to the ledge above. - -You are on a small ledge at the top of a nearly vertical cliff. -There is a low crawl leading off to the northeast. - -> ne - -You have reached a dead end. - -There is a richly-carved ebony statuette here! - -> take ebony - -OK - -> sw - -You're at top of cliff. - -> d - -You are climbing along a nearly vertical cliff. - -> d - -You're at base of cliff. - -> d - -You are on a very steep incline, which widens at it goes upward. - -> d - -You are scrambling along a treacherously steep, rocky passage. - -> d - -You're north of reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> take water - -Your bottle is now full of water. - -> s - -You're at bottom of reservoir. - -> s - -You're at reservoir. - -The waters have parted to form a narrow path across the reservoir. - -> s - -You are in a north/south canyon about 25 feet across. The floor is -covered by white mist seeping in from the north. The walls extend -upward for well over 100 feet. Suspended from some unseen point far -above you, an enormous two-sided mirror is hanging parallel to and -midway between the canyon walls. (The mirror is obviously provided -for the use of the dwarves who, as you know, are extremely vain.) A -small window can be seen in either wall, some fifty feet up. - -> s - -You are in a secret n/s canyon above a large room. - -> d - -You're in Slab Room. - -> s - -You're at west end of Twopit Room. - -The top of a 12-foot-tall beanstalk is poking out of the west pit. - -> d - -You're in west pit. - -There is a 12-foot-tall beanstalk stretching up out of the pit, -bellowing "WATER!! WATER!!" - -> water plant - -The plant grows explosively, almost filling the bottom of the pit. - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> u - -You're at west end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> drop appendage - -OK - -> e - -You are at the east end of the Twopit Room. The floor here is -littered with thin rock slabs, which make it easy to descend the pits. -There is a path here bypassing the pits to connect passages from east -and west. There are holes all over, but the only big one is on the -wall directly over the west pit where you can't get to it. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You are at the bottom of the eastern pit in the Twopit Room. There is -a small pool of oil in one corner of the pit. - -> get oil - -Your bottle is now full of oil. - -> - -> u - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> w - -You're at west end of Twopit Room. - -Your keen eye spots a severed leporine appendage lying on the ground. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> climb - -You clamber up the plant and scurry through the hole at the top. - -You are in a long, narrow corridor stretching out of sight to the -west. At the eastern end is a hole through which you can see a -profusion of leaves. - -> w - -You are in the Giant Room. The ceiling here is too high up for your -lamp to show it. Cavernous passages lead east, north, and south. On -the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. - -There is a large nest here, full of golden eggs! - -> n - -You are at one end of an immense north/south passage. - -The way north is barred by a massive, rusty, iron door. - -> oil door - -The oil has freed up the hinges so that the door will now move, -although it requires some effort. - -> drop bottle - -OK - -> n - -You are in a magnificent cavern with a rushing stream, which cascades -over a sparkling waterfall into a roaring whirlpool which disappears -through a hole in the floor. Passages exit to the south and west. - -There is a jewel-encrusted trident here! - -> take trident - -OK - -> w - -You are at the top of a steep incline above a large room. You could -climb down here, but you would not be able to climb up. There is a -passage leading back to the north. - -> d - -You are in a large low room. Crawls lead north, se, and sw. - -> se - -This is the Oriental Room. Ancient oriental cave drawings cover the -walls. A gently sloping passage leads upward to the north, another -passage leads se, and a hands and knees crawl leads west. - -There is a delicate, precious, ming vase here! - -> n - -You are following a wide path around the outer edge of a large cavern. -Far below, through a heavy white mist, strange splashing noises can be -heard. The mist rises up through a fissure in the ceiling. The path -exits to the south and west. - -> w - -You are in an alcove. A small nw path seems to widen after a short -distance. An extremely tight tunnel leads east. It looks like a very -tight squeeze. An eerie light can be seen at the other end. - -> drop trident - -OK - -> drop ebony - -OK - -> drop axe - -OK - -> drop lantern - -OK - -> e - -You're in Plover Room. - -There is an emerald here the size of a plover's egg! - -> take emerald - -OK - -> w - -You're in alcove. - -There is a lamp shining nearby. - -There is a little axe here. - -There is a richly-carved ebony statuette here! - -There is a jewel-encrusted trident here! - -> take lamp - -OK - -> take axe - -OK - -> take ebony - -OK - -> take trident - -OK - -> nw - -You're in misty cavern. - -> s - -You're in Oriental Room. - -There is a delicate, precious, ming vase here! - -> take vase - -OK - -> se - -There is a threatening little dwarf in the room with you! - -You are in a room whose walls resemble Swiss cheese. Obvious passages -go west, east, ne, and nw. Part of the room is occupied by a large -bedrock block. - -> throw axe - -You killed a little dwarf. - -You're in Swiss Cheese Room. - -There is a little axe here. - -> take axe - -OK - -> e - -You are in the Soft Room. The walls are covered with heavy curtains, -the floor with a thick pile carpet. Moss covers the ceiling. - -A small velvet pillow lies on the floor. - -> take pillow - -OK - -> w - -You're in Swiss Cheese Room. - -> drop axe - -OK - -> ne - -You're in Bedquilt. - -> e - -You are at a complex junction. A low hands and knees passage from the -north joins a higher crawl from the east to make a walking passage -going west. There is also a large room above. The air is damp here. - -> n - -You're in a large room carved out of sedimentary rock. The floor and -walls are littered with bits of shells embedded in the stone. A -shallow passage proceeds downward, and a somewhat steeper one leads -up. A low hands and knees passage enters from the south. - -There is an enormous clam here with its shell tightly closed. - -> open clam - -A glistening pearl falls out of the clam and rolls away. Goodness, -this must really be an oyster. (I never was very good at identifying -bivalves.) Whatever it is, it has now snapped shut again. - -> s - -You're at complex junction. - -> u - -You are in a large room full of dusty rocks. There is a big hole in -the floor. There are cracks everywhere, and a passage leading east. - -> e - -You're in dirty passage. - -> u - -You're in n/s passage above e/w passage. - -> n - -You're at "Y2". - -> off - -Your lamp is now off. - -It is now pitch dark. If you proceed you will likely fall into a pit. - -> plugh - ->>Foof!<< - -You are inside a building, a well house for a large spring. - -There is a platinum pyramid here, 8 inches on a side! - -There are diamonds here! - -There is an enormous ruby here! - -There are bars of silver here! - -There is a Persian rug spread out on the floor! - -There is a large sparkling nugget of gold here! - -A precious jade necklace has been dropped here! - -There is precious jewelry here! - -There are many coins here! - -There are some keys on the ground here. - -There is food here. - -> drop pillow - -OK - -> drop vase - -The vase is now resting, delicately, on a velvet pillow. - -> drop trident - -OK - -> drop emerald - -OK - -> drop ebony - -OK - -> take keys - -OK - -> take food - -OK - -> plugh - ->>Foof!<< - -It is now pitch dark. If you proceed you will likely fall into a pit. - -A hollow voice says "PLUGH". - -> on - -Your lamp is now on. - -You're at "Y2". - -A hollow voice says "PLUGH". - -> s - -You're in n/s passage above e/w passage. - -> d - -You're in dirty passage. - -> w - -You're in dusty rock room. - -> d - -You're at complex junction. - -> n - -You're in Shell Room. - -There is an enormous oyster here with its shell tightly closed. - -> d - -You are in a long sloping corridor with ragged sharp walls. - -> d - -You are in a cul-de-sac about eight feet across. - -Off to one side lies a glistening pearl! - -> take pearl - -OK - -> u - -You are in a long sloping corridor with ragged sharp walls. - -> u - -You're in Shell Room. - -There is an enormous oyster here with its shell tightly closed. - -> s - -You're at complex junction. - -> w - -You're in Bedquilt. - -> w - -You're in Swiss Cheese Room. - -There is a little axe here. - -> w - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> w - -You are at the west end of the Twopit Room. There is a large hole in -the wall above the pit at this end of the room. - -Your keen eye spots a severed leporine appendage lying on the ground. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You are at the bottom of the western pit in the Twopit Room. There is -a large hole in the wall about 25 feet above you. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> climb - -You clamber up the plant and scurry through the hole at the top. - -You're in narrow corridor. - -> w - -You're in Giant Room. - -There is a large nest here, full of golden eggs! - -> get eggs - -OK - -> n - -You are at one end of an immense north/south passage. - -There is an empty bottle here. - -The way north leads through a massive, rusty, iron door. - -> take bottle - -OK - -> n - -You're in cavern with waterfall. - -> w - -You're at steep incline above large room. - -> d - -You're in large low room. - -> sw - -You are in a long winding corridor sloping out of sight in both -directions. - -> u - -You are on one side of a large, deep chasm. A heavy white mist rising -up from below obscures all view of the far side. A sw path leads away -from the chasm into a winding corridor. - -A rickety wooden bridge extends across the chasm, vanishing into the -mist. A notice posted on the bridge reads, "Stop! Pay troll!" - -A burly troll stands by the bridge and insists you throw him a -treasure before you may cross. - -> toss eggs - -The troll catches your treasure and scurries away out of sight. - -> ne - -You are on the far side of the chasm. A ne path leads away from the -chasm on this side. - -A rickety wooden bridge extends across the chasm, vanishing into the -mist. A notice posted on the bridge reads, "Stop! Pay troll!" - -The troll is nowhere to be seen. - -> ne - -You're in a long east/west corridor. A faint rumbling noise can be -heard in the distance. - -> barren - -You are standing at the entrance to a large, barren room. A notice -above the entrance reads: "Caution! Bear in room!" - -> in - -You are inside a barren room. The center of the room is completely -empty except for some dust. Marks in the dust lead away toward the -far end of the room. The only exit is the way you came in. - -There is a ferocious cave bear eyeing you from the far end of the room! - -The bear is locked to the wall with a golden chain! - -> feed bear - -The bear eagerly wolfs down your food, after which he seems to calm -down considerably and even becomes rather friendly. - -> unlock chain - -The chain is now unlocked. - -> take chain - -OK - -> take bear - -OK - -> fork - -You are being followed by a very large, tame bear. - -The path forks here. The left fork leads northeast. A dull rumbling -seems to get louder in that direction. The right fork leads southeast -down a gentle slope. The main corridor enters from the west. - -> ne - -You are being followed by a very large, tame bear. - -The walls are quite warm here. From the north can be heard a steady -roar, so loud that the entire cave seems to be trembling. Another -passage leads south, and a low crawl goes east. - -> e - -You are being followed by a very large, tame bear. - -You are in a small chamber filled with large boulders. The walls are -very warm, causing the air in the room to be almost stifling from the -heat. The only exit is a crawl heading west, through which is coming -a low rumbling. - -There are rare spices here! - -> take spices - -OK - -> drop keys - -OK - -> fork - -You are being followed by a very large, tame bear. - -You're at fork in path. - -> w - -You are being followed by a very large, tame bear. - -You're in corridor. - -> w - -You are being followed by a very large, tame bear. - -You're on ne side of chasm. - -A rickety wooden bridge extends across the chasm, vanishing into the -mist. A notice posted on the bridge reads, "Stop! Pay troll!" - -The troll is nowhere to be seen. - -> sw - -The troll steps out from beneath the bridge and blocks your way. - -You are being followed by a very large, tame bear. - -You're on ne side of chasm. - -A rickety wooden bridge extends across the chasm, vanishing into the -mist. A notice posted on the bridge reads, "Stop! Pay troll!" - -A burly troll stands by the bridge and insists you throw him a -treasure before you may cross. - -> free bear - -The bear lumbers toward the troll, who lets out a startled shriek and -scurries away. The bear soon gives up the pursuit and wanders back. - -> inven - -You are currently holding the following: -Brass lantern -Small bottle -Glistening pearl -Rare spices -Golden chain - -> sw - -You're on sw side of chasm. - -A rickety wooden bridge extends across the chasm, vanishing into the -mist. A notice posted on the bridge reads, "Stop! Pay troll!" - -The troll is nowhere to be seen. - -> sw - -You're in sloping corridor. - -> d - -You're in large low room. - -> se - -You're in Oriental Room. - -> se - -You're in Swiss Cheese Room. - -There is a little axe here. - -> w - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You're in east pit. - -> get oil - -Your bottle is now full of oil. - -> up - -You're at east end of Twopit Room. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> e - -You are in a room whose walls resemble Swiss cheese. Obvious passages -go west, east, ne, and nw. Part of the room is occupied by a large -bedrock block. - -There is a little axe here. - -> take axe - -OK - -> w - -You are at the east end of the Twopit Room. The floor here is -littered with thin rock slabs, which make it easy to descend the pits. -There is a path here bypassing the pits to connect passages from east -and west. There are holes all over, but the only big one is on the -wall directly over the west pit where you can't get to it. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> w - -You're at west end of Twopit Room. - -Your keen eye spots a severed leporine appendage lying on the ground. - -There is a huge beanstalk growing out of the west pit up to the hole. - -> d - -You're in west pit. - -There is a gigantic beanstalk stretching all the way up to the hole. - -> climb - -You clamber up the plant and scurry through the hole at the top. - -You're in narrow corridor. - -> w - -You're in Giant Room. - -> fee - -OK - -> fie - -OK - -> foe - -OK - -> fum - -What's the matter, can't you read? Now you'd best start over. - -> quit - -Do you really want to quit now? - -> yes - -OK - -You scored 253 out of a possible 430, using 304 turns. - -You have reached "Junior Master" status. - -To achieve the next higher rating, you need 68 more points. diff --git a/tests/foofum.log b/tests/foofum.log deleted file mode 100644 index 801884a..0000000 --- a/tests/foofum.log +++ /dev/null @@ -1,344 +0,0 @@ -## Test processing of fee fie foe fum -# -# How thry're supposed to work: -# -# 1. The word "fum", from the famous phrase, "fee fie foe fum" is treated -# as a red herring for the player and is handled differently in the -# logic of the game -# -# 2. Each word of the magic phrase and the word "fum" can be preceded by -# the word "say", so "say fee", "say fie", etc. will work, as -# well. For "say fum", 'Okay, "FUM"' should NOT be the response, -# similar to what is seen when other non-magic words are uttered with -# "say" -# -# 3. The sequence is triggered by the first word "fee" only. If any of -# the other words of the phrase or "fum" are said before "fee", -# "nothing happens" -# -# 4. The phrase "fee fie foe foo" must be entered as four separate -# commands, in order, without interruption. A move, like "east" or a -# non-move, like "look", are both considered interruptions -# -# 5. Once the sequence has begun, if any of the words of the phrase, -# including a second "fee", are said out of order, or "fum" is spoken at -# all during the sequence, the player is admonished for not being able -# to read. The assumption here is the player at some point in the time -# had previously read the phrase, but then messes up the order and/or -# thinks "fum" was a part of the phrase when they attempt to speak -# it. The player then must say "fee" again to restart the sequence. And -# to clarify, a second "fee" in the sequence triggers the admonishment, -# it does not restart the sequence -# -# Now that we're at the Giant's Room, actual testing can start -# -n -seed 1838473132 -in -take lamp -xyzzy -on -take rod -e -take cage -w -w -w -drop rod -take bird -take rod -w -free bird -wave rod -take necklace -drop rod -take bird -take rod -d -d -free bird -drop rod -drop cage -take cage -take bird -w -take coins -e -s -take jewelry -n -up -s -take gold -n -d -n -n -plugh -extinguish lamp -drop coins -drop jewelry -drop necklace -drop gold -plugh -on -s -take silver -s -sw -take axe -w -kill dragon -yes -drink blood -take rug -e -e -up -d -n -n -off -plugh -inven -drop rug -drop silver -out -s -w -n -take appendage -free bird -drop cage -listen -s -s -n -in -take water -plugh -on -plover -ne -take pyramid -s -plover -s -s -take rod -up -w -wave rod -drop rod -west -take diamonds -w -w -w -s -sw -se -s -kill machine -s -s -kill ogre -n -take ruby -s -w -n -n -n -nw -d -e -e -e -e -e -throw axe -take axe -n -n -n -off -plugh -drop ruby -drop diamonds -drop pyramid -plugh -on -s -s -u -n -n -d -bedquilt -throw axe -take axe -slab -s -d -water plant -u -w -u -reservoir -H'CFL -n -n -nw -u -u -u -u -ne -take ebony -sw -d -d -d -d -d -take water -s -s -s -s -d -s -d -water plant -u -drop appendage -e -d -get oil - -u -w -d -climb -w -n -oil door -drop bottle -n -take trident -w -d -se -n -w -drop trident -drop ebony -drop axe -drop lantern -e -take emerald -w -take lamp -take axe -take ebony -take trident -nw -s -take vase -se -throw axe -take axe -e -take pillow -w -drop axe -ne -e -n -open clam -s -u -e -u -n -off -plugh -drop pillow -drop vase -drop trident -drop emerald -drop ebony -take keys -take food -plugh -on -s -d -w -d -n -d -d -take pearl -u -u -s -w -w -w -w -d -climb -w -get eggs -n -take bottle -n -w -d -sw -u -toss eggs -ne -ne -barren -in -feed bear -unlock chain -take chain -take bear -fork -ne -e -take spices -drop keys -fork -w -w -sw -free bear -inven -sw -sw -d -se -se -w -d -get oil -up -e -take axe -w -w -d -climb -w -# We're at Giant Room -fee -fie -foe -fum -quit -yes diff --git a/tests/illformed.chk b/tests/illformed.chk index 7366d49..925fc31 100644 --- a/tests/illformed.chk +++ b/tests/illformed.chk @@ -126,22 +126,6 @@ There is a bottle of water here. Nothing happens. -> say fee - -OK - -> say fie - -OK - -> say foe - -OK - -> say fum - -Nothing happens. - > in I don't know in from out here. Use compass points or name something @@ -162,7 +146,7 @@ There is a bottle of water here. What do you want to do with the keys? > -You scored 27 out of a possible 430, using 21 turns. +You scored 27 out of a possible 430, using 17 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/illformed.log b/tests/illformed.log index c86b874..db4d1a5 100644 --- a/tests/illformed.log +++ b/tests/illformed.log @@ -24,11 +24,6 @@ eat building in # Z'ZZZ Word correct, but does nothing say F'UNJ -# Say bigwords when giant isn't around -say fee -say fie -say foe -say fum # Meant to evoke "I don't know in from out here." in keys diff --git a/tests/illformed2.chk b/tests/illformed2.chk index 2d02768..ab2095b 100644 --- a/tests/illformed2.chk +++ b/tests/illformed2.chk @@ -247,10 +247,6 @@ I believe what you want is right here with you. You can't unlock the keys. -> find foo - -Nothing happens. - > find bar Sorry, I don't know the word "bar". @@ -492,7 +488,7 @@ Okay, "boo". > score -You have garnered 32 out of a possible 430 points, using 102 turns. +You have garnered 32 out of a possible 430 points, using 101 turns. > z @@ -500,7 +496,7 @@ OK > score -You have garnered 32 out of a possible 430 points, using 104 turns. +You have garnered 32 out of a possible 430 points, using 103 turns. > quit keys @@ -550,7 +546,7 @@ You're outside grate. The grate is locked. > -You scored 32 out of a possible 430, using 111 turns. +You scored 32 out of a possible 430, using 110 turns. You are obviously a rank amateur. Better luck next time. diff --git a/tests/illformed2.log b/tests/illformed2.log index c03110f..99c9c80 100644 --- a/tests/illformed2.log +++ b/tests/illformed2.log @@ -61,7 +61,6 @@ in listen find keys unlock keys -find foo find bar carry blast diff --git a/tests/isofoo.chk b/tests/isofoo.chk deleted file mode 100644 index 23f17a7..0000000 --- a/tests/isofoo.chk +++ /dev/null @@ -1,19 +0,0 @@ - -Welcome to Adventure!! Would you like instructions? - -> n - -You are standing at the end of a road before a small brick building. -Around you is a forest. A small stream flows out of the building and -down a gully. - -> foo - -Nothing happens. - -> -You scored 32 out of a possible 430, using 1 turn. - -You are obviously a rank amateur. Better luck next time. - -To achieve the next higher rating, you need 14 more points. diff --git a/tests/isofoo.log b/tests/isofoo.log deleted file mode 100644 index 82b5906..0000000 --- a/tests/isofoo.log +++ /dev/null @@ -1,3 +0,0 @@ -## Test isolated 'foo' word -n -foo diff --git a/tests/magicwords.chk b/tests/magicwords.chk index 6424ad7..597c64c 100644 --- a/tests/magicwords.chk +++ b/tests/magicwords.chk @@ -13,6 +13,14 @@ Seed set to 1838473132 You're in front of building. +> foo + +Nothing happens. + +> say foo + +Nothing happens. + > in You are inside a building, a well house for a large spring. @@ -25,6 +33,54 @@ There is food here. There is a bottle of water here. +> say fee + +OK + +> say fie + +OK + +> say foe + +OK + +> say foo + +Nothing happens. + +> z + +OK + +> say fee + +OK + +> say fie + +OK + +> say foe + +OK + +> say fum + +Nothing happens. + +> z + +OK + +> find foo + +Nothing happens. + +> z + +OK + > take lamp OK @@ -1822,15 +1878,8 @@ OK What's the matter, can't you read? Now you'd best start over. -> quit - -Do you really want to quit now? - -> yes - -OK - -You scored 253 out of a possible 430, using 304 turns. +> +You scored 253 out of a possible 430, using 317 turns. You have reached "Junior Master" status. diff --git a/tests/magicwords.log b/tests/magicwords.log index 801884a..4b86370 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -1,4 +1,4 @@ -## Test processing of fee fie foe fum +## Test processing of variuus fee fie foe foo fum cases. # # How thry're supposed to work: # @@ -30,11 +30,26 @@ # to clarify, a second "fee" in the sequence triggers the admonishment, # it does not restart the sequence # -# Now that we're at the Giant's Room, actual testing can start -# n seed 1838473132 +# Test isolated 'foo' word +foo +say foo in +# Say bigwords ending with foo when not in Giant's Room +say fee +say fie +say foe +say foo +z +# Say bigwords ending with fum when not in Giant's Room +say fee +say fie +say foe +say fum +z +find foo +z take lamp xyzzy on @@ -335,10 +350,8 @@ w d climb w -# We're at Giant Room +# Now that we're at the Giant's Room, actual testing can start fee fie foe fum -quit -yes diff --git a/tests/multifile.chk b/tests/multifile.chk index 910fee2..ab4b57d 100644 --- a/tests/multifile.chk +++ b/tests/multifile.chk @@ -1,7 +1,7 @@ Welcome to Adventure!! Would you like instructions? -> ## Test isolated 'foo' word +> ## Test handling of object after transitive verb. > n > n @@ -9,18 +9,44 @@ You are standing at the end of a road before a small brick building. Around you is a forest. A small stream flows out of the building and down a gully. -> foo -> foo +> seed 826186526 +> seed 826186526 -Nothing happens. +Seed set to 826186526 + +You're in front of building. + +> in +> in + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> get +> get + +Get what? + +> food +> food + +OK > inven > inven -You're not carrying anything. +You are currently holding the following: +Tasty food -You scored 32 out of a possible 430, using 2 turns. +You scored 32 out of a possible 430, using 4 turns. You are obviously a rank amateur. Better luck next time. From b86d4afd20fe109863c778d360eb1e9b6333db70 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 2 Apr 2023 17:53:09 -0400 Subject: [PATCH 085/213] Back out the behavior change to magic words outside the Giant's Room. There are twi reasons for this. One is to decompolicate verifying the fix for issue $85: revisiting "fee fie foe foo" and "fum". The other is because I'm now convinced that the test should notr be "Are you in the Giant's Room" but :Have you read the grafitti there? --- actions.c | 8 +------- notes.adoc | 5 ----- tests/magicwords.chk | 6 +++--- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/actions.c b/actions.c index 4c2fcdb..5d763b9 100644 --- a/actions.c +++ b/actions.c @@ -228,13 +228,7 @@ static phase_codes_t bigwords(vocab_t id) } } else { fum: - if (game.loc == LOC_GIANTROOM || settings.oldstyle) { - rspeak(START_OVER); - } else { - /* This is new behavior in Open Adventure - sounds better when - * player isn't in the Giant Room. */ - rspeak(NOTHING_HAPPENS); - } + rspeak(START_OVER); game.foobar = WORD_EMPTY; return GO_CLEAROBJ; } diff --git a/notes.adoc b/notes.adoc index f5116bc..8358565 100644 --- a/notes.adoc +++ b/notes.adoc @@ -53,11 +53,6 @@ Bug fixes: * Response to an attempt to unlock the oyster while carrying it was incorrect. -* Behavior when saying the giant's magic words outside his room wasn't - quite correct - the game responded as though the player were in - the room ("...can't you read?"). The new message is "Nothing happens." - The -o option reverts this change. - * Attempting to extinguish an unlit urn caused it to lose its oil. * "A crystal bridge now spans the fissure." (progressive present) was diff --git a/tests/magicwords.chk b/tests/magicwords.chk index 597c64c..1b1a158 100644 --- a/tests/magicwords.chk +++ b/tests/magicwords.chk @@ -15,11 +15,11 @@ You're in front of building. > foo -Nothing happens. +What's the matter, can't you read? Now you'd best start over. > say foo -Nothing happens. +What's the matter, can't you read? Now you'd best start over. > in @@ -75,7 +75,7 @@ OK > find foo -Nothing happens. +What's the matter, can't you read? Now you'd best start over. > z From 20cb8b9ffbf2d228ffad77cd9ac8e1884c2d688e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 2 Apr 2023 18:28:45 -0400 Subject: [PATCH 086/213] Back out test lines that break compatibility with advent430. Coverage is still 100% even withthese lines commebted out. --- tests/magicwords.chk | 18 +----------------- tests/magicwords.log | 8 ++++---- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/tests/magicwords.chk b/tests/magicwords.chk index 1b1a158..7263870 100644 --- a/tests/magicwords.chk +++ b/tests/magicwords.chk @@ -13,14 +13,6 @@ Seed set to 1838473132 You're in front of building. -> foo - -What's the matter, can't you read? Now you'd best start over. - -> say foo - -What's the matter, can't you read? Now you'd best start over. - > in You are inside a building, a well house for a large spring. @@ -65,18 +57,10 @@ OK OK -> say fum - -Nothing happens. - > z OK -> find foo - -What's the matter, can't you read? Now you'd best start over. - > z OK @@ -1879,7 +1863,7 @@ OK What's the matter, can't you read? Now you'd best start over. > -You scored 253 out of a possible 430, using 317 turns. +You scored 253 out of a possible 430, using 313 turns. You have reached "Junior Master" status. diff --git a/tests/magicwords.log b/tests/magicwords.log index 4b86370..0f93def 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -33,8 +33,8 @@ n seed 1838473132 # Test isolated 'foo' word -foo -say foo +#foo +#say foo in # Say bigwords ending with foo when not in Giant's Room say fee @@ -46,9 +46,9 @@ z say fee say fie say foe -say fum +#say fum z -find foo +#find foo z take lamp xyzzy From 0a1f5dbb43aacb696f9219a03b96376c06f7122e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Apr 2023 06:10:12 -0400 Subject: [PATCH 087/213] Nothing but FOO can start a magic-word sequence, 100% coverage ans oldcompare passes. --- actions.c | 5 +++++ tests/magicwords.chk | 10 +++++++++- tests/magicwords.log | 6 +++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/actions.c b/actions.c index 5d763b9..936e4d8 100644 --- a/actions.c +++ b/actions.c @@ -194,6 +194,11 @@ static phase_codes_t bigwords(vocab_t id) { int foobar = abs(game.foobar); + if ((foobar == WORD_EMPTY) && (id == FIE || id == FOE || id == FOO || id == FUM)) { + rspeak(NOTHING_HAPPENS); + return GO_CLEAROBJ; + } + if ((foobar == WORD_EMPTY && id == FEE) || (foobar == FEE && id == FIE) || (foobar == FIE && id == FOE) || diff --git a/tests/magicwords.chk b/tests/magicwords.chk index 7263870..54ab5a5 100644 --- a/tests/magicwords.chk +++ b/tests/magicwords.chk @@ -13,6 +13,14 @@ Seed set to 1838473132 You're in front of building. +> foo + +Nothing happens. + +> say foo + +Nothing happens. + > in You are inside a building, a well house for a large spring. @@ -1863,7 +1871,7 @@ OK What's the matter, can't you read? Now you'd best start over. > -You scored 253 out of a possible 430, using 313 turns. +You scored 253 out of a possible 430, using 315 turns. You have reached "Junior Master" status. diff --git a/tests/magicwords.log b/tests/magicwords.log index 0f93def..f636711 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -33,8 +33,8 @@ n seed 1838473132 # Test isolated 'foo' word -#foo -#say foo +foo +say foo in # Say bigwords ending with foo when not in Giant's Room say fee @@ -48,7 +48,7 @@ say fie say foe #say fum z -#find foo +find foo z take lamp xyzzy From 2dd1ccc53580a93a144b163006f32fe374921447 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Apr 2023 09:24:21 -0400 Subject: [PATCH 088/213] Fix for Gitlab issue #65: revisiting "fee fie foe foo" and "fum". 100% coverage, "make oldcompare" passes. --- actions.c | 8 ++------ tests/magicwords.chk | 10 +++++++++- tests/magicwords.log | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/actions.c b/actions.c index 936e4d8..05c59d5 100644 --- a/actions.c +++ b/actions.c @@ -202,10 +202,9 @@ static phase_codes_t bigwords(vocab_t id) if ((foobar == WORD_EMPTY && id == FEE) || (foobar == FEE && id == FIE) || (foobar == FIE && id == FOE) || - (foobar == FOE && id == FOO) || - (foobar == FOE && id == FUM)) { + (foobar == FOE && id == FOO)) { game.foobar = id; - if ((id != FOO) && (id != FUM)) { + if (id != FOO) { rspeak(OK_MAN); return GO_CLEAROBJ; } @@ -214,8 +213,6 @@ static phase_codes_t bigwords(vocab_t id) (TOTING(EGGS) && game.loc == objects[EGGS].plac)) { rspeak(NOTHING_HAPPENS); return GO_CLEAROBJ; - } else if (id == FUM) { - goto fum; } else { /* Bring back troll if we steal the eggs back from him before * crossing. */ @@ -232,7 +229,6 @@ static phase_codes_t bigwords(vocab_t id) return GO_CLEAROBJ; } } else { -fum: rspeak(START_OVER); game.foobar = WORD_EMPTY; return GO_CLEAROBJ; diff --git a/tests/magicwords.chk b/tests/magicwords.chk index 54ab5a5..24df443 100644 --- a/tests/magicwords.chk +++ b/tests/magicwords.chk @@ -65,10 +65,18 @@ OK OK +> say fum + +What's the matter, can't you read? Now you'd best start over. + > z OK +> find foo + +Nothing happens. + > z OK @@ -1871,7 +1879,7 @@ OK What's the matter, can't you read? Now you'd best start over. > -You scored 253 out of a possible 430, using 315 turns. +You scored 253 out of a possible 430, using 317 turns. You have reached "Junior Master" status. diff --git a/tests/magicwords.log b/tests/magicwords.log index f636711..4b86370 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -46,7 +46,7 @@ z say fee say fie say foe -#say fum +say fum z find foo z From 71abcb4e650191977a679d86549d28a69f8feb1d Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Apr 2023 09:42:55 -0400 Subject: [PATCH 089/213] Add explanatory comment. --- actions.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/actions.c b/actions.c index 05c59d5..27364b7 100644 --- a/actions.c +++ b/actions.c @@ -194,6 +194,7 @@ static phase_codes_t bigwords(vocab_t id) { int foobar = abs(game.foobar); + /* Only FEE can start a magic-word sequence. */ if ((foobar == WORD_EMPTY) && (id == FIE || id == FOE || id == FOO || id == FUM)) { rspeak(NOTHING_HAPPENS); return GO_CLEAROBJ; @@ -229,6 +230,7 @@ static phase_codes_t bigwords(vocab_t id) return GO_CLEAROBJ; } } else { + /* Magic-word sequebce was started but is incorrect */ rspeak(START_OVER); game.foobar = WORD_EMPTY; return GO_CLEAROBJ; From 25230068fe3afb9d1faa9c606413784294700cef Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Apr 2023 10:10:06 -0400 Subject: [PATCH 090/213] Partial REUSE cmpliance. --- .gitignore | 2 ++ .gitlab-ci.yml | 2 ++ .shipper | 4 ++++ COPYING | 5 +---- Dockerfile.ci | 2 ++ Makefile | 3 +++ actions.c | 6 +++--- advent.desktop | 2 ++ advent.h | 7 +++++++ advent.svg | 26 ++------------------------ adventure.yaml | 5 +++-- cheat.c | 6 +++--- init.c | 6 +++--- main.c | 6 +++--- make_dungeon.py | 7 +++---- make_graph.py | 4 ++-- misc.c | 6 +++--- saveresume.c | 6 +++--- score.c | 6 +++--- templates/coverage_dungeon.html.tpl | 4 ++++ templates/dungeon.c.tpl | 7 ++++++- templates/dungeon.h.tpl | 4 ++++ tests/Makefile | 3 +++ tests/axebear.log | 2 ++ tests/axeorama.log | 2 ++ tests/barehands.log | 2 ++ tests/bigfail.log | 2 ++ tests/birdsnakewake.log | 2 ++ tests/birdweight.log | 2 ++ tests/boulder2.log | 2 ++ tests/breakmirror.log | 2 ++ tests/carrybird.log | 2 ++ tests/carryfreebird.log | 2 ++ tests/cheatresume.log | 2 ++ tests/cheatresume2.log | 2 ++ tests/coverage_dungeon.py | 2 ++ tests/death-jump.log | 2 ++ tests/defeat.log | 2 ++ tests/domefail.log | 2 ++ tests/dragon_secret5.log | 2 ++ tests/dropcagedbird.log | 2 ++ tests/drown.log | 2 ++ tests/dwarf.log | 2 ++ tests/dwarf_alternative.log | 2 ++ tests/eggs_done.log | 2 ++ tests/eggs_vanish.log | 2 ++ tests/endgame428.log | 2 ++ tests/endobjects.log | 2 ++ tests/fail_hint_maze.log | 2 ++ tests/fail_hint_ogre.log | 2 ++ tests/fail_hint_ogre2.log | 2 ++ tests/fail_hint_woods.log | 2 ++ tests/fillfail.log | 2 ++ tests/fillvase.log | 2 ++ tests/flyback.log | 2 ++ tests/footslip.log | 2 ++ tests/gemstates.log | 2 ++ tests/goback.log | 2 ++ tests/hint_dark.log | 2 ++ tests/hint_grate.log | 2 ++ tests/hint_jade.log | 2 ++ tests/hint_snake.log | 2 ++ tests/hint_urn.log | 2 ++ tests/hint_witt.log | 2 ++ tests/illformed.log | 2 ++ tests/illformed2.log | 2 ++ tests/intransitivecarry.log | 2 ++ tests/issue36.log | 2 ++ tests/issue37.log | 2 ++ tests/lampdim.log | 2 ++ tests/lampdim2.log | 2 ++ tests/lampdim3.log | 2 ++ tests/listen.log | 2 ++ tests/listenloud.log | 4 +++- tests/lockchain.log | 2 ++ tests/logopt.log | 2 ++ tests/magicwords.log | 2 ++ tests/mazealldiff.log | 2 ++ tests/mazehint.log | 2 ++ tests/multifile.chk | 2 ++ tests/notrident.log | 2 ++ tests/ogre_no_dwarves.log | 2 ++ tests/ogrehint.log | 2 ++ tests/oilplant.log | 2 ++ tests/oldstyle.log | 2 ++ tests/outcheck.sh | 2 ++ tests/oysterbug.log | 2 ++ tests/panic.log | 2 ++ tests/panic2.log | 2 ++ tests/pirate_carry.log | 2 ++ tests/pirate_pyramid.log | 2 ++ tests/pirate_spotted.log | 2 ++ tests/pitfall.log | 2 ++ tests/plover.log | 2 ++ tests/reach_ledge_short.log | 2 ++ tests/reach_noclimb.log | 2 ++ tests/reach_planttop.log | 2 ++ tests/reincarnate.log | 2 ++ tests/resumefail.log | 2 ++ tests/resumefail2.log | 2 ++ tests/savefail.log | 2 ++ tests/saveresume.1.log | 2 ++ tests/saveresume.2.log | 2 ++ tests/saveresume.3.log | 2 ++ tests/saveresume.4.log | 2 ++ tests/saveresumeopt.log | 2 ++ tests/savetamper.log | 2 ++ tests/snake_food.log | 2 ++ tests/softroom.log | 2 ++ tests/specials.log | 2 ++ tests/splatter.log | 2 ++ tests/takebird.log | 2 ++ tests/tall.log | 2 ++ tests/tapdiffer | 2 ++ tests/tapview | 3 +-- tests/trident.log | 2 ++ tests/troll_returns.log | 2 ++ tests/turnpenalties.log | 2 ++ tests/urntest.log | 2 ++ tests/urntest2.log | 2 ++ tests/urntest3.log | 2 ++ tests/vending.log | 2 ++ tests/wakedwarves.log | 2 ++ tests/wakedwarves2.log | 2 ++ tests/wakedwarves3.log | 2 ++ tests/water_plant2.log | 2 ++ tests/weirdbird.log | 2 ++ tests/weirddwarf.log | 2 ++ tests/win430.log | 2 ++ tests/wittsend.log | 2 ++ tests/woodshint.log | 2 ++ 131 files changed, 287 insertions(+), 61 deletions(-) diff --git a/.gitignore b/.gitignore index ddb549b..7aa1928 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause advent *.gcda *.gcno diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0d0ab9d..6b6bd6d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause stages: - ci-build - build diff --git a/.shipper b/.shipper index a34d7d6..4127e0c 100644 --- a/.shipper +++ b/.shipper @@ -1,3 +1,7 @@ +<-- +SPDX-FileCopyrightText: Eric S. Raymond +SPDX-License-Identifier: BSD-2-Clause +--> extralines="""

There is a code coverage analysis and a symbol coverage analysis

""" diff --git a/COPYING b/COPYING index c4da3e1..b1de571 100644 --- a/COPYING +++ b/COPYING @@ -1,7 +1,4 @@ - BSD LICENSE - -Copyright (c) 1977, 2005 by Will Crowther and Don Woods -Copyright (c) 2017 by Eric S. Raymond + BSD 2-Clause LICENSE Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/Dockerfile.ci b/Dockerfile.ci index 535ed65..8a2c8bb 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,5 +1,7 @@ # This image is built by the Gitlab CI pipeline to be used in subsequent # pipeline steps. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause FROM ubuntu diff --git a/Makefile b/Makefile index 0f82c4a..d6ceb82 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ # Makefile for the open-source release of adventure 2.5 +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause + # To build with save/resume disabled, pass CFLAGS="-DADVENT_NOSAVE" # To build with auto-save/resume enabled, pass CFLAGS="-DADVENT_AUTOSAVE" diff --git a/actions.c b/actions.c index 27364b7..05377ff 100644 --- a/actions.c +++ b/actions.c @@ -1,9 +1,9 @@ /* * Actions for the dungeon-running code. * - * Copyright (c) 1977, 2005 by Will Crowther and Don Woods - * Copyright (c) 2017 by Eric S. Raymond - * SPDX-License-Identifier: BSD-2-clause + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/advent.desktop b/advent.desktop index d41c896..bb049de 100644 --- a/advent.desktop +++ b/advent.desktop @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause [Desktop Entry] Type=Application Name=Open Adventure diff --git a/advent.h b/advent.h index 8a31a9c..100de43 100644 --- a/advent.h +++ b/advent.h @@ -1,3 +1,10 @@ +/* + * Dungeon types and macros. + * + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause + */ #include #include #include diff --git a/advent.svg b/advent.svg index 8f50e5e..02a0e1b 100644 --- a/advent.svg +++ b/advent.svg @@ -2,30 +2,8 @@ diff --git a/adventure.yaml b/adventure.yaml index 8dfd1c8..791d8ac 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause +# # This YAML file gets processed into a collection of data structures and # variable initializers describing Colossal Cave. It replaces an ad-hoc # text database shipped with Adventure versions up to 2.5. The format @@ -115,8 +118,6 @@ # %S = the letter 's' or nothing (if a previous %d value is exactly 1) # %V = substitute program version string # -# Copyright (c) 2017 by Eric S. Raymond -# SPDX-License-Identifier: BSD-2-clause # Motion names of the form MOT_* are not explicitly referenced in the # locations YAML, but usually get compiled into generated C. diff --git a/cheat.c b/cheat.c index df9ab5b..ebbc166 100644 --- a/cheat.c +++ b/cheat.c @@ -4,9 +4,9 @@ * savefile(), so we know we're always outputting save files that advent * can import. * - * Copyright (c) 1977, 2005 by Will Crowther and Don Woods - * Copyright (c) 2017 by Eric S. Raymond - * SPDX-License-Identifier: BSD-2-clause + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause */ #include #include diff --git a/init.c b/init.c index b890fba..dbdfb11 100644 --- a/init.c +++ b/init.c @@ -1,9 +1,9 @@ /* * Initialisation * - * Copyright (c) 1977, 2005 by Will Crowther and Don Woods - * Copyright (c) 2017 by Eric S. Raymond - * SPDX-License-Identifier: BSD-2-clause + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/main.c b/main.c index d4539b1..acbabb6 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ /* - * Copyright (c) 1977, 2005 by Will Crowther and Don Woods - * Copyright (c) 2017 by Eric S. Raymond - * SPDX-License-Identifier: BSD-2-clause + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/make_dungeon.py b/make_dungeon.py index c7c9b75..0d224d3 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause """ This is the open-adventure dungeon generator. It consumes a YAML description of the dungeon and outputs a dungeon.h and dungeon.c pair of C code files. @@ -6,9 +8,6 @@ the dungeon and outputs a dungeon.h and dungeon.c pair of C code files. The nontrivial part of this is the compilation of the YAML for movement rules to the travel array that's actually used by playermove(). - -Copyright (c) 2017 by Eric S. Raymond -SPDX-License-Identifier: BSD-2-clause """ # pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,too-many-branches,global-statement,multiple-imports,too-many-locals,too-many-statements,too-many-nested-blocks,no-else-return,raise-missing-from,redefined-outer-name @@ -21,7 +20,7 @@ C_NAME = "dungeon.c" H_TEMPLATE_PATH = "templates/dungeon.h.tpl" C_TEMPLATE_PATH = "templates/dungeon.c.tpl" -DONOTEDIT_COMMENT = "/* Generated from adventure.yaml - do not hand-hack! */\n/* SPDX-License-Identifier: BSD-2-clause */\n\n" +DONOTEDIT_COMMENT = "/* Generated from adventure.yaml - do not hand-hack! */\n\n" statedefines = "" diff --git a/make_graph.py b/make_graph.py index 62ac68b..edaaa6f 100755 --- a/make_graph.py +++ b/make_graph.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause """\ usage: make-graph.py [-a] -d] [-m] [-s] @@ -11,8 +13,6 @@ Make a DOT graph of Colossal Cave. -s = emit graph of non-forest surface locations -v = include internal symbols in room labels """ -# Copyright (c) 2017 by Eric S. Raymond -# SPDX-License-Identifier: BSD-2-clause # pylint: disable=consider-using-f-string,line-too-long,invalid-name,missing-function-docstring,multiple-imports,redefined-outer-name diff --git a/misc.c b/misc.c index c2512cb..9a8d2e5 100644 --- a/misc.c +++ b/misc.c @@ -1,9 +1,9 @@ /* * I/O and support routines. * - * Copyright (c) 1977, 2005 by Will Crowther and Don Woods - * Copyright (c) 2017 by Eric S. Raymond - * SPDX-License-Identifier: BSD-2-clause + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/saveresume.c b/saveresume.c index dedb5bb..db1153b 100644 --- a/saveresume.c +++ b/saveresume.c @@ -4,9 +4,9 @@ * (ESR) This replaces a bunch of particularly nasty FORTRAN-derived code; * see the history.adoc file in the source distribution for discussion. * - * Copyright (c) 1977, 2005 by Will Crowther and Don Woods - * Copyright (c) 2017 by Eric S. Raymond - * SPDX-License-Identifier: BSD-2-clause + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/score.c b/score.c index 24dcc0a..8e37374 100644 --- a/score.c +++ b/score.c @@ -1,9 +1,9 @@ /* * Scoring and wrap-up. * - * Copyright (c) 1977, 2005 by Will Crowther and Don Woods - * Copyright (c) 2017 by Eric S. Raymond - * SPDX-License-Identifier: BSD-2-clause + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause */ #include #include "advent.h" diff --git a/templates/coverage_dungeon.html.tpl b/templates/coverage_dungeon.html.tpl index 372c43f..9545ca2 100644 --- a/templates/coverage_dungeon.html.tpl +++ b/templates/coverage_dungeon.html.tpl @@ -1,3 +1,7 @@ +<-- +SPDX-FileCopyrightText: Eric S. Raymond +SPDX-License-Identifier: BSD-2-Clause +--> diff --git a/templates/dungeon.c.tpl b/templates/dungeon.c.tpl index dbc28a6..25f4d26 100644 --- a/templates/dungeon.c.tpl +++ b/templates/dungeon.c.tpl @@ -1,3 +1,8 @@ +/* +SPDX-FileCopyrightText: Eric S. Raymond +SPDX-License-Identifier: BSD-2-Clause +*/ + #include "{h_file}" const char* arbitrary_messages[] = {{ @@ -48,4 +53,4 @@ const travelop_t travel[] = {{ const char *ignore = "{ignore}"; -/* end */ \ No newline at end of file +/* end */ diff --git a/templates/dungeon.h.tpl b/templates/dungeon.h.tpl index e42ab07..8abb529 100644 --- a/templates/dungeon.h.tpl +++ b/templates/dungeon.h.tpl @@ -1,3 +1,7 @@ +/* +SPDX-FileCopyrightText: Eric S. Raymond +SPDX-License-Identifier: BSD-2-Clause +*/ #ifndef DUNGEON_H #define DUNGEON_H diff --git a/tests/Makefile b/tests/Makefile index 2f547a0..a95f464 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,8 @@ # Test-suite makefile for open-adventure +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause + # Use absolute path so tests that change working directory still use # scripts from parent directory. Note that using $PWD seems to fail # here under Gitlab's CI environment. diff --git a/tests/axebear.log b/tests/axebear.log index 8498b21..c27ad64 100644 --- a/tests/axebear.log +++ b/tests/axebear.log @@ -1,4 +1,6 @@ ## Observe axe after throwing at bear +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/axeorama.log b/tests/axeorama.log index 7d2e273..a3b050c 100644 --- a/tests/axeorama.log +++ b/tests/axeorama.log @@ -1,4 +1,6 @@ ## Test throwing axe at non-dwarves. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Added coverage of LOC_DEADCRAWL and CROSS_BRIDGE n seed 1838473132 diff --git a/tests/barehands.log b/tests/barehands.log index 233c325..47559a0 100644 --- a/tests/barehands.log +++ b/tests/barehands.log @@ -1,4 +1,6 @@ ## Get to dragon, refuse to use bare hands +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Fails due uninteresting difference in whitespace process. # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/bigfail.log b/tests/bigfail.log index 121cd09..e4543b6 100644 --- a/tests/bigfail.log +++ b/tests/bigfail.log @@ -1,4 +1,6 @@ ## Test many nonlethal failure conditions +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # See comments in this log n seed 1838473132 diff --git a/tests/birdsnakewake.log b/tests/birdsnakewake.log index 0d64d15..81e3080 100644 --- a/tests/birdsnakewake.log +++ b/tests/birdsnakewake.log @@ -1,4 +1,6 @@ ## Attempt to kill snake with bird in the endgame +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/birdweight.log b/tests/birdweight.log index 80cc3a6..8b56bb4 100644 --- a/tests/birdweight.log +++ b/tests/birdweight.log @@ -1,4 +1,6 @@ ## Verify that the bird is weightless in inventory +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Checks fix for GitLab issue #40 #NOCOMPARE Bird was not weightless in cage in advent430 so this test is invalid. n diff --git a/tests/boulder2.log b/tests/boulder2.log index b52c757..d2dc120 100644 --- a/tests/boulder2.log +++ b/tests/boulder2.log @@ -1,4 +1,6 @@ ## Coverage of LOC_BOULDERS2.short +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/breakmirror.log b/tests/breakmirror.log index d93b075..8254c97 100644 --- a/tests/breakmirror.log +++ b/tests/breakmirror.log @@ -1,4 +1,6 @@ ## Break the mirror in endgame and die +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/carrybird.log b/tests/carrybird.log index d57736c..42ab656 100644 --- a/tests/carrybird.log +++ b/tests/carrybird.log @@ -1,4 +1,6 @@ ## Try to carry bird without cage, then kill bird +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 in diff --git a/tests/carryfreebird.log b/tests/carryfreebird.log index 0c81742..aa80f69 100644 --- a/tests/carryfreebird.log +++ b/tests/carryfreebird.log @@ -1,4 +1,6 @@ ## Try to carry the bird after freeing it instead of listening +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 attack diff --git a/tests/cheatresume.log b/tests/cheatresume.log index 96c442a..eaa110b 100644 --- a/tests/cheatresume.log +++ b/tests/cheatresume.log @@ -1,4 +1,6 @@ ## Resume from absurd save file with numdie = -900 +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n resume diff --git a/tests/cheatresume2.log b/tests/cheatresume2.log index f317d82..f9a69f4 100644 --- a/tests/cheatresume2.log +++ b/tests/cheatresume2.log @@ -1,4 +1,6 @@ ## Resume from absurd save file with numdie = -1000 +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # generating "off my scale" score threshold message #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index c583ffb..9d01c84 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause """ This is the open-adventure dungeon text coverage report generator. It consumes a YAML description of the dungeon and determines whether the diff --git a/tests/death-jump.log b/tests/death-jump.log index 3c877f0..f37b80f 100644 --- a/tests/death-jump.log +++ b/tests/death-jump.log @@ -1,4 +1,6 @@ ## Jump into a pit and die, refuse reincarnation +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 in diff --git a/tests/defeat.log b/tests/defeat.log index c42430a..a09858c 100644 --- a/tests/defeat.log +++ b/tests/defeat.log @@ -1,4 +1,6 @@ ## Last-minute defeat, with lava. Also tests vase drop before pillow. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1838473132 diff --git a/tests/domefail.log b/tests/domefail.log index df46939..984d659 100644 --- a/tests/domefail.log +++ b/tests/domefail.log @@ -1,4 +1,6 @@ ## Take nugget and fail to climb to the dome +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/dragon_secret5.log b/tests/dragon_secret5.log index 15f3668..1c5213f 100644 --- a/tests/dragon_secret5.log +++ b/tests/dragon_secret5.log @@ -1,4 +1,6 @@ ## Check that dead dragon actually moves its location (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 18084731 in diff --git a/tests/dropcagedbird.log b/tests/dropcagedbird.log index c7adca1..299e6b0 100644 --- a/tests/dropcagedbird.log +++ b/tests/dropcagedbird.log @@ -1,4 +1,6 @@ ## Try to carry the bird after freeing it instead of listening +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 in diff --git a/tests/drown.log b/tests/drown.log index b5ebf27..4089b60 100644 --- a/tests/drown.log +++ b/tests/drown.log @@ -1,4 +1,6 @@ ## Speak a magic word at an inopportune time and drown. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1838473132 diff --git a/tests/dwarf.log b/tests/dwarf.log index 3bb0d4b..38054e8 100644 --- a/tests/dwarf.log +++ b/tests/dwarf.log @@ -1,4 +1,6 @@ ## In which the dwarf kills you +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1494912171 in diff --git a/tests/dwarf_alternative.log b/tests/dwarf_alternative.log index 590cb59..28d9f93 100644 --- a/tests/dwarf_alternative.log +++ b/tests/dwarf_alternative.log @@ -1,4 +1,6 @@ ## Check that dwarf spawns in alternative location (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 383847 in diff --git a/tests/eggs_done.log b/tests/eggs_done.log index 2384789..4aef5b5 100644 --- a/tests/eggs_done.log +++ b/tests/eggs_done.log @@ -1,4 +1,6 @@ ## Be done with Giant Room and eggs (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/eggs_vanish.log b/tests/eggs_vanish.log index b14fb72..97ba790 100644 --- a/tests/eggs_vanish.log +++ b/tests/eggs_vanish.log @@ -1,4 +1,6 @@ ## Vanishing eggs in Giant Room (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/endgame428.log b/tests/endgame428.log index 8df0238..04130d5 100644 --- a/tests/endgame428.log +++ b/tests/endgame428.log @@ -1,4 +1,6 @@ ## 428-point walkthrough +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1838473132 diff --git a/tests/endobjects.log b/tests/endobjects.log index 96e9fd8..63d98a8 100644 --- a/tests/endobjects.log +++ b/tests/endobjects.log @@ -1,4 +1,6 @@ ### Check that water is unavailable in endgame +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Addresses GitLab issue #55: in endgame, some object starting states are incorrect #NOCOMPARE Bird was not weightless in cage in advent430, this test depends on that. no diff --git a/tests/fail_hint_maze.log b/tests/fail_hint_maze.log index d458561..ce429fe 100644 --- a/tests/fail_hint_maze.log +++ b/tests/fail_hint_maze.log @@ -1,4 +1,6 @@ ## Fail to get maze hint by being empty-handed (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 25508795 in diff --git a/tests/fail_hint_ogre.log b/tests/fail_hint_ogre.log index f75fd79..9623c1e 100644 --- a/tests/fail_hint_ogre.log +++ b/tests/fail_hint_ogre.log @@ -1,4 +1,6 @@ ## Qualify for ogre hint but fail due to dwarves dead (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Fails due uninteresting difference in whitespace process. n seed 1838473132 diff --git a/tests/fail_hint_ogre2.log b/tests/fail_hint_ogre2.log index 4961479..89c294a 100644 --- a/tests/fail_hint_ogre2.log +++ b/tests/fail_hint_ogre2.log @@ -1,4 +1,6 @@ ## Qualify for ogre hint but fail due to nearby dwarf (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 25508795 in diff --git a/tests/fail_hint_woods.log b/tests/fail_hint_woods.log index 3df72f4..455c715 100644 --- a/tests/fail_hint_woods.log +++ b/tests/fail_hint_woods.log @@ -1,4 +1,6 @@ ## Fail getting wood hint by finding appendage (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n n z diff --git a/tests/fillfail.log b/tests/fillfail.log index afb125f..503992b 100644 --- a/tests/fillfail.log +++ b/tests/fillfail.log @@ -1,4 +1,6 @@ ## Attempt to fill lamp, attempt to fill bottle with no source +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n in carry lamp diff --git a/tests/fillvase.log b/tests/fillvase.log index 8414f14..babbf9f 100644 --- a/tests/fillvase.log +++ b/tests/fillvase.log @@ -1,4 +1,6 @@ ## Fill the vase +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Arthur O'Dwyer writes: # # (4) Lastly, here's a test case for you! Go get the VASE; then get the diff --git a/tests/flyback.log b/tests/flyback.log index d0db54b..e661942 100644 --- a/tests/flyback.log +++ b/tests/flyback.log @@ -1,4 +1,6 @@ ## Test fix for issue 51: rug flying is broken +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a bug fix. n seed 1838473132 diff --git a/tests/footslip.log b/tests/footslip.log index ad02244..398027a 100644 --- a/tests/footslip.log +++ b/tests/footslip.log @@ -1,4 +1,6 @@ ## Coverage of LOC_FOOTSLIP +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/gemstates.log b/tests/gemstates.log index ea49416..9daaa6b 100644 --- a/tests/gemstates.log +++ b/tests/gemstates.log @@ -1,4 +1,6 @@ ## Observe amber, ruby, sapphire after state change +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 in diff --git a/tests/goback.log b/tests/goback.log index 490ed7a..ea6c87c 100644 --- a/tests/goback.log +++ b/tests/goback.log @@ -1,4 +1,6 @@ ## Test many nonlethal failure conditions +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # This variant elicits the prompt to go back for batteries # See comments in this log #NOCOMPARE Relies on "waste" diff --git a/tests/hint_dark.log b/tests/hint_dark.log index ddc9bc9..456f33c 100644 --- a/tests/hint_dark.log +++ b/tests/hint_dark.log @@ -1,4 +1,6 @@ ## Elicit hint for dealing with plugh room and darkness (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 in diff --git a/tests/hint_grate.log b/tests/hint_grate.log index e7ddd73..f13b03f 100644 --- a/tests/hint_grate.log +++ b/tests/hint_grate.log @@ -1,4 +1,6 @@ ## Elicit hint for dealing with grate +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 in diff --git a/tests/hint_jade.log b/tests/hint_jade.log index 58a44fe..9fdac24 100644 --- a/tests/hint_jade.log +++ b/tests/hint_jade.log @@ -1,4 +1,6 @@ ## Elicit hint for getting the jade (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/hint_snake.log b/tests/hint_snake.log index 9ffc302..169b2b5 100644 --- a/tests/hint_snake.log +++ b/tests/hint_snake.log @@ -1,4 +1,6 @@ ## Elicit hint for dealing with snake +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 in diff --git a/tests/hint_urn.log b/tests/hint_urn.log index 926bc7d..ed5a8aa 100644 --- a/tests/hint_urn.log +++ b/tests/hint_urn.log @@ -1,4 +1,6 @@ ## Elicit hint for dealing with urn (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Policy decision - no point in emulating advent430's extra \n here n seed 1495951709 diff --git a/tests/hint_witt.log b/tests/hint_witt.log index 6127dd5..c657f16 100644 --- a/tests/hint_witt.log +++ b/tests/hint_witt.log @@ -1,4 +1,6 @@ ## Hint for Witt's End +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Policy decision - no point in emulating advent430's extra \n here n seed 1635997320 diff --git a/tests/illformed.log b/tests/illformed.log index db4d1a5..3e5d6a2 100644 --- a/tests/illformed.log +++ b/tests/illformed.log @@ -1,4 +1,6 @@ ## Test for various cases not found in walkthroughs. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE This is busted under advent430 -- see comments within. foo diff --git a/tests/illformed2.log b/tests/illformed2.log index 99c9c80..4685861 100644 --- a/tests/illformed2.log +++ b/tests/illformed2.log @@ -1,4 +1,6 @@ ## Test for various cases not found in walkthroughs (advent430-compatible). +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Commented-out lines cause troble in advent430 n seed 1635997320 diff --git a/tests/intransitivecarry.log b/tests/intransitivecarry.log index 640a296..ee81196 100644 --- a/tests/intransitivecarry.log +++ b/tests/intransitivecarry.log @@ -1,4 +1,6 @@ ## Carry when only one object is present +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n in carry lamp diff --git a/tests/issue36.log b/tests/issue36.log index cab1d04..8176d4d 100644 --- a/tests/issue36.log +++ b/tests/issue36.log @@ -1,4 +1,6 @@ ## Test handling of object after transitive verb. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 826186526 in diff --git a/tests/issue37.log b/tests/issue37.log index ded6a10..b9caafe 100644 --- a/tests/issue37.log +++ b/tests/issue37.log @@ -1,4 +1,6 @@ ## Test handling of transitive verb after noun +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n in food diff --git a/tests/lampdim.log b/tests/lampdim.log index fe4fc4e..54d95d9 100644 --- a/tests/lampdim.log +++ b/tests/lampdim.log @@ -1,4 +1,6 @@ ## Test the case where your lamp goes dim +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/lampdim2.log b/tests/lampdim2.log index 14a615e..6771c36 100644 --- a/tests/lampdim2.log +++ b/tests/lampdim2.log @@ -1,4 +1,6 @@ ## Try (and fail) to carry message at vending machine +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/lampdim3.log b/tests/lampdim3.log index 18f7e47..37282e5 100644 --- a/tests/lampdim3.log +++ b/tests/lampdim3.log @@ -1,4 +1,6 @@ ## Die while closing +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/listen.log b/tests/listen.log index 135fdbc..e58c687 100644 --- a/tests/listen.log +++ b/tests/listen.log @@ -1,4 +1,6 @@ ## Check that listen command hears all objects as well as location sound +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause no seed 1181530211 e diff --git a/tests/listenloud.log b/tests/listenloud.log index 3e820e4..81dfcf3 100644 --- a/tests/listenloud.log +++ b/tests/listenloud.log @@ -1,4 +1,6 @@ ## Attempt to listen at a loud location +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1495951709 @@ -139,4 +141,4 @@ u reservoir Q'IBJ n -listen \ No newline at end of file +listen diff --git a/tests/lockchain.log b/tests/lockchain.log index bf9cd99..9d2c0e2 100644 --- a/tests/lockchain.log +++ b/tests/lockchain.log @@ -1,4 +1,6 @@ ## Test multiple re-locking and unlocking of bear's chain +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1635997320 diff --git a/tests/logopt.log b/tests/logopt.log index 5074144..74ba48a 100644 --- a/tests/logopt.log +++ b/tests/logopt.log @@ -1,4 +1,6 @@ ## Exercise logging option and seed dump +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #options: -l scratch.tmp n in diff --git a/tests/magicwords.log b/tests/magicwords.log index 4b86370..f99a66b 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -1,4 +1,6 @@ ## Test processing of variuus fee fie foe foo fum cases. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # # How thry're supposed to work: # diff --git a/tests/mazealldiff.log b/tests/mazealldiff.log index d129c13..a13a372 100644 --- a/tests/mazealldiff.log +++ b/tests/mazealldiff.log @@ -1,4 +1,6 @@ ## Coverage of all LOC_DIFFERENT* +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/mazehint.log b/tests/mazehint.log index 454b4f9..cf7ef02 100644 --- a/tests/mazehint.log +++ b/tests/mazehint.log @@ -1,4 +1,6 @@ ## Elicit the maze hint. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 in diff --git a/tests/multifile.chk b/tests/multifile.chk index ab4b57d..3e845b3 100644 --- a/tests/multifile.chk +++ b/tests/multifile.chk @@ -2,6 +2,8 @@ Welcome to Adventure!! Would you like instructions? > ## Test handling of object after transitive verb. +> # SPDX-FileCopyrightText: Eric S. Raymond +> # SPDX-License-Identifier: BSD-2-Clause > n > n diff --git a/tests/notrident.log b/tests/notrident.log index e51a325..fecef2a 100644 --- a/tests/notrident.log +++ b/tests/notrident.log @@ -1,4 +1,6 @@ ## Try to open clam without trident and fail +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 in diff --git a/tests/ogre_no_dwarves.log b/tests/ogre_no_dwarves.log index fe51b51..62f6576 100644 --- a/tests/ogre_no_dwarves.log +++ b/tests/ogre_no_dwarves.log @@ -1,4 +1,6 @@ ## Try to attack ogre with no dwarves present (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 25508795 in diff --git a/tests/ogrehint.log b/tests/ogrehint.log index 12a9d02..18b8977 100644 --- a/tests/ogrehint.log +++ b/tests/ogrehint.log @@ -1,4 +1,6 @@ ## Elicit the ogre hint. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 437547289 seed 1071883378 diff --git a/tests/oilplant.log b/tests/oilplant.log index 35eab35..b29408b 100644 --- a/tests/oilplant.log +++ b/tests/oilplant.log @@ -1,4 +1,6 @@ ## Attempt to oil the beanstalk after watering it +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/oldstyle.log b/tests/oldstyle.log index 4711df0..f82e847 100644 --- a/tests/oldstyle.log +++ b/tests/oldstyle.log @@ -1,4 +1,6 @@ ## Simple quit +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #options: -o #NOCOMPARE Comment not interpreted by advent430 n diff --git a/tests/outcheck.sh b/tests/outcheck.sh index e46979f..c88b8ba 100755 --- a/tests/outcheck.sh +++ b/tests/outcheck.sh @@ -1,4 +1,6 @@ #! /bin/sh +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause case $? in 0) echo "ok - $1 succeeded";; *) echo "not ok - $1 failed";; diff --git a/tests/oysterbug.log b/tests/oysterbug.log index 0310c97..c7392d5 100644 --- a/tests/oysterbug.log +++ b/tests/oysterbug.log @@ -1,4 +1,6 @@ # Demonstrate fix of buggy response to unlocking oyster while carrying it. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE This fails due to a known bug in advent430 n seed 1838473132 diff --git a/tests/panic.log b/tests/panic.log index de6f2c5..b2701be 100644 --- a/tests/panic.log +++ b/tests/panic.log @@ -1,4 +1,6 @@ ## Panic test - attempt to unlock grate after game closed. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/panic2.log b/tests/panic2.log index f95aa5b..53324a6 100644 --- a/tests/panic2.log +++ b/tests/panic2.log @@ -1,4 +1,6 @@ ## Panic test - attempt to xyzzy out after game is closed. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/pirate_carry.log b/tests/pirate_carry.log index 0ba55c4..c4feadb 100644 --- a/tests/pirate_carry.log +++ b/tests/pirate_carry.log @@ -1,4 +1,6 @@ ## Check that pirate steals loose treasure from ground (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1837473132 in diff --git a/tests/pirate_pyramid.log b/tests/pirate_pyramid.log index 1d16702..1c3a858 100644 --- a/tests/pirate_pyramid.log +++ b/tests/pirate_pyramid.log @@ -1,4 +1,6 @@ ## Pirate mustn't take pyramid from plover/dark rooms (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1830473132 in diff --git a/tests/pirate_spotted.log b/tests/pirate_spotted.log index 0c6512a..3b6269a 100644 --- a/tests/pirate_spotted.log +++ b/tests/pirate_spotted.log @@ -1,4 +1,6 @@ ## Spot pirate to manifest chest before last treasure (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/pitfall.log b/tests/pitfall.log index 6532713..85dec35 100644 --- a/tests/pitfall.log +++ b/tests/pitfall.log @@ -1,4 +1,6 @@ ## Death by pitfall +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Die 3 times so we can cover all the obituary messages n seed 780351908 diff --git a/tests/plover.log b/tests/plover.log index 740ed16..cdba74c 100644 --- a/tests/plover.log +++ b/tests/plover.log @@ -1,4 +1,6 @@ ## Test access to emerald room and plover teleport +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1495951709 diff --git a/tests/reach_ledge_short.log b/tests/reach_ledge_short.log index a0acfc6..2952898 100644 --- a/tests/reach_ledge_short.log +++ b/tests/reach_ledge_short.log @@ -1,4 +1,6 @@ ## LOC_NOCLIMB.short (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/reach_noclimb.log b/tests/reach_noclimb.log index 59768ea..e32e28d 100644 --- a/tests/reach_noclimb.log +++ b/tests/reach_noclimb.log @@ -1,4 +1,6 @@ ## LOC_NOCLIMB (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/reach_planttop.log b/tests/reach_planttop.log index 730ea1b..6614da1 100644 --- a/tests/reach_planttop.log +++ b/tests/reach_planttop.log @@ -1,4 +1,6 @@ ## LOC_PLANTTOP (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/reincarnate.log b/tests/reincarnate.log index 39be5dd..1b76b44 100644 --- a/tests/reincarnate.log +++ b/tests/reincarnate.log @@ -1,4 +1,6 @@ ## Jump into a pit and die, then be reincarnated +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 in diff --git a/tests/resumefail.log b/tests/resumefail.log index e7944ef..7f661da 100644 --- a/tests/resumefail.log +++ b/tests/resumefail.log @@ -1,4 +1,6 @@ ## Resume from invalid filename +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE advent430 crashes on resume from invalid filename and we don't care. n seed 1240742801 diff --git a/tests/resumefail2.log b/tests/resumefail2.log index 7aaac36..fa4e063 100644 --- a/tests/resumefail2.log +++ b/tests/resumefail2.log @@ -1,4 +1,6 @@ ## Resume from from generated save with version mismatch error +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Reveals a bug in advent430 handling of saves with invalid versions. n resume diff --git a/tests/savefail.log b/tests/savefail.log index c598d19..c9f489e 100644 --- a/tests/savefail.log +++ b/tests/savefail.log @@ -1,4 +1,6 @@ ## Save right after starting to invalid filename +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE advent430 crashes on save to invalid filename and we don't care. n seed 1240742801 diff --git a/tests/saveresume.1.log b/tests/saveresume.1.log index 45945ce..bf97407 100644 --- a/tests/saveresume.1.log +++ b/tests/saveresume.1.log @@ -1,4 +1,6 @@ ## Save right after starting +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n seed 1240742801 diff --git a/tests/saveresume.2.log b/tests/saveresume.2.log index 71db28c..d995289 100644 --- a/tests/saveresume.2.log +++ b/tests/saveresume.2.log @@ -1,4 +1,6 @@ ## Resume and then quit +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n in diff --git a/tests/saveresume.3.log b/tests/saveresume.3.log index fd7be6f..29ea76b 100644 --- a/tests/saveresume.3.log +++ b/tests/saveresume.3.log @@ -1,4 +1,6 @@ ## Almost win, then save +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 #NOCOMPARE Seems to reveal a bug in advent430's save function. n diff --git a/tests/saveresume.4.log b/tests/saveresume.4.log index 883d098..c419410 100644 --- a/tests/saveresume.4.log +++ b/tests/saveresume.4.log @@ -1,4 +1,6 @@ ## Resume, then win +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Here to get class threshold of 426 # Note, savefile name has trailing space #NOCOMPARE Reveals that advent430 does not resume in endgame gracefully. diff --git a/tests/saveresumeopt.log b/tests/saveresumeopt.log index f5256c2..f776e68 100644 --- a/tests/saveresumeopt.log +++ b/tests/saveresumeopt.log @@ -1,3 +1,5 @@ ## Simple quit +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE New feature, -r option #options: -r saveresume.adv diff --git a/tests/savetamper.log b/tests/savetamper.log index 0396e99..31146c1 100644 --- a/tests/savetamper.log +++ b/tests/savetamper.log @@ -1,4 +1,6 @@ ## Resume from artificial "corrupted" save +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n resume diff --git a/tests/snake_food.log b/tests/snake_food.log index 4950277..015f0eb 100644 --- a/tests/snake_food.log +++ b/tests/snake_food.log @@ -1,4 +1,6 @@ ## Snake must vocally eat bird +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 in diff --git a/tests/softroom.log b/tests/softroom.log index b6b60e7..125f2a3 100644 --- a/tests/softroom.log +++ b/tests/softroom.log @@ -1,4 +1,6 @@ ## Drop vase in soft room after pillow removed +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Verify that the vase does not break n seed 1838473132 diff --git a/tests/specials.log b/tests/specials.log index 4784faf..3cf9c5c 100644 --- a/tests/specials.log +++ b/tests/specials.log @@ -1,4 +1,6 @@ ## Test special words +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE The news text has changed n thank diff --git a/tests/splatter.log b/tests/splatter.log index 2408bcd..8c718d9 100644 --- a/tests/splatter.log +++ b/tests/splatter.log @@ -1,4 +1,6 @@ ## Adventurer fall down go boom. Also tests 'say' verb on magic words. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1838473132 diff --git a/tests/takebird.log b/tests/takebird.log index b2f5f70..279d9e9 100644 --- a/tests/takebird.log +++ b/tests/takebird.log @@ -1,4 +1,6 @@ ## Verify that bird starts caged in endgame +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause no seed 1318612053 e diff --git a/tests/tall.log b/tests/tall.log index eaebfad..1ca79c8 100644 --- a/tests/tall.log +++ b/tests/tall.log @@ -1,4 +1,6 @@ ## Coverage of LOC_TALL, LOC_WIDEPLACE, LOC_TIGHTPLACE +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/tapdiffer b/tests/tapdiffer index f48bcc3..98df500 100755 --- a/tests/tapdiffer +++ b/tests/tapdiffer @@ -1,4 +1,6 @@ #! /bin/sh +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # # tapdiffer - Render diff between input and checkfile as a TAP report # diff --git a/tests/tapview b/tests/tapview index ca984eb..ee3ec50 100755 --- a/tests/tapview +++ b/tests/tapview @@ -1,14 +1,13 @@ #! /bin/sh # tapview - a TAP (Test Anything Protocol) viewer in pure POSIX shell # -# Copyright by Eric S. Raymond -# # This code is intended to be embedded in your project. The author # grants permission for it to be distributed under the prevailing # license of your project if you choose, provided that license is # OSD-compliant; otherwise the following SPDX tag incorporates a # license by reference. # +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # This is version 1.6 diff --git a/tests/trident.log b/tests/trident.log index 871834a..f3c5073 100644 --- a/tests/trident.log +++ b/tests/trident.log @@ -1,4 +1,6 @@ ## 161-point run to pirate appearance and death by dwarf +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1071883378 diff --git a/tests/troll_returns.log b/tests/troll_returns.log index 2697faf..c8d9a25 100644 --- a/tests/troll_returns.log +++ b/tests/troll_returns.log @@ -1,4 +1,6 @@ ## See that troll returns if we stole his eggs before crossing +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/turnpenalties.log b/tests/turnpenalties.log index 2cd3c9e..04c87e5 100644 --- a/tests/turnpenalties.log +++ b/tests/turnpenalties.log @@ -1,4 +1,6 @@ ## check that the turn count penalties occur +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 in diff --git a/tests/urntest.log b/tests/urntest.log index a02d663..97b8ee1 100644 --- a/tests/urntest.log +++ b/tests/urntest.log @@ -1,4 +1,6 @@ ## Test verbs on urn +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/urntest2.log b/tests/urntest2.log index e0c3a6b..87daa80 100644 --- a/tests/urntest2.log +++ b/tests/urntest2.log @@ -1,4 +1,6 @@ ## Test filling urn when you have no bottle +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Also, try to lock door after oiling it n seed 1838473132 diff --git a/tests/urntest3.log b/tests/urntest3.log index a835588..a095fa5 100644 --- a/tests/urntest3.log +++ b/tests/urntest3.log @@ -1,4 +1,6 @@ ## Test filling urn twice. Also, try to lock door after oiling it. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/vending.log b/tests/vending.log index 883a3c7..c78b276 100644 --- a/tests/vending.log +++ b/tests/vending.log @@ -1,4 +1,6 @@ ## Get batteries from the vending machine +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 in diff --git a/tests/wakedwarves.log b/tests/wakedwarves.log index d733fb9..63dfe50 100644 --- a/tests/wakedwarves.log +++ b/tests/wakedwarves.log @@ -1,4 +1,6 @@ ## Wake the dwarves and die. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/wakedwarves2.log b/tests/wakedwarves2.log index adf737e..4d8986b 100644 --- a/tests/wakedwarves2.log +++ b/tests/wakedwarves2.log @@ -1,4 +1,6 @@ ## Wake the dwarves by waving rod and die. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/wakedwarves3.log b/tests/wakedwarves3.log index e04669b..c21a71e 100644 --- a/tests/wakedwarves3.log +++ b/tests/wakedwarves3.log @@ -1,4 +1,6 @@ ## Wake the dwarves by attacking one and die. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 in diff --git a/tests/water_plant2.log b/tests/water_plant2.log index 4f39d8f..6c53d30 100644 --- a/tests/water_plant2.log +++ b/tests/water_plant2.log @@ -1,4 +1,6 @@ ## Check that pour correctly switches among plant states (fuzzed) +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a parser bug fix. n seed 183847312 diff --git a/tests/weirdbird.log b/tests/weirdbird.log index 37f4a36..b6c1457 100644 --- a/tests/weirdbird.log +++ b/tests/weirdbird.log @@ -1,4 +1,6 @@ ## Do pointless things to the bird to test odd cases. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 694608006 in diff --git a/tests/weirddwarf.log b/tests/weirddwarf.log index b7af3a0..7d22d1e 100644 --- a/tests/weirddwarf.log +++ b/tests/weirddwarf.log @@ -1,4 +1,6 @@ ## Exercise various verbs on a dwarf +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 in diff --git a/tests/win430.log b/tests/win430.log index c989c53..efcbd76 100644 --- a/tests/win430.log +++ b/tests/win430.log @@ -1,4 +1,6 @@ ## Ryan Sarson's 430-point win. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause no seed 1318612053 e diff --git a/tests/wittsend.log b/tests/wittsend.log index 580f7c8..5657f35 100644 --- a/tests/wittsend.log +++ b/tests/wittsend.log @@ -1,4 +1,6 @@ ## 342-point run to Witt's End and plover room. +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n seed 1635997320 diff --git a/tests/woodshint.log b/tests/woodshint.log index 6052028..fadef1a 100644 --- a/tests/woodshint.log +++ b/tests/woodshint.log @@ -1,4 +1,6 @@ ## Test hinting logic - elicit forest hint +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a parser bug fix. # Also some tests of intransitive-verb cases n From 6ebc2bf0e3043f23563e4c8eb90e2a8af7d8b2c8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Apr 2023 11:10:03 -0400 Subject: [PATCH 091/213] Documentation fix. --- tests/README | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/README b/tests/README index 1118056..d84dfd4 100644 --- a/tests/README +++ b/tests/README @@ -17,9 +17,9 @@ To see summary lines from all tests, 'make testlist'. The summary lines are those led with ##; you should have one such descriptive line at the head of each file. -To run the tests, "make regress". +To run the tests, "make check". -To remake the check files, "make buildregress". +To remake the check files, "make buildchecks". == Composing tests == @@ -29,12 +29,8 @@ option giving a log path. Commands will be captured to that log. To re-use a command sequence from an existing log, run advent and paste it to the advent command log from the clipboard. -To see where we can use more tests, have a look at our test coverage -report: +To see where we can use more tests, "make coverage". -http://esr.gitlab.io/open-adventure/coverage/ - -Improvements in test coverage are always welcome. // end From ec1d99f354c91eb13d414594470a26dd60dc85bf Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Apr 2023 11:36:20 -0400 Subject: [PATCH 092/213] Commenting fix. --- .shipper | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.shipper b/.shipper index 4127e0c..d3ed58d 100644 --- a/.shipper +++ b/.shipper @@ -1,7 +1,5 @@ -<-- -SPDX-FileCopyrightText: Eric S. Raymond -SPDX-License-Identifier: BSD-2-Clause ---> +#SPDX-FileCopyrightText: Eric S. Raymond +#SPDX-License-Identifier: BSD-2-Clause extralines="""

There is a code coverage analysis and a symbol coverage analysis

""" From 642b7e48903657edba509c3fc219f146b1351941 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Apr 2023 11:34:58 -0400 Subject: [PATCH 093/213] Ready to ship 1.15. --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 3692be2..90c848e 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ = Open Adventure project news = -Repository head:: +1.15: 2023-04-03:: Commands in magic-word sequence now interrupt it, as in original. Bug fix for bird not starting caged in endgame. From 1ce4fc2ac3d3bd09996ea342311ad141e56f343d Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Apr 2023 17:05:01 -0400 Subject: [PATCH 094/213] Improve copyright lines. --- Dockerfile.ci | 2 +- Makefile | 2 +- advent.desktop | 2 +- adventure.yaml | 2 +- make_dungeon.py | 2 +- make_graph.py | 2 +- templates/coverage_dungeon.html.tpl | 2 +- templates/dungeon.c.tpl | 2 +- templates/dungeon.h.tpl | 2 +- tests/Makefile | 2 +- tests/axebear.log | 2 +- tests/axeorama.log | 2 +- tests/barehands.log | 2 +- tests/bigfail.log | 2 +- tests/birdsnakewake.log | 2 +- tests/birdweight.log | 2 +- tests/boulder2.log | 2 +- tests/breakmirror.log | 2 +- tests/carrybird.log | 2 +- tests/carryfreebird.log | 2 +- tests/cheatresume.log | 2 +- tests/cheatresume2.log | 2 +- tests/coverage_dungeon.py | 2 +- tests/death-jump.log | 2 +- tests/defeat.log | 2 +- tests/domefail.log | 2 +- tests/dragon_secret5.log | 2 +- tests/dropcagedbird.log | 2 +- tests/drown.log | 2 +- tests/dwarf.log | 2 +- tests/dwarf_alternative.log | 2 +- tests/eggs_done.log | 2 +- tests/eggs_vanish.log | 2 +- tests/endgame428.log | 2 +- tests/endobjects.log | 2 +- tests/fail_hint_maze.log | 2 +- tests/fail_hint_ogre.log | 2 +- tests/fail_hint_ogre2.log | 2 +- tests/fail_hint_woods.log | 2 +- tests/fillfail.log | 2 +- tests/fillvase.log | 2 +- tests/flyback.log | 2 +- tests/footslip.log | 2 +- tests/gemstates.log | 2 +- tests/goback.log | 2 +- tests/hint_dark.log | 2 +- tests/hint_grate.log | 2 +- tests/hint_jade.log | 2 +- tests/hint_snake.log | 2 +- tests/hint_urn.log | 2 +- tests/hint_witt.log | 2 +- tests/illformed.log | 2 +- tests/illformed2.log | 2 +- tests/intransitivecarry.log | 2 +- tests/issue36.log | 2 +- tests/issue37.log | 2 +- tests/lampdim.log | 2 +- tests/lampdim2.log | 2 +- tests/lampdim3.log | 2 +- tests/listen.log | 2 +- tests/listenloud.log | 2 +- tests/lockchain.log | 2 +- tests/logopt.log | 2 +- tests/magicwords.log | 2 +- tests/mazealldiff.log | 2 +- tests/mazehint.log | 2 +- tests/multifile.chk | 2 +- tests/notrident.log | 2 +- tests/ogre_no_dwarves.log | 2 +- tests/ogrehint.log | 2 +- tests/oilplant.log | 2 +- tests/oldstyle.log | 2 +- tests/outcheck.sh | 2 +- tests/oysterbug.log | 2 +- tests/panic.log | 2 +- tests/panic2.log | 2 +- tests/pirate_carry.log | 2 +- tests/pirate_pyramid.log | 2 +- tests/pirate_spotted.log | 2 +- tests/pitfall.log | 2 +- tests/plover.log | 2 +- tests/reach_ledge_short.log | 2 +- tests/reach_noclimb.log | 2 +- tests/reach_planttop.log | 2 +- tests/reincarnate.log | 2 +- tests/resumefail.log | 2 +- tests/resumefail2.log | 2 +- tests/savefail.log | 2 +- tests/saveresume.1.log | 2 +- tests/saveresume.2.log | 2 +- tests/saveresume.3.log | 2 +- tests/saveresume.4.log | 2 +- tests/saveresumeopt.log | 2 +- tests/savetamper.log | 2 +- tests/snake_food.log | 2 +- tests/softroom.log | 2 +- tests/specials.log | 2 +- tests/splatter.log | 2 +- tests/takebird.log | 2 +- tests/tall.log | 2 +- tests/tapdiffer | 2 +- tests/tapview | 2 +- tests/trident.log | 2 +- tests/troll_returns.log | 2 +- tests/turnpenalties.log | 2 +- tests/urntest.log | 2 +- tests/urntest2.log | 2 +- tests/urntest3.log | 2 +- tests/vending.log | 2 +- tests/wakedwarves.log | 2 +- tests/wakedwarves2.log | 2 +- tests/wakedwarves3.log | 2 +- tests/water_plant2.log | 2 +- tests/weirdbird.log | 2 +- tests/weirddwarf.log | 2 +- tests/win430.log | 2 +- tests/wittsend.log | 2 +- tests/woodshint.log | 2 +- 118 files changed, 118 insertions(+), 118 deletions(-) diff --git a/Dockerfile.ci b/Dockerfile.ci index 8a2c8bb..e67cd1f 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,6 +1,6 @@ # This image is built by the Gitlab CI pipeline to be used in subsequent # pipeline steps. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause FROM ubuntu diff --git a/Makefile b/Makefile index d6ceb82..003935d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Makefile for the open-source release of adventure 2.5 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # To build with save/resume disabled, pass CFLAGS="-DADVENT_NOSAVE" diff --git a/advent.desktop b/advent.desktop index bb049de..fdc2f26 100644 --- a/advent.desktop +++ b/advent.desktop @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause [Desktop Entry] Type=Application diff --git a/adventure.yaml b/adventure.yaml index 791d8ac..c9827df 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # This YAML file gets processed into a collection of data structures and diff --git a/make_dungeon.py b/make_dungeon.py index 0d224d3..a9193b6 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """ This is the open-adventure dungeon generator. It consumes a YAML description of diff --git a/make_graph.py b/make_graph.py index edaaa6f..63e440a 100755 --- a/make_graph.py +++ b/make_graph.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """\ usage: make-graph.py [-a] -d] [-m] [-s] diff --git a/templates/coverage_dungeon.html.tpl b/templates/coverage_dungeon.html.tpl index 9545ca2..164473e 100644 --- a/templates/coverage_dungeon.html.tpl +++ b/templates/coverage_dungeon.html.tpl @@ -1,5 +1,5 @@ <-- -SPDX-FileCopyrightText: Eric S. Raymond +SPDX-FileCopyrightText: Eric S. Raymond SPDX-License-Identifier: BSD-2-Clause --> diff --git a/templates/dungeon.c.tpl b/templates/dungeon.c.tpl index 25f4d26..d1604a5 100644 --- a/templates/dungeon.c.tpl +++ b/templates/dungeon.c.tpl @@ -1,5 +1,5 @@ /* -SPDX-FileCopyrightText: Eric S. Raymond +SPDX-FileCopyrightText: Eric S. Raymond SPDX-License-Identifier: BSD-2-Clause */ diff --git a/templates/dungeon.h.tpl b/templates/dungeon.h.tpl index 8abb529..ab3d6d7 100644 --- a/templates/dungeon.h.tpl +++ b/templates/dungeon.h.tpl @@ -1,5 +1,5 @@ /* -SPDX-FileCopyrightText: Eric S. Raymond +SPDX-FileCopyrightText: Eric S. Raymond SPDX-License-Identifier: BSD-2-Clause */ #ifndef DUNGEON_H diff --git a/tests/Makefile b/tests/Makefile index a95f464..b49a2f2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,6 @@ # Test-suite makefile for open-adventure -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Use absolute path so tests that change working directory still use diff --git a/tests/axebear.log b/tests/axebear.log index c27ad64..27c0af5 100644 --- a/tests/axebear.log +++ b/tests/axebear.log @@ -1,5 +1,5 @@ ## Observe axe after throwing at bear -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/axeorama.log b/tests/axeorama.log index a3b050c..fd10948 100644 --- a/tests/axeorama.log +++ b/tests/axeorama.log @@ -1,5 +1,5 @@ ## Test throwing axe at non-dwarves. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Added coverage of LOC_DEADCRAWL and CROSS_BRIDGE n diff --git a/tests/barehands.log b/tests/barehands.log index 47559a0..1ad2c32 100644 --- a/tests/barehands.log +++ b/tests/barehands.log @@ -1,5 +1,5 @@ ## Get to dragon, refuse to use bare hands -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Fails due uninteresting difference in whitespace process. # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 diff --git a/tests/bigfail.log b/tests/bigfail.log index e4543b6..ae13163 100644 --- a/tests/bigfail.log +++ b/tests/bigfail.log @@ -1,5 +1,5 @@ ## Test many nonlethal failure conditions -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # See comments in this log n diff --git a/tests/birdsnakewake.log b/tests/birdsnakewake.log index 81e3080..8c2d514 100644 --- a/tests/birdsnakewake.log +++ b/tests/birdsnakewake.log @@ -1,5 +1,5 @@ ## Attempt to kill snake with bird in the endgame -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/birdweight.log b/tests/birdweight.log index 8b56bb4..216979b 100644 --- a/tests/birdweight.log +++ b/tests/birdweight.log @@ -1,5 +1,5 @@ ## Verify that the bird is weightless in inventory -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Checks fix for GitLab issue #40 #NOCOMPARE Bird was not weightless in cage in advent430 so this test is invalid. diff --git a/tests/boulder2.log b/tests/boulder2.log index d2dc120..886e0b9 100644 --- a/tests/boulder2.log +++ b/tests/boulder2.log @@ -1,5 +1,5 @@ ## Coverage of LOC_BOULDERS2.short -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/breakmirror.log b/tests/breakmirror.log index 8254c97..ba73337 100644 --- a/tests/breakmirror.log +++ b/tests/breakmirror.log @@ -1,5 +1,5 @@ ## Break the mirror in endgame and die -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/carrybird.log b/tests/carrybird.log index 42ab656..296a825 100644 --- a/tests/carrybird.log +++ b/tests/carrybird.log @@ -1,5 +1,5 @@ ## Try to carry bird without cage, then kill bird -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 diff --git a/tests/carryfreebird.log b/tests/carryfreebird.log index aa80f69..4867b05 100644 --- a/tests/carryfreebird.log +++ b/tests/carryfreebird.log @@ -1,5 +1,5 @@ ## Try to carry the bird after freeing it instead of listening -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 diff --git a/tests/cheatresume.log b/tests/cheatresume.log index eaa110b..1a0e60e 100644 --- a/tests/cheatresume.log +++ b/tests/cheatresume.log @@ -1,5 +1,5 @@ ## Resume from absurd save file with numdie = -900 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/cheatresume2.log b/tests/cheatresume2.log index f9a69f4..d5d8eee 100644 --- a/tests/cheatresume2.log +++ b/tests/cheatresume2.log @@ -1,5 +1,5 @@ ## Resume from absurd save file with numdie = -1000 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # generating "off my scale" score threshold message #NOCOMPARE Can't compare to advent430 due to version skew diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index 9d01c84..2b4c515 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """ This is the open-adventure dungeon text coverage report generator. It diff --git a/tests/death-jump.log b/tests/death-jump.log index f37b80f..835c02c 100644 --- a/tests/death-jump.log +++ b/tests/death-jump.log @@ -1,5 +1,5 @@ ## Jump into a pit and die, refuse reincarnation -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 diff --git a/tests/defeat.log b/tests/defeat.log index a09858c..b46767d 100644 --- a/tests/defeat.log +++ b/tests/defeat.log @@ -1,5 +1,5 @@ ## Last-minute defeat, with lava. Also tests vase drop before pillow. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/domefail.log b/tests/domefail.log index 984d659..c832fb0 100644 --- a/tests/domefail.log +++ b/tests/domefail.log @@ -1,5 +1,5 @@ ## Take nugget and fail to climb to the dome -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/dragon_secret5.log b/tests/dragon_secret5.log index 1c5213f..a630ccc 100644 --- a/tests/dragon_secret5.log +++ b/tests/dragon_secret5.log @@ -1,5 +1,5 @@ ## Check that dead dragon actually moves its location (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 18084731 diff --git a/tests/dropcagedbird.log b/tests/dropcagedbird.log index 299e6b0..2ca0c99 100644 --- a/tests/dropcagedbird.log +++ b/tests/dropcagedbird.log @@ -1,5 +1,5 @@ ## Try to carry the bird after freeing it instead of listening -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 diff --git a/tests/drown.log b/tests/drown.log index 4089b60..257aeea 100644 --- a/tests/drown.log +++ b/tests/drown.log @@ -1,5 +1,5 @@ ## Speak a magic word at an inopportune time and drown. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/dwarf.log b/tests/dwarf.log index 38054e8..36a225b 100644 --- a/tests/dwarf.log +++ b/tests/dwarf.log @@ -1,5 +1,5 @@ ## In which the dwarf kills you -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1494912171 diff --git a/tests/dwarf_alternative.log b/tests/dwarf_alternative.log index 28d9f93..af0a9c8 100644 --- a/tests/dwarf_alternative.log +++ b/tests/dwarf_alternative.log @@ -1,5 +1,5 @@ ## Check that dwarf spawns in alternative location (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 383847 diff --git a/tests/eggs_done.log b/tests/eggs_done.log index 4aef5b5..451d3e5 100644 --- a/tests/eggs_done.log +++ b/tests/eggs_done.log @@ -1,5 +1,5 @@ ## Be done with Giant Room and eggs (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/eggs_vanish.log b/tests/eggs_vanish.log index 97ba790..7c5f406 100644 --- a/tests/eggs_vanish.log +++ b/tests/eggs_vanish.log @@ -1,5 +1,5 @@ ## Vanishing eggs in Giant Room (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/endgame428.log b/tests/endgame428.log index 04130d5..e86c92d 100644 --- a/tests/endgame428.log +++ b/tests/endgame428.log @@ -1,5 +1,5 @@ ## 428-point walkthrough -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/endobjects.log b/tests/endobjects.log index 63d98a8..1165360 100644 --- a/tests/endobjects.log +++ b/tests/endobjects.log @@ -1,5 +1,5 @@ ### Check that water is unavailable in endgame -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Addresses GitLab issue #55: in endgame, some object starting states are incorrect #NOCOMPARE Bird was not weightless in cage in advent430, this test depends on that. diff --git a/tests/fail_hint_maze.log b/tests/fail_hint_maze.log index ce429fe..409286c 100644 --- a/tests/fail_hint_maze.log +++ b/tests/fail_hint_maze.log @@ -1,5 +1,5 @@ ## Fail to get maze hint by being empty-handed (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 25508795 diff --git a/tests/fail_hint_ogre.log b/tests/fail_hint_ogre.log index 9623c1e..01af475 100644 --- a/tests/fail_hint_ogre.log +++ b/tests/fail_hint_ogre.log @@ -1,5 +1,5 @@ ## Qualify for ogre hint but fail due to dwarves dead (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Fails due uninteresting difference in whitespace process. n diff --git a/tests/fail_hint_ogre2.log b/tests/fail_hint_ogre2.log index 89c294a..9b01049 100644 --- a/tests/fail_hint_ogre2.log +++ b/tests/fail_hint_ogre2.log @@ -1,5 +1,5 @@ ## Qualify for ogre hint but fail due to nearby dwarf (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 25508795 diff --git a/tests/fail_hint_woods.log b/tests/fail_hint_woods.log index 455c715..69d075e 100644 --- a/tests/fail_hint_woods.log +++ b/tests/fail_hint_woods.log @@ -1,5 +1,5 @@ ## Fail getting wood hint by finding appendage (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n n diff --git a/tests/fillfail.log b/tests/fillfail.log index 503992b..543bc27 100644 --- a/tests/fillfail.log +++ b/tests/fillfail.log @@ -1,5 +1,5 @@ ## Attempt to fill lamp, attempt to fill bottle with no source -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n in diff --git a/tests/fillvase.log b/tests/fillvase.log index babbf9f..da776b9 100644 --- a/tests/fillvase.log +++ b/tests/fillvase.log @@ -1,5 +1,5 @@ ## Fill the vase -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Arthur O'Dwyer writes: # diff --git a/tests/flyback.log b/tests/flyback.log index e661942..3c34df4 100644 --- a/tests/flyback.log +++ b/tests/flyback.log @@ -1,5 +1,5 @@ ## Test fix for issue 51: rug flying is broken -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a bug fix. n diff --git a/tests/footslip.log b/tests/footslip.log index 398027a..4f1d7cd 100644 --- a/tests/footslip.log +++ b/tests/footslip.log @@ -1,5 +1,5 @@ ## Coverage of LOC_FOOTSLIP -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/gemstates.log b/tests/gemstates.log index 9daaa6b..6ac1547 100644 --- a/tests/gemstates.log +++ b/tests/gemstates.log @@ -1,5 +1,5 @@ ## Observe amber, ruby, sapphire after state change -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 diff --git a/tests/goback.log b/tests/goback.log index ea6c87c..fcc06c2 100644 --- a/tests/goback.log +++ b/tests/goback.log @@ -1,5 +1,5 @@ ## Test many nonlethal failure conditions -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # This variant elicits the prompt to go back for batteries # See comments in this log diff --git a/tests/hint_dark.log b/tests/hint_dark.log index 456f33c..a45074a 100644 --- a/tests/hint_dark.log +++ b/tests/hint_dark.log @@ -1,5 +1,5 @@ ## Elicit hint for dealing with plugh room and darkness (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 diff --git a/tests/hint_grate.log b/tests/hint_grate.log index f13b03f..8af49de 100644 --- a/tests/hint_grate.log +++ b/tests/hint_grate.log @@ -1,5 +1,5 @@ ## Elicit hint for dealing with grate -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 diff --git a/tests/hint_jade.log b/tests/hint_jade.log index 9fdac24..904aa92 100644 --- a/tests/hint_jade.log +++ b/tests/hint_jade.log @@ -1,5 +1,5 @@ ## Elicit hint for getting the jade (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/hint_snake.log b/tests/hint_snake.log index 169b2b5..76b719b 100644 --- a/tests/hint_snake.log +++ b/tests/hint_snake.log @@ -1,5 +1,5 @@ ## Elicit hint for dealing with snake -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 diff --git a/tests/hint_urn.log b/tests/hint_urn.log index ed5a8aa..d12ceda 100644 --- a/tests/hint_urn.log +++ b/tests/hint_urn.log @@ -1,5 +1,5 @@ ## Elicit hint for dealing with urn (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Policy decision - no point in emulating advent430's extra \n here n diff --git a/tests/hint_witt.log b/tests/hint_witt.log index c657f16..07e0785 100644 --- a/tests/hint_witt.log +++ b/tests/hint_witt.log @@ -1,5 +1,5 @@ ## Hint for Witt's End -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Policy decision - no point in emulating advent430's extra \n here n diff --git a/tests/illformed.log b/tests/illformed.log index 3e5d6a2..0cb22e0 100644 --- a/tests/illformed.log +++ b/tests/illformed.log @@ -1,5 +1,5 @@ ## Test for various cases not found in walkthroughs. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE This is busted under advent430 -- see comments within. foo diff --git a/tests/illformed2.log b/tests/illformed2.log index 4685861..f6193d7 100644 --- a/tests/illformed2.log +++ b/tests/illformed2.log @@ -1,5 +1,5 @@ ## Test for various cases not found in walkthroughs (advent430-compatible). -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Commented-out lines cause troble in advent430 n diff --git a/tests/intransitivecarry.log b/tests/intransitivecarry.log index ee81196..acef62e 100644 --- a/tests/intransitivecarry.log +++ b/tests/intransitivecarry.log @@ -1,5 +1,5 @@ ## Carry when only one object is present -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n in diff --git a/tests/issue36.log b/tests/issue36.log index 8176d4d..fa8ef7f 100644 --- a/tests/issue36.log +++ b/tests/issue36.log @@ -1,5 +1,5 @@ ## Test handling of object after transitive verb. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 826186526 diff --git a/tests/issue37.log b/tests/issue37.log index b9caafe..14afe5e 100644 --- a/tests/issue37.log +++ b/tests/issue37.log @@ -1,5 +1,5 @@ ## Test handling of transitive verb after noun -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n in diff --git a/tests/lampdim.log b/tests/lampdim.log index 54d95d9..514b6a2 100644 --- a/tests/lampdim.log +++ b/tests/lampdim.log @@ -1,5 +1,5 @@ ## Test the case where your lamp goes dim -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/lampdim2.log b/tests/lampdim2.log index 6771c36..3afe71c 100644 --- a/tests/lampdim2.log +++ b/tests/lampdim2.log @@ -1,5 +1,5 @@ ## Try (and fail) to carry message at vending machine -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/lampdim3.log b/tests/lampdim3.log index 37282e5..e944d4e 100644 --- a/tests/lampdim3.log +++ b/tests/lampdim3.log @@ -1,5 +1,5 @@ ## Die while closing -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/listen.log b/tests/listen.log index e58c687..6aa7b97 100644 --- a/tests/listen.log +++ b/tests/listen.log @@ -1,5 +1,5 @@ ## Check that listen command hears all objects as well as location sound -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause no seed 1181530211 diff --git a/tests/listenloud.log b/tests/listenloud.log index 81dfcf3..f0c62fe 100644 --- a/tests/listenloud.log +++ b/tests/listenloud.log @@ -1,5 +1,5 @@ ## Attempt to listen at a loud location -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/lockchain.log b/tests/lockchain.log index 9d2c0e2..f311485 100644 --- a/tests/lockchain.log +++ b/tests/lockchain.log @@ -1,5 +1,5 @@ ## Test multiple re-locking and unlocking of bear's chain -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/logopt.log b/tests/logopt.log index 74ba48a..ee4a860 100644 --- a/tests/logopt.log +++ b/tests/logopt.log @@ -1,5 +1,5 @@ ## Exercise logging option and seed dump -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #options: -l scratch.tmp n diff --git a/tests/magicwords.log b/tests/magicwords.log index f99a66b..7c4deff 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -1,5 +1,5 @@ ## Test processing of variuus fee fie foe foo fum cases. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # How thry're supposed to work: diff --git a/tests/mazealldiff.log b/tests/mazealldiff.log index a13a372..2da3152 100644 --- a/tests/mazealldiff.log +++ b/tests/mazealldiff.log @@ -1,5 +1,5 @@ ## Coverage of all LOC_DIFFERENT* -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/mazehint.log b/tests/mazehint.log index cf7ef02..83ae210 100644 --- a/tests/mazehint.log +++ b/tests/mazehint.log @@ -1,5 +1,5 @@ ## Elicit the maze hint. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 diff --git a/tests/multifile.chk b/tests/multifile.chk index 3e845b3..991ea9c 100644 --- a/tests/multifile.chk +++ b/tests/multifile.chk @@ -2,7 +2,7 @@ Welcome to Adventure!! Would you like instructions? > ## Test handling of object after transitive verb. -> # SPDX-FileCopyrightText: Eric S. Raymond +> # SPDX-FileCopyrightText: Eric S. Raymond > # SPDX-License-Identifier: BSD-2-Clause > n > n diff --git a/tests/notrident.log b/tests/notrident.log index fecef2a..8e649cb 100644 --- a/tests/notrident.log +++ b/tests/notrident.log @@ -1,5 +1,5 @@ ## Try to open clam without trident and fail -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 diff --git a/tests/ogre_no_dwarves.log b/tests/ogre_no_dwarves.log index 62f6576..3ba7102 100644 --- a/tests/ogre_no_dwarves.log +++ b/tests/ogre_no_dwarves.log @@ -1,5 +1,5 @@ ## Try to attack ogre with no dwarves present (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 25508795 diff --git a/tests/ogrehint.log b/tests/ogrehint.log index 18b8977..58a8abf 100644 --- a/tests/ogrehint.log +++ b/tests/ogrehint.log @@ -1,5 +1,5 @@ ## Elicit the ogre hint. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 437547289 diff --git a/tests/oilplant.log b/tests/oilplant.log index b29408b..3174357 100644 --- a/tests/oilplant.log +++ b/tests/oilplant.log @@ -1,5 +1,5 @@ ## Attempt to oil the beanstalk after watering it -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/oldstyle.log b/tests/oldstyle.log index f82e847..a259abd 100644 --- a/tests/oldstyle.log +++ b/tests/oldstyle.log @@ -1,5 +1,5 @@ ## Simple quit -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #options: -o #NOCOMPARE Comment not interpreted by advent430 diff --git a/tests/outcheck.sh b/tests/outcheck.sh index c88b8ba..4dc5b0d 100755 --- a/tests/outcheck.sh +++ b/tests/outcheck.sh @@ -1,5 +1,5 @@ #! /bin/sh -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause case $? in 0) echo "ok - $1 succeeded";; diff --git a/tests/oysterbug.log b/tests/oysterbug.log index c7392d5..58299cc 100644 --- a/tests/oysterbug.log +++ b/tests/oysterbug.log @@ -1,5 +1,5 @@ # Demonstrate fix of buggy response to unlocking oyster while carrying it. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE This fails due to a known bug in advent430 n diff --git a/tests/panic.log b/tests/panic.log index b2701be..155669e 100644 --- a/tests/panic.log +++ b/tests/panic.log @@ -1,5 +1,5 @@ ## Panic test - attempt to unlock grate after game closed. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/panic2.log b/tests/panic2.log index 53324a6..1f70a46 100644 --- a/tests/panic2.log +++ b/tests/panic2.log @@ -1,5 +1,5 @@ ## Panic test - attempt to xyzzy out after game is closed. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/pirate_carry.log b/tests/pirate_carry.log index c4feadb..733d03f 100644 --- a/tests/pirate_carry.log +++ b/tests/pirate_carry.log @@ -1,5 +1,5 @@ ## Check that pirate steals loose treasure from ground (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1837473132 diff --git a/tests/pirate_pyramid.log b/tests/pirate_pyramid.log index 1c3a858..83f7a6d 100644 --- a/tests/pirate_pyramid.log +++ b/tests/pirate_pyramid.log @@ -1,5 +1,5 @@ ## Pirate mustn't take pyramid from plover/dark rooms (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1830473132 diff --git a/tests/pirate_spotted.log b/tests/pirate_spotted.log index 3b6269a..a0ed6f5 100644 --- a/tests/pirate_spotted.log +++ b/tests/pirate_spotted.log @@ -1,5 +1,5 @@ ## Spot pirate to manifest chest before last treasure (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/pitfall.log b/tests/pitfall.log index 85dec35..cd16da9 100644 --- a/tests/pitfall.log +++ b/tests/pitfall.log @@ -1,5 +1,5 @@ ## Death by pitfall -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Die 3 times so we can cover all the obituary messages n diff --git a/tests/plover.log b/tests/plover.log index cdba74c..47d3ec8 100644 --- a/tests/plover.log +++ b/tests/plover.log @@ -1,5 +1,5 @@ ## Test access to emerald room and plover teleport -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/reach_ledge_short.log b/tests/reach_ledge_short.log index 2952898..f53f98d 100644 --- a/tests/reach_ledge_short.log +++ b/tests/reach_ledge_short.log @@ -1,5 +1,5 @@ ## LOC_NOCLIMB.short (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/reach_noclimb.log b/tests/reach_noclimb.log index e32e28d..f3670e6 100644 --- a/tests/reach_noclimb.log +++ b/tests/reach_noclimb.log @@ -1,5 +1,5 @@ ## LOC_NOCLIMB (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/reach_planttop.log b/tests/reach_planttop.log index 6614da1..851c55a 100644 --- a/tests/reach_planttop.log +++ b/tests/reach_planttop.log @@ -1,5 +1,5 @@ ## LOC_PLANTTOP (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/reincarnate.log b/tests/reincarnate.log index 1b76b44..550be2f 100644 --- a/tests/reincarnate.log +++ b/tests/reincarnate.log @@ -1,5 +1,5 @@ ## Jump into a pit and die, then be reincarnated -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 diff --git a/tests/resumefail.log b/tests/resumefail.log index 7f661da..6ca8d49 100644 --- a/tests/resumefail.log +++ b/tests/resumefail.log @@ -1,5 +1,5 @@ ## Resume from invalid filename -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE advent430 crashes on resume from invalid filename and we don't care. n diff --git a/tests/resumefail2.log b/tests/resumefail2.log index fa4e063..973f7c9 100644 --- a/tests/resumefail2.log +++ b/tests/resumefail2.log @@ -1,5 +1,5 @@ ## Resume from from generated save with version mismatch error -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Reveals a bug in advent430 handling of saves with invalid versions. n diff --git a/tests/savefail.log b/tests/savefail.log index c9f489e..d5c5b6e 100644 --- a/tests/savefail.log +++ b/tests/savefail.log @@ -1,5 +1,5 @@ ## Save right after starting to invalid filename -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE advent430 crashes on save to invalid filename and we don't care. n diff --git a/tests/saveresume.1.log b/tests/saveresume.1.log index bf97407..aa74e77 100644 --- a/tests/saveresume.1.log +++ b/tests/saveresume.1.log @@ -1,5 +1,5 @@ ## Save right after starting -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/saveresume.2.log b/tests/saveresume.2.log index d995289..bda1a1e 100644 --- a/tests/saveresume.2.log +++ b/tests/saveresume.2.log @@ -1,5 +1,5 @@ ## Resume and then quit -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/saveresume.3.log b/tests/saveresume.3.log index 29ea76b..7777da0 100644 --- a/tests/saveresume.3.log +++ b/tests/saveresume.3.log @@ -1,5 +1,5 @@ ## Almost win, then save -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 #NOCOMPARE Seems to reveal a bug in advent430's save function. diff --git a/tests/saveresume.4.log b/tests/saveresume.4.log index c419410..1009ea7 100644 --- a/tests/saveresume.4.log +++ b/tests/saveresume.4.log @@ -1,5 +1,5 @@ ## Resume, then win -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Here to get class threshold of 426 # Note, savefile name has trailing space diff --git a/tests/saveresumeopt.log b/tests/saveresumeopt.log index f776e68..e52593d 100644 --- a/tests/saveresumeopt.log +++ b/tests/saveresumeopt.log @@ -1,5 +1,5 @@ ## Simple quit -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE New feature, -r option #options: -r saveresume.adv diff --git a/tests/savetamper.log b/tests/savetamper.log index 31146c1..6662443 100644 --- a/tests/savetamper.log +++ b/tests/savetamper.log @@ -1,5 +1,5 @@ ## Resume from artificial "corrupted" save -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/snake_food.log b/tests/snake_food.log index 015f0eb..843fa0e 100644 --- a/tests/snake_food.log +++ b/tests/snake_food.log @@ -1,5 +1,5 @@ ## Snake must vocally eat bird -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 diff --git a/tests/softroom.log b/tests/softroom.log index 125f2a3..9bb6185 100644 --- a/tests/softroom.log +++ b/tests/softroom.log @@ -1,5 +1,5 @@ ## Drop vase in soft room after pillow removed -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Verify that the vase does not break n diff --git a/tests/specials.log b/tests/specials.log index 3cf9c5c..7900a6c 100644 --- a/tests/specials.log +++ b/tests/specials.log @@ -1,5 +1,5 @@ ## Test special words -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE The news text has changed n diff --git a/tests/splatter.log b/tests/splatter.log index 8c718d9..76df98e 100644 --- a/tests/splatter.log +++ b/tests/splatter.log @@ -1,5 +1,5 @@ ## Adventurer fall down go boom. Also tests 'say' verb on magic words. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/takebird.log b/tests/takebird.log index 279d9e9..557f0ac 100644 --- a/tests/takebird.log +++ b/tests/takebird.log @@ -1,5 +1,5 @@ ## Verify that bird starts caged in endgame -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause no seed 1318612053 diff --git a/tests/tall.log b/tests/tall.log index 1ca79c8..1af372e 100644 --- a/tests/tall.log +++ b/tests/tall.log @@ -1,5 +1,5 @@ ## Coverage of LOC_TALL, LOC_WIDEPLACE, LOC_TIGHTPLACE -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/tapdiffer b/tests/tapdiffer index 98df500..ebf270b 100755 --- a/tests/tapdiffer +++ b/tests/tapdiffer @@ -1,5 +1,5 @@ #! /bin/sh -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # tapdiffer - Render diff between input and checkfile as a TAP report diff --git a/tests/tapview b/tests/tapview index ee3ec50..33216ad 100755 --- a/tests/tapview +++ b/tests/tapview @@ -7,7 +7,7 @@ # OSD-compliant; otherwise the following SPDX tag incorporates a # license by reference. # -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # This is version 1.6 diff --git a/tests/trident.log b/tests/trident.log index f3c5073..bca7e3c 100644 --- a/tests/trident.log +++ b/tests/trident.log @@ -1,5 +1,5 @@ ## 161-point run to pirate appearance and death by dwarf -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/troll_returns.log b/tests/troll_returns.log index c8d9a25..2cbf136 100644 --- a/tests/troll_returns.log +++ b/tests/troll_returns.log @@ -1,5 +1,5 @@ ## See that troll returns if we stole his eggs before crossing -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/turnpenalties.log b/tests/turnpenalties.log index 04c87e5..e4d2df9 100644 --- a/tests/turnpenalties.log +++ b/tests/turnpenalties.log @@ -1,5 +1,5 @@ ## check that the turn count penalties occur -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 diff --git a/tests/urntest.log b/tests/urntest.log index 97b8ee1..b67e61c 100644 --- a/tests/urntest.log +++ b/tests/urntest.log @@ -1,5 +1,5 @@ ## Test verbs on urn -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/urntest2.log b/tests/urntest2.log index 87daa80..0bcbd7e 100644 --- a/tests/urntest2.log +++ b/tests/urntest2.log @@ -1,5 +1,5 @@ ## Test filling urn when you have no bottle -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Also, try to lock door after oiling it n diff --git a/tests/urntest3.log b/tests/urntest3.log index a095fa5..0ec5aab 100644 --- a/tests/urntest3.log +++ b/tests/urntest3.log @@ -1,5 +1,5 @@ ## Test filling urn twice. Also, try to lock door after oiling it. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/vending.log b/tests/vending.log index c78b276..7e33036 100644 --- a/tests/vending.log +++ b/tests/vending.log @@ -1,5 +1,5 @@ ## Get batteries from the vending machine -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 diff --git a/tests/wakedwarves.log b/tests/wakedwarves.log index 63dfe50..2ed3948 100644 --- a/tests/wakedwarves.log +++ b/tests/wakedwarves.log @@ -1,5 +1,5 @@ ## Wake the dwarves and die. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/wakedwarves2.log b/tests/wakedwarves2.log index 4d8986b..d6f91d2 100644 --- a/tests/wakedwarves2.log +++ b/tests/wakedwarves2.log @@ -1,5 +1,5 @@ ## Wake the dwarves by waving rod and die. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/wakedwarves3.log b/tests/wakedwarves3.log index c21a71e..2cbd78e 100644 --- a/tests/wakedwarves3.log +++ b/tests/wakedwarves3.log @@ -1,5 +1,5 @@ ## Wake the dwarves by attacking one and die. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/water_plant2.log b/tests/water_plant2.log index 6c53d30..4a6f489 100644 --- a/tests/water_plant2.log +++ b/tests/water_plant2.log @@ -1,5 +1,5 @@ ## Check that pour correctly switches among plant states (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a parser bug fix. n diff --git a/tests/weirdbird.log b/tests/weirdbird.log index b6c1457..5c48271 100644 --- a/tests/weirdbird.log +++ b/tests/weirdbird.log @@ -1,5 +1,5 @@ ## Do pointless things to the bird to test odd cases. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 694608006 diff --git a/tests/weirddwarf.log b/tests/weirddwarf.log index 7d22d1e..a857eb0 100644 --- a/tests/weirddwarf.log +++ b/tests/weirddwarf.log @@ -1,5 +1,5 @@ ## Exercise various verbs on a dwarf -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 diff --git a/tests/win430.log b/tests/win430.log index efcbd76..beaa8d4 100644 --- a/tests/win430.log +++ b/tests/win430.log @@ -1,5 +1,5 @@ ## Ryan Sarson's 430-point win. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause no seed 1318612053 diff --git a/tests/wittsend.log b/tests/wittsend.log index 5657f35..5ae3ec0 100644 --- a/tests/wittsend.log +++ b/tests/wittsend.log @@ -1,5 +1,5 @@ ## 342-point run to Witt's End and plover room. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/woodshint.log b/tests/woodshint.log index fadef1a..68b2e38 100644 --- a/tests/woodshint.log +++ b/tests/woodshint.log @@ -1,5 +1,5 @@ ## Test hinting logic - elicit forest hint -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a parser bug fix. # Also some tests of intransitive-verb cases From 20e1b9d9303a66e492ba1a12437971b817785e84 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 4 Apr 2023 09:32:18 -0400 Subject: [PATCH 095/213] Update tapdiffer version. --- tests/Makefile | 2 +- tests/tapdiffer | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index b49a2f2..24ec9bf 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -162,7 +162,7 @@ oldcompare: else \ ./advent430 <$${stem}.log | oldfilter >$${stem}.ochk; \ ../advent <$${stem}.log >$${stem}.log-new; \ - ./newfilter <$${stem}.log-new | tapdiffer -w "$${stem}: $${legend}" $${stem}.ochk; \ + ./newfilter <$${stem}.log-new | tapdiffer -b "$${stem}: $${legend}" $${stem}.ochk; \ fi; \ done; \ echo 1..$(words $(shell ls *.log))) | $(TAPFILTER) diff --git a/tests/tapdiffer b/tests/tapdiffer index ebf270b..495427e 100755 --- a/tests/tapdiffer +++ b/tests/tapdiffer @@ -1,6 +1,6 @@ #! /bin/sh # SPDX-FileCopyrightText: Eric S. Raymond -# SPDX-License-Identifier: BSD-2-Clause +# SPDX-License-Identifier: MIT-0 # # tapdiffer - Render diff between input and checkfile as a TAP report # @@ -10,9 +10,19 @@ # A nonempty diff is shipped as a TAP YAML block following "not ok" # unless QUIET=1 in the environment. # -if [ "$1" = "-w" ] +# This code is intended to be embedded in your project. The author +# grants permission for it to be distributed under the prevailing +# license of your project if you choose, provided that license is +# OSD-compliant; otherwise the following SPDX tag incorporates the +# MIT No Attribution license by reference. +# +# A newer version may be available at https://gitlab.com/esr/tapview +# Check your last commit dqte for this file against the commit list +# there to see if it might be a good idea to update. +# +if [ "$1" = "-b" ] then - diffopts=-ubZ + diffopts=-ub shift else diffopts=-u @@ -23,7 +33,7 @@ checkfile=$2 trap 'rm /tmp/tapdiff$$' EXIT HUP INT QUIT TERM -if diff --text "${diffopts}" ${checkfile} - >/tmp/tapdiff$$ +if diff --text "${diffopts}" "${checkfile}" - >/tmp/tapdiff$$ then echo "ok - ${legend}" else From 00bdc2133ace5d4e8c79fedb9dc64f14c07d28f7 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 4 Apr 2023 09:53:10 -0400 Subject: [PATCH 096/213] Improve TAP messages slightly. --- tests/Makefile | 2 +- tests/oysterbug.log | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 24ec9bf..efa5332 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -118,7 +118,7 @@ RUN_TARGETS=$(TESTLOADS:%=run-regress-%) $(RUN_TARGETS): run-regress-%: %.log @(test=$(<:.log=); legend=$$(sed -n '/^## /s///p' <"$<" 2>/dev/null || echo "(no description)"); \ OPTS=`sed -n /#options:/s///p $<`; \ - $(advent) $$OPTS <$< | tapdiffer "$<: $${legend}" "$${test}.chk") + $(advent) $$OPTS <$< | tapdiffer "$${test}: $${legend}" "$${test}.chk") multifile-regress: @(echo "inven" | advent issue36.log /dev/stdin) | tapdiffer "multifile: multiple-file test" multifile.chk diff --git a/tests/oysterbug.log b/tests/oysterbug.log index 58299cc..0337967 100644 --- a/tests/oysterbug.log +++ b/tests/oysterbug.log @@ -1,4 +1,4 @@ -# Demonstrate fix of buggy response to unlocking oyster while carrying it. +## Demonstrate fix of buggy response to unlocking oyster while carrying it. # SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE This fails due to a known bug in advent430 From 3c6648882d4d9b98a5d5f67e090ef401fa5db30a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 4 Apr 2023 19:14:45 -0400 Subject: [PATCH 097/213] How to set up prerequisites for oldcompare --- tests/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Makefile b/tests/Makefile index efa5332..122e94a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -136,6 +136,14 @@ count: # master leaving advent430 and adventure.data in place (make clean # does not remove them). # +# make clean # Clean up object files, laving a bare source tree +# git checkout advent430 # Check out the advent430 branch +# make # Build the advent430 binary +# advent430 # Run it. Answer the novice question and quit +# make clean # Remove .o files +# git checkout master # Go back to master branch +# make # Rebuild advent. +# # The diff file produced has corrected spellings in it. That's what oldfilter # is for, to massage out the original spellings and avoid noise diffs. # Diffs in amount of whitespace and trailing whitespace are ignored From 9b53140f1cc99acebf429fa9812ec75de7a511cc Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 5 Apr 2023 17:48:26 -0400 Subject: [PATCH 098/213] GO_* enums no longer have an order constraint. --- advent.h | 1 - 1 file changed, 1 deletion(-) diff --git a/advent.h b/advent.h index 100de43..805b7a7 100644 --- a/advent.h +++ b/advent.h @@ -115,7 +115,6 @@ typedef enum scorebonus {none, splatter, defeat, victory} score_t; /* Phase codes for action returns. * These were at one time FORTRAN line numbers. - * The values don't matter, but perturb their order at your peril. */ typedef enum { GO_TERMINATE, From 4ce4de190ee7088c94a87888298352b35d0ca4f3 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 5 Apr 2023 18:02:47 -0400 Subject: [PATCH 099/213] Magic number removal. --- advent.h | 1 + main.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/advent.h b/advent.h index 805b7a7..3afeb8e 100644 --- a/advent.h +++ b/advent.h @@ -34,6 +34,7 @@ #define BATTERYLIFE 2500 // turn limit increment from batteries #define WORD_NOT_FOUND -1 // "Word not found" flag value for the vocab hash functions. #define WORD_EMPTY 0 // "Word empty" flag value for the vocab hash functions +#define PIT_KILL_PROB 35 // Percentage probability of dying from fall in pit. #define CARRIED -1 // Player is toting it #define READ_MODE "rb" // b is not needed for POSIX but harmless #define WRITE_MODE "wb" // b is not needed for POSIX but harmless diff --git a/main.c b/main.c index acbabb6..ef7d392 100644 --- a/main.c +++ b/main.c @@ -1069,7 +1069,7 @@ static bool do_move(void) /* The easiest way to get killed is to fall into a pit in * pitch darkness. */ - if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && PCT(35)) { // FIXME: magic number + if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && PCT(PIT_KILL_PROB)) { rspeak(PIT_FALL); game.oldlc2 = game.loc; croak(); From fe378b9e136bfe93b5166ef36f03cad976d643b2 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 5 Apr 2023 19:49:38 -0400 Subject: [PATCH 100/213] Improved behavior when magic words are said before they're seen. Note: there is a tiny risk that this could break savefile compatibility, as I swiped an unused int member in the game structure and turned it into a bool. int and bool *should* be the same sixe... --- actions.c | 5 ++++- advent.h | 2 +- adventure.yaml | 1 + main.c | 2 ++ notes.adoc | 5 +++++ tests/magicwords.chk | 2 +- tests/newfilter | 1 + 7 files changed, 15 insertions(+), 3 deletions(-) diff --git a/actions.c b/actions.c index 05377ff..658d95d 100644 --- a/actions.c +++ b/actions.c @@ -231,7 +231,10 @@ static phase_codes_t bigwords(vocab_t id) } } else { /* Magic-word sequebce was started but is incorrect */ - rspeak(START_OVER); + if (settings.oldstyle || game.seenbigwords) + rspeak(START_OVER); + else + rspeak(WELL_POINTLESS); game.foobar = WORD_EMPTY; return GO_CLEAROBJ; } diff --git a/advent.h b/advent.h index 3afeb8e..5ff1146 100644 --- a/advent.h +++ b/advent.h @@ -178,7 +178,7 @@ struct game_t { int saved; // point penalty for saves int tally; // count of treasures gained int thresh; // current threshold for endgame scoring tier - turn_t trndex; // FIXME: not used, remove on next format bump + bool seenbigwords; // have we red the grafitti in the Giant's Room? turn_t trnluz; // # points lost so far due to turns used turn_t turns; // counts commands given (ignores yes/no) char zzword[TOKLEN + 1]; // randomly generated magic word from bird diff --git a/adventure.yaml b/adventure.yaml index c9827df..a48ee7d 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -3016,6 +3016,7 @@ arbitrary_messages: !!omap black smoke. - SHELL_IMPERVIOUS: 'The shell is very strong and is impervious to attack.' - START_OVER: 'What''s the matter, can''t you read? Now you''d best start over.' +- WELL_POINTLESS: 'Well, that was remarkably pointless!' - DRAGON_SCALES: 'The axe bounces harmlessly off the dragon''s thick scales.' - NASTY_DRAGON: 'The dragon looks rather nasty. You''d best not try to get by.' - BIRD_BURNT: |- diff --git a/main.c b/main.c index ef7d392..124ba44 100644 --- a/main.c +++ b/main.c @@ -935,6 +935,8 @@ static void listobjects(void) game.prop[RUG] = RUG_DRAGON; if (obj == CHAIN) game.prop[CHAIN] = CHAINING_BEAR; + if (obj == EGGS) + game.seenbigwords = true; --game.tally; /* Note: There used to be a test here to see whether the * player had blown it so badly that he could never ever see diff --git a/notes.adoc b/notes.adoc index 8358565..d8d8292 100644 --- a/notes.adoc +++ b/notes.adoc @@ -53,6 +53,11 @@ Bug fixes: * Response to an attempt to unlock the oyster while carrying it was incorrect. +* Behavior when saying the giant's magic words before having seen them wasn't + quite correct - the game responded as though the player had already + read them ("...can't you read?"). The new message is "Nothing happens." + The -o option reverts this change. + * Attempting to extinguish an unlit urn caused it to lose its oil. * "A crystal bridge now spans the fissure." (progressive present) was diff --git a/tests/magicwords.chk b/tests/magicwords.chk index 24df443..4db287a 100644 --- a/tests/magicwords.chk +++ b/tests/magicwords.chk @@ -67,7 +67,7 @@ OK > say fum -What's the matter, can't you read? Now you'd best start over. +Well, that was remarkably pointless! > z diff --git a/tests/newfilter b/tests/newfilter index 9ae3da7..c5bad71 100755 --- a/tests/newfilter +++ b/tests/newfilter @@ -6,5 +6,6 @@ sed \ -e '/bridge now spans the fissure/s//bridge spans the fissure/' \ -e '/ground/s//surface/' \ -e '/floor/s//surface/' \ + -e "/Well, that was remarkably pointless!/s//What's the matter, can't you read? Now you'd best start over./" \ # end From 9726d8207cc7eecf0d6c24b0f1a34eeb457a564e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 5 Apr 2023 21:36:52 -0400 Subject: [PATCH 101/213] Add some SPDX headers. --- INSTALL.adoc | 2 ++ README.adoc | 2 ++ advent.adoc | 2 ++ hints.adoc | 2 ++ history.adoc | 2 ++ notes.adoc | 2 ++ 6 files changed, 12 insertions(+) diff --git a/INSTALL.adoc b/INSTALL.adoc index a51b8ac..f61783c 100644 --- a/INSTALL.adoc +++ b/INSTALL.adoc @@ -1,4 +1,6 @@ = Installing Open Adventure = +// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-License-Identifier: CC-BY-4.0 Installation now requires Python3 due to a security issue with the YAML library. diff --git a/README.adoc b/README.adoc index 03f249d..573bf7a 100644 --- a/README.adoc +++ b/README.adoc @@ -1,4 +1,6 @@ = README for Open Adventure = +// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-License-Identifier: CC-BY-4.0 If you are reading this anywhere but at http://www.catb.org/~esr/open-adventure you can go there for tarball downloads and other resources. diff --git a/advent.adoc b/advent.adoc index 6257e6c..db55ab2 100644 --- a/advent.adoc +++ b/advent.adoc @@ -1,5 +1,7 @@ = advent(6) = :doctype: manpage +// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-License-Identifier: CC-BY-4.0 == NAME == advent - Colossal Cave Adventure diff --git a/hints.adoc b/hints.adoc index 1d2b092..c77afee 100644 --- a/hints.adoc +++ b/hints.adoc @@ -1,4 +1,6 @@ = Non-spoiler hints = +// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-License-Identifier: CC-BY-4.0 Say the words you see. They can have interesting effects. diff --git a/history.adoc b/history.adoc index ea237e9..1e4028c 100644 --- a/history.adoc +++ b/history.adoc @@ -1,5 +1,7 @@ = A brief history of Colossal Cave Adventure = by Eric S. Raymond +// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-License-Identifier: CC-BY-4.0 Adventure is the fons et origo of all later dungeon-crawling computer games, the granddaddy of interactive fiction, and one of the hallowed diff --git a/notes.adoc b/notes.adoc index d8d8292..c6759ac 100644 --- a/notes.adoc +++ b/notes.adoc @@ -1,5 +1,7 @@ = Open Adventure Maintainer's Notes = by Eric S. Raymond +// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-License-Identifier: CC-BY-4.0 In which we explain what has been done to this code since Don Woods authorized us to ship it under an open-source license. There's a From e1a528a4c56a5d0e233088ec71badeaaceebba90 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 5 Apr 2023 21:48:02 -0400 Subject: [PATCH 102/213] Move NEWS file to asciidoc. --- Makefile | 4 ++-- NEWS => NEWS.adoc | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) rename NEWS => NEWS.adoc (96%) diff --git a/Makefile b/Makefile index 003935d..5d306b0 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # To build with save/resume disabled, pass CFLAGS="-DADVENT_NOSAVE" # To build with auto-save/resume enabled, pass CFLAGS="-DADVENT_AUTOSAVE" -VERS=$(shell sed -n +// SPDX-License-Identifier: CC-BY-4.0 1.15: 2023-04-03:: Commands in magic-word sequence now interrupt it, as in original. From f5ff25f52aaec53581d371c4d019af75c57fb989 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 10:03:24 -0400 Subject: [PATCH 103/213] Magic-number elimination. --- main.c | 3 +-- saveresume.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/main.c b/main.c index 124ba44..80689e3 100644 --- a/main.c +++ b/main.c @@ -463,8 +463,7 @@ static void describe_location(void) { const char* msg = locations[game.loc].description.small; - if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || - msg == NO_MESSAGE) + if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == NO_MESSAGE) msg = locations[game.loc].description.big; if (!FORCED(game.loc) && DARK(game.loc)) { diff --git a/saveresume.c b/saveresume.c index db1153b..d7fe76e 100644 --- a/saveresume.c +++ b/saveresume.c @@ -29,8 +29,7 @@ /* * If you change the first three members, the resume function may not properly - * reject saves from older versions. Yes, this glues us to a hardware- - * dependent length of int. Later members can change, but bump the version + * reject saves from older versions. Later members can change, but bump the version * when you do that. */ struct save_t { @@ -123,8 +122,7 @@ int resume(void) #endif FILE *fp = NULL; - if (game.loc != 1 || - game.abbrev[1] != 1) { + if (game.loc != LOC_START || game.abbrev[LOC_START] != 1) { rspeak(RESUME_ABANDON); if (!yes_or_no(arbitrary_messages[THIS_ACCEPTABLE], arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN])) return GO_CLEAROBJ; From 3e724867245069eb41da7bb913c199598170671e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 12:13:38 -0400 Subject: [PATCH 104/213] Comment typo fix --- tests/resumefail2.log | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/resumefail2.log b/tests/resumefail2.log index 973f7c9..30b3e20 100644 --- a/tests/resumefail2.log +++ b/tests/resumefail2.log @@ -1,4 +1,4 @@ -## Resume from from generated save with version mismatch error +## Resume from generated save with version mismatch error # SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Reveals a bug in advent430 handling of saves with invalid versions. From e8991f69e946e540464561eca75cd6d13457780c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 16:38:21 -0400 Subject: [PATCH 105/213] Simplify and speed up testing. --- tests/Makefile | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 122e94a..39dba7d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -48,28 +48,29 @@ listcheck: done # Generate bogus savegames. -sgame1: +cheat_numdie.adv: @$(PARDIR)/cheat -d -900 -o cheat_numdie.adv > /tmp/cheat_numdie @./outcheck.sh "cheat: Generate save file with -900 deaths" -sgame2: +cheat_numdie1000.adv: @$(PARDIR)/cheat -d -1000 -o cheat_numdie1000.adv > /tmp/cheat_numdie1000 @./outcheck.sh "cheat: Generate save file with -1000 deaths" -sgame3: +cheat_savetamper.adv: @$(PARDIR)/cheat -d 2000 -o cheat_savetamper.adv > /tmp/cheat_savetamper @./outcheck.sh "cheat: Generate tamper-detection test" -sgame4: +resume_badversion.adv: @$(PARDIR)/cheat -v -1337 -o resume_badversion.adv > /tmp/cheat_badversion @./outcheck.sh "cheat: Generate save file with version -1337" -sgame5: +thousand_saves.adv: @$(PARDIR)/cheat -s -1000 -o thousand_saves.adv > /tmp/cheat_1000saves @./outcheck.sh "cheat: Generate save file 1000 saves" -sgame6: - @$(PARDIR)/cheat -t -1000 -o thousand_saves.adv > /tmp/cheat_1000turns +thousand_turns.adv: + @$(PARDIR)/cheat -t -1000 -o thousand_turns.adv > /tmp/cheat_1000turns @./outcheck.sh "cheat: Generate save file 1000 turns" -sgame7: - @$(PARDIR)/cheat -l -1000 -o thousand_lamp.adv > /tmp/cheat_1000lamp - @./outcheck.sh "cheat: Generate save file 1000 turns" -SGAMES = sgame1 sgame2 sgame3 sgame4 sgame5 sgame6 sgame7 +thousand_limit.adv: + @$(PARDIR)/cheat -l -1000 -o thousand_limit.adv > /tmp/cheat_1000limit + @./outcheck.sh "cheat: Generate save file with game limot 1000" +SGAMES = cheat_numdie.adv cheat_numdie1000.adv cheat_savetamper.adv resume_badversion.adv \ + thousand_saves.adv thousand_turns.adv thousand_limit.adv # Force coverage of cheat edgecases scheck1: @@ -123,13 +124,17 @@ $(RUN_TARGETS): run-regress-%: %.log multifile-regress: @(echo "inven" | advent issue36.log /dev/stdin) | tapdiffer "multifile: multiple-file test" multifile.chk -TEST_TARGETS = $(SGAMES) $(SCHECKS) $(RUN_TARGETS) multifile-regress +TEST_TARGETS = $(SCHECKS) $(RUN_TARGETS) multifile-regress -tap: count $(TEST_TARGETS) +tap: count $(SGAMES) $(TEST_TARGETS) @rm -f scratch.tmp /tmp/coverage* /tmp/cheat* count: @echo 1..$(words $(TEST_TARGETS)) +foobar: + exit 1 + + # The following machinery tests the game against a binary made from # the advent430 branch To use it, switch to that branch, build the # binary, run it once to generate adventure.data, then switch back to From e99cc69de01220b80400e42e7cb625746d31e6f2 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 17:28:43 -0400 Subject: [PATCH 106/213] Quiet make test down. --- tests/Makefile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 39dba7d..66280f4 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -50,25 +50,18 @@ listcheck: # Generate bogus savegames. cheat_numdie.adv: @$(PARDIR)/cheat -d -900 -o cheat_numdie.adv > /tmp/cheat_numdie - @./outcheck.sh "cheat: Generate save file with -900 deaths" cheat_numdie1000.adv: @$(PARDIR)/cheat -d -1000 -o cheat_numdie1000.adv > /tmp/cheat_numdie1000 - @./outcheck.sh "cheat: Generate save file with -1000 deaths" cheat_savetamper.adv: @$(PARDIR)/cheat -d 2000 -o cheat_savetamper.adv > /tmp/cheat_savetamper - @./outcheck.sh "cheat: Generate tamper-detection test" resume_badversion.adv: @$(PARDIR)/cheat -v -1337 -o resume_badversion.adv > /tmp/cheat_badversion - @./outcheck.sh "cheat: Generate save file with version -1337" thousand_saves.adv: @$(PARDIR)/cheat -s -1000 -o thousand_saves.adv > /tmp/cheat_1000saves - @./outcheck.sh "cheat: Generate save file 1000 saves" thousand_turns.adv: @$(PARDIR)/cheat -t -1000 -o thousand_turns.adv > /tmp/cheat_1000turns - @./outcheck.sh "cheat: Generate save file 1000 turns" thousand_limit.adv: @$(PARDIR)/cheat -l -1000 -o thousand_limit.adv > /tmp/cheat_1000limit - @./outcheck.sh "cheat: Generate save file with game limot 1000" SGAMES = cheat_numdie.adv cheat_numdie1000.adv cheat_savetamper.adv resume_badversion.adv \ thousand_saves.adv thousand_turns.adv thousand_limit.adv From 3640e5cb96db9057dec008b05e69d27676ecbfbb Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 17:44:11 -0400 Subject: [PATCH 107/213] Refactoring step - change some visibilities. --- advent.h | 25 +++++++++++++++++++++++-- saveresume.c | 28 ++++------------------------ 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/advent.h b/advent.h index 5ff1146..faf298e 100644 --- a/advent.h +++ b/advent.h @@ -226,7 +226,29 @@ typedef struct { command_state_t state; } command_t; +/* + * Bump on save format change. + * + * Note: Verify that the tests run clean before bumping this, then rebuild the check + * files afterwards. Otherwise you will get a spurious failure due to the old version + * having been generated into a check file. + */ +#define SAVE_VERSION 29 + +/* + * If you change the first three members, the resume function may not properly + * reject saves from older versions. Later members can change, but bump the version + * when you do that. + */ +struct save_t { + int64_t savetime; + int32_t mode; /* not used, must be present for version detection */ + int32_t version; + struct game_t game; +}; + extern struct game_t game; +extern struct save_t save; extern struct settings_t settings; extern char *myreadline(const char *); @@ -262,8 +284,7 @@ extern int initialise(void); extern phase_codes_t action(command_t); extern void state_change(obj_t, int); extern bool is_valid(struct game_t); - -void bug(enum bugtype, const char *) __attribute__((__noreturn__)); +extern void bug(enum bugtype, const char *) __attribute__((__noreturn__)); /* represent an empty command word */ static const command_word_t empty_command_word = { diff --git a/saveresume.c b/saveresume.c index d7fe76e..8584982 100644 --- a/saveresume.c +++ b/saveresume.c @@ -18,26 +18,6 @@ #include "advent.h" #include "dungeon.h" -/* - * Bump on save format change. - * - * Note: Verify that the tests run clean before bumping this, then rebuild the check - * files afterwards. Otherwise you will get a spurious failure due to the old version - * having been generated into a check file. - */ -#define VRSION 29 - -/* - * If you change the first three members, the resume function may not properly - * reject saves from older versions. Later members can change, but bump the version - * when you do that. - */ -struct save_t { - int64_t savetime; - int32_t mode; /* not used, must be present for version detection */ - int32_t version; - struct game_t game; -}; struct save_t save; #define IGNORE(r) do{if (r){}}while(0) @@ -47,7 +27,7 @@ int savefile(FILE *fp, int32_t version) { save.savetime = time(NULL); save.mode = -1; - save.version = (version == 0) ? VRSION : version; + save.version = (version == 0) ? SAVE_VERSION : version; save.game = game; IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp)); @@ -105,7 +85,7 @@ int suspend(void) free(name); } - savefile(fp, VRSION); + savefile(fp, SAVE_VERSION); fclose(fp); rspeak(RESUME_HELP); exit(EXIT_SUCCESS); @@ -156,8 +136,8 @@ int restore(FILE* fp) IGNORE(fread(&save, sizeof(struct save_t), 1, fp)); fclose(fp); - if (save.version != VRSION) { - rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), VRSION / 10, MOD(VRSION, 10)); + if (save.version != SAVE_VERSION) { + rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), SAVE_VERSION / 10, MOD(SAVE_VERSION, 10)); } else if (!is_valid(save.game)) { rspeak(SAVE_TAMPERING); exit(EXIT_SUCCESS); From d16822a5837f5243e708b5349dbb0e4144152a23 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 17:54:02 -0400 Subject: [PATCH 108/213] Give savefiles an identifting header. SAve format version gets bumped. --- advent.h | 10 +++++++--- saveresume.c | 3 +-- tests/resumefail2.chk | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/advent.h b/advent.h index faf298e..f9a6a9a 100644 --- a/advent.h +++ b/advent.h @@ -233,7 +233,12 @@ typedef struct { * files afterwards. Otherwise you will get a spurious failure due to the old version * having been generated into a check file. */ -#define SAVE_VERSION 29 +#define SAVE_VERSION 30 + +/* + * Goes at start of gile so sabes can be identified by file(1) and the like. + */ +#define ADVENT_MAGIC "open-adventure\n" /* * If you change the first three members, the resume function may not properly @@ -241,8 +246,7 @@ typedef struct { * when you do that. */ struct save_t { - int64_t savetime; - int32_t mode; /* not used, must be present for version detection */ + char magic[sizeof(ADVENT_MAGIC)]; int32_t version; struct game_t game; }; diff --git a/saveresume.c b/saveresume.c index 8584982..76de1c4 100644 --- a/saveresume.c +++ b/saveresume.c @@ -25,8 +25,7 @@ struct save_t save; int savefile(FILE *fp, int32_t version) /* Save game to file. No input or output from user. */ { - save.savetime = time(NULL); - save.mode = -1; + memcpy(&save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)); save.version = (version == 0) ? SAVE_VERSION : version; save.game = game; diff --git a/tests/resumefail2.chk b/tests/resumefail2.chk index 931c72d..7493ad8 100644 --- a/tests/resumefail2.chk +++ b/tests/resumefail2.chk @@ -11,7 +11,7 @@ down a gully. Can't open file y, try again. I'm sorry, but that Adventure was begun using Version -133.-7 of the -save file format, and this program uses Version 2.9. You must find an instance +save file format, and this program uses Version 3.0. You must find an instance using that other version in order to resume that Adventure. You're in front of building. From 58cf204eba055cc7633aa83be7ec6f7c06ed70b7 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 19:03:02 -0400 Subject: [PATCH 109/213] Implement the magic-cookie check and its test. --- adventure.yaml | 1 + saveresume.c | 4 +++- tests/badmagic.chk | 22 ++++++++++++++++++++++ tests/badmagic.log | 8 ++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tests/badmagic.chk create mode 100644 tests/badmagic.log diff --git a/adventure.yaml b/adventure.yaml index a48ee7d..8909914 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -3186,6 +3186,7 @@ arbitrary_messages: !!omap # %d of %d "random" messages %d of %d "class" messages # %d of %d hints %d of %d turn thresholds' - RESUME_ABANDON: 'To resume an earlier Adventure, you must abandon the current one.' +- BAD_SAVE: 'Oops, that does not look like a valid save file.' - VERSION_SKEW: |- I'm sorry, but that Adventure was begun using Version %d.%d of the save file format, and this program uses Version %d.%d. You must find an instance diff --git a/saveresume.c b/saveresume.c index 76de1c4..0ed8cd3 100644 --- a/saveresume.c +++ b/saveresume.c @@ -135,7 +135,9 @@ int restore(FILE* fp) IGNORE(fread(&save, sizeof(struct save_t), 1, fp)); fclose(fp); - if (save.version != SAVE_VERSION) { + if (memcmp(save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)) != 0) + rspeak(BAD_SAVE); + else if (save.version != SAVE_VERSION) { rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), SAVE_VERSION / 10, MOD(SAVE_VERSION, 10)); } else if (!is_valid(save.game)) { rspeak(SAVE_TAMPERING); diff --git a/tests/badmagic.chk b/tests/badmagic.chk new file mode 100644 index 0000000..08c8ffe --- /dev/null +++ b/tests/badmagic.chk @@ -0,0 +1,22 @@ + +Welcome to Adventure!! Would you like instructions? + +> n + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> resume +Can't open file y, try again. + +Oops, that does not look like a valid save file. + +You're in front of building. + +> +You scored 32 out of a possible 430, using 1 turn. + +You are obviously a rank amateur. Better luck next time. + +To achieve the next higher rating, you need 14 more points. diff --git a/tests/badmagic.log b/tests/badmagic.log new file mode 100644 index 0000000..4ee9f10 --- /dev/null +++ b/tests/badmagic.log @@ -0,0 +1,8 @@ +## Resume from filename withoy the right magic at the front +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause +#NOCOMPARE advent430 doesn't have this test +n +resume +y +../main.o From 4b08b726f9735b5a6a17e588753a496700ff25f7 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 19:26:04 -0400 Subject: [PATCH 110/213] Simplify the signature of savefile(). --- advent.h | 3 ++- cheat.c | 7 +++---- main.c | 2 +- saveresume.c | 7 ++++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/advent.h b/advent.h index f9a6a9a..3cea5f5 100644 --- a/advent.h +++ b/advent.h @@ -248,6 +248,7 @@ typedef struct { struct save_t { char magic[sizeof(ADVENT_MAGIC)]; int32_t version; + int32_t canary; struct game_t game; }; @@ -277,7 +278,7 @@ extern void set_seed(int32_t); extern int32_t randrange(int32_t); extern int score(enum termination); extern void terminate(enum termination) __attribute__((noreturn)); -extern int savefile(FILE *, int32_t); +extern int savefile(FILE *); #if defined ADVENT_AUTOSAVE extern void autosave(void); #endif diff --git a/cheat.c b/cheat.c index ebbc166..1a415b7 100644 --- a/cheat.c +++ b/cheat.c @@ -19,7 +19,6 @@ int main(int argc, char *argv[]) { int ch; char *savefilename = NULL; - int version = 0; FILE *fp = NULL; // Initialize game variables @@ -59,8 +58,8 @@ int main(int argc, char *argv[]) printf("cheat: game.turns = %d\n", game.turns); break; case 'v': - version = atoi(optarg); - printf("cheat: version = %d\n", version); + save.version = atoi(optarg); + printf("cheat: version = %d\n", save.version); break; case 'o': savefilename = optarg; @@ -89,7 +88,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - savefile(fp, version); + savefile(fp); fclose(fp); diff --git a/main.c b/main.c index 80689e3..a162463 100644 --- a/main.c +++ b/main.c @@ -24,7 +24,7 @@ void autosave(void) { if (autosave_fp != NULL) { rewind(autosave_fp); - savefile(autosave_fp, /* version (auto): */0); + savefile(autosave_fp); fflush(autosave_fp); } } diff --git a/saveresume.c b/saveresume.c index 0ed8cd3..0b71319 100644 --- a/saveresume.c +++ b/saveresume.c @@ -22,11 +22,12 @@ struct save_t save; #define IGNORE(r) do{if (r){}}while(0) -int savefile(FILE *fp, int32_t version) +int savefile(FILE *fp) /* Save game to file. No input or output from user. */ { memcpy(&save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)); - save.version = (version == 0) ? SAVE_VERSION : version; + if (save.version == 0) + save.version = SAVE_VERSION; save.game = game; IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp)); @@ -84,7 +85,7 @@ int suspend(void) free(name); } - savefile(fp, SAVE_VERSION); + savefile(fp); fclose(fp); rspeak(RESUME_HELP); exit(EXIT_SUCCESS); From 520d365f74b77496c2b5f7897463e1ddbaf5dfb9 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 19:35:56 -0400 Subject: [PATCH 111/213] Resume now detects if a save has incompatible endianness. --- NEWS.adoc | 4 ++++ saveresume.c | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS.adoc b/NEWS.adoc index f01d4f3..da58c79 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,6 +2,10 @@ // SPDX-FileCopyrightText: Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 +Reoisitory head:: + Savefiles now have an identigting magic cookie at the front. + Resume detects if a save has incompatible endianness. + 1.15: 2023-04-03:: Commands in magic-word sequence now interrupt it, as in original. Bug fix for bird not starting caged in endgame. diff --git a/saveresume.c b/saveresume.c index 0b71319..c6d0ba0 100644 --- a/saveresume.c +++ b/saveresume.c @@ -18,6 +18,11 @@ #include "advent.h" #include "dungeon.h" +/* + * Use this to detect endianness mismatch. Can't be unchanges by byte-swapping. + */ +#define ENDIAN_MAGIC 2317 + struct save_t save; #define IGNORE(r) do{if (r){}}while(0) @@ -28,6 +33,8 @@ int savefile(FILE *fp) memcpy(&save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)); if (save.version == 0) save.version = SAVE_VERSION; + if (save.canary == 0) + save.canary = ENDIAN_MAGIC; save.game = game; IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp)); @@ -136,7 +143,7 @@ int restore(FILE* fp) IGNORE(fread(&save, sizeof(struct save_t), 1, fp)); fclose(fp); - if (memcmp(save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)) != 0) + if (memcmp(save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)) != 0 || save.canary != ENDIAN_MAGIC) rspeak(BAD_SAVE); else if (save.version != SAVE_VERSION) { rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), SAVE_VERSION / 10, MOD(SAVE_VERSION, 10)); From 5de3b8ff7018e56dc876b1ac579de53597fd96f9 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 19:57:05 -0400 Subject: [PATCH 112/213] In notes.adoc, update the new-features list and credits. --- notes.adoc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/notes.adoc b/notes.adoc index c6759ac..b9ce8b1 100644 --- a/notes.adoc +++ b/notes.adoc @@ -15,7 +15,9 @@ the game; Jason signed on early in the process to help. The assistance of Peje Nilsson in restructuring some particularly grotty gotos is gratefully acknowledged. Petr Voropaev contributed fuzz testing and code cleanups. Aaron Traas did a lot of painstaking work to improve -test coverage, and factored out the last handful of gotos. +test coverage, and factored out the last handful of gotos. Ryan +Sarson nudged us into fixing a longstannding minor bug in the +handling of incorrect magic-word sequebcesm, == Nomenclature == @@ -55,10 +57,10 @@ Bug fixes: * Response to an attempt to unlock the oyster while carrying it was incorrect. -* Behavior when saying the giant's magic words before having seen them wasn't - quite correct - the game responded as though the player had already - read them ("...can't you read?"). The new message is "Nothing happens." - The -o option reverts this change. +* Behavior when saying the giant's magic words before having seen them + wasn't quite correct - the game responded as though the player had + already read them ("...can't you read?"). The new message is "Well, + that was remarkably pointless!" The -o option reverts this change. * Attempting to extinguish an unlit urn caused it to lose its oil. @@ -121,7 +123,10 @@ functions; without C's fread(3)/fwrite() and structs it was necessarily pretty ugly by modern standards. Encryption and checksumming have been discarded - it's pointless to try tamper-proofing saves when everyone has the source code. However -the game still integrity-checks savefiles on resume. +the game still integrity-checks savefiles on resume, including an +abort if the endianness of the restoring machine does not match that of +the saving machine. There is a magic-cookie header on the saves so +in theory they could be identified by programs like file(1). Save and resume filenames are stripped of leading and trailing whitespace before processing. From 2f60504e077dfdb8c37308239dd0ef7964cd3517 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 21:01:48 -0400 Subject: [PATCH 113/213] Comment typo fixes. --- actions.c | 2 +- tests/magicwords.log | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actions.c b/actions.c index 658d95d..8b3891b 100644 --- a/actions.c +++ b/actions.c @@ -230,7 +230,7 @@ static phase_codes_t bigwords(vocab_t id) return GO_CLEAROBJ; } } else { - /* Magic-word sequebce was started but is incorrect */ + /* Magic-word sequence was started but is incorrect */ if (settings.oldstyle || game.seenbigwords) rspeak(START_OVER); else diff --git a/tests/magicwords.log b/tests/magicwords.log index 7c4deff..a63cbf9 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -1,8 +1,8 @@ -## Test processing of variuus fee fie foe foo fum cases. +## Test processing of variuos fee fie foe foo fum cases. # SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # -# How thry're supposed to work: +# How they're supposed to work: # # 1. The word "fum", from the famous phrase, "fee fie foe fum" is treated # as a red herring for the player and is handled differently in the From 829c13d1d56e398e5b47186c31b2e2146f26dc6a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 6 Apr 2023 21:29:39 -0400 Subject: [PATCH 114/213] Fix some screwy formatting of conditionals... ...probably by the original FOTRAN-to-C translator. --- actions.c | 52 ++++++++++++++++------------------------------------ init.c | 3 +-- main.c | 25 ++++++++----------------- misc.c | 9 +++------ 4 files changed, 28 insertions(+), 61 deletions(-) diff --git a/actions.c b/actions.c index 8b3891b..d8b1546 100644 --- a/actions.c +++ b/actions.c @@ -243,8 +243,7 @@ static phase_codes_t bigwords(vocab_t id) static void blast(void) /* Blast. No effect unless you've got dynamite, which is a neat trick! */ { - if (game.prop[ROD2] == STATE_NOTFOUND || - !game.closed) + if (game.prop[ROD2] == STATE_NOTFOUND || !game.closed) rspeak(REQUIRES_DYNAMITE); else { if (HERE(ROD2)) { @@ -355,10 +354,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) return GO_CLEAROBJ; } - if (obj == WATER || - obj == OIL) { - if (!HERE(BOTTLE) || - LIQUID() != obj) { + if (obj == WATER || obj == OIL) { + if (!HERE(BOTTLE) || LIQUID() != obj) { if (!TOTING(BOTTLE)) { rspeak(NO_CONTAINER); return GO_CLEAROBJ; @@ -394,8 +391,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) } game.prop[BIRD] = BIRD_CAGED; } - if ((obj == BIRD || - obj == CAGE) && + if ((obj == BIRD || obj == CAGE) && (game.prop[BIRD] == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) { /* expression maps BIRD to CAGE and CAGE to BIRD */ carry(BIRD + CAGE - obj, game.loc); @@ -815,10 +811,8 @@ static phase_codes_t find(verb_t verb, obj_t obj) return GO_CLEAROBJ; } - if (AT(obj) || - (LIQUID() == obj && AT(BOTTLE)) || - obj == LIQLOC(game.loc) || - (obj == DWARF && atdwrf(game.loc) > 0)) { + if (AT(obj) || (LIQUID() == obj && AT(BOTTLE)) || + obj == LIQLOC(game.loc) || (obj == DWARF && atdwrf(game.loc) > 0)) { rspeak(YOU_HAVEIT); return GO_CLEAROBJ; } @@ -876,8 +870,7 @@ static phase_codes_t inven(void) { bool empty = true; for (obj_t i = 1; i <= NOBJECTS; i++) { - if (i == BEAR || - !TOTING(i)) + if (i == BEAR || !TOTING(i)) continue; if (empty) { rspeak(NOW_HOLDING); @@ -942,9 +935,7 @@ static phase_codes_t listen(void) soundlatch = true; } for (obj_t i = 1; i <= NOBJECTS; i++) { - if (!HERE(i) || - objects[i].sounds[0] == NULL || - game.prop[i] < 0) + if (!HERE(i) || objects[i].sounds[0] == NULL || game.prop[i] < 0) continue; int mi = game.prop[i]; /* (ESR) Some unpleasant magic on object states here. Ideally @@ -1054,9 +1045,8 @@ static phase_codes_t pour(verb_t verb, obj_t obj) /* Pour. If no object, or object is bottle, assume contents of bottle. * special tests for pouring water or oil on plant or rusty door. */ { - if (obj == BOTTLE || - obj == INTRANSITIVE) - obj = LIQUID(); + if (obj == BOTTLE || obj == INTRANSITIVE) + obj = LIQUID(); if (obj == NO_OBJECT) return GO_UNKNOWN; if (!TOTING(obj)) { @@ -1072,8 +1062,7 @@ static phase_codes_t pour(verb_t verb, obj_t obj) return fill(verb, URN); game.prop[BOTTLE] = EMPTY_BOTTLE; game.place[obj] = LOC_NOWHERE; - if (!(AT(PLANT) || - AT(DOOR))) { + if (!(AT(PLANT) || AT(DOOR))) { rspeak(GROUND_WET); return GO_CLEAROBJ; } @@ -1112,9 +1101,7 @@ static phase_codes_t read(command_t command) if (HERE(i) && objects[i].texts[0] != NULL && game.prop[i] >= 0) command.obj = command.obj * NOBJECTS + i; } - if (command.obj > NOBJECTS || - command.obj == NO_OBJECT || - DARK(game.loc)) + if (command.obj > NOBJECTS || command.obj == NO_OBJECT || DARK(game.loc)) return GO_UNKNOWN; } @@ -1270,8 +1257,7 @@ static phase_codes_t throwit(command_t command) static phase_codes_t wake(verb_t verb, obj_t obj) /* Wake. Only use is to disturb the dwarves. */ { - if (obj != DWARF || - !game.closed) { + if (obj != DWARF || !game.closed) { speak(actions[verb].message); return GO_CLEAROBJ; } else { @@ -1301,11 +1287,7 @@ static phase_codes_t waste(verb_t verb, turn_t turns) static phase_codes_t wave(verb_t verb, obj_t obj) /* Wave. No effect unless waving rod at fissure or at bird. */ { - if (obj != ROD || - !TOTING(obj) || - (!HERE(BIRD) && - (game.closng || - !AT(FISSURE)))) { + if (obj != ROD || !TOTING(obj) || (!HERE(BIRD) && (game.closng || !AT(FISSURE)))) { speak(((!TOTING(obj)) && (obj != ROD || !TOTING(ROD2))) ? arbitrary_messages[ARENT_CARRYING] : @@ -1326,8 +1308,7 @@ static phase_codes_t wave(verb_t verb, obj_t obj) FREE_FLY); return GO_DWARFWAKE; } - if (game.closng || - !AT(FISSURE)) { + if (game.closng || !AT(FISSURE)) { rspeak((game.prop[BIRD] == BIRD_CAGED) ? CAGE_FLY : FREE_FLY); @@ -1406,8 +1387,7 @@ phase_codes_t action(command_t command) * will do here. We're preventing interpretation as an intransitive * verb when the word is unknown. */ command.obj = command.word[1].raw[0] != '\0' ? KEYS : NO_OBJECT; - if (command.obj == NO_OBJECT || - command.obj == INTRANSITIVE) { + if (command.obj == NO_OBJECT || command.obj == INTRANSITIVE) { /* Analyse an intransitive verb (ie, no object given yet). */ switch (command.verb) { case CARRY: diff --git a/init.c b/init.c index dbdfb11..202bf65 100644 --- a/init.c +++ b/init.c @@ -57,8 +57,7 @@ int initialise(void) } for (int i = 1; i <= NLOCATIONS; i++) { - if (!(locations[i].description.big == 0 || - tkey[i] == 0)) { + if (!(locations[i].description.big == 0 || tkey[i] == 0)) { int k = tkey[i]; if (travel[k].motion == HERE) conditions[i] |= (1 << COND_FORCED); diff --git a/main.c b/main.c index a162463..cdc83ba 100644 --- a/main.c +++ b/main.c @@ -199,8 +199,7 @@ static bool spotted_by_pirate(int i) * that game.place[CHEST] = LOC_NOWHERE might mean that he's thrown * it to the troll, but in that case he's seen the chest * (game.prop[CHEST] == STATE_FOUND). */ - if (game.loc == game.chloc || - game.prop[CHEST] != STATE_NOTFOUND) + if (game.loc == game.chloc || game.prop[CHEST] != STATE_NOTFOUND) return true; int snarfed = 0; bool movechest = false, robplayer = false; @@ -213,8 +212,7 @@ static bool spotted_by_pirate(int i) game.loc == objects[EMERALD].plac)) { continue; } - if (TOTING(treasure) || - HERE(treasure)) + if (TOTING(treasure) || HERE(treasure)) ++snarfed; if (TOTING(treasure)) { movechest = true; @@ -276,9 +274,7 @@ static bool dwarfmove(void) * steal return toll, and dwarves can't meet the bear. Also * means dwarves won't follow him into dead end in maze, but * c'est la vie. They'll wait for him outside the dead end. */ - if (game.loc == LOC_NOWHERE || - FORCED(game.loc) || - CNDBIT(game.newloc, COND_NOARRR)) + if (game.loc == LOC_NOWHERE || FORCED(game.loc) || CNDBIT(game.newloc, COND_NOARRR)) return true; /* Dwarf activity level ratchets up */ @@ -293,8 +289,7 @@ static bool dwarfmove(void) * replace him with the alternate. */ if (game.dflag == 1) { if (!INDEEP(game.loc) || - (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || - PCT(85)))) + (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || PCT(85)))) return true; game.dflag = 2; for (int i = 1; i <= 2; i++) { @@ -571,8 +566,7 @@ static void playermove(int motion) /* Look for a way to fulfil the motion verb passed in - travel_entry indexes * the beginning of the motion entries for here (game.loc). */ for (;;) { - if ((travel[travel_entry].motion == HERE) || - travel[travel_entry].motion == motion) + if ((travel[travel_entry].motion == HERE) || travel[travel_entry].motion == motion) break; if (travel[travel_entry].stop) { /* Couldn't find an entry matching the motion word passed @@ -626,14 +620,12 @@ static void playermove(int motion) if (condtype < cond_not) { /* YAML N and [pct N] conditionals */ if (condtype == cond_goto || condtype == cond_pct) { - if (condarg1 == 0 || - PCT(condarg1)) + if (condarg1 == 0 || PCT(condarg1)) break; /* else fall through */ } /* YAML [with OBJ] clause */ - else if (TOTING(condarg1) || - (condtype == cond_with && AT(condarg1))) + else if (TOTING(condarg1) || (condtype == cond_with && AT(condarg1))) break; /* else fall through to check [not OBJ STATE] */ } else if (game.prop[condarg1] != condarg2) @@ -672,8 +664,7 @@ static void playermove(int motion) game.newloc = (game.loc == LOC_PLOVER) ? LOC_ALCOVE : LOC_PLOVER; - if (game.holdng > 1 || - (game.holdng == 1 && !TOTING(EMERALD))) { + if (game.holdng > 1 || (game.holdng == 1 && !TOTING(EMERALD))) { game.newloc = game.loc; rspeak(MUST_DROP); } diff --git a/misc.c b/misc.c index 9a8d2e5..9971cb5 100644 --- a/misc.c +++ b/misc.c @@ -335,13 +335,11 @@ bool yes_or_no(const char* question, const char* yes_response, const char* no_re free(firstword); - if (yes == 0 || - y == 0) { + if (yes == 0 || y == 0) { speak(yes_response); outcome = true; break; - } else if (no == 0 || - n == 0) { + } else if (no == 0 || n == 0) { speak(no_response); outcome = false; break; @@ -656,8 +654,7 @@ void drop(obj_t object, loc_t where) --game.holdng; game.place[object] = where; } - if (where == LOC_NOWHERE || - where == CARRIED) + if (where == LOC_NOWHERE || where == CARRIED) return; game.link[object] = game.atloc[where]; game.atloc[where] = object; From 7e21108e95aa0f745249720270247f7f69472d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Andersson?= Date: Mon, 3 Apr 2023 19:05:58 +0200 Subject: [PATCH 115/213] Spelling fixes. --- NEWS.adoc | 2 +- advent.h | 4 ++-- saveresume.c | 2 +- tests/magicwords.log | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NEWS.adoc b/NEWS.adoc index da58c79..b879e17 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -3,7 +3,7 @@ // SPDX-License-Identifier: CC-BY-4.0 Reoisitory head:: - Savefiles now have an identigting magic cookie at the front. + Savefiles now have an identifying magic cookie at the front. Resume detects if a save has incompatible endianness. 1.15: 2023-04-03:: diff --git a/advent.h b/advent.h index 3cea5f5..70c0c68 100644 --- a/advent.h +++ b/advent.h @@ -178,7 +178,7 @@ struct game_t { int saved; // point penalty for saves int tally; // count of treasures gained int thresh; // current threshold for endgame scoring tier - bool seenbigwords; // have we red the grafitti in the Giant's Room? + bool seenbigwords; // have we red the graffiti in the Giant's Room? turn_t trnluz; // # points lost so far due to turns used turn_t turns; // counts commands given (ignores yes/no) char zzword[TOKLEN + 1]; // randomly generated magic word from bird @@ -236,7 +236,7 @@ typedef struct { #define SAVE_VERSION 30 /* - * Goes at start of gile so sabes can be identified by file(1) and the like. + * Goes at start of file so saves can be identified by file(1) and the like. */ #define ADVENT_MAGIC "open-adventure\n" diff --git a/saveresume.c b/saveresume.c index c6d0ba0..f77925a 100644 --- a/saveresume.c +++ b/saveresume.c @@ -19,7 +19,7 @@ #include "dungeon.h" /* - * Use this to detect endianness mismatch. Can't be unchanges by byte-swapping. + * Use this to detect endianness mismatch. Can't be unchanged by byte-swapping. */ #define ENDIAN_MAGIC 2317 diff --git a/tests/magicwords.log b/tests/magicwords.log index a63cbf9..5e7f39a 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -1,4 +1,4 @@ -## Test processing of variuos fee fie foe foo fum cases. +## Test processing of various fee fie foe foo fum cases. # SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # From 4369284c75828ca78e7ab7ad3dfe732d3538c132 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 07:35:28 -0400 Subject: [PATCH 116/213] Boolification. --- advent.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/advent.h b/advent.h index 70c0c68..1162106 100644 --- a/advent.h +++ b/advent.h @@ -190,8 +190,8 @@ struct game_t { loc_t fixed[NOBJECTS + 1]; // fixed location of object (if not IS_FREE) obj_t link[NOBJECTS * 2 + 1];// object-list links loc_t place[NOBJECTS + 1]; // location of object - int hinted[NHINTS]; // hinted[i] = true iff hint i has been used. - int hintlc[NHINTS]; // hintlc[i] = how int at LOC with cond bit i + bool hinted[NHINTS]; // hinted[i] = true iff hint i has been used. + int hintlc[NHINTS]; // hintlc[i] = show int at LOC with cond bit i int prop[NOBJECTS + 1]; // object state array */ }; From 195e6e149b401cd8d27f406834c7f54a8cca4909 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 08:18:50 -0400 Subject: [PATCH 117/213] Apply loc_t type. --- advent.h | 2 +- main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/advent.h b/advent.h index 1162106..c1d3132 100644 --- a/advent.h +++ b/advent.h @@ -167,7 +167,7 @@ struct game_t { int holdng; // number of objects being carried int igo; // # uses of "go" instead of a direction int iwest; // # times he's said "west" instead of "w" - int knfloc; // knife location; 0 if none, -1 after caveat + loc_t knfloc; // knife location; LOC_NOWERE if none, -1 after caveat turn_t limit; // lifetime of lamp loc_t loc; // where player is now loc_t newloc; // where player is going diff --git a/main.c b/main.c index cdc83ba..e3e6a96 100644 --- a/main.c +++ b/main.c @@ -370,7 +370,7 @@ static bool dwarfmove(void) ++game.dtotal; if (game.odloc[i] == game.dloc[i]) { ++attack; - if (game.knfloc >= 0) + if (game.knfloc >= LOC_NOWHERE) game.knfloc = game.loc; if (randrange(1000) < 95 * (game.dflag - 2)) ++stick; From ff9c73a37d898d824aa9f8ecd4b670acd84d37e7 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 09:15:20 -0400 Subject: [PATCH 118/213] Structurize the informaruin about dwarves. --- actions.c | 10 +++++----- advent.h | 8 +++++--- init.c | 12 ++++++------ main.c | 48 ++++++++++++++++++++++++------------------------ misc.c | 4 ++-- saveresume.c | 4 ++-- 6 files changed, 44 insertions(+), 42 deletions(-) diff --git a/actions.c b/actions.c index d8b1546..06149d3 100644 --- a/actions.c +++ b/actions.c @@ -145,10 +145,10 @@ static phase_codes_t attack(command_t command) DESTROY(OGRE); int dwarves = 0; for (int i = 1; i < PIRATE; i++) { - if (game.dloc[i] == game.loc) { + if (game.dwarves[i].loc == game.loc) { ++dwarves; - game.dloc[i] = LOC_LONGWEST; - game.dseen[i] = false; + game.dwarves[i].loc = LOC_LONGWEST; + game.dwarves[i].seen = false; } } rspeak((dwarves > 1) ? @@ -1245,8 +1245,8 @@ static phase_codes_t throwit(command_t command) return throw_support(DWARF_DODGES); } else { int i = atdwrf(game.loc); - game.dseen[i] = false; - game.dloc[i] = LOC_NOWHERE; + game.dwarves[i].seen = false; + game.dwarves[i].loc = LOC_NOWHERE; return throw_support((++game.dkill == 1) ? DWARF_SMOKE : KILLED_DWARF); diff --git a/advent.h b/advent.h index c1d3132..56dcbe5 100644 --- a/advent.h +++ b/advent.h @@ -184,9 +184,11 @@ struct game_t { char zzword[TOKLEN + 1]; // randomly generated magic word from bird int abbrev[NLOCATIONS + 1]; // has location been seen? int atloc[NLOCATIONS + 1]; // head of object linked list per location - int dseen[NDWARVES + 1]; // true if dwarf has seen him - loc_t dloc[NDWARVES + 1]; // location of dwarves, initially hard-wired in - loc_t odloc[NDWARVES + 1]; // prior loc of each dwarf, initially garbage + struct { + int seen; // true if dwarf has seen him + loc_t loc; // location of dwarves, initially hard-wired in + loc_t oldloc; // prior loc of each dwarf, initially garbage + } dwarves[NDWARVES + 1]; loc_t fixed[NOBJECTS + 1]; // fixed location of object (if not IS_FREE) obj_t link[NOBJECTS * 2 + 1];// object-list links loc_t place[NOBJECTS + 1]; // location of object diff --git a/init.c b/init.c index 202bf65..b84f5fc 100644 --- a/init.c +++ b/init.c @@ -21,17 +21,17 @@ struct settings_t settings = { }; struct game_t game = { - .dloc[1] = LOC_KINGHALL, - .dloc[2] = LOC_WESTBANK, - .dloc[3] = LOC_Y2, - .dloc[4] = LOC_ALIKE3, - .dloc[5] = LOC_COMPLEX, + .dwarves[1].loc = LOC_KINGHALL, + .dwarves[2].loc = LOC_WESTBANK, + .dwarves[3].loc = LOC_Y2, + .dwarves[4].loc = LOC_ALIKE3, + .dwarves[5].loc = LOC_COMPLEX, /* Sixth dwarf is special (the pirate). He always starts at his * chest's eventual location inside the maze. This loc is saved * in chloc for ref. The dead end in the other maze has its * loc stored in chloc2. */ - .dloc[6] = LOC_MAZEEND12, + .dwarves[6].loc = LOC_MAZEEND12, .chloc = LOC_MAZEEND12, .chloc2 = LOC_DEADEND13, .abbnum = 5, diff --git a/main.c b/main.c index e3e6a96..3d17ec9 100644 --- a/main.c +++ b/main.c @@ -229,13 +229,13 @@ static bool spotted_by_pirate(int i) if (movechest) { move(CHEST, game.chloc); move(MESSAG, game.chloc2); - game.dloc[PIRATE] = game.chloc; - game.odloc[PIRATE] = game.chloc; - game.dseen[PIRATE] = false; + game.dwarves[PIRATE].loc = game.chloc; + game.dwarves[PIRATE].oldloc = game.chloc; + game.dwarves[PIRATE].seen = false; } else { /* You might get a hint of the pirate's presence even if the * chest doesn't move... */ - if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20)) + if (game.dwarves[PIRATE].oldloc != game.dwarves[PIRATE].loc && PCT(20)) rspeak(PIRATE_RUSTLES); } if (robplayer) { @@ -295,15 +295,15 @@ static bool dwarfmove(void) for (int i = 1; i <= 2; i++) { int j = 1 + randrange(NDWARVES - 1); if (PCT(50)) - game.dloc[j] = 0; + game.dwarves[j].loc = 0; } /* Alternate initial loc for dwarf, in case one of them * starts out on top of the adventurer. */ for (int i = 1; i <= NDWARVES - 1; i++) { - if (game.dloc[i] == game.loc) - game.dloc[i] = DALTLC; // - game.odloc[i] = game.dloc[i]; + if (game.dwarves[i].loc == game.loc) + game.dwarves[i].loc = DALTLC; // + game.dwarves[i].oldloc = game.dwarves[i].loc; } rspeak(DWARF_RAN); drop(AXE, game.loc); @@ -320,11 +320,11 @@ static bool dwarfmove(void) attack = 0; stick = 0; for (int i = 1; i <= NDWARVES; i++) { - if (game.dloc[i] == 0) + if (game.dwarves[i].loc == 0) continue; /* Fill tk array with all the places this dwarf might go. */ unsigned int j = 1; - kk = tkey[game.dloc[i]]; + kk = tkey[game.dwarves[i].loc]; if (kk != 0) do { enum desttype_t desttype = travel[kk].desttype; @@ -334,14 +334,14 @@ static bool dwarfmove(void) continue; else if (!INDEEP(game.newloc)) continue; - else if (game.newloc == game.odloc[i]) + else if (game.newloc == game.dwarves[i].oldloc) continue; else if (j > 1 && game.newloc == tk[j - 1]) continue; else if (j >= DIM(tk) - 1) /* This can't actually happen. */ continue; // LCOV_EXCL_LINE - else if (game.newloc == game.dloc[i]) + else if (game.newloc == game.dwarves[i].loc) continue; else if (FORCED(game.newloc)) continue; @@ -352,23 +352,23 @@ static bool dwarfmove(void) tk[j++] = game.newloc; } while (!travel[kk++].stop); - tk[j] = game.odloc[i]; + tk[j] = game.dwarves[i].oldloc; if (j >= 2) --j; j = 1 + randrange(j); - game.odloc[i] = game.dloc[i]; - game.dloc[i] = tk[j]; - game.dseen[i] = (game.dseen[i] && INDEEP(game.loc)) || - (game.dloc[i] == game.loc || - game.odloc[i] == game.loc); - if (!game.dseen[i]) + game.dwarves[i].oldloc = game.dwarves[i].loc; + game.dwarves[i].loc = tk[j]; + game.dwarves[i].seen = (game.dwarves[i].seen && INDEEP(game.loc)) || + (game.dwarves[i].loc == game.loc || + game.dwarves[i].oldloc == game.loc); + if (!game.dwarves[i].seen) continue; - game.dloc[i] = game.loc; + game.dwarves[i].loc = game.loc; if (spotted_by_pirate(i)) continue; /* This threatening little dwarf is in the room with him! */ ++game.dtotal; - if (game.odloc[i] == game.dloc[i]) { + if (game.dwarves[i].oldloc == game.dwarves[i].loc) { ++attack; if (game.knfloc >= LOC_NOWHERE) game.knfloc = game.loc; @@ -827,8 +827,8 @@ static bool closecheck(void) game.prop[GRATE] = GRATE_CLOSED; game.prop[FISSURE] = UNBRIDGED; for (int i = 1; i <= NDWARVES; i++) { - game.dseen[i] = false; - game.dloc[i] = LOC_NOWHERE; + game.dwarves[i].seen = false; + game.dwarves[i].loc = LOC_NOWHERE; } DESTROY(TROLL); move(TROLL + NOBJECTS, IS_FREE); @@ -1044,7 +1044,7 @@ static bool do_move(void) * place) let him get out (and attacked). */ if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc, COND_NOARRR)) { for (size_t i = 1; i <= NDWARVES - 1; i++) { - if (game.odloc[i] == game.newloc && game.dseen[i]) { + if (game.dwarves[i].oldloc == game.newloc && game.dwarves[i].seen) { game.newloc = game.loc; rspeak(DWARF_BLOCK); break; diff --git a/misc.c b/misc.c index 9971cb5..9502c8b 100644 --- a/misc.c +++ b/misc.c @@ -672,9 +672,9 @@ int atdwrf(loc_t where) return at; at = -1; for (int i = 1; i <= NDWARVES - 1; i++) { - if (game.dloc[i] == where) + if (game.dwarves[i].loc == where) return i; - if (game.dloc[i] != 0) + if (game.dwarves[i].loc != 0) at = 0; } return at; diff --git a/saveresume.c b/saveresume.c index f77925a..d66b52c 100644 --- a/saveresume.c +++ b/saveresume.c @@ -190,8 +190,8 @@ bool is_valid(struct game_t valgame) } /* Bounds check for location arrays */ for (int i = 0; i <= NDWARVES; i++) { - if (valgame.dloc[i] < -1 || valgame.dloc[i] > NLOCATIONS || - valgame.odloc[i] < -1 || valgame.odloc[i] > NLOCATIONS) { + if (valgame.dwarves[i].loc < -1 || valgame.dwarves[i].loc > NLOCATIONS || + valgame.dwarves[i].oldloc < -1 || valgame.dwarves[i].oldloc > NLOCATIONS) { return false; // LCOV_EXCL_LINE } } From 8fe07c8bf36b1c06e8cf8689c04629df0fe51504 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 09:30:33 -0400 Subject: [PATCH 119/213] Structurize locatiuon info. --- actions.c | 6 +++--- advent.h | 6 ++++-- init.c | 2 +- main.c | 20 ++++++++++---------- misc.c | 14 +++++++------- saveresume.c | 4 ++-- 6 files changed, 27 insertions(+), 25 deletions(-) diff --git a/actions.c b/actions.c index 06149d3..4a86f01 100644 --- a/actions.c +++ b/actions.c @@ -303,11 +303,11 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) { if (obj == INTRANSITIVE) { /* Carry, no object given yet. OK if only one object present. */ - if (game.atloc[game.loc] == NO_OBJECT || - game.link[game.atloc[game.loc]] != 0 || + if (game.locs[game.loc].atloc == NO_OBJECT || + game.link[game.locs[game.loc].atloc] != 0 || atdwrf(game.loc) > 0) return GO_UNKNOWN; - obj = game.atloc[game.loc]; + obj = game.locs[game.loc].atloc; } if (TOTING(obj)) { diff --git a/advent.h b/advent.h index 56dcbe5..8150aa2 100644 --- a/advent.h +++ b/advent.h @@ -182,8 +182,10 @@ struct game_t { turn_t trnluz; // # points lost so far due to turns used turn_t turns; // counts commands given (ignores yes/no) char zzword[TOKLEN + 1]; // randomly generated magic word from bird - int abbrev[NLOCATIONS + 1]; // has location been seen? - int atloc[NLOCATIONS + 1]; // head of object linked list per location + struct { + int abbrev; // has location been seen? + int atloc; // head of object linked list per location + } locs[NLOCATIONS + 1]; struct { int seen; // true if dwarf has seen him loc_t loc; // location of dwarves, initially hard-wired in diff --git a/init.c b/init.c index b84f5fc..29737be 100644 --- a/init.c +++ b/init.c @@ -64,7 +64,7 @@ int initialise(void) } } - /* Set up the game.atloc and game.link arrays. + /* Set up the game.locs atloc and game.link arrays. * We'll use the DROP subroutine, which prefaces new objects on the * lists. Since we want things in the other order, we'll run the * loop backwards. If the object is in two locs, we drop it twice. diff --git a/main.c b/main.c index 3d17ec9..98a1d7f 100644 --- a/main.c +++ b/main.c @@ -131,9 +131,9 @@ static void checkhints(void) game.hintlc[hint] = 0; return; case 3: /* maze */ - if (game.atloc[game.loc] == NO_OBJECT && - game.atloc[game.oldloc] == NO_OBJECT && - game.atloc[game.oldlc2] == NO_OBJECT && + if (game.locs[game.loc].atloc == NO_OBJECT && + game.locs[game.oldloc].atloc == NO_OBJECT && + game.locs[game.oldlc2].atloc == NO_OBJECT && game.holdng > 1) break; game.hintlc[hint] = 0; @@ -151,9 +151,9 @@ static void checkhints(void) game.hintlc[hint] = 0; return; case 7: /* woods */ - if (game.atloc[game.loc] == NO_OBJECT && - game.atloc[game.oldloc] == NO_OBJECT && - game.atloc[game.oldlc2] == NO_OBJECT) + if (game.locs[game.loc].atloc == NO_OBJECT && + game.locs[game.oldloc].atloc == NO_OBJECT && + game.locs[game.oldlc2].atloc == NO_OBJECT) break; return; case 8: /* ogre */ @@ -458,7 +458,7 @@ static void describe_location(void) { const char* msg = locations[game.loc].description.small; - if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == NO_MESSAGE) + if (MOD(game.locs[game.loc].abbrev, game.abbnum) == 0 || msg == NO_MESSAGE) msg = locations[game.loc].description.big; if (!FORCED(game.loc) && DARK(game.loc)) { @@ -551,7 +551,7 @@ static void playermove(int motion) rspeak(NO_MORE_DETAIL); ++game.detail; game.wzdark = false; - game.abbrev[game.loc] = 0; + game.locs[game.loc].abbrev = 0; return; } else if (motion == CAVE) { /* Cave. Different messages depending on whether above ground. */ @@ -910,8 +910,8 @@ static void listobjects(void) * get full score. */ { if (!DARK(game.loc)) { - ++game.abbrev[game.loc]; - for (int i = game.atloc[game.loc]; i != 0; i = game.link[i]) { + ++game.locs[game.loc].abbrev; + for (int i = game.locs[game.loc].atloc; i != 0; i = game.link[i]) { obj_t obj = i; if (obj > NOBJECTS) obj = obj - NOBJECTS; diff --git a/misc.c b/misc.c index 9502c8b..450f727 100644 --- a/misc.c +++ b/misc.c @@ -581,7 +581,7 @@ void move(obj_t object, loc_t where) /* Place any object anywhere by picking it up and dropping it. May * already be toting, in which case the carry is a no-op. Mustn't * pick up objects which are not at any loc, since carry wants to - * remove objects from game.atloc chains. */ + * remove objects from game atloc chains. */ { loc_t from; @@ -625,11 +625,11 @@ void carry(obj_t object, loc_t where) if (object != BIRD) ++game.holdng; } - if (game.atloc[where] == object) { - game.atloc[where] = game.link[object]; + if (game.locs[where].atloc == object) { + game.locs[where].atloc = game.link[object]; return; } - temp = game.atloc[where]; + temp = game.locs[where].atloc; while (game.link[temp] != object) { temp = game.link[temp]; } @@ -637,7 +637,7 @@ void carry(obj_t object, loc_t where) } void drop(obj_t object, loc_t where) -/* Place an object at a given loc, prefixing it onto the game.atloc list. Decr +/* Place an object at a given loc, prefixing it onto the game atloc list. Decr * game.holdng if the object was being toted. No state change on the object. */ { if (object > NOBJECTS) @@ -656,8 +656,8 @@ void drop(obj_t object, loc_t where) } if (where == LOC_NOWHERE || where == CARRIED) return; - game.link[object] = game.atloc[where]; - game.atloc[where] = object; + game.link[object] = game.locs[where].atloc; + game.locs[where].atloc = object; } int atdwrf(loc_t where) diff --git a/saveresume.c b/saveresume.c index d66b52c..53278ae 100644 --- a/saveresume.c +++ b/saveresume.c @@ -109,7 +109,7 @@ int resume(void) #endif FILE *fp = NULL; - if (game.loc != LOC_START || game.abbrev[LOC_START] != 1) { + if (game.loc != LOC_START || game.locs[LOC_START].abbrev != 1) { rspeak(RESUME_ABANDON); if (!yes_or_no(arbitrary_messages[THIS_ACCEPTABLE], arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN])) return GO_CLEAROBJ; @@ -258,7 +258,7 @@ bool is_valid(struct game_t valgame) /* Check that values in linked lists for objects in locations are inside bounds */ for (loc_t loc = LOC_NOWHERE; loc <= NLOCATIONS; loc++) { - if (valgame.atloc[loc] < NO_OBJECT || valgame.atloc[loc] > NOBJECTS * 2) { + if (valgame.locs[loc].atloc < NO_OBJECT || valgame.locs[loc].atloc > NOBJECTS * 2) { return false; // LCOV_EXCL_LINE } } From eebc87f889b0fa1404684aa6e72dda5a5e53d96b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 09:51:49 -0400 Subject: [PATCH 120/213] Structurize object info. --- actions.c | 206 ++++++++++++++++++++++++++------------------------- advent.h | 18 +++-- init.c | 8 +- main.c | 106 +++++++++++++------------- misc.c | 20 ++--- saveresume.c | 12 +-- score.c | 6 +- 7 files changed, 190 insertions(+), 186 deletions(-) diff --git a/actions.c b/actions.c index 4a86f01..20f0b90 100644 --- a/actions.c +++ b/actions.c @@ -34,7 +34,7 @@ static phase_codes_t attack(command_t command) obj = SNAKE; ++changes; } - if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) { + if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) { obj = DRAGON; ++changes; } @@ -46,7 +46,7 @@ static phase_codes_t attack(command_t command) obj = OGRE; ++changes; } - if (HERE(BEAR) && game.prop[BEAR] == UNTAMED_BEAR) { + if (HERE(BEAR) && game.objects[BEAR].prop == UNTAMED_BEAR) { obj = BEAR; ++changes; } @@ -83,13 +83,13 @@ static phase_codes_t attack(command_t command) } if (obj == VEND) { state_change(VEND, - game.prop[VEND] == VEND_BLOCKS ? VEND_UNBLOCKS : VEND_BLOCKS); + game.objects[VEND].prop == VEND_BLOCKS ? VEND_UNBLOCKS : VEND_BLOCKS); return GO_CLEAROBJ; } if (obj == BEAR) { - switch (game.prop[BEAR]) { + switch (game.objects[BEAR].prop) { case UNTAMED_BEAR: rspeak(BEAR_HANDS); break; @@ -105,7 +105,7 @@ static phase_codes_t attack(command_t command) } return GO_CLEAROBJ; } - if (obj == DRAGON && game.prop[DRAGON] == DRAGON_BARS) { + if (obj == DRAGON && game.objects[DRAGON].prop == DRAGON_BARS) { /* Fun stuff for dragon. If he insists on attacking it, win! * Set game.prop to dead, move dragon to central loc (still * fixed), move rug there (not fixed), and move him there, @@ -116,7 +116,7 @@ static phase_codes_t attack(command_t command) return GO_MOVE; } state_change(DRAGON, DRAGON_DEAD); - game.prop[RUG] = RUG_FLOOR; + game.objects[RUG].prop = RUG_FLOOR; /* Hardcoding LOC_SECRET5 as the dragon's death location is ugly. * The way it was computed before was worse; it depended on the * two dragon locations being LOC_SECRET4 and LOC_SECRET6 and @@ -128,8 +128,8 @@ static phase_codes_t attack(command_t command) move(RUG, LOC_SECRET5); drop(BLOOD, LOC_SECRET5); for (obj_t i = 1; i <= NOBJECTS; i++) { - if (game.place[i] == objects[DRAGON].plac || - game.place[i] == objects[DRAGON].fixd) + if (game.objects[i].place == objects[DRAGON].plac || + game.objects[i].place == objects[DRAGON].fixd) move(i, LOC_SECRET5); } game.loc = LOC_SECRET5; @@ -210,15 +210,16 @@ static phase_codes_t bigwords(vocab_t id) return GO_CLEAROBJ; } game.foobar = WORD_EMPTY; - if (game.place[EGGS] == objects[EGGS].plac || + if (game.objects[EGGS].place == objects[EGGS].plac || (TOTING(EGGS) && game.loc == objects[EGGS].plac)) { rspeak(NOTHING_HAPPENS); return GO_CLEAROBJ; } else { /* Bring back troll if we steal the eggs back from him before * crossing. */ - if (game.place[EGGS] == LOC_NOWHERE && game.place[TROLL] == LOC_NOWHERE && game.prop[TROLL] == TROLL_UNPAID) - game.prop[TROLL] = TROLL_PAIDONCE; + if (game.objects[EGGS].place == LOC_NOWHERE && game.objects[TROLL].place == LOC_NOWHERE + && game.objects[TROLL].prop == TROLL_UNPAID) + game.objects[TROLL].prop = TROLL_PAIDONCE; if (HERE(EGGS)) pspeak(EGGS, look, true, EGGS_VANISHED); else if (game.loc == objects[EGGS].plac) @@ -243,7 +244,7 @@ static phase_codes_t bigwords(vocab_t id) static void blast(void) /* Blast. No effect unless you've got dynamite, which is a neat trick! */ { - if (game.prop[ROD2] == STATE_NOTFOUND || !game.closed) + if (game.objects[ROD2].prop == STATE_NOTFOUND || !game.closed) rspeak(REQUIRES_DYNAMITE); else { if (HERE(ROD2)) { @@ -273,11 +274,11 @@ static phase_codes_t vbreak(verb_t verb, obj_t obj) break; } case VASE: - if (game.prop[VASE] == VASE_WHOLE) { + if (game.objects[VASE].prop == VASE_WHOLE) { if (TOTING(VASE)) drop(VASE, game.loc); state_change(VASE, VASE_BROKEN); - game.fixed[VASE] = IS_FIXED; + game.objects[VASE].fixed = IS_FIXED; break; } /* FALLTHRU */ @@ -321,20 +322,20 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) return GO_CLEAROBJ; } - if (game.fixed[obj] != IS_FREE) { + if (game.objects[obj].fixed != IS_FREE) { switch (obj) { case PLANT: /* Next guard tests whether plant is tiny or stashed */ - rspeak(game.prop[PLANT] <= PLANT_THIRSTY ? DEEP_ROOTS : YOU_JOKING); + rspeak(game.objects[PLANT].prop <= PLANT_THIRSTY ? DEEP_ROOTS : YOU_JOKING); break; case BEAR: - rspeak( game.prop[BEAR] == SITTING_BEAR ? BEAR_CHAINED : YOU_JOKING); + rspeak( game.objects[BEAR].prop == SITTING_BEAR ? BEAR_CHAINED : YOU_JOKING); break; case CHAIN: - rspeak( game.prop[BEAR] != UNTAMED_BEAR ? STILL_LOCKED : YOU_JOKING); + rspeak( game.objects[BEAR].prop != UNTAMED_BEAR ? STILL_LOCKED : YOU_JOKING); break; case RUG: - rspeak(game.prop[RUG] == RUG_HOVER ? RUG_HOVERS : YOU_JOKING); + rspeak(game.objects[RUG].prop == RUG_HOVER ? RUG_HOVERS : YOU_JOKING); break; case URN: rspeak(URN_NOBUDGE); @@ -360,7 +361,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) rspeak(NO_CONTAINER); return GO_CLEAROBJ; } - if (game.prop[BOTTLE] == EMPTY_BOTTLE) { + if (game.objects[BOTTLE].prop == EMPTY_BOTTLE) { return (fill(verb, BOTTLE)); } else rspeak(BOTTLE_FULL); @@ -375,8 +376,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) } - if (obj == BIRD && game.prop[BIRD] != BIRD_CAGED && STASHED(BIRD) != BIRD_CAGED) { - if (game.prop[BIRD] == BIRD_FOREST_UNCAGED) { + if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && STASHED(BIRD) != BIRD_CAGED) { + if (game.objects[BIRD].prop == BIRD_FOREST_UNCAGED) { DESTROY(BIRD); rspeak(BIRD_CRAP); return GO_CLEAROBJ; @@ -389,10 +390,10 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) rspeak(BIRD_EVADES); return GO_CLEAROBJ; } - game.prop[BIRD] = BIRD_CAGED; + game.objects[BIRD].prop = BIRD_CAGED; } if ((obj == BIRD || obj == CAGE) && - (game.prop[BIRD] == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) { + (game.objects[BIRD].prop == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) { /* expression maps BIRD to CAGE and CAGE to BIRD */ carry(BIRD + CAGE - obj, game.loc); } @@ -400,11 +401,11 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) carry(obj, game.loc); if (obj == BOTTLE && LIQUID() != NO_OBJECT) - game.place[LIQUID()] = CARRIED; + game.objects[LIQUID()].place = CARRIED; - if (GSTONE(obj) && game.prop[obj] != STATE_FOUND) { - game.prop[obj] = STATE_FOUND; - game.prop[CAVITY] = CAVITY_EMPTY; + if (GSTONE(obj) && game.objects[obj].prop != STATE_FOUND) { + game.objects[obj].prop = STATE_FOUND; + game.objects[CAVITY].prop = CAVITY_EMPTY; } rspeak(OK_MAN); return GO_CLEAROBJ; @@ -414,36 +415,36 @@ static int chain(verb_t verb) /* Do something to the bear's chain */ { if (verb != LOCK) { - if (game.prop[BEAR] == UNTAMED_BEAR) { + if (game.objects[BEAR].prop == UNTAMED_BEAR) { rspeak(BEAR_BLOCKS); return GO_CLEAROBJ; } - if (game.prop[CHAIN] == CHAIN_HEAP) { + if (game.objects[CHAIN].prop == CHAIN_HEAP) { rspeak(ALREADY_UNLOCKED); return GO_CLEAROBJ; } - game.prop[CHAIN] = CHAIN_HEAP; - game.fixed[CHAIN] = IS_FREE; - if (game.prop[BEAR] != BEAR_DEAD) - game.prop[BEAR] = CONTENTED_BEAR; + game.objects[CHAIN].prop = CHAIN_HEAP; + game.objects[CHAIN].fixed = IS_FREE; + if (game.objects[BEAR].prop != BEAR_DEAD) + game.objects[BEAR].prop = CONTENTED_BEAR; - switch (game.prop[BEAR]) { + switch (game.objects[BEAR].prop) { // LCOV_EXCL_START case BEAR_DEAD: /* Can't be reached until the bear can die in some way other * than a bridge collapse. Leave in in case this changes, but * exclude from coverage testing. */ - game.fixed[BEAR] = IS_FIXED; + game.objects[BEAR].fixed = IS_FIXED; break; // LCOV_EXCL_STOP default: - game.fixed[BEAR] = IS_FREE; + game.objects[BEAR].fixed = IS_FREE; } rspeak(CHAIN_UNLOCKED); return GO_CLEAROBJ; } - if (game.prop[CHAIN] != CHAIN_HEAP) { + if (game.objects[CHAIN].prop != CHAIN_HEAP) { rspeak(ALREADY_LOCKED); return GO_CLEAROBJ; } @@ -452,11 +453,11 @@ static int chain(verb_t verb) return GO_CLEAROBJ; } - game.prop[CHAIN] = CHAIN_FIXED; + game.objects[CHAIN].prop = CHAIN_FIXED; if (TOTING(CHAIN)) drop(CHAIN, game.loc); - game.fixed[CHAIN] = IS_FIXED; + game.objects[CHAIN].fixed = IS_FIXED; rspeak(CHAIN_LOCKED); return GO_CLEAROBJ; @@ -476,12 +477,12 @@ static phase_codes_t discard(verb_t verb, obj_t obj) return GO_CLEAROBJ; } - if (GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != CAVITY_FULL) { + if (GSTONE(obj) && AT(CAVITY) && game.objects[CAVITY].prop != CAVITY_FULL) { rspeak(GEM_FITS); - game.prop[obj] = STATE_IN_CAVITY; - game.prop[CAVITY] = CAVITY_FULL; - if (HERE(RUG) && ((obj == EMERALD && game.prop[RUG] != RUG_HOVER) || - (obj == RUBY && game.prop[RUG] == RUG_HOVER))) { + game.objects[obj].prop = STATE_IN_CAVITY; + game.objects[CAVITY].prop = CAVITY_FULL; + if (HERE(RUG) && ((obj == EMERALD && game.objects[RUG].prop != RUG_HOVER) || + (obj == RUBY && game.objects[RUG].prop == RUG_HOVER))) { if (obj == RUBY) rspeak(RUG_SETTLES); else if (TOTING(RUG)) @@ -489,8 +490,8 @@ static phase_codes_t discard(verb_t verb, obj_t obj) else rspeak(RUG_RISES); if (!TOTING(RUG) || obj == RUBY) { - int k = (game.prop[RUG] == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER; - game.prop[RUG] = k; + int k = (game.objects[RUG].prop == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER; + game.objects[RUG].prop = k; if (k == RUG_HOVER) k = objects[SAPPH].plac; move(RUG + NOBJECTS, k); @@ -510,7 +511,7 @@ static phase_codes_t discard(verb_t verb, obj_t obj) if (LIQUID() == obj) obj = BOTTLE; if (obj == BOTTLE && LIQUID() != NO_OBJECT) { - game.place[LIQUID()] = LOC_NOWHERE; + game.objects[LIQUID()].place = LOC_NOWHERE; } if (obj == BEAR && AT(TROLL)) { @@ -529,19 +530,19 @@ static phase_codes_t discard(verb_t verb, obj_t obj) state_change(VASE, AT(PILLOW) ? VASE_WHOLE : VASE_DROPPED); - if (game.prop[VASE] != VASE_WHOLE) - game.fixed[VASE] = IS_FIXED; + if (game.objects[VASE].prop != VASE_WHOLE) + game.objects[VASE].fixed = IS_FIXED; drop(obj, game.loc); return GO_CLEAROBJ; } } - if (obj == CAGE && game.prop[BIRD] == BIRD_CAGED) { + if (obj == CAGE && game.objects[BIRD].prop == BIRD_CAGED) { drop(BIRD, game.loc); } if (obj == BIRD) { - if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) { + if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) { rspeak(BIRD_BURNT); DESTROY(BIRD); return GO_CLEAROBJ; @@ -552,11 +553,11 @@ static phase_codes_t discard(verb_t verb, obj_t obj) return GO_DWARFWAKE; DESTROY(SNAKE); /* Set game.prop for use by travel options */ - game.prop[SNAKE] = SNAKE_CHASED; + game.objects[SNAKE].prop = SNAKE_CHASED; } else rspeak(OK_MAN); - game.prop[BIRD] = FOREST(game.loc) ? BIRD_FOREST_UNCAGED : BIRD_UNCAGED; + game.objects[BIRD].prop = FOREST(game.loc) ? BIRD_FOREST_UNCAGED : BIRD_UNCAGED; drop(obj, game.loc); return GO_CLEAROBJ; } @@ -587,7 +588,7 @@ static phase_codes_t drink(verb_t verb, obj_t obj) return GO_CLEAROBJ; } if (LIQUID() == WATER && HERE(BOTTLE)) { - game.place[WATER] = LOC_NOWHERE; + game.objects[WATER].place = LOC_NOWHERE; state_change(BOTTLE, EMPTY_BOTTLE); return GO_CLEAROBJ; } @@ -630,9 +631,9 @@ static phase_codes_t extinguish(verb_t verb, obj_t obj) /* Extinguish. Lamp, urn, dragon/volcano (nice try). */ { if (obj == INTRANSITIVE) { - if (HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT) + if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) obj = LAMP; - if (HERE(URN) && game.prop[URN] == URN_LIT) + if (HERE(URN) && game.objects[URN].prop == URN_LIT) obj = URN; if (obj == INTRANSITIVE) return GO_UNKNOWN; @@ -640,7 +641,7 @@ static phase_codes_t extinguish(verb_t verb, obj_t obj) switch (obj) { case URN: - if (game.prop[URN] != URN_EMPTY) { + if (game.objects[URN].prop != URN_EMPTY) { state_change(URN, URN_DARK); } else { pspeak(URN, change, true, URN_DARK); @@ -671,7 +672,7 @@ static phase_codes_t feed(verb_t verb, obj_t obj) rspeak(BIRD_PINING); break; case DRAGON: - if (game.prop[DRAGON] != DRAGON_BARS) + if (game.objects[DRAGON].prop != DRAGON_BARS) rspeak(RIDICULOUS_ATTEMPT); else rspeak(NOTHING_EDIBLE); @@ -694,15 +695,15 @@ static phase_codes_t feed(verb_t verb, obj_t obj) speak(actions[verb].message); break; case BEAR: - if (game.prop[BEAR] == BEAR_DEAD) { + if (game.objects[BEAR].prop == BEAR_DEAD) { rspeak(RIDICULOUS_ATTEMPT); break; } - if (game.prop[BEAR] == UNTAMED_BEAR) { + if (game.objects[BEAR].prop == UNTAMED_BEAR) { if (HERE(FOOD)) { DESTROY(FOOD); - game.fixed[AXE] = IS_FREE; - game.prop[AXE] = AXE_HERE; + game.objects[AXE].fixed = IS_FREE; + game.objects[AXE].prop = AXE_HERE; state_change(BEAR, SITTING_BEAR); } else rspeak(NOTHING_EDIBLE); @@ -736,14 +737,14 @@ phase_codes_t fill(verb_t verb, obj_t obj) return GO_CLEAROBJ; } rspeak(SHATTER_VASE); - game.prop[VASE] = VASE_BROKEN; - game.fixed[VASE] = IS_FIXED; + game.objects[VASE].prop = VASE_BROKEN; + game.objects[VASE].fixed = IS_FIXED; drop(VASE, game.loc); return GO_CLEAROBJ; } if (obj == URN) { - if (game.prop[URN] != URN_EMPTY) { + if (game.objects[URN].prop != URN_EMPTY) { rspeak(FULL_URN); return GO_CLEAROBJ; } @@ -754,12 +755,12 @@ phase_codes_t fill(verb_t verb, obj_t obj) int k = LIQUID(); switch (k) { case WATER: - game.prop[BOTTLE] = EMPTY_BOTTLE; + game.objects[BOTTLE].prop = EMPTY_BOTTLE; rspeak(WATER_URN); break; case OIL: - game.prop[URN] = URN_DARK; - game.prop[BOTTLE] = EMPTY_BOTTLE; + game.objects[URN].prop = URN_DARK; + game.objects[BOTTLE].prop = EMPTY_BOTTLE; rspeak(OIL_URN); break; case NO_OBJECT: @@ -767,7 +768,7 @@ phase_codes_t fill(verb_t verb, obj_t obj) rspeak(FILL_INVALID); return GO_CLEAROBJ; } - game.place[k] = LOC_NOWHERE; + game.objects[k].place = LOC_NOWHERE; return GO_CLEAROBJ; } if (obj != INTRANSITIVE && obj != BOTTLE) { @@ -777,7 +778,7 @@ phase_codes_t fill(verb_t verb, obj_t obj) if (obj == INTRANSITIVE && !HERE(BOTTLE)) return GO_UNKNOWN; - if (HERE(URN) && game.prop[URN] != URN_EMPTY) { + if (HERE(URN) && game.objects[URN].prop != URN_EMPTY) { rspeak(URN_NOPOUR); return GO_CLEAROBJ; } @@ -794,7 +795,7 @@ phase_codes_t fill(verb_t verb, obj_t obj) ? OIL_BOTTLE : WATER_BOTTLE); if (TOTING(BOTTLE)) - game.place[LIQUID()] = CARRIED; + game.objects[LIQUID()].place = CARRIED; return GO_CLEAROBJ; } @@ -830,7 +831,7 @@ static phase_codes_t fly(verb_t verb, obj_t obj) rspeak(FLAP_ARMS); return GO_CLEAROBJ; } - if (game.prop[RUG] != RUG_HOVER) { + if (game.objects[RUG].prop != RUG_HOVER) { rspeak(RUG_NOTHING2); return GO_CLEAROBJ; } @@ -841,7 +842,7 @@ static phase_codes_t fly(verb_t verb, obj_t obj) speak(actions[verb].message); return GO_CLEAROBJ; } - if (game.prop[RUG] != RUG_HOVER) { + if (game.objects[RUG].prop != RUG_HOVER) { rspeak(RUG_NOTHING1); return GO_CLEAROBJ; } @@ -890,11 +891,11 @@ static phase_codes_t light(verb_t verb, obj_t obj) { if (obj == INTRANSITIVE) { int selects = 0; - if (HERE(LAMP) && game.prop[LAMP] == LAMP_DARK && game.limit >= 0) { + if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_DARK && game.limit >= 0) { obj = LAMP; selects++; } - if (HERE(URN) && game.prop[URN] == URN_DARK) { + if (HERE(URN) && game.objects[URN].prop == URN_DARK) { obj = URN; selects++; } @@ -904,7 +905,7 @@ static phase_codes_t light(verb_t verb, obj_t obj) switch (obj) { case URN: - state_change(URN, game.prop[URN] == URN_EMPTY ? + state_change(URN, game.objects[URN].prop == URN_EMPTY ? URN_EMPTY : URN_LIT); break; @@ -935,9 +936,9 @@ static phase_codes_t listen(void) soundlatch = true; } for (obj_t i = 1; i <= NOBJECTS; i++) { - if (!HERE(i) || objects[i].sounds[0] == NULL || game.prop[i] < 0) + if (!HERE(i) || objects[i].sounds[0] == NULL || game.objects[i].prop < 0) continue; - int mi = game.prop[i]; + int mi = game.objects[i].prop; /* (ESR) Some unpleasant magic on object states here. Ideally * we'd have liked the bird to be a normal object that we can * use state_change() on; can't do it, because there are @@ -1026,7 +1027,7 @@ static phase_codes_t lock(verb_t verb, obj_t obj) rspeak(OYSTER_OPENS); break; case DOOR: - rspeak((game.prop[DOOR] == DOOR_UNRUSTED) ? OK_MAN : RUSTY_DOOR); + rspeak((game.objects[DOOR].prop == DOOR_UNRUSTED) ? OK_MAN : RUSTY_DOOR); break; case CAGE: rspeak( NO_LOCK); @@ -1058,10 +1059,10 @@ static phase_codes_t pour(verb_t verb, obj_t obj) rspeak(CANT_POUR); return GO_CLEAROBJ; } - if (HERE(URN) && game.prop[URN] == URN_EMPTY) + if (HERE(URN) && game.objects[URN].prop == URN_EMPTY) return fill(verb, URN); - game.prop[BOTTLE] = EMPTY_BOTTLE; - game.place[obj] = LOC_NOWHERE; + game.objects[BOTTLE].prop = EMPTY_BOTTLE; + game.objects[obj].place = LOC_NOWHERE; if (!(AT(PLANT) || AT(DOOR))) { rspeak(GROUND_WET); return GO_CLEAROBJ; @@ -1069,8 +1070,8 @@ static phase_codes_t pour(verb_t verb, obj_t obj) if (!AT(DOOR)) { if (obj == WATER) { /* cycle through the three plant states */ - state_change(PLANT, MOD(game.prop[PLANT] + 1, 3)); - game.prop[PLANT2] = game.prop[PLANT]; + state_change(PLANT, MOD(game.objects[PLANT].prop + 1, 3)); + game.objects[PLANT2].prop = game.objects[PLANT].prop; return GO_MOVE; } else { rspeak(SHAKING_LEAVES); @@ -1098,7 +1099,7 @@ static phase_codes_t read(command_t command) if (command.obj == INTRANSITIVE) { command.obj = NO_OBJECT; for (int i = 1; i <= NOBJECTS; i++) { - if (HERE(i) && objects[i].texts[0] != NULL && game.prop[i] >= 0) + if (HERE(i) && objects[i].texts[0] != NULL && game.objects[i].prop >= 0) command.obj = command.obj * NOBJECTS + i; } if (command.obj > NOBJECTS || command.obj == NO_OBJECT || DARK(game.loc)) @@ -1116,10 +1117,10 @@ static phase_codes_t read(command_t command) pspeak(OYSTER, hear, true, 1); // Not really a sound, but oh well. } } else if (objects[command.obj].texts[0] == NULL || - game.prop[command.obj] == STATE_NOTFOUND) { + game.objects[command.obj].prop == STATE_NOTFOUND) { speak(actions[command.verb].message); } else - pspeak(command.obj, study, true, game.prop[command.obj]); + pspeak(command.obj, study, true, game.objects[command.obj].prop); return GO_CLEAROBJ; } @@ -1131,7 +1132,7 @@ static phase_codes_t reservoir(void) return GO_CLEAROBJ; } else { state_change(RESER, - game.prop[RESER] == WATERS_PARTED ? WATERS_UNPARTED : WATERS_PARTED); + game.objects[RESER].prop == WATERS_PARTED ? WATERS_UNPARTED : WATERS_PARTED); if (AT(RESER)) return GO_CLEAROBJ; else { @@ -1146,10 +1147,10 @@ static phase_codes_t reservoir(void) static phase_codes_t rub(verb_t verb, obj_t obj) /* Rub. Yields various snide remarks except for lit urn. */ { - if (obj == URN && game.prop[URN] == URN_LIT) { + if (obj == URN && game.objects[URN].prop == URN_LIT) { DESTROY(URN); drop(AMBER, game.loc); - game.prop[AMBER] = AMBER_IN_ROCK; + game.objects[AMBER].prop = AMBER_IN_ROCK; --game.tally; drop(CAVITY, game.loc); rspeak(URN_GENIES); @@ -1223,16 +1224,16 @@ static phase_codes_t throwit(command_t command) return (discard(command.verb, command.obj)); else { if (atdwrf(game.loc) <= 0) { - if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) + if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) return throw_support(DRAGON_SCALES); if (AT(TROLL)) return throw_support(TROLL_RETURNS); if (AT(OGRE)) return throw_support(OGRE_DODGE); - if (HERE(BEAR) && game.prop[BEAR] == UNTAMED_BEAR) { + if (HERE(BEAR) && game.objects[BEAR].prop == UNTAMED_BEAR) { /* This'll teach him to throw the axe at the bear! */ drop(AXE, game.loc); - game.fixed[AXE] = IS_FIXED; + game.objects[AXE].fixed = IS_FIXED; juggle(BEAR); state_change(AXE, AXE_LOST); return GO_CLEAROBJ; @@ -1295,32 +1296,33 @@ static phase_codes_t wave(verb_t verb, obj_t obj) return GO_CLEAROBJ; } - if (game.prop[BIRD] == BIRD_UNCAGED && game.loc == game.place[STEPS] && game.prop[JADE] == STATE_NOTFOUND) { + if (game.objects[BIRD].prop == BIRD_UNCAGED && game.loc == game.objects[STEPS].place + && game.objects[JADE].prop == STATE_NOTFOUND) { drop(JADE, game.loc); - game.prop[JADE] = STATE_FOUND; + game.objects[JADE].prop = STATE_FOUND; --game.tally; rspeak(NECKLACE_FLY); return GO_CLEAROBJ; } else { if (game.closed) { - rspeak((game.prop[BIRD] == BIRD_CAGED) ? + rspeak((game.objects[BIRD].prop == BIRD_CAGED) ? CAGE_FLY : FREE_FLY); return GO_DWARFWAKE; } if (game.closng || !AT(FISSURE)) { - rspeak((game.prop[BIRD] == BIRD_CAGED) ? + rspeak((game.objects[BIRD].prop == BIRD_CAGED) ? CAGE_FLY : FREE_FLY); return GO_CLEAROBJ; } if (HERE(BIRD)) - rspeak((game.prop[BIRD] == BIRD_CAGED) ? + rspeak((game.objects[BIRD].prop == BIRD_CAGED) ? CAGE_FLY : FREE_FLY); state_change(FISSURE, - game.prop[FISSURE] == BRIDGED ? UNBRIDGED : BRIDGED); + game.objects[FISSURE].prop == BRIDGED ? UNBRIDGED : BRIDGED); return GO_CLEAROBJ; } } @@ -1353,10 +1355,10 @@ phase_codes_t action(command_t command) else if (!game.closed && ((LIQUID() == command.obj && HERE(BOTTLE)) || command.obj == LIQLOC(game.loc))) /* FALL THROUGH */; - else if (command.obj == OIL && HERE(URN) && game.prop[URN] != URN_EMPTY) { + else if (command.obj == OIL && HERE(URN) && game.objects[URN].prop != URN_EMPTY) { command.obj = URN; /* FALL THROUGH */; - } else if (command.obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != PLANT_THIRSTY) { + } else if (command.obj == PLANT && AT(PLANT2) && game.objects[PLANT2].prop != PLANT_THIRSTY) { command.obj = PLANT2; /* FALL THROUGH */; } else if (command.obj == KNIFE && game.knfloc == game.loc) { diff --git a/advent.h b/advent.h index 8150aa2..04d2fc2 100644 --- a/advent.h +++ b/advent.h @@ -51,7 +51,7 @@ /* Map a state property value to a negative range, where the object cannot be * picked up but the value can be recovered later. Avoid colliding with -1, * which has its own meaning as STATE_NOTFOUND. */ -#define STASHED(obj) (-1 - game.prop[obj]) +#define STASHED(obj) (-1 - game.objects[obj].prop) #define PROMPT "> " @@ -76,14 +76,14 @@ */ #define DESTROY(N) move(N, LOC_NOWHERE) #define MOD(N,M) ((N) % (M)) -#define TOTING(OBJ) (game.place[OBJ] == CARRIED) -#define AT(OBJ) (game.place[OBJ] == game.loc || game.fixed[OBJ] == game.loc) +#define TOTING(OBJ) (game.objects[OBJ].place == CARRIED) +#define AT(OBJ) (game.objects[OBJ].place == game.loc || game.objects[OBJ].fixed == game.loc) #define HERE(OBJ) (AT(OBJ) || TOTING(OBJ)) #define CNDBIT(L,N) (tstbit(conditions[L],N)) -#define LIQUID() (game.prop[BOTTLE] == WATER_BOTTLE? WATER : game.prop[BOTTLE] == OIL_BOTTLE ? OIL : NO_OBJECT ) +#define LIQUID() (game.objects[BOTTLE].prop == WATER_BOTTLE? WATER : game.objects[BOTTLE].prop == OIL_BOTTLE ? OIL : NO_OBJECT ) #define LIQLOC(LOC) (CNDBIT((LOC),COND_FLUID)? CNDBIT((LOC),COND_OILY) ? OIL : WATER : NO_OBJECT) #define FORCED(LOC) CNDBIT(LOC, COND_FORCED) -#define DARK(DUMMY) (!CNDBIT(game.loc,COND_LIT) && (game.prop[LAMP] == LAMP_DARK || !HERE(LAMP))) +#define DARK(DUMMY) (!CNDBIT(game.loc,COND_LIT) && (game.objects[LAMP].prop == LAMP_DARK || !HERE(LAMP))) #define PCT(N) (randrange(100) < (N)) #define GSTONE(OBJ) ((OBJ) == EMERALD || (OBJ) == RUBY || (OBJ) == AMBER || (OBJ) == SAPPH) #define FOREST(LOC) CNDBIT(LOC, COND_FOREST) @@ -191,12 +191,14 @@ struct game_t { loc_t loc; // location of dwarves, initially hard-wired in loc_t oldloc; // prior loc of each dwarf, initially garbage } dwarves[NDWARVES + 1]; - loc_t fixed[NOBJECTS + 1]; // fixed location of object (if not IS_FREE) + struct object { + loc_t fixed; // fixed location of object (if not IS_FREE) + int prop; // object state */ + loc_t place; // location of object + } objects[NOBJECTS + 1]; obj_t link[NOBJECTS * 2 + 1];// object-list links - loc_t place[NOBJECTS + 1]; // location of object bool hinted[NHINTS]; // hinted[i] = true iff hint i has been used. int hintlc[NHINTS]; // hintlc[i] = show int at LOC with cond bit i - int prop[NOBJECTS + 1]; // object state array */ }; /* diff --git a/init.c b/init.c index 29737be..c384f71 100644 --- a/init.c +++ b/init.c @@ -53,7 +53,7 @@ int initialise(void) set_seed(seedval); for (int i = 1; i <= NOBJECTS; i++) { - game.place[i] = LOC_NOWHERE; + game.objects[i].place = LOC_NOWHERE; } for (int i = 1; i <= NLOCATIONS; i++) { @@ -79,7 +79,7 @@ int initialise(void) for (int i = 1; i <= NOBJECTS; i++) { int k = NOBJECTS + 1 - i; - game.fixed[k] = objects[k].fixd; + game.objects[k].fixed = objects[k].fixd; if (objects[k].plac != 0 && objects[k].fixd <= 0) drop(k, objects[k].plac); } @@ -90,8 +90,8 @@ int initialise(void) for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { if (objects[treasure].inventory != 0) - game.prop[treasure] = STATE_NOTFOUND; - game.tally = game.tally - game.prop[treasure]; + game.objects[treasure].prop = STATE_NOTFOUND; + game.tally = game.tally - game.objects[treasure].prop; } } game.conds = setbit(COND_HBASE); diff --git a/main.c b/main.c index 98a1d7f..5e7d6ab 100644 --- a/main.c +++ b/main.c @@ -117,12 +117,12 @@ static void checkhints(void) switch (hint) { case 0: /* cave */ - if (game.prop[GRATE] == GRATE_CLOSED && !HERE(KEYS)) + if (game.objects[GRATE].prop == GRATE_CLOSED && !HERE(KEYS)) break; game.hintlc[hint] = 0; return; case 1: /* bird */ - if (game.place[BIRD] == game.loc && TOTING(ROD) && game.oldobj == BIRD) + if (game.objects[BIRD].place == game.loc && TOTING(ROD) && game.oldobj == BIRD) break; return; case 2: /* snake */ @@ -139,7 +139,7 @@ static void checkhints(void) game.hintlc[hint] = 0; return; case 4: /* dark */ - if (game.prop[EMERALD] != STATE_NOTFOUND && game.prop[PYRAMID] == STATE_NOTFOUND) + if (game.objects[EMERALD].prop != STATE_NOTFOUND && game.objects[PYRAMID].prop == STATE_NOTFOUND) break; game.hintlc[hint] = 0; return; @@ -166,7 +166,7 @@ static void checkhints(void) break; return; case 9: /* jade */ - if (game.tally == 1 && game.prop[JADE] < 0) + if (game.tally == 1 && game.objects[JADE].prop < 0) break; game.hintlc[hint] = 0; return; @@ -199,7 +199,7 @@ static bool spotted_by_pirate(int i) * that game.place[CHEST] = LOC_NOWHERE might mean that he's thrown * it to the troll, but in that case he's seen the chest * (game.prop[CHEST] == STATE_FOUND). */ - if (game.loc == game.chloc || game.prop[CHEST] != STATE_NOTFOUND) + if (game.loc == game.chloc || game.objects[CHEST].prop != STATE_NOTFOUND) return true; int snarfed = 0; bool movechest = false, robplayer = false; @@ -220,7 +220,7 @@ static bool spotted_by_pirate(int i) } } /* Force chest placement before player finds last treasure */ - if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == LOC_NOWHERE && HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT) { + if (game.tally == 1 && snarfed == 0 && game.objects[CHEST].place == LOC_NOWHERE && HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) { rspeak(PIRATE_SPOTTED); movechest = true; } @@ -245,7 +245,7 @@ static bool spotted_by_pirate(int i) continue; if (!(treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || game.loc == objects[EMERALD].plac))) { - if (AT(treasure) && game.fixed[treasure] == IS_FREE) + if (AT(treasure) && game.objects[treasure].fixed == IS_FREE) carry(treasure, game.loc); if (TOTING(treasure)) drop(treasure, game.chloc); @@ -439,9 +439,9 @@ static void croak(void) /* If player wishes to continue, we empty the liquids in the * user's inventory, turn off the lamp, and drop all items * where he died. */ - game.place[WATER] = game.place[OIL] = LOC_NOWHERE; + game.objects[WATER].place = game.objects[OIL].place = LOC_NOWHERE; if (TOTING(LAMP)) - game.prop[LAMP] = LAMP_DARK; + game.objects[LAMP].prop = LAMP_DARK; for (int j = 1; j <= NOBJECTS; j++) { int i = NOBJECTS + 1 - j; if (TOTING(i)) { @@ -628,7 +628,7 @@ static void playermove(int motion) else if (TOTING(condarg1) || (condtype == cond_with && AT(condarg1))) break; /* else fall through to check [not OBJ STATE] */ - } else if (game.prop[condarg1] != condarg2) + } else if (game.objects[condarg1].prop != condarg2) break; /* We arrive here on conditional failure. @@ -698,9 +698,9 @@ static void playermove(int motion) * (standard travel entries check for * game.prop[TROLL]=TROLL_UNPAID.) Special stuff * for bear. */ - if (game.prop[TROLL] == TROLL_PAIDONCE) { + if (game.objects[TROLL].prop == TROLL_PAIDONCE) { pspeak(TROLL, look, true, TROLL_PAIDONCE); - game.prop[TROLL] = TROLL_UNPAID; + game.objects[TROLL].prop = TROLL_UNPAID; DESTROY(TROLL2); move(TROLL2 + NOBJECTS, IS_FREE); move(TROLL, objects[TROLL].plac); @@ -710,15 +710,15 @@ static void playermove(int motion) return; } else { game.newloc = objects[TROLL].plac + objects[TROLL].fixd - game.loc; - if (game.prop[TROLL] == TROLL_UNPAID) - game.prop[TROLL] = TROLL_PAIDONCE; + if (game.objects[TROLL].prop == TROLL_UNPAID) + game.objects[TROLL].prop = TROLL_PAIDONCE; if (!TOTING(BEAR)) return; state_change(CHASM, BRIDGE_WRECKED); - game.prop[TROLL] = TROLL_GONE; + game.objects[TROLL].prop = TROLL_GONE; drop(BEAR, game.newloc); - game.fixed[BEAR] = IS_FIXED; - game.prop[BEAR] = BEAR_DEAD; + game.objects[BEAR].fixed = IS_FIXED; + game.objects[BEAR].prop = BEAR_DEAD; game.oldlc2 = game.newloc; croak(); return; @@ -736,7 +736,7 @@ static void playermove(int motion) static void lampcheck(void) /* Check game limit and lamp timers */ { - if (game.prop[LAMP] == LAMP_BRIGHT) + if (game.objects[LAMP].prop == LAMP_BRIGHT) --game.limit; /* Another way we can force an end to things is by having the @@ -746,9 +746,9 @@ static void lampcheck(void) * Second is for other cases of lamp dying. Even after it goes * out, he can explore outside for a while if desired. */ if (game.limit <= WARNTIME) { - if (HERE(BATTERY) && game.prop[BATTERY] == FRESH_BATTERIES && HERE(LAMP)) { + if (HERE(BATTERY) && game.objects[BATTERY].prop == FRESH_BATTERIES && HERE(LAMP)) { rspeak(REPLACE_BATTERIES); - game.prop[BATTERY] = DEAD_BATTERIES; + game.objects[BATTERY].prop = DEAD_BATTERIES; #ifdef __unused__ /* This code from the original game seems to have been faulty. * No tests ever passed the guard, and with the guard removed @@ -761,9 +761,9 @@ static void lampcheck(void) game.lmwarn = false; } else if (!game.lmwarn && HERE(LAMP)) { game.lmwarn = true; - if (game.prop[BATTERY] == DEAD_BATTERIES) + if (game.objects[BATTERY].prop == DEAD_BATTERIES) rspeak(MISSING_BATTERIES); - else if (game.place[BATTERY] == LOC_NOWHERE) + else if (game.objects[BATTERY].place == LOC_NOWHERE) rspeak(LAMP_DIM); else rspeak(GET_BATTERIES); @@ -771,7 +771,7 @@ static void lampcheck(void) } if (game.limit == 0) { game.limit = -1; - game.prop[LAMP] = LAMP_DARK; + game.objects[LAMP].prop = LAMP_DARK; if (HERE(LAMP)) rspeak(LAMP_OUT); } @@ -824,8 +824,8 @@ static bool closecheck(void) * know the bivalve is an oyster. *And*, the dwarves must * have been activated, since we've found chest. */ if (game.clock1 == 0) { - game.prop[GRATE] = GRATE_CLOSED; - game.prop[FISSURE] = UNBRIDGED; + game.objects[GRATE].prop = GRATE_CLOSED; + game.objects[FISSURE].prop = UNBRIDGED; for (int i = 1; i <= NDWARVES; i++) { game.dwarves[i].seen = false; game.dwarves[i].loc = LOC_NOWHERE; @@ -835,12 +835,12 @@ static bool closecheck(void) move(TROLL2, objects[TROLL].plac); move(TROLL2 + NOBJECTS, objects[TROLL].fixd); juggle(CHASM); - if (game.prop[BEAR] != BEAR_DEAD) + if (game.objects[BEAR].prop != BEAR_DEAD) DESTROY(BEAR); - game.prop[CHAIN] = CHAIN_HEAP; - game.fixed[CHAIN] = IS_FREE; - game.prop[AXE] = AXE_HERE; - game.fixed[AXE] = IS_FREE; + game.objects[CHAIN].prop = CHAIN_HEAP; + game.objects[CHAIN].fixed = IS_FREE; + game.objects[AXE].prop = AXE_HERE; + game.objects[AXE].fixed = IS_FREE; rspeak(CAVE_CLOSING); game.clock1 = -1; game.closng = true; @@ -863,12 +863,12 @@ static bool closecheck(void) * objects he might be carrying (lest he have some which * could cause trouble, such as the keys). We describe the * flash of light and trundle back. */ - game.prop[BOTTLE] = put(BOTTLE, LOC_NE, EMPTY_BOTTLE); - game.prop[PLANT] = put(PLANT, LOC_NE, PLANT_THIRSTY); - game.prop[OYSTER] = put(OYSTER, LOC_NE, STATE_FOUND); - game.prop[LAMP] = put(LAMP, LOC_NE, LAMP_DARK); - game.prop[ROD] = put(ROD, LOC_NE, STATE_FOUND); - game.prop[DWARF] = put(DWARF, LOC_NE, 0); + game.objects[BOTTLE].prop = put(BOTTLE, LOC_NE, EMPTY_BOTTLE); + game.objects[PLANT].prop = put(PLANT, LOC_NE, PLANT_THIRSTY); + game.objects[OYSTER].prop = put(OYSTER, LOC_NE, STATE_FOUND); + game.objects[LAMP].prop = put(LAMP, LOC_NE, LAMP_DARK); + game.objects[ROD].prop = put(ROD, LOC_NE, STATE_FOUND); + game.objects[DWARF].prop = put(DWARF, LOC_NE, 0); game.loc = LOC_NE; game.oldloc = LOC_NE; game.newloc = LOC_NE; @@ -876,15 +876,15 @@ static bool closecheck(void) * Reuse sign. */ put(GRATE, LOC_SW, 0); put(SIGN, LOC_SW, 0); - game.prop[SIGN] = ENDGAME_SIGN; - game.prop[SNAKE] = put(SNAKE, LOC_SW, SNAKE_CHASED); - game.prop[BIRD] = put(BIRD, LOC_SW, BIRD_CAGED); - game.prop[CAGE] = put(CAGE, LOC_SW, STATE_FOUND); - game.prop[ROD2] = put(ROD2, LOC_SW, STATE_FOUND); - game.prop[PILLOW] = put(PILLOW, LOC_SW, STATE_FOUND); + game.objects[SIGN].prop = ENDGAME_SIGN; + game.objects[SNAKE].prop = put(SNAKE, LOC_SW, SNAKE_CHASED); + game.objects[BIRD].prop = put(BIRD, LOC_SW, BIRD_CAGED); + game.objects[CAGE].prop = put(CAGE, LOC_SW, STATE_FOUND); + game.objects[ROD2].prop = put(ROD2, LOC_SW, STATE_FOUND); + game.objects[PILLOW].prop = put(PILLOW, LOC_SW, STATE_FOUND); - game.prop[MIRROR] = put(MIRROR, LOC_NE, STATE_FOUND); - game.fixed[MIRROR] = LOC_SW; + game.objects[MIRROR].prop = put(MIRROR, LOC_NE, STATE_FOUND); + game.objects[MIRROR].fixed = LOC_SW; for (int i = 1; i <= NOBJECTS; i++) { if (TOTING(i)) @@ -917,14 +917,14 @@ static void listobjects(void) obj = obj - NOBJECTS; if (obj == STEPS && TOTING(NUGGET)) continue; - if (game.prop[obj] < 0) { + if (game.objects[obj].prop < 0) { if (game.closed) continue; - game.prop[obj] = STATE_FOUND; + game.objects[obj].prop = STATE_FOUND; if (obj == RUG) - game.prop[RUG] = RUG_DRAGON; + game.objects[RUG].prop = RUG_DRAGON; if (obj == CHAIN) - game.prop[CHAIN] = CHAINING_BEAR; + game.objects[CHAIN].prop = CHAINING_BEAR; if (obj == EGGS) game.seenbigwords = true; --game.tally; @@ -943,9 +943,9 @@ static void listobjects(void) * gross blunder isn't likely to find everything else anyway * (so goes the rationalisation). */ } - int kk = game.prop[obj]; + int kk = game.objects[obj].prop; if (obj == STEPS) - kk = (game.loc == game.fixed[STEPS]) + kk = (game.loc == game.objects[STEPS].fixed) ? STEPS_UP : STEPS_DOWN; pspeak(obj, look, true, kk); @@ -1098,11 +1098,11 @@ static bool do_command(void) * game.prop < 0 and stash them. This way objects won't be * described until they've been picked up and put down * separate from their respective piles. */ - if (game.prop[OYSTER] < 0 && TOTING(OYSTER)) + if (game.objects[OYSTER].prop < 0 && TOTING(OYSTER)) pspeak(OYSTER, look, true, 1); for (size_t i = 1; i <= NOBJECTS; i++) { - if (TOTING(i) && game.prop[i] < 0) - game.prop[i] = STASHED(i); + if (TOTING(i) && game.objects[i].prop < 0) + game.objects[i].prop = STASHED(i); } } diff --git a/misc.c b/misc.c index 450f727..b8bc461 100644 --- a/misc.c +++ b/misc.c @@ -571,8 +571,8 @@ void juggle(obj_t object) { loc_t i, j; - i = game.place[object]; - j = game.fixed[object]; + i = game.objects[object].place; + j = game.objects[object].fixed; move(object, i); move(object + NOBJECTS, j); } @@ -586,9 +586,9 @@ void move(obj_t object, loc_t where) loc_t from; if (object > NOBJECTS) - from = game.fixed[object - NOBJECTS]; + from = game.objects[object - NOBJECTS].fixed; else - from = game.place[object]; + from = game.objects[object].place; /* (ESR) Used to check for !SPECIAL(from). I *think* that was wrong... */ if (from != LOC_NOWHERE && from != CARRIED) carry(object, from); @@ -611,9 +611,9 @@ void carry(obj_t object, loc_t where) int temp; if (object <= NOBJECTS) { - if (game.place[object] == CARRIED) + if (game.objects[object].place == CARRIED) return; - game.place[object] = CARRIED; + game.objects[object].place = CARRIED; /* * Without this conditional your inventory is overcounted @@ -641,9 +641,9 @@ void drop(obj_t object, loc_t where) * game.holdng if the object was being toted. No state change on the object. */ { if (object > NOBJECTS) - game.fixed[object - NOBJECTS] = where; + game.objects[object - NOBJECTS].fixed = where; else { - if (game.place[object] == CARRIED) + if (game.objects[object].place == CARRIED) if (object != BIRD) /* The bird has to be weightless. This ugly hack (and the * corresponding code in the carry function) brought to you @@ -652,7 +652,7 @@ void drop(obj_t object, loc_t where) * happen. */ --game.holdng; - game.place[object] = where; + game.objects[object].place = where; } if (where == LOC_NOWHERE || where == CARRIED) return; @@ -738,7 +738,7 @@ void bug(enum bugtype num, const char *error_string) void state_change(obj_t obj, int state) /* Object must have a change-message list for this to be useful; only some do */ { - game.prop[obj] = state; + game.objects[obj].prop = state; pspeak(obj, change, true, state); } diff --git a/saveresume.c b/saveresume.c index 53278ae..4cac034 100644 --- a/saveresume.c +++ b/saveresume.c @@ -197,8 +197,8 @@ bool is_valid(struct game_t valgame) } for (int i = 0; i <= NOBJECTS; i++) { - if (valgame.place[i] < -1 || valgame.place[i] > NLOCATIONS || - valgame.fixed[i] < -1 || valgame.fixed[i] > NLOCATIONS) { + if (valgame.objects[i].place < -1 || valgame.objects[i].place > NLOCATIONS || + valgame.objects[i].fixed < -1 || valgame.objects[i].fixed > NLOCATIONS) { return false; // LCOV_EXCL_LINE } } @@ -218,7 +218,7 @@ bool is_valid(struct game_t valgame) int temp_tally = 0; for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { - if (valgame.prop[treasure] == STATE_NOTFOUND) { + if (valgame.objects[treasure].prop == STATE_NOTFOUND) { ++temp_tally; } } @@ -230,7 +230,7 @@ bool is_valid(struct game_t valgame) /* Check that properties of objects aren't beyond expected */ for (obj_t obj = 0; obj <= NOBJECTS; obj++) { /* Magic number -2 allows a STASHED version of state 1 */ - if (valgame.prop[obj] < -2 || valgame.prop[obj] > 1) { + if (valgame.objects[obj].prop < -2 || valgame.objects[obj].prop > 1) { switch (obj) { case RUG: case DRAGON: @@ -243,11 +243,11 @@ bool is_valid(struct game_t valgame) case EGGS: case VASE: case CHAIN: - if (valgame.prop[obj] == 2) // There are multiple different states, but it's convenient to clump them together + if (valgame.objects[obj].prop == 2) // There are multiple different states, but it's convenient to clump them together continue; // LCOV_EXCL_LINE /* FALLTHRU */ case BEAR: - if (valgame.prop[BEAR] == CONTENTED_BEAR || valgame.prop[BEAR] == BEAR_DEAD) + if (valgame.objects[BEAR].prop == CONTENTED_BEAR || valgame.objects[BEAR].prop == BEAR_DEAD) continue; /* FALLTHRU */ default: diff --git a/score.c b/score.c index 8e37374..d3eeb0a 100644 --- a/score.c +++ b/score.c @@ -48,9 +48,9 @@ int score(enum termination mode) k = 14; if (i > CHEST) k = 16; - if (game.prop[i] > STATE_NOTFOUND) + if (game.objects[i].prop > STATE_NOTFOUND) score += 2; - if (game.place[i] == LOC_BUILDING && game.prop[i] == STATE_FOUND) + if (game.objects[i].place == LOC_BUILDING && game.objects[i].prop == STATE_FOUND) score += k - 2; mxscor += k; } @@ -86,7 +86,7 @@ int score(enum termination mode) mxscor += 45; /* Did he come to Witt's End as he should? */ - if (game.place[MAGAZINE] == LOC_WITTSEND) + if (game.objects[MAGAZINE].place == LOC_WITTSEND) score += 1; mxscor += 1; From 8d4d64fafbff1191bf221e32ed4a8aba48ac63f4 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 10:52:16 -0400 Subject: [PATCH 121/213] Structurization of hints. --- advent.h | 8 +++++--- main.c | 28 ++++++++++++++-------------- score.c | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/advent.h b/advent.h index 04d2fc2..62a54ac 100644 --- a/advent.h +++ b/advent.h @@ -191,14 +191,16 @@ struct game_t { loc_t loc; // location of dwarves, initially hard-wired in loc_t oldloc; // prior loc of each dwarf, initially garbage } dwarves[NDWARVES + 1]; - struct object { + struct { loc_t fixed; // fixed location of object (if not IS_FREE) int prop; // object state */ loc_t place; // location of object } objects[NOBJECTS + 1]; + struct { + bool used; // hints[i].used = true iff hint i has been used. + int lc; // hints[i].lc = show int at LOC with cond bit i + } hints[NHINTS]; obj_t link[NOBJECTS * 2 + 1];// object-list links - bool hinted[NHINTS]; // hinted[i] = true iff hint i has been used. - int hintlc[NHINTS]; // hintlc[i] = show int at LOC with cond bit i }; /* diff --git a/main.c b/main.c index 5e7d6ab..52e4187 100644 --- a/main.c +++ b/main.c @@ -104,14 +104,14 @@ static void checkhints(void) { if (conditions[game.loc] >= game.conds) { for (int hint = 0; hint < NHINTS; hint++) { - if (game.hinted[hint]) + if (game.hints[hint].used) continue; if (!CNDBIT(game.loc, hint + 1 + COND_HBASE)) - game.hintlc[hint] = -1; - ++game.hintlc[hint]; + game.hints[hint].lc = -1; + ++game.hints[hint].lc; /* Come here if he's been int enough at required loc(s) for some * unused hint. */ - if (game.hintlc[hint] >= hints[hint].turns) { + if (game.hints[hint].lc >= hints[hint].turns) { int i; switch (hint) { @@ -119,7 +119,7 @@ static void checkhints(void) /* cave */ if (game.objects[GRATE].prop == GRATE_CLOSED && !HERE(KEYS)) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 1: /* bird */ if (game.objects[BIRD].place == game.loc && TOTING(ROD) && game.oldobj == BIRD) @@ -128,7 +128,7 @@ static void checkhints(void) case 2: /* snake */ if (HERE(SNAKE) && !HERE(BIRD)) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 3: /* maze */ if (game.locs[game.loc].atloc == NO_OBJECT && @@ -136,19 +136,19 @@ static void checkhints(void) game.locs[game.oldlc2].atloc == NO_OBJECT && game.holdng > 1) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 4: /* dark */ if (game.objects[EMERALD].prop != STATE_NOTFOUND && game.objects[PYRAMID].prop == STATE_NOTFOUND) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 5: /* witt */ break; case 6: /* urn */ if (game.dflag == 0) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 7: /* woods */ if (game.locs[game.loc].atloc == NO_OBJECT && @@ -159,7 +159,7 @@ static void checkhints(void) case 8: /* ogre */ i = atdwrf(game.loc); if (i < 0) { - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; } if (HERE(OGRE) && i == 0) @@ -168,7 +168,7 @@ static void checkhints(void) case 9: /* jade */ if (game.tally == 1 && game.objects[JADE].prop < 0) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; default: // LCOV_EXCL_LINE // Should never happen @@ -176,12 +176,12 @@ static void checkhints(void) } /* Fall through to hint display */ - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; if (!yes_or_no(hints[hint].question, arbitrary_messages[NO_MESSAGE], arbitrary_messages[OK_MAN])) return; rspeak(HINT_COST, hints[hint].penalty, hints[hint].penalty); - game.hinted[hint] = yes_or_no(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]); - if (game.hinted[hint] && game.limit > WARNTIME) + game.hints[hint].used = yes_or_no(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]); + if (game.hints[hint].used && game.limit > WARNTIME) game.limit += WARNTIME * hints[hint].penalty; } } diff --git a/score.c b/score.c index d3eeb0a..2e804e4 100644 --- a/score.c +++ b/score.c @@ -96,7 +96,7 @@ int score(enum termination mode) /* Deduct for hints/turns/saves. Hints < 4 are special; see database desc. */ for (int i = 0; i < NHINTS; i++) { - if (game.hinted[i]) + if (game.hints[i].used) score = score - hints[i].penalty; } if (game.novice) From 819aed5c4ef5746e1b978be83be00ae26557efce Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 12:33:52 -0400 Subject: [PATCH 122/213] Add test for behavior of stashed objects in endgame. --- tests/stashed.chk | 2086 +++++++++++++++++++++++++++++++++++++++++++++ tests/stashed.log | 353 ++++++++ 2 files changed, 2439 insertions(+) create mode 100644 tests/stashed.chk create mode 100644 tests/stashed.log diff --git a/tests/stashed.chk b/tests/stashed.chk new file mode 100644 index 0000000..58b989c --- /dev/null +++ b/tests/stashed.chk @@ -0,0 +1,2086 @@ + +Welcome to Adventure!! Would you like instructions? + +> no + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed 1318612053 + +Seed set to 1318612053 + +You're in front of building. + +> e + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plove + +>>Foof!<< + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +There is an emerald here the size of a plover's egg! + +> get emerald + +OK + +> w + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> drop emerald + +OK + +> e + +You're in Plover Room. + +> ne + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> get pyramid + +OK + +> s + +You're in Plover Room. + +> plove + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> drop pyramid + +OK + +> get lamp + +OK + +> get water + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There are bars of silver here! + +> d + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> bedquilt + +You are in Bedquilt, a long east/west passage with holes everywhere. +To explore at random select north, south, up, or down. + +> w + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +> e + +You are in the Soft Room. The walls are covered with heavy curtains, +the floor with a thick pile carpet. Moss covers the ceiling. + +A small velvet pillow lies on the floor. + +> take pillow + +OK + +> w + +You're in Swiss Cheese Room. + +> oriental + +This is the Oriental Room. Ancient oriental cave drawings cover the +walls. A gently sloping passage leads upward to the north, another +passage leads se, and a hands and knees crawl leads west. + +There is a delicate, precious, ming vase here! + +> take vase + +OK + +> n + +You are following a wide path around the outer edge of a large cavern. +Far below, through a heavy white mist, strange splashing noises can be +heard. The mist rises up through a fissure in the ceiling. The path +exits to the south and west. + +> w + +You are in an alcove. A small nw path seems to widen after a short +distance. An extremely tight tunnel leads east. It looks like a very +tight squeeze. An eerie light can be seen at the other end. + +There is an emerald here the size of a plover's egg! + +> take emerald + +OK + +> nw + +You're in misty cavern. + +> s + +You're in Oriental Room. + +> se + +You're in Swiss Cheese Room. + +> w + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +> w + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a tiny little plant in the pit, murmuring "water, water, ..." + +> water plant + +The plant spurts into furious growth for a few seconds. + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> u + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> e + +You're at east end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You are at the bottom of the eastern pit in the Twopit Room. There is +a small pool of oil in one corner of the pit. + +> fill bottle + +Your bottle is now full of oil. + +> u + +You're at east end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> e + +You're in Swiss Cheese Room. + +> ne + +You're in Bedquilt. + +> e + +You are at a complex junction. A low hands and knees passage from the +north joins a higher crawl from the east to make a walking passage +going west. There is also a large room above. The air is damp here. + +> u + +You are in a large room full of dusty rocks. There is a big hole in +the floor. There are cracks everywhere, and a passage leading east. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> n + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop pillow + +OK + +> drop vase + +The vase is now resting, delicately, on a velvet pillow. + +> drop bottle + +OK + +> drop emerald + +OK + +> xyzzy + +>>Foof!<< + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> e + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> take cage + +OK + +> pit + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> drop rod + +OK + +> e + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> take bird + +OK + +> w + +You're at top of small pit. + +A three foot black rod with a rusty star on an end lies nearby. + +Rough stone steps lead down the pit. + +> drop bird + +OK + +> take rod + +OK + +> wave rod + +The bird flies about agitatedly for a moment, then disappears through +the crack. It reappears shortly, carrying in its beak a jade +necklace, which it drops at your feet. + +> take necklace + +OK + +> drop rod + +OK + +> take bird + +OK + +> d + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> s + +This is a low room with a crude note on the wall. The note says, +"You won't get it up the steps". + +There is a large sparkling nugget of gold here! + +> take nugget + +OK + +> n + +You're in Hall of Mists. + +> n + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A huge green fierce snake bars the way! + +> drop bird + +The little bird attacks the green snake, and in an astounding flurry +drives the snake away. + +> take bird + +OK + +> sw + +You are in a secret canyon which here runs e/w. It crosses over a +very tight canyon 15 feet below. If you go down you may not be able +to get back up. + +> w + +You are in a secret canyon which exits to the north and east. + +A huge green fierce dragon bars the way! + +The dragon is sprawled out on a Persian rug!! + +> kill dragon + +With what? Your bare hands? + +> yes + +Congratulations! You have just vanquished a dragon with your bare +hands! (Unbelievable, isn't it?) + +You are in a secret canyon which exits to the north and east. + +There is a Persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. + +> drink blood + +Your head buzzes strangely for a moment. + +> take rug + +OK + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +You're in Hall of Mt King. + +> n + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> take bars + +OK + +> n + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +There is an emerald here the size of a plover's egg! + +There is a bottle of oil here. + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop cage + +OK + +> drop necklace + +OK + +> drop nugget + +OK + +> drop bars + +OK + +> drop rug + +OK + +> xyzzy + +>>Foof!<< + +You're in debris room. + +> pit + +You're at top of small pit. + +A three foot black rod with a rusty star on an end lies nearby. + +Rough stone steps lead down the pit. + +> take rod + +OK + +> d + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +A crystal bridge now spans the fissure. + +> w + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> take diamonds + +OK + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of the Hall of Mists. A low wide crawl +continues west and another goes north. To the south is a little +passage 6 feet off the floor. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the east end of a very long hall apparently without side +chambers. To the east a low wide crawl slants up. To the north a +round two foot hole slants down. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of a very long featureless hall. The hall +joins up with a narrow north/south passage. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisting little passages, all different. + +> e + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisting passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +Dead end + +There is a massive and somewhat battered vending machine here. The +instructions on it read: "Drop coins here to receive fresh batteries." + +> hit machine + +As you strike the vending machine, it pivots backward along with a +section of wall, revealing a dark passage leading south. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a long, rough-hewn, north/south corridor. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a large chamber with passages to the west and north. + +A formidable ogre bars the northern exit. + +> kill ogre + +The ogre, who despite his bulk is quite agile, easily dodges your +attack. He seems almost amused by your puny effort. + +One sharp nasty knife is thrown at you! + +The ogre, distracted by your rush, is struck by the knife. With a +blood-curdling yell he turns and bounds after the dwarf, who flees +in panic. You are left alone in the room. + +> n + +You are in the ogre's storeroom. The only exit is to the south. + +There is an enormous ruby here! + +> take ruby + +OK + +> s + +You are in a large chamber with passages to the west and north. + +> w + +You are in a long, rough-hewn, north/south corridor. + +> n + +Dead end + +There is a massive vending machine here, swung back to reveal a +southward passage. + +> n + +You are in a little maze of twisting passages, all different. + +> sw + +You are in a maze of twisting little passages, all different. + +> w + +You are in a maze of twisty little passages, all different. + +> d + +You're at west end of long hall. + +> n + +You are at a crossover of a high n/s passage and a low e/w one. + +> e + +You are in the west side chamber of the Hall of the Mountain King. +A passage continues west and up here. + +There are many coins here! + +> take coins + +OK + +> e + +You're in Hall of Mt King. + +> s + +You are in the south side chamber. + +There is precious jewelry here! + +> take jewelry + +OK + +> n + +You're in Hall of Mt King. + +> e + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're at west end of Hall of Mists. + +> s + +You are in a maze of twisty little passages, all alike. + +> e + +Out from the shadows behind you pounces a bearded pirate! "Har, har," +he chortles, "I'll just take all this booty and hide it away with me +chest deep in the maze!" He snatches your treasure and vanishes into +the gloom. + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> s + +You are in a maze of twisty little passages, all alike. + +> n + +You are in a maze of twisty little passages, all alike. + +> e + +You are on the brink of a thirty foot pit with a massive orange column +down one wall. You could climb down here but you could not get back +up. The maze continues at this level. + +> e + +You are in a maze of twisty little passages, all alike. + +> nw + +Dead end + +There is an enormous ruby here! + +There are many coins here! + +There is precious jewelry here! + +There are diamonds here! + +The pirate's treasure chest is here! + +> drop rod + +OK + +> take jewelry + +OK + +> take chest + +OK + +> take ruby + +OK + +> take diamonds + +OK + +> take coins + +OK + +> se + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all alike. + +> w + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all alike. + +> s + +There is a threatening little dwarf in the room with you! + +You're at brink of pit. + +> d + +You're in bird chamber. + +> debris + +You're in debris room. + +> xyzzy + +>>Foof!<< + +You're inside building. + +There is a Persian rug spread out on the floor! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a small wicker cage discarded nearby. + +There is a little bird in the cage. + +There is an emerald here the size of a plover's egg! + +There is a bottle of oil here. + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> off + +Your lamp is now off. + +> drop coins + +OK + +> drop diamonds + +OK + +> drop jewelry + +OK + +> drop chest + +OK + +> drop lamp + +OK + +> take rug + +OK + +> take emerald + +OK + +> take cage + +OK + +> take bottle + +OK + +> w + +You're in front of building. + +> s + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> w + +You are wandering aimlessly through the forest. + +> drop bird + +OK + +> listen + +The bird is singing to you in gratitude for your having returned it to +its home. In return, it informs you of a magic word which it thinks +you may find useful somewhere near the Hall of Mists. The magic word +changes frequently, but for now the bird believes it is "N'BEH". You +thank the bird for this information, and it flies off into the forest. + +> drop cage + +OK + +> n + +You are wandering aimlessly through the forest. + +Your keen eye spots a severed leporine appendage lying on the ground. + +> take appendage + +OK + +> n + +You are wandering aimlessly through the forest. + +> e + +You are wandering aimlessly through the forest. + +> n + +You are wandering aimlessly through the forest. + +> n + +The forest thins out here to reveal a steep cliff. There is no way +down, but a small ledge can be seen to the west across the chasm. + +A small urn is embedded in the rock. + +> fill urn + +Your bottle is now empty and the urn is full of oil. + +> light urn + +The urn is now lit. + +> rub urn + +As you rub the urn, there is a flash of light and a genie appears. +His aspect is stern as he advises: "One who wouldst traffic in +precious stones must first learn to recognize the signals thereof." +He wrests the urn from the stone, leaving a small cavity. Turning to +face you again, he fixes you with a steely eye and intones: "Caution!" +Genie and urn vanish in a cloud of amber smoke. The smoke condenses +to form a rare amber gemstone, resting in the cavity in the rock. + +> drop rug + +OK + +> take amber + +OK + +> drop emerald + +The gem fits easily into the cavity. + +The Persian rug stiffens and rises a foot or so off the ground. + +> fly + +You board the Persian rug, which promptly whisks you across the chasm. +You have time for a fleeting glimpse of a two thousand foot drop to a +mighty river; then you find yourself on the other side. + +You are on a small ledge on one face of a sheer cliff. There are no +paths away from the ledge. Across the chasm is a small clearing +surrounded by forest. + +There is a Persian rug here, hovering in mid-air! + +A brilliant blue star sapphire is here! + +> take sapphire + +OK + +> fly + +The rug ferries you back across the chasm. + +You're at cliff. + +There is an emerald resting in a small cavity in the rock! + +There is a Persian rug here, hovering in mid-air! + +> take emerald + +OK + +> drop ruby + +The gem fits easily into the cavity. + +The Persian rug settles gently to the ground. + +> take rug + +OK + +> take ruby + +OK + +> e + +You are wandering aimlessly through the forest. + +> s + +You are wandering aimlessly through the forest. + +> e + +You have walked up a hill, still in the forest. The road slopes back +down the other side of the hill. There is a building in the distance. + +> e + +You're in front of building. + +> e + +You are inside a building, a well house for a large spring. + +There is a shiny brass lamp nearby. + +The pirate's treasure chest is here! + +There is precious jewelry here! + +There are diamonds here! + +There are many coins here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop emerald + +OK + +> drop ruby + +OK + +> drop amber + +OK + +> drop rug + +OK + +> drop sapphire + +OK + +> fill bottle + +Your bottle is now full of water. + +> take lamp + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +There is a little axe here. + +> s + +You're in n/s passage above e/w passage. + +> s + +You're in Hall of Mt King. + +> sw + +You're in secret e/w canyon above tight canyon. + +> w + +You are in a secret canyon which exits to the north and east. + +The body of a huge green dead dragon is lying off to one side. + +> n + +You are in a secret n/s canyon above a large room. + +> reservoir + +You are at the edge of a large underground reservoir. An opaque cloud +of white mist fills the room and rises rapidly upward. The lake is +fed by a stream, which tumbles out of a hole in the wall about 10 feet +overhead and splashes noisily into the water somewhere within the +mist. There is a passage going back toward the south. + +> n'beh + +The waters have parted to form a narrow path across the reservoir. + +> n + +You are walking across the bottom of the reservoir. Walls of water +rear up on either side. The roar of the water cascading past is +nearly deafening, and the mist is so thick you can barely see. + +> n + +You are at the northern edge of the reservoir. A northwest passage +leads sharply up from here. + +The waters have parted to form a narrow path across the reservoir. + +> u + +You are scrambling along a treacherously steep, rocky passage. + +> u + +You are on a very steep incline, which widens at it goes upward. + +> u + +You are at the base of a nearly vertical cliff. There are some +slim footholds which would enable you to climb up, but it looks +extremely dangerous. Here at the base of the cliff lie the remains +of several earlier adventurers who apparently failed to make it. + +> u + +You are climbing along a nearly vertical cliff. + +> u + +Just as you reach the top, your foot slips on a loose rock and you +make one last desperate grab. Your luck holds, as does your grip. +With an enormous heave, you lift yourself to the ledge above. + +You are on a small ledge at the top of a nearly vertical cliff. +There is a low crawl leading off to the northeast. + +> ne + +You have reached a dead end. + +There is a richly-carved ebony statuette here! + +> take statuette + +OK + +> sw + +You're at top of cliff. + +> d + +You are climbing along a nearly vertical cliff. + +> d + +You're at base of cliff. + +> d + +You are on a very steep incline, which widens at it goes upward. + +> d + +You are scrambling along a treacherously steep, rocky passage. + +> d + +You're north of reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You're at bottom of reservoir. + +> s + +You're at reservoir. + +The waters have parted to form a narrow path across the reservoir. + +> s + +You are in a north/south canyon about 25 feet across. The floor is +covered by white mist seeping in from the north. The walls extend +upward for well over 100 feet. Suspended from some unseen point far +above you, an enormous two-sided mirror is hanging parallel to and +midway between the canyon walls. (The mirror is obviously provided +for the use of the dwarves who, as you know, are extremely vain.) A +small window can be seen in either wall, some fifty feet up. + +> s + +You are in a secret n/s canyon above a large room. + +> d + +You are in a large low circular chamber whose floor is an immense slab +fallen from the ceiling (Slab Room). East and west there once were +large passages, but they are now filled with boulders. Low small +passages go north and south, and the south one quickly bends west +around the boulders. + +> s + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> d + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> water plant + +The plant grows explosively, almost filling the bottom of the pit. + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> u + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> e + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in east pit. + +> fill bottle + +Your bottle is now full of oil. + +> u + +You're at east end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You're at west end of Twopit Room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You're in west pit. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You are in a long, narrow corridor stretching out of sight to the +west. At the eastern end is a hole through which you can see a +profusion of leaves. + +> w + +You are in the Giant Room. The ceiling here is too high up for your +lamp to show it. Cavernous passages lead east, north, and south. On +the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. + +There is a large nest here, full of golden eggs! + +> take eggs + +OK + +> n + +You are at one end of an immense north/south passage. + +The way north is barred by a massive, rusty, iron door. + +> oil door + +The oil has freed up the hinges so that the door will now move, +although it requires some effort. + +> drop bottle + +OK + +> n + +You are in a magnificent cavern with a rushing stream, which cascades +over a sparkling waterfall into a roaring whirlpool which disappears +through a hole in the floor. Passages exit to the south and west. + +There is a jewel-encrusted trident here! + +> take trident + +OK + +> w + +You are at the top of a steep incline above a large room. You could +climb down here, but you would not be able to climb up. There is a +passage leading back to the north. + +> d + +You are in a large low room. Crawls lead north, se, and sw. + +> bedquilt + +You're in Bedquilt. + +> e + +You're at complex junction. + +> n + +You're in a large room carved out of sedimentary rock. The floor and +walls are littered with bits of shells embedded in the stone. A +shallow passage proceeds downward, and a somewhat steeper one leads +up. A low hands and knees passage enters from the south. + +There is an enormous clam here with its shell tightly closed. + +> open clam + +A glistening pearl falls out of the clam and rolls away. Goodness, +this must really be an oyster. (I never was very good at identifying +bivalves.) Whatever it is, it has now snapped shut again. + +> d + +You are in a long sloping corridor with ragged sharp walls. + +> d + +You are in a cul-de-sac about eight feet across. + +Off to one side lies a glistening pearl! + +> take pearl + +OK + +> shell + +You're in Shell Room. + +There is an enormous oyster here with its shell tightly closed. + +> s + +You're at complex junction. + +> u + +You're in dusty rock room. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +A brilliant blue star sapphire is here! + +There is a Persian rug spread out on the floor! + +There is a rare amber gemstone here! + +There is an enormous ruby here! + +There is an emerald here the size of a plover's egg! + +The pirate's treasure chest is here! + +There is precious jewelry here! + +There are diamonds here! + +There are many coins here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +There are some keys on the ground here. + +There is food here. + +> drop trident + +OK + +> drop pearl + +OK + +> drop statuette + +OK + +> drop appendage + +OK + +> take keys + +OK + +> take food + +OK + +> plugh + +>>Foof!<< + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +There is a little axe here. + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> d + +You're in dirty passage. + +> bedquilt + +You're in Bedquilt. + +> w + +You're in Swiss Cheese Room. + +> oriental + +You're in Oriental Room. + +> w + +You're in large low room. + +> sw + +You are in a long winding corridor sloping out of sight in both +directions. + +> u + +You are on one side of a large, deep chasm. A heavy white mist rising +up from below obscures all view of the far side. A sw path leads away +from the chasm into a winding corridor. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> throw eggs + +The troll catches your treasure and scurries away out of sight. + +> ne + +You are on the far side of the chasm. A ne path leads away from the +chasm on this side. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> barren + +You are standing at the entrance to a large, barren room. A notice +above the entrance reads: "Caution! Bear in room!" + +> e + +You are inside a barren room. The center of the room is completely +empty except for some dust. Marks in the dust lead away toward the +far end of the room. The only exit is the way you came in. + +There is a ferocious cave bear eyeing you from the far end of the room! + +The bear is locked to the wall with a golden chain! + +> throw food + +The bear eagerly wolfs down your food, after which he seems to calm +down considerably and even becomes rather friendly. + +> unlock chain + +The chain is now unlocked. + +> take chain + +OK + +> take bear + +OK + +> fork + +You are being followed by a very large, tame bear. + +The path forks here. The left fork leads northeast. A dull rumbling +seems to get louder in that direction. The right fork leads southeast +down a gentle slope. The main corridor enters from the west. + +> ne + +You are being followed by a very large, tame bear. + +The walls are quite warm here. From the north can be heard a steady +roar, so loud that the entire cave seems to be trembling. Another +passage leads south, and a low crawl goes east. + +> fee + +OK + +> fie + +OK + +> foe + +OK + +> foo + +Done! + +> e + +You are being followed by a very large, tame bear. + +You are in a small chamber filled with large boulders. The walls are +very warm, causing the air in the room to be almost stifling from the +heat. The only exit is a crawl heading west, through which is coming +a low rumbling. + +There are rare spices here! + +> take spices + +OK + +> fork + +You are being followed by a very large, tame bear. + +You're at fork in path. + +> w + +You are being followed by a very large, tame bear. + +You're in a long east/west corridor. A faint rumbling noise can be +heard in the distance. + +> w + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +The troll steps out from beneath the bridge and blocks your way. + +You are being followed by a very large, tame bear. + +You're on ne side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +A burly troll stands by the bridge and insists you throw him a +treasure before you may cross. + +> release bear + +The bear lumbers toward the troll, who lets out a startled shriek and +scurries away. The bear soon gives up the pursuit and wanders back. + +> sw + +You're on sw side of chasm. + +A rickety wooden bridge extends across the chasm, vanishing into the +mist. A notice posted on the bridge reads, "Stop! Pay troll!" + +The troll is nowhere to be seen. + +> sw + +You're in sloping corridor. + +> d + +You're in large low room. + +> se + +You're in Oriental Room. + +> se + +You are in a room whose walls resemble Swiss cheese. Obvious passages +go west, east, ne, and nw. Part of the room is occupied by a large +bedrock block. + +> w + +You are at the east end of the Twopit Room. The floor here is +littered with thin rock slabs, which make it easy to descend the pits. +There is a path here bypassing the pits to connect passages from east +and west. There are holes all over, but the only big one is on the +wall directly over the west pit where you can't get to it. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> w + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +There is a huge beanstalk growing out of the west pit up to the hole. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a gigantic beanstalk stretching all the way up to the hole. + +> climb + +You clamber up the plant and scurry through the hole at the top. + +You're in narrow corridor. + +> w + +You're in Giant Room. + +There is a large nest here, full of golden eggs! + +> take eggs + +OK + +> n + +You are at one end of an immense north/south passage. + +There is an empty bottle here. + +The way north leads through a massive, rusty, iron door. + +> n + +You're in cavern with waterfall. + +> w + +You're at steep incline above large room. + +> d + +You're in large low room. + +> bedquilt + +You're in Bedquilt. + +> e + +You're at complex junction. + +> u + +You're in dusty rock room. + +> e + +You're in dirty passage. + +> u + +You're in n/s passage above e/w passage. + +> n + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're at "Y2". + +There is a little axe here. + +> plugh + +>>Foof!<< + +You're inside building. + +Your keen eye spots a severed leporine appendage lying on the ground. + +There is a richly-carved ebony statuette here! + +Off to one side lies a glistening pearl! + +There is a jewel-encrusted trident here! + +A brilliant blue star sapphire is here! + +There is a Persian rug spread out on the floor! + +There is a rare amber gemstone here! + +There is an enormous ruby here! + +There is an emerald here the size of a plover's egg! + +The pirate's treasure chest is here! + +There is precious jewelry here! + +There are diamonds here! + +There are many coins here! + +There are bars of silver here! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is a delicate, precious, ming vase here! + +A small velvet pillow lies on the floor. + +There is a platinum pyramid here, 8 inches on a side! + +> drop eggs + +OK + +> drop chain + +OK + +> drop spices + +OK + +> plugh + +>>Foof!<< + +You're at "Y2". + +A hollow voice says "PLUGH". + +There is a little axe here. + +> s + +You're in n/s passage above e/w passage. + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> n + +A sepulchral voice reverberating through the cave, says, "Cave closing +soon. All adventurers exit immediately through main office." + +You're at "Y2". + +There is a little axe here. + +> plugh + +A mysterious recorded voice groans into life and announces: + "This exit is closed. Please leave via main office." + +You're at "Y2". + +There is a little axe here. + +> s + +You're in n/s passage above e/w passage. + +> d + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> w + +You're in dusty rock room. + +> d + +You're at complex junction. + +> e + +You are in an anteroom leading to a large passage to the east. Small +passages go west and up. The remnants of recent digging are evident. +A sign in midair here says "Cave under construction beyond this point. +Proceed at own risk. [Witt Construction Company]" + +There are a few recent issues of "Spelunker Today" magazine here. + +> take magazine + +OK + +> e + +You are at Witt's End. Passages lead off in *ALL* directions. + +> drop magazine + +OK + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +You are at Witt's End. Passages lead off in *ALL* directions. + +There are a few recent issues of "Spelunker Today" magazine here. + +> look + +The sepulchral voice intones, "The cave is now closed." As the echoes +fade, there is a blinding flash of light (and a small puff of orange +smoke). . . . As your eyes refocus, you look around and find... + +You are at the northeast end of an immense room, even larger than the +Giant Room. It appears to be a repository for the "Adventure" +program. Massive torches far overhead bathe the room with smoky +yellow light. Scattered about you can be seen a pile of bottles (all +of them empty), a nursery of young beanstalks murmuring quietly, a bed +of oysters, a bundle of black rods with rusty stars on their ends, and +a collection of brass lanterns. Off to one side a great many dwarves +are sleeping on the floor, snoring loudly. A notice nearby reads: "Do +not disturb the dwarves!" An immense mirror is hanging against one +wall, and stretches to the other end of the room, where various other +sundry objects can be glimpsed dimly in the distance. + +> sw + +You are at the southwest end of the repository. To one side is a pit +full of fierce green snakes. On the other side is a row of small +wicker cages, each of which contains a little sulking bird. In one +corner is a bundle of black rods with rusty marks on their ends. A +large number of velvet pillows are scattered about on the floor. A +vast mirror stretches off to the northeast. At your feet is a large +steel grate, next to which is a sign that reads, "Treasure Vault. +Keys in main office." + +The grate is locked. + +> take pillow + +OK + +> + +> +You scored 391 out of a possible 430, using 345 turns. + +Your score puts you in Master Adventurer Class B. + +To achieve the next higher rating, you need 20 more points. diff --git a/tests/stashed.log b/tests/stashed.log new file mode 100644 index 0000000..0968282 --- /dev/null +++ b/tests/stashed.log @@ -0,0 +1,353 @@ +## Test picking up stashed objects in endgame +# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause +no +seed 1318612053 +e +plugh +plove +get emerald +w +drop emerald +e +ne +get pyramid +s +plove +plugh +drop pyramid +get lamp +get water +plugh +on +s +d +bedquilt +w +e +take pillow +w +oriental +take vase +n +w +take emerald +nw +s +se +w +w +d +water plant +u +e +d +fill bottle +u +e +ne +e +u +e +u +n +plugh +drop pillow +drop vase +drop bottle +drop emerald +xyzzy +take rod +e +take cage +pit +drop rod +e +take bird +w +drop bird +take rod +wave rod +take necklace +drop rod +take bird +d +s +take nugget +n +n +drop bird +take bird +sw +w +kill dragon +yes +drink blood +take rug +e +e +n +take bars +n +plugh +drop cage +drop necklace +drop nugget +drop bars +drop rug +xyzzy +pit +take rod +d +w +wave rod +w +take diamonds +w +w +w +s +s +e +s +hit machine +s +s +kill ogre +n +take ruby +s +w +n +n +sw +w +d +n +e +take coins +e +s +take jewelry +n +e +w +w +w +s +e +s +s +s +n +e +e +nw +drop rod +take jewelry +take chest +take ruby +take diamonds +take coins +se +w +s +d +debris +xyzzy +off +drop coins +drop diamonds +drop jewelry +drop chest +drop lamp +take rug +take emerald +take cage +take bottle +w +s +w +drop bird +listen +drop cage +n +take appendage +n +e +n +n +fill urn +light urn +rub urn +drop rug +take amber +drop emerald +fly +take sapphire +fly +take emerald +drop ruby +take rug +take ruby +e +s +e +e +e +drop emerald +drop ruby +drop amber +drop rug +drop sapphire +fill bottle +take lamp +plugh +on +s +s +sw +w +n +reservoir +n'beh +n +n +u +u +u +u +u +ne +take statuette +sw +d +d +d +d +d +s +s +s +s +d +s +d +water plant +u +e +d +fill bottle +u +w +d +climb +w +take eggs +n +oil door +drop bottle +n +take trident +w +d +bedquilt +e +n +open clam +d +d +take pearl +shell +s +u +e +u +n +plugh +drop trident +drop pearl +drop statuette +drop appendage +take keys +take food +plugh +s +d +bedquilt +w +oriental +w +sw +u +throw eggs +ne +barren +e +throw food +unlock chain +take chain +take bear +fork +ne +fee +fie +foe +foo +e +take spices +fork +w +w +sw +release bear +sw +sw +d +se +se +w +w +d +climb +w +take eggs +n +n +w +d +bedquilt +e +u +e +u +n +plugh +drop eggs +drop chain +drop spices +plugh +s +look +look +n +plugh +s +d +w +d +e +take magazine +e +drop magazine +look +look +look +look +look +look +look +sw +# Here we are +take pillow + From ab2779cd93e4757ea8a7631ed6447def7ded649b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 13:09:57 -0400 Subject: [PATCH 123/213] Remove unneeded use of put(). --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 52e4187..981e4d4 100644 --- a/main.c +++ b/main.c @@ -874,8 +874,8 @@ static bool closecheck(void) game.newloc = LOC_NE; /* Leave the grate with normal (non-negative) property. * Reuse sign. */ - put(GRATE, LOC_SW, 0); - put(SIGN, LOC_SW, 0); + move(GRATE, LOC_SW); + move(SIGN, LOC_SW); game.objects[SIGN].prop = ENDGAME_SIGN; game.objects[SNAKE].prop = put(SNAKE, LOC_SW, SNAKE_CHASED); game.objects[BIRD].prop = put(BIRD, LOC_SW, BIRD_CAGED); From 9cd7c53d789a8a3bc845ff8f6b0e6b46af631627 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 13:19:51 -0400 Subject: [PATCH 124/213] Refactor put() function and calls. --- advent.h | 2 +- main.c | 24 ++++++++++++------------ misc.c | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/advent.h b/advent.h index 62a54ac..55d1b82 100644 --- a/advent.h +++ b/advent.h @@ -276,7 +276,7 @@ extern bool silent_yes_or_no(void); extern bool yes_or_no(const char*, const char*, const char*); extern void juggle(obj_t); extern void move(obj_t, loc_t); -extern loc_t put(obj_t, loc_t, int); +extern void put(obj_t, loc_t, int); extern void carry(obj_t, loc_t); extern void drop(obj_t, loc_t); extern int atdwrf(loc_t); diff --git a/main.c b/main.c index 981e4d4..a740b42 100644 --- a/main.c +++ b/main.c @@ -863,12 +863,12 @@ static bool closecheck(void) * objects he might be carrying (lest he have some which * could cause trouble, such as the keys). We describe the * flash of light and trundle back. */ - game.objects[BOTTLE].prop = put(BOTTLE, LOC_NE, EMPTY_BOTTLE); - game.objects[PLANT].prop = put(PLANT, LOC_NE, PLANT_THIRSTY); - game.objects[OYSTER].prop = put(OYSTER, LOC_NE, STATE_FOUND); - game.objects[LAMP].prop = put(LAMP, LOC_NE, LAMP_DARK); - game.objects[ROD].prop = put(ROD, LOC_NE, STATE_FOUND); - game.objects[DWARF].prop = put(DWARF, LOC_NE, 0); + put(BOTTLE, LOC_NE, EMPTY_BOTTLE); + put(PLANT, LOC_NE, PLANT_THIRSTY); + put(OYSTER, LOC_NE, STATE_FOUND); + put(LAMP, LOC_NE, LAMP_DARK); + put(ROD, LOC_NE, STATE_FOUND); + put(DWARF, LOC_NE, 0); game.loc = LOC_NE; game.oldloc = LOC_NE; game.newloc = LOC_NE; @@ -877,13 +877,13 @@ static bool closecheck(void) move(GRATE, LOC_SW); move(SIGN, LOC_SW); game.objects[SIGN].prop = ENDGAME_SIGN; - game.objects[SNAKE].prop = put(SNAKE, LOC_SW, SNAKE_CHASED); - game.objects[BIRD].prop = put(BIRD, LOC_SW, BIRD_CAGED); - game.objects[CAGE].prop = put(CAGE, LOC_SW, STATE_FOUND); - game.objects[ROD2].prop = put(ROD2, LOC_SW, STATE_FOUND); - game.objects[PILLOW].prop = put(PILLOW, LOC_SW, STATE_FOUND); + put(SNAKE, LOC_SW, SNAKE_CHASED); + put(BIRD, LOC_SW, BIRD_CAGED); + put(CAGE, LOC_SW, STATE_FOUND); + put(ROD2, LOC_SW, STATE_FOUND); + put(PILLOW, LOC_SW, STATE_FOUND); - game.objects[MIRROR].prop = put(MIRROR, LOC_NE, STATE_FOUND); + put(MIRROR, LOC_NE, STATE_FOUND); game.objects[MIRROR].fixed = LOC_SW; for (int i = 1; i <= NOBJECTS; i++) { diff --git a/misc.c b/misc.c index b8bc461..8889941 100644 --- a/misc.c +++ b/misc.c @@ -595,12 +595,12 @@ void move(obj_t object, loc_t where) drop(object, where); } -loc_t put(obj_t object, loc_t where, int pval) +void put(obj_t object, loc_t where, int pval) /* put() is the same as move(), except it returns a value used to set up the * negated game.prop values for the repository objects. */ { move(object, where); - return (-1) - pval;; // Needs to stay sinchronized with STASHED + game.objects[object].prop = (-1) - pval;; // Needs to stay synchronized with STASHED } void carry(obj_t object, loc_t where) From 02987d0330cf586a90307ad7e8a06cfcde6f6b92 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 7 Apr 2023 16:11:04 -0400 Subject: [PATCH 125/213] Encapsulate object-state state tests and setttings in macros. This isn't a complete refwctoring, just the part than can be done with transparetly correct capture of inlinre logic into macros. No logic changes. Tests pass, 100% coverage. --- actions.c | 19 +++++++++---------- advent.h | 13 +++++++++++-- init.c | 2 +- main.c | 16 ++++++++-------- misc.c | 2 +- saveresume.c | 3 +-- score.c | 2 +- 7 files changed, 32 insertions(+), 25 deletions(-) diff --git a/actions.c b/actions.c index 20f0b90..cbc8d3f 100644 --- a/actions.c +++ b/actions.c @@ -244,7 +244,7 @@ static phase_codes_t bigwords(vocab_t id) static void blast(void) /* Blast. No effect unless you've got dynamite, which is a neat trick! */ { - if (game.objects[ROD2].prop == STATE_NOTFOUND || !game.closed) + if (PROP_IS_NOTFOUND(ROD2) || !game.closed) rspeak(REQUIRES_DYNAMITE); else { if (HERE(ROD2)) { @@ -376,7 +376,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) } - if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && STASHED(BIRD) != BIRD_CAGED) { + if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && !PROP_IS_STASHED(BIRD)) { if (game.objects[BIRD].prop == BIRD_FOREST_UNCAGED) { DESTROY(BIRD); rspeak(BIRD_CRAP); @@ -393,7 +393,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) game.objects[BIRD].prop = BIRD_CAGED; } if ((obj == BIRD || obj == CAGE) && - (game.objects[BIRD].prop == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) { + (game.objects[BIRD].prop == BIRD_CAGED || PROP_STASHED(BIRD) == BIRD_CAGED)) { /* expression maps BIRD to CAGE and CAGE to BIRD */ carry(BIRD + CAGE - obj, game.loc); } @@ -403,8 +403,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) if (obj == BOTTLE && LIQUID() != NO_OBJECT) game.objects[LIQUID()].place = CARRIED; - if (GSTONE(obj) && game.objects[obj].prop != STATE_FOUND) { - game.objects[obj].prop = STATE_FOUND; + if (GSTONE(obj) && !PROP_IS_FOUND(obj)) { + PROP_SET_FOUND(obj); game.objects[CAVITY].prop = CAVITY_EMPTY; } rspeak(OK_MAN); @@ -936,7 +936,7 @@ static phase_codes_t listen(void) soundlatch = true; } for (obj_t i = 1; i <= NOBJECTS; i++) { - if (!HERE(i) || objects[i].sounds[0] == NULL || game.objects[i].prop < 0) + if (!HERE(i) || objects[i].sounds[0] == NULL || PROP_IS_STASHED_OR_UNSEEN(i)) continue; int mi = game.objects[i].prop; /* (ESR) Some unpleasant magic on object states here. Ideally @@ -1116,8 +1116,7 @@ static phase_codes_t read(command_t command) } else { pspeak(OYSTER, hear, true, 1); // Not really a sound, but oh well. } - } else if (objects[command.obj].texts[0] == NULL || - game.objects[command.obj].prop == STATE_NOTFOUND) { + } else if (objects[command.obj].texts[0] == NULL || PROP_IS_NOTFOUND(command.obj)) { speak(actions[command.verb].message); } else pspeak(command.obj, study, true, game.objects[command.obj].prop); @@ -1297,9 +1296,9 @@ static phase_codes_t wave(verb_t verb, obj_t obj) } if (game.objects[BIRD].prop == BIRD_UNCAGED && game.loc == game.objects[STEPS].place - && game.objects[JADE].prop == STATE_NOTFOUND) { + && PROP_IS_NOTFOUND(JADE)) { drop(JADE, game.loc); - game.objects[JADE].prop = STATE_FOUND; + PROP_SET_FOUND(JADE); --game.tally; rspeak(NECKLACE_FLY); return GO_CLEAROBJ; diff --git a/advent.h b/advent.h index 55d1b82..738d546 100644 --- a/advent.h +++ b/advent.h @@ -48,10 +48,19 @@ #define IS_FIXED -1 #define IS_FREE 0 -/* Map a state property value to a negative range, where the object cannot be +/* STASH map a state property value to a negative range, where the object cannot be * picked up but the value can be recovered later. Avoid colliding with -1, * which has its own meaning as STATE_NOTFOUND. */ -#define STASHED(obj) (-1 - game.objects[obj].prop) +#define PROP_STASHED(obj) (STATE_NOTFOUND - game.objects[obj].prop) +#define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) +#define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) +/* Don't use this on an object wi nore thab 2 (unstashed) states */ +#define PROP_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) +/* Magic number -2 allows a PROP_STASHED version of state 1 */ +#define PROP_IS_INVALID(val) (val < -2 || val > 1) +#define PROP_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) +#define PROP_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) +#define PROP_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) #define PROMPT "> " diff --git a/init.c b/init.c index c384f71..0813fb7 100644 --- a/init.c +++ b/init.c @@ -90,7 +90,7 @@ int initialise(void) for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { if (objects[treasure].inventory != 0) - game.objects[treasure].prop = STATE_NOTFOUND; + PROP_SET_NOT_FOUND(treasure); game.tally = game.tally - game.objects[treasure].prop; } } diff --git a/main.c b/main.c index a740b42..4b6165e 100644 --- a/main.c +++ b/main.c @@ -139,7 +139,7 @@ static void checkhints(void) game.hints[hint].lc = 0; return; case 4: /* dark */ - if (game.objects[EMERALD].prop != STATE_NOTFOUND && game.objects[PYRAMID].prop == STATE_NOTFOUND) + if (!PROP_IS_NOTFOUND(EMERALD) && PROP_IS_NOTFOUND(PYRAMID)) break; game.hints[hint].lc = 0; return; @@ -166,7 +166,7 @@ static void checkhints(void) break; return; case 9: /* jade */ - if (game.tally == 1 && game.objects[JADE].prop < 0) + if (game.tally == 1 && PROP_IS_STASHED_OR_UNSEEN(JADE)) break; game.hints[hint].lc = 0; return; @@ -196,10 +196,10 @@ static bool spotted_by_pirate(int i) /* The pirate's spotted him. Pirate leaves him alone once we've * found chest. K counts if a treasure is here. If not, and * tally=1 for an unseen chest, let the pirate be spotted. Note - * that game.place[CHEST] = LOC_NOWHERE might mean that he's thrown + * that game.objexts,place[CHEST] = LOC_NOWHERE might mean that he's thrown * it to the troll, but in that case he's seen the chest - * (game.prop[CHEST] == STATE_FOUND). */ - if (game.loc == game.chloc || game.objects[CHEST].prop != STATE_NOTFOUND) + * PROP_IS_FOUND(CHEST) == true. */ + if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST)) return true; int snarfed = 0; bool movechest = false, robplayer = false; @@ -917,10 +917,10 @@ static void listobjects(void) obj = obj - NOBJECTS; if (obj == STEPS && TOTING(NUGGET)) continue; - if (game.objects[obj].prop < 0) { + if (PROP_IS_STASHED_OR_UNSEEN(obj)) { if (game.closed) continue; - game.objects[obj].prop = STATE_FOUND; + PROP_SET_FOUND(obj); if (obj == RUG) game.objects[RUG].prop = RUG_DRAGON; if (obj == CHAIN) @@ -1102,7 +1102,7 @@ static bool do_command(void) pspeak(OYSTER, look, true, 1); for (size_t i = 1; i <= NOBJECTS; i++) { if (TOTING(i) && game.objects[i].prop < 0) - game.objects[i].prop = STASHED(i); + game.objects[i].prop = PROP_STASHED(i); } } diff --git a/misc.c b/misc.c index 8889941..f224d4c 100644 --- a/misc.c +++ b/misc.c @@ -600,7 +600,7 @@ void put(obj_t object, loc_t where, int pval) * negated game.prop values for the repository objects. */ { move(object, where); - game.objects[object].prop = (-1) - pval;; // Needs to stay synchronized with STASHED + game.objects[object].prop = (-1) - pval;; // Needs to stay synchronized with PROP_STASHED } void carry(obj_t object, loc_t where) diff --git a/saveresume.c b/saveresume.c index 4cac034..ceda43c 100644 --- a/saveresume.c +++ b/saveresume.c @@ -229,8 +229,7 @@ bool is_valid(struct game_t valgame) /* Check that properties of objects aren't beyond expected */ for (obj_t obj = 0; obj <= NOBJECTS; obj++) { - /* Magic number -2 allows a STASHED version of state 1 */ - if (valgame.objects[obj].prop < -2 || valgame.objects[obj].prop > 1) { + if (PROP_IS_INVALID(valgame.objects[obj].prop)) { switch (obj) { case RUG: case DRAGON: diff --git a/score.c b/score.c index 2e804e4..ed9cded 100644 --- a/score.c +++ b/score.c @@ -50,7 +50,7 @@ int score(enum termination mode) k = 16; if (game.objects[i].prop > STATE_NOTFOUND) score += 2; - if (game.objects[i].place == LOC_BUILDING && game.objects[i].prop == STATE_FOUND) + if (game.objects[i].place == LOC_BUILDING && PROP_IS_FOUND(i)) score += k - 2; mxscor += k; } From c82d1214fa0de6237e1bece692e2f9f439fa68a9 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 8 Apr 2023 20:02:27 -0400 Subject: [PATCH 126/213] First nontrivial replacement of object state test by macro. Test was game.objects[i].prop >= 0, but we know that state -1 (STATE_NOTFOUND) can't occiur here because the object is in a lit room. --- actions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions.c b/actions.c index cbc8d3f..4f4ced1 100644 --- a/actions.c +++ b/actions.c @@ -1099,7 +1099,7 @@ static phase_codes_t read(command_t command) if (command.obj == INTRANSITIVE) { command.obj = NO_OBJECT; for (int i = 1; i <= NOBJECTS; i++) { - if (HERE(i) && objects[i].texts[0] != NULL && game.objects[i].prop >= 0) + if (HERE(i) && objects[i].texts[0] != NULL && !PROP_IS_STASHED(i)) command.obj = command.obj * NOBJECTS + i; } if (command.obj > NOBJECTS || command.obj == NO_OBJECT || DARK(game.loc)) From 191d3cb04393599e90be909013494ca6f68ba328 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 8 Apr 2023 20:20:36 -0400 Subject: [PATCH 127/213] More nontrivial macro abstraction of state checks. game.prop < 0 becomes an alternation of macros. --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 4b6165e..196a4ed 100644 --- a/main.c +++ b/main.c @@ -1098,10 +1098,10 @@ static bool do_command(void) * game.prop < 0 and stash them. This way objects won't be * described until they've been picked up and put down * separate from their respective piles. */ - if (game.objects[OYSTER].prop < 0 && TOTING(OYSTER)) + if ((PROP_IS_NOTFOUND(OYSTER) || PROP_IS_STASHED(OYSTER)) && TOTING(OYSTER)) pspeak(OYSTER, look, true, 1); for (size_t i = 1; i <= NOBJECTS; i++) { - if (TOTING(i) && game.objects[i].prop < 0) + if (TOTING(i) && (PROP_IS_NOTFOUND(i) || PROP_IS_STASHED(i))) game.objects[i].prop = PROP_STASHED(i); } } From 9e9731d59b79a1a7c4bd4583d621ec125849220a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 8 Apr 2023 21:17:55 -0400 Subject: [PATCH 128/213] Turn an odd test into a macro disjunction. Was game.objects[i].prop > STATE_NOTFOUND. This finishes off all the statec comparisons we want to macroize. --- score.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/score.c b/score.c index ed9cded..c0a0277 100644 --- a/score.c +++ b/score.c @@ -48,7 +48,7 @@ int score(enum termination mode) k = 14; if (i > CHEST) k = 16; - if (game.objects[i].prop > STATE_NOTFOUND) + if (!PROP_IS_STASHED(i) && !PROP_IS_NOTFOUND(i)) score += 2; if (game.objects[i].place == LOC_BUILDING && PROP_IS_FOUND(i)) score += k - 2; From 1af01ff91fd0fee206d096449a564996ea85abed Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 8 Apr 2023 22:53:06 -0400 Subject: [PATCH 129/213] Confine use of STATE_NOTFOUND to macros. --- advent.h | 1 + main.c | 6 +++--- saveresume.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/advent.h b/advent.h index 738d546..b24eed7 100644 --- a/advent.h +++ b/advent.h @@ -61,6 +61,7 @@ #define PROP_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) #define PROP_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) #define PROP_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) +#define PROP_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) #define PROMPT "> " diff --git a/main.c b/main.c index 196a4ed..b90056c 100644 --- a/main.c +++ b/main.c @@ -859,8 +859,8 @@ static bool closecheck(void) * objects come from known locations and/or states (e.g. the * snake is known to have been destroyed and needn't be * carried away from its old "place"), making the various - * objects be handled differently. We also drop all other - * objects he might be carrying (lest he have some which + * objects be handled differently. We also drop all other + * objects he might be acrrying (lest he have some which * could cause trouble, such as the keys). We describe the * flash of light and trundle back. */ put(BOTTLE, LOC_NE, EMPTY_BOTTLE); @@ -868,7 +868,7 @@ static bool closecheck(void) put(OYSTER, LOC_NE, STATE_FOUND); put(LAMP, LOC_NE, LAMP_DARK); put(ROD, LOC_NE, STATE_FOUND); - put(DWARF, LOC_NE, 0); + put(DWARF, LOC_NE, STATE_FOUND); game.loc = LOC_NE; game.oldloc = LOC_NE; game.newloc = LOC_NE; diff --git a/saveresume.c b/saveresume.c index ceda43c..9c788d1 100644 --- a/saveresume.c +++ b/saveresume.c @@ -218,7 +218,7 @@ bool is_valid(struct game_t valgame) int temp_tally = 0; for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { - if (valgame.objects[treasure].prop == STATE_NOTFOUND) { + if (PROP_IS_NOTFOUND2(valgame, treasure)) { ++temp_tally; } } From 82c3ae5e65573b97f52d3c14986d45167fa8f884 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 10 Apr 2023 18:46:47 -0400 Subject: [PATCH 130/213] Condition in alternative state-management macros. These do not entirely work yet. #define FOUNDBOOL to enable them. All tests pass, 100% coverage. --- advent.h | 28 +++++++++++++++++++++++----- misc.c | 5 +++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/advent.h b/advent.h index b24eed7..42491e7 100644 --- a/advent.h +++ b/advent.h @@ -48,20 +48,31 @@ #define IS_FIXED -1 #define IS_FREE 0 -/* STASH map a state property value to a negative range, where the object cannot be - * picked up but the value can be recovered later. Avoid colliding with -1, +/* PROP_STASHED maps a state property value to a negative range, where the object + * cannot be picked up but the value can be recovered later. */ +#ifndef FOUNDBOOL +/* PROP_STASHED needs ro avoid colliding with -1, * which has its own meaning as STATE_NOTFOUND. */ #define PROP_STASHED(obj) (STATE_NOTFOUND - game.objects[obj].prop) #define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) #define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) -/* Don't use this on an object wi nore thab 2 (unstashed) states */ #define PROP_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) -/* Magic number -2 allows a PROP_STASHED version of state 1 */ -#define PROP_IS_INVALID(val) (val < -2 || val > 1) #define PROP_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) #define PROP_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) #define PROP_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) #define PROP_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) +#else +#define PROP_STASHED(obj) (-game.objects[obj].prop) +#define PROP_IS_STASHED(obj) (game.objects[obj].prop < 0) +#define PROP_IS_NOTFOUND(obj) (!game.objects[obj].found) +#define PROP_IS_FOUND(obj) (game.objects[obj].found && game.objects[obj].prop == 0) +#define PROP_IS_STASHED_OR_UNSEEN(obj) (!game.objects[obj].found || game.objects[obj].prop < 0) +#define PROP_SET_FOUND(obj) do {game.objects[obj].found = true; game.objects[obj].prop = STATE_FOUND;} while(0) +#define PROP_SET_NOT_FOUND(obj) game.objects[obj].found = false +#define PROP_IS_NOTFOUND2(g, o) (!g.objects[o].found) +#endif +/* Magic number -2 allows a PROP_STASHED version of state 1 */ +#define PROP_IS_INVALID(val) (val < -2 || val > 1) #define PROMPT "> " @@ -202,13 +213,20 @@ struct game_t { loc_t oldloc; // prior loc of each dwarf, initially garbage } dwarves[NDWARVES + 1]; struct { +#ifdef FOUNDBOOL + bool found; // has the location of this object bween found? +#endif loc_t fixed; // fixed location of object (if not IS_FREE) int prop; // object state */ loc_t place; // location of object } objects[NOBJECTS + 1]; struct { bool used; // hints[i].used = true iff hint i has been used. +#ifndef FOUNDBOOL int lc; // hints[i].lc = show int at LOC with cond bit i +#else + int lc; // hints[i].lc = show int at LOC with cond bit i +#endif } hints[NHINTS]; obj_t link[NOBJECTS * 2 + 1];// object-list links }; diff --git a/misc.c b/misc.c index f224d4c..0d540c6 100644 --- a/misc.c +++ b/misc.c @@ -600,7 +600,12 @@ void put(obj_t object, loc_t where, int pval) * negated game.prop values for the repository objects. */ { move(object, where); +#ifndef FOUNDBOOL game.objects[object].prop = (-1) - pval;; // Needs to stay synchronized with PROP_STASHED +#else + game.objects[object].prop = - pval;; // Needs to stay synchronized with PROP_STASHED + game.objects[object].found = true; +#endif } void carry(obj_t object, loc_t where) From 4d4e8dce96cc9401151181a259c5160291031947 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 10 Apr 2023 10:28:18 -0400 Subject: [PATCH 131/213] Magic-number elimination. --- advent.h | 4 ++-- make_dungeon.py | 3 +++ saveresume.c | 23 +---------------------- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/advent.h b/advent.h index 42491e7..cb2b71b 100644 --- a/advent.h +++ b/advent.h @@ -61,6 +61,7 @@ #define PROP_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) #define PROP_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) #define PROP_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) +#define PROP_IS_INVALID(val) (val < -MAX_STATE - 1 || val > MAX_STATE) #else #define PROP_STASHED(obj) (-game.objects[obj].prop) #define PROP_IS_STASHED(obj) (game.objects[obj].prop < 0) @@ -70,9 +71,8 @@ #define PROP_SET_FOUND(obj) do {game.objects[obj].found = true; game.objects[obj].prop = STATE_FOUND;} while(0) #define PROP_SET_NOT_FOUND(obj) game.objects[obj].found = false #define PROP_IS_NOTFOUND2(g, o) (!g.objects[o].found) +#define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) #endif -/* Magic number -2 allows a PROP_STASHED version of state 1 */ -#define PROP_IS_INVALID(val) (val < -2 || val > 1) #define PROMPT "> " diff --git a/make_dungeon.py b/make_dungeon.py index a9193b6..bae97f2 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -136,6 +136,7 @@ def get_objects(obj): }}, }}, """ + max_state = 0 obj_str = "" for (i, item) in enumerate(obj): attr = item[1] @@ -159,6 +160,7 @@ def get_objects(obj): statedefines += "/* States for %s */\n" % item[0] for (n, label) in enumerate(labels): statedefines += "#define %s\t%d\n" % (label, n) + max_state = max(max_state, n) statedefines += "\n" sounds_str = "" if attr.get("sounds") is None: @@ -192,6 +194,7 @@ def get_objects(obj): treasure = "true" if attr.get("treasure") else "false" obj_str += template.format(i, item[0], words_str, i_msg, locs[0], locs[1], treasure, descriptions_str, sounds_str, texts_str, changes_str) obj_str = obj_str[:-1] # trim trailing newline + statedefines += "/* Maximum state value */\n#define MAX_STATE %d\n" % max_state return obj_str def get_obituaries(obit): diff --git a/saveresume.c b/saveresume.c index 9c788d1..70b9461 100644 --- a/saveresume.c +++ b/saveresume.c @@ -230,28 +230,7 @@ bool is_valid(struct game_t valgame) /* Check that properties of objects aren't beyond expected */ for (obj_t obj = 0; obj <= NOBJECTS; obj++) { if (PROP_IS_INVALID(valgame.objects[obj].prop)) { - switch (obj) { - case RUG: - case DRAGON: - case BIRD: - case BOTTLE: - case PLANT: - case PLANT2: - case TROLL: - case URN: - case EGGS: - case VASE: - case CHAIN: - if (valgame.objects[obj].prop == 2) // There are multiple different states, but it's convenient to clump them together - continue; // LCOV_EXCL_LINE - /* FALLTHRU */ - case BEAR: - if (valgame.objects[BEAR].prop == CONTENTED_BEAR || valgame.objects[BEAR].prop == BEAR_DEAD) - continue; - /* FALLTHRU */ - default: - return false; // LCOV_EXCL_LINE - } + return false; // LCOV_EXCL_LINE } } From 88feaab0c050b6ca2289df121e80d7b64cf596d9 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 10 Apr 2023 18:33:36 -0400 Subject: [PATCH 132/213] Remove a remnant line number. --- main.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/main.c b/main.c index b90056c..92ab1b1 100644 --- a/main.c +++ b/main.c @@ -783,19 +783,19 @@ static bool closecheck(void) * chest, which may of course never show up). Note that the * treasures need not have been taken yet, just located. Hence * clock1 must be large enough to get out of the cave (it only ticks - * while inside the cave). When it hits zero, we branch to 10000 to - * start closing the cave, and then sit back and wait for him to try - * to get out. If he doesn't within clock2 turns, we close the cave; - * if he does try, we assume he panics, and give him a few additional - * turns to get frantic before we close. When clock2 hits zero, we - * transport him into the final puzzle. Note that the puzzle depends - * upon all sorts of random things. For instance, there must be no - * water or oil, since there are beanstalks which we don't want to be - * able to water, since the code can't handle it. Also, we can have - * no keys, since there is a grate (having moved the fixed object!) - * there separating him from all the treasures. Most of these - * problems arise from the use of negative prop numbers to suppress - * the object descriptions until he's actually moved the objects. */ + * while inside the cave). When it hits zero, we start closing the + * cave, and then sit back and wait for him to try to get out. If he + * doesn't within clock2 turns, we close the cave; if he does try, we + * assume he panics, and give him a few additional turns to get + * frantic before we close. When clock2 hits zero, we transport him + * into the final puzzle. Note that the puzzle depends upon all + * sorts of random things. For instance, there must be no water or + * oil, since there are beanstalks which we don't want to be able to + * water, since the code can't handle it. Also, we can have no keys, + * since there is a grate (having moved the fixed object!) there + * separating him from all the treasures. Most of these problems + * arise from the use of negative prop numbers to suppress the object + * descriptions until he's actually moved the objects. */ { /* If a turn threshold has been met, apply penalties and tell * the player about it. */ From 9ff036d789ff734b2abe15276e369f57bd41501a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 14 Apr 2023 06:16:29 -0400 Subject: [PATCH 133/213] Make build with conditional compilation easier. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5d306b0..8a09496 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ VERS=$(shell sed -n Date: Fri, 14 Apr 2023 08:13:24 -0400 Subject: [PATCH 134/213] Simplify initialization code. All tests pass, 100% coverage. --- init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.c b/init.c index 0813fb7..532f271 100644 --- a/init.c +++ b/init.c @@ -89,9 +89,9 @@ int initialise(void) * not yet found, so we know when to close the cave. */ for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { + ++game.tally; if (objects[treasure].inventory != 0) PROP_SET_NOT_FOUND(treasure); - game.tally = game.tally - game.objects[treasure].prop; } } game.conds = setbit(COND_HBASE); From 5d3205e1e9e29bc477e7f785a263cd43dd9cd1bd Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 15 Apr 2023 06:29:59 -0400 Subject: [PATCH 135/213] Add explanatory comments. --- NEWS.adoc | 2 +- advent.h | 32 +++++++++++++++++++++++++++----- main.c | 4 ++++ misc.c | 4 +++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/NEWS.adoc b/NEWS.adoc index b879e17..c390e7e 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 -Reoisitory head:: +Repository head:: Savefiles now have an identifying magic cookie at the front. Resume detects if a save has incompatible endianness. diff --git a/advent.h b/advent.h index cb2b71b..0cbe7fb 100644 --- a/advent.h +++ b/advent.h @@ -48,12 +48,27 @@ #define IS_FIXED -1 #define IS_FREE 0 -/* PROP_STASHED maps a state property value to a negative range, where the object - * cannot be picked up but the value can be recovered later. */ #ifndef FOUNDBOOL -/* PROP_STASHED needs ro avoid colliding with -1, - * which has its own meaning as STATE_NOTFOUND. */ -#define PROP_STASHED(obj) (STATE_NOTFOUND - game.objects[obj].prop) +/* (ESR) It is fitting that translation of the original ADVENT should + * have left us a maze of twisty little conditionals that resists all + * understanding. Setting and use of what is now the per-object state + * member (which used to be an array of its own) is our mystery. This + * state tangles together information about whether the object is a + * treasure, whether the player has seen it yet, and its activation + * state. + * + * Things we think we know: + * + * STATE_NOTFOUND is only set on treasures. Non-treasures start the + * game in STATE_FOUND. + * + * PROP_STASHED is supposed to map a state property value to a + * negative range, where the object cannot be picked up but the value + * can be recovered later. Various objects get this peoperty when + * the cave starts to close. On;y seems to be signifucant for the bird + * and readable objects, notably the clam/oyster - but the code around + * those test is difficult to read. */ +#define PROP_STASHED(obj) (-1 - game.objects[obj].prop) #define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) #define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) #define PROP_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) @@ -63,6 +78,13 @@ #define PROP_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) #define PROP_IS_INVALID(val) (val < -MAX_STATE - 1 || val > MAX_STATE) #else +/* (ESR) Only the boldest of adventurers will explore here. This + * alternate set of definitions for the macros above was an attempt to + * break from out of the state encoding a per-object "found" member + * telling whether or not the player has seen the object. These is one + * accompanying change in misc.c. What's broken when you try to use + * thus is PROP_IS_STASHED_OR_UNSEEN. + */ #define PROP_STASHED(obj) (-game.objects[obj].prop) #define PROP_IS_STASHED(obj) (game.objects[obj].prop < 0) #define PROP_IS_NOTFOUND(obj) (!game.objects[obj].found) diff --git a/main.c b/main.c index 92ab1b1..c688018 100644 --- a/main.c +++ b/main.c @@ -917,6 +917,10 @@ static void listobjects(void) obj = obj - NOBJECTS; if (obj == STEPS && TOTING(NUGGET)) continue; + /* (ESR) Warning: it looks like you could get away with + * running this code only on objects with the treasure + * property set. Nope. There is mystery here. + */ if (PROP_IS_STASHED_OR_UNSEEN(obj)) { if (game.closed) continue; diff --git a/misc.c b/misc.c index 0d540c6..f6a37f7 100644 --- a/misc.c +++ b/misc.c @@ -600,8 +600,10 @@ void put(obj_t object, loc_t where, int pval) * negated game.prop values for the repository objects. */ { move(object, where); + /* (ESR) Read this in combination with the macro defintions in advebt.h. + */ #ifndef FOUNDBOOL - game.objects[object].prop = (-1) - pval;; // Needs to stay synchronized with PROP_STASHED + game.objects[object].prop = (-1) - pval; // Needs to stay synchronized with PROP_STASHED #else game.objects[object].prop = - pval;; // Needs to stay synchronized with PROP_STASHED game.objects[object].found = true; From ef78c36ddb2c4d3715a3885525bc4106fffb3060 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 15 Apr 2023 09:29:28 -0400 Subject: [PATCH 136/213] Improve state-macro encapsulation. --- advent.h | 14 +++++++++----- init.c | 7 ++++--- misc.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/advent.h b/advent.h index 0cbe7fb..4188b17 100644 --- a/advent.h +++ b/advent.h @@ -68,7 +68,7 @@ * the cave starts to close. On;y seems to be signifucant for the bird * and readable objects, notably the clam/oyster - but the code around * those test is difficult to read. */ -#define PROP_STASHED(obj) (-1 - game.objects[obj].prop) +#define PROP_STASHIFY(n) (-1 - (n)) #define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) #define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) #define PROP_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) @@ -81,11 +81,13 @@ /* (ESR) Only the boldest of adventurers will explore here. This * alternate set of definitions for the macros above was an attempt to * break from out of the state encoding a per-object "found" member - * telling whether or not the player has seen the object. These is one - * accompanying change in misc.c. What's broken when you try to use - * thus is PROP_IS_STASHED_OR_UNSEEN. + * telling whether or not the player has seen the object. + * + * What's broken when you try to use thus is + * PROP_IS_STASHED_OR_UNSEEN. The symptom is game.tally getting + * decremented on non-treasures. */ -#define PROP_STASHED(obj) (-game.objects[obj].prop) +#define PROP_STASHIFY(n) (-(n)) #define PROP_IS_STASHED(obj) (game.objects[obj].prop < 0) #define PROP_IS_NOTFOUND(obj) (!game.objects[obj].found) #define PROP_IS_FOUND(obj) (game.objects[obj].found && game.objects[obj].prop == 0) @@ -94,7 +96,9 @@ #define PROP_SET_NOT_FOUND(obj) game.objects[obj].found = false #define PROP_IS_NOTFOUND2(g, o) (!g.objects[o].found) #define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) +#define PROP_SET_SEEN(obj) game.objects[object].found = true #endif +#define PROP_STASHED(obj) PROP_STASHIFY(game.objects[obj].prop) #define PROMPT "> " diff --git a/init.c b/init.c index 532f271..9104a59 100644 --- a/init.c +++ b/init.c @@ -84,9 +84,10 @@ int initialise(void) drop(k, objects[k].plac); } - /* Treasure props are initially -1, and are set to 0 the first time - * they are described. game.tally keeps track of how many are - * not yet found, so we know when to close the cave. */ + /* Treasure props are initially STATE_NOTFOUND, and are set to + * STATE_FOUND the first time they are described. game.tally + * keeps track of how many are not yet found, so we know when to + * close the cave. */ for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { ++game.tally; diff --git a/misc.c b/misc.c index f6a37f7..5aebb2a 100644 --- a/misc.c +++ b/misc.c @@ -602,11 +602,9 @@ void put(obj_t object, loc_t where, int pval) move(object, where); /* (ESR) Read this in combination with the macro defintions in advebt.h. */ -#ifndef FOUNDBOOL - game.objects[object].prop = (-1) - pval; // Needs to stay synchronized with PROP_STASHED -#else - game.objects[object].prop = - pval;; // Needs to stay synchronized with PROP_STASHED - game.objects[object].found = true; + game.objects[object].prop = PROP_STASHIFY(pval); +#ifdef PROP_SET_SEEN + PROP_SET_SEEN(object); #endif } From 869c53d1b1ae2d1da6cbb37070e76054e65cd559 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 15 Apr 2023 10:00:23 -0400 Subject: [PATCH 137/213] Comment polishing. --- advent.h | 5 +++-- main.c | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/advent.h b/advent.h index 4188b17..946fcae 100644 --- a/advent.h +++ b/advent.h @@ -64,10 +64,11 @@ * * PROP_STASHED is supposed to map a state property value to a * negative range, where the object cannot be picked up but the value - * can be recovered later. Various objects get this peoperty when + * can be recovered later. Various objects get this property when * the cave starts to close. On;y seems to be signifucant for the bird * and readable objects, notably the clam/oyster - but the code around - * those test is difficult to read. */ + * those test is difficult to read. + */ #define PROP_STASHIFY(n) (-1 - (n)) #define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) #define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) diff --git a/main.c b/main.c index c688018..cbaf92c 100644 --- a/main.c +++ b/main.c @@ -1098,10 +1098,11 @@ static bool do_command(void) while (command.state <= GIVEN) { if (game.closed) { - /* If closing time, check for any objects being toted with - * game.prop < 0 and stash them. This way objects won't be - * described until they've been picked up and put down - * separate from their respective piles. */ + /* If closing time, check for any stashed objects + * being toted and unstash them. This way objects + * won't be described until they've been picked up + * and put down separate from their respective + * piles. */ if ((PROP_IS_NOTFOUND(OYSTER) || PROP_IS_STASHED(OYSTER)) && TOTING(OYSTER)) pspeak(OYSTER, look, true, 1); for (size_t i = 1; i <= NOBJECTS; i++) { From adbb5c1204523b01956d8a054e614a7b0c878e19 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 15 Apr 2023 14:44:20 -0400 Subject: [PATCH 138/213] Ready to ship 1.16. --- NEWS.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.adoc b/NEWS.adoc index c390e7e..54774fe 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 -Repository head:: +1.16: 2023-04-15:: Savefiles now have an identifying magic cookie at the front. Resume detects if a save has incompatible endianness. From 234da6b468a5014a622d1dfd3c5a55bf019ff922 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 17 Apr 2023 07:06:56 -0400 Subject: [PATCH 139/213] Remove unnecessary code duplication. --- advent.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/advent.h b/advent.h index 946fcae..fa87028 100644 --- a/advent.h +++ b/advent.h @@ -249,11 +249,7 @@ struct game_t { } objects[NOBJECTS + 1]; struct { bool used; // hints[i].used = true iff hint i has been used. -#ifndef FOUNDBOOL int lc; // hints[i].lc = show int at LOC with cond bit i -#else - int lc; // hints[i].lc = show int at LOC with cond bit i -#endif } hints[NHINTS]; obj_t link[NOBJECTS * 2 + 1];// object-list links }; From 6cef68cda5fba95b24e7ce7141166354f8f945ad Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 17 Apr 2023 07:24:51 -0400 Subject: [PATCH 140/213] Use fixed-lwength types to make the save format more portable --- advent.h | 72 ++++++++++++++++++++++--------------------- tests/resumefail2.chk | 2 +- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/advent.h b/advent.h index fa87028..41c659f 100644 --- a/advent.h +++ b/advent.h @@ -176,30 +176,32 @@ typedef enum { GO_DWARFWAKE, } phase_codes_t; -typedef int vocab_t; // index into a vocabulary array */ -typedef int verb_t; // index into an actions array */ -typedef int obj_t; // index into the object array */ -typedef int loc_t; // index into the locations array */ -typedef int turn_t; // turn counter or threshold */ +/* Use fixed-lwength types to make the save format moore portable */ +typedef int32_t vocab_t; // index into a vocabulary array */ +typedef int32_t verb_t; // index into an actions array */ +typedef int32_t obj_t; // index into the object array */ +typedef int32_t loc_t; // index into the locations array */ +typedef int32_t turn_t; // turn counter or threshold */ +typedef int32_t bool32_t; // turn counter or threshold */ struct game_t { int32_t lcg_x; - int abbnum; // How often to print int descriptions + int32_t abbnum; // How often to print int descriptions score_t bonus; // What kind of finishing bonus we are getting loc_t chloc; // pirate chest location loc_t chloc2; // pirate chest alternate location turn_t clock1; // # turns from finding last treasure to close turn_t clock2; // # turns from warning till blinding flash - bool clshnt; // has player read the clue in the endgame? - bool closed; // whether we're all the way closed - bool closng; // whether it's closing time yet - bool lmwarn; // has player been warned about lamp going dim? - bool novice; // asked for instructions at start-up? - bool panic; // has player found out he's trapped? - bool wzdark; // whether the loc he's leaving was dark - bool blooded; // has player drunk of dragon's blood? - int conds; // min value for cond[loc] if loc has any hints - int detail; // level of detail in descriptions + bool32_t clshnt; // has player read the clue in the endgame? + bool32_t closed; // whether we're all the way closed + bool32_t closng; // whether it's closing time yet + bool32_t lmwarn; // has player been warned about lamp going dim? + bool32_t novice; // asked for instructions at start-up? + bool32_t panic; // has player found out he's trapped? + bool32_t wzdark; // whether the loc he's leaving was dark + bool32_t blooded; // has player drunk of dragon's blood? + int32_t conds; // min value for cond[loc] if loc has any hints + int32_t detail; // level of detail in descriptions /* dflag controls the level of activation of dwarves: * 0 No dwarf stuff yet (wait until reaches Hall Of Mists) @@ -207,14 +209,14 @@ struct game_t { * 2 Met first dwarf, others start moving, no knives thrown yet * 3 A knife has been thrown (first set always misses) * 3+ Dwarves are mad (increases their accuracy) */ - int dflag; + int32_t dflag; - int dkill; // dwarves killed - int dtotal; // total dwarves (including pirate) in loc - int foobar; // progress in saying "FEE FIE FOE FOO". - int holdng; // number of objects being carried - int igo; // # uses of "go" instead of a direction - int iwest; // # times he's said "west" instead of "w" + int32_t dkill; // dwarves killed + int32_t dtotal; // total dwarves (including pirate) in loc + int32_t foobar; // progress in saying "FEE FIE FOE FOO". + int32_t holdng; // number of objects being carried + int32_t igo; // # uses of "go" instead of a direction + int32_t iwest; // # times he's said "west" instead of "w" loc_t knfloc; // knife location; LOC_NOWERE if none, -1 after caveat turn_t limit; // lifetime of lamp loc_t loc; // where player is now @@ -223,33 +225,33 @@ struct game_t { loc_t oldloc; // where player was loc_t oldlc2; // where player was two moves ago obj_t oldobj; // last object player handled - int saved; // point penalty for saves - int tally; // count of treasures gained - int thresh; // current threshold for endgame scoring tier - bool seenbigwords; // have we red the graffiti in the Giant's Room? + int32_t saved; // point penalty for saves + int32_t tally; // count of treasures gained + int32_t thresh; // current threshold for endgame scoring tier + bool32_t seenbigwords; // have we red the graffiti in the Giant's Room? turn_t trnluz; // # points lost so far due to turns used turn_t turns; // counts commands given (ignores yes/no) char zzword[TOKLEN + 1]; // randomly generated magic word from bird struct { - int abbrev; // has location been seen? - int atloc; // head of object linked list per location + int32_t abbrev; // has location been seen? + int32_t atloc; // head of object linked list per location } locs[NLOCATIONS + 1]; struct { - int seen; // true if dwarf has seen him + int32_t seen; // true if dwarf has seen him loc_t loc; // location of dwarves, initially hard-wired in loc_t oldloc; // prior loc of each dwarf, initially garbage } dwarves[NDWARVES + 1]; struct { #ifdef FOUNDBOOL - bool found; // has the location of this object bween found? + bool32_t found; // has the location of this object bween found? #endif loc_t fixed; // fixed location of object (if not IS_FREE) - int prop; // object state */ + int32_t prop; // object state */ loc_t place; // location of object } objects[NOBJECTS + 1]; struct { - bool used; // hints[i].used = true iff hint i has been used. - int lc; // hints[i].lc = show int at LOC with cond bit i + bool32_t used; // hints[i].used = true iff hint i has been used. + int32_t lc; // hints[i].lc = show int at LOC with cond bit i } hints[NHINTS]; obj_t link[NOBJECTS * 2 + 1];// object-list links }; @@ -292,7 +294,7 @@ typedef struct { * files afterwards. Otherwise you will get a spurious failure due to the old version * having been generated into a check file. */ -#define SAVE_VERSION 30 +#define SAVE_VERSION 31 /* * Goes at start of file so saves can be identified by file(1) and the like. diff --git a/tests/resumefail2.chk b/tests/resumefail2.chk index 7493ad8..2aa9441 100644 --- a/tests/resumefail2.chk +++ b/tests/resumefail2.chk @@ -11,7 +11,7 @@ down a gully. Can't open file y, try again. I'm sorry, but that Adventure was begun using Version -133.-7 of the -save file format, and this program uses Version 3.0. You must find an instance +save file format, and this program uses Version 3.1. You must find an instance using that other version in order to resume that Adventure. You're in front of building. From ebf3e389c0026c500f9e5d3ca3dc6fb5218ae68f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 17 Apr 2023 09:19:26 -0400 Subject: [PATCH 141/213] Add exolanatory comment. --- adventure.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adventure.yaml b/adventure.yaml index 8909914..e809882 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -3253,7 +3253,9 @@ turn_thresholds: Good grief, don't you *EVER* give up? Do you realize you've spent over 2500 turns at this? That's another ten points off, a total of twenty points lost for taking so long. - + +# Objects names OBJ_* are not made visible by the map-graph generator. +# Don't change these casually. objects: !!omap - NO_OBJECT: inventory: !!null From 5075c63cf4f625105050d2221671d9d1f57d8276 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 18 Apr 2023 07:51:55 -0400 Subject: [PATCH 142/213] Add some map tags. --- adventure.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adventure.yaml b/adventure.yaml index e809882..35c541d 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -784,7 +784,7 @@ locations: !!omap You are in a low n/s passage at a hole in the floor. The hole goes down to an e/w passage. short: 'You''re in n/s passage above e/w passage.' - maptag: !!null + maptag: "Floor hole." conditions: {DEEP: true} travel: [ {verbs: [HALL, OUT, SOUTH], action: [goto, LOC_KINGHALL]}, @@ -1730,7 +1730,7 @@ locations: !!omap description: long: 'You are in a long sloping corridor with ragged sharp walls.' short: !!null - maptag: !!null + maptag: "Sloping corridor" conditions: {DEEP: true} travel: [ {verbs: [UPWAR, SHELL], action: [goto, LOC_SHELLROOM]}, @@ -2048,7 +2048,7 @@ locations: !!omap roar, so loud that the entire cave seems to be trembling. Another passage leads south, and a low crawl goes east. short: 'You''re at junction with warm walls.' - maptag: !!null + maptag: "Warm junction" conditions: {NOARRR: true, DEEP: true} sound: LOUD_ROAR travel: [ From f0119f8431be30713e29ef89a63a45d0fa28111c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 18 Apr 2023 08:02:14 -0400 Subject: [PATCH 143/213] Comment rtpo fix. --- make_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make_graph.py b/make_graph.py index 63e440a..429125e 100755 --- a/make_graph.py +++ b/make_graph.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """\ -usage: make-graph.py [-a] -d] [-m] [-s] +usage: make_graph.py [-a] -d] [-m] [-s] Make a DOT graph of Colossal Cave. From b28eb668688bcfc465cf6731d6c2529067803dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Andersson?= Date: Tue, 18 Apr 2023 18:44:08 +0200 Subject: [PATCH 144/213] Spelling fixes. --- Makefile | 4 ++-- advent.h | 4 ++-- main.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 8a09496..fa18e6f 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ check: advent cheat cd tests; $(MAKE) --quiet # Requires gcov, lcov, libasan6, and libubsan1 -# The last two are Ubuntu names, might vary onb other distributions. +# The last two are Ubuntu names, might vary on other distributions. # After this, run your browser on coverage/open-adventure/index.html # to see coverage results. Browse coverage/adventure.yaml.html # to see symbol coverage over the YAML file. @@ -134,7 +134,7 @@ linty: CCFLAGS += -Winit-self linty: CCFLAGS += -Wpointer-arith linty: advent cheat -# These seem to be more modeern options for enabling coverage testing. +# These seem to be more modern options for enabling coverage testing. # Documenting them here in case a future version bump disables --coverage. #debug: CCFLAGS += -ftest-coverage #debug: CCFLAGS += -fprofile-arcs diff --git a/advent.h b/advent.h index 41c659f..68890da 100644 --- a/advent.h +++ b/advent.h @@ -65,7 +65,7 @@ * PROP_STASHED is supposed to map a state property value to a * negative range, where the object cannot be picked up but the value * can be recovered later. Various objects get this property when - * the cave starts to close. On;y seems to be signifucant for the bird + * the cave starts to close. Only seems to be significant for the bird * and readable objects, notably the clam/oyster - but the code around * those test is difficult to read. */ @@ -243,7 +243,7 @@ struct game_t { } dwarves[NDWARVES + 1]; struct { #ifdef FOUNDBOOL - bool32_t found; // has the location of this object bween found? + bool32_t found; // has the location of this object been found? #endif loc_t fixed; // fixed location of object (if not IS_FREE) int32_t prop; // object state */ diff --git a/main.c b/main.c index cbaf92c..16cf42d 100644 --- a/main.c +++ b/main.c @@ -860,7 +860,7 @@ static bool closecheck(void) * snake is known to have been destroyed and needn't be * carried away from its old "place"), making the various * objects be handled differently. We also drop all other - * objects he might be acrrying (lest he have some which + * objects he might be carrying (lest he has some which * could cause trouble, such as the keys). We describe the * flash of light and trundle back. */ put(BOTTLE, LOC_NE, EMPTY_BOTTLE); From ab4653b89cd3e720a565b61624acff8c2d7cb208 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 18 Apr 2023 08:56:44 -0400 Subject: [PATCH 145/213] Comment polishing. --- make_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make_graph.py b/make_graph.py index 429125e..f33e2b5 100755 --- a/make_graph.py +++ b/make_graph.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """\ -usage: make_graph.py [-a] -d] [-m] [-s] +usage: make_graph.py [-a] -d] [-m] [-s] [-v] Make a DOT graph of Colossal Cave. From 7d4dd78679453010fc71aa51a51fbf4e13b018a8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 17 Sep 2023 16:17:30 -0400 Subject: [PATCH 146/213] Apply black to move Python style to standard form. --- make_dungeon.py | 250 +++++++++++++++++++++++--------------- make_graph.py | 52 +++++--- tests/coverage_dungeon.py | 114 ++++++++++------- 3 files changed, 265 insertions(+), 151 deletions(-) diff --git a/make_dungeon.py b/make_dungeon.py index bae97f2..12f39e7 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -24,6 +24,7 @@ DONOTEDIT_COMMENT = "/* Generated from adventure.yaml - do not hand-hack! */\n\n statedefines = "" + def make_c_string(string): """Render a Python string into C string literal format.""" if string is None: @@ -35,14 +36,16 @@ def make_c_string(string): string = '"' + string + '"' return string + def get_refs(l): reflist = [x[0] for x in l] ref_str = "" for ref in reflist: ref_str += " {},\n".format(ref) - ref_str = ref_str[:-1] # trim trailing newline + ref_str = ref_str[:-1] # trim trailing newline return ref_str + def get_string_group(strings): template = """{{ .strs = {}, @@ -51,20 +54,24 @@ def get_string_group(strings): if strings == []: strs = "NULL" else: - strs = "(const char* []) {" + ", ".join([make_c_string(s) for s in strings]) + "}" + strs = ( + "(const char* []) {" + ", ".join([make_c_string(s) for s in strings]) + "}" + ) n = len(strings) sg_str = template.format(strs, n) return sg_str + def get_arbitrary_messages(arb): template = """ {}, """ arb_str = "" for item in arb: arb_str += template.format(make_c_string(item[1])) - arb_str = arb_str[:-1] # trim trailing newline + arb_str = arb_str[:-1] # trim trailing newline return arb_str + def get_class_messages(cls): template = """ {{ .threshold = {}, @@ -76,9 +83,10 @@ def get_class_messages(cls): threshold = item["threshold"] message = make_c_string(item["message"]) cls_str += template.format(threshold, message) - cls_str = cls_str[:-1] # trim trailing newline + cls_str = cls_str[:-1] # trim trailing newline return cls_str + def get_turn_thresholds(trn): template = """ {{ .threshold = {}, @@ -92,9 +100,10 @@ def get_turn_thresholds(trn): point_loss = item["point_loss"] message = make_c_string(item["message"]) trn_str += template.format(threshold, point_loss, message) - trn_str = trn_str[:-1] # trim trailing newline + trn_str = trn_str[:-1] # trim trailing newline return trn_str + def get_locations(loc): template = """ {{ // {}: {} .description = {{ @@ -112,9 +121,10 @@ def get_locations(loc): sound = item[1].get("sound", "SILENT") loud = "true" if item[1].get("loud") else "false" loc_str += template.format(i, item[0], short_d, long_d, sound, loud) - loc_str = loc_str[:-1] # trim trailing newline + loc_str = loc_str[:-1] # trim trailing newline return loc_str + def get_objects(obj): template = """ {{ // {}: {} .words = {}, @@ -154,7 +164,7 @@ def get_objects(obj): descriptions_str += " " * 12 + make_c_string(l_msg) + ",\n" for label in attr.get("states", []): labels.append(label) - descriptions_str = descriptions_str[:-1] # trim trailing newline + descriptions_str = descriptions_str[:-1] # trim trailing newline if labels: global statedefines statedefines += "/* States for %s */\n" % item[0] @@ -168,21 +178,21 @@ def get_objects(obj): else: for l_msg in attr["sounds"]: sounds_str += " " * 12 + make_c_string(l_msg) + ",\n" - sounds_str = sounds_str[:-1] # trim trailing newline + sounds_str = sounds_str[:-1] # trim trailing newline texts_str = "" if attr.get("texts") is None: texts_str = " " * 12 + "NULL," else: for l_msg in attr["texts"]: texts_str += " " * 12 + make_c_string(l_msg) + ",\n" - texts_str = texts_str[:-1] # trim trailing newline + texts_str = texts_str[:-1] # trim trailing newline changes_str = "" if attr.get("changes") is None: changes_str = " " * 12 + "NULL," else: for l_msg in attr["changes"]: changes_str += " " * 12 + make_c_string(l_msg) + ",\n" - changes_str = changes_str[:-1] # trim trailing newline + changes_str = changes_str[:-1] # trim trailing newline locs = attr.get("locations", ["LOC_NOWHERE", "LOC_NOWHERE"]) immovable = attr.get("immovable", False) try: @@ -192,11 +202,24 @@ def get_objects(obj): sys.stderr.write("dungeon: unknown object location in %s\n" % locs) sys.exit(1) treasure = "true" if attr.get("treasure") else "false" - obj_str += template.format(i, item[0], words_str, i_msg, locs[0], locs[1], treasure, descriptions_str, sounds_str, texts_str, changes_str) - obj_str = obj_str[:-1] # trim trailing newline + obj_str += template.format( + i, + item[0], + words_str, + i_msg, + locs[0], + locs[1], + treasure, + descriptions_str, + sounds_str, + texts_str, + changes_str, + ) + obj_str = obj_str[:-1] # trim trailing newline statedefines += "/* Maximum state value */\n#define MAX_STATE %d\n" % max_state return obj_str + def get_obituaries(obit): template = """ {{ .query = {}, @@ -208,9 +231,10 @@ def get_obituaries(obit): query = make_c_string(o["query"]) yes = make_c_string(o["yes_response"]) obit_str += template.format(query, yes) - obit_str = obit_str[:-1] # trim trailing newline + obit_str = obit_str[:-1] # trim trailing newline return obit_str + def get_hints(hnt): template = """ {{ .number = {}, @@ -229,9 +253,10 @@ def get_hints(hnt): question = make_c_string(item["question"]) hint = make_c_string(item["hint"]) hnt_str += template.format(number, penalty, turns, question, hint) - hnt_str = hnt_str[:-1] # trim trailing newline + hnt_str = hnt_str[:-1] # trim trailing newline return hnt_str + def get_condbits(locations): cnd_str = "" for (name, loc) in locations: @@ -242,7 +267,7 @@ def get_condbits(locations): if conditions[flag]: flaglist.append(flag) line = "|".join([("(1<500 message N-500 from section 6 is printed, - # and he stays wherever he is. + # If N<=300 it is the location to go to. + # If 300500 message N-500 from section 6 is printed, + # and he stays wherever he is. # Meanwhile, M specifies the conditions on the motion. - # If M=0 it's unconditional. - # If 0 0: arc += ' [label="%s"]' % label print(" " + arc) diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index 2b4c515..e4ca88e 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -29,42 +29,45 @@ DEFAULT_HTML_OUTPUT_PATH = "../coverage/adventure.yaml.html" DANGLING_ACTIONS = ["ACT_VERSION"] DANGLING_MESSAGES = ["SAVERESUME_DISABLED"] -STDOUT_REPORT_CATEGORY = " {name:.<19}: {percent:5.1f}% covered ({covered} of {total})\n" +STDOUT_REPORT_CATEGORY = ( + " {name:.<19}: {percent:5.1f}% covered ({covered} of {total})\n" +) -HTML_SUMMARY_ROW = ''' +HTML_SUMMARY_ROW = """ {name}: {total} {covered} {percent:.1f}% -''' +""" -HTML_CATEGORY_SECTION = ''' +HTML_CATEGORY_SECTION = """ {rows}   -''' +""" -HTML_CATEGORY_HEADER = ''' +HTML_CATEGORY_HEADER = """ {label} {cells} -''' +""" HTML_CATEGORY_HEADER_CELL = '{}\n' HTML_CATEGORY_COVERAGE_CELL = ' \n' -HTML_CATEGORY_ROW = ''' +HTML_CATEGORY_ROW = """ {id} {cells} -''' +""" + def search(needle, haystack): # Search for needle in haystack, first escaping needle for regex, then @@ -75,16 +78,19 @@ def search(needle, haystack): # if needle is empty, assume we're going to find an empty string return True - needle_san = re.escape(needle) \ - .replace("\\n", "\n") \ - .replace("\\t", "\t") \ - .replace("%S", ".*") \ - .replace("%s", ".*") \ - .replace("%d", ".*") \ - .replace("%V", ".*") + needle_san = ( + re.escape(needle) + .replace("\\n", "\n") + .replace("\\t", "\t") + .replace("%S", ".*") + .replace("%s", ".*") + .replace("%d", ".*") + .replace("%V", ".*") + ) return re.search(needle_san, haystack) + def obj_coverage(objects, text, report): # objects have multiple descriptions based on state for _, objouter in enumerate(objects): @@ -93,19 +99,20 @@ def obj_coverage(objects, text, report): for j, desc in enumerate(obj["descriptions"]): name = "{}[{}]".format(obj_name, j) if name not in report["messages"]: - report["messages"][name] = {"covered" : False} + report["messages"][name] = {"covered": False} report["total"] += 1 if not report["messages"][name]["covered"] and search(desc, text): report["messages"][name]["covered"] = True report["covered"] += 1 + def loc_coverage(locations, text, report): # locations have a long and a short description, that each have to # be checked separately for name, loc in locations: desc = loc["description"] if name not in report["messages"]: - report["messages"][name] = {"long" : False, "short": False} + report["messages"][name] = {"long": False, "short": False} report["total"] += 2 if not report["messages"][name]["long"] and search(desc["long"], text): report["messages"][name]["long"] = True @@ -114,6 +121,7 @@ def loc_coverage(locations, text, report): report["messages"][name]["short"] = True report["covered"] += 1 + def hint_coverage(obituaries, text, report): # hints have a "question" where the hint is offered, followed # by the actual hint if the player requests it @@ -121,7 +129,7 @@ def hint_coverage(obituaries, text, report): hint = hintouter["hint"] name = hint["name"] if name not in report["messages"]: - report["messages"][name] = {"question" : False, "hint": False} + report["messages"][name] = {"question": False, "hint": False} report["total"] += 2 if not report["messages"][name]["question"] and search(hint["question"], text): report["messages"][name]["question"] = True @@ -130,50 +138,61 @@ def hint_coverage(obituaries, text, report): report["messages"][name]["hint"] = True report["covered"] += 1 + def obit_coverage(obituaries, text, report): # obituaries have a "query" where it asks the player for a resurrection, # followed by a snarky comment if the player says yes for name, obit in enumerate(obituaries): if name not in report["messages"]: - report["messages"][name] = {"query" : False, "yes_response": False} + report["messages"][name] = {"query": False, "yes_response": False} report["total"] += 2 if not report["messages"][name]["query"] and search(obit["query"], text): report["messages"][name]["query"] = True report["covered"] += 1 - if not report["messages"][name]["yes_response"] and search(obit["yes_response"], text): + if not report["messages"][name]["yes_response"] and search( + obit["yes_response"], text + ): report["messages"][name]["yes_response"] = True report["covered"] += 1 + def threshold_coverage(classes, text, report): # works for class thresholds and turn threshold, which have a "message" # property for name, item in enumerate(classes): if name not in report["messages"]: - report["messages"][name] = {"covered" : False} + report["messages"][name] = {"covered": False} report["total"] += 1 if not report["messages"][name]["covered"] and search(item["message"], text): report["messages"][name]["covered"] = True report["covered"] += 1 + def arb_coverage(arb_msgs, text, report): for name, message in arb_msgs: if name not in report["messages"]: - report["messages"][name] = {"covered" : False} + report["messages"][name] = {"covered": False} report["total"] += 1 - if not report["messages"][name]["covered"] and (search(message, text) or name in DANGLING_MESSAGES): + if not report["messages"][name]["covered"] and ( + search(message, text) or name in DANGLING_MESSAGES + ): report["messages"][name]["covered"] = True report["covered"] += 1 + def actions_coverage(items, text, report): # works for actions for name, item in items: if name not in report["messages"]: - report["messages"][name] = {"covered" : False} + report["messages"][name] = {"covered": False} report["total"] += 1 - if not report["messages"][name]["covered"] and (search(item["message"], text) or name in DANGLING_ACTIONS): + if not report["messages"][name]["covered"] and ( + search(item["message"], text) or name in DANGLING_ACTIONS + ): report["messages"][name]["covered"] = True report["covered"] += 1 + def coverage_report(db, check_file_contents): # Create report for each category, including total items, number of items # covered, and a list of the covered messages @@ -181,10 +200,10 @@ def coverage_report(db, check_file_contents): for name in db.keys(): # initialize each catagory report[name] = { - "name" : name, # convenience for string formatting - "total" : 0, - "covered" : 0, - "messages" : {} + "name": name, # convenience for string formatting + "total": 0, + "covered": 0, + "messages": {}, } # search for each message in every test check file @@ -200,20 +219,21 @@ def coverage_report(db, check_file_contents): return report + if __name__ == "__main__": # load DB try: - with open(YAML_PATH, "r", encoding='ascii', errors='surrogateescape') as f: + with open(YAML_PATH, "r", encoding="ascii", errors="surrogateescape") as f: db = yaml.safe_load(f) except IOError as e: - print('ERROR: could not load %s (%s)' % (YAML_PATH, e.strerror)) + print("ERROR: could not load %s (%s)" % (YAML_PATH, e.strerror)) sys.exit(-1) # get contents of all the check files check_file_contents = [] for filename in os.listdir(TEST_DIR): if filename.endswith(".chk"): - with open(filename, "r", encoding='ascii', errors='surrogateescape') as f: + with open(filename, "r", encoding="ascii", errors="surrogateescape") as f: check_file_contents.append(f.read()) # run coverage analysis report on dungeon database @@ -236,14 +256,20 @@ if __name__ == "__main__": colspan = 10 - len(cat_keys) for key in cat_keys: headers_html += HTML_CATEGORY_HEADER_CELL.format(key) - category_html = HTML_CATEGORY_HEADER.format(colspan=colspan, label=category["name"], cells=headers_html) + category_html = HTML_CATEGORY_HEADER.format( + colspan=colspan, label=category["name"], cells=headers_html + ) # render message coverage row for message_id, covered in cat_messages: category_html_row = "" for key, value in covered.items(): - category_html_row += HTML_CATEGORY_COVERAGE_CELL.format("uncovered" if not value else "covered") - category_html += HTML_CATEGORY_ROW.format(id=message_id,colspan=colspan, cells=category_html_row) + category_html_row += HTML_CATEGORY_COVERAGE_CELL.format( + "uncovered" if not value else "covered" + ) + category_html += HTML_CATEGORY_ROW.format( + id=message_id, colspan=colspan, cells=category_html_row + ) categories_html += HTML_CATEGORY_SECTION.format(id=name, rows=category_html) # render category summaries @@ -260,16 +286,22 @@ if __name__ == "__main__": # render HTML report try: - with open(HTML_TEMPLATE_PATH, "r", encoding='ascii', errors='surrogateescape') as f: + with open( + HTML_TEMPLATE_PATH, "r", encoding="ascii", errors="surrogateescape" + ) as f: # read in HTML template html_template = f.read() except IOError as e: - print('ERROR: reading HTML report template failed ({})'.format(e.strerror)) + print("ERROR: reading HTML report template failed ({})".format(e.strerror)) sys.exit(-1) # parse template with report and write it out try: - with open(html_output_path, "w", encoding='ascii', errors='surrogateescape') as f: - f.write(html_template.format(categories=categories_html, summary=summary_html)) + with open( + html_output_path, "w", encoding="ascii", errors="surrogateescape" + ) as f: + f.write( + html_template.format(categories=categories_html, summary=summary_html) + ) except IOError as e: - print('ERROR: writing HTML report failed ({})'.format(e.strerror)) + print("ERROR: writing HTML report failed ({})".format(e.strerror)) From 50169781566c00f035020557d96255a7ac5a0904 Mon Sep 17 00:00:00 2001 From: Nicola Smaniotto Date: Mon, 27 Nov 2023 17:41:26 +0100 Subject: [PATCH 147/213] saveresume.c: add missing semicolon Fixes compilation when ADVENT_NOSAVE is set --- saveresume.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saveresume.c b/saveresume.c index 70b9461..a2c10a0 100644 --- a/saveresume.c +++ b/saveresume.c @@ -137,7 +137,7 @@ int restore(FILE* fp) * sane initial state. * If ADVENT_NOSAVE is defined, gripe instead. */ #ifdef ADVENT_NOSAVE - rspeak(SAVERESUME_DISABLED) + rspeak(SAVERESUME_DISABLED); return GO_TOP; #endif From 9fbd603f8dd345fe0d4eb50f75e750a6f47bd645 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 09:28:39 -0500 Subject: [PATCH 148/213] Typo fix. --- make_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make_graph.py b/make_graph.py index cd786ed..e5154ca 100755 --- a/make_graph.py +++ b/make_graph.py @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """\ -usage: make_graph.py [-a] -d] [-m] [-s] [-v] +usage: make_graph.py [-a] [-d] [-m] [-s] [-v] Make a DOT graph of Colossal Cave. From 2582e240bd504307b206a384008adb4dd545eb19 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 09:46:09 -0500 Subject: [PATCH 149/213] Fix defective copyright notices. --- Dockerfile.ci | 2 +- INSTALL.adoc | 2 +- Makefile | 2 +- NEWS.adoc | 2 +- README.adoc | 2 +- advent.adoc | 2 +- advent.desktop | 2 +- adventure.yaml | 2 +- hints.adoc | 2 +- history.adoc | 2 +- make_dungeon.py | 2 +- make_graph.py | 2 +- notes.adoc | 2 +- templates/coverage_dungeon.html.tpl | 2 +- templates/dungeon.c.tpl | 2 +- templates/dungeon.h.tpl | 2 +- tests/Makefile | 2 +- tests/axebear.log | 2 +- tests/axeorama.log | 2 +- tests/badmagic.log | 2 +- tests/barehands.log | 2 +- tests/bigfail.log | 2 +- tests/birdsnakewake.log | 2 +- tests/birdweight.log | 2 +- tests/boulder2.log | 2 +- tests/breakmirror.log | 2 +- tests/carrybird.log | 2 +- tests/carryfreebird.log | 2 +- tests/cheatresume.log | 2 +- tests/cheatresume2.log | 2 +- tests/coverage_dungeon.py | 2 +- tests/death-jump.log | 2 +- tests/defeat.log | 2 +- tests/domefail.log | 2 +- tests/dragon_secret5.log | 2 +- tests/dropcagedbird.log | 2 +- tests/drown.log | 2 +- tests/dwarf.log | 2 +- tests/dwarf_alternative.log | 2 +- tests/eggs_done.log | 2 +- tests/eggs_vanish.log | 2 +- tests/endgame428.log | 2 +- tests/endobjects.log | 2 +- tests/fail_hint_maze.log | 2 +- tests/fail_hint_ogre.log | 2 +- tests/fail_hint_ogre2.log | 2 +- tests/fail_hint_woods.log | 2 +- tests/fillfail.log | 2 +- tests/fillvase.log | 2 +- tests/flyback.log | 2 +- tests/footslip.log | 2 +- tests/gemstates.log | 2 +- tests/goback.log | 2 +- tests/hint_dark.log | 2 +- tests/hint_grate.log | 2 +- tests/hint_jade.log | 2 +- tests/hint_snake.log | 2 +- tests/hint_urn.log | 2 +- tests/hint_witt.log | 2 +- tests/illformed.log | 2 +- tests/illformed2.log | 2 +- tests/intransitivecarry.log | 2 +- tests/issue36.log | 2 +- tests/issue37.log | 2 +- tests/lampdim.log | 2 +- tests/lampdim2.log | 2 +- tests/lampdim3.log | 2 +- tests/listen.log | 2 +- tests/listenloud.log | 2 +- tests/lockchain.log | 2 +- tests/logopt.log | 2 +- tests/magicwords.log | 2 +- tests/mazealldiff.log | 2 +- tests/mazehint.log | 2 +- tests/multifile.chk | 2 +- tests/notrident.log | 2 +- tests/ogre_no_dwarves.log | 2 +- tests/ogrehint.log | 2 +- tests/oilplant.log | 2 +- tests/oldstyle.log | 2 +- tests/outcheck.sh | 2 +- tests/oysterbug.log | 2 +- tests/panic.log | 2 +- tests/panic2.log | 2 +- tests/pirate_carry.log | 2 +- tests/pirate_pyramid.log | 2 +- tests/pirate_spotted.log | 2 +- tests/pitfall.log | 2 +- tests/plover.log | 2 +- tests/reach_ledge_short.log | 2 +- tests/reach_noclimb.log | 2 +- tests/reach_planttop.log | 2 +- tests/reincarnate.log | 2 +- tests/resumefail.log | 2 +- tests/resumefail2.log | 2 +- tests/savefail.log | 2 +- tests/saveresume.1.log | 2 +- tests/saveresume.2.log | 2 +- tests/saveresume.3.log | 2 +- tests/saveresume.4.log | 2 +- tests/saveresumeopt.log | 2 +- tests/savetamper.log | 2 +- tests/snake_food.log | 2 +- tests/softroom.log | 2 +- tests/specials.log | 2 +- tests/splatter.log | 2 +- tests/stashed.log | 2 +- tests/takebird.log | 2 +- tests/tall.log | 2 +- tests/tapdiffer | 2 +- tests/tapview | 2 +- tests/trident.log | 2 +- tests/troll_returns.log | 2 +- tests/turnpenalties.log | 2 +- tests/urntest.log | 2 +- tests/urntest2.log | 2 +- tests/urntest3.log | 2 +- tests/vending.log | 2 +- tests/wakedwarves.log | 2 +- tests/wakedwarves2.log | 2 +- tests/wakedwarves3.log | 2 +- tests/water_plant2.log | 2 +- tests/weirdbird.log | 2 +- tests/weirddwarf.log | 2 +- tests/win430.log | 2 +- tests/wittsend.log | 2 +- tests/woodshint.log | 2 +- 127 files changed, 127 insertions(+), 127 deletions(-) diff --git a/Dockerfile.ci b/Dockerfile.ci index e67cd1f..c8f29a1 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,6 +1,6 @@ # This image is built by the Gitlab CI pipeline to be used in subsequent # pipeline steps. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause FROM ubuntu diff --git a/INSTALL.adoc b/INSTALL.adoc index f61783c..b6f5b4b 100644 --- a/INSTALL.adoc +++ b/INSTALL.adoc @@ -1,5 +1,5 @@ = Installing Open Adventure = -// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 Installation now requires Python3 due to a security issue diff --git a/Makefile b/Makefile index fa18e6f..dfd3ff2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Makefile for the open-source release of adventure 2.5 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # To build with save/resume disabled, pass CFLAGS="-DADVENT_NOSAVE" diff --git a/NEWS.adoc b/NEWS.adoc index 54774fe..7e4e88a 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -1,5 +1,5 @@ = Open Adventure project news = -// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 1.16: 2023-04-15:: diff --git a/README.adoc b/README.adoc index 573bf7a..ba67510 100644 --- a/README.adoc +++ b/README.adoc @@ -1,5 +1,5 @@ = README for Open Adventure = -// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 If you are reading this anywhere but at http://www.catb.org/~esr/open-adventure diff --git a/advent.adoc b/advent.adoc index db55ab2..f48df70 100644 --- a/advent.adoc +++ b/advent.adoc @@ -1,6 +1,6 @@ = advent(6) = :doctype: manpage -// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 == NAME == diff --git a/advent.desktop b/advent.desktop index fdc2f26..3fe5420 100644 --- a/advent.desktop +++ b/advent.desktop @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause [Desktop Entry] Type=Application diff --git a/adventure.yaml b/adventure.yaml index 35c541d..3c0e566 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # This YAML file gets processed into a collection of data structures and diff --git a/hints.adoc b/hints.adoc index c77afee..c22c11b 100644 --- a/hints.adoc +++ b/hints.adoc @@ -1,5 +1,5 @@ = Non-spoiler hints = -// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 Say the words you see. They can have interesting effects. diff --git a/history.adoc b/history.adoc index 1e4028c..5384c2c 100644 --- a/history.adoc +++ b/history.adoc @@ -1,6 +1,6 @@ = A brief history of Colossal Cave Adventure = by Eric S. Raymond -// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 Adventure is the fons et origo of all later dungeon-crawling computer diff --git a/make_dungeon.py b/make_dungeon.py index 12f39e7..8ab149e 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """ This is the open-adventure dungeon generator. It consumes a YAML description of diff --git a/make_graph.py b/make_graph.py index e5154ca..779572a 100755 --- a/make_graph.py +++ b/make_graph.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """\ usage: make_graph.py [-a] [-d] [-m] [-s] [-v] diff --git a/notes.adoc b/notes.adoc index b9ce8b1..d1d3c4c 100644 --- a/notes.adoc +++ b/notes.adoc @@ -1,6 +1,6 @@ = Open Adventure Maintainer's Notes = by Eric S. Raymond -// SPDX-FileCopyrightText: Eric S. Raymond +// SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 In which we explain what has been done to this code since Don Woods diff --git a/templates/coverage_dungeon.html.tpl b/templates/coverage_dungeon.html.tpl index 164473e..e9f7f74 100644 --- a/templates/coverage_dungeon.html.tpl +++ b/templates/coverage_dungeon.html.tpl @@ -1,5 +1,5 @@ <-- -SPDX-FileCopyrightText: Eric S. Raymond +SPDX-FileCopyrightText: Copyright Eric S. Raymond SPDX-License-Identifier: BSD-2-Clause --> diff --git a/templates/dungeon.c.tpl b/templates/dungeon.c.tpl index d1604a5..4a7011a 100644 --- a/templates/dungeon.c.tpl +++ b/templates/dungeon.c.tpl @@ -1,5 +1,5 @@ /* -SPDX-FileCopyrightText: Eric S. Raymond +SPDX-FileCopyrightText: Copyright Eric S. Raymond SPDX-License-Identifier: BSD-2-Clause */ diff --git a/templates/dungeon.h.tpl b/templates/dungeon.h.tpl index ab3d6d7..0a9c1c5 100644 --- a/templates/dungeon.h.tpl +++ b/templates/dungeon.h.tpl @@ -1,5 +1,5 @@ /* -SPDX-FileCopyrightText: Eric S. Raymond +SPDX-FileCopyrightText: Copyright Eric S. Raymond SPDX-License-Identifier: BSD-2-Clause */ #ifndef DUNGEON_H diff --git a/tests/Makefile b/tests/Makefile index 66280f4..427137b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,6 @@ # Test-suite makefile for open-adventure -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Use absolute path so tests that change working directory still use diff --git a/tests/axebear.log b/tests/axebear.log index 27c0af5..1788008 100644 --- a/tests/axebear.log +++ b/tests/axebear.log @@ -1,5 +1,5 @@ ## Observe axe after throwing at bear -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/axeorama.log b/tests/axeorama.log index fd10948..a6def76 100644 --- a/tests/axeorama.log +++ b/tests/axeorama.log @@ -1,5 +1,5 @@ ## Test throwing axe at non-dwarves. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Added coverage of LOC_DEADCRAWL and CROSS_BRIDGE n diff --git a/tests/badmagic.log b/tests/badmagic.log index 4ee9f10..6a1f056 100644 --- a/tests/badmagic.log +++ b/tests/badmagic.log @@ -1,5 +1,5 @@ ## Resume from filename withoy the right magic at the front -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE advent430 doesn't have this test n diff --git a/tests/barehands.log b/tests/barehands.log index 1ad2c32..cb5ad99 100644 --- a/tests/barehands.log +++ b/tests/barehands.log @@ -1,5 +1,5 @@ ## Get to dragon, refuse to use bare hands -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Fails due uninteresting difference in whitespace process. # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 diff --git a/tests/bigfail.log b/tests/bigfail.log index ae13163..8de6118 100644 --- a/tests/bigfail.log +++ b/tests/bigfail.log @@ -1,5 +1,5 @@ ## Test many nonlethal failure conditions -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # See comments in this log n diff --git a/tests/birdsnakewake.log b/tests/birdsnakewake.log index 8c2d514..ef1a6d5 100644 --- a/tests/birdsnakewake.log +++ b/tests/birdsnakewake.log @@ -1,5 +1,5 @@ ## Attempt to kill snake with bird in the endgame -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/birdweight.log b/tests/birdweight.log index 216979b..5cfe3db 100644 --- a/tests/birdweight.log +++ b/tests/birdweight.log @@ -1,5 +1,5 @@ ## Verify that the bird is weightless in inventory -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Checks fix for GitLab issue #40 #NOCOMPARE Bird was not weightless in cage in advent430 so this test is invalid. diff --git a/tests/boulder2.log b/tests/boulder2.log index 886e0b9..dbaaf81 100644 --- a/tests/boulder2.log +++ b/tests/boulder2.log @@ -1,5 +1,5 @@ ## Coverage of LOC_BOULDERS2.short -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/breakmirror.log b/tests/breakmirror.log index ba73337..7cd9dcc 100644 --- a/tests/breakmirror.log +++ b/tests/breakmirror.log @@ -1,5 +1,5 @@ ## Break the mirror in endgame and die -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/carrybird.log b/tests/carrybird.log index 296a825..d661145 100644 --- a/tests/carrybird.log +++ b/tests/carrybird.log @@ -1,5 +1,5 @@ ## Try to carry bird without cage, then kill bird -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 diff --git a/tests/carryfreebird.log b/tests/carryfreebird.log index 4867b05..e0482f2 100644 --- a/tests/carryfreebird.log +++ b/tests/carryfreebird.log @@ -1,5 +1,5 @@ ## Try to carry the bird after freeing it instead of listening -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 diff --git a/tests/cheatresume.log b/tests/cheatresume.log index 1a0e60e..5440c4f 100644 --- a/tests/cheatresume.log +++ b/tests/cheatresume.log @@ -1,5 +1,5 @@ ## Resume from absurd save file with numdie = -900 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/cheatresume2.log b/tests/cheatresume2.log index d5d8eee..b479726 100644 --- a/tests/cheatresume2.log +++ b/tests/cheatresume2.log @@ -1,5 +1,5 @@ ## Resume from absurd save file with numdie = -1000 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # generating "off my scale" score threshold message #NOCOMPARE Can't compare to advent430 due to version skew diff --git a/tests/coverage_dungeon.py b/tests/coverage_dungeon.py index e4ca88e..d193b27 100755 --- a/tests/coverage_dungeon.py +++ b/tests/coverage_dungeon.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """ This is the open-adventure dungeon text coverage report generator. It diff --git a/tests/death-jump.log b/tests/death-jump.log index 835c02c..91e63f9 100644 --- a/tests/death-jump.log +++ b/tests/death-jump.log @@ -1,5 +1,5 @@ ## Jump into a pit and die, refuse reincarnation -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 diff --git a/tests/defeat.log b/tests/defeat.log index b46767d..f3d6b08 100644 --- a/tests/defeat.log +++ b/tests/defeat.log @@ -1,5 +1,5 @@ ## Last-minute defeat, with lava. Also tests vase drop before pillow. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/domefail.log b/tests/domefail.log index c832fb0..d75352e 100644 --- a/tests/domefail.log +++ b/tests/domefail.log @@ -1,5 +1,5 @@ ## Take nugget and fail to climb to the dome -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/dragon_secret5.log b/tests/dragon_secret5.log index a630ccc..61f01ac 100644 --- a/tests/dragon_secret5.log +++ b/tests/dragon_secret5.log @@ -1,5 +1,5 @@ ## Check that dead dragon actually moves its location (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 18084731 diff --git a/tests/dropcagedbird.log b/tests/dropcagedbird.log index 2ca0c99..d069f1a 100644 --- a/tests/dropcagedbird.log +++ b/tests/dropcagedbird.log @@ -1,5 +1,5 @@ ## Try to carry the bird after freeing it instead of listening -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 diff --git a/tests/drown.log b/tests/drown.log index 257aeea..75e89ba 100644 --- a/tests/drown.log +++ b/tests/drown.log @@ -1,5 +1,5 @@ ## Speak a magic word at an inopportune time and drown. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/dwarf.log b/tests/dwarf.log index 36a225b..7954a62 100644 --- a/tests/dwarf.log +++ b/tests/dwarf.log @@ -1,5 +1,5 @@ ## In which the dwarf kills you -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1494912171 diff --git a/tests/dwarf_alternative.log b/tests/dwarf_alternative.log index af0a9c8..ef0a881 100644 --- a/tests/dwarf_alternative.log +++ b/tests/dwarf_alternative.log @@ -1,5 +1,5 @@ ## Check that dwarf spawns in alternative location (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 383847 diff --git a/tests/eggs_done.log b/tests/eggs_done.log index 451d3e5..829c292 100644 --- a/tests/eggs_done.log +++ b/tests/eggs_done.log @@ -1,5 +1,5 @@ ## Be done with Giant Room and eggs (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/eggs_vanish.log b/tests/eggs_vanish.log index 7c5f406..3e9c799 100644 --- a/tests/eggs_vanish.log +++ b/tests/eggs_vanish.log @@ -1,5 +1,5 @@ ## Vanishing eggs in Giant Room (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/endgame428.log b/tests/endgame428.log index e86c92d..9556677 100644 --- a/tests/endgame428.log +++ b/tests/endgame428.log @@ -1,5 +1,5 @@ ## 428-point walkthrough -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/endobjects.log b/tests/endobjects.log index 1165360..978d457 100644 --- a/tests/endobjects.log +++ b/tests/endobjects.log @@ -1,5 +1,5 @@ ### Check that water is unavailable in endgame -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Addresses GitLab issue #55: in endgame, some object starting states are incorrect #NOCOMPARE Bird was not weightless in cage in advent430, this test depends on that. diff --git a/tests/fail_hint_maze.log b/tests/fail_hint_maze.log index 409286c..982d44b 100644 --- a/tests/fail_hint_maze.log +++ b/tests/fail_hint_maze.log @@ -1,5 +1,5 @@ ## Fail to get maze hint by being empty-handed (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 25508795 diff --git a/tests/fail_hint_ogre.log b/tests/fail_hint_ogre.log index 01af475..3df4697 100644 --- a/tests/fail_hint_ogre.log +++ b/tests/fail_hint_ogre.log @@ -1,5 +1,5 @@ ## Qualify for ogre hint but fail due to dwarves dead (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Fails due uninteresting difference in whitespace process. n diff --git a/tests/fail_hint_ogre2.log b/tests/fail_hint_ogre2.log index 9b01049..6e37f8e 100644 --- a/tests/fail_hint_ogre2.log +++ b/tests/fail_hint_ogre2.log @@ -1,5 +1,5 @@ ## Qualify for ogre hint but fail due to nearby dwarf (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 25508795 diff --git a/tests/fail_hint_woods.log b/tests/fail_hint_woods.log index 69d075e..21694b5 100644 --- a/tests/fail_hint_woods.log +++ b/tests/fail_hint_woods.log @@ -1,5 +1,5 @@ ## Fail getting wood hint by finding appendage (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n n diff --git a/tests/fillfail.log b/tests/fillfail.log index 543bc27..1a9e12b 100644 --- a/tests/fillfail.log +++ b/tests/fillfail.log @@ -1,5 +1,5 @@ ## Attempt to fill lamp, attempt to fill bottle with no source -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n in diff --git a/tests/fillvase.log b/tests/fillvase.log index da776b9..2f9c76c 100644 --- a/tests/fillvase.log +++ b/tests/fillvase.log @@ -1,5 +1,5 @@ ## Fill the vase -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Arthur O'Dwyer writes: # diff --git a/tests/flyback.log b/tests/flyback.log index 3c34df4..18c380c 100644 --- a/tests/flyback.log +++ b/tests/flyback.log @@ -1,5 +1,5 @@ ## Test fix for issue 51: rug flying is broken -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a bug fix. n diff --git a/tests/footslip.log b/tests/footslip.log index 4f1d7cd..8b9edf2 100644 --- a/tests/footslip.log +++ b/tests/footslip.log @@ -1,5 +1,5 @@ ## Coverage of LOC_FOOTSLIP -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/gemstates.log b/tests/gemstates.log index 6ac1547..a07d86f 100644 --- a/tests/gemstates.log +++ b/tests/gemstates.log @@ -1,5 +1,5 @@ ## Observe amber, ruby, sapphire after state change -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 diff --git a/tests/goback.log b/tests/goback.log index fcc06c2..83199f5 100644 --- a/tests/goback.log +++ b/tests/goback.log @@ -1,5 +1,5 @@ ## Test many nonlethal failure conditions -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # This variant elicits the prompt to go back for batteries # See comments in this log diff --git a/tests/hint_dark.log b/tests/hint_dark.log index a45074a..78a3c79 100644 --- a/tests/hint_dark.log +++ b/tests/hint_dark.log @@ -1,5 +1,5 @@ ## Elicit hint for dealing with plugh room and darkness (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495951709 diff --git a/tests/hint_grate.log b/tests/hint_grate.log index 8af49de..634caf3 100644 --- a/tests/hint_grate.log +++ b/tests/hint_grate.log @@ -1,5 +1,5 @@ ## Elicit hint for dealing with grate -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 diff --git a/tests/hint_jade.log b/tests/hint_jade.log index 904aa92..d220260 100644 --- a/tests/hint_jade.log +++ b/tests/hint_jade.log @@ -1,5 +1,5 @@ ## Elicit hint for getting the jade (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/hint_snake.log b/tests/hint_snake.log index 76b719b..710c5e3 100644 --- a/tests/hint_snake.log +++ b/tests/hint_snake.log @@ -1,5 +1,5 @@ ## Elicit hint for dealing with snake -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 diff --git a/tests/hint_urn.log b/tests/hint_urn.log index d12ceda..b1f3d3a 100644 --- a/tests/hint_urn.log +++ b/tests/hint_urn.log @@ -1,5 +1,5 @@ ## Elicit hint for dealing with urn (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Policy decision - no point in emulating advent430's extra \n here n diff --git a/tests/hint_witt.log b/tests/hint_witt.log index 07e0785..f97a906 100644 --- a/tests/hint_witt.log +++ b/tests/hint_witt.log @@ -1,5 +1,5 @@ ## Hint for Witt's End -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Policy decision - no point in emulating advent430's extra \n here n diff --git a/tests/illformed.log b/tests/illformed.log index 0cb22e0..1e31a41 100644 --- a/tests/illformed.log +++ b/tests/illformed.log @@ -1,5 +1,5 @@ ## Test for various cases not found in walkthroughs. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE This is busted under advent430 -- see comments within. foo diff --git a/tests/illformed2.log b/tests/illformed2.log index f6193d7..b1e722a 100644 --- a/tests/illformed2.log +++ b/tests/illformed2.log @@ -1,5 +1,5 @@ ## Test for various cases not found in walkthroughs (advent430-compatible). -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Commented-out lines cause troble in advent430 n diff --git a/tests/intransitivecarry.log b/tests/intransitivecarry.log index acef62e..f6a7bfa 100644 --- a/tests/intransitivecarry.log +++ b/tests/intransitivecarry.log @@ -1,5 +1,5 @@ ## Carry when only one object is present -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n in diff --git a/tests/issue36.log b/tests/issue36.log index fa8ef7f..279b7f3 100644 --- a/tests/issue36.log +++ b/tests/issue36.log @@ -1,5 +1,5 @@ ## Test handling of object after transitive verb. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 826186526 diff --git a/tests/issue37.log b/tests/issue37.log index 14afe5e..b796aa6 100644 --- a/tests/issue37.log +++ b/tests/issue37.log @@ -1,5 +1,5 @@ ## Test handling of transitive verb after noun -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n in diff --git a/tests/lampdim.log b/tests/lampdim.log index 514b6a2..5042356 100644 --- a/tests/lampdim.log +++ b/tests/lampdim.log @@ -1,5 +1,5 @@ ## Test the case where your lamp goes dim -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/lampdim2.log b/tests/lampdim2.log index 3afe71c..0f33787 100644 --- a/tests/lampdim2.log +++ b/tests/lampdim2.log @@ -1,5 +1,5 @@ ## Try (and fail) to carry message at vending machine -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/lampdim3.log b/tests/lampdim3.log index e944d4e..e7b1b44 100644 --- a/tests/lampdim3.log +++ b/tests/lampdim3.log @@ -1,5 +1,5 @@ ## Die while closing -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/listen.log b/tests/listen.log index 6aa7b97..b29570c 100644 --- a/tests/listen.log +++ b/tests/listen.log @@ -1,5 +1,5 @@ ## Check that listen command hears all objects as well as location sound -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause no seed 1181530211 diff --git a/tests/listenloud.log b/tests/listenloud.log index f0c62fe..6d5ce61 100644 --- a/tests/listenloud.log +++ b/tests/listenloud.log @@ -1,5 +1,5 @@ ## Attempt to listen at a loud location -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/lockchain.log b/tests/lockchain.log index f311485..78ae677 100644 --- a/tests/lockchain.log +++ b/tests/lockchain.log @@ -1,5 +1,5 @@ ## Test multiple re-locking and unlocking of bear's chain -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/logopt.log b/tests/logopt.log index ee4a860..3ba2fb5 100644 --- a/tests/logopt.log +++ b/tests/logopt.log @@ -1,5 +1,5 @@ ## Exercise logging option and seed dump -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #options: -l scratch.tmp n diff --git a/tests/magicwords.log b/tests/magicwords.log index 5e7f39a..02ed3aa 100644 --- a/tests/magicwords.log +++ b/tests/magicwords.log @@ -1,5 +1,5 @@ ## Test processing of various fee fie foe foo fum cases. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # How they're supposed to work: diff --git a/tests/mazealldiff.log b/tests/mazealldiff.log index 2da3152..72f142b 100644 --- a/tests/mazealldiff.log +++ b/tests/mazealldiff.log @@ -1,5 +1,5 @@ ## Coverage of all LOC_DIFFERENT* -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/mazehint.log b/tests/mazehint.log index 83ae210..8cf1ddb 100644 --- a/tests/mazehint.log +++ b/tests/mazehint.log @@ -1,5 +1,5 @@ ## Elicit the maze hint. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 diff --git a/tests/multifile.chk b/tests/multifile.chk index 991ea9c..22bc511 100644 --- a/tests/multifile.chk +++ b/tests/multifile.chk @@ -2,7 +2,7 @@ Welcome to Adventure!! Would you like instructions? > ## Test handling of object after transitive verb. -> # SPDX-FileCopyrightText: Eric S. Raymond +> # SPDX-FileCopyrightText: Copyright Eric S. Raymond > # SPDX-License-Identifier: BSD-2-Clause > n > n diff --git a/tests/notrident.log b/tests/notrident.log index 8e649cb..1faab2d 100644 --- a/tests/notrident.log +++ b/tests/notrident.log @@ -1,5 +1,5 @@ ## Try to open clam without trident and fail -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 diff --git a/tests/ogre_no_dwarves.log b/tests/ogre_no_dwarves.log index 3ba7102..4326320 100644 --- a/tests/ogre_no_dwarves.log +++ b/tests/ogre_no_dwarves.log @@ -1,5 +1,5 @@ ## Try to attack ogre with no dwarves present (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 25508795 diff --git a/tests/ogrehint.log b/tests/ogrehint.log index 58a8abf..38e423d 100644 --- a/tests/ogrehint.log +++ b/tests/ogrehint.log @@ -1,5 +1,5 @@ ## Elicit the ogre hint. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 437547289 diff --git a/tests/oilplant.log b/tests/oilplant.log index 3174357..1b3bf85 100644 --- a/tests/oilplant.log +++ b/tests/oilplant.log @@ -1,5 +1,5 @@ ## Attempt to oil the beanstalk after watering it -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/oldstyle.log b/tests/oldstyle.log index a259abd..05b7c8a 100644 --- a/tests/oldstyle.log +++ b/tests/oldstyle.log @@ -1,5 +1,5 @@ ## Simple quit -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #options: -o #NOCOMPARE Comment not interpreted by advent430 diff --git a/tests/outcheck.sh b/tests/outcheck.sh index 4dc5b0d..91901a5 100755 --- a/tests/outcheck.sh +++ b/tests/outcheck.sh @@ -1,5 +1,5 @@ #! /bin/sh -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause case $? in 0) echo "ok - $1 succeeded";; diff --git a/tests/oysterbug.log b/tests/oysterbug.log index 0337967..3b31c7e 100644 --- a/tests/oysterbug.log +++ b/tests/oysterbug.log @@ -1,5 +1,5 @@ ## Demonstrate fix of buggy response to unlocking oyster while carrying it. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE This fails due to a known bug in advent430 n diff --git a/tests/panic.log b/tests/panic.log index 155669e..248fb72 100644 --- a/tests/panic.log +++ b/tests/panic.log @@ -1,5 +1,5 @@ ## Panic test - attempt to unlock grate after game closed. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/panic2.log b/tests/panic2.log index 1f70a46..ae05f60 100644 --- a/tests/panic2.log +++ b/tests/panic2.log @@ -1,5 +1,5 @@ ## Panic test - attempt to xyzzy out after game is closed. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/pirate_carry.log b/tests/pirate_carry.log index 733d03f..2f7598e 100644 --- a/tests/pirate_carry.log +++ b/tests/pirate_carry.log @@ -1,5 +1,5 @@ ## Check that pirate steals loose treasure from ground (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1837473132 diff --git a/tests/pirate_pyramid.log b/tests/pirate_pyramid.log index 83f7a6d..b5cbe49 100644 --- a/tests/pirate_pyramid.log +++ b/tests/pirate_pyramid.log @@ -1,5 +1,5 @@ ## Pirate mustn't take pyramid from plover/dark rooms (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1830473132 diff --git a/tests/pirate_spotted.log b/tests/pirate_spotted.log index a0ed6f5..f998cdd 100644 --- a/tests/pirate_spotted.log +++ b/tests/pirate_spotted.log @@ -1,5 +1,5 @@ ## Spot pirate to manifest chest before last treasure (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/pitfall.log b/tests/pitfall.log index cd16da9..1582283 100644 --- a/tests/pitfall.log +++ b/tests/pitfall.log @@ -1,5 +1,5 @@ ## Death by pitfall -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Die 3 times so we can cover all the obituary messages n diff --git a/tests/plover.log b/tests/plover.log index 47d3ec8..0d1b5a5 100644 --- a/tests/plover.log +++ b/tests/plover.log @@ -1,5 +1,5 @@ ## Test access to emerald room and plover teleport -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/reach_ledge_short.log b/tests/reach_ledge_short.log index f53f98d..4890a42 100644 --- a/tests/reach_ledge_short.log +++ b/tests/reach_ledge_short.log @@ -1,5 +1,5 @@ ## LOC_NOCLIMB.short (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/reach_noclimb.log b/tests/reach_noclimb.log index f3670e6..ebf8ae3 100644 --- a/tests/reach_noclimb.log +++ b/tests/reach_noclimb.log @@ -1,5 +1,5 @@ ## LOC_NOCLIMB (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/reach_planttop.log b/tests/reach_planttop.log index 851c55a..e85f908 100644 --- a/tests/reach_planttop.log +++ b/tests/reach_planttop.log @@ -1,5 +1,5 @@ ## LOC_PLANTTOP (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/reincarnate.log b/tests/reincarnate.log index 550be2f..bdf93c4 100644 --- a/tests/reincarnate.log +++ b/tests/reincarnate.log @@ -1,5 +1,5 @@ ## Jump into a pit and die, then be reincarnated -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1495774850 diff --git a/tests/resumefail.log b/tests/resumefail.log index 6ca8d49..c86b323 100644 --- a/tests/resumefail.log +++ b/tests/resumefail.log @@ -1,5 +1,5 @@ ## Resume from invalid filename -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE advent430 crashes on resume from invalid filename and we don't care. n diff --git a/tests/resumefail2.log b/tests/resumefail2.log index 30b3e20..8a466d5 100644 --- a/tests/resumefail2.log +++ b/tests/resumefail2.log @@ -1,5 +1,5 @@ ## Resume from generated save with version mismatch error -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Reveals a bug in advent430 handling of saves with invalid versions. n diff --git a/tests/savefail.log b/tests/savefail.log index d5c5b6e..8e5fe6a 100644 --- a/tests/savefail.log +++ b/tests/savefail.log @@ -1,5 +1,5 @@ ## Save right after starting to invalid filename -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE advent430 crashes on save to invalid filename and we don't care. n diff --git a/tests/saveresume.1.log b/tests/saveresume.1.log index aa74e77..c5def6a 100644 --- a/tests/saveresume.1.log +++ b/tests/saveresume.1.log @@ -1,5 +1,5 @@ ## Save right after starting -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/saveresume.2.log b/tests/saveresume.2.log index bda1a1e..9995b96 100644 --- a/tests/saveresume.2.log +++ b/tests/saveresume.2.log @@ -1,5 +1,5 @@ ## Resume and then quit -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/saveresume.3.log b/tests/saveresume.3.log index 7777da0..aaffab4 100644 --- a/tests/saveresume.3.log +++ b/tests/saveresume.3.log @@ -1,5 +1,5 @@ ## Almost win, then save -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 #NOCOMPARE Seems to reveal a bug in advent430's save function. diff --git a/tests/saveresume.4.log b/tests/saveresume.4.log index 1009ea7..5accd34 100644 --- a/tests/saveresume.4.log +++ b/tests/saveresume.4.log @@ -1,5 +1,5 @@ ## Resume, then win -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Here to get class threshold of 426 # Note, savefile name has trailing space diff --git a/tests/saveresumeopt.log b/tests/saveresumeopt.log index e52593d..d1889d1 100644 --- a/tests/saveresumeopt.log +++ b/tests/saveresumeopt.log @@ -1,5 +1,5 @@ ## Simple quit -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE New feature, -r option #options: -r saveresume.adv diff --git a/tests/savetamper.log b/tests/savetamper.log index 6662443..62a28f9 100644 --- a/tests/savetamper.log +++ b/tests/savetamper.log @@ -1,5 +1,5 @@ ## Resume from artificial "corrupted" save -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Can't compare to advent430 due to version skew n diff --git a/tests/snake_food.log b/tests/snake_food.log index 843fa0e..7717f39 100644 --- a/tests/snake_food.log +++ b/tests/snake_food.log @@ -1,5 +1,5 @@ ## Snake must vocally eat bird -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 diff --git a/tests/softroom.log b/tests/softroom.log index 9bb6185..113001a 100644 --- a/tests/softroom.log +++ b/tests/softroom.log @@ -1,5 +1,5 @@ ## Drop vase in soft room after pillow removed -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Verify that the vase does not break n diff --git a/tests/specials.log b/tests/specials.log index 7900a6c..aad0a63 100644 --- a/tests/specials.log +++ b/tests/specials.log @@ -1,5 +1,5 @@ ## Test special words -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE The news text has changed n diff --git a/tests/splatter.log b/tests/splatter.log index 76df98e..13a0eb5 100644 --- a/tests/splatter.log +++ b/tests/splatter.log @@ -1,5 +1,5 @@ ## Adventurer fall down go boom. Also tests 'say' verb on magic words. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/stashed.log b/tests/stashed.log index 0968282..a86a760 100644 --- a/tests/stashed.log +++ b/tests/stashed.log @@ -1,5 +1,5 @@ ## Test picking up stashed objects in endgame -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause no seed 1318612053 diff --git a/tests/takebird.log b/tests/takebird.log index 557f0ac..e4fa8e2 100644 --- a/tests/takebird.log +++ b/tests/takebird.log @@ -1,5 +1,5 @@ ## Verify that bird starts caged in endgame -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause no seed 1318612053 diff --git a/tests/tall.log b/tests/tall.log index 1af372e..259732e 100644 --- a/tests/tall.log +++ b/tests/tall.log @@ -1,5 +1,5 @@ ## Coverage of LOC_TALL, LOC_WIDEPLACE, LOC_TIGHTPLACE -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/tapdiffer b/tests/tapdiffer index 495427e..679867e 100755 --- a/tests/tapdiffer +++ b/tests/tapdiffer @@ -1,5 +1,5 @@ #! /bin/sh -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: MIT-0 # # tapdiffer - Render diff between input and checkfile as a TAP report diff --git a/tests/tapview b/tests/tapview index 33216ad..b96b436 100755 --- a/tests/tapview +++ b/tests/tapview @@ -7,7 +7,7 @@ # OSD-compliant; otherwise the following SPDX tag incorporates a # license by reference. # -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # This is version 1.6 diff --git a/tests/trident.log b/tests/trident.log index bca7e3c..44c9fba 100644 --- a/tests/trident.log +++ b/tests/trident.log @@ -1,5 +1,5 @@ ## 161-point run to pirate appearance and death by dwarf -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/troll_returns.log b/tests/troll_returns.log index 2cbf136..2806ade 100644 --- a/tests/troll_returns.log +++ b/tests/troll_returns.log @@ -1,5 +1,5 @@ ## See that troll returns if we stole his eggs before crossing -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/turnpenalties.log b/tests/turnpenalties.log index e4d2df9..d44ecfc 100644 --- a/tests/turnpenalties.log +++ b/tests/turnpenalties.log @@ -1,5 +1,5 @@ ## check that the turn count penalties occur -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1951269982 diff --git a/tests/urntest.log b/tests/urntest.log index b67e61c..8fffb2f 100644 --- a/tests/urntest.log +++ b/tests/urntest.log @@ -1,5 +1,5 @@ ## Test verbs on urn -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/urntest2.log b/tests/urntest2.log index 0bcbd7e..22c0d9b 100644 --- a/tests/urntest2.log +++ b/tests/urntest2.log @@ -1,5 +1,5 @@ ## Test filling urn when you have no bottle -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Also, try to lock door after oiling it n diff --git a/tests/urntest3.log b/tests/urntest3.log index 0ec5aab..fcbdf5e 100644 --- a/tests/urntest3.log +++ b/tests/urntest3.log @@ -1,5 +1,5 @@ ## Test filling urn twice. Also, try to lock door after oiling it. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/vending.log b/tests/vending.log index 7e33036..3f4a469 100644 --- a/tests/vending.log +++ b/tests/vending.log @@ -1,5 +1,5 @@ ## Get batteries from the vending machine -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1635997320 diff --git a/tests/wakedwarves.log b/tests/wakedwarves.log index 2ed3948..4aab61a 100644 --- a/tests/wakedwarves.log +++ b/tests/wakedwarves.log @@ -1,5 +1,5 @@ ## Wake the dwarves and die. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/wakedwarves2.log b/tests/wakedwarves2.log index d6f91d2..8237af1 100644 --- a/tests/wakedwarves2.log +++ b/tests/wakedwarves2.log @@ -1,5 +1,5 @@ ## Wake the dwarves by waving rod and die. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/wakedwarves3.log b/tests/wakedwarves3.log index 2cbd78e..1d86845 100644 --- a/tests/wakedwarves3.log +++ b/tests/wakedwarves3.log @@ -1,5 +1,5 @@ ## Wake the dwarves by attacking one and die. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1838473132 diff --git a/tests/water_plant2.log b/tests/water_plant2.log index 4a6f489..44aa76e 100644 --- a/tests/water_plant2.log +++ b/tests/water_plant2.log @@ -1,5 +1,5 @@ ## Check that pour correctly switches among plant states (fuzzed) -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a parser bug fix. n diff --git a/tests/weirdbird.log b/tests/weirdbird.log index 5c48271..b0f9f79 100644 --- a/tests/weirdbird.log +++ b/tests/weirdbird.log @@ -1,5 +1,5 @@ ## Do pointless things to the bird to test odd cases. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 694608006 diff --git a/tests/weirddwarf.log b/tests/weirddwarf.log index a857eb0..613b5f9 100644 --- a/tests/weirddwarf.log +++ b/tests/weirddwarf.log @@ -1,5 +1,5 @@ ## Exercise various verbs on a dwarf -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause n seed 1071883378 diff --git a/tests/win430.log b/tests/win430.log index beaa8d4..29e6564 100644 --- a/tests/win430.log +++ b/tests/win430.log @@ -1,5 +1,5 @@ ## Ryan Sarson's 430-point win. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause no seed 1318612053 diff --git a/tests/wittsend.log b/tests/wittsend.log index 5ae3ec0..6c3a223 100644 --- a/tests/wittsend.log +++ b/tests/wittsend.log @@ -1,5 +1,5 @@ ## 342-point run to Witt's End and plover room. -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 n diff --git a/tests/woodshint.log b/tests/woodshint.log index 68b2e38..acf2f61 100644 --- a/tests/woodshint.log +++ b/tests/woodshint.log @@ -1,5 +1,5 @@ ## Test hinting logic - elicit forest hint -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause #NOCOMPARE Behavior differs due to a parser bug fix. # Also some tests of intransitive-verb cases From 1f9f39d789aed4daec0f901a84f54abbeb5b6c57 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 10:42:11 -0500 Subject: [PATCH 150/213] Address GitLab issue #67: saying Z'ZZZ at the reservoir causes the water to part/crash together --- misc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc.c b/misc.c index 5aebb2a..d24ed2f 100644 --- a/misc.c +++ b/misc.c @@ -432,7 +432,8 @@ static void get_vocab_metadata(const char* word, vocab_t* id, word_type_t* type) vocab_t ref_num; ref_num = get_motion_vocab_id(word); - if (ref_num != WORD_NOT_FOUND) { + // Second conjunct is because the magic-word placeholder is a bit special + if (ref_num != WORD_NOT_FOUND || ref_num == PART) { *id = ref_num; *type = MOTION; return; From b247359d7f5422fe0c5c1f78d05da01c7d311f9e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 10:32:23 -0500 Subject: [PATCH 151/213] Initialize dwarf locations in YAML, not C. Minimizes magic numbers. --- adventure.yaml | 12 ++++++++++++ init.c | 15 +++++++-------- make_dungeon.py | 2 ++ templates/dungeon.c.tpl | 3 +++ templates/dungeon.h.tpl | 4 ++++ 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/adventure.yaml b/adventure.yaml index 3c0e566..2069759 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -2835,6 +2835,18 @@ locations: !!omap {verbs: [], action: [goto, LOC_Y2]}, ] +# Starting locations of dwarves. +# Sixth dwarf is special (the pirate). He always starts at his +# chest's eventual location inside the maze. +dwarflocs: [ + LOC_KINGHALL, + LOC_WESTBANK, + LOC_Y2, + LOC_ALIKE3, + LOC_COMPLEX, + LOC_MAZEEND12, +] + arbitrary_messages: !!omap - NO_MESSAGE: !!null - CAVE_NEARBY: |- diff --git a/init.c b/init.c index 9104a59..aabd1cb 100644 --- a/init.c +++ b/init.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "advent.h" @@ -21,17 +22,10 @@ struct settings_t settings = { }; struct game_t game = { - .dwarves[1].loc = LOC_KINGHALL, - .dwarves[2].loc = LOC_WESTBANK, - .dwarves[3].loc = LOC_Y2, - .dwarves[4].loc = LOC_ALIKE3, - .dwarves[5].loc = LOC_COMPLEX, - - /* Sixth dwarf is special (the pirate). He always starts at his + /* Last dwarf is special (the pirate). He always starts at his * chest's eventual location inside the maze. This loc is saved * in chloc for ref. The dead end in the other maze has its * loc stored in chloc2. */ - .dwarves[6].loc = LOC_MAZEEND12, .chloc = LOC_MAZEEND12, .chloc2 = LOC_DEADEND13, .abbnum = 5, @@ -52,6 +46,11 @@ int initialise(void) int seedval = (int)rand(); set_seed(seedval); + assert(NDWARVES == NDWARFLOCS); + for (int i = 1; i <= NDWARFLOCS; i++) { + game.dwarves[i].loc = dwarflocs[i-1]; + } + for (int i = 1; i <= NOBJECTS; i++) { game.objects[i].place = LOC_NOWHERE; } diff --git a/make_dungeon.py b/make_dungeon.py index 8ab149e..0b8bc53 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -626,6 +626,7 @@ if __name__ == "__main__": tkeys=bigdump(tkey), travel=get_travel(travel), ignore=ignore, + dwarflocs=", ".join(db["dwarflocs"]) + ",", ) # 0-origin index of birds's last song. Bird should @@ -650,6 +651,7 @@ if __name__ == "__main__": motions=get_refs(db["motions"]), actions=get_refs(db["actions"]), state_definitions=statedefines, + ndwarflocs=str(len(db["dwarflocs"])), ) with open(H_NAME, "w", encoding="ascii", errors="surrogateescape") as hf: diff --git a/templates/dungeon.c.tpl b/templates/dungeon.c.tpl index 4a7011a..a192adb 100644 --- a/templates/dungeon.c.tpl +++ b/templates/dungeon.c.tpl @@ -53,4 +53,7 @@ const travelop_t travel[] = {{ const char *ignore = "{ignore}"; +/* Dwarf starting locations */ +const int dwarflocs[NDWARFLOCS] = {{{dwarflocs}}}; + /* end */ diff --git a/templates/dungeon.h.tpl b/templates/dungeon.h.tpl index 0a9c1c5..2a26917 100644 --- a/templates/dungeon.h.tpl +++ b/templates/dungeon.h.tpl @@ -35,6 +35,10 @@ SPDX-License-Identifier: BSD-2-Clause #define COND_HOGRE 20 /* Trying to deal with ogre */ #define COND_HJADE 21 /* Found all treasures except jade */ +/* Count of dwarf starting locations */ +#define NDWARFLOCS {ndwarflocs} +extern const int dwarflocs[NDWARFLOCS]; + typedef struct {{ const char** strs; const int n; From 0b82afa5c1ef86d0255496dbb8b63af41b4ba316 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 16:03:30 -0500 Subject: [PATCH 152/213] Commit a test script. --- tests/compare | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 tests/compare diff --git a/tests/compare b/tests/compare new file mode 100755 index 0000000..32f60be --- /dev/null +++ b/tests/compare @@ -0,0 +1,4 @@ +#! /bin/sh +# Display diff for an individual test +test=$1 +../advent <${test}.log | ./tapdiffer "${test}" "${test}.chk" From eb6399493141662334aa8dc9e1a985df2bd271f8 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 16:34:54 -0500 Subject: [PATCH 153/213] Better explanation of backwards compatibility with 4.30. --- notes.adoc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/notes.adoc b/notes.adoc index d1d3c4c..c369177 100644 --- a/notes.adoc +++ b/notes.adoc @@ -45,6 +45,11 @@ form that is (a) readable, and (b) friendly to forward translation to future languages. It has already survived a move from FORTRAN to C; a future as a Python or Go translation seems possible, even probable. +Compatibility with the 2.5 source we found has been checked by +building a version patched minimally to support the seed command and +running it against the entire test suite, which has 100% code +coverage. + == Functional changes == Bug fixes: @@ -213,7 +218,7 @@ messages with the objects that conceptually own them. We consider this project finished. All issues and TODOs have been cleared, behavior has been carefully checked against original ADVENT, no future demand for new features is expected, and the test suite has -100% code coverage. If new bugs appear the toolchain bit-rots out +100% code coverage. If new bugs appear as the toolchain bit-rots out from under underneath, we will fix those problems. // end From e1a17fd442d2cf4c7dcb711f2428fb48a293e0c3 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 16:38:59 -0500 Subject: [PATCH 154/213] NEWS update. --- NEWS.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index 7e4e88a..e40b945 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,6 +2,9 @@ // SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 +Repository head:: + Saying Z'ZZZ at reservoir no longer causes the waters to part and crash. + 1.16: 2023-04-15:: Savefiles now have an identifying magic cookie at the front. Resume detects if a save has incompatible endianness. From 11d966f3496c9a5c0de2190027c1cae2c6d8e73a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 16:57:15 -0500 Subject: [PATCH 155/213] Add -a option to synopsis. --- advent.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advent.adoc b/advent.adoc index f48df70..5ce5b3f 100644 --- a/advent.adoc +++ b/advent.adoc @@ -7,7 +7,7 @@ advent - Colossal Cave Adventure == SYNOPSIS == -*advent* [-l logfile] [-o] [-r savefile] [script...] +*advent* [-l logfile] [-o] [-r savefile] [-a savefile] [script...] == DESCRIPTION == The original Colossal Cave Adventure from 1976-1977 was the origin of all From c10e9694e3e689204b8352a778ee5a4e29634157 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 17:19:42 -0500 Subject: [PATCH 156/213] Corrected fix, and test, for #67. --- misc.c | 4 +- tests/Makefile | 2 +- tests/placeholder.chk | 944 ++++++++++++++++++++++++++++++++++++++++++ tests/placeholder.log | 158 +++++++ 4 files changed, 1105 insertions(+), 3 deletions(-) create mode 100644 tests/placeholder.chk create mode 100644 tests/placeholder.log diff --git a/misc.c b/misc.c index d24ed2f..d2d0b8f 100644 --- a/misc.c +++ b/misc.c @@ -433,7 +433,7 @@ static void get_vocab_metadata(const char* word, vocab_t* id, word_type_t* type) ref_num = get_motion_vocab_id(word); // Second conjunct is because the magic-word placeholder is a bit special - if (ref_num != WORD_NOT_FOUND || ref_num == PART) { + if (ref_num != WORD_NOT_FOUND) { *id = ref_num; *type = MOTION; return; @@ -447,7 +447,7 @@ static void get_vocab_metadata(const char* word, vocab_t* id, word_type_t* type) } ref_num = get_action_vocab_id(word); - if (ref_num != WORD_NOT_FOUND) { + if (ref_num != WORD_NOT_FOUND && ref_num != PART) { *id = ref_num; *type = ACTION; return; diff --git a/tests/Makefile b/tests/Makefile index 427137b..c39bcbe 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -153,7 +153,7 @@ foobar: # # When adding more tests, bear in mind that any game that continues after a # resurrection will need a NOCOMPARE. At some point in the forward port, -# resurrection was accidentally changed in a way that messed wil the LCG chain. +# resurrection was accidentally changed in a way that messed with the LCG chain. # # The *.chk files need not be up-to-date for this to work. # diff --git a/tests/placeholder.chk b/tests/placeholder.chk new file mode 100644 index 0000000..349bf74 --- /dev/null +++ b/tests/placeholder.chk @@ -0,0 +1,944 @@ + +Welcome to Adventure!! Would you like instructions? + +> n + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed 1838473132 + +Seed set to 1838473132 + +You're in front of building. + +> in + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> take lamp + +OK + +> xyzzy + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> e + +You are crawling over cobbles in a low passage. There is a dim light +at the east end of the passage. + +There is a small wicker cage discarded nearby. + +> take cage + +OK + +> w + +You're in debris room. + +> w + +You are in an awkward sloping east/west canyon. + +> w + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> drop rod + +OK + +> take bird + +OK + +> take rod + +OK + +> w + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> free bird + +OK + +> wave rod + +The bird flies about agitatedly for a moment, then disappears through +the crack. It reappears shortly, carrying in its beak a jade +necklace, which it drops at your feet. + +> take necklace + +OK + +> drop rod + +OK + +> take bird + +OK + +> take rod + +OK + +> d + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> d + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A huge green fierce snake bars the way! + +> free bird + +The little bird attacks the green snake, and in an astounding flurry +drives the snake away. + +> drop rod + +OK + +> drop cage + +OK + +> take cage + +OK + +> take bird + +OK + +> w + +You are in the west side chamber of the Hall of the Mountain King. +A passage continues west and up here. + +There are many coins here! + +> take coins + +OK + +> e + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> s + +You are in the south side chamber. + +There is precious jewelry here! + +> take jewelry + +OK + +> n + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> up + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> s + +This is a low room with a crude note on the wall. The note says, +"You won't get it up the steps". + +There is a large sparkling nugget of gold here! + +> take gold + +OK + +> n + +You're in Hall of Mists. + +> d + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> n + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +There are bars of silver here! + +> n + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> plugh + +>>Foof!<< + +You're inside building. + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> extinguish lamp + +Your lamp is now off. + +> drop coins + +OK + +> drop jewelry + +OK + +> drop necklace + +OK + +> drop gold + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +> s + +You're in n/s passage above e/w passage. + +There are bars of silver here! + +> take silver + +OK + +> s + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> sw + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You are in a secret canyon which here runs e/w. It crosses over a +very tight canyon 15 feet below. If you go down you may not be able +to get back up. + +There is a little axe here. + +> take axe + +OK + +> w + +You are in a secret canyon which exits to the north and east. + +A huge green fierce dragon bars the way! + +The dragon is sprawled out on a Persian rug!! + +> kill dragon + +With what? Your bare hands? + +> yes + +Congratulations! You have just vanquished a dragon with your bare +hands! (Unbelievable, isn't it?) + +You are in a secret canyon which exits to the north and east. + +There is a Persian rug spread out on the floor! + +The blood-specked body of a huge green dead dragon lies to one side. + +> feed dragon + +Don't be ridiculous! + +> drink blood + +Your head buzzes strangely for a moment. + +> take rug + +OK + +> e + +You're in secret e/w canyon above tight canyon. + +> e + +You are in the Hall of the Mountain King, with passages off in all +directions. + +A three foot black rod with a rusty star on an end lies nearby. + +> up + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> d + +There is a threatening little dwarf in the room with you! + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> n + +There is a threatening little dwarf in the room with you! + +You're in n/s passage above e/w passage. + +> n + +There is a threatening little dwarf in the room with you! + +You're at "Y2". + +A hollow voice says "PLUGH". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> inven + +You are currently holding the following: +Brass lantern +Wicker cage +Little bird in cage +Dwarf's axe +Bars of silver +Persian rug + +> drop rug + +OK + +> drop silver + +OK + +> out + +You're in front of building. + +> s + +You are in a valley in the forest beside a stream tumbling along a +rocky bed. + +> w + +You are wandering aimlessly through the forest. + +> n + +You are wandering aimlessly through the forest. + +Your keen eye spots a severed leporine appendage lying on the ground. + +> take appendage + +OK + +> free bird + +OK + +> drop cage + +OK + +> listen + +The bird is singing to you in gratitude for your having returned it to +its home. In return, it informs you of a magic word which it thinks +you may find useful somewhere near the Hall of Mists. The magic word +changes frequently, but for now the bird believes it is "H'CFL". You +thank the bird for this information, and it flies off into the forest. + +> s + +You are wandering aimlessly through the forest. + +> s + +You're in valley. + +> n + +You're in front of building. + +> in + +You're inside building. + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +There is a bottle of water here. + +> take water + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +> plover + +>>Foof!<< + +You're in a small chamber lit by an eerie green light. An extremely +narrow tunnel exits to the west. A dark corridor leads ne. + +There is an emerald here the size of a plover's egg! + +> ne + +You're in the dark-room. A corridor leading south is the only exit. + +A massive stone tablet embedded in the wall reads: +"Congratulations on bringing light into the dark-room!" + +There is a platinum pyramid here, 8 inches on a side! + +> take pyramid + +OK + +> s + +You're in Plover Room. + +There is an emerald here the size of a plover's egg! + +> plover + +>>Foof!<< + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You're in n/s passage above e/w passage. + +> s + +You're in Hall of Mt King. + +A three foot black rod with a rusty star on an end lies nearby. + +> take rod + +OK + +> up + +You're in Hall of Mists. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +A crystal bridge now spans the fissure. + +> drop rod + +OK + +> west + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> take diamonds + +OK + +> w + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are at the west end of the Hall of Mists. A low wide crawl +continues west and another goes north. To the south is a little +passage 6 feet off the floor. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the east end of a very long hall apparently without side +chambers. To the east a low wide crawl slants up. To the north a +round two foot hole slants down. + +> w + +There is a threatening little dwarf in the room with you! + +You are at the west end of a very long featureless hall. The hall +joins up with a narrow north/south passage. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a maze of twisty little passages, all different. + +> sw + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisty passages, all different. + +> se + +There is a threatening little dwarf in the room with you! + +You are in a little maze of twisting passages, all different. + +> s + +There is a threatening little dwarf in the room with you! + +Dead end + +There is a massive and somewhat battered vending machine here. The +instructions on it read: "Drop coins here to receive fresh batteries." + +> kill machine + +As you strike the vending machine, it pivots backward along with a +section of wall, revealing a dark passage leading south. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a long, rough-hewn, north/south corridor. + +> s + +There is a threatening little dwarf in the room with you! + +You are in a large chamber with passages to the west and north. + +A formidable ogre bars the northern exit. + +> kill ogre + +The ogre, who despite his bulk is quite agile, easily dodges your +attack. He seems almost amused by your puny effort. + +One sharp nasty knife is thrown at you! + +The ogre, distracted by your rush, is struck by the knife. With a +blood-curdling yell he turns and bounds after the dwarf, who flees +in panic. You are left alone in the room. + +> n + +You are in the ogre's storeroom. The only exit is to the south. + +There is an enormous ruby here! + +> take ruby + +OK + +> s + +You are in a large chamber with passages to the west and north. + +> w + +You are in a long, rough-hewn, north/south corridor. + +> n + +Dead end + +There is a massive vending machine here, swung back to reveal a +southward passage. + +> n + +You are in a little maze of twisting passages, all different. + +> n + +You are in a little maze of twisty passages, all different. + +> nw + +You are in a maze of twisty little passages, all different. + +> d + +You're at west end of long hall. + +> e + +You're at east end of long hall. + +> e + +You're at west end of Hall of Mists. + +> e + +You're on west bank of fissure. + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A three foot black rod with a rusty star on an end lies nearby. + +A crystal bridge spans the fissure. + +> e + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> throw axe + +You killed a little dwarf. The body vanishes in a cloud of greasy +black smoke. + +You're in Hall of Mists. + +There is a little axe here. + +Rough stone steps lead up the dome. + +> take axe + +OK + +> n + +You're in Hall of Mt King. + +> n + +You're in n/s passage above e/w passage. + +> n + +You are in a large room, with a passage to the south, a passage to the +west, and a wall of broken rock to the east. There is a large "Y2" on +a rock in the room's center. + +A hollow voice says "PLUGH". + +> off + +Your lamp is now off. + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> plugh + +>>Foof!<< + +You're inside building. + +There are bars of silver here! + +There is a Persian rug spread out on the floor! + +There is a large sparkling nugget of gold here! + +A precious jade necklace has been dropped here! + +There is precious jewelry here! + +There are many coins here! + +There are some keys on the ground here. + +There is food here. + +> drop ruby + +OK + +> drop diamonds + +OK + +> drop pyramid + +OK + +> plugh + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> on + +Your lamp is now on. + +You're at "Y2". + +A hollow voice says "PLUGH". + +> s + +You are in a low n/s passage at a hole in the floor. The hole goes +down to an e/w passage. + +> s + +You're in Hall of Mt King. + +> n + +You're in n/s passage above e/w passage. + +> d + +You are in a dirty broken passage. To the east is a crawl. To the +west is a large passage. Above you is a hole to another passage. + +> bedquilt + +You are in Bedquilt, a long east/west passage with holes everywhere. +To explore at random select north, south, up, or down. + +> slab + +You are in a large low circular chamber whose floor is an immense slab +fallen from the ceiling (Slab Room). East and west there once were +large passages, but they are now filled with boulders. Low small +passages go north and south, and the south one quickly bends west +around the boulders. + +> s + +You are at the west end of the Twopit Room. There is a large hole in +the wall above the pit at this end of the room. + +> d + +You are at the bottom of the western pit in the Twopit Room. There is +a large hole in the wall about 25 feet above you. + +There is a tiny little plant in the pit, murmuring "water, water, ..." + +> water plant + +The plant spurts into furious growth for a few seconds. + +You're in west pit. + +There is a 12-foot-tall beanstalk stretching up out of the pit, +bellowing "WATER!! WATER!!" + +> H'CFL + +Nothing happens. + +> u + +You're at west end of Twopit Room. + +The top of a 12-foot-tall beanstalk is poking out of the west pit. + +> w + +You're in Slab Room. + +> u + +You are in a secret n/s canyon above a large room. + +> reservoir + +You are at the edge of a large underground reservoir. An opaque cloud +of white mist fills the room and rises rapidly upward. The lake is +fed by a stream, which tumbles out of a hole in the wall about 10 feet +overhead and splashes noisily into the water somewhere within the +mist. There is a passage going back toward the south. + +> Z'ZZZ + +Sorry, I don't know the word "Z'ZZZ". + +> + +> +You scored 183 out of a possible 430, using 150 turns. + +You may now consider yourself a "Seasoned Adventurer". + +To achieve the next higher rating, you need 68 more points. diff --git a/tests/placeholder.log b/tests/placeholder.log new file mode 100644 index 0000000..7d07add --- /dev/null +++ b/tests/placeholder.log @@ -0,0 +1,158 @@ +## Test behavior of placeholder magic word at reservoir +# SPDX-FileCopyrightText: Copyright Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause +# Based on walkthrough at http://www.ecsoftwareconsulting.com/node/56 +n +seed 1838473132 +in +take lamp +xyzzy +on +take rod +e +take cage +w +w +w +drop rod +take bird +take rod +w +free bird +wave rod +take necklace +drop rod +take bird +take rod +d +d +free bird +drop rod +drop cage +take cage +take bird +w +take coins +e +s +take jewelry +n +up +s +take gold +n +d +n +n +plugh +extinguish lamp +drop coins +drop jewelry +drop necklace +drop gold +plugh +on +s +take silver +s +sw +take axe +w +kill dragon +yes +feed dragon +drink blood +take rug +e +e +up +d +n +n +off +plugh +inven +drop rug +drop silver +out +s +w +n +take appendage +free bird +drop cage +listen +s +s +n +in +take water +plugh +on +plover +ne +take pyramid +s +plover +s +s +take rod +up +w +wave rod +drop rod +west +take diamonds +w +w +w +s +sw +se +s +kill machine +s +s +kill ogre +n +take ruby +s +w +n +n +n +nw +d +e +e +e +e +e +throw axe +take axe +n +n +n +off +plugh +drop ruby +drop diamonds +drop pyramid +plugh +on +s +s +n +d +bedquilt +slab +s +d +water plant +H'CFL +u +w +u +reservoir +Z'ZZZ + From 90f96a25da8fd36563d0273ea619968bd72ca9c0 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 21:52:59 -0500 Subject: [PATCH 157/213] pylint cleanup. --- make_graph.py | 1 + 1 file changed, 1 insertion(+) diff --git a/make_graph.py b/make_graph.py index 779572a..35dd92f 100755 --- a/make_graph.py +++ b/make_graph.py @@ -144,6 +144,7 @@ if __name__ == "__main__": debug = False for (switch, val) in options: if switch == "-a": + # pylint: disable=unnecessary-lambda-assignment subset = lambda loc: True elif switch == "-d": subset = alldifferent From dd65960ec5067cb6dce43a0e3f272a3880098708 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 2 Jan 2024 21:50:21 -0500 Subject: [PATCH 158/213] Ready to ship 1.17. --- NEWS.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.adoc b/NEWS.adoc index e40b945..b61a477 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Copyright Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 -Repository head:: +1.17: 2024-01-02:: Saying Z'ZZZ at reservoir no longer causes the waters to part and crash. 1.16: 2023-04-15:: From 75bc031b46097725c83b63bbdb520ac3c907ef05 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 3 Jan 2024 05:55:57 -0500 Subject: [PATCH 159/213] Reduce include complexity. --- actions.c | 4 ++-- main.c | 1 - saveresume.c | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/actions.c b/actions.c index 4f4ced1..f5a7abd 100644 --- a/actions.c +++ b/actions.c @@ -9,10 +9,10 @@ #include #include #include -#include "advent.h" -#include "dungeon.h" #include +#include "advent.h" + static phase_codes_t fill(verb_t, obj_t); static phase_codes_t attack(command_t command) diff --git a/main.c b/main.c index 16cf42d..3fadf10 100644 --- a/main.c +++ b/main.c @@ -14,7 +14,6 @@ #include #include #include "advent.h" -#include "dungeon.h" #define DIM(a) (sizeof(a)/sizeof(a[0])) diff --git a/saveresume.c b/saveresume.c index a2c10a0..3b94b48 100644 --- a/saveresume.c +++ b/saveresume.c @@ -16,7 +16,6 @@ #include #include "advent.h" -#include "dungeon.h" /* * Use this to detect endianness mismatch. Can't be unchanged by byte-swapping. From a6ec8a9595e988db977f0075402ab5279e653af9 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 3 Jan 2024 06:15:04 -0500 Subject: [PATCH 160/213] Simplify some dependencies. --- advent.h | 1 - init.c | 3 +-- templates/dungeon.c.tpl | 2 +- templates/dungeon.h.tpl | 5 ++--- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/advent.h b/advent.h index 68890da..394a389 100644 --- a/advent.h +++ b/advent.h @@ -21,7 +21,6 @@ #define LINESIZE 1024 #define TOKLEN 5 // # outputting characters in a token */ -#define NDWARVES 6 // number of dwarves #define PIRATE NDWARVES // must be NDWARVES-1 when zero-origin #define DALTLC LOC_NUGGET // alternate dwarf location #define INVLIMIT 7 // inventory limit (# of objects) diff --git a/init.c b/init.c index aabd1cb..715f3ef 100644 --- a/init.c +++ b/init.c @@ -46,8 +46,7 @@ int initialise(void) int seedval = (int)rand(); set_seed(seedval); - assert(NDWARVES == NDWARFLOCS); - for (int i = 1; i <= NDWARFLOCS; i++) { + for (int i = 1; i <= NDWARVES; i++) { game.dwarves[i].loc = dwarflocs[i-1]; } diff --git a/templates/dungeon.c.tpl b/templates/dungeon.c.tpl index a192adb..03640d5 100644 --- a/templates/dungeon.c.tpl +++ b/templates/dungeon.c.tpl @@ -54,6 +54,6 @@ const travelop_t travel[] = {{ const char *ignore = "{ignore}"; /* Dwarf starting locations */ -const int dwarflocs[NDWARFLOCS] = {{{dwarflocs}}}; +const int dwarflocs[NDWARVES] = {{{dwarflocs}}}; /* end */ diff --git a/templates/dungeon.h.tpl b/templates/dungeon.h.tpl index 2a26917..cf637c8 100644 --- a/templates/dungeon.h.tpl +++ b/templates/dungeon.h.tpl @@ -35,9 +35,8 @@ SPDX-License-Identifier: BSD-2-Clause #define COND_HOGRE 20 /* Trying to deal with ogre */ #define COND_HJADE 21 /* Found all treasures except jade */ -/* Count of dwarf starting locations */ -#define NDWARFLOCS {ndwarflocs} -extern const int dwarflocs[NDWARFLOCS]; +#define NDWARVES {ndwarflocs} // number of dwarves +extern const int dwarflocs[NDWARVES]; typedef struct {{ const char** strs; From 2db3bed3f1ee0a220bf1d1b818716afb90b30b35 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 3 Jan 2024 06:30:40 -0500 Subject: [PATCH 161/213] Fix up copyright notices. SPDX wants only one per file. --- actions.c | 3 +-- advent.h | 3 +-- cheat.c | 3 +-- init.c | 3 +-- main.c | 3 +-- misc.c | 3 +-- saveresume.c | 3 +-- score.c | 3 +-- 8 files changed, 8 insertions(+), 16 deletions(-) diff --git a/actions.c b/actions.c index f5a7abd..9239b50 100644 --- a/actions.c +++ b/actions.c @@ -1,8 +1,7 @@ /* * Actions for the dungeon-running code. * - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/advent.h b/advent.h index 394a389..e3be917 100644 --- a/advent.h +++ b/advent.h @@ -1,8 +1,7 @@ /* * Dungeon types and macros. * - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copyright, 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/cheat.c b/cheat.c index 1a415b7..9842d5c 100644 --- a/cheat.c +++ b/cheat.c @@ -4,8 +4,7 @@ * savefile(), so we know we're always outputting save files that advent * can import. * - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyrighy * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/init.c b/init.c index 715f3ef..4be4b62 100644 --- a/init.c +++ b/init.c @@ -1,8 +1,7 @@ /* * Initialisation * - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copright 1977, 2005 by Will Crowther and Don Woodsm, Copyright 2017 by Eric S. Raymond * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/main.c b/main.c index 3fadf10..2e7fdf2 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,5 @@ /* - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/misc.c b/misc.c index d2d0b8f..432d5d8 100644 --- a/misc.c +++ b/misc.c @@ -1,8 +1,7 @@ /* * I/O and support routines. * - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, 2017 by Eric S. Raymond * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/saveresume.c b/saveresume.c index 3b94b48..0d1fbf4 100644 --- a/saveresume.c +++ b/saveresume.c @@ -4,8 +4,7 @@ * (ESR) This replaces a bunch of particularly nasty FORTRAN-derived code; * see the history.adoc file in the source distribution for discussion. * - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/score.c b/score.c index c0a0277..9d3d63f 100644 --- a/score.c +++ b/score.c @@ -1,8 +1,7 @@ /* * Scoring and wrap-up. * - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copyright 977, 2005 by Will Crowther and Don Woods, Copyright, 2017 by Eric S. Raymond * SPDX-License-Identifier: BSD-2-Clause */ #include From cf7ea0cd89952ff4bbd9f820399ee7bc473916ba Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 15 Jan 2024 04:57:47 -0500 Subject: [PATCH 162/213] Remove debugging debris. --- tests/Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index c39bcbe..2ed7431 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -124,10 +124,6 @@ tap: count $(SGAMES) $(TEST_TARGETS) count: @echo 1..$(words $(TEST_TARGETS)) -foobar: - exit 1 - - # The following machinery tests the game against a binary made from # the advent430 branch To use it, switch to that branch, build the # binary, run it once to generate adventure.data, then switch back to From f26514b5dd3624076f59801cfca66cc7cbdd3313 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 15 Jan 2024 04:58:21 -0500 Subject: [PATCH 163/213] Fix SPDX headers. --- .gitignore | 2 +- .gitlab-ci.yml | 2 +- .shipper | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7aa1928..fcfc9f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause advent *.gcda diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6b6bd6d..b8f4b91 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Eric S. Raymond +# SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause stages: - ci-build diff --git a/.shipper b/.shipper index d3ed58d..5e5904c 100644 --- a/.shipper +++ b/.shipper @@ -1,4 +1,4 @@ -#SPDX-FileCopyrightText: Eric S. Raymond +#SPDX-FileCopyrightText: (C) Eric S. Raymond #SPDX-License-Identifier: BSD-2-Clause extralines="""

There is a code coverage analysis and a symbol coverage analysis

From 3c09c25cc3343546143447547297d23201f2140c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 15 Jan 2024 05:03:53 -0500 Subject: [PATCH 164/213] Update tapview and tapdiffer. --- tests/tapdiffer | 24 ++++++++++++++---------- tests/tapview | 22 +++++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/tests/tapdiffer b/tests/tapdiffer index 679867e..ea1cfa7 100755 --- a/tests/tapdiffer +++ b/tests/tapdiffer @@ -1,6 +1,4 @@ #! /bin/sh -# SPDX-FileCopyrightText: Copyright Eric S. Raymond -# SPDX-License-Identifier: MIT-0 # # tapdiffer - Render diff between input and checkfile as a TAP report # @@ -16,17 +14,23 @@ # OSD-compliant; otherwise the following SPDX tag incorporates the # MIT No Attribution license by reference. # +# SPDX-FileCopyrightText: (C) Eric S. Raymond +# SPDX-License-Identifier: MIT-0 +# # A newer version may be available at https://gitlab.com/esr/tapview # Check your last commit dqte for this file against the commit list # there to see if it might be a good idea to update. # -if [ "$1" = "-b" ] -then - diffopts=-ub - shift -else - diffopts=-u -fi +diffopts=-u +while getopts bn opt +do + case $opt in + b) diffopts=-ub;; + *) echo "tapdiffer: unknown option ${opt}."; exit 1;; + esac +done +# shellcheck disable=SC2004 +shift $(($OPTIND - 1)) legend=$1 checkfile=$2 @@ -37,7 +41,7 @@ if diff --text "${diffopts}" "${checkfile}" - >/tmp/tapdiff$$ then echo "ok - ${legend}" else - echo "not ok - ${checkfile}: ${legend}" + echo "not ok - ${legend}" if [ ! "${QUIET}" = 1 ] then echo " --- |" diff --git a/tests/tapview b/tests/tapview index b96b436..0a36f88 100755 --- a/tests/tapview +++ b/tests/tapview @@ -4,14 +4,15 @@ # This code is intended to be embedded in your project. The author # grants permission for it to be distributed under the prevailing # license of your project if you choose, provided that license is -# OSD-compliant; otherwise the following SPDX tag incorporates a -# license by reference. +# OSD-compliant; otherwise the following SPDX tag incorporates the +# MIT No Attribution license by reference. # -# SPDX-FileCopyrightText: Copyright Eric S. Raymond -# SPDX-License-Identifier: BSD-2-Clause +# SPDX-FileCopyrightText: (C) Eric S. Raymond +# SPDX-License-Identifier: MIT-0 # -# This is version 1.6 # A newer version may be available at https://gitlab.com/esr/tapview +# Check your last commit date for this file against the commit list +# there to see if it might be a good idea to update. # OK="." FAIL="F" @@ -19,13 +20,16 @@ SKIP="s" TODO_NOT_OK="x" TODO_OK="u" +LF=' +' + ship_char() { # shellcheck disable=SC2039 printf '%s' "$1" # https://www.etalabs.net/sh_tricks.html } ship_line() { - report="${report}${1}\n" + report="${report}${1}$LF" } ship_error() { @@ -34,7 +38,7 @@ ship_error() { then echo "" fi - report="${report}${1}\n" + report="${report}${1}$LF" echo "${report}" exit 1 } @@ -76,6 +80,10 @@ context_pop () { then ship_line "Expected $(context_get expect) tests but only ${testcount} ran." status=1 + elif [ "$(context_get plan)" != "" ] && [ "$(context_get expect)" -lt "$(context_get count)" ] + then + ship_line "${testcount} ran but $(context_get expect) expected." + status=1 fi } From 83c6a66887002170cec56f0e5c562288cb19b3a0 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 15 Jan 2024 05:10:46 -0500 Subject: [PATCH 165/213] Typo fix. --- notes.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes.adoc b/notes.adoc index c369177..cc57885 100644 --- a/notes.adoc +++ b/notes.adoc @@ -139,7 +139,7 @@ whitespace before processing. A -r command-line option has been added. When it is given (with a file path argument) it is functionally equivalent to a RESTORE command. -An -a command-line option has been added (comditionally on +An -a command-line option has been added (conditionally on ADVENT_AUTOSAVE) for use in BBS door systems. When this option is given, the game roads from the specified filename argument on startup and saves to it on quit or a received signal. There is a new nmessage From 258b7703f22045be1b6e9fb74bd3391ed94ed86b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 28 Jan 2024 05:55:33 -0500 Subject: [PATCH 166/213] Simplify SPDX copyright lines to the shortest canonical form... ...because if we leave them longer than 80 chars, reflow is going to mess them up. --- Dockerfile.ci | 2 +- INSTALL.adoc | 2 +- Makefile | 2 +- NEWS.adoc | 2 +- README.adoc | 2 +- actions.c | 2 +- advent.adoc | 2 +- advent.desktop | 2 +- advent.h | 2 +- adventure.yaml | 2 +- cheat.c | 2 +- hints.adoc | 2 +- history.adoc | 2 +- init.c | 2 +- main.c | 2 +- make_dungeon.py | 2 +- make_graph.py | 2 +- misc.c | 2 +- notes.adoc | 2 +- saveresume.c | 2 +- score.c | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Dockerfile.ci b/Dockerfile.ci index c8f29a1..598687b 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,6 +1,6 @@ # This image is built by the Gitlab CI pipeline to be used in subsequent # pipeline steps. -# SPDX-FileCopyrightText: Copyright Eric S. Raymond +# SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause FROM ubuntu diff --git a/INSTALL.adoc b/INSTALL.adoc index b6f5b4b..683e2f0 100644 --- a/INSTALL.adoc +++ b/INSTALL.adoc @@ -1,5 +1,5 @@ = Installing Open Adventure = -// SPDX-FileCopyrightText: Copyright Eric S. Raymond +// SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 Installation now requires Python3 due to a security issue diff --git a/Makefile b/Makefile index dfd3ff2..49c909e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Makefile for the open-source release of adventure 2.5 -# SPDX-FileCopyrightText: Copyright Eric S. Raymond +# SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # To build with save/resume disabled, pass CFLAGS="-DADVENT_NOSAVE" diff --git a/NEWS.adoc b/NEWS.adoc index b61a477..68aa36c 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -1,5 +1,5 @@ = Open Adventure project news = -// SPDX-FileCopyrightText: Copyright Eric S. Raymond +// SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 1.17: 2024-01-02:: diff --git a/README.adoc b/README.adoc index ba67510..6b25f7f 100644 --- a/README.adoc +++ b/README.adoc @@ -1,5 +1,5 @@ = README for Open Adventure = -// SPDX-FileCopyrightText: Copyright Eric S. Raymond +// SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 If you are reading this anywhere but at http://www.catb.org/~esr/open-adventure diff --git a/actions.c b/actions.c index 9239b50..ec62447 100644 --- a/actions.c +++ b/actions.c @@ -1,7 +1,7 @@ /* * Actions for the dungeon-running code. * - * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: (C) 1977, 2005 Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/advent.adoc b/advent.adoc index 5ce5b3f..9e628e0 100644 --- a/advent.adoc +++ b/advent.adoc @@ -1,6 +1,6 @@ = advent(6) = :doctype: manpage -// SPDX-FileCopyrightText: Copyright Eric S. Raymond +// SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 == NAME == diff --git a/advent.desktop b/advent.desktop index 3fe5420..1cc38f8 100644 --- a/advent.desktop +++ b/advent.desktop @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright Eric S. Raymond +# SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause [Desktop Entry] Type=Application diff --git a/advent.h b/advent.h index e3be917..55518cb 100644 --- a/advent.h +++ b/advent.h @@ -1,7 +1,7 @@ /* * Dungeon types and macros. * - * SPDX-FileCopyrightText: Copyright, 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/adventure.yaml b/adventure.yaml index 2069759..31988de 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright Eric S. Raymond +# SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # # This YAML file gets processed into a collection of data structures and diff --git a/cheat.c b/cheat.c index 9842d5c..279bcd9 100644 --- a/cheat.c +++ b/cheat.c @@ -4,7 +4,7 @@ * savefile(), so we know we're always outputting save files that advent * can import. * - * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyrighy + * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ #include diff --git a/hints.adoc b/hints.adoc index c22c11b..f7e25e1 100644 --- a/hints.adoc +++ b/hints.adoc @@ -1,5 +1,5 @@ = Non-spoiler hints = -// SPDX-FileCopyrightText: Copyright Eric S. Raymond +// SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 Say the words you see. They can have interesting effects. diff --git a/history.adoc b/history.adoc index 5384c2c..8ca5da7 100644 --- a/history.adoc +++ b/history.adoc @@ -1,6 +1,6 @@ = A brief history of Colossal Cave Adventure = by Eric S. Raymond -// SPDX-FileCopyrightText: Copyright Eric S. Raymond +// SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 Adventure is the fons et origo of all later dungeon-crawling computer diff --git a/init.c b/init.c index 4be4b62..a620b2c 100644 --- a/init.c +++ b/init.c @@ -1,7 +1,7 @@ /* * Initialisation * - * SPDX-FileCopyrightText: Copright 1977, 2005 by Will Crowther and Don Woodsm, Copyright 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woodsm * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/main.c b/main.c index 2e7fdf2..e0fdb69 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/make_dungeon.py b/make_dungeon.py index 0b8bc53..8d7f719 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Copyright Eric S. Raymond +# SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """ This is the open-adventure dungeon generator. It consumes a YAML description of diff --git a/make_graph.py b/make_graph.py index 35dd92f..5a58895 100755 --- a/make_graph.py +++ b/make_graph.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Copyright Eric S. Raymond +# SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause """\ usage: make_graph.py [-a] [-d] [-m] [-s] [-v] diff --git a/misc.c b/misc.c index 432d5d8..c853237 100644 --- a/misc.c +++ b/misc.c @@ -1,7 +1,7 @@ /* * I/O and support routines. * - * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/notes.adoc b/notes.adoc index cc57885..b970e7c 100644 --- a/notes.adoc +++ b/notes.adoc @@ -1,6 +1,6 @@ = Open Adventure Maintainer's Notes = by Eric S. Raymond -// SPDX-FileCopyrightText: Copyright Eric S. Raymond +// SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 In which we explain what has been done to this code since Don Woods diff --git a/saveresume.c b/saveresume.c index 0d1fbf4..34404c6 100644 --- a/saveresume.c +++ b/saveresume.c @@ -4,7 +4,7 @@ * (ESR) This replaces a bunch of particularly nasty FORTRAN-derived code; * see the history.adoc file in the source distribution for discussion. * - * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/score.c b/score.c index 9d3d63f..1c9a397 100644 --- a/score.c +++ b/score.c @@ -1,7 +1,7 @@ /* * Scoring and wrap-up. * - * SPDX-FileCopyrightText: Copyright 977, 2005 by Will Crowther and Don Woods, Copyright, 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ #include From c11938aed5e261ac40a562781325996628663610 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 28 Jan 2024 07:11:21 -0500 Subject: [PATCH 167/213] Place1TBS mandatory braces. --- actions.c | 381 ++++++++++++++++++++++++++++-------------------------- init.c | 9 +- main.c | 319 +++++++++++++++++++++++++++------------------ score.c | 72 +++++++---- 4 files changed, 438 insertions(+), 343 deletions(-) diff --git a/actions.c b/actions.c index ec62447..fed70b9 100644 --- a/actions.c +++ b/actions.c @@ -14,12 +14,11 @@ static phase_codes_t fill(verb_t, obj_t); -static phase_codes_t attack(command_t command) +static phase_codes_t attack(command_t command) { /* Attack. Assume target if unambiguous. "Throw" also links here. * Attackable objects fall into two categories: enemies (snake, * dwarf, etc.) and others (bird, clam, machine). Ambiguous if 2 * enemies, or no enemies but 2 others. */ -{ verb_t verb = command.verb; obj_t obj = command.obj; @@ -137,9 +136,9 @@ static phase_codes_t attack(command_t command) if (obj == OGRE) { rspeak(OGRE_DODGE); - if (atdwrf(game.loc) == 0) + if (atdwrf(game.loc) == 0) { return GO_CLEAROBJ; - + } rspeak(KNIFE_THROWN); DESTROY(OGRE); int dwarves = 0; @@ -185,12 +184,11 @@ static phase_codes_t attack(command_t command) return GO_CLEAROBJ; } -static phase_codes_t bigwords(vocab_t id) +static phase_codes_t bigwords(vocab_t id) { /* Only called on FEE FIE FOE FOO (AND FUM). Advance to next state if given * in proper order. Look up foo in special section of vocab to determine which * word we've got. Last word zips the eggs back to the giant room (unless * already there). */ -{ int foobar = abs(game.foobar); /* Only FEE can start a magic-word sequence. */ @@ -219,30 +217,31 @@ static phase_codes_t bigwords(vocab_t id) if (game.objects[EGGS].place == LOC_NOWHERE && game.objects[TROLL].place == LOC_NOWHERE && game.objects[TROLL].prop == TROLL_UNPAID) game.objects[TROLL].prop = TROLL_PAIDONCE; - if (HERE(EGGS)) + if (HERE(EGGS)) { pspeak(EGGS, look, true, EGGS_VANISHED); - else if (game.loc == objects[EGGS].plac) + } else if (game.loc == objects[EGGS].plac) { pspeak(EGGS, look, true, EGGS_HERE); - else + } else { pspeak(EGGS, look, true, EGGS_DONE); + } move(EGGS, objects[EGGS].plac); return GO_CLEAROBJ; } } else { /* Magic-word sequence was started but is incorrect */ - if (settings.oldstyle || game.seenbigwords) - rspeak(START_OVER); - else + if (settings.oldstyle || game.seenbigwords) { + rspeak(START_OVER); + } else { rspeak(WELL_POINTLESS); + } game.foobar = WORD_EMPTY; return GO_CLEAROBJ; } } -static void blast(void) +static void blast(void) { /* Blast. No effect unless you've got dynamite, which is a neat trick! */ -{ if (PROP_IS_NOTFOUND(ROD2) || !game.closed) rspeak(REQUIRES_DYNAMITE); else { @@ -260,9 +259,8 @@ static void blast(void) } } -static phase_codes_t vbreak(verb_t verb, obj_t obj) +static phase_codes_t vbreak(verb_t verb, obj_t obj) { /* Break. Only works for mirror in repository and, of course, the vase. */ -{ switch (obj) { case MIRROR: if (game.closed) { @@ -287,26 +285,25 @@ static phase_codes_t vbreak(verb_t verb, obj_t obj) return (GO_CLEAROBJ); } -static phase_codes_t brief(void) +static phase_codes_t brief(void) { /* Brief. Intransitive only. Suppress full descriptions after first time. */ -{ game.abbnum = 10000; game.detail = 3; rspeak(BRIEF_CONFIRM); return GO_CLEAROBJ; } -static phase_codes_t vcarry(verb_t verb, obj_t obj) +static phase_codes_t vcarry(verb_t verb, obj_t obj) { /* Carry an object. Special cases for bird and cage (if bird in cage, can't * take one without the other). Liquids also special, since they depend on * status of bottle. Also various side effects, etc. */ -{ if (obj == INTRANSITIVE) { /* Carry, no object given yet. OK if only one object present. */ if (game.locs[game.loc].atloc == NO_OBJECT || game.link[game.locs[game.loc].atloc] != 0 || - atdwrf(game.loc) > 0) + atdwrf(game.loc) > 0) { return GO_UNKNOWN; + } obj = game.locs[game.loc].atloc; } @@ -362,8 +359,9 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) } if (game.objects[BOTTLE].prop == EMPTY_BOTTLE) { return (fill(verb, BOTTLE)); - } else + } else { rspeak(BOTTLE_FULL); + } return GO_CLEAROBJ; } obj = BOTTLE; @@ -399,8 +397,9 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) carry(obj, game.loc); - if (obj == BOTTLE && LIQUID() != NO_OBJECT) + if (obj == BOTTLE && LIQUID() != NO_OBJECT) { game.objects[LIQUID()].place = CARRIED; + } if (GSTONE(obj) && !PROP_IS_FOUND(obj)) { PROP_SET_FOUND(obj); @@ -410,9 +409,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static int chain(verb_t verb) +static int chain(verb_t verb) { /* Do something to the bear's chain */ -{ if (verb != LOCK) { if (game.objects[BEAR].prop == UNTAMED_BEAR) { rspeak(BEAR_BLOCKS); @@ -462,11 +460,10 @@ static int chain(verb_t verb) return GO_CLEAROBJ; } -static phase_codes_t discard(verb_t verb, obj_t obj) +static phase_codes_t discard(verb_t verb, obj_t obj) { /* Discard object. "Throw" also comes here for most objects. Special cases for * bird (might attack snake or dragon) and cage (might contain bird) and vase. * Drop coins at vending machine for extra batteries. */ -{ if (obj == ROD && !TOTING(ROD) && TOTING(ROD2)) { obj = ROD2; } @@ -482,17 +479,19 @@ static phase_codes_t discard(verb_t verb, obj_t obj) game.objects[CAVITY].prop = CAVITY_FULL; if (HERE(RUG) && ((obj == EMERALD && game.objects[RUG].prop != RUG_HOVER) || (obj == RUBY && game.objects[RUG].prop == RUG_HOVER))) { - if (obj == RUBY) - rspeak(RUG_SETTLES); - else if (TOTING(RUG)) - rspeak(RUG_WIGGLES); - else - rspeak(RUG_RISES); + if (obj == RUBY) { + rspeak(RUG_SETTLES); + } else if (TOTING(RUG)) { + rspeak(RUG_WIGGLES); + } else { + rspeak(RUG_RISES); + } if (!TOTING(RUG) || obj == RUBY) { int k = (game.objects[RUG].prop == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER; game.objects[RUG].prop = k; - if (k == RUG_HOVER) + if (k == RUG_HOVER) { k = objects[SAPPH].plac; + } move(RUG + NOBJECTS, k); } } @@ -507,8 +506,9 @@ static phase_codes_t discard(verb_t verb, obj_t obj) return GO_CLEAROBJ; } - if (LIQUID() == obj) + if (LIQUID() == obj) { obj = BOTTLE; + } if (obj == BOTTLE && LIQUID() != NO_OBJECT) { game.objects[LIQUID()].place = LOC_NOWHERE; } @@ -529,8 +529,9 @@ static phase_codes_t discard(verb_t verb, obj_t obj) state_change(VASE, AT(PILLOW) ? VASE_WHOLE : VASE_DROPPED); - if (game.objects[VASE].prop != VASE_WHOLE) + if (game.objects[VASE].prop != VASE_WHOLE) { game.objects[VASE].fixed = IS_FIXED; + } drop(obj, game.loc); return GO_CLEAROBJ; } @@ -548,13 +549,15 @@ static phase_codes_t discard(verb_t verb, obj_t obj) } if (HERE(SNAKE)) { rspeak(BIRD_ATTACKS); - if (game.closed) + if (game.closed) { return GO_DWARFWAKE; + } DESTROY(SNAKE); /* Set game.prop for use by travel options */ game.objects[SNAKE].prop = SNAKE_CHASED; - } else + } else { rspeak(OK_MAN); + } game.objects[BIRD].prop = FOREST(game.loc) ? BIRD_FOREST_UNCAGED : BIRD_UNCAGED; drop(obj, game.loc); @@ -566,10 +569,9 @@ static phase_codes_t discard(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static phase_codes_t drink(verb_t verb, obj_t obj) +static phase_codes_t drink(verb_t verb, obj_t obj) { /* Drink. If no object, assume water and look for it here. If water is in * the bottle, drink that, else must be at a water loc, so drink stream. */ -{ if (obj == INTRANSITIVE && LIQLOC(game.loc) != WATER && (LIQUID() != WATER || !HERE(BOTTLE))) { return GO_UNKNOWN; @@ -596,10 +598,9 @@ static phase_codes_t drink(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static phase_codes_t eat(verb_t verb, obj_t obj) +static phase_codes_t eat(verb_t verb, obj_t obj) { /* Eat. Intransitive: assume food if present, else ask what. Transitive: food * ok, some things lose appetite, rest are ridiculous. */ -{ switch (obj) { case INTRANSITIVE: if (!HERE(FOOD)) @@ -626,16 +627,18 @@ static phase_codes_t eat(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static phase_codes_t extinguish(verb_t verb, obj_t obj) +static phase_codes_t extinguish(verb_t verb, obj_t obj) { /* Extinguish. Lamp, urn, dragon/volcano (nice try). */ -{ if (obj == INTRANSITIVE) { - if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) - obj = LAMP; - if (HERE(URN) && game.objects[URN].prop == URN_LIT) - obj = URN; - if (obj == INTRANSITIVE) - return GO_UNKNOWN; + if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) { + obj = LAMP; + } + if (HERE(URN) && game.objects[URN].prop == URN_LIT) { + obj = URN; + } + if (obj == INTRANSITIVE) { + return GO_UNKNOWN; + } } switch (obj) { @@ -662,26 +665,27 @@ static phase_codes_t extinguish(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static phase_codes_t feed(verb_t verb, obj_t obj) +static phase_codes_t feed(verb_t verb, obj_t obj) { /* Feed. If bird, no seed. Snake, dragon, troll: quip. If dwarf, make him * mad. Bear, special. */ -{ switch (obj) { case BIRD: rspeak(BIRD_PINING); break; case DRAGON: - if (game.objects[DRAGON].prop != DRAGON_BARS) - rspeak(RIDICULOUS_ATTEMPT); - else - rspeak(NOTHING_EDIBLE); + if (game.objects[DRAGON].prop != DRAGON_BARS) { + rspeak(RIDICULOUS_ATTEMPT); + } else { + rspeak(NOTHING_EDIBLE); + } break; case SNAKE: if (!game.closed && HERE(BIRD)) { DESTROY(BIRD); rspeak(BIRD_DEVOURED); - } else + } else { rspeak(NOTHING_EDIBLE); + } break; case TROLL: rspeak(TROLL_VICES); @@ -690,8 +694,9 @@ static phase_codes_t feed(verb_t verb, obj_t obj) if (HERE(FOOD)) { game.dflag += 2; rspeak(REALLY_MAD); - } else + } else { speak(actions[verb].message); + } break; case BEAR: if (game.objects[BEAR].prop == BEAR_DEAD) { @@ -704,17 +709,19 @@ static phase_codes_t feed(verb_t verb, obj_t obj) game.objects[AXE].fixed = IS_FREE; game.objects[AXE].prop = AXE_HERE; state_change(BEAR, SITTING_BEAR); - } else + } else { rspeak(NOTHING_EDIBLE); + } break; } speak(actions[verb].message); break; case OGRE: - if (HERE(FOOD)) - rspeak(OGRE_FULL); - else - speak(actions[verb].message); + if (HERE(FOOD)) { + rspeak(OGRE_FULL); + } else { + speak(actions[verb].message); + } break; default: rspeak(AM_GAME); @@ -722,10 +729,9 @@ static phase_codes_t feed(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -phase_codes_t fill(verb_t verb, obj_t obj) +phase_codes_t fill(verb_t verb, obj_t obj) { /* Fill. Bottle or urn must be empty, and liquid available. (Vase * is nasty.) */ -{ if (obj == VASE) { if (LIQLOC(game.loc) == NO_OBJECT) { rspeak(FILL_INVALID); @@ -793,14 +799,14 @@ phase_codes_t fill(verb_t verb, obj_t obj) state_change(BOTTLE, (LIQLOC(game.loc) == OIL) ? OIL_BOTTLE : WATER_BOTTLE); - if (TOTING(BOTTLE)) + if (TOTING(BOTTLE)) { game.objects[LIQUID()].place = CARRIED; + } return GO_CLEAROBJ; } -static phase_codes_t find(verb_t verb, obj_t obj) +static phase_codes_t find(verb_t verb, obj_t obj) { /* Find. Might be carrying it, or it might be here. Else give caveat. */ -{ if (TOTING(obj)) { rspeak(ALREADY_CARRYING); return GO_CLEAROBJ; @@ -822,9 +828,8 @@ static phase_codes_t find(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static phase_codes_t fly(verb_t verb, obj_t obj) +static phase_codes_t fly(verb_t verb, obj_t obj) { /* Fly. Snide remarks unless hovering rug is here. */ -{ if (obj == INTRANSITIVE) { if (!HERE(RUG)) { rspeak(FLAP_ARMS); @@ -865,9 +870,8 @@ static phase_codes_t fly(verb_t verb, obj_t obj) return GO_TERMINATE; } -static phase_codes_t inven(void) +static phase_codes_t inven(void) { /* Inventory. If object, treat same as find. Else report on current burden. */ -{ bool empty = true; for (obj_t i = 1; i <= NOBJECTS; i++) { if (i == BEAR || !TOTING(i)) @@ -885,9 +889,8 @@ static phase_codes_t inven(void) return GO_CLEAROBJ; } -static phase_codes_t light(verb_t verb, obj_t obj) +static phase_codes_t light(verb_t verb, obj_t obj) { /* Light. Applicable only to lamp and urn. */ -{ if (obj == INTRANSITIVE) { int selects = 0; if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_DARK && game.limit >= 0) { @@ -914,8 +917,9 @@ static phase_codes_t light(verb_t verb, obj_t obj) break; } state_change(LAMP, LAMP_BRIGHT); - if (game.wzdark) + if (game.wzdark) { return GO_TOP; + } break; default: speak(actions[verb].message); @@ -923,53 +927,61 @@ static phase_codes_t light(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static phase_codes_t listen(void) +static phase_codes_t listen(void) { /* Listen. Intransitive only. Print stuff based on object sound properties. */ -{ bool soundlatch = false; vocab_t sound = locations[game.loc].sound; if (sound != SILENT) { rspeak(sound); - if (!locations[game.loc].loud) + if (!locations[game.loc].loud) { rspeak(NO_MESSAGE); + } soundlatch = true; } for (obj_t i = 1; i <= NOBJECTS; i++) { - if (!HERE(i) || objects[i].sounds[0] == NULL || PROP_IS_STASHED_OR_UNSEEN(i)) - continue; + if (!HERE(i) || objects[i].sounds[0] == NULL || PROP_IS_STASHED_OR_UNSEEN(i)) { + continue; + } int mi = game.objects[i].prop; /* (ESR) Some unpleasant magic on object states here. Ideally * we'd have liked the bird to be a normal object that we can * use state_change() on; can't do it, because there are * actually two different series of per-state birdsounds * depending on whether player has drunk dragon's blood. */ - if (i == BIRD) + if (i == BIRD) { mi += 3 * game.blooded; + } pspeak(i, hear, true, mi, game.zzword); rspeak(NO_MESSAGE); - if (i == BIRD && mi == BIRD_ENDSTATE) + if (i == BIRD && mi == BIRD_ENDSTATE) { DESTROY(BIRD); + } soundlatch = true; } - if (!soundlatch) + if (!soundlatch) { rspeak(ALL_SILENT); + } return GO_CLEAROBJ; } -static phase_codes_t lock(verb_t verb, obj_t obj) +static phase_codes_t lock(verb_t verb, obj_t obj) { /* Lock, unlock, no object given. Assume various things if present. */ -{ if (obj == INTRANSITIVE) { - if (HERE(CLAM)) - obj = CLAM; - if (HERE(OYSTER)) - obj = OYSTER; - if (AT(DOOR)) - obj = DOOR; - if (AT(GRATE)) - obj = GRATE; - if (HERE(CHAIN)) - obj = CHAIN; + if (HERE(CLAM)) { + obj = CLAM; + } + if (HERE(OYSTER)) { + obj = OYSTER; + } + if (AT(DOOR)) { + obj = DOOR; + } + if (AT(GRATE)) { + obj = GRATE; + } + if (HERE(CHAIN)) { + obj = CHAIN; + } if (obj == INTRANSITIVE) { rspeak(NOTHING_LOCKED); return GO_CLEAROBJ; @@ -983,32 +995,35 @@ static phase_codes_t lock(verb_t verb, obj_t obj) case CHAIN: if (HERE(KEYS)) { return chain(verb); - } else + } else { rspeak(NO_KEYS); + } break; case GRATE: if (HERE(KEYS)) { if (game.closng) { rspeak(EXIT_CLOSED); - if (!game.panic) + if (!game.panic) { game.clock2 = PANICTIME; + } game.panic = true; } else { state_change(GRATE, (verb == LOCK) ? GRATE_CLOSED : GRATE_OPEN); } - } else + } else { rspeak(NO_KEYS); + } break; case CLAM: - if (verb == LOCK) - rspeak(HUH_MAN); - else if (TOTING(CLAM)) - rspeak(DROP_CLAM); - else if (!TOTING(TRIDENT)) - rspeak(CLAM_OPENER); - else { + if (verb == LOCK) { + rspeak(HUH_MAN); + } else if (TOTING(CLAM)) { + rspeak(DROP_CLAM); + } else if (!TOTING(TRIDENT)) { + rspeak(CLAM_OPENER); + } else { DESTROY(CLAM); drop(OYSTER, game.loc); drop(PEARL, LOC_CULDESAC); @@ -1016,14 +1031,15 @@ static phase_codes_t lock(verb_t verb, obj_t obj) } break; case OYSTER: - if (verb == LOCK) - rspeak(HUH_MAN); - else if (TOTING(OYSTER)) - rspeak(DROP_OYSTER); - else if (!TOTING(TRIDENT)) - rspeak(OYSTER_OPENER); - else - rspeak(OYSTER_OPENS); + if (verb == LOCK) { + rspeak(HUH_MAN); + } else if (TOTING(OYSTER)) { + rspeak(DROP_OYSTER); + } else if (!TOTING(TRIDENT)) { + rspeak(OYSTER_OPENER); + } else { + rspeak(OYSTER_OPENS); + } break; case DOOR: rspeak((game.objects[DOOR].prop == DOOR_UNRUSTED) ? OK_MAN : RUSTY_DOOR); @@ -1041,14 +1057,15 @@ static phase_codes_t lock(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static phase_codes_t pour(verb_t verb, obj_t obj) +static phase_codes_t pour(verb_t verb, obj_t obj) { /* Pour. If no object, or object is bottle, assume contents of bottle. * special tests for pouring water or oil on plant or rusty door. */ -{ - if (obj == BOTTLE || obj == INTRANSITIVE) - obj = LIQUID(); - if (obj == NO_OBJECT) - return GO_UNKNOWN; + if (obj == BOTTLE || obj == INTRANSITIVE) { + obj = LIQUID(); + } + if (obj == NO_OBJECT) { + return GO_UNKNOWN; + } if (!TOTING(obj)) { speak(actions[verb].message); return GO_CLEAROBJ; @@ -1058,8 +1075,9 @@ static phase_codes_t pour(verb_t verb, obj_t obj) rspeak(CANT_POUR); return GO_CLEAROBJ; } - if (HERE(URN) && game.objects[URN].prop == URN_EMPTY) + if (HERE(URN) && game.objects[URN].prop == URN_EMPTY) { return fill(verb, URN); + } game.objects[BOTTLE].prop = EMPTY_BOTTLE; game.objects[obj].place = LOC_NOWHERE; if (!(AT(PLANT) || AT(DOOR))) { @@ -1084,11 +1102,11 @@ static phase_codes_t pour(verb_t verb, obj_t obj) } } -static phase_codes_t quit(void) +static phase_codes_t quit(void) { /* Quit. Intransitive only. Verify intent and exit if that's what he wants. */ -{ - if (yes_or_no(arbitrary_messages[REALLY_QUIT], arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN])) - terminate(quitgame); + if (yes_or_no(arbitrary_messages[REALLY_QUIT], arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN])) { + terminate(quitgame); + } return GO_CLEAROBJ; } @@ -1098,11 +1116,13 @@ static phase_codes_t read(command_t command) if (command.obj == INTRANSITIVE) { command.obj = NO_OBJECT; for (int i = 1; i <= NOBJECTS; i++) { - if (HERE(i) && objects[i].texts[0] != NULL && !PROP_IS_STASHED(i)) - command.obj = command.obj * NOBJECTS + i; + if (HERE(i) && objects[i].texts[0] != NULL && !PROP_IS_STASHED(i)) { + command.obj = command.obj * NOBJECTS + i; + } } - if (command.obj > NOBJECTS || command.obj == NO_OBJECT || DARK(game.loc)) + if (command.obj > NOBJECTS || command.obj == NO_OBJECT || DARK(game.loc)) { return GO_UNKNOWN; + } } if (DARK(game.loc)) { @@ -1117,14 +1137,14 @@ static phase_codes_t read(command_t command) } } else if (objects[command.obj].texts[0] == NULL || PROP_IS_NOTFOUND(command.obj)) { speak(actions[command.verb].message); - } else + } else { pspeak(command.obj, study, true, game.objects[command.obj].prop); + } return GO_CLEAROBJ; } -static phase_codes_t reservoir(void) +static phase_codes_t reservoir(void) { /* Z'ZZZ (word gets recomputed at startup; different each game). */ -{ if (!AT(RESER) && game.loc != LOC_RESBOTTOM) { rspeak(NOTHING_HAPPENS); return GO_CLEAROBJ; @@ -1142,9 +1162,8 @@ static phase_codes_t reservoir(void) } } -static phase_codes_t rub(verb_t verb, obj_t obj) +static phase_codes_t rub(verb_t verb, obj_t obj) { /* Rub. Yields various snide remarks except for lit urn. */ -{ if (obj == URN && game.objects[URN].prop == URN_LIT) { DESTROY(URN); drop(AMBER, game.loc); @@ -1160,17 +1179,17 @@ static phase_codes_t rub(verb_t verb, obj_t obj) return GO_CLEAROBJ; } -static phase_codes_t say(command_t command) +static phase_codes_t say(command_t command) { /* Say. Echo WD2. Magic words override. */ -{ if (command.word[1].type == MOTION && (command.word[1].id == XYZZY || command.word[1].id == PLUGH || command.word[1].id == PLOVER)) { return GO_WORD2; } - if (command.word[1].type == ACTION && command.word[1].id == PART) + if (command.word[1].type == ACTION && command.word[1].id == PART) { return reservoir(); + } if (command.word[1].type == ACTION && (command.word[1].id == FEE || @@ -1192,12 +1211,11 @@ static phase_codes_t throw_support(vocab_t spk) return GO_MOVE; } -static phase_codes_t throwit(command_t command) +static phase_codes_t throwit(command_t command) { /* Throw. Same as discard unless axe. Then same as attack except * ignore bird, and if dwarf is present then one might be killed. * (Only way to do so!) Axe also special for dragon, bear, and * troll. Treasures special for troll. */ -{ if (!TOTING(command.obj)) { speak(actions[command.verb].message); return GO_CLEAROBJ; @@ -1218,16 +1236,18 @@ static phase_codes_t throwit(command_t command) command.obj = BEAR; return (feed(command.verb, command.obj)); } - if (command.obj != AXE) + if (command.obj != AXE) { return (discard(command.verb, command.obj)); - else { + } else { if (atdwrf(game.loc) <= 0) { if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) return throw_support(DRAGON_SCALES); - if (AT(TROLL)) - return throw_support(TROLL_RETURNS); - if (AT(OGRE)) + if (AT(TROLL)) { + return throw_support(TROLL_RETURNS); + } + if (AT(OGRE)) { return throw_support(OGRE_DODGE); + } if (HERE(BEAR) && game.objects[BEAR].prop == UNTAMED_BEAR) { /* This'll teach him to throw the axe at the bear! */ drop(AXE, game.loc); @@ -1253,9 +1273,8 @@ static phase_codes_t throwit(command_t command) } } -static phase_codes_t wake(verb_t verb, obj_t obj) +static phase_codes_t wake(verb_t verb, obj_t obj) { /* Wake. Only use is to disturb the dwarves. */ -{ if (obj != DWARF || !game.closed) { speak(actions[verb].message); return GO_CLEAROBJ; @@ -1265,9 +1284,8 @@ static phase_codes_t wake(verb_t verb, obj_t obj) } } -static phase_codes_t seed(verb_t verb, const char *arg) +static phase_codes_t seed(verb_t verb, const char *arg) { /* Set seed */ -{ int32_t seed = strtol(arg, NULL, 10); speak(actions[verb].message, seed); set_seed(seed); @@ -1275,17 +1293,15 @@ static phase_codes_t seed(verb_t verb, const char *arg) return GO_TOP; } -static phase_codes_t waste(verb_t verb, turn_t turns) +static phase_codes_t waste(verb_t verb, turn_t turns) { /* Burn turns */ -{ game.limit -= turns; speak(actions[verb].message, (int)game.limit); return GO_TOP; } -static phase_codes_t wave(verb_t verb, obj_t obj) +static phase_codes_t wave(verb_t verb, obj_t obj) { /* Wave. No effect unless waving rod at fissure or at bird. */ -{ if (obj != ROD || !TOTING(obj) || (!HERE(BIRD) && (game.closng || !AT(FISSURE)))) { speak(((!TOTING(obj)) && (obj != ROD || !TOTING(ROD2))) ? @@ -1325,11 +1341,10 @@ static phase_codes_t wave(verb_t verb, obj_t obj) } } -phase_codes_t action(command_t command) +phase_codes_t action(command_t command) { /* Analyse a verb. Remember what it was, go back for object if second word * unless verb is "say", which snarfs arbitrary second word. */ -{ /* Previously, actions that result in a message, but don't do anything * further were called "specials". Now they're handled here as normal * actions. If noaction is true, then we spit out the message and return */ @@ -1346,14 +1361,14 @@ phase_codes_t action(command_t command) * they are never actually dropped at any location, but might * be here inside the bottle or urn or as a feature of the * location. */ - if (HERE(command.obj)) - /* FALL THROUGH */; - else if (command.obj == DWARF && atdwrf(game.loc) > 0) - /* FALL THROUGH */; - else if (!game.closed && ((LIQUID() == command.obj && HERE(BOTTLE)) || - command.obj == LIQLOC(game.loc))) - /* FALL THROUGH */; - else if (command.obj == OIL && HERE(URN) && game.objects[URN].prop != URN_EMPTY) { + if (HERE(command.obj)) { + /* FALL THROUGH */; + } else if (command.obj == DWARF && atdwrf(game.loc) > 0) { + /* FALL THROUGH */; + } else if (!game.closed && ((LIQUID() == command.obj && HERE(BOTTLE)) || + command.obj == LIQLOC(game.loc))) { + /* FALL THROUGH */; + } else if (command.obj == OIL && HERE(URN) && game.objects[URN].prop != URN_EMPTY) { command.obj = URN; /* FALL THROUGH */; } else if (command.obj == PLANT && AT(PLANT2) && game.objects[PLANT2].prop != PLANT_THIRSTY) { @@ -1367,26 +1382,29 @@ phase_codes_t action(command_t command) command.obj = ROD2; /* FALL THROUGH */; } else if ((command.verb == FIND || - command.verb == INVENTORY) && (command.word[1].id == WORD_EMPTY || command.word[1].id == WORD_NOT_FOUND)) + command.verb == INVENTORY) && (command.word[1].id == WORD_EMPTY || command.word[1].id == WORD_NOT_FOUND)) { /* FALL THROUGH */; - else { + } else { sspeak(NO_SEE, command.word[0].raw); return GO_CLEAROBJ; } - if (command.verb != 0) + if (command.verb != 0) { command.part = transitive; + } } switch (command.part) { case intransitive: - if (command.word[1].raw[0] != '\0' && command.verb != SAY) - return GO_WORD2; - if (command.verb == SAY) - /* KEYS is not special, anything not NO_OBJECT or INTRANSITIVE - * will do here. We're preventing interpretation as an intransitive - * verb when the word is unknown. */ - command.obj = command.word[1].raw[0] != '\0' ? KEYS : NO_OBJECT; + if (command.word[1].raw[0] != '\0' && command.verb != SAY) { + return GO_WORD2; + } + if (command.verb == SAY) { + /* KEYS is not special, anything not NO_OBJECT or INTRANSITIVE + * will do here. We're preventing interpretation as an intransitive + * verb when the word is unknown. */ + command.obj = command.word[1].raw[0] != '\0' ? KEYS : NO_OBJECT; + } if (command.obj == NO_OBJECT || command.obj == INTRANSITIVE) { /* Analyse an intransitive verb (ie, no object given yet). */ switch (command.verb) { @@ -1522,10 +1540,9 @@ phase_codes_t action(command_t command) return rub(command.verb, command.obj); case THROW: return throwit(command); - case QUIT: { + case QUIT: speak(actions[command.verb].message); return GO_CLEAROBJ; - } case FIND: return find(command.verb, command.obj); case INVENTORY: @@ -1537,42 +1554,36 @@ phase_codes_t action(command_t command) case BLAST: blast(); return GO_CLEAROBJ; - case SCORE: { + case SCORE: speak(actions[command.verb].message); return GO_CLEAROBJ; - } case FEE: case FIE: case FOE: case FOO: - case FUM: { + case FUM: speak(actions[command.verb].message); return GO_CLEAROBJ; - } - case BRIEF: { + case BRIEF: speak(actions[command.verb].message); return GO_CLEAROBJ; - } case READ: return read(command); case BREAK: return vbreak(command.verb, command.obj); case WAKE: return wake(command.verb, command.obj); - case SAVE: { + case SAVE: speak(actions[command.verb].message); return GO_CLEAROBJ; - } - case RESUME: { + case RESUME: speak(actions[command.verb].message); return GO_CLEAROBJ; - } case FLY: return fly(command.verb, command.obj); - case LISTEN: { + case LISTEN: speak(actions[command.verb].message); return GO_CLEAROBJ; - } // LCOV_EXCL_START // This case should never happen - here only as placeholder case PART: @@ -1593,3 +1604,5 @@ phase_codes_t action(command_t command) BUG(SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN); // LCOV_EXCL_LINE } } + +// end diff --git a/init.c b/init.c index a620b2c..94c972d 100644 --- a/init.c +++ b/init.c @@ -56,8 +56,9 @@ int initialise(void) for (int i = 1; i <= NLOCATIONS; i++) { if (!(locations[i].description.big == 0 || tkey[i] == 0)) { int k = tkey[i]; - if (travel[k].motion == HERE) + if (travel[k].motion == HERE) { conditions[i] |= (1 << COND_FORCED); + } } } @@ -77,8 +78,9 @@ int initialise(void) for (int i = 1; i <= NOBJECTS; i++) { int k = NOBJECTS + 1 - i; game.objects[k].fixed = objects[k].fixd; - if (objects[k].plac != 0 && objects[k].fixd <= 0) + if (objects[k].plac != 0 && objects[k].fixd <= 0) { drop(k, objects[k].plac); + } } /* Treasure props are initially STATE_NOTFOUND, and are set to @@ -88,8 +90,9 @@ int initialise(void) for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { ++game.tally; - if (objects[treasure].inventory != 0) + if (objects[treasure].inventory != 0) { PROP_SET_NOT_FOUND(treasure); + } } } game.conds = setbit(COND_HBASE); diff --git a/main.c b/main.c index e0fdb69..fd0852f 100644 --- a/main.c +++ b/main.c @@ -38,8 +38,9 @@ static void sig_handler(int signo) } #if defined ADVENT_AUTOSAVE - if (signo == SIGHUP || signo == SIGTERM) + if (signo == SIGHUP || signo == SIGTERM) { autosave(); + } #endif exit(EXIT_FAILURE); } @@ -71,12 +72,14 @@ char *myreadline(const char *prompt) char *next = settings.argv[settings.optind++]; - if (settings.scriptfp != NULL && feof(settings.scriptfp)) + if (settings.scriptfp != NULL && feof(settings.scriptfp)) { fclose(settings.scriptfp); - if (strcmp(next, "-") == 0) + } + if (strcmp(next, "-") == 0) { settings.scriptfp = stdin; // LCOV_EXCL_LINE - else + } else { settings.scriptfp = fopen(next, "r"); + } } if (isatty(fileno(settings.scriptfp))) { @@ -102,10 +105,12 @@ static void checkhints(void) { if (conditions[game.loc] >= game.conds) { for (int hint = 0; hint < NHINTS; hint++) { - if (game.hints[hint].used) - continue; - if (!CNDBIT(game.loc, hint + 1 + COND_HBASE)) + if (game.hints[hint].used) { + continue; + } + if (!CNDBIT(game.loc, hint + 1 + COND_HBASE)) { game.hints[hint].lc = -1; + } ++game.hints[hint].lc; /* Come here if he's been int enough at required loc(s) for some * unused hint. */ @@ -115,17 +120,20 @@ static void checkhints(void) switch (hint) { case 0: /* cave */ - if (game.objects[GRATE].prop == GRATE_CLOSED && !HERE(KEYS)) - break; + if (game.objects[GRATE].prop == GRATE_CLOSED && !HERE(KEYS)) { + break; + } game.hints[hint].lc = 0; return; case 1: /* bird */ - if (game.objects[BIRD].place == game.loc && TOTING(ROD) && game.oldobj == BIRD) - break; + if (game.objects[BIRD].place == game.loc && TOTING(ROD) && game.oldobj == BIRD) { + break; + } return; case 2: /* snake */ - if (HERE(SNAKE) && !HERE(BIRD)) - break; + if (HERE(SNAKE) && !HERE(BIRD)) { + break; + } game.hints[hint].lc = 0; return; case 3: /* maze */ @@ -137,15 +145,17 @@ static void checkhints(void) game.hints[hint].lc = 0; return; case 4: /* dark */ - if (!PROP_IS_NOTFOUND(EMERALD) && PROP_IS_NOTFOUND(PYRAMID)) - break; + if (!PROP_IS_NOTFOUND(EMERALD) && PROP_IS_NOTFOUND(PYRAMID)) { + break; + } game.hints[hint].lc = 0; return; case 5: /* witt */ break; case 6: /* urn */ - if (game.dflag == 0) - break; + if (game.dflag == 0) { + break; + } game.hints[hint].lc = 0; return; case 7: /* woods */ @@ -160,12 +170,14 @@ static void checkhints(void) game.hints[hint].lc = 0; return; } - if (HERE(OGRE) && i == 0) + if (HERE(OGRE) && i == 0) { break; + } return; case 9: /* jade */ - if (game.tally == 1 && PROP_IS_STASHED_OR_UNSEEN(JADE)) - break; + if (game.tally == 1 && PROP_IS_STASHED_OR_UNSEEN(JADE)) { + break; + } game.hints[hint].lc = 0; return; default: // LCOV_EXCL_LINE @@ -175,12 +187,14 @@ static void checkhints(void) /* Fall through to hint display */ game.hints[hint].lc = 0; - if (!yes_or_no(hints[hint].question, arbitrary_messages[NO_MESSAGE], arbitrary_messages[OK_MAN])) + if (!yes_or_no(hints[hint].question, arbitrary_messages[NO_MESSAGE], arbitrary_messages[OK_MAN])) { return; + } rspeak(HINT_COST, hints[hint].penalty, hints[hint].penalty); game.hints[hint].used = yes_or_no(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]); - if (game.hints[hint].used && game.limit > WARNTIME) + if (game.hints[hint].used && game.limit > WARNTIME) { game.limit += WARNTIME * hints[hint].penalty; + } } } } @@ -188,8 +202,9 @@ static void checkhints(void) static bool spotted_by_pirate(int i) { - if (i != PIRATE) - return false; + if (i != PIRATE) { + return false; + } /* The pirate's spotted him. Pirate leaves him alone once we've * found chest. K counts if a treasure is here. If not, and @@ -197,21 +212,24 @@ static bool spotted_by_pirate(int i) * that game.objexts,place[CHEST] = LOC_NOWHERE might mean that he's thrown * it to the troll, but in that case he's seen the chest * PROP_IS_FOUND(CHEST) == true. */ - if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST)) + if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST)) { return true; + } int snarfed = 0; bool movechest = false, robplayer = false; for (int treasure = 1; treasure <= NOBJECTS; treasure++) { - if (!objects[treasure].is_treasure) + if (!objects[treasure].is_treasure) { continue; + } /* Pirate won't take pyramid from plover room or dark * room (too easy!). */ if (treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || game.loc == objects[EMERALD].plac)) { continue; } - if (TOTING(treasure) || HERE(treasure)) + if (TOTING(treasure) || HERE(treasure)) { ++snarfed; + } if (TOTING(treasure)) { movechest = true; robplayer = true; @@ -233,20 +251,24 @@ static bool spotted_by_pirate(int i) } else { /* You might get a hint of the pirate's presence even if the * chest doesn't move... */ - if (game.dwarves[PIRATE].oldloc != game.dwarves[PIRATE].loc && PCT(20)) - rspeak(PIRATE_RUSTLES); + if (game.dwarves[PIRATE].oldloc != game.dwarves[PIRATE].loc && PCT(20)) { + rspeak(PIRATE_RUSTLES); + } } if (robplayer) { rspeak(PIRATE_POUNCES); for (int treasure = 1; treasure <= NOBJECTS; treasure++) { - if (!objects[treasure].is_treasure) - continue; + if (!objects[treasure].is_treasure) { + continue; + } if (!(treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || game.loc == objects[EMERALD].plac))) { - if (AT(treasure) && game.objects[treasure].fixed == IS_FREE) - carry(treasure, game.loc); - if (TOTING(treasure)) - drop(treasure, game.chloc); + if (AT(treasure) && game.objects[treasure].fixed == IS_FREE) { + carry(treasure, game.loc); + } + if (TOTING(treasure)) { + drop(treasure, game.chloc); + } } } } @@ -254,9 +276,8 @@ static bool spotted_by_pirate(int i) return true; } -static bool dwarfmove(void) +static bool dwarfmove(void) { /* Dwarves move. Return true if player survives, false if he dies. */ -{ int kk, stick, attack; loc_t tk[21]; @@ -272,8 +293,9 @@ static bool dwarfmove(void) * steal return toll, and dwarves can't meet the bear. Also * means dwarves won't follow him into dead end in maze, but * c'est la vie. They'll wait for him outside the dead end. */ - if (game.loc == LOC_NOWHERE || FORCED(game.loc) || CNDBIT(game.newloc, COND_NOARRR)) + if (game.loc == LOC_NOWHERE || FORCED(game.loc) || CNDBIT(game.newloc, COND_NOARRR)) { return true; + } /* Dwarf activity level ratchets up */ if (game.dflag == 0) { @@ -287,20 +309,23 @@ static bool dwarfmove(void) * replace him with the alternate. */ if (game.dflag == 1) { if (!INDEEP(game.loc) || - (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || PCT(85)))) + (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || PCT(85)))) { return true; + } game.dflag = 2; for (int i = 1; i <= 2; i++) { int j = 1 + randrange(NDWARVES - 1); - if (PCT(50)) + if (PCT(50)) { game.dwarves[j].loc = 0; + } } /* Alternate initial loc for dwarf, in case one of them * starts out on top of the adventurer. */ for (int i = 1; i <= NDWARVES - 1; i++) { - if (game.dwarves[i].loc == game.loc) - game.dwarves[i].loc = DALTLC; // + if (game.dwarves[i].loc == game.loc) { + game.dwarves[i].loc = DALTLC; + } game.dwarves[i].oldloc = game.dwarves[i].loc; } rspeak(DWARF_RAN); @@ -318,8 +343,9 @@ static bool dwarfmove(void) attack = 0; stick = 0; for (int i = 1; i <= NDWARVES; i++) { - if (game.dwarves[i].loc == 0) - continue; + if (game.dwarves[i].loc == 0) { + continue; + } /* Fill tk array with all the places this dwarf might go. */ unsigned int j = 1; kk = tkey[game.dwarves[i].loc]; @@ -351,38 +377,46 @@ static bool dwarfmove(void) } while (!travel[kk++].stop); tk[j] = game.dwarves[i].oldloc; - if (j >= 2) + if (j >= 2) { --j; + } j = 1 + randrange(j); game.dwarves[i].oldloc = game.dwarves[i].loc; game.dwarves[i].loc = tk[j]; game.dwarves[i].seen = (game.dwarves[i].seen && INDEEP(game.loc)) || (game.dwarves[i].loc == game.loc || game.dwarves[i].oldloc == game.loc); - if (!game.dwarves[i].seen) + if (!game.dwarves[i].seen) { continue; + } game.dwarves[i].loc = game.loc; - if (spotted_by_pirate(i)) + if (spotted_by_pirate(i)) { continue; + } /* This threatening little dwarf is in the room with him! */ ++game.dtotal; if (game.dwarves[i].oldloc == game.dwarves[i].loc) { ++attack; - if (game.knfloc >= LOC_NOWHERE) + if (game.knfloc >= LOC_NOWHERE) { game.knfloc = game.loc; - if (randrange(1000) < 95 * (game.dflag - 2)) + } + if (randrange(1000) < 95 * (game.dflag - 2)) { ++stick; + } } } /* Now we know what's happening. Let's tell the poor sucker about it. */ - if (game.dtotal == 0) + if (game.dtotal == 0) { return true; + } rspeak(game.dtotal == 1 ? DWARF_SINGLE : DWARF_PACK, game.dtotal); - if (attack == 0) + if (attack == 0) { return true; - if (game.dflag == 2) + } + if (game.dflag == 2) { game.dflag = 3; + } if (attack > 1) { rspeak(THROWN_KNIVES, attack); rspeak(stick > 1 ? MULTIPLE_HITS : (stick == 1 ? ONE_HIT : NONE_HIT), stick); @@ -390,8 +424,9 @@ static bool dwarfmove(void) rspeak(KNIFE_THROWN); rspeak(stick ? GETS_YOU : MISSES_YOU); } - if (stick == 0) + if (stick == 0) { return true; + } game.oldlc2 = game.loc; return false; } @@ -415,9 +450,8 @@ static bool dwarfmove(void) * building (and heaven help him if he tries to xyzzy back into the * cave without the lamp!). game.oldloc is zapped so he can't just * "retreat". */ -static void croak(void) +static void croak(void) { /* Okay, he's dead. Let's get on with it. */ -{ const char* query = obituaries[game.numdie].query; const char* yes_response = obituaries[game.numdie].yes_response; @@ -451,9 +485,8 @@ static void croak(void) } } -static void describe_location(void) +static void describe_location(void) { /* Describe the location to the user */ -{ const char* msg = locations[game.loc].description.small; if (MOD(game.locs[game.loc].abbrev, game.abbnum) == 0 || msg == NO_MESSAGE) @@ -463,8 +496,9 @@ static void describe_location(void) msg = arbitrary_messages[PITCH_DARK]; } - if (TOTING(BEAR)) + if (TOTING(BEAR)) { rspeak(TAME_BEAR); + } speak(msg); @@ -473,9 +507,8 @@ static void describe_location(void) } -static bool traveleq(int a, int b) +static bool traveleq(int a, int b) { /* Are two travel entries equal for purposes of skip after failed condition? */ -{ return (travel[a].condtype == travel[b].condtype) && (travel[a].condarg1 == travel[b].condarg1) && (travel[a].condarg2 == travel[b].condarg2) @@ -494,11 +527,12 @@ static void playermove(int motion) { int scratchloc, travel_entry = tkey[game.loc]; game.newloc = game.loc; - if (travel_entry == 0) + if (travel_entry == 0) { BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES); // LCOV_EXCL_LINE - if (motion == NUL) + } + if (motion == NUL) { return; - else if (motion == BACK) { + } else if (motion == BACK) { /* Handle "go back". Look for verb which goes from game.loc to * game.oldloc, or to game.oldlc2 If game.oldloc has forced-motion. * te_tmp saves entry -> forced loc -> previous loc. */ @@ -545,8 +579,9 @@ static void playermove(int motion) /* Look. Can't give more detail. Pretend it wasn't dark * (though it may now be dark) so he won't fall into a * pit while staring into the gloom. */ - if (game.detail < 3) - rspeak(NO_MORE_DETAIL); + if (game.detail < 3) { + rspeak(NO_MORE_DETAIL); + } ++game.detail; game.wzdark = false; game.locs[game.loc].abbrev = 0; @@ -626,8 +661,9 @@ static void playermove(int motion) else if (TOTING(condarg1) || (condtype == cond_with && AT(condarg1))) break; /* else fall through to check [not OBJ STATE] */ - } else if (game.objects[condarg1].prop != condarg2) + } else if (game.objects[condarg1].prop != condarg2) { break; + } /* We arrive here on conditional failure. * Skip to next non-matching destination */ @@ -644,8 +680,9 @@ static void playermove(int motion) /* Found an eligible rule, now execute it */ enum desttype_t desttype = travel[travel_entry].desttype; game.newloc = travel[travel_entry].destval; - if (desttype == dest_goto) + if (desttype == dest_goto) { return; + } if (desttype == dest_speak) { /* Execute a speak rule */ @@ -710,8 +747,9 @@ static void playermove(int motion) game.newloc = objects[TROLL].plac + objects[TROLL].fixd - game.loc; if (game.objects[TROLL].prop == TROLL_UNPAID) game.objects[TROLL].prop = TROLL_PAIDONCE; - if (!TOTING(BEAR)) + if (!TOTING(BEAR)) { return; + } state_change(CHASM, BRIDGE_WRECKED); game.objects[TROLL].prop = TROLL_GONE; drop(BEAR, game.newloc); @@ -731,11 +769,11 @@ static void playermove(int motion) (false); } -static void lampcheck(void) +static void lampcheck(void) { /* Check game limit and lamp timers */ -{ - if (game.objects[LAMP].prop == LAMP_BRIGHT) - --game.limit; + if (game.objects[LAMP].prop == LAMP_BRIGHT) { + --game.limit; + } /* Another way we can force an end to things is by having the * lamp give out. When it gets close, we come here to warn him. @@ -752,30 +790,32 @@ static void lampcheck(void) * No tests ever passed the guard, and with the guard removed * the game hangs when the lamp limit is reached. */ - if (TOTING(BATTERY)) + if (TOTING(BATTERY)) { drop(BATTERY, game.loc); + } #endif game.limit += BATTERYLIFE; game.lmwarn = false; } else if (!game.lmwarn && HERE(LAMP)) { game.lmwarn = true; - if (game.objects[BATTERY].prop == DEAD_BATTERIES) + if (game.objects[BATTERY].prop == DEAD_BATTERIES) { rspeak(MISSING_BATTERIES); - else if (game.objects[BATTERY].place == LOC_NOWHERE) + } else if (game.objects[BATTERY].place == LOC_NOWHERE) { rspeak(LAMP_DIM); - else + } else { rspeak(GET_BATTERIES); + } } } if (game.limit == 0) { game.limit = -1; game.objects[LAMP].prop = LAMP_DARK; - if (HERE(LAMP)) + if (HERE(LAMP)) { rspeak(LAMP_OUT); + } } } -static bool closecheck(void) /* Handle the closing of the cave. The cave closes "clock1" turns * after the last treasure has been located (including the pirate's * chest, which may of course never show up). Note that the @@ -794,7 +834,7 @@ static bool closecheck(void) * separating him from all the treasures. Most of these problems * arise from the use of negative prop numbers to suppress the object * descriptions until he's actually moved the objects. */ -{ +static bool closecheck(void) { /* If a turn threshold has been met, apply penalties and tell * the player about it. */ for (int i = 0; i < NTHRESHOLDS; ++i) { @@ -805,8 +845,9 @@ static bool closecheck(void) } /* Don't tick game.clock1 unless well into cave (and not at Y2). */ - if (game.tally == 0 && INDEEP(game.loc) && game.loc != LOC_Y2) + if (game.tally == 0 && INDEEP(game.loc) && game.loc != LOC_Y2) { --game.clock1; + } /* When the first warning comes, we lock the grate, destroy * the bridge, kill all the dwarves (and the pirate), remove @@ -833,8 +874,9 @@ static bool closecheck(void) move(TROLL2, objects[TROLL].plac); move(TROLL2 + NOBJECTS, objects[TROLL].fixd); juggle(CHASM); - if (game.objects[BEAR].prop != BEAR_DEAD) + if (game.objects[BEAR].prop != BEAR_DEAD) { DESTROY(BEAR); + } game.objects[CHAIN].prop = CHAIN_HEAP; game.objects[CHAIN].fixed = IS_FREE; game.objects[AXE].prop = AXE_HERE; @@ -885,8 +927,9 @@ static bool closecheck(void) game.objects[MIRROR].fixed = LOC_SW; for (int i = 1; i <= NOBJECTS; i++) { - if (TOTING(i)) - DESTROY(i); + if (TOTING(i)) { + DESTROY(i); + } } rspeak(CAVE_CLOSED); @@ -898,7 +941,7 @@ static bool closecheck(void) return false; } -static void listobjects(void) +static void listobjects(void) { /* Print out descriptions of objects at this location. If * not closing and property value is negative, tally off * another treasure. Rug is special case; once seen, its @@ -906,29 +949,34 @@ static void listobjects(void) * Similarly for chain; game.prop is initially CHAINING_BEAR (locked to * bear). These hacks are because game.prop=0 is needed to * get full score. */ -{ if (!DARK(game.loc)) { ++game.locs[game.loc].abbrev; for (int i = game.locs[game.loc].atloc; i != 0; i = game.link[i]) { obj_t obj = i; - if (obj > NOBJECTS) + if (obj > NOBJECTS) { obj = obj - NOBJECTS; - if (obj == STEPS && TOTING(NUGGET)) + } + if (obj == STEPS && TOTING(NUGGET)) { continue; + } /* (ESR) Warning: it looks like you could get away with * running this code only on objects with the treasure * property set. Nope. There is mystery here. */ if (PROP_IS_STASHED_OR_UNSEEN(obj)) { - if (game.closed) - continue; + if (game.closed) { + continue; + } PROP_SET_FOUND(obj); - if (obj == RUG) + if (obj == RUG) { game.objects[RUG].prop = RUG_DRAGON; - if (obj == CHAIN) + } + if (obj == CHAIN) { game.objects[CHAIN].prop = CHAINING_BEAR; - if (obj == EGGS) + } + if (obj == EGGS) { game.seenbigwords = true; + } --game.tally; /* Note: There used to be a test here to see whether the * player had blown it so badly that he could never ever see @@ -946,16 +994,16 @@ static void listobjects(void) * (so goes the rationalisation). */ } int kk = game.objects[obj].prop; - if (obj == STEPS) + if (obj == STEPS) { kk = (game.loc == game.objects[STEPS].fixed) ? STEPS_UP : STEPS_DOWN; + } pspeak(obj, look, true, kk); } } } -static bool preprocess_command(command_t *command) /* Pre-processes a command input to see if we need to tease out a few specific cases: * - "enter water" or "enter stream": * weird specific case that gets the user wet, and then kicks us back to get another command @@ -972,13 +1020,14 @@ static bool preprocess_command(command_t *command) * * Returns true if pre-processing is complete, and we're ready to move to the primary command * processing, false otherwise. */ -{ +static bool preprocess_command(command_t *command) { if (command->word[0].type == MOTION && command->word[0].id == ENTER && (command->word[1].id == STREAM || command->word[1].id == WATER)) { - if (LIQLOC(game.loc) == WATER) - rspeak(FEET_WET); - else - rspeak(WHERE_QUERY); + if (LIQLOC(game.loc) == WATER) { + rspeak(FEET_WET); + } else { + rspeak(WHERE_QUERY); + } } else { if (command->word[0].type == OBJECT) { /* From OV to VO form */ @@ -1028,15 +1077,15 @@ static bool preprocess_command(command_t *command) return false; } -static bool do_move(void) +static bool do_move(void) { /* Actually execute the move to the new location and dwarf movement */ -{ /* Can't leave cave once it's closing (except by main office). */ if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) { rspeak(EXIT_CLOSED); game.newloc = game.loc; - if (!game.panic) + if (!game.panic) { game.clock2 = PANICTIME; + } game.panic = true; } @@ -1055,11 +1104,13 @@ static bool do_move(void) } game.loc = game.newloc; - if (!dwarfmove()) + if (!dwarfmove()) { croak(); + } - if (game.loc == LOC_NOWHERE) + if (game.loc == LOC_NOWHERE) { croak(); + } /* The easiest way to get killed is to fall into a pit in * pitch darkness. */ @@ -1073,9 +1124,8 @@ static bool do_move(void) return true; } -static bool do_command(void) +static bool do_command(void) { /* Get and execute a command */ -{ static command_t command; clear_command(&command); @@ -1101,8 +1151,9 @@ static bool do_command(void) * won't be described until they've been picked up * and put down separate from their respective * piles. */ - if ((PROP_IS_NOTFOUND(OYSTER) || PROP_IS_STASHED(OYSTER)) && TOTING(OYSTER)) - pspeak(OYSTER, look, true, 1); + if ((PROP_IS_NOTFOUND(OYSTER) || PROP_IS_STASHED(OYSTER)) && TOTING(OYSTER)) { + pspeak(OYSTER, look, true, 1); + } for (size_t i = 1; i <= NOBJECTS; i++) { if (TOTING(i) && (PROP_IS_NOTFOUND(i) || PROP_IS_STASHED(i))) game.objects[i].prop = PROP_STASHED(i); @@ -1112,8 +1163,9 @@ static bool do_command(void) /* Check to see if the room is dark. If the knife is here, * and it's dark, the knife permanently disappears */ game.wzdark = DARK(game.loc); - if (game.knfloc != LOC_NOWHERE && game.knfloc != game.loc) + if (game.knfloc != LOC_NOWHERE && game.knfloc != game.loc) { game.knfloc = LOC_NOWHERE; + } /* Check some for hints, get input from user, increment * turn, and pre-process commands. Keep going until @@ -1122,8 +1174,9 @@ static bool do_command(void) checkhints(); /* Get command input from user */ - if (!get_command_input(&command)) + if (!get_command_input(&command)) { return false; + } /* Every input, check "foobar" flag. If zero, nothing's going * on. If pos, make neg. If neg, he skipped a word, so make it @@ -1136,8 +1189,9 @@ static bool do_command(void) } /* check if game is closed, and exit if it is */ - if (closecheck() ) + if (closecheck()) { return true; + } /* loop until all words in command are processed */ while (command.state == PREPROCESSED ) { @@ -1152,12 +1206,14 @@ static bool do_command(void) /* Give user hints of shortcuts */ if (strncasecmp(command.word[0].raw, "west", sizeof("west")) == 0) { - if (++game.iwest == 10) - rspeak(W_IS_WEST); + if (++game.iwest == 10) { + rspeak(W_IS_WEST); + } } if (strncasecmp(command.word[0].raw, "go", sizeof("go")) == 0 && command.word[1].id != WORD_EMPTY) { - if (++game.igo == 10) - rspeak(GO_UNNEEDED); + if (++game.igo == 10) { + rspeak(GO_UNNEEDED); + } } switch (command.word[0].type) { @@ -1170,10 +1226,11 @@ static bool do_command(void) command.obj = command.word[0].id; break; case ACTION: - if (command.word[1].type == NUMERIC) - command.part = transitive; - else - command.part = intransitive; + if (command.word[1].type == NUMERIC) { + command.part = transitive; + } else { + command.part = intransitive; + } command.verb = command.word[0].id; break; case NUMERIC: @@ -1275,10 +1332,11 @@ int main(int argc, char *argv[]) break; // LCOV_EXCL_LINE case 'l': settings.logfp = fopen(optarg, "w"); - if (settings.logfp == NULL) + if (settings.logfp == NULL) { fprintf(stderr, "advent: can't open logfile %s for write\n", optarg); + } signal(SIGINT, sig_handler); break; case 'o': @@ -1295,10 +1353,11 @@ int main(int argc, char *argv[]) #elif !defined ADVENT_NOSAVE case 'r': rfp = fopen(optarg, "r"); - if (rfp == NULL) + if (rfp == NULL) { fprintf(stderr, "advent: can't open save file %s for read\n", optarg); + } break; #endif default: @@ -1331,8 +1390,9 @@ int main(int argc, char *argv[]) #if !defined ADVENT_NOSAVE if (!rfp) { game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); - if (game.novice) + if (game.novice) { game.limit = NOVICELIMIT; + } } else { restore(rfp); #if defined ADVENT_AUTOSAVE @@ -1354,18 +1414,21 @@ int main(int argc, char *argv[]) game.limit = NOVICELIMIT; #endif - if (settings.logfp) + if (settings.logfp) { fprintf(settings.logfp, "seed %d\n", seedval); + } /* interpret commands until EOF or interrupt */ for (;;) { // if we're supposed to move, move - if (!do_move()) - continue; + if (!do_move()) { + continue; + } - // get command - if (!do_command()) - break; + // get command + if (!do_command()) { + break; + } } /* show score and exit */ terminate(quitgame); diff --git a/score.c b/score.c index 1c9a397..473ec6a 100644 --- a/score.c +++ b/score.c @@ -10,10 +10,9 @@ static int mxscor; /* ugh..the price for having score() not exit. */ -int score(enum termination mode) +int score(enum termination mode) { /* mode is 'scoregame' if scoring, 'quitgame' if quitting, 'endgame' if died * or won */ -{ int score = 0; /* The present scoring algorithm is as follows: @@ -39,18 +38,23 @@ int score(enum termination mode) * Give the poor guy 2 points just for finding each treasure. */ mxscor = 0; for (int i = 1; i <= NOBJECTS; i++) { - if (!objects[i].is_treasure) - continue; + if (!objects[i].is_treasure) { + continue; + } if (objects[i].inventory != 0) { int k = 12; - if (i == CHEST) + if (i == CHEST) { k = 14; - if (i > CHEST) + } + if (i > CHEST) { k = 16; - if (!PROP_IS_STASHED(i) && !PROP_IS_NOTFOUND(i)) + } + if (!PROP_IS_STASHED(i) && !PROP_IS_NOTFOUND(i)) { score += 2; - if (game.objects[i].place == LOC_BUILDING && PROP_IS_FOUND(i)) + } + if (game.objects[i].place == LOC_BUILDING && PROP_IS_FOUND(i)) { score += k - 2; + } mxscor += k; } } @@ -63,30 +67,38 @@ int score(enum termination mode) * mundane exits or 133, 134, 135 if he blew it (so to speak). */ score += (NDEATHS - game.numdie) * 10; mxscor += NDEATHS * 10; - if (mode == endgame) + if (mode == endgame) { score += 4; + } mxscor += 4; - if (game.dflag != 0) + if (game.dflag != 0) { score += 25; + } mxscor += 25; - if (game.closng) + if (game.closng) { score += 25; + } mxscor += 25; if (game.closed) { - if (game.bonus == none) - score += 10; - if (game.bonus == splatter) - score += 25; - if (game.bonus == defeat) - score += 30; - if (game.bonus == victory) - score += 45; + if (game.bonus == none) { + score += 10; + } + if (game.bonus == splatter) { + score += 25; + } + if (game.bonus == defeat) { + score += 30; + } + if (game.bonus == victory) { + score += 45; + } } mxscor += 45; /* Did he come to Witt's End as he should? */ - if (game.objects[MAGAZINE].place == LOC_WITTSEND) + if (game.objects[MAGAZINE].place == LOC_WITTSEND) { score += 1; + } mxscor += 1; /* Round it off. */ @@ -95,13 +107,16 @@ int score(enum termination mode) /* Deduct for hints/turns/saves. Hints < 4 are special; see database desc. */ for (int i = 0; i < NHINTS; i++) { - if (game.hints[i].used) - score = score - hints[i].penalty; + if (game.hints[i].used) { + score = score - hints[i].penalty; + } } - if (game.novice) + if (game.novice) { score -= 5; - if (game.clshnt) + } + if (game.clshnt) { score -= 10; + } score = score - game.trnluz - game.saved; /* Return to score command if that's where we came from. */ @@ -112,18 +127,19 @@ int score(enum termination mode) return score; } -void terminate(enum termination mode) +void terminate(enum termination mode) { /* End of game. Let's tell him all about it. */ -{ int points = score(mode); #if defined ADVENT_AUTOSAVE autosave(); #endif - if (points + game.trnluz + 1 >= mxscor && game.trnluz != 0) + if (points + game.trnluz + 1 >= mxscor && game.trnluz != 0) { rspeak(TOOK_LONG); - if (points + game.saved + 1 >= mxscor && game.saved != 0) + } + if (points + game.saved + 1 >= mxscor && game.saved != 0) { rspeak(WITHOUT_SUSPENDS); + } rspeak(TOTAL_SCORE, points, mxscor, game.turns, game.turns); for (int i = 1; i <= (int)NCLASSES; i++) { if (classes[i].threshold >= points) { From be429016afc256ce6731867ffed6f2d6f2d876f2 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 27 Jan 2024 06:17:02 -0500 Subject: [PATCH 168/213] 1TBS reflow with clang-format. --- Makefile | 3 + actions.c | 2920 +++++++++++++++++++++++++------------------------- advent.h | 393 +++---- cheat.c | 154 ++- init.c | 141 ++- main.c | 2570 +++++++++++++++++++++++--------------------- misc.c | 1220 ++++++++++----------- saveresume.c | 414 +++---- score.c | 258 ++--- 9 files changed, 4137 insertions(+), 3936 deletions(-) diff --git a/Makefile b/Makefile index 49c909e..9c837d2 100644 --- a/Makefile +++ b/Makefile @@ -68,6 +68,9 @@ cheat: $(CHEAT_OBJS) dungeon.o check: advent cheat cd tests; $(MAKE) --quiet +reflow: + @clang-format --style="{IndentWidth: 8, UseTab: ForIndentation}" -i $$(find . -name "*.[ch]") + # Requires gcov, lcov, libasan6, and libubsan1 # The last two are Ubuntu names, might vary on other distributions. # After this, run your browser on coverage/open-adventure/index.html diff --git a/actions.c b/actions.c index fed70b9..97e5a48 100644 --- a/actions.c +++ b/actions.c @@ -5,1604 +5,1642 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include -#include -#include #include +#include +#include +#include #include "advent.h" static phase_codes_t fill(verb_t, obj_t); static phase_codes_t attack(command_t command) { -/* Attack. Assume target if unambiguous. "Throw" also links here. - * Attackable objects fall into two categories: enemies (snake, - * dwarf, etc.) and others (bird, clam, machine). Ambiguous if 2 - * enemies, or no enemies but 2 others. */ - verb_t verb = command.verb; - obj_t obj = command.obj; + /* Attack. Assume target if unambiguous. "Throw" also links here. + * Attackable objects fall into two categories: enemies (snake, + * dwarf, etc.) and others (bird, clam, machine). Ambiguous if 2 + * enemies, or no enemies but 2 others. */ + verb_t verb = command.verb; + obj_t obj = command.obj; - if (obj == INTRANSITIVE) { - int changes = 0; - if (atdwrf(game.loc) > 0) { - obj = DWARF; - ++changes; - } - if (HERE(SNAKE)) { - obj = SNAKE; - ++changes; - } - if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) { - obj = DRAGON; - ++changes; - } - if (AT(TROLL)) { - obj = TROLL; - ++changes; - } - if (AT(OGRE)) { - obj = OGRE; - ++changes; - } - if (HERE(BEAR) && game.objects[BEAR].prop == UNTAMED_BEAR) { - obj = BEAR; - ++changes; - } - /* check for low-priority targets */ - if (obj == INTRANSITIVE) { - /* Can't attack bird or machine by throwing axe. */ - if (HERE(BIRD) && verb != THROW) { - obj = BIRD; - ++changes; - } - if (HERE(VEND) && verb != THROW) { - obj = VEND; - ++changes; - } - /* Clam and oyster both treated as clam for intransitive case; - * no harm done. */ - if (HERE(CLAM) || HERE(OYSTER)) { - obj = CLAM; - ++changes; - } - } - if (changes >= 2) - return GO_UNKNOWN; - } - - if (obj == BIRD) { - if (game.closed) { - rspeak(UNHAPPY_BIRD); - } else { - DESTROY(BIRD); - rspeak(BIRD_DEAD); - } - return GO_CLEAROBJ; - } - if (obj == VEND) { - state_change(VEND, - game.objects[VEND].prop == VEND_BLOCKS ? VEND_UNBLOCKS : VEND_BLOCKS); - - return GO_CLEAROBJ; - } - - if (obj == BEAR) { - switch (game.objects[BEAR].prop) { - case UNTAMED_BEAR: - rspeak(BEAR_HANDS); - break; - case SITTING_BEAR: - rspeak(BEAR_CONFUSED); - break; - case CONTENTED_BEAR: - rspeak(BEAR_CONFUSED); - break; - case BEAR_DEAD: - rspeak(ALREADY_DEAD); - break; - } - return GO_CLEAROBJ; - } - if (obj == DRAGON && game.objects[DRAGON].prop == DRAGON_BARS) { - /* Fun stuff for dragon. If he insists on attacking it, win! - * Set game.prop to dead, move dragon to central loc (still - * fixed), move rug there (not fixed), and move him there, - * too. Then do a null motion to get new description. */ - rspeak(BARE_HANDS_QUERY); - if (!silent_yes_or_no()) { - speak(arbitrary_messages[NASTY_DRAGON]); - return GO_MOVE; - } - state_change(DRAGON, DRAGON_DEAD); - game.objects[RUG].prop = RUG_FLOOR; - /* Hardcoding LOC_SECRET5 as the dragon's death location is ugly. - * The way it was computed before was worse; it depended on the - * two dragon locations being LOC_SECRET4 and LOC_SECRET6 and - * LOC_SECRET5 being right between them. - */ - move(DRAGON + NOBJECTS, IS_FIXED); - move(RUG + NOBJECTS, IS_FREE); - move(DRAGON, LOC_SECRET5); - move(RUG, LOC_SECRET5); - drop(BLOOD, LOC_SECRET5); - for (obj_t i = 1; i <= NOBJECTS; i++) { - if (game.objects[i].place == objects[DRAGON].plac || - game.objects[i].place == objects[DRAGON].fixd) - move(i, LOC_SECRET5); - } - game.loc = LOC_SECRET5; - return GO_MOVE; - } - - if (obj == OGRE) { - rspeak(OGRE_DODGE); - if (atdwrf(game.loc) == 0) { - return GO_CLEAROBJ; + if (obj == INTRANSITIVE) { + int changes = 0; + if (atdwrf(game.loc) > 0) { + obj = DWARF; + ++changes; + } + if (HERE(SNAKE)) { + obj = SNAKE; + ++changes; + } + if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) { + obj = DRAGON; + ++changes; + } + if (AT(TROLL)) { + obj = TROLL; + ++changes; + } + if (AT(OGRE)) { + obj = OGRE; + ++changes; + } + if (HERE(BEAR) && game.objects[BEAR].prop == UNTAMED_BEAR) { + obj = BEAR; + ++changes; + } + /* check for low-priority targets */ + if (obj == INTRANSITIVE) { + /* Can't attack bird or machine by throwing axe. */ + if (HERE(BIRD) && verb != THROW) { + obj = BIRD; + ++changes; + } + if (HERE(VEND) && verb != THROW) { + obj = VEND; + ++changes; + } + /* Clam and oyster both treated as clam for intransitive + * case; no harm done. */ + if (HERE(CLAM) || HERE(OYSTER)) { + obj = CLAM; + ++changes; + } + } + if (changes >= 2) + return GO_UNKNOWN; } - rspeak(KNIFE_THROWN); - DESTROY(OGRE); - int dwarves = 0; - for (int i = 1; i < PIRATE; i++) { - if (game.dwarves[i].loc == game.loc) { - ++dwarves; - game.dwarves[i].loc = LOC_LONGWEST; - game.dwarves[i].seen = false; - } - } - rspeak((dwarves > 1) ? - OGRE_PANIC1 : - OGRE_PANIC2); - return GO_CLEAROBJ; - } - switch (obj) { - case INTRANSITIVE: - rspeak(NO_TARGET); - break; - case CLAM: - case OYSTER: - rspeak(SHELL_IMPERVIOUS); - break; - case SNAKE: - rspeak(SNAKE_WARNING); - break; - case DWARF: - if (game.closed) { - return GO_DWARFWAKE; - } - rspeak(BARE_HANDS_QUERY); - break; - case DRAGON: - rspeak(ALREADY_DEAD); - break; - case TROLL: - rspeak(ROCKY_TROLL); - break; - default: - speak(actions[verb].message); - } - return GO_CLEAROBJ; + if (obj == BIRD) { + if (game.closed) { + rspeak(UNHAPPY_BIRD); + } else { + DESTROY(BIRD); + rspeak(BIRD_DEAD); + } + return GO_CLEAROBJ; + } + if (obj == VEND) { + state_change(VEND, game.objects[VEND].prop == VEND_BLOCKS + ? VEND_UNBLOCKS + : VEND_BLOCKS); + + return GO_CLEAROBJ; + } + + if (obj == BEAR) { + switch (game.objects[BEAR].prop) { + case UNTAMED_BEAR: + rspeak(BEAR_HANDS); + break; + case SITTING_BEAR: + rspeak(BEAR_CONFUSED); + break; + case CONTENTED_BEAR: + rspeak(BEAR_CONFUSED); + break; + case BEAR_DEAD: + rspeak(ALREADY_DEAD); + break; + } + return GO_CLEAROBJ; + } + if (obj == DRAGON && game.objects[DRAGON].prop == DRAGON_BARS) { + /* Fun stuff for dragon. If he insists on attacking it, win! + * Set game.prop to dead, move dragon to central loc (still + * fixed), move rug there (not fixed), and move him there, + * too. Then do a null motion to get new description. */ + rspeak(BARE_HANDS_QUERY); + if (!silent_yes_or_no()) { + speak(arbitrary_messages[NASTY_DRAGON]); + return GO_MOVE; + } + state_change(DRAGON, DRAGON_DEAD); + game.objects[RUG].prop = RUG_FLOOR; + /* Hardcoding LOC_SECRET5 as the dragon's death location is + * ugly. The way it was computed before was worse; it depended + * on the two dragon locations being LOC_SECRET4 and LOC_SECRET6 + * and LOC_SECRET5 being right between them. + */ + move(DRAGON + NOBJECTS, IS_FIXED); + move(RUG + NOBJECTS, IS_FREE); + move(DRAGON, LOC_SECRET5); + move(RUG, LOC_SECRET5); + drop(BLOOD, LOC_SECRET5); + for (obj_t i = 1; i <= NOBJECTS; i++) { + if (game.objects[i].place == objects[DRAGON].plac || + game.objects[i].place == objects[DRAGON].fixd) + move(i, LOC_SECRET5); + } + game.loc = LOC_SECRET5; + return GO_MOVE; + } + + if (obj == OGRE) { + rspeak(OGRE_DODGE); + if (atdwrf(game.loc) == 0) { + return GO_CLEAROBJ; + } + rspeak(KNIFE_THROWN); + DESTROY(OGRE); + int dwarves = 0; + for (int i = 1; i < PIRATE; i++) { + if (game.dwarves[i].loc == game.loc) { + ++dwarves; + game.dwarves[i].loc = LOC_LONGWEST; + game.dwarves[i].seen = false; + } + } + rspeak((dwarves > 1) ? OGRE_PANIC1 : OGRE_PANIC2); + return GO_CLEAROBJ; + } + + switch (obj) { + case INTRANSITIVE: + rspeak(NO_TARGET); + break; + case CLAM: + case OYSTER: + rspeak(SHELL_IMPERVIOUS); + break; + case SNAKE: + rspeak(SNAKE_WARNING); + break; + case DWARF: + if (game.closed) { + return GO_DWARFWAKE; + } + rspeak(BARE_HANDS_QUERY); + break; + case DRAGON: + rspeak(ALREADY_DEAD); + break; + case TROLL: + rspeak(ROCKY_TROLL); + break; + default: + speak(actions[verb].message); + } + return GO_CLEAROBJ; } static phase_codes_t bigwords(vocab_t id) { -/* Only called on FEE FIE FOE FOO (AND FUM). Advance to next state if given - * in proper order. Look up foo in special section of vocab to determine which - * word we've got. Last word zips the eggs back to the giant room (unless - * already there). */ - int foobar = abs(game.foobar); + /* Only called on FEE FIE FOE FOO (AND FUM). Advance to next state if + * given in proper order. Look up foo in special section of vocab to + * determine which word we've got. Last word zips the eggs back to the + * giant room (unless already there). */ + int foobar = abs(game.foobar); - /* Only FEE can start a magic-word sequence. */ - if ((foobar == WORD_EMPTY) && (id == FIE || id == FOE || id == FOO || id == FUM)) { - rspeak(NOTHING_HAPPENS); - return GO_CLEAROBJ; - } - - if ((foobar == WORD_EMPTY && id == FEE) || - (foobar == FEE && id == FIE) || - (foobar == FIE && id == FOE) || - (foobar == FOE && id == FOO)) { - game.foobar = id; - if (id != FOO) { - rspeak(OK_MAN); - return GO_CLEAROBJ; - } - game.foobar = WORD_EMPTY; - if (game.objects[EGGS].place == objects[EGGS].plac || - (TOTING(EGGS) && game.loc == objects[EGGS].plac)) { - rspeak(NOTHING_HAPPENS); - return GO_CLEAROBJ; - } else { - /* Bring back troll if we steal the eggs back from him before - * crossing. */ - if (game.objects[EGGS].place == LOC_NOWHERE && game.objects[TROLL].place == LOC_NOWHERE - && game.objects[TROLL].prop == TROLL_UNPAID) - game.objects[TROLL].prop = TROLL_PAIDONCE; - if (HERE(EGGS)) { - pspeak(EGGS, look, true, EGGS_VANISHED); - } else if (game.loc == objects[EGGS].plac) { - pspeak(EGGS, look, true, EGGS_HERE); - } else { - pspeak(EGGS, look, true, EGGS_DONE); - } - move(EGGS, objects[EGGS].plac); - - return GO_CLEAROBJ; - } - } else { - /* Magic-word sequence was started but is incorrect */ - if (settings.oldstyle || game.seenbigwords) { - rspeak(START_OVER); - } else { - rspeak(WELL_POINTLESS); + /* Only FEE can start a magic-word sequence. */ + if ((foobar == WORD_EMPTY) && + (id == FIE || id == FOE || id == FOO || id == FUM)) { + rspeak(NOTHING_HAPPENS); + return GO_CLEAROBJ; + } + + if ((foobar == WORD_EMPTY && id == FEE) || + (foobar == FEE && id == FIE) || (foobar == FIE && id == FOE) || + (foobar == FOE && id == FOO)) { + game.foobar = id; + if (id != FOO) { + rspeak(OK_MAN); + return GO_CLEAROBJ; + } + game.foobar = WORD_EMPTY; + if (game.objects[EGGS].place == objects[EGGS].plac || + (TOTING(EGGS) && game.loc == objects[EGGS].plac)) { + rspeak(NOTHING_HAPPENS); + return GO_CLEAROBJ; + } else { + /* Bring back troll if we steal the eggs back from him + * before crossing. */ + if (game.objects[EGGS].place == LOC_NOWHERE && + game.objects[TROLL].place == LOC_NOWHERE && + game.objects[TROLL].prop == TROLL_UNPAID) + game.objects[TROLL].prop = TROLL_PAIDONCE; + if (HERE(EGGS)) { + pspeak(EGGS, look, true, EGGS_VANISHED); + } else if (game.loc == objects[EGGS].plac) { + pspeak(EGGS, look, true, EGGS_HERE); + } else { + pspeak(EGGS, look, true, EGGS_DONE); + } + move(EGGS, objects[EGGS].plac); + + return GO_CLEAROBJ; + } + } else { + /* Magic-word sequence was started but is incorrect */ + if (settings.oldstyle || game.seenbigwords) { + rspeak(START_OVER); + } else { + rspeak(WELL_POINTLESS); + } + game.foobar = WORD_EMPTY; + return GO_CLEAROBJ; } - game.foobar = WORD_EMPTY; - return GO_CLEAROBJ; - } } static void blast(void) { -/* Blast. No effect unless you've got dynamite, which is a neat trick! */ - if (PROP_IS_NOTFOUND(ROD2) || !game.closed) - rspeak(REQUIRES_DYNAMITE); - else { - if (HERE(ROD2)) { - game.bonus = splatter; - rspeak(SPLATTER_MESSAGE); - } else if (game.loc == LOC_NE) { - game.bonus = defeat; - rspeak(DEFEAT_MESSAGE); - } else { - game.bonus = victory; - rspeak(VICTORY_MESSAGE); - } - terminate(endgame); - } + /* Blast. No effect unless you've got dynamite, which is a neat trick! + */ + if (PROP_IS_NOTFOUND(ROD2) || !game.closed) + rspeak(REQUIRES_DYNAMITE); + else { + if (HERE(ROD2)) { + game.bonus = splatter; + rspeak(SPLATTER_MESSAGE); + } else if (game.loc == LOC_NE) { + game.bonus = defeat; + rspeak(DEFEAT_MESSAGE); + } else { + game.bonus = victory; + rspeak(VICTORY_MESSAGE); + } + terminate(endgame); + } } static phase_codes_t vbreak(verb_t verb, obj_t obj) { -/* Break. Only works for mirror in repository and, of course, the vase. */ - switch (obj) { - case MIRROR: - if (game.closed) { - state_change(MIRROR, MIRROR_BROKEN); - return GO_DWARFWAKE; - } else { - rspeak(TOO_FAR); - break; - } - case VASE: - if (game.objects[VASE].prop == VASE_WHOLE) { - if (TOTING(VASE)) - drop(VASE, game.loc); - state_change(VASE, VASE_BROKEN); - game.objects[VASE].fixed = IS_FIXED; - break; - } - /* FALLTHRU */ - default: - speak(actions[verb].message); - } - return (GO_CLEAROBJ); + /* Break. Only works for mirror in repository and, of course, the + * vase. */ + switch (obj) { + case MIRROR: + if (game.closed) { + state_change(MIRROR, MIRROR_BROKEN); + return GO_DWARFWAKE; + } else { + rspeak(TOO_FAR); + break; + } + case VASE: + if (game.objects[VASE].prop == VASE_WHOLE) { + if (TOTING(VASE)) + drop(VASE, game.loc); + state_change(VASE, VASE_BROKEN); + game.objects[VASE].fixed = IS_FIXED; + break; + } + /* FALLTHRU */ + default: + speak(actions[verb].message); + } + return (GO_CLEAROBJ); } static phase_codes_t brief(void) { -/* Brief. Intransitive only. Suppress full descriptions after first time. */ - game.abbnum = 10000; - game.detail = 3; - rspeak(BRIEF_CONFIRM); - return GO_CLEAROBJ; + /* Brief. Intransitive only. Suppress full descriptions after first + * time. */ + game.abbnum = 10000; + game.detail = 3; + rspeak(BRIEF_CONFIRM); + return GO_CLEAROBJ; } static phase_codes_t vcarry(verb_t verb, obj_t obj) { -/* Carry an object. Special cases for bird and cage (if bird in cage, can't - * take one without the other). Liquids also special, since they depend on - * status of bottle. Also various side effects, etc. */ - if (obj == INTRANSITIVE) { - /* Carry, no object given yet. OK if only one object present. */ - if (game.locs[game.loc].atloc == NO_OBJECT || - game.link[game.locs[game.loc].atloc] != 0 || - atdwrf(game.loc) > 0) { - return GO_UNKNOWN; + /* Carry an object. Special cases for bird and cage (if bird in cage, + * can't take one without the other). Liquids also special, since they + * depend on status of bottle. Also various side effects, etc. */ + if (obj == INTRANSITIVE) { + /* Carry, no object given yet. OK if only one object present. + */ + if (game.locs[game.loc].atloc == NO_OBJECT || + game.link[game.locs[game.loc].atloc] != 0 || + atdwrf(game.loc) > 0) { + return GO_UNKNOWN; + } + obj = game.locs[game.loc].atloc; } - obj = game.locs[game.loc].atloc; - } - if (TOTING(obj)) { - speak(actions[verb].message); - return GO_CLEAROBJ; - } + if (TOTING(obj)) { + speak(actions[verb].message); + return GO_CLEAROBJ; + } - if (obj == MESSAG) { - rspeak(REMOVE_MESSAGE); - DESTROY(MESSAG); - return GO_CLEAROBJ; - } + if (obj == MESSAG) { + rspeak(REMOVE_MESSAGE); + DESTROY(MESSAG); + return GO_CLEAROBJ; + } - if (game.objects[obj].fixed != IS_FREE) { - switch (obj) { - case PLANT: - /* Next guard tests whether plant is tiny or stashed */ - rspeak(game.objects[PLANT].prop <= PLANT_THIRSTY ? DEEP_ROOTS : YOU_JOKING); - break; - case BEAR: - rspeak( game.objects[BEAR].prop == SITTING_BEAR ? BEAR_CHAINED : YOU_JOKING); - break; - case CHAIN: - rspeak( game.objects[BEAR].prop != UNTAMED_BEAR ? STILL_LOCKED : YOU_JOKING); - break; - case RUG: - rspeak(game.objects[RUG].prop == RUG_HOVER ? RUG_HOVERS : YOU_JOKING); - break; - case URN: - rspeak(URN_NOBUDGE); - break; - case CAVITY: - rspeak(DOUGHNUT_HOLES); - break; - case BLOOD: - rspeak(FEW_DROPS); - break; - case SIGN: - rspeak(HAND_PASSTHROUGH); - break; - default: - rspeak(YOU_JOKING); - } - return GO_CLEAROBJ; - } + if (game.objects[obj].fixed != IS_FREE) { + switch (obj) { + case PLANT: + /* Next guard tests whether plant is tiny or stashed */ + rspeak(game.objects[PLANT].prop <= PLANT_THIRSTY + ? DEEP_ROOTS + : YOU_JOKING); + break; + case BEAR: + rspeak(game.objects[BEAR].prop == SITTING_BEAR + ? BEAR_CHAINED + : YOU_JOKING); + break; + case CHAIN: + rspeak(game.objects[BEAR].prop != UNTAMED_BEAR + ? STILL_LOCKED + : YOU_JOKING); + break; + case RUG: + rspeak(game.objects[RUG].prop == RUG_HOVER + ? RUG_HOVERS + : YOU_JOKING); + break; + case URN: + rspeak(URN_NOBUDGE); + break; + case CAVITY: + rspeak(DOUGHNUT_HOLES); + break; + case BLOOD: + rspeak(FEW_DROPS); + break; + case SIGN: + rspeak(HAND_PASSTHROUGH); + break; + default: + rspeak(YOU_JOKING); + } + return GO_CLEAROBJ; + } - if (obj == WATER || obj == OIL) { - if (!HERE(BOTTLE) || LIQUID() != obj) { - if (!TOTING(BOTTLE)) { - rspeak(NO_CONTAINER); - return GO_CLEAROBJ; - } - if (game.objects[BOTTLE].prop == EMPTY_BOTTLE) { - return (fill(verb, BOTTLE)); - } else { - rspeak(BOTTLE_FULL); - } - return GO_CLEAROBJ; - } - obj = BOTTLE; - } + if (obj == WATER || obj == OIL) { + if (!HERE(BOTTLE) || LIQUID() != obj) { + if (!TOTING(BOTTLE)) { + rspeak(NO_CONTAINER); + return GO_CLEAROBJ; + } + if (game.objects[BOTTLE].prop == EMPTY_BOTTLE) { + return (fill(verb, BOTTLE)); + } else { + rspeak(BOTTLE_FULL); + } + return GO_CLEAROBJ; + } + obj = BOTTLE; + } - if (game.holdng >= INVLIMIT) { - rspeak(CARRY_LIMIT); - return GO_CLEAROBJ; + if (game.holdng >= INVLIMIT) { + rspeak(CARRY_LIMIT); + return GO_CLEAROBJ; + } - } + if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && + !PROP_IS_STASHED(BIRD)) { + if (game.objects[BIRD].prop == BIRD_FOREST_UNCAGED) { + DESTROY(BIRD); + rspeak(BIRD_CRAP); + return GO_CLEAROBJ; + } + if (!TOTING(CAGE)) { + rspeak(CANNOT_CARRY); + return GO_CLEAROBJ; + } + if (TOTING(ROD)) { + rspeak(BIRD_EVADES); + return GO_CLEAROBJ; + } + game.objects[BIRD].prop = BIRD_CAGED; + } + if ((obj == BIRD || obj == CAGE) && + (game.objects[BIRD].prop == BIRD_CAGED || + PROP_STASHED(BIRD) == BIRD_CAGED)) { + /* expression maps BIRD to CAGE and CAGE to BIRD */ + carry(BIRD + CAGE - obj, game.loc); + } - if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && !PROP_IS_STASHED(BIRD)) { - if (game.objects[BIRD].prop == BIRD_FOREST_UNCAGED) { - DESTROY(BIRD); - rspeak(BIRD_CRAP); - return GO_CLEAROBJ; - } - if (!TOTING(CAGE)) { - rspeak(CANNOT_CARRY); - return GO_CLEAROBJ; - } - if (TOTING(ROD)) { - rspeak(BIRD_EVADES); - return GO_CLEAROBJ; - } - game.objects[BIRD].prop = BIRD_CAGED; - } - if ((obj == BIRD || obj == CAGE) && - (game.objects[BIRD].prop == BIRD_CAGED || PROP_STASHED(BIRD) == BIRD_CAGED)) { - /* expression maps BIRD to CAGE and CAGE to BIRD */ - carry(BIRD + CAGE - obj, game.loc); - } + carry(obj, game.loc); - carry(obj, game.loc); + if (obj == BOTTLE && LIQUID() != NO_OBJECT) { + game.objects[LIQUID()].place = CARRIED; + } - if (obj == BOTTLE && LIQUID() != NO_OBJECT) { - game.objects[LIQUID()].place = CARRIED; - } - - if (GSTONE(obj) && !PROP_IS_FOUND(obj)) { - PROP_SET_FOUND(obj); - game.objects[CAVITY].prop = CAVITY_EMPTY; - } - rspeak(OK_MAN); - return GO_CLEAROBJ; + if (GSTONE(obj) && !PROP_IS_FOUND(obj)) { + PROP_SET_FOUND(obj); + game.objects[CAVITY].prop = CAVITY_EMPTY; + } + rspeak(OK_MAN); + return GO_CLEAROBJ; } static int chain(verb_t verb) { -/* Do something to the bear's chain */ - if (verb != LOCK) { - if (game.objects[BEAR].prop == UNTAMED_BEAR) { - rspeak(BEAR_BLOCKS); - return GO_CLEAROBJ; - } - if (game.objects[CHAIN].prop == CHAIN_HEAP) { - rspeak(ALREADY_UNLOCKED); - return GO_CLEAROBJ; - } - game.objects[CHAIN].prop = CHAIN_HEAP; - game.objects[CHAIN].fixed = IS_FREE; - if (game.objects[BEAR].prop != BEAR_DEAD) - game.objects[BEAR].prop = CONTENTED_BEAR; + /* Do something to the bear's chain */ + if (verb != LOCK) { + if (game.objects[BEAR].prop == UNTAMED_BEAR) { + rspeak(BEAR_BLOCKS); + return GO_CLEAROBJ; + } + if (game.objects[CHAIN].prop == CHAIN_HEAP) { + rspeak(ALREADY_UNLOCKED); + return GO_CLEAROBJ; + } + game.objects[CHAIN].prop = CHAIN_HEAP; + game.objects[CHAIN].fixed = IS_FREE; + if (game.objects[BEAR].prop != BEAR_DEAD) + game.objects[BEAR].prop = CONTENTED_BEAR; - switch (game.objects[BEAR].prop) { - // LCOV_EXCL_START - case BEAR_DEAD: - /* Can't be reached until the bear can die in some way other - * than a bridge collapse. Leave in in case this changes, but - * exclude from coverage testing. */ - game.objects[BEAR].fixed = IS_FIXED; - break; - // LCOV_EXCL_STOP - default: - game.objects[BEAR].fixed = IS_FREE; - } - rspeak(CHAIN_UNLOCKED); - return GO_CLEAROBJ; - } + switch (game.objects[BEAR].prop) { + // LCOV_EXCL_START + case BEAR_DEAD: + /* Can't be reached until the bear can die in some way + * other than a bridge collapse. Leave in in case this + * changes, but exclude from coverage testing. */ + game.objects[BEAR].fixed = IS_FIXED; + break; + // LCOV_EXCL_STOP + default: + game.objects[BEAR].fixed = IS_FREE; + } + rspeak(CHAIN_UNLOCKED); + return GO_CLEAROBJ; + } - if (game.objects[CHAIN].prop != CHAIN_HEAP) { - rspeak(ALREADY_LOCKED); - return GO_CLEAROBJ; - } - if (game.loc != objects[CHAIN].plac) { - rspeak(NO_LOCKSITE); - return GO_CLEAROBJ; - } + if (game.objects[CHAIN].prop != CHAIN_HEAP) { + rspeak(ALREADY_LOCKED); + return GO_CLEAROBJ; + } + if (game.loc != objects[CHAIN].plac) { + rspeak(NO_LOCKSITE); + return GO_CLEAROBJ; + } - game.objects[CHAIN].prop = CHAIN_FIXED; + game.objects[CHAIN].prop = CHAIN_FIXED; - if (TOTING(CHAIN)) - drop(CHAIN, game.loc); - game.objects[CHAIN].fixed = IS_FIXED; + if (TOTING(CHAIN)) + drop(CHAIN, game.loc); + game.objects[CHAIN].fixed = IS_FIXED; - rspeak(CHAIN_LOCKED); - return GO_CLEAROBJ; + rspeak(CHAIN_LOCKED); + return GO_CLEAROBJ; } static phase_codes_t discard(verb_t verb, obj_t obj) { -/* Discard object. "Throw" also comes here for most objects. Special cases for - * bird (might attack snake or dragon) and cage (might contain bird) and vase. - * Drop coins at vending machine for extra batteries. */ - if (obj == ROD && !TOTING(ROD) && TOTING(ROD2)) { - obj = ROD2; - } - - if (!TOTING(obj)) { - speak(actions[verb].message); - return GO_CLEAROBJ; - } - - if (GSTONE(obj) && AT(CAVITY) && game.objects[CAVITY].prop != CAVITY_FULL) { - rspeak(GEM_FITS); - game.objects[obj].prop = STATE_IN_CAVITY; - game.objects[CAVITY].prop = CAVITY_FULL; - if (HERE(RUG) && ((obj == EMERALD && game.objects[RUG].prop != RUG_HOVER) || - (obj == RUBY && game.objects[RUG].prop == RUG_HOVER))) { - if (obj == RUBY) { - rspeak(RUG_SETTLES); - } else if (TOTING(RUG)) { - rspeak(RUG_WIGGLES); - } else { - rspeak(RUG_RISES); - } - if (!TOTING(RUG) || obj == RUBY) { - int k = (game.objects[RUG].prop == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER; - game.objects[RUG].prop = k; - if (k == RUG_HOVER) { - k = objects[SAPPH].plac; - } - move(RUG + NOBJECTS, k); - } - } - drop(obj, game.loc); - return GO_CLEAROBJ; - } - - if (obj == COINS && HERE(VEND)) { - DESTROY(COINS); - drop(BATTERY, game.loc); - pspeak(BATTERY, look, true, FRESH_BATTERIES); - return GO_CLEAROBJ; - } - - if (LIQUID() == obj) { - obj = BOTTLE; - } - if (obj == BOTTLE && LIQUID() != NO_OBJECT) { - game.objects[LIQUID()].place = LOC_NOWHERE; - } - - if (obj == BEAR && AT(TROLL)) { - state_change(TROLL, TROLL_GONE); - move(TROLL, LOC_NOWHERE); - move(TROLL + NOBJECTS, IS_FREE); - move(TROLL2, objects[TROLL].plac); - move(TROLL2 + NOBJECTS, objects[TROLL].fixd); - juggle(CHASM); - drop(obj, game.loc); - return GO_CLEAROBJ; - } - - if (obj == VASE) { - if (game.loc != objects[PILLOW].plac) { - state_change(VASE, AT(PILLOW) - ? VASE_WHOLE - : VASE_DROPPED); - if (game.objects[VASE].prop != VASE_WHOLE) { - game.objects[VASE].fixed = IS_FIXED; - } - drop(obj, game.loc); - return GO_CLEAROBJ; - } - } - - if (obj == CAGE && game.objects[BIRD].prop == BIRD_CAGED) { - drop(BIRD, game.loc); - } - - if (obj == BIRD) { - if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) { - rspeak(BIRD_BURNT); - DESTROY(BIRD); - return GO_CLEAROBJ; - } - if (HERE(SNAKE)) { - rspeak(BIRD_ATTACKS); - if (game.closed) { - return GO_DWARFWAKE; - } - DESTROY(SNAKE); - /* Set game.prop for use by travel options */ - game.objects[SNAKE].prop = SNAKE_CHASED; - } else { - rspeak(OK_MAN); + /* Discard object. "Throw" also comes here for most objects. Special + * cases for bird (might attack snake or dragon) and cage (might contain + * bird) and vase. Drop coins at vending machine for extra batteries. */ + if (obj == ROD && !TOTING(ROD) && TOTING(ROD2)) { + obj = ROD2; } - game.objects[BIRD].prop = FOREST(game.loc) ? BIRD_FOREST_UNCAGED : BIRD_UNCAGED; - drop(obj, game.loc); - return GO_CLEAROBJ; - } + if (!TOTING(obj)) { + speak(actions[verb].message); + return GO_CLEAROBJ; + } - rspeak(OK_MAN); - drop(obj, game.loc); - return GO_CLEAROBJ; + if (GSTONE(obj) && AT(CAVITY) && + game.objects[CAVITY].prop != CAVITY_FULL) { + rspeak(GEM_FITS); + game.objects[obj].prop = STATE_IN_CAVITY; + game.objects[CAVITY].prop = CAVITY_FULL; + if (HERE(RUG) && + ((obj == EMERALD && game.objects[RUG].prop != RUG_HOVER) || + (obj == RUBY && game.objects[RUG].prop == RUG_HOVER))) { + if (obj == RUBY) { + rspeak(RUG_SETTLES); + } else if (TOTING(RUG)) { + rspeak(RUG_WIGGLES); + } else { + rspeak(RUG_RISES); + } + if (!TOTING(RUG) || obj == RUBY) { + int k = (game.objects[RUG].prop == RUG_HOVER) + ? RUG_FLOOR + : RUG_HOVER; + game.objects[RUG].prop = k; + if (k == RUG_HOVER) { + k = objects[SAPPH].plac; + } + move(RUG + NOBJECTS, k); + } + } + drop(obj, game.loc); + return GO_CLEAROBJ; + } + + if (obj == COINS && HERE(VEND)) { + DESTROY(COINS); + drop(BATTERY, game.loc); + pspeak(BATTERY, look, true, FRESH_BATTERIES); + return GO_CLEAROBJ; + } + + if (LIQUID() == obj) { + obj = BOTTLE; + } + if (obj == BOTTLE && LIQUID() != NO_OBJECT) { + game.objects[LIQUID()].place = LOC_NOWHERE; + } + + if (obj == BEAR && AT(TROLL)) { + state_change(TROLL, TROLL_GONE); + move(TROLL, LOC_NOWHERE); + move(TROLL + NOBJECTS, IS_FREE); + move(TROLL2, objects[TROLL].plac); + move(TROLL2 + NOBJECTS, objects[TROLL].fixd); + juggle(CHASM); + drop(obj, game.loc); + return GO_CLEAROBJ; + } + + if (obj == VASE) { + if (game.loc != objects[PILLOW].plac) { + state_change(VASE, + AT(PILLOW) ? VASE_WHOLE : VASE_DROPPED); + if (game.objects[VASE].prop != VASE_WHOLE) { + game.objects[VASE].fixed = IS_FIXED; + } + drop(obj, game.loc); + return GO_CLEAROBJ; + } + } + + if (obj == CAGE && game.objects[BIRD].prop == BIRD_CAGED) { + drop(BIRD, game.loc); + } + + if (obj == BIRD) { + if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) { + rspeak(BIRD_BURNT); + DESTROY(BIRD); + return GO_CLEAROBJ; + } + if (HERE(SNAKE)) { + rspeak(BIRD_ATTACKS); + if (game.closed) { + return GO_DWARFWAKE; + } + DESTROY(SNAKE); + /* Set game.prop for use by travel options */ + game.objects[SNAKE].prop = SNAKE_CHASED; + } else { + rspeak(OK_MAN); + } + + game.objects[BIRD].prop = + FOREST(game.loc) ? BIRD_FOREST_UNCAGED : BIRD_UNCAGED; + drop(obj, game.loc); + return GO_CLEAROBJ; + } + + rspeak(OK_MAN); + drop(obj, game.loc); + return GO_CLEAROBJ; } static phase_codes_t drink(verb_t verb, obj_t obj) { -/* Drink. If no object, assume water and look for it here. If water is in - * the bottle, drink that, else must be at a water loc, so drink stream. */ - if (obj == INTRANSITIVE && LIQLOC(game.loc) != WATER && - (LIQUID() != WATER || !HERE(BOTTLE))) { - return GO_UNKNOWN; - } + /* Drink. If no object, assume water and look for it here. If water + * is in the bottle, drink that, else must be at a water loc, so drink + * stream. */ + if (obj == INTRANSITIVE && LIQLOC(game.loc) != WATER && + (LIQUID() != WATER || !HERE(BOTTLE))) { + return GO_UNKNOWN; + } - if (obj == BLOOD) { - DESTROY(BLOOD); - state_change(DRAGON, DRAGON_BLOODLESS); - game.blooded = true; - return GO_CLEAROBJ; - } + if (obj == BLOOD) { + DESTROY(BLOOD); + state_change(DRAGON, DRAGON_BLOODLESS); + game.blooded = true; + return GO_CLEAROBJ; + } - if (obj != INTRANSITIVE && obj != WATER) { - rspeak(RIDICULOUS_ATTEMPT); - return GO_CLEAROBJ; - } - if (LIQUID() == WATER && HERE(BOTTLE)) { - game.objects[WATER].place = LOC_NOWHERE; - state_change(BOTTLE, EMPTY_BOTTLE); - return GO_CLEAROBJ; - } + if (obj != INTRANSITIVE && obj != WATER) { + rspeak(RIDICULOUS_ATTEMPT); + return GO_CLEAROBJ; + } + if (LIQUID() == WATER && HERE(BOTTLE)) { + game.objects[WATER].place = LOC_NOWHERE; + state_change(BOTTLE, EMPTY_BOTTLE); + return GO_CLEAROBJ; + } - speak(actions[verb].message); - return GO_CLEAROBJ; + speak(actions[verb].message); + return GO_CLEAROBJ; } static phase_codes_t eat(verb_t verb, obj_t obj) { -/* Eat. Intransitive: assume food if present, else ask what. Transitive: food - * ok, some things lose appetite, rest are ridiculous. */ - switch (obj) { - case INTRANSITIVE: - if (!HERE(FOOD)) - return GO_UNKNOWN; - /* FALLTHRU */ - case FOOD: - DESTROY(FOOD); - rspeak(THANKS_DELICIOUS); - break; - case BIRD: - case SNAKE: - case CLAM: - case OYSTER: - case DWARF: - case DRAGON: - case TROLL: - case BEAR: - case OGRE: - rspeak(LOST_APPETITE); - break; - default: - speak(actions[verb].message); - } - return GO_CLEAROBJ; + /* Eat. Intransitive: assume food if present, else ask what. + * Transitive: food ok, some things lose appetite, rest are ridiculous. + */ + switch (obj) { + case INTRANSITIVE: + if (!HERE(FOOD)) + return GO_UNKNOWN; + /* FALLTHRU */ + case FOOD: + DESTROY(FOOD); + rspeak(THANKS_DELICIOUS); + break; + case BIRD: + case SNAKE: + case CLAM: + case OYSTER: + case DWARF: + case DRAGON: + case TROLL: + case BEAR: + case OGRE: + rspeak(LOST_APPETITE); + break; + default: + speak(actions[verb].message); + } + return GO_CLEAROBJ; } static phase_codes_t extinguish(verb_t verb, obj_t obj) { -/* Extinguish. Lamp, urn, dragon/volcano (nice try). */ - if (obj == INTRANSITIVE) { - if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) { - obj = LAMP; - } - if (HERE(URN) && game.objects[URN].prop == URN_LIT) { - obj = URN; - } + /* Extinguish. Lamp, urn, dragon/volcano (nice try). */ if (obj == INTRANSITIVE) { - return GO_UNKNOWN; + if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) { + obj = LAMP; + } + if (HERE(URN) && game.objects[URN].prop == URN_LIT) { + obj = URN; + } + if (obj == INTRANSITIVE) { + return GO_UNKNOWN; + } } - } - switch (obj) { - case URN: - if (game.objects[URN].prop != URN_EMPTY) { - state_change(URN, URN_DARK); - } else { - pspeak(URN, change, true, URN_DARK); - } - break; - case LAMP: - state_change(LAMP, LAMP_DARK); - rspeak(DARK(game.loc) ? - PITCH_DARK : - NO_MESSAGE); - break; - case DRAGON: - case VOLCANO: - rspeak(BEYOND_POWER); - break; - default: - speak(actions[verb].message); - } - return GO_CLEAROBJ; + switch (obj) { + case URN: + if (game.objects[URN].prop != URN_EMPTY) { + state_change(URN, URN_DARK); + } else { + pspeak(URN, change, true, URN_DARK); + } + break; + case LAMP: + state_change(LAMP, LAMP_DARK); + rspeak(DARK(game.loc) ? PITCH_DARK : NO_MESSAGE); + break; + case DRAGON: + case VOLCANO: + rspeak(BEYOND_POWER); + break; + default: + speak(actions[verb].message); + } + return GO_CLEAROBJ; } static phase_codes_t feed(verb_t verb, obj_t obj) { -/* Feed. If bird, no seed. Snake, dragon, troll: quip. If dwarf, make him - * mad. Bear, special. */ - switch (obj) { - case BIRD: - rspeak(BIRD_PINING); - break; - case DRAGON: - if (game.objects[DRAGON].prop != DRAGON_BARS) { - rspeak(RIDICULOUS_ATTEMPT); - } else { - rspeak(NOTHING_EDIBLE); + /* Feed. If bird, no seed. Snake, dragon, troll: quip. If dwarf, + * make him mad. Bear, special. */ + switch (obj) { + case BIRD: + rspeak(BIRD_PINING); + break; + case DRAGON: + if (game.objects[DRAGON].prop != DRAGON_BARS) { + rspeak(RIDICULOUS_ATTEMPT); + } else { + rspeak(NOTHING_EDIBLE); + } + break; + case SNAKE: + if (!game.closed && HERE(BIRD)) { + DESTROY(BIRD); + rspeak(BIRD_DEVOURED); + } else { + rspeak(NOTHING_EDIBLE); + } + break; + case TROLL: + rspeak(TROLL_VICES); + break; + case DWARF: + if (HERE(FOOD)) { + game.dflag += 2; + rspeak(REALLY_MAD); + } else { + speak(actions[verb].message); + } + break; + case BEAR: + if (game.objects[BEAR].prop == BEAR_DEAD) { + rspeak(RIDICULOUS_ATTEMPT); + break; + } + if (game.objects[BEAR].prop == UNTAMED_BEAR) { + if (HERE(FOOD)) { + DESTROY(FOOD); + game.objects[AXE].fixed = IS_FREE; + game.objects[AXE].prop = AXE_HERE; + state_change(BEAR, SITTING_BEAR); + } else { + rspeak(NOTHING_EDIBLE); + } + break; + } + speak(actions[verb].message); + break; + case OGRE: + if (HERE(FOOD)) { + rspeak(OGRE_FULL); + } else { + speak(actions[verb].message); + } + break; + default: + rspeak(AM_GAME); } - break; - case SNAKE: - if (!game.closed && HERE(BIRD)) { - DESTROY(BIRD); - rspeak(BIRD_DEVOURED); - } else { - rspeak(NOTHING_EDIBLE); - } - break; - case TROLL: - rspeak(TROLL_VICES); - break; - case DWARF: - if (HERE(FOOD)) { - game.dflag += 2; - rspeak(REALLY_MAD); - } else { - speak(actions[verb].message); - } - break; - case BEAR: - if (game.objects[BEAR].prop == BEAR_DEAD) { - rspeak(RIDICULOUS_ATTEMPT); - break; - } - if (game.objects[BEAR].prop == UNTAMED_BEAR) { - if (HERE(FOOD)) { - DESTROY(FOOD); - game.objects[AXE].fixed = IS_FREE; - game.objects[AXE].prop = AXE_HERE; - state_change(BEAR, SITTING_BEAR); - } else { - rspeak(NOTHING_EDIBLE); - } - break; - } - speak(actions[verb].message); - break; - case OGRE: - if (HERE(FOOD)) { - rspeak(OGRE_FULL); - } else { - speak(actions[verb].message); - } - break; - default: - rspeak(AM_GAME); - } - return GO_CLEAROBJ; + return GO_CLEAROBJ; } phase_codes_t fill(verb_t verb, obj_t obj) { -/* Fill. Bottle or urn must be empty, and liquid available. (Vase - * is nasty.) */ - if (obj == VASE) { - if (LIQLOC(game.loc) == NO_OBJECT) { - rspeak(FILL_INVALID); - return GO_CLEAROBJ; - } - if (!TOTING(VASE)) { - rspeak(ARENT_CARRYING); - return GO_CLEAROBJ; - } - rspeak(SHATTER_VASE); - game.objects[VASE].prop = VASE_BROKEN; - game.objects[VASE].fixed = IS_FIXED; - drop(VASE, game.loc); - return GO_CLEAROBJ; - } + /* Fill. Bottle or urn must be empty, and liquid available. (Vase + * is nasty.) */ + if (obj == VASE) { + if (LIQLOC(game.loc) == NO_OBJECT) { + rspeak(FILL_INVALID); + return GO_CLEAROBJ; + } + if (!TOTING(VASE)) { + rspeak(ARENT_CARRYING); + return GO_CLEAROBJ; + } + rspeak(SHATTER_VASE); + game.objects[VASE].prop = VASE_BROKEN; + game.objects[VASE].fixed = IS_FIXED; + drop(VASE, game.loc); + return GO_CLEAROBJ; + } - if (obj == URN) { - if (game.objects[URN].prop != URN_EMPTY) { - rspeak(FULL_URN); - return GO_CLEAROBJ; - } - if (!HERE(BOTTLE)) { - rspeak(FILL_INVALID); - return GO_CLEAROBJ; - } - int k = LIQUID(); - switch (k) { - case WATER: - game.objects[BOTTLE].prop = EMPTY_BOTTLE; - rspeak(WATER_URN); - break; - case OIL: - game.objects[URN].prop = URN_DARK; - game.objects[BOTTLE].prop = EMPTY_BOTTLE; - rspeak(OIL_URN); - break; - case NO_OBJECT: - default: - rspeak(FILL_INVALID); - return GO_CLEAROBJ; - } - game.objects[k].place = LOC_NOWHERE; - return GO_CLEAROBJ; - } - if (obj != INTRANSITIVE && obj != BOTTLE) { - speak(actions[verb].message); - return GO_CLEAROBJ; - } - if (obj == INTRANSITIVE && !HERE(BOTTLE)) - return GO_UNKNOWN; + if (obj == URN) { + if (game.objects[URN].prop != URN_EMPTY) { + rspeak(FULL_URN); + return GO_CLEAROBJ; + } + if (!HERE(BOTTLE)) { + rspeak(FILL_INVALID); + return GO_CLEAROBJ; + } + int k = LIQUID(); + switch (k) { + case WATER: + game.objects[BOTTLE].prop = EMPTY_BOTTLE; + rspeak(WATER_URN); + break; + case OIL: + game.objects[URN].prop = URN_DARK; + game.objects[BOTTLE].prop = EMPTY_BOTTLE; + rspeak(OIL_URN); + break; + case NO_OBJECT: + default: + rspeak(FILL_INVALID); + return GO_CLEAROBJ; + } + game.objects[k].place = LOC_NOWHERE; + return GO_CLEAROBJ; + } + if (obj != INTRANSITIVE && obj != BOTTLE) { + speak(actions[verb].message); + return GO_CLEAROBJ; + } + if (obj == INTRANSITIVE && !HERE(BOTTLE)) + return GO_UNKNOWN; - if (HERE(URN) && game.objects[URN].prop != URN_EMPTY) { - rspeak(URN_NOPOUR); - return GO_CLEAROBJ; - } - if (LIQUID() != NO_OBJECT) { - rspeak(BOTTLE_FULL); - return GO_CLEAROBJ; - } - if (LIQLOC(game.loc) == NO_OBJECT) { - rspeak(NO_LIQUID); - return GO_CLEAROBJ; - } + if (HERE(URN) && game.objects[URN].prop != URN_EMPTY) { + rspeak(URN_NOPOUR); + return GO_CLEAROBJ; + } + if (LIQUID() != NO_OBJECT) { + rspeak(BOTTLE_FULL); + return GO_CLEAROBJ; + } + if (LIQLOC(game.loc) == NO_OBJECT) { + rspeak(NO_LIQUID); + return GO_CLEAROBJ; + } - state_change(BOTTLE, (LIQLOC(game.loc) == OIL) - ? OIL_BOTTLE - : WATER_BOTTLE); - if (TOTING(BOTTLE)) { - game.objects[LIQUID()].place = CARRIED; - } - return GO_CLEAROBJ; + state_change(BOTTLE, + (LIQLOC(game.loc) == OIL) ? OIL_BOTTLE : WATER_BOTTLE); + if (TOTING(BOTTLE)) { + game.objects[LIQUID()].place = CARRIED; + } + return GO_CLEAROBJ; } static phase_codes_t find(verb_t verb, obj_t obj) { -/* Find. Might be carrying it, or it might be here. Else give caveat. */ - if (TOTING(obj)) { - rspeak(ALREADY_CARRYING); - return GO_CLEAROBJ; - } + /* Find. Might be carrying it, or it might be here. Else give caveat. + */ + if (TOTING(obj)) { + rspeak(ALREADY_CARRYING); + return GO_CLEAROBJ; + } - if (game.closed) { - rspeak(NEEDED_NEARBY); - return GO_CLEAROBJ; - } + if (game.closed) { + rspeak(NEEDED_NEARBY); + return GO_CLEAROBJ; + } - if (AT(obj) || (LIQUID() == obj && AT(BOTTLE)) || - obj == LIQLOC(game.loc) || (obj == DWARF && atdwrf(game.loc) > 0)) { - rspeak(YOU_HAVEIT); - return GO_CLEAROBJ; - } + if (AT(obj) || (LIQUID() == obj && AT(BOTTLE)) || + obj == LIQLOC(game.loc) || (obj == DWARF && atdwrf(game.loc) > 0)) { + rspeak(YOU_HAVEIT); + return GO_CLEAROBJ; + } - - speak(actions[verb].message); - return GO_CLEAROBJ; + speak(actions[verb].message); + return GO_CLEAROBJ; } static phase_codes_t fly(verb_t verb, obj_t obj) { -/* Fly. Snide remarks unless hovering rug is here. */ - if (obj == INTRANSITIVE) { - if (!HERE(RUG)) { - rspeak(FLAP_ARMS); - return GO_CLEAROBJ; - } - if (game.objects[RUG].prop != RUG_HOVER) { - rspeak(RUG_NOTHING2); - return GO_CLEAROBJ; - } - obj = RUG; - } + /* Fly. Snide remarks unless hovering rug is here. */ + if (obj == INTRANSITIVE) { + if (!HERE(RUG)) { + rspeak(FLAP_ARMS); + return GO_CLEAROBJ; + } + if (game.objects[RUG].prop != RUG_HOVER) { + rspeak(RUG_NOTHING2); + return GO_CLEAROBJ; + } + obj = RUG; + } - if (obj != RUG) { - speak(actions[verb].message); - return GO_CLEAROBJ; - } - if (game.objects[RUG].prop != RUG_HOVER) { - rspeak(RUG_NOTHING1); - return GO_CLEAROBJ; - } + if (obj != RUG) { + speak(actions[verb].message); + return GO_CLEAROBJ; + } + if (game.objects[RUG].prop != RUG_HOVER) { + rspeak(RUG_NOTHING1); + return GO_CLEAROBJ; + } - if (game.loc == LOC_CLIFF) { - game.oldlc2 = game.oldloc; - game.oldloc = game.loc; - game.newloc = LOC_LEDGE; - rspeak(RUG_GOES); - } else if (game.loc == LOC_LEDGE) { - game.oldlc2 = game.oldloc; - game.oldloc = game.loc; - game.newloc = LOC_CLIFF; - rspeak(RUG_RETURNS); - } else { -// LCOV_EXCL_START - /* should never happen */ - rspeak(NOTHING_HAPPENS); -// LCOV_EXCL_STOP - } - return GO_TERMINATE; + if (game.loc == LOC_CLIFF) { + game.oldlc2 = game.oldloc; + game.oldloc = game.loc; + game.newloc = LOC_LEDGE; + rspeak(RUG_GOES); + } else if (game.loc == LOC_LEDGE) { + game.oldlc2 = game.oldloc; + game.oldloc = game.loc; + game.newloc = LOC_CLIFF; + rspeak(RUG_RETURNS); + } else { + // LCOV_EXCL_START + /* should never happen */ + rspeak(NOTHING_HAPPENS); + // LCOV_EXCL_STOP + } + return GO_TERMINATE; } static phase_codes_t inven(void) { -/* Inventory. If object, treat same as find. Else report on current burden. */ - bool empty = true; - for (obj_t i = 1; i <= NOBJECTS; i++) { - if (i == BEAR || !TOTING(i)) - continue; - if (empty) { - rspeak(NOW_HOLDING); - empty = false; - } - pspeak(i, touch, false, -1); - } - if (TOTING(BEAR)) - rspeak(TAME_BEAR); - if (empty) - rspeak(NO_CARRY); - return GO_CLEAROBJ; + /* Inventory. If object, treat same as find. Else report on current + * burden. */ + bool empty = true; + for (obj_t i = 1; i <= NOBJECTS; i++) { + if (i == BEAR || !TOTING(i)) + continue; + if (empty) { + rspeak(NOW_HOLDING); + empty = false; + } + pspeak(i, touch, false, -1); + } + if (TOTING(BEAR)) + rspeak(TAME_BEAR); + if (empty) + rspeak(NO_CARRY); + return GO_CLEAROBJ; } static phase_codes_t light(verb_t verb, obj_t obj) { -/* Light. Applicable only to lamp and urn. */ - if (obj == INTRANSITIVE) { - int selects = 0; - if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_DARK && game.limit >= 0) { - obj = LAMP; - selects++; - } - if (HERE(URN) && game.objects[URN].prop == URN_DARK) { - obj = URN; - selects++; - } - if (selects != 1) - return GO_UNKNOWN; - } - - switch (obj) { - case URN: - state_change(URN, game.objects[URN].prop == URN_EMPTY ? - URN_EMPTY : - URN_LIT); - break; - case LAMP: - if (game.limit < 0) { - rspeak(LAMP_OUT); - break; - } - state_change(LAMP, LAMP_BRIGHT); - if (game.wzdark) { - return GO_TOP; + /* Light. Applicable only to lamp and urn. */ + if (obj == INTRANSITIVE) { + int selects = 0; + if (HERE(LAMP) && game.objects[LAMP].prop == LAMP_DARK && + game.limit >= 0) { + obj = LAMP; + selects++; + } + if (HERE(URN) && game.objects[URN].prop == URN_DARK) { + obj = URN; + selects++; + } + if (selects != 1) + return GO_UNKNOWN; } - break; - default: - speak(actions[verb].message); - } - return GO_CLEAROBJ; + + switch (obj) { + case URN: + state_change(URN, game.objects[URN].prop == URN_EMPTY + ? URN_EMPTY + : URN_LIT); + break; + case LAMP: + if (game.limit < 0) { + rspeak(LAMP_OUT); + break; + } + state_change(LAMP, LAMP_BRIGHT); + if (game.wzdark) { + return GO_TOP; + } + break; + default: + speak(actions[verb].message); + } + return GO_CLEAROBJ; } static phase_codes_t listen(void) { -/* Listen. Intransitive only. Print stuff based on object sound properties. */ - bool soundlatch = false; - vocab_t sound = locations[game.loc].sound; - if (sound != SILENT) { - rspeak(sound); - if (!locations[game.loc].loud) { - rspeak(NO_MESSAGE); + /* Listen. Intransitive only. Print stuff based on object sound + * properties. */ + bool soundlatch = false; + vocab_t sound = locations[game.loc].sound; + if (sound != SILENT) { + rspeak(sound); + if (!locations[game.loc].loud) { + rspeak(NO_MESSAGE); + } + soundlatch = true; } - soundlatch = true; - } - for (obj_t i = 1; i <= NOBJECTS; i++) { - if (!HERE(i) || objects[i].sounds[0] == NULL || PROP_IS_STASHED_OR_UNSEEN(i)) { - continue; + for (obj_t i = 1; i <= NOBJECTS; i++) { + if (!HERE(i) || objects[i].sounds[0] == NULL || + PROP_IS_STASHED_OR_UNSEEN(i)) { + continue; + } + int mi = game.objects[i].prop; + /* (ESR) Some unpleasant magic on object states here. Ideally + * we'd have liked the bird to be a normal object that we can + * use state_change() on; can't do it, because there are + * actually two different series of per-state birdsounds + * depending on whether player has drunk dragon's blood. */ + if (i == BIRD) { + mi += 3 * game.blooded; + } + pspeak(i, hear, true, mi, game.zzword); + rspeak(NO_MESSAGE); + if (i == BIRD && mi == BIRD_ENDSTATE) { + DESTROY(BIRD); + } + soundlatch = true; } - int mi = game.objects[i].prop; - /* (ESR) Some unpleasant magic on object states here. Ideally - * we'd have liked the bird to be a normal object that we can - * use state_change() on; can't do it, because there are - * actually two different series of per-state birdsounds - * depending on whether player has drunk dragon's blood. */ - if (i == BIRD) { - mi += 3 * game.blooded; + if (!soundlatch) { + rspeak(ALL_SILENT); } - pspeak(i, hear, true, mi, game.zzword); - rspeak(NO_MESSAGE); - if (i == BIRD && mi == BIRD_ENDSTATE) { - DESTROY(BIRD); - } - soundlatch = true; - } - if (!soundlatch) { - rspeak(ALL_SILENT); - } - return GO_CLEAROBJ; + return GO_CLEAROBJ; } static phase_codes_t lock(verb_t verb, obj_t obj) { -/* Lock, unlock, no object given. Assume various things if present. */ - if (obj == INTRANSITIVE) { - if (HERE(CLAM)) { - obj = CLAM; - } - if (HERE(OYSTER)) { - obj = OYSTER; - } - if (AT(DOOR)) { - obj = DOOR; - } - if (AT(GRATE)) { - obj = GRATE; - } - if (HERE(CHAIN)) { - obj = CHAIN; - } - if (obj == INTRANSITIVE) { - rspeak(NOTHING_LOCKED); - return GO_CLEAROBJ; - } - } - - /* Lock, unlock object. Special stuff for opening clam/oyster - * and for chain. */ - - switch (obj) { - case CHAIN: - if (HERE(KEYS)) { - return chain(verb); - } else { - rspeak(NO_KEYS); - } - break; - case GRATE: - if (HERE(KEYS)) { - if (game.closng) { - rspeak(EXIT_CLOSED); - if (!game.panic) { - game.clock2 = PANICTIME; + /* Lock, unlock, no object given. Assume various things if present. */ + if (obj == INTRANSITIVE) { + if (HERE(CLAM)) { + obj = CLAM; + } + if (HERE(OYSTER)) { + obj = OYSTER; + } + if (AT(DOOR)) { + obj = DOOR; + } + if (AT(GRATE)) { + obj = GRATE; + } + if (HERE(CHAIN)) { + obj = CHAIN; + } + if (obj == INTRANSITIVE) { + rspeak(NOTHING_LOCKED); + return GO_CLEAROBJ; } - game.panic = true; - } else { - state_change(GRATE, (verb == LOCK) ? - GRATE_CLOSED : - GRATE_OPEN); - } - } else { - rspeak(NO_KEYS); } - break; - case CLAM: - if (verb == LOCK) { - rspeak(HUH_MAN); - } else if (TOTING(CLAM)) { - rspeak(DROP_CLAM); - } else if (!TOTING(TRIDENT)) { - rspeak(CLAM_OPENER); - } else { - DESTROY(CLAM); - drop(OYSTER, game.loc); - drop(PEARL, LOC_CULDESAC); - rspeak(PEARL_FALLS); - } - break; - case OYSTER: - if (verb == LOCK) { - rspeak(HUH_MAN); - } else if (TOTING(OYSTER)) { - rspeak(DROP_OYSTER); - } else if (!TOTING(TRIDENT)) { - rspeak(OYSTER_OPENER); - } else { - rspeak(OYSTER_OPENS); - } - break; - case DOOR: - rspeak((game.objects[DOOR].prop == DOOR_UNRUSTED) ? OK_MAN : RUSTY_DOOR); - break; - case CAGE: - rspeak( NO_LOCK); - break; - case KEYS: - rspeak(CANNOT_UNLOCK); - break; - default: - speak(actions[verb].message); - } - return GO_CLEAROBJ; + /* Lock, unlock object. Special stuff for opening clam/oyster + * and for chain. */ + + switch (obj) { + case CHAIN: + if (HERE(KEYS)) { + return chain(verb); + } else { + rspeak(NO_KEYS); + } + break; + case GRATE: + if (HERE(KEYS)) { + if (game.closng) { + rspeak(EXIT_CLOSED); + if (!game.panic) { + game.clock2 = PANICTIME; + } + game.panic = true; + } else { + state_change(GRATE, (verb == LOCK) + ? GRATE_CLOSED + : GRATE_OPEN); + } + } else { + rspeak(NO_KEYS); + } + break; + case CLAM: + if (verb == LOCK) { + rspeak(HUH_MAN); + } else if (TOTING(CLAM)) { + rspeak(DROP_CLAM); + } else if (!TOTING(TRIDENT)) { + rspeak(CLAM_OPENER); + } else { + DESTROY(CLAM); + drop(OYSTER, game.loc); + drop(PEARL, LOC_CULDESAC); + rspeak(PEARL_FALLS); + } + break; + case OYSTER: + if (verb == LOCK) { + rspeak(HUH_MAN); + } else if (TOTING(OYSTER)) { + rspeak(DROP_OYSTER); + } else if (!TOTING(TRIDENT)) { + rspeak(OYSTER_OPENER); + } else { + rspeak(OYSTER_OPENS); + } + break; + case DOOR: + rspeak((game.objects[DOOR].prop == DOOR_UNRUSTED) ? OK_MAN + : RUSTY_DOOR); + break; + case CAGE: + rspeak(NO_LOCK); + break; + case KEYS: + rspeak(CANNOT_UNLOCK); + break; + default: + speak(actions[verb].message); + } + + return GO_CLEAROBJ; } static phase_codes_t pour(verb_t verb, obj_t obj) { -/* Pour. If no object, or object is bottle, assume contents of bottle. - * special tests for pouring water or oil on plant or rusty door. */ - if (obj == BOTTLE || obj == INTRANSITIVE) { - obj = LIQUID(); - } - if (obj == NO_OBJECT) { - return GO_UNKNOWN; - } - if (!TOTING(obj)) { - speak(actions[verb].message); - return GO_CLEAROBJ; - } + /* Pour. If no object, or object is bottle, assume contents of bottle. + * special tests for pouring water or oil on plant or rusty door. */ + if (obj == BOTTLE || obj == INTRANSITIVE) { + obj = LIQUID(); + } + if (obj == NO_OBJECT) { + return GO_UNKNOWN; + } + if (!TOTING(obj)) { + speak(actions[verb].message); + return GO_CLEAROBJ; + } - if (obj != OIL && obj != WATER) { - rspeak(CANT_POUR); - return GO_CLEAROBJ; - } - if (HERE(URN) && game.objects[URN].prop == URN_EMPTY) { - return fill(verb, URN); - } - game.objects[BOTTLE].prop = EMPTY_BOTTLE; - game.objects[obj].place = LOC_NOWHERE; - if (!(AT(PLANT) || AT(DOOR))) { - rspeak(GROUND_WET); - return GO_CLEAROBJ; - } - if (!AT(DOOR)) { - if (obj == WATER) { - /* cycle through the three plant states */ - state_change(PLANT, MOD(game.objects[PLANT].prop + 1, 3)); - game.objects[PLANT2].prop = game.objects[PLANT].prop; - return GO_MOVE; - } else { - rspeak(SHAKING_LEAVES); - return GO_CLEAROBJ; - } - } else { - state_change(DOOR, (obj == OIL) ? - DOOR_UNRUSTED : - DOOR_RUSTED); - return GO_CLEAROBJ; - } + if (obj != OIL && obj != WATER) { + rspeak(CANT_POUR); + return GO_CLEAROBJ; + } + if (HERE(URN) && game.objects[URN].prop == URN_EMPTY) { + return fill(verb, URN); + } + game.objects[BOTTLE].prop = EMPTY_BOTTLE; + game.objects[obj].place = LOC_NOWHERE; + if (!(AT(PLANT) || AT(DOOR))) { + rspeak(GROUND_WET); + return GO_CLEAROBJ; + } + if (!AT(DOOR)) { + if (obj == WATER) { + /* cycle through the three plant states */ + state_change(PLANT, + MOD(game.objects[PLANT].prop + 1, 3)); + game.objects[PLANT2].prop = game.objects[PLANT].prop; + return GO_MOVE; + } else { + rspeak(SHAKING_LEAVES); + return GO_CLEAROBJ; + } + } else { + state_change(DOOR, (obj == OIL) ? DOOR_UNRUSTED : DOOR_RUSTED); + return GO_CLEAROBJ; + } } static phase_codes_t quit(void) { -/* Quit. Intransitive only. Verify intent and exit if that's what he wants. */ - if (yes_or_no(arbitrary_messages[REALLY_QUIT], arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN])) { - terminate(quitgame); - } - return GO_CLEAROBJ; + /* Quit. Intransitive only. Verify intent and exit if that's what he + * wants. */ + if (yes_or_no(arbitrary_messages[REALLY_QUIT], + arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN])) { + terminate(quitgame); + } + return GO_CLEAROBJ; } static phase_codes_t read(command_t command) /* Read. Print stuff based on objtxt. Oyster (?) is special case. */ { - if (command.obj == INTRANSITIVE) { - command.obj = NO_OBJECT; - for (int i = 1; i <= NOBJECTS; i++) { - if (HERE(i) && objects[i].texts[0] != NULL && !PROP_IS_STASHED(i)) { - command.obj = command.obj * NOBJECTS + i; - } - } - if (command.obj > NOBJECTS || command.obj == NO_OBJECT || DARK(game.loc)) { - return GO_UNKNOWN; + if (command.obj == INTRANSITIVE) { + command.obj = NO_OBJECT; + for (int i = 1; i <= NOBJECTS; i++) { + if (HERE(i) && objects[i].texts[0] != NULL && + !PROP_IS_STASHED(i)) { + command.obj = command.obj * NOBJECTS + i; + } + } + if (command.obj > NOBJECTS || command.obj == NO_OBJECT || + DARK(game.loc)) { + return GO_UNKNOWN; + } } - } - if (DARK(game.loc)) { - sspeak(NO_SEE, command.word[0].raw); - } else if (command.obj == OYSTER) { - if (!TOTING(OYSTER) || !game.closed) { - rspeak(DONT_UNDERSTAND); - } else if (!game.clshnt) { - game.clshnt = yes_or_no(arbitrary_messages[CLUE_QUERY], arbitrary_messages[WAYOUT_CLUE], arbitrary_messages[OK_MAN]); - } else { - pspeak(OYSTER, hear, true, 1); // Not really a sound, but oh well. - } - } else if (objects[command.obj].texts[0] == NULL || PROP_IS_NOTFOUND(command.obj)) { - speak(actions[command.verb].message); - } else { - pspeak(command.obj, study, true, game.objects[command.obj].prop); - } - return GO_CLEAROBJ; + if (DARK(game.loc)) { + sspeak(NO_SEE, command.word[0].raw); + } else if (command.obj == OYSTER) { + if (!TOTING(OYSTER) || !game.closed) { + rspeak(DONT_UNDERSTAND); + } else if (!game.clshnt) { + game.clshnt = yes_or_no(arbitrary_messages[CLUE_QUERY], + arbitrary_messages[WAYOUT_CLUE], + arbitrary_messages[OK_MAN]); + } else { + pspeak(OYSTER, hear, true, + 1); // Not really a sound, but oh well. + } + } else if (objects[command.obj].texts[0] == NULL || + PROP_IS_NOTFOUND(command.obj)) { + speak(actions[command.verb].message); + } else { + pspeak(command.obj, study, true, + game.objects[command.obj].prop); + } + return GO_CLEAROBJ; } static phase_codes_t reservoir(void) { -/* Z'ZZZ (word gets recomputed at startup; different each game). */ - if (!AT(RESER) && game.loc != LOC_RESBOTTOM) { - rspeak(NOTHING_HAPPENS); - return GO_CLEAROBJ; - } else { - state_change(RESER, - game.objects[RESER].prop == WATERS_PARTED ? WATERS_UNPARTED : WATERS_PARTED); - if (AT(RESER)) - return GO_CLEAROBJ; - else { - game.oldlc2 = game.loc; - game.newloc = LOC_NOWHERE; - rspeak(NOT_BRIGHT); - return GO_TERMINATE; - } - } + /* Z'ZZZ (word gets recomputed at startup; different each game). */ + if (!AT(RESER) && game.loc != LOC_RESBOTTOM) { + rspeak(NOTHING_HAPPENS); + return GO_CLEAROBJ; + } else { + state_change(RESER, game.objects[RESER].prop == WATERS_PARTED + ? WATERS_UNPARTED + : WATERS_PARTED); + if (AT(RESER)) + return GO_CLEAROBJ; + else { + game.oldlc2 = game.loc; + game.newloc = LOC_NOWHERE; + rspeak(NOT_BRIGHT); + return GO_TERMINATE; + } + } } static phase_codes_t rub(verb_t verb, obj_t obj) { -/* Rub. Yields various snide remarks except for lit urn. */ - if (obj == URN && game.objects[URN].prop == URN_LIT) { - DESTROY(URN); - drop(AMBER, game.loc); - game.objects[AMBER].prop = AMBER_IN_ROCK; - --game.tally; - drop(CAVITY, game.loc); - rspeak(URN_GENIES); - } else if (obj != LAMP) { - rspeak(PECULIAR_NOTHING); - } else { - speak(actions[verb].message); - } - return GO_CLEAROBJ; + /* Rub. Yields various snide remarks except for lit urn. */ + if (obj == URN && game.objects[URN].prop == URN_LIT) { + DESTROY(URN); + drop(AMBER, game.loc); + game.objects[AMBER].prop = AMBER_IN_ROCK; + --game.tally; + drop(CAVITY, game.loc); + rspeak(URN_GENIES); + } else if (obj != LAMP) { + rspeak(PECULIAR_NOTHING); + } else { + speak(actions[verb].message); + } + return GO_CLEAROBJ; } static phase_codes_t say(command_t command) { -/* Say. Echo WD2. Magic words override. */ - if (command.word[1].type == MOTION && - (command.word[1].id == XYZZY || - command.word[1].id == PLUGH || - command.word[1].id == PLOVER)) { - return GO_WORD2; - } - if (command.word[1].type == ACTION && command.word[1].id == PART) { - return reservoir(); - } + /* Say. Echo WD2. Magic words override. */ + if (command.word[1].type == MOTION && + (command.word[1].id == XYZZY || command.word[1].id == PLUGH || + command.word[1].id == PLOVER)) { + return GO_WORD2; + } + if (command.word[1].type == ACTION && command.word[1].id == PART) { + return reservoir(); + } - if (command.word[1].type == ACTION && - (command.word[1].id == FEE || - command.word[1].id == FIE || - command.word[1].id == FOE || - command.word[1].id == FOO || - command.word[1].id == FUM || - command.word[1].id == PART)) { - return bigwords(command.word[1].id); - } - sspeak(OKEY_DOKEY, command.word[1].raw); - return GO_CLEAROBJ; + if (command.word[1].type == ACTION && + (command.word[1].id == FEE || command.word[1].id == FIE || + command.word[1].id == FOE || command.word[1].id == FOO || + command.word[1].id == FUM || command.word[1].id == PART)) { + return bigwords(command.word[1].id); + } + sspeak(OKEY_DOKEY, command.word[1].raw); + return GO_CLEAROBJ; } -static phase_codes_t throw_support(vocab_t spk) -{ - rspeak(spk); - drop(AXE, game.loc); - return GO_MOVE; +static phase_codes_t throw_support(vocab_t spk) { + rspeak(spk); + drop(AXE, game.loc); + return GO_MOVE; } static phase_codes_t throwit(command_t command) { -/* Throw. Same as discard unless axe. Then same as attack except - * ignore bird, and if dwarf is present then one might be killed. - * (Only way to do so!) Axe also special for dragon, bear, and - * troll. Treasures special for troll. */ - if (!TOTING(command.obj)) { - speak(actions[command.verb].message); - return GO_CLEAROBJ; - } - if (objects[command.obj].is_treasure && AT(TROLL)) { - /* Snarf a treasure for the troll. */ - drop(command.obj, LOC_NOWHERE); - move(TROLL, LOC_NOWHERE); - move(TROLL + NOBJECTS, IS_FREE); - drop(TROLL2, objects[TROLL].plac); - drop(TROLL2 + NOBJECTS, objects[TROLL].fixd); - juggle(CHASM); - rspeak(TROLL_SATISFIED); - return GO_CLEAROBJ; - } - if (command.obj == FOOD && HERE(BEAR)) { - /* But throwing food is another story. */ - command.obj = BEAR; - return (feed(command.verb, command.obj)); - } - if (command.obj != AXE) { - return (discard(command.verb, command.obj)); - } else { - if (atdwrf(game.loc) <= 0) { - if (AT(DRAGON) && game.objects[DRAGON].prop == DRAGON_BARS) - return throw_support(DRAGON_SCALES); - if (AT(TROLL)) { - return throw_support(TROLL_RETURNS); - } - if (AT(OGRE)) { - return throw_support(OGRE_DODGE); - } - if (HERE(BEAR) && game.objects[BEAR].prop == UNTAMED_BEAR) { - /* This'll teach him to throw the axe at the bear! */ - drop(AXE, game.loc); - game.objects[AXE].fixed = IS_FIXED; - juggle(BEAR); - state_change(AXE, AXE_LOST); - return GO_CLEAROBJ; - } - command.obj = INTRANSITIVE; - return (attack(command)); - } + /* Throw. Same as discard unless axe. Then same as attack except + * ignore bird, and if dwarf is present then one might be killed. + * (Only way to do so!) Axe also special for dragon, bear, and + * troll. Treasures special for troll. */ + if (!TOTING(command.obj)) { + speak(actions[command.verb].message); + return GO_CLEAROBJ; + } + if (objects[command.obj].is_treasure && AT(TROLL)) { + /* Snarf a treasure for the troll. */ + drop(command.obj, LOC_NOWHERE); + move(TROLL, LOC_NOWHERE); + move(TROLL + NOBJECTS, IS_FREE); + drop(TROLL2, objects[TROLL].plac); + drop(TROLL2 + NOBJECTS, objects[TROLL].fixd); + juggle(CHASM); + rspeak(TROLL_SATISFIED); + return GO_CLEAROBJ; + } + if (command.obj == FOOD && HERE(BEAR)) { + /* But throwing food is another story. */ + command.obj = BEAR; + return (feed(command.verb, command.obj)); + } + if (command.obj != AXE) { + return (discard(command.verb, command.obj)); + } else { + if (atdwrf(game.loc) <= 0) { + if (AT(DRAGON) && + game.objects[DRAGON].prop == DRAGON_BARS) + return throw_support(DRAGON_SCALES); + if (AT(TROLL)) { + return throw_support(TROLL_RETURNS); + } + if (AT(OGRE)) { + return throw_support(OGRE_DODGE); + } + if (HERE(BEAR) && + game.objects[BEAR].prop == UNTAMED_BEAR) { + /* This'll teach him to throw the axe at the + * bear! */ + drop(AXE, game.loc); + game.objects[AXE].fixed = IS_FIXED; + juggle(BEAR); + state_change(AXE, AXE_LOST); + return GO_CLEAROBJ; + } + command.obj = INTRANSITIVE; + return (attack(command)); + } - if (randrange(NDWARVES + 1) < game.dflag) { - return throw_support(DWARF_DODGES); - } else { - int i = atdwrf(game.loc); - game.dwarves[i].seen = false; - game.dwarves[i].loc = LOC_NOWHERE; - return throw_support((++game.dkill == 1) ? - DWARF_SMOKE : - KILLED_DWARF); - } - } + if (randrange(NDWARVES + 1) < game.dflag) { + return throw_support(DWARF_DODGES); + } else { + int i = atdwrf(game.loc); + game.dwarves[i].seen = false; + game.dwarves[i].loc = LOC_NOWHERE; + return throw_support( + (++game.dkill == 1) ? DWARF_SMOKE : KILLED_DWARF); + } + } } static phase_codes_t wake(verb_t verb, obj_t obj) { -/* Wake. Only use is to disturb the dwarves. */ - if (obj != DWARF || !game.closed) { - speak(actions[verb].message); - return GO_CLEAROBJ; - } else { - rspeak(PROD_DWARF); - return GO_DWARFWAKE; - } + /* Wake. Only use is to disturb the dwarves. */ + if (obj != DWARF || !game.closed) { + speak(actions[verb].message); + return GO_CLEAROBJ; + } else { + rspeak(PROD_DWARF); + return GO_DWARFWAKE; + } } static phase_codes_t seed(verb_t verb, const char *arg) { -/* Set seed */ - int32_t seed = strtol(arg, NULL, 10); - speak(actions[verb].message, seed); - set_seed(seed); - --game.turns; - return GO_TOP; + /* Set seed */ + int32_t seed = strtol(arg, NULL, 10); + speak(actions[verb].message, seed); + set_seed(seed); + --game.turns; + return GO_TOP; } static phase_codes_t waste(verb_t verb, turn_t turns) { -/* Burn turns */ - game.limit -= turns; - speak(actions[verb].message, (int)game.limit); - return GO_TOP; + /* Burn turns */ + game.limit -= turns; + speak(actions[verb].message, (int)game.limit); + return GO_TOP; } static phase_codes_t wave(verb_t verb, obj_t obj) { -/* Wave. No effect unless waving rod at fissure or at bird. */ - if (obj != ROD || !TOTING(obj) || (!HERE(BIRD) && (game.closng || !AT(FISSURE)))) { - speak(((!TOTING(obj)) && (obj != ROD || - !TOTING(ROD2))) ? - arbitrary_messages[ARENT_CARRYING] : - actions[verb].message); - return GO_CLEAROBJ; - } + /* Wave. No effect unless waving rod at fissure or at bird. */ + if (obj != ROD || !TOTING(obj) || + (!HERE(BIRD) && (game.closng || !AT(FISSURE)))) { + speak(((!TOTING(obj)) && (obj != ROD || !TOTING(ROD2))) + ? arbitrary_messages[ARENT_CARRYING] + : actions[verb].message); + return GO_CLEAROBJ; + } - if (game.objects[BIRD].prop == BIRD_UNCAGED && game.loc == game.objects[STEPS].place - && PROP_IS_NOTFOUND(JADE)) { - drop(JADE, game.loc); - PROP_SET_FOUND(JADE); - --game.tally; - rspeak(NECKLACE_FLY); - return GO_CLEAROBJ; - } else { - if (game.closed) { - rspeak((game.objects[BIRD].prop == BIRD_CAGED) ? - CAGE_FLY : - FREE_FLY); - return GO_DWARFWAKE; - } - if (game.closng || !AT(FISSURE)) { - rspeak((game.objects[BIRD].prop == BIRD_CAGED) ? - CAGE_FLY : - FREE_FLY); - return GO_CLEAROBJ; - } - if (HERE(BIRD)) - rspeak((game.objects[BIRD].prop == BIRD_CAGED) ? - CAGE_FLY : - FREE_FLY); + if (game.objects[BIRD].prop == BIRD_UNCAGED && + game.loc == game.objects[STEPS].place && PROP_IS_NOTFOUND(JADE)) { + drop(JADE, game.loc); + PROP_SET_FOUND(JADE); + --game.tally; + rspeak(NECKLACE_FLY); + return GO_CLEAROBJ; + } else { + if (game.closed) { + rspeak((game.objects[BIRD].prop == BIRD_CAGED) + ? CAGE_FLY + : FREE_FLY); + return GO_DWARFWAKE; + } + if (game.closng || !AT(FISSURE)) { + rspeak((game.objects[BIRD].prop == BIRD_CAGED) + ? CAGE_FLY + : FREE_FLY); + return GO_CLEAROBJ; + } + if (HERE(BIRD)) + rspeak((game.objects[BIRD].prop == BIRD_CAGED) + ? CAGE_FLY + : FREE_FLY); - state_change(FISSURE, - game.objects[FISSURE].prop == BRIDGED ? UNBRIDGED : BRIDGED); - return GO_CLEAROBJ; - } + state_change(FISSURE, game.objects[FISSURE].prop == BRIDGED + ? UNBRIDGED + : BRIDGED); + return GO_CLEAROBJ; + } } phase_codes_t action(command_t command) { -/* Analyse a verb. Remember what it was, go back for object if second word - * unless verb is "say", which snarfs arbitrary second word. - */ - /* Previously, actions that result in a message, but don't do anything - * further were called "specials". Now they're handled here as normal - * actions. If noaction is true, then we spit out the message and return */ - if (actions[command.verb].noaction) { - speak(actions[command.verb].message); - return GO_CLEAROBJ; - } - - if (command.part == unknown) { - /* Analyse an object word. See if the thing is here, whether - * we've got a verb yet, and so on. Object must be here - * unless verb is "find" or "invent(ory)" (and no new verb - * yet to be analysed). Water and oil are also funny, since - * they are never actually dropped at any location, but might - * be here inside the bottle or urn or as a feature of the - * location. */ - if (HERE(command.obj)) { - /* FALL THROUGH */; - } else if (command.obj == DWARF && atdwrf(game.loc) > 0) { - /* FALL THROUGH */; - } else if (!game.closed && ((LIQUID() == command.obj && HERE(BOTTLE)) || - command.obj == LIQLOC(game.loc))) { - /* FALL THROUGH */; - } else if (command.obj == OIL && HERE(URN) && game.objects[URN].prop != URN_EMPTY) { - command.obj = URN; - /* FALL THROUGH */; - } else if (command.obj == PLANT && AT(PLANT2) && game.objects[PLANT2].prop != PLANT_THIRSTY) { - command.obj = PLANT2; - /* FALL THROUGH */; - } else if (command.obj == KNIFE && game.knfloc == game.loc) { - game.knfloc = -1; - rspeak(KNIVES_VANISH); - return GO_CLEAROBJ; - } else if (command.obj == ROD && HERE(ROD2)) { - command.obj = ROD2; - /* FALL THROUGH */; - } else if ((command.verb == FIND || - command.verb == INVENTORY) && (command.word[1].id == WORD_EMPTY || command.word[1].id == WORD_NOT_FOUND)) { - /* FALL THROUGH */; - } else { - sspeak(NO_SEE, command.word[0].raw); - return GO_CLEAROBJ; - } - - if (command.verb != 0) { - command.part = transitive; + /* Analyse a verb. Remember what it was, go back for object if second + * word unless verb is "say", which snarfs arbitrary second word. + */ + /* Previously, actions that result in a message, but don't do anything + * further were called "specials". Now they're handled here as normal + * actions. If noaction is true, then we spit out the message and return + */ + if (actions[command.verb].noaction) { + speak(actions[command.verb].message); + return GO_CLEAROBJ; } - } - switch (command.part) { - case intransitive: - if (command.word[1].raw[0] != '\0' && command.verb != SAY) { - return GO_WORD2; + if (command.part == unknown) { + /* Analyse an object word. See if the thing is here, whether + * we've got a verb yet, and so on. Object must be here + * unless verb is "find" or "invent(ory)" (and no new verb + * yet to be analysed). Water and oil are also funny, since + * they are never actually dropped at any location, but might + * be here inside the bottle or urn or as a feature of the + * location. */ + if (HERE(command.obj)) { + /* FALL THROUGH */; + } else if (command.obj == DWARF && atdwrf(game.loc) > 0) { + /* FALL THROUGH */; + } else if (!game.closed && + ((LIQUID() == command.obj && HERE(BOTTLE)) || + command.obj == LIQLOC(game.loc))) { + /* FALL THROUGH */; + } else if (command.obj == OIL && HERE(URN) && + game.objects[URN].prop != URN_EMPTY) { + command.obj = URN; + /* FALL THROUGH */; + } else if (command.obj == PLANT && AT(PLANT2) && + game.objects[PLANT2].prop != PLANT_THIRSTY) { + command.obj = PLANT2; + /* FALL THROUGH */; + } else if (command.obj == KNIFE && game.knfloc == game.loc) { + game.knfloc = -1; + rspeak(KNIVES_VANISH); + return GO_CLEAROBJ; + } else if (command.obj == ROD && HERE(ROD2)) { + command.obj = ROD2; + /* FALL THROUGH */; + } else if ((command.verb == FIND || + command.verb == INVENTORY) && + (command.word[1].id == WORD_EMPTY || + command.word[1].id == WORD_NOT_FOUND)) { + /* FALL THROUGH */; + } else { + sspeak(NO_SEE, command.word[0].raw); + return GO_CLEAROBJ; + } + + if (command.verb != 0) { + command.part = transitive; + } } - if (command.verb == SAY) { - /* KEYS is not special, anything not NO_OBJECT or INTRANSITIVE - * will do here. We're preventing interpretation as an intransitive - * verb when the word is unknown. */ - command.obj = command.word[1].raw[0] != '\0' ? KEYS : NO_OBJECT; + + switch (command.part) { + case intransitive: + if (command.word[1].raw[0] != '\0' && command.verb != SAY) { + return GO_WORD2; + } + if (command.verb == SAY) { + /* KEYS is not special, anything not NO_OBJECT or + * INTRANSITIVE will do here. We're preventing + * interpretation as an intransitive verb when the word + * is unknown. */ + command.obj = + command.word[1].raw[0] != '\0' ? KEYS : NO_OBJECT; + } + if (command.obj == NO_OBJECT || command.obj == INTRANSITIVE) { + /* Analyse an intransitive verb (ie, no object given + * yet). */ + switch (command.verb) { + case CARRY: + return vcarry(command.verb, INTRANSITIVE); + case DROP: + return GO_UNKNOWN; + case SAY: + return GO_UNKNOWN; + case UNLOCK: + return lock(command.verb, INTRANSITIVE); + case NOTHING: { + rspeak(OK_MAN); + return (GO_CLEAROBJ); + } + case LOCK: + return lock(command.verb, INTRANSITIVE); + case LIGHT: + return light(command.verb, INTRANSITIVE); + case EXTINGUISH: + return extinguish(command.verb, INTRANSITIVE); + case WAVE: + return GO_UNKNOWN; + case TAME: + return GO_UNKNOWN; + case GO: { + speak(actions[command.verb].message); + return GO_CLEAROBJ; + } + case ATTACK: + command.obj = INTRANSITIVE; + return attack(command); + case POUR: + return pour(command.verb, INTRANSITIVE); + case EAT: + return eat(command.verb, INTRANSITIVE); + case DRINK: + return drink(command.verb, INTRANSITIVE); + case RUB: + return GO_UNKNOWN; + case THROW: + return GO_UNKNOWN; + case QUIT: + return quit(); + case FIND: + return GO_UNKNOWN; + case INVENTORY: + return inven(); + case FEED: + return GO_UNKNOWN; + case FILL: + return fill(command.verb, INTRANSITIVE); + case BLAST: + blast(); + return GO_CLEAROBJ; + case SCORE: + score(scoregame); + return GO_CLEAROBJ; + case FEE: + case FIE: + case FOE: + case FOO: + case FUM: + return bigwords(command.word[0].id); + case BRIEF: + return brief(); + case READ: + command.obj = INTRANSITIVE; + return read(command); + case BREAK: + return GO_UNKNOWN; + case WAKE: + return GO_UNKNOWN; + case SAVE: + return suspend(); + case RESUME: + return resume(); + case FLY: + return fly(command.verb, INTRANSITIVE); + case LISTEN: + return listen(); + case PART: + return reservoir(); + case SEED: + case WASTE: + rspeak(NUMERIC_REQUIRED); + return GO_TOP; + default: // LCOV_EXCL_LINE + BUG(INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE + } + } + /* FALLTHRU */ + case transitive: + /* Analyse a transitive verb. */ + switch (command.verb) { + case CARRY: + return vcarry(command.verb, command.obj); + case DROP: + return discard(command.verb, command.obj); + case SAY: + return say(command); + case UNLOCK: + return lock(command.verb, command.obj); + case NOTHING: { + rspeak(OK_MAN); + return (GO_CLEAROBJ); + } + case LOCK: + return lock(command.verb, command.obj); + case LIGHT: + return light(command.verb, command.obj); + case EXTINGUISH: + return extinguish(command.verb, command.obj); + case WAVE: + return wave(command.verb, command.obj); + case TAME: { + speak(actions[command.verb].message); + return GO_CLEAROBJ; + } + case GO: { + speak(actions[command.verb].message); + return GO_CLEAROBJ; + } + case ATTACK: + return attack(command); + case POUR: + return pour(command.verb, command.obj); + case EAT: + return eat(command.verb, command.obj); + case DRINK: + return drink(command.verb, command.obj); + case RUB: + return rub(command.verb, command.obj); + case THROW: + return throwit(command); + case QUIT: + speak(actions[command.verb].message); + return GO_CLEAROBJ; + case FIND: + return find(command.verb, command.obj); + case INVENTORY: + return find(command.verb, command.obj); + case FEED: + return feed(command.verb, command.obj); + case FILL: + return fill(command.verb, command.obj); + case BLAST: + blast(); + return GO_CLEAROBJ; + case SCORE: + speak(actions[command.verb].message); + return GO_CLEAROBJ; + case FEE: + case FIE: + case FOE: + case FOO: + case FUM: + speak(actions[command.verb].message); + return GO_CLEAROBJ; + case BRIEF: + speak(actions[command.verb].message); + return GO_CLEAROBJ; + case READ: + return read(command); + case BREAK: + return vbreak(command.verb, command.obj); + case WAKE: + return wake(command.verb, command.obj); + case SAVE: + speak(actions[command.verb].message); + return GO_CLEAROBJ; + case RESUME: + speak(actions[command.verb].message); + return GO_CLEAROBJ; + case FLY: + return fly(command.verb, command.obj); + case LISTEN: + speak(actions[command.verb].message); + return GO_CLEAROBJ; + // LCOV_EXCL_START + // This case should never happen - here only as placeholder + case PART: + return reservoir(); + // LCOV_EXCL_STOP + case SEED: + return seed(command.verb, command.word[1].raw); + case WASTE: + return waste(command.verb, + (turn_t)atol(command.word[1].raw)); + default: // LCOV_EXCL_LINE + BUG(TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE + } + case unknown: + /* Unknown verb, couldn't deduce object - might need hint */ + sspeak(WHAT_DO, command.word[0].raw); + return GO_CHECKHINT; + default: // LCOV_EXCL_LINE + BUG(SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN); // LCOV_EXCL_LINE } - if (command.obj == NO_OBJECT || command.obj == INTRANSITIVE) { - /* Analyse an intransitive verb (ie, no object given yet). */ - switch (command.verb) { - case CARRY: - return vcarry(command.verb, INTRANSITIVE); - case DROP: - return GO_UNKNOWN; - case SAY: - return GO_UNKNOWN; - case UNLOCK: - return lock(command.verb, INTRANSITIVE); - case NOTHING: { - rspeak(OK_MAN); - return (GO_CLEAROBJ); - } - case LOCK: - return lock(command.verb, INTRANSITIVE); - case LIGHT: - return light(command.verb, INTRANSITIVE); - case EXTINGUISH: - return extinguish(command.verb, INTRANSITIVE); - case WAVE: - return GO_UNKNOWN; - case TAME: - return GO_UNKNOWN; - case GO: { - speak(actions[command.verb].message); - return GO_CLEAROBJ; - } - case ATTACK: - command.obj = INTRANSITIVE; - return attack(command); - case POUR: - return pour(command.verb, INTRANSITIVE); - case EAT: - return eat(command.verb, INTRANSITIVE); - case DRINK: - return drink(command.verb, INTRANSITIVE); - case RUB: - return GO_UNKNOWN; - case THROW: - return GO_UNKNOWN; - case QUIT: - return quit(); - case FIND: - return GO_UNKNOWN; - case INVENTORY: - return inven(); - case FEED: - return GO_UNKNOWN; - case FILL: - return fill(command.verb, INTRANSITIVE); - case BLAST: - blast(); - return GO_CLEAROBJ; - case SCORE: - score(scoregame); - return GO_CLEAROBJ; - case FEE: - case FIE: - case FOE: - case FOO: - case FUM: - return bigwords(command.word[0].id); - case BRIEF: - return brief(); - case READ: - command.obj = INTRANSITIVE; - return read(command); - case BREAK: - return GO_UNKNOWN; - case WAKE: - return GO_UNKNOWN; - case SAVE: - return suspend(); - case RESUME: - return resume(); - case FLY: - return fly(command.verb, INTRANSITIVE); - case LISTEN: - return listen(); - case PART: - return reservoir(); - case SEED: - case WASTE: - rspeak(NUMERIC_REQUIRED); - return GO_TOP; - default: // LCOV_EXCL_LINE - BUG(INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE - } - } - /* FALLTHRU */ - case transitive: - /* Analyse a transitive verb. */ - switch (command.verb) { - case CARRY: - return vcarry(command.verb, command.obj); - case DROP: - return discard(command.verb, command.obj); - case SAY: - return say(command); - case UNLOCK: - return lock(command.verb, command.obj); - case NOTHING: { - rspeak(OK_MAN); - return (GO_CLEAROBJ); - } - case LOCK: - return lock(command.verb, command.obj); - case LIGHT: - return light(command.verb, command.obj); - case EXTINGUISH: - return extinguish(command.verb, command.obj); - case WAVE: - return wave(command.verb, command.obj); - case TAME: { - speak(actions[command.verb].message); - return GO_CLEAROBJ; - } - case GO: { - speak(actions[command.verb].message); - return GO_CLEAROBJ; - } - case ATTACK: - return attack(command); - case POUR: - return pour(command.verb, command.obj); - case EAT: - return eat(command.verb, command.obj); - case DRINK: - return drink(command.verb, command.obj); - case RUB: - return rub(command.verb, command.obj); - case THROW: - return throwit(command); - case QUIT: - speak(actions[command.verb].message); - return GO_CLEAROBJ; - case FIND: - return find(command.verb, command.obj); - case INVENTORY: - return find(command.verb, command.obj); - case FEED: - return feed(command.verb, command.obj); - case FILL: - return fill(command.verb, command.obj); - case BLAST: - blast(); - return GO_CLEAROBJ; - case SCORE: - speak(actions[command.verb].message); - return GO_CLEAROBJ; - case FEE: - case FIE: - case FOE: - case FOO: - case FUM: - speak(actions[command.verb].message); - return GO_CLEAROBJ; - case BRIEF: - speak(actions[command.verb].message); - return GO_CLEAROBJ; - case READ: - return read(command); - case BREAK: - return vbreak(command.verb, command.obj); - case WAKE: - return wake(command.verb, command.obj); - case SAVE: - speak(actions[command.verb].message); - return GO_CLEAROBJ; - case RESUME: - speak(actions[command.verb].message); - return GO_CLEAROBJ; - case FLY: - return fly(command.verb, command.obj); - case LISTEN: - speak(actions[command.verb].message); - return GO_CLEAROBJ; - // LCOV_EXCL_START - // This case should never happen - here only as placeholder - case PART: - return reservoir(); - // LCOV_EXCL_STOP - case SEED: - return seed(command.verb, command.word[1].raw); - case WASTE: - return waste(command.verb, (turn_t)atol(command.word[1].raw)); - default: // LCOV_EXCL_LINE - BUG(TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE - } - case unknown: - /* Unknown verb, couldn't deduce object - might need hint */ - sspeak(WHAT_DO, command.word[0].raw); - return GO_CHECKHINT; - default: // LCOV_EXCL_LINE - BUG(SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN); // LCOV_EXCL_LINE - } } // end diff --git a/advent.h b/advent.h index 55518cb..b263645 100644 --- a/advent.h +++ b/advent.h @@ -4,11 +4,11 @@ * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ +#include +#include +#include #include #include -#include -#include -#include #include "dungeon.h" @@ -18,29 +18,30 @@ #define LCG_C 221587L #define LCG_M 1048576L -#define LINESIZE 1024 -#define TOKLEN 5 // # outputting characters in a token */ -#define PIRATE NDWARVES // must be NDWARVES-1 when zero-origin -#define DALTLC LOC_NUGGET // alternate dwarf location -#define INVLIMIT 7 // inventory limit (# of objects) -#define INTRANSITIVE -1 // illegal object number -#define GAMELIMIT 330 // base limit of turns -#define NOVICELIMIT 1000 // limit of turns for novice -#define WARNTIME 30 // late game starts at game.limit-this -#define FLASHTIME 50 // turns from first warning till blinding flash -#define PANICTIME 15 // time left after closing -#define BATTERYLIFE 2500 // turn limit increment from batteries -#define WORD_NOT_FOUND -1 // "Word not found" flag value for the vocab hash functions. -#define WORD_EMPTY 0 // "Word empty" flag value for the vocab hash functions -#define PIT_KILL_PROB 35 // Percentage probability of dying from fall in pit. -#define CARRIED -1 // Player is toting it -#define READ_MODE "rb" // b is not needed for POSIX but harmless -#define WRITE_MODE "wb" // b is not needed for POSIX but harmless +#define LINESIZE 1024 +#define TOKLEN 5 // # outputting characters in a token */ +#define PIRATE NDWARVES // must be NDWARVES-1 when zero-origin +#define DALTLC LOC_NUGGET // alternate dwarf location +#define INVLIMIT 7 // inventory limit (# of objects) +#define INTRANSITIVE -1 // illegal object number +#define GAMELIMIT 330 // base limit of turns +#define NOVICELIMIT 1000 // limit of turns for novice +#define WARNTIME 30 // late game starts at game.limit-this +#define FLASHTIME 50 // turns from first warning till blinding flash +#define PANICTIME 15 // time left after closing +#define BATTERYLIFE 2500 // turn limit increment from batteries +#define WORD_NOT_FOUND \ + -1 // "Word not found" flag value for the vocab hash functions. +#define WORD_EMPTY 0 // "Word empty" flag value for the vocab hash functions +#define PIT_KILL_PROB 35 // Percentage probability of dying from fall in pit. +#define CARRIED -1 // Player is toting it +#define READ_MODE "rb" // b is not needed for POSIX but harmless +#define WRITE_MODE "wb" // b is not needed for POSIX but harmless /* Special object-state values - integers > 0 are object-specific */ -#define STATE_NOTFOUND -1 // 'Not found" state of treasures -#define STATE_FOUND 0 // After discovered, before messed with -#define STATE_IN_CAVITY 1 // State value common to all gemstones +#define STATE_NOTFOUND -1 // 'Not found" state of treasures +#define STATE_FOUND 0 // After discovered, before messed with +#define STATE_IN_CAVITY 1 // State value common to all gemstones /* Special fixed object-state values - integers > 0 are location */ #define IS_FIXED -1 @@ -67,39 +68,45 @@ * and readable objects, notably the clam/oyster - but the code around * those test is difficult to read. */ -#define PROP_STASHIFY(n) (-1 - (n)) -#define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) -#define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) -#define PROP_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) -#define PROP_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) -#define PROP_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) -#define PROP_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) -#define PROP_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) -#define PROP_IS_INVALID(val) (val < -MAX_STATE - 1 || val > MAX_STATE) +#define PROP_STASHIFY(n) (-1 - (n)) +#define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) +#define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) +#define PROP_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) +#define PROP_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) +#define PROP_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) +#define PROP_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) +#define PROP_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) +#define PROP_IS_INVALID(val) (val < -MAX_STATE - 1 || val > MAX_STATE) #else /* (ESR) Only the boldest of adventurers will explore here. This * alternate set of definitions for the macros above was an attempt to * break from out of the state encoding a per-object "found" member - * telling whether or not the player has seen the object. + * telling whether or not the player has seen the object. * * What's broken when you try to use thus is * PROP_IS_STASHED_OR_UNSEEN. The symptom is game.tally getting * decremented on non-treasures. */ -#define PROP_STASHIFY(n) (-(n)) -#define PROP_IS_STASHED(obj) (game.objects[obj].prop < 0) -#define PROP_IS_NOTFOUND(obj) (!game.objects[obj].found) -#define PROP_IS_FOUND(obj) (game.objects[obj].found && game.objects[obj].prop == 0) -#define PROP_IS_STASHED_OR_UNSEEN(obj) (!game.objects[obj].found || game.objects[obj].prop < 0) -#define PROP_SET_FOUND(obj) do {game.objects[obj].found = true; game.objects[obj].prop = STATE_FOUND;} while(0) -#define PROP_SET_NOT_FOUND(obj) game.objects[obj].found = false -#define PROP_IS_NOTFOUND2(g, o) (!g.objects[o].found) -#define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) -#define PROP_SET_SEEN(obj) game.objects[object].found = true +#define PROP_STASHIFY(n) (-(n)) +#define PROP_IS_STASHED(obj) (game.objects[obj].prop < 0) +#define PROP_IS_NOTFOUND(obj) (!game.objects[obj].found) +#define PROP_IS_FOUND(obj) \ + (game.objects[obj].found && game.objects[obj].prop == 0) +#define PROP_IS_STASHED_OR_UNSEEN(obj) \ + (!game.objects[obj].found || game.objects[obj].prop < 0) +#define PROP_SET_FOUND(obj) \ + do { \ + game.objects[obj].found = true; \ + game.objects[obj].prop = STATE_FOUND; \ + } while (0) +#define PROP_SET_NOT_FOUND(obj) game.objects[obj].found = false +#define PROP_IS_NOTFOUND2(g, o) (!g.objects[o].found) +#define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) +#define PROP_SET_SEEN(obj) game.objects[object].found = true #endif -#define PROP_STASHED(obj) PROP_STASHIFY(game.objects[obj].prop) +#define PROP_STASHED(obj) PROP_STASHIFY(game.objects[obj].prop) -#define PROMPT "> " +#define PROMPT "> " /* * DESTROY(N) = Get rid of an item by putting it in LOC_NOWHERE @@ -116,62 +123,72 @@ * GSTONE(OBJ) = true if OBJ is a gemstone * FOREST(LOC) = true if LOC is part of the forest * OUTSID(LOC) = true if location not in the cave - * INSIDE(LOC) = true if location is in the cave or the building at the beginning of the game - * INDEEP(LOC) = true if location is in the Hall of Mists or deeper - * BUG(X) = report bug and exit + * INSIDE(LOC) = true if location is in the cave or the building at the + * beginning of the game INDEEP(LOC) = true if location is in the Hall of Mists + * or deeper BUG(X) = report bug and exit */ -#define DESTROY(N) move(N, LOC_NOWHERE) -#define MOD(N,M) ((N) % (M)) -#define TOTING(OBJ) (game.objects[OBJ].place == CARRIED) -#define AT(OBJ) (game.objects[OBJ].place == game.loc || game.objects[OBJ].fixed == game.loc) -#define HERE(OBJ) (AT(OBJ) || TOTING(OBJ)) -#define CNDBIT(L,N) (tstbit(conditions[L],N)) -#define LIQUID() (game.objects[BOTTLE].prop == WATER_BOTTLE? WATER : game.objects[BOTTLE].prop == OIL_BOTTLE ? OIL : NO_OBJECT ) -#define LIQLOC(LOC) (CNDBIT((LOC),COND_FLUID)? CNDBIT((LOC),COND_OILY) ? OIL : WATER : NO_OBJECT) -#define FORCED(LOC) CNDBIT(LOC, COND_FORCED) -#define DARK(DUMMY) (!CNDBIT(game.loc,COND_LIT) && (game.objects[LAMP].prop == LAMP_DARK || !HERE(LAMP))) -#define PCT(N) (randrange(100) < (N)) -#define GSTONE(OBJ) ((OBJ) == EMERALD || (OBJ) == RUBY || (OBJ) == AMBER || (OBJ) == SAPPH) -#define FOREST(LOC) CNDBIT(LOC, COND_FOREST) -#define OUTSID(LOC) (CNDBIT(LOC, COND_ABOVE) || FOREST(LOC)) -#define INSIDE(LOC) (!OUTSID(LOC) || LOC == LOC_BUILDING) -#define INDEEP(LOC) CNDBIT((LOC),COND_DEEP) -#define BUG(x) bug(x, #x) +#define DESTROY(N) move(N, LOC_NOWHERE) +#define MOD(N, M) ((N) % (M)) +#define TOTING(OBJ) (game.objects[OBJ].place == CARRIED) +#define AT(OBJ) \ + (game.objects[OBJ].place == game.loc || \ + game.objects[OBJ].fixed == game.loc) +#define HERE(OBJ) (AT(OBJ) || TOTING(OBJ)) +#define CNDBIT(L, N) (tstbit(conditions[L], N)) +#define LIQUID() \ + (game.objects[BOTTLE].prop == WATER_BOTTLE ? WATER \ + : game.objects[BOTTLE].prop == OIL_BOTTLE ? OIL \ + : NO_OBJECT) +#define LIQLOC(LOC) \ + (CNDBIT((LOC), COND_FLUID) ? CNDBIT((LOC), COND_OILY) ? OIL : WATER \ + : NO_OBJECT) +#define FORCED(LOC) CNDBIT(LOC, COND_FORCED) +#define DARK(DUMMY) \ + (!CNDBIT(game.loc, COND_LIT) && \ + (game.objects[LAMP].prop == LAMP_DARK || !HERE(LAMP))) +#define PCT(N) (randrange(100) < (N)) +#define GSTONE(OBJ) \ + ((OBJ) == EMERALD || (OBJ) == RUBY || (OBJ) == AMBER || (OBJ) == SAPPH) +#define FOREST(LOC) CNDBIT(LOC, COND_FOREST) +#define OUTSID(LOC) (CNDBIT(LOC, COND_ABOVE) || FOREST(LOC)) +#define INSIDE(LOC) (!OUTSID(LOC) || LOC == LOC_BUILDING) +#define INDEEP(LOC) CNDBIT((LOC), COND_DEEP) +#define BUG(x) bug(x, #x) enum bugtype { - SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST, - VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3, - INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST, - TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST, - CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION, - LOCATION_HAS_NO_TRAVEL_ENTRIES, - HINT_NUMBER_EXCEEDS_GOTO_LIST, - SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN, - ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH, + SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST, + VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3, + INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST, + TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST, + CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION, + LOCATION_HAS_NO_TRAVEL_ENTRIES, + HINT_NUMBER_EXCEEDS_GOTO_LIST, + SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN, + ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH, }; -enum speaktype {touch, look, hear, study, change}; +enum speaktype { touch, look, hear, study, change }; -enum termination {endgame, quitgame, scoregame}; +enum termination { endgame, quitgame, scoregame }; -enum speechpart {unknown, intransitive, transitive}; +enum speechpart { unknown, intransitive, transitive }; -typedef enum {NO_WORD_TYPE, MOTION, OBJECT, ACTION, NUMERIC} word_type_t; +typedef enum { NO_WORD_TYPE, MOTION, OBJECT, ACTION, NUMERIC } word_type_t; -typedef enum scorebonus {none, splatter, defeat, victory} score_t; +typedef enum scorebonus { none, splatter, defeat, victory } score_t; /* Phase codes for action returns. * These were at one time FORTRAN line numbers. */ typedef enum { - GO_TERMINATE, - GO_MOVE, - GO_TOP, - GO_CLEAROBJ, - GO_CHECKHINT, - GO_WORD2, - GO_UNKNOWN, - GO_DWARFWAKE, + GO_TERMINATE, + GO_MOVE, + GO_TOP, + GO_CLEAROBJ, + GO_CHECKHINT, + GO_WORD2, + GO_UNKNOWN, + GO_DWARFWAKE, } phase_codes_t; /* Use fixed-lwength types to make the save format moore portable */ @@ -183,75 +200,75 @@ typedef int32_t turn_t; // turn counter or threshold */ typedef int32_t bool32_t; // turn counter or threshold */ struct game_t { - int32_t lcg_x; - int32_t abbnum; // How often to print int descriptions - score_t bonus; // What kind of finishing bonus we are getting - loc_t chloc; // pirate chest location - loc_t chloc2; // pirate chest alternate location - turn_t clock1; // # turns from finding last treasure to close - turn_t clock2; // # turns from warning till blinding flash - bool32_t clshnt; // has player read the clue in the endgame? - bool32_t closed; // whether we're all the way closed - bool32_t closng; // whether it's closing time yet - bool32_t lmwarn; // has player been warned about lamp going dim? - bool32_t novice; // asked for instructions at start-up? - bool32_t panic; // has player found out he's trapped? - bool32_t wzdark; // whether the loc he's leaving was dark - bool32_t blooded; // has player drunk of dragon's blood? - int32_t conds; // min value for cond[loc] if loc has any hints - int32_t detail; // level of detail in descriptions + int32_t lcg_x; + int32_t abbnum; // How often to print int descriptions + score_t bonus; // What kind of finishing bonus we are getting + loc_t chloc; // pirate chest location + loc_t chloc2; // pirate chest alternate location + turn_t clock1; // # turns from finding last treasure to close + turn_t clock2; // # turns from warning till blinding flash + bool32_t clshnt; // has player read the clue in the endgame? + bool32_t closed; // whether we're all the way closed + bool32_t closng; // whether it's closing time yet + bool32_t lmwarn; // has player been warned about lamp going dim? + bool32_t novice; // asked for instructions at start-up? + bool32_t panic; // has player found out he's trapped? + bool32_t wzdark; // whether the loc he's leaving was dark + bool32_t blooded; // has player drunk of dragon's blood? + int32_t conds; // min value for cond[loc] if loc has any hints + int32_t detail; // level of detail in descriptions - /* dflag controls the level of activation of dwarves: - * 0 No dwarf stuff yet (wait until reaches Hall Of Mists) - * 1 Reached Hall Of Mists, but hasn't met first dwarf - * 2 Met first dwarf, others start moving, no knives thrown yet - * 3 A knife has been thrown (first set always misses) - * 3+ Dwarves are mad (increases their accuracy) */ - int32_t dflag; + /* dflag controls the level of activation of dwarves: + * 0 No dwarf stuff yet (wait until reaches Hall Of Mists) + * 1 Reached Hall Of Mists, but hasn't met first dwarf + * 2 Met first dwarf, others start moving, no knives thrown + *yet 3 A knife has been thrown (first set always misses) 3+ + *Dwarves are mad (increases their accuracy) */ + int32_t dflag; - int32_t dkill; // dwarves killed - int32_t dtotal; // total dwarves (including pirate) in loc - int32_t foobar; // progress in saying "FEE FIE FOE FOO". - int32_t holdng; // number of objects being carried - int32_t igo; // # uses of "go" instead of a direction - int32_t iwest; // # times he's said "west" instead of "w" - loc_t knfloc; // knife location; LOC_NOWERE if none, -1 after caveat - turn_t limit; // lifetime of lamp - loc_t loc; // where player is now - loc_t newloc; // where player is going - turn_t numdie; // number of times killed so far - loc_t oldloc; // where player was - loc_t oldlc2; // where player was two moves ago - obj_t oldobj; // last object player handled - int32_t saved; // point penalty for saves - int32_t tally; // count of treasures gained - int32_t thresh; // current threshold for endgame scoring tier - bool32_t seenbigwords; // have we red the graffiti in the Giant's Room? - turn_t trnluz; // # points lost so far due to turns used - turn_t turns; // counts commands given (ignores yes/no) - char zzword[TOKLEN + 1]; // randomly generated magic word from bird - struct { - int32_t abbrev; // has location been seen? - int32_t atloc; // head of object linked list per location - } locs[NLOCATIONS + 1]; - struct { - int32_t seen; // true if dwarf has seen him - loc_t loc; // location of dwarves, initially hard-wired in - loc_t oldloc; // prior loc of each dwarf, initially garbage - } dwarves[NDWARVES + 1]; - struct { + int32_t dkill; // dwarves killed + int32_t dtotal; // total dwarves (including pirate) in loc + int32_t foobar; // progress in saying "FEE FIE FOE FOO". + int32_t holdng; // number of objects being carried + int32_t igo; // # uses of "go" instead of a direction + int32_t iwest; // # times he's said "west" instead of "w" + loc_t knfloc; // knife location; LOC_NOWERE if none, -1 after caveat + turn_t limit; // lifetime of lamp + loc_t loc; // where player is now + loc_t newloc; // where player is going + turn_t numdie; // number of times killed so far + loc_t oldloc; // where player was + loc_t oldlc2; // where player was two moves ago + obj_t oldobj; // last object player handled + int32_t saved; // point penalty for saves + int32_t tally; // count of treasures gained + int32_t thresh; // current threshold for endgame scoring tier + bool32_t seenbigwords; // have we red the graffiti in the Giant's Room? + turn_t trnluz; // # points lost so far due to turns used + turn_t turns; // counts commands given (ignores yes/no) + char zzword[TOKLEN + 1]; // randomly generated magic word from bird + struct { + int32_t abbrev; // has location been seen? + int32_t atloc; // head of object linked list per location + } locs[NLOCATIONS + 1]; + struct { + int32_t seen; // true if dwarf has seen him + loc_t loc; // location of dwarves, initially hard-wired in + loc_t oldloc; // prior loc of each dwarf, initially garbage + } dwarves[NDWARVES + 1]; + struct { #ifdef FOUNDBOOL - bool32_t found; // has the location of this object been found? + bool32_t found; // has the location of this object been found? #endif - loc_t fixed; // fixed location of object (if not IS_FREE) - int32_t prop; // object state */ - loc_t place; // location of object - } objects[NOBJECTS + 1]; - struct { - bool32_t used; // hints[i].used = true iff hint i has been used. - int32_t lc; // hints[i].lc = show int at LOC with cond bit i - } hints[NHINTS]; - obj_t link[NOBJECTS * 2 + 1];// object-list links + loc_t fixed; // fixed location of object (if not IS_FREE) + int32_t prop; // object state */ + loc_t place; // location of object + } objects[NOBJECTS + 1]; + struct { + bool32_t used; // hints[i].used = true iff hint i has been used. + int32_t lc; // hints[i].lc = show int at LOC with cond bit i + } hints[NHINTS]; + obj_t link[NOBJECTS * 2 + 1]; // object-list links }; /* @@ -259,56 +276,64 @@ struct game_t { * This data is not saved in a saved game. */ struct settings_t { - FILE *logfp; - bool oldstyle; - bool prompt; - char **argv; - int argc; - int optind; - FILE *scriptfp; - int debug; + FILE *logfp; + bool oldstyle; + bool prompt; + char **argv; + int argc; + int optind; + FILE *scriptfp; + int debug; }; typedef struct { - char raw[LINESIZE]; - vocab_t id; - word_type_t type; + char raw[LINESIZE]; + vocab_t id; + word_type_t type; } command_word_t; -typedef enum {EMPTY, RAW, TOKENIZED, GIVEN, PREPROCESSED, PROCESSING, EXECUTED} command_state_t; +typedef enum { + EMPTY, + RAW, + TOKENIZED, + GIVEN, + PREPROCESSED, + PROCESSING, + EXECUTED +} command_state_t; typedef struct { - enum speechpart part; - command_word_t word[2]; - verb_t verb; - obj_t obj; - command_state_t state; + enum speechpart part; + command_word_t word[2]; + verb_t verb; + obj_t obj; + command_state_t state; } command_t; /* * Bump on save format change. * - * Note: Verify that the tests run clean before bumping this, then rebuild the check - * files afterwards. Otherwise you will get a spurious failure due to the old version - * having been generated into a check file. + * Note: Verify that the tests run clean before bumping this, then rebuild the + * check files afterwards. Otherwise you will get a spurious failure due to the + * old version having been generated into a check file. */ -#define SAVE_VERSION 31 +#define SAVE_VERSION 31 /* * Goes at start of file so saves can be identified by file(1) and the like. */ -#define ADVENT_MAGIC "open-adventure\n" +#define ADVENT_MAGIC "open-adventure\n" /* * If you change the first three members, the resume function may not properly - * reject saves from older versions. Later members can change, but bump the version - * when you do that. + * reject saves from older versions. Later members can change, but bump the + * version when you do that. */ struct save_t { - char magic[sizeof(ADVENT_MAGIC)]; - int32_t version; - int32_t canary; - struct game_t game; + char magic[sizeof(ADVENT_MAGIC)]; + int32_t version; + int32_t canary; + struct game_t game; }; extern struct game_t game; @@ -318,13 +343,13 @@ extern struct settings_t settings; extern char *myreadline(const char *); extern bool get_command_input(command_t *); extern void clear_command(command_t *); -extern void speak(const char*, ...); +extern void speak(const char *, ...); extern void sspeak(int msg, ...); extern void pspeak(vocab_t, enum speaktype, bool, int, ...); extern void rspeak(vocab_t, ...); -extern void echo_input(FILE*, const char*, const char*); +extern void echo_input(FILE *, const char *, const char *); extern bool silent_yes_or_no(void); -extern bool yes_or_no(const char*, const char*, const char*); +extern bool yes_or_no(const char *, const char *, const char *); extern void juggle(obj_t); extern void move(obj_t, loc_t); extern void put(obj_t, loc_t, int); diff --git a/cheat.c b/cheat.c index 279bcd9..4e94025 100644 --- a/cheat.c +++ b/cheat.c @@ -7,93 +7,90 @@ * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ -#include -#include -#include -#include -#include #include "advent.h" +#include +#include +#include +#include +#include -int main(int argc, char *argv[]) -{ - int ch; - char *savefilename = NULL; - FILE *fp = NULL; +int main(int argc, char *argv[]) { + int ch; + char *savefilename = NULL; + FILE *fp = NULL; - // Initialize game variables - initialise(); + // Initialize game variables + initialise(); - /* we're generating a saved game, so saved once by default, - * unless overridden with command-line options below. - */ - game.saved = 1; + /* we're generating a saved game, so saved once by default, + * unless overridden with command-line options below. + */ + game.saved = 1; - /* Options. */ - const char* opts = "d:l:s:t:v:o:"; - const char* usage = "Usage: %s [-d numdie] [-s numsaves] [-v version] -o savefilename \n" - " -d number of deaths. Signed integer.\n" - " -l lifetime of lamp in turns. Signed integer.\n" - " -s number of saves. Signed integer.\n" - " -t number of turns. Signed integer.\n" - " -v version number of save format.\n" - " -o required. File name of save game to write.\n"; + /* Options. */ + const char *opts = "d:l:s:t:v:o:"; + const char *usage = + "Usage: %s [-d numdie] [-s numsaves] [-v version] -o savefilename " + "\n" + " -d number of deaths. Signed integer.\n" + " -l lifetime of lamp in turns. Signed integer.\n" + " -s number of saves. Signed integer.\n" + " -t number of turns. Signed integer.\n" + " -v version number of save format.\n" + " -o required. File name of save game to write.\n"; - while ((ch = getopt(argc, argv, opts)) != EOF) { - switch (ch) { - case 'd': - game.numdie = (turn_t)atoi(optarg); - printf("cheat: game.numdie = %d\n", game.numdie); - break; - case 'l': - game.limit = (turn_t)atoi(optarg); - printf("cheat: game.limit = %d\n", game.limit); - break; - case 's': - game.saved = (int)atoi(optarg); - printf("cheat: game.saved = %d\n", game.saved); - break; - case 't': - game.turns = (turn_t)atoi(optarg); - printf("cheat: game.turns = %d\n", game.turns); - break; - case 'v': - save.version = atoi(optarg); - printf("cheat: version = %d\n", save.version); - break; - case 'o': - savefilename = optarg; - break; - default: - fprintf(stderr, - usage, argv[0]); - exit(EXIT_FAILURE); - break; - } - } + while ((ch = getopt(argc, argv, opts)) != EOF) { + switch (ch) { + case 'd': + game.numdie = (turn_t)atoi(optarg); + printf("cheat: game.numdie = %d\n", game.numdie); + break; + case 'l': + game.limit = (turn_t)atoi(optarg); + printf("cheat: game.limit = %d\n", game.limit); + break; + case 's': + game.saved = (int)atoi(optarg); + printf("cheat: game.saved = %d\n", game.saved); + break; + case 't': + game.turns = (turn_t)atoi(optarg); + printf("cheat: game.turns = %d\n", game.turns); + break; + case 'v': + save.version = atoi(optarg); + printf("cheat: version = %d\n", save.version); + break; + case 'o': + savefilename = optarg; + break; + default: + fprintf(stderr, usage, argv[0]); + exit(EXIT_FAILURE); + break; + } + } - // Save filename required; the point of cheat is to generate save file - if (savefilename == NULL) { - fprintf(stderr, - usage, argv[0]); - fprintf(stderr, - "ERROR: filename required\n"); - exit(EXIT_FAILURE); - } + // Save filename required; the point of cheat is to generate save file + if (savefilename == NULL) { + fprintf(stderr, usage, argv[0]); + fprintf(stderr, "ERROR: filename required\n"); + exit(EXIT_FAILURE); + } - fp = fopen(savefilename, WRITE_MODE); - if (fp == NULL) { - fprintf(stderr, - "Can't open file %s. Exiting.\n", savefilename); - exit(EXIT_FAILURE); - } + fp = fopen(savefilename, WRITE_MODE); + if (fp == NULL) { + fprintf(stderr, "Can't open file %s. Exiting.\n", savefilename); + exit(EXIT_FAILURE); + } - savefile(fp); + savefile(fp); - fclose(fp); + fclose(fp); - printf("cheat: %s created.\n", savefilename); + printf("cheat: %s created.\n", savefilename); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } // LCOV_EXCL_START @@ -102,12 +99,7 @@ int main(int argc, char *argv[]) * See the actually useful version of this in main.c */ -char *myreadline(const char *prompt) -{ - return readline(prompt); -} +char *myreadline(const char *prompt) { return readline(prompt); } // LCOV_EXCL_STOP /* end */ - - diff --git a/init.c b/init.c index 94c972d..d00255d 100644 --- a/init.c +++ b/init.c @@ -5,97 +5,86 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include "advent.h" -struct settings_t settings = { - .logfp = NULL, - .oldstyle = false, - .prompt = true -}; +struct settings_t settings = {.logfp = NULL, .oldstyle = false, .prompt = true}; struct game_t game = { /* Last dwarf is special (the pirate). He always starts at his * chest's eventual location inside the maze. This loc is saved * in chloc for ref. The dead end in the other maze has its * loc stored in chloc2. */ - .chloc = LOC_MAZEEND12, - .chloc2 = LOC_DEADEND13, - .abbnum = 5, - .clock1 = WARNTIME, - .clock2 = FLASHTIME, - .newloc = LOC_START, - .loc = LOC_START, - .limit = GAMELIMIT, - .foobar = WORD_EMPTY, + .chloc = LOC_MAZEEND12, .chloc2 = LOC_DEADEND13, .abbnum = 5, + .clock1 = WARNTIME, .clock2 = FLASHTIME, .newloc = LOC_START, + .loc = LOC_START, .limit = GAMELIMIT, .foobar = WORD_EMPTY, }; -int initialise(void) -{ - if (settings.oldstyle) - printf("Initialising...\n"); +int initialise(void) { + if (settings.oldstyle) + printf("Initialising...\n"); - srand(time(NULL)); - int seedval = (int)rand(); - set_seed(seedval); + srand(time(NULL)); + int seedval = (int)rand(); + set_seed(seedval); - for (int i = 1; i <= NDWARVES; i++) { - game.dwarves[i].loc = dwarflocs[i-1]; - } - - for (int i = 1; i <= NOBJECTS; i++) { - game.objects[i].place = LOC_NOWHERE; - } - - for (int i = 1; i <= NLOCATIONS; i++) { - if (!(locations[i].description.big == 0 || tkey[i] == 0)) { - int k = tkey[i]; - if (travel[k].motion == HERE) { - conditions[i] |= (1 << COND_FORCED); - } - } - } - - /* Set up the game.locs atloc and game.link arrays. - * We'll use the DROP subroutine, which prefaces new objects on the - * lists. Since we want things in the other order, we'll run the - * loop backwards. If the object is in two locs, we drop it twice. - * Also, since two-placed objects are typically best described - * last, we'll drop them first. */ - for (int i = NOBJECTS; i >= 1; i--) { - if (objects[i].fixd > 0) { - drop(i + NOBJECTS, objects[i].fixd); - drop(i, objects[i].plac); - } - } - - for (int i = 1; i <= NOBJECTS; i++) { - int k = NOBJECTS + 1 - i; - game.objects[k].fixed = objects[k].fixd; - if (objects[k].plac != 0 && objects[k].fixd <= 0) { - drop(k, objects[k].plac); + for (int i = 1; i <= NDWARVES; i++) { + game.dwarves[i].loc = dwarflocs[i - 1]; } - } - /* Treasure props are initially STATE_NOTFOUND, and are set to - * STATE_FOUND the first time they are described. game.tally - * keeps track of how many are not yet found, so we know when to - * close the cave. */ - for (int treasure = 1; treasure <= NOBJECTS; treasure++) { - if (objects[treasure].is_treasure) { - ++game.tally; - if (objects[treasure].inventory != 0) { - PROP_SET_NOT_FOUND(treasure); - } - } - } - game.conds = setbit(COND_HBASE); + for (int i = 1; i <= NOBJECTS; i++) { + game.objects[i].place = LOC_NOWHERE; + } - return seedval; + for (int i = 1; i <= NLOCATIONS; i++) { + if (!(locations[i].description.big == 0 || tkey[i] == 0)) { + int k = tkey[i]; + if (travel[k].motion == HERE) { + conditions[i] |= (1 << COND_FORCED); + } + } + } + + /* Set up the game.locs atloc and game.link arrays. + * We'll use the DROP subroutine, which prefaces new objects on the + * lists. Since we want things in the other order, we'll run the + * loop backwards. If the object is in two locs, we drop it twice. + * Also, since two-placed objects are typically best described + * last, we'll drop them first. */ + for (int i = NOBJECTS; i >= 1; i--) { + if (objects[i].fixd > 0) { + drop(i + NOBJECTS, objects[i].fixd); + drop(i, objects[i].plac); + } + } + + for (int i = 1; i <= NOBJECTS; i++) { + int k = NOBJECTS + 1 - i; + game.objects[k].fixed = objects[k].fixd; + if (objects[k].plac != 0 && objects[k].fixd <= 0) { + drop(k, objects[k].plac); + } + } + + /* Treasure props are initially STATE_NOTFOUND, and are set to + * STATE_FOUND the first time they are described. game.tally + * keeps track of how many are not yet found, so we know when to + * close the cave. */ + for (int treasure = 1; treasure <= NOBJECTS; treasure++) { + if (objects[treasure].is_treasure) { + ++game.tally; + if (objects[treasure].inventory != 0) { + PROP_SET_NOT_FOUND(treasure); + } + } + } + game.conds = setbit(COND_HBASE); + + return seedval; } diff --git a/main.c b/main.c index fd0852f..cff0780 100644 --- a/main.c +++ b/main.c @@ -3,432 +3,460 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include -#include -#include +#include "advent.h" +#include +#include #include #include +#include +#include +#include #include -#include #include -#include -#include "advent.h" -#define DIM(a) (sizeof(a)/sizeof(a[0])) +#define DIM(a) (sizeof(a) / sizeof(a[0])) #if defined ADVENT_AUTOSAVE -static FILE* autosave_fp; -void autosave(void) -{ - if (autosave_fp != NULL) { - rewind(autosave_fp); - savefile(autosave_fp); - fflush(autosave_fp); - } +static FILE *autosave_fp; +void autosave(void) { + if (autosave_fp != NULL) { + rewind(autosave_fp); + savefile(autosave_fp); + fflush(autosave_fp); + } } #endif // LCOV_EXCL_START // exclude from coverage analysis because it requires interactivity to test -static void sig_handler(int signo) -{ - if (signo == SIGINT) { - if (settings.logfp != NULL) - fflush(settings.logfp); - } +static void sig_handler(int signo) { + if (signo == SIGINT) { + if (settings.logfp != NULL) + fflush(settings.logfp); + } #if defined ADVENT_AUTOSAVE - if (signo == SIGHUP || signo == SIGTERM) { - autosave(); - } + if (signo == SIGHUP || signo == SIGTERM) { + autosave(); + } #endif - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } // LCOV_EXCL_STOP -char *myreadline(const char *prompt) -{ - /* - * This function isn't required for gameplay, readline() straight - * up would suffice for that. It's where we interpret command-line - * logfiles for testing purposes. - */ - /* Normal case - no script arguments */ - if (settings.argc == 0) { - char *ln = readline(prompt); - if (ln == NULL) { - fputs(prompt, stdout); - } - return ln; - } - - char *buf = malloc(LINESIZE + 1); - for (;;) { - if (settings.scriptfp == NULL || feof(settings.scriptfp)) { - if (settings.optind >= settings.argc) { - free(buf); - return NULL; - } - - char *next = settings.argv[settings.optind++]; - - if (settings.scriptfp != NULL && feof(settings.scriptfp)) { - fclose(settings.scriptfp); - } - if (strcmp(next, "-") == 0) { - settings.scriptfp = stdin; // LCOV_EXCL_LINE - } else { - settings.scriptfp = fopen(next, "r"); - } - } - - if (isatty(fileno(settings.scriptfp))) { - free(buf); // LCOV_EXCL_LINE - return readline(prompt); // LCOV_EXCL_LINE - } else { - char *ln = fgets(buf, LINESIZE, settings.scriptfp); - if (ln != NULL) { - fputs(prompt, stdout); - fputs(ln, stdout); +char *myreadline(const char *prompt) { + /* + * This function isn't required for gameplay, readline() straight + * up would suffice for that. It's where we interpret command-line + * logfiles for testing purposes. + */ + /* Normal case - no script arguments */ + if (settings.argc == 0) { + char *ln = readline(prompt); + if (ln == NULL) { + fputs(prompt, stdout); + } return ln; - } - } - } + } - return NULL; + char *buf = malloc(LINESIZE + 1); + for (;;) { + if (settings.scriptfp == NULL || feof(settings.scriptfp)) { + if (settings.optind >= settings.argc) { + free(buf); + return NULL; + } + + char *next = settings.argv[settings.optind++]; + + if (settings.scriptfp != NULL && + feof(settings.scriptfp)) { + fclose(settings.scriptfp); + } + if (strcmp(next, "-") == 0) { + settings.scriptfp = stdin; // LCOV_EXCL_LINE + } else { + settings.scriptfp = fopen(next, "r"); + } + } + + if (isatty(fileno(settings.scriptfp))) { + free(buf); // LCOV_EXCL_LINE + return readline(prompt); // LCOV_EXCL_LINE + } else { + char *ln = fgets(buf, LINESIZE, settings.scriptfp); + if (ln != NULL) { + fputs(prompt, stdout); + fputs(ln, stdout); + return ln; + } + } + } + + return NULL; } /* Check if this loc is eligible for any hints. If been here int * enough, display. Ignore "HINTS" < 4 (special stuff, see database * notes). */ -static void checkhints(void) -{ - if (conditions[game.loc] >= game.conds) { - for (int hint = 0; hint < NHINTS; hint++) { - if (game.hints[hint].used) { - continue; - } - if (!CNDBIT(game.loc, hint + 1 + COND_HBASE)) { - game.hints[hint].lc = -1; - } - ++game.hints[hint].lc; - /* Come here if he's been int enough at required loc(s) for some - * unused hint. */ - if (game.hints[hint].lc >= hints[hint].turns) { - int i; +static void checkhints(void) { + if (conditions[game.loc] >= game.conds) { + for (int hint = 0; hint < NHINTS; hint++) { + if (game.hints[hint].used) { + continue; + } + if (!CNDBIT(game.loc, hint + 1 + COND_HBASE)) { + game.hints[hint].lc = -1; + } + ++game.hints[hint].lc; + /* Come here if he's been int enough at required loc(s) + * for some unused hint. */ + if (game.hints[hint].lc >= hints[hint].turns) { + int i; - switch (hint) { - case 0: - /* cave */ - if (game.objects[GRATE].prop == GRATE_CLOSED && !HERE(KEYS)) { - break; - } - game.hints[hint].lc = 0; - return; - case 1: /* bird */ - if (game.objects[BIRD].place == game.loc && TOTING(ROD) && game.oldobj == BIRD) { - break; - } - return; - case 2: /* snake */ - if (HERE(SNAKE) && !HERE(BIRD)) { - break; - } - game.hints[hint].lc = 0; - return; - case 3: /* maze */ - if (game.locs[game.loc].atloc == NO_OBJECT && - game.locs[game.oldloc].atloc == NO_OBJECT && - game.locs[game.oldlc2].atloc == NO_OBJECT && - game.holdng > 1) - break; - game.hints[hint].lc = 0; - return; - case 4: /* dark */ - if (!PROP_IS_NOTFOUND(EMERALD) && PROP_IS_NOTFOUND(PYRAMID)) { - break; - } - game.hints[hint].lc = 0; - return; - case 5: /* witt */ - break; - case 6: /* urn */ - if (game.dflag == 0) { - break; - } - game.hints[hint].lc = 0; - return; - case 7: /* woods */ - if (game.locs[game.loc].atloc == NO_OBJECT && - game.locs[game.oldloc].atloc == NO_OBJECT && - game.locs[game.oldlc2].atloc == NO_OBJECT) - break; - return; - case 8: /* ogre */ - i = atdwrf(game.loc); - if (i < 0) { - game.hints[hint].lc = 0; - return; - } - if (HERE(OGRE) && i == 0) { - break; - } - return; - case 9: /* jade */ - if (game.tally == 1 && PROP_IS_STASHED_OR_UNSEEN(JADE)) { - break; - } - game.hints[hint].lc = 0; - return; - default: // LCOV_EXCL_LINE - // Should never happen - BUG(HINT_NUMBER_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE - } + switch (hint) { + case 0: + /* cave */ + if (game.objects[GRATE].prop == + GRATE_CLOSED && + !HERE(KEYS)) { + break; + } + game.hints[hint].lc = 0; + return; + case 1: /* bird */ + if (game.objects[BIRD].place == + game.loc && + TOTING(ROD) && + game.oldobj == BIRD) { + break; + } + return; + case 2: /* snake */ + if (HERE(SNAKE) && !HERE(BIRD)) { + break; + } + game.hints[hint].lc = 0; + return; + case 3: /* maze */ + if (game.locs[game.loc].atloc == + NO_OBJECT && + game.locs[game.oldloc].atloc == + NO_OBJECT && + game.locs[game.oldlc2].atloc == + NO_OBJECT && + game.holdng > 1) + break; + game.hints[hint].lc = 0; + return; + case 4: /* dark */ + if (!PROP_IS_NOTFOUND(EMERALD) && + PROP_IS_NOTFOUND(PYRAMID)) { + break; + } + game.hints[hint].lc = 0; + return; + case 5: /* witt */ + break; + case 6: /* urn */ + if (game.dflag == 0) { + break; + } + game.hints[hint].lc = 0; + return; + case 7: /* woods */ + if (game.locs[game.loc].atloc == + NO_OBJECT && + game.locs[game.oldloc].atloc == + NO_OBJECT && + game.locs[game.oldlc2].atloc == + NO_OBJECT) + break; + return; + case 8: /* ogre */ + i = atdwrf(game.loc); + if (i < 0) { + game.hints[hint].lc = 0; + return; + } + if (HERE(OGRE) && i == 0) { + break; + } + return; + case 9: /* jade */ + if (game.tally == 1 && + PROP_IS_STASHED_OR_UNSEEN(JADE)) { + break; + } + game.hints[hint].lc = 0; + return; + default: // LCOV_EXCL_LINE + // Should never happen + BUG(HINT_NUMBER_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE + } - /* Fall through to hint display */ - game.hints[hint].lc = 0; - if (!yes_or_no(hints[hint].question, arbitrary_messages[NO_MESSAGE], arbitrary_messages[OK_MAN])) { - return; + /* Fall through to hint display */ + game.hints[hint].lc = 0; + if (!yes_or_no(hints[hint].question, + arbitrary_messages[NO_MESSAGE], + arbitrary_messages[OK_MAN])) { + return; + } + rspeak(HINT_COST, hints[hint].penalty, + hints[hint].penalty); + game.hints[hint].used = + yes_or_no(arbitrary_messages[WANT_HINT], + hints[hint].hint, + arbitrary_messages[OK_MAN]); + if (game.hints[hint].used && + game.limit > WARNTIME) { + game.limit += + WARNTIME * hints[hint].penalty; + } + } } - rspeak(HINT_COST, hints[hint].penalty, hints[hint].penalty); - game.hints[hint].used = yes_or_no(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]); - if (game.hints[hint].used && game.limit > WARNTIME) { - game.limit += WARNTIME * hints[hint].penalty; - } - } - } - } + } } -static bool spotted_by_pirate(int i) -{ - if (i != PIRATE) { - return false; - } +static bool spotted_by_pirate(int i) { + if (i != PIRATE) { + return false; + } - /* The pirate's spotted him. Pirate leaves him alone once we've - * found chest. K counts if a treasure is here. If not, and - * tally=1 for an unseen chest, let the pirate be spotted. Note - * that game.objexts,place[CHEST] = LOC_NOWHERE might mean that he's thrown - * it to the troll, but in that case he's seen the chest - * PROP_IS_FOUND(CHEST) == true. */ - if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST)) { - return true; - } - int snarfed = 0; - bool movechest = false, robplayer = false; - for (int treasure = 1; treasure <= NOBJECTS; treasure++) { - if (!objects[treasure].is_treasure) { - continue; - } - /* Pirate won't take pyramid from plover room or dark - * room (too easy!). */ - if (treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || - game.loc == objects[EMERALD].plac)) { - continue; - } - if (TOTING(treasure) || HERE(treasure)) { - ++snarfed; + /* The pirate's spotted him. Pirate leaves him alone once we've + * found chest. K counts if a treasure is here. If not, and + * tally=1 for an unseen chest, let the pirate be spotted. Note + * that game.objexts,place[CHEST] = LOC_NOWHERE might mean that he's + * thrown it to the troll, but in that case he's seen the chest + * PROP_IS_FOUND(CHEST) == true. */ + if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST)) { + return true; } - if (TOTING(treasure)) { - movechest = true; - robplayer = true; - } - } - /* Force chest placement before player finds last treasure */ - if (game.tally == 1 && snarfed == 0 && game.objects[CHEST].place == LOC_NOWHERE && HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) { - rspeak(PIRATE_SPOTTED); - movechest = true; - } - /* Do things in this order (chest move before robbery) so chest is listed - * last at the maze location. */ - if (movechest) { - move(CHEST, game.chloc); - move(MESSAG, game.chloc2); - game.dwarves[PIRATE].loc = game.chloc; - game.dwarves[PIRATE].oldloc = game.chloc; - game.dwarves[PIRATE].seen = false; - } else { - /* You might get a hint of the pirate's presence even if the - * chest doesn't move... */ - if (game.dwarves[PIRATE].oldloc != game.dwarves[PIRATE].loc && PCT(20)) { - rspeak(PIRATE_RUSTLES); - } - } - if (robplayer) { - rspeak(PIRATE_POUNCES); - for (int treasure = 1; treasure <= NOBJECTS; treasure++) { - if (!objects[treasure].is_treasure) { - continue; - } - if (!(treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || - game.loc == objects[EMERALD].plac))) { - if (AT(treasure) && game.objects[treasure].fixed == IS_FREE) { - carry(treasure, game.loc); + int snarfed = 0; + bool movechest = false, robplayer = false; + for (int treasure = 1; treasure <= NOBJECTS; treasure++) { + if (!objects[treasure].is_treasure) { + continue; + } + /* Pirate won't take pyramid from plover room or dark + * room (too easy!). */ + if (treasure == PYRAMID && + (game.loc == objects[PYRAMID].plac || + game.loc == objects[EMERALD].plac)) { + continue; + } + if (TOTING(treasure) || HERE(treasure)) { + ++snarfed; } if (TOTING(treasure)) { - drop(treasure, game.chloc); + movechest = true; + robplayer = true; } - } - } - } + } + /* Force chest placement before player finds last treasure */ + if (game.tally == 1 && snarfed == 0 && + game.objects[CHEST].place == LOC_NOWHERE && HERE(LAMP) && + game.objects[LAMP].prop == LAMP_BRIGHT) { + rspeak(PIRATE_SPOTTED); + movechest = true; + } + /* Do things in this order (chest move before robbery) so chest is + * listed last at the maze location. */ + if (movechest) { + move(CHEST, game.chloc); + move(MESSAG, game.chloc2); + game.dwarves[PIRATE].loc = game.chloc; + game.dwarves[PIRATE].oldloc = game.chloc; + game.dwarves[PIRATE].seen = false; + } else { + /* You might get a hint of the pirate's presence even if the + * chest doesn't move... */ + if (game.dwarves[PIRATE].oldloc != game.dwarves[PIRATE].loc && + PCT(20)) { + rspeak(PIRATE_RUSTLES); + } + } + if (robplayer) { + rspeak(PIRATE_POUNCES); + for (int treasure = 1; treasure <= NOBJECTS; treasure++) { + if (!objects[treasure].is_treasure) { + continue; + } + if (!(treasure == PYRAMID && + (game.loc == objects[PYRAMID].plac || + game.loc == objects[EMERALD].plac))) { + if (AT(treasure) && + game.objects[treasure].fixed == IS_FREE) { + carry(treasure, game.loc); + } + if (TOTING(treasure)) { + drop(treasure, game.chloc); + } + } + } + } - return true; + return true; } static bool dwarfmove(void) { -/* Dwarves move. Return true if player survives, false if he dies. */ - int kk, stick, attack; - loc_t tk[21]; + /* Dwarves move. Return true if player survives, false if he dies. */ + int kk, stick, attack; + loc_t tk[21]; - /* Dwarf stuff. See earlier comments for description of - * variables. Remember sixth dwarf is pirate and is thus - * very different except for motion rules. */ + /* Dwarf stuff. See earlier comments for description of + * variables. Remember sixth dwarf is pirate and is thus + * very different except for motion rules. */ - /* First off, don't let the dwarves follow him into a pit or a - * wall. Activate the whole mess the first time he gets as far - * as the Hall of Mists (what INDEEP() tests). If game.newloc - * is forbidden to pirate (in particular, if it's beyond the - * troll bridge), bypass dwarf stuff. That way pirate can't - * steal return toll, and dwarves can't meet the bear. Also - * means dwarves won't follow him into dead end in maze, but - * c'est la vie. They'll wait for him outside the dead end. */ - if (game.loc == LOC_NOWHERE || FORCED(game.loc) || CNDBIT(game.newloc, COND_NOARRR)) { - return true; - } - - /* Dwarf activity level ratchets up */ - if (game.dflag == 0) { - if (INDEEP(game.loc)) - game.dflag = 1; - return true; - } - - /* When we encounter the first dwarf, we kill 0, 1, or 2 of - * the 5 dwarves. If any of the survivors is at game.loc, - * replace him with the alternate. */ - if (game.dflag == 1) { - if (!INDEEP(game.loc) || - (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || PCT(85)))) { - return true; + /* First off, don't let the dwarves follow him into a pit or a + * wall. Activate the whole mess the first time he gets as far + * as the Hall of Mists (what INDEEP() tests). If game.newloc + * is forbidden to pirate (in particular, if it's beyond the + * troll bridge), bypass dwarf stuff. That way pirate can't + * steal return toll, and dwarves can't meet the bear. Also + * means dwarves won't follow him into dead end in maze, but + * c'est la vie. They'll wait for him outside the dead end. */ + if (game.loc == LOC_NOWHERE || FORCED(game.loc) || + CNDBIT(game.newloc, COND_NOARRR)) { + return true; } - game.dflag = 2; - for (int i = 1; i <= 2; i++) { - int j = 1 + randrange(NDWARVES - 1); - if (PCT(50)) { - game.dwarves[j].loc = 0; - } - } - /* Alternate initial loc for dwarf, in case one of them - * starts out on top of the adventurer. */ - for (int i = 1; i <= NDWARVES - 1; i++) { - if (game.dwarves[i].loc == game.loc) { - game.dwarves[i].loc = DALTLC; - } - game.dwarves[i].oldloc = game.dwarves[i].loc; - } - rspeak(DWARF_RAN); - drop(AXE, game.loc); - return true; - } + /* Dwarf activity level ratchets up */ + if (game.dflag == 0) { + if (INDEEP(game.loc)) + game.dflag = 1; + return true; + } - /* Things are in full swing. Move each dwarf at random, - * except if he's seen us he sticks with us. Dwarves stay - * deep inside. If wandering at random, they don't back up - * unless there's no alternative. If they don't have to - * move, they attack. And, of course, dead dwarves don't do - * much of anything. */ - game.dtotal = 0; - attack = 0; - stick = 0; - for (int i = 1; i <= NDWARVES; i++) { - if (game.dwarves[i].loc == 0) { - continue; - } - /* Fill tk array with all the places this dwarf might go. */ - unsigned int j = 1; - kk = tkey[game.dwarves[i].loc]; - if (kk != 0) - do { - enum desttype_t desttype = travel[kk].desttype; - game.newloc = travel[kk].destval; - /* Have we avoided a dwarf encounter? */ - if (desttype != dest_goto) - continue; - else if (!INDEEP(game.newloc)) - continue; - else if (game.newloc == game.dwarves[i].oldloc) - continue; - else if (j > 1 && game.newloc == tk[j - 1]) - continue; - else if (j >= DIM(tk) - 1) - /* This can't actually happen. */ - continue; // LCOV_EXCL_LINE - else if (game.newloc == game.dwarves[i].loc) - continue; - else if (FORCED(game.newloc)) - continue; - else if (i == PIRATE && CNDBIT(game.newloc, COND_NOARRR)) - continue; - else if (travel[kk].nodwarves) - continue; - tk[j++] = game.newloc; - } while - (!travel[kk++].stop); - tk[j] = game.dwarves[i].oldloc; - if (j >= 2) { - --j; - } - j = 1 + randrange(j); - game.dwarves[i].oldloc = game.dwarves[i].loc; - game.dwarves[i].loc = tk[j]; - game.dwarves[i].seen = (game.dwarves[i].seen && INDEEP(game.loc)) || - (game.dwarves[i].loc == game.loc || - game.dwarves[i].oldloc == game.loc); - if (!game.dwarves[i].seen) { - continue; - } - game.dwarves[i].loc = game.loc; - if (spotted_by_pirate(i)) { - continue; - } - /* This threatening little dwarf is in the room with him! */ - ++game.dtotal; - if (game.dwarves[i].oldloc == game.dwarves[i].loc) { - ++attack; - if (game.knfloc >= LOC_NOWHERE) { - game.knfloc = game.loc; - } - if (randrange(1000) < 95 * (game.dflag - 2)) { - ++stick; - } - } - } + /* When we encounter the first dwarf, we kill 0, 1, or 2 of + * the 5 dwarves. If any of the survivors is at game.loc, + * replace him with the alternate. */ + if (game.dflag == 1) { + if (!INDEEP(game.loc) || + (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || PCT(85)))) { + return true; + } + game.dflag = 2; + for (int i = 1; i <= 2; i++) { + int j = 1 + randrange(NDWARVES - 1); + if (PCT(50)) { + game.dwarves[j].loc = 0; + } + } - /* Now we know what's happening. Let's tell the poor sucker about it. */ - if (game.dtotal == 0) { - return true; - } - rspeak(game.dtotal == 1 ? DWARF_SINGLE : DWARF_PACK, game.dtotal); - if (attack == 0) { - return true; - } - if (game.dflag == 2) { - game.dflag = 3; - } - if (attack > 1) { - rspeak(THROWN_KNIVES, attack); - rspeak(stick > 1 ? MULTIPLE_HITS : (stick == 1 ? ONE_HIT : NONE_HIT), stick); - } else { - rspeak(KNIFE_THROWN); - rspeak(stick ? GETS_YOU : MISSES_YOU); - } - if (stick == 0) { - return true; - } - game.oldlc2 = game.loc; - return false; + /* Alternate initial loc for dwarf, in case one of them + * starts out on top of the adventurer. */ + for (int i = 1; i <= NDWARVES - 1; i++) { + if (game.dwarves[i].loc == game.loc) { + game.dwarves[i].loc = DALTLC; + } + game.dwarves[i].oldloc = game.dwarves[i].loc; + } + rspeak(DWARF_RAN); + drop(AXE, game.loc); + return true; + } + + /* Things are in full swing. Move each dwarf at random, + * except if he's seen us he sticks with us. Dwarves stay + * deep inside. If wandering at random, they don't back up + * unless there's no alternative. If they don't have to + * move, they attack. And, of course, dead dwarves don't do + * much of anything. */ + game.dtotal = 0; + attack = 0; + stick = 0; + for (int i = 1; i <= NDWARVES; i++) { + if (game.dwarves[i].loc == 0) { + continue; + } + /* Fill tk array with all the places this dwarf might go. */ + unsigned int j = 1; + kk = tkey[game.dwarves[i].loc]; + if (kk != 0) + do { + enum desttype_t desttype = travel[kk].desttype; + game.newloc = travel[kk].destval; + /* Have we avoided a dwarf encounter? */ + if (desttype != dest_goto) + continue; + else if (!INDEEP(game.newloc)) + continue; + else if (game.newloc == game.dwarves[i].oldloc) + continue; + else if (j > 1 && game.newloc == tk[j - 1]) + continue; + else if (j >= DIM(tk) - 1) + /* This can't actually happen. */ + continue; // LCOV_EXCL_LINE + else if (game.newloc == game.dwarves[i].loc) + continue; + else if (FORCED(game.newloc)) + continue; + else if (i == PIRATE && + CNDBIT(game.newloc, COND_NOARRR)) + continue; + else if (travel[kk].nodwarves) + continue; + tk[j++] = game.newloc; + } while (!travel[kk++].stop); + tk[j] = game.dwarves[i].oldloc; + if (j >= 2) { + --j; + } + j = 1 + randrange(j); + game.dwarves[i].oldloc = game.dwarves[i].loc; + game.dwarves[i].loc = tk[j]; + game.dwarves[i].seen = + (game.dwarves[i].seen && INDEEP(game.loc)) || + (game.dwarves[i].loc == game.loc || + game.dwarves[i].oldloc == game.loc); + if (!game.dwarves[i].seen) { + continue; + } + game.dwarves[i].loc = game.loc; + if (spotted_by_pirate(i)) { + continue; + } + /* This threatening little dwarf is in the room with him! */ + ++game.dtotal; + if (game.dwarves[i].oldloc == game.dwarves[i].loc) { + ++attack; + if (game.knfloc >= LOC_NOWHERE) { + game.knfloc = game.loc; + } + if (randrange(1000) < 95 * (game.dflag - 2)) { + ++stick; + } + } + } + + /* Now we know what's happening. Let's tell the poor sucker about it. + */ + if (game.dtotal == 0) { + return true; + } + rspeak(game.dtotal == 1 ? DWARF_SINGLE : DWARF_PACK, game.dtotal); + if (attack == 0) { + return true; + } + if (game.dflag == 2) { + game.dflag = 3; + } + if (attack > 1) { + rspeak(THROWN_KNIVES, attack); + rspeak(stick > 1 ? MULTIPLE_HITS + : (stick == 1 ? ONE_HIT : NONE_HIT), + stick); + } else { + rspeak(KNIFE_THROWN); + rspeak(stick ? GETS_YOU : MISSES_YOU); + } + if (stick == 0) { + return true; + } + game.oldlc2 = game.loc; + return false; } /* "You're dead, Jim." @@ -451,69 +479,73 @@ static bool dwarfmove(void) { * cave without the lamp!). game.oldloc is zapped so he can't just * "retreat". */ static void croak(void) { -/* Okay, he's dead. Let's get on with it. */ - const char* query = obituaries[game.numdie].query; - const char* yes_response = obituaries[game.numdie].yes_response; + /* Okay, he's dead. Let's get on with it. */ + const char *query = obituaries[game.numdie].query; + const char *yes_response = obituaries[game.numdie].yes_response; - ++game.numdie; + ++game.numdie; - if (game.closng) { - /* He died during closing time. No resurrection. Tally up a - * death and exit. */ - rspeak(DEATH_CLOSING); - terminate(endgame); - } else if (!yes_or_no(query, yes_response, arbitrary_messages[OK_MAN]) - || game.numdie == NDEATHS) { - /* Player is asked if he wants to try again. If not, or if - * he's already used all of his lives, we end the game */ - terminate(endgame); - } else { - /* If player wishes to continue, we empty the liquids in the - * user's inventory, turn off the lamp, and drop all items - * where he died. */ - game.objects[WATER].place = game.objects[OIL].place = LOC_NOWHERE; - if (TOTING(LAMP)) - game.objects[LAMP].prop = LAMP_DARK; - for (int j = 1; j <= NOBJECTS; j++) { - int i = NOBJECTS + 1 - j; - if (TOTING(i)) { - /* Always leave lamp where it's accessible aboveground */ - drop(i, (i == LAMP) ? LOC_START : game.oldlc2); - } - } - game.oldloc = game.loc = game.newloc = LOC_BUILDING; - } + if (game.closng) { + /* He died during closing time. No resurrection. Tally up a + * death and exit. */ + rspeak(DEATH_CLOSING); + terminate(endgame); + } else if (!yes_or_no(query, yes_response, + arbitrary_messages[OK_MAN]) || + game.numdie == NDEATHS) { + /* Player is asked if he wants to try again. If not, or if + * he's already used all of his lives, we end the game */ + terminate(endgame); + } else { + /* If player wishes to continue, we empty the liquids in the + * user's inventory, turn off the lamp, and drop all items + * where he died. */ + game.objects[WATER].place = game.objects[OIL].place = + LOC_NOWHERE; + if (TOTING(LAMP)) + game.objects[LAMP].prop = LAMP_DARK; + for (int j = 1; j <= NOBJECTS; j++) { + int i = NOBJECTS + 1 - j; + if (TOTING(i)) { + /* Always leave lamp where it's accessible + * aboveground */ + drop(i, (i == LAMP) ? LOC_START : game.oldlc2); + } + } + game.oldloc = game.loc = game.newloc = LOC_BUILDING; + } } static void describe_location(void) { -/* Describe the location to the user */ - const char* msg = locations[game.loc].description.small; + /* Describe the location to the user */ + const char *msg = locations[game.loc].description.small; - if (MOD(game.locs[game.loc].abbrev, game.abbnum) == 0 || msg == NO_MESSAGE) - msg = locations[game.loc].description.big; + if (MOD(game.locs[game.loc].abbrev, game.abbnum) == 0 || + msg == NO_MESSAGE) + msg = locations[game.loc].description.big; - if (!FORCED(game.loc) && DARK(game.loc)) { - msg = arbitrary_messages[PITCH_DARK]; - } + if (!FORCED(game.loc) && DARK(game.loc)) { + msg = arbitrary_messages[PITCH_DARK]; + } - if (TOTING(BEAR)) { - rspeak(TAME_BEAR); - } + if (TOTING(BEAR)) { + rspeak(TAME_BEAR); + } - speak(msg); + speak(msg); - if (game.loc == LOC_Y2 && PCT(25) && !game.closng) - rspeak(SAYS_PLUGH); + if (game.loc == LOC_Y2 && PCT(25) && !game.closng) + rspeak(SAYS_PLUGH); } - static bool traveleq(int a, int b) { -/* Are two travel entries equal for purposes of skip after failed condition? */ - return (travel[a].condtype == travel[b].condtype) - && (travel[a].condarg1 == travel[b].condarg1) - && (travel[a].condarg2 == travel[b].condarg2) - && (travel[a].desttype == travel[b].desttype) - && (travel[a].destval == travel[b].destval); + /* Are two travel entries equal for purposes of skip after failed + * condition? */ + return (travel[a].condtype == travel[b].condtype) && + (travel[a].condarg1 == travel[b].condarg1) && + (travel[a].condarg2 == travel[b].condarg2) && + (travel[a].desttype == travel[b].desttype) && + (travel[a].destval == travel[b].destval); } /* Given the current location in "game.loc", and a motion verb number in @@ -523,297 +555,342 @@ static bool traveleq(int a, int b) { * does, game.newloc will be limbo, and game.oldloc will be what killed * him, so we need game.oldlc2, which is the last place he was * safe.) */ -static void playermove(int motion) -{ - int scratchloc, travel_entry = tkey[game.loc]; - game.newloc = game.loc; - if (travel_entry == 0) { - BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES); // LCOV_EXCL_LINE - } - if (motion == NUL) { - return; - } else if (motion == BACK) { - /* Handle "go back". Look for verb which goes from game.loc to - * game.oldloc, or to game.oldlc2 If game.oldloc has forced-motion. - * te_tmp saves entry -> forced loc -> previous loc. */ - motion = game.oldloc; - if (FORCED(motion)) - motion = game.oldlc2; - game.oldlc2 = game.oldloc; - game.oldloc = game.loc; - if (CNDBIT(game.loc, COND_NOBACK)) { - rspeak(TWIST_TURN); - return; - } - if (motion == game.loc) { - rspeak(FORGOT_PATH); - return; - } - - int te_tmp = 0; - for (;;) { - enum desttype_t desttype = travel[travel_entry].desttype; - scratchloc = travel[travel_entry].destval; - if (desttype != dest_goto || scratchloc != motion) { - if (desttype == dest_goto) { - if (FORCED(scratchloc) && travel[tkey[scratchloc]].destval == motion) - te_tmp = travel_entry; - } - if (!travel[travel_entry].stop) { - ++travel_entry; /* go to next travel entry for this location */ - continue; - } - /* we've reached the end of travel entries for game.loc */ - travel_entry = te_tmp; - if (travel_entry == 0) { - rspeak(NOT_CONNECTED); - return; - } - } - - motion = travel[travel_entry].motion; - travel_entry = tkey[game.loc]; - break; /* fall through to ordinary travel */ - } - } else if (motion == LOOK) { - /* Look. Can't give more detail. Pretend it wasn't dark - * (though it may now be dark) so he won't fall into a - * pit while staring into the gloom. */ - if (game.detail < 3) { - rspeak(NO_MORE_DETAIL); +static void playermove(int motion) { + int scratchloc, travel_entry = tkey[game.loc]; + game.newloc = game.loc; + if (travel_entry == 0) { + BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES); // LCOV_EXCL_LINE } - ++game.detail; - game.wzdark = false; - game.locs[game.loc].abbrev = 0; - return; - } else if (motion == CAVE) { - /* Cave. Different messages depending on whether above ground. */ - rspeak((OUTSID(game.loc) && game.loc != LOC_GRATE) ? FOLLOW_STREAM : NEED_DETAIL); - return; - } else { - /* none of the specials */ - game.oldlc2 = game.oldloc; - game.oldloc = game.loc; - } - - /* Look for a way to fulfil the motion verb passed in - travel_entry indexes - * the beginning of the motion entries for here (game.loc). */ - for (;;) { - if ((travel[travel_entry].motion == HERE) || travel[travel_entry].motion == motion) - break; - if (travel[travel_entry].stop) { - /* Couldn't find an entry matching the motion word passed - * in. Various messages depending on word given. */ - switch (motion) { - case EAST: - case WEST: - case SOUTH: - case NORTH: - case NE: - case NW: - case SW: - case SE: - case UP: - case DOWN: - rspeak(BAD_DIRECTION); - break; - case FORWARD: - case LEFT: - case RIGHT: - rspeak(UNSURE_FACING); - break; - case OUTSIDE: - case INSIDE: - rspeak(NO_INOUT_HERE); - break; - case XYZZY: - case PLUGH: - rspeak(NOTHING_HAPPENS); - break; - case CRAWL: - rspeak(WHICH_WAY); - break; - default: - rspeak(CANT_APPLY); - } - return; - } - ++travel_entry; - } - - /* (ESR) We've found a destination that goes with the motion verb. - * Next we need to check any conditional(s) on this destination, and - * possibly on following entries. */ - do { - for (;;) { /* L12 loop */ - for (;;) { - enum condtype_t condtype = travel[travel_entry].condtype; - int condarg1 = travel[travel_entry].condarg1; - int condarg2 = travel[travel_entry].condarg2; - if (condtype < cond_not) { - /* YAML N and [pct N] conditionals */ - if (condtype == cond_goto || condtype == cond_pct) { - if (condarg1 == 0 || PCT(condarg1)) - break; - /* else fall through */ - } - /* YAML [with OBJ] clause */ - else if (TOTING(condarg1) || (condtype == cond_with && AT(condarg1))) - break; - /* else fall through to check [not OBJ STATE] */ - } else if (game.objects[condarg1].prop != condarg2) { - break; + if (motion == NUL) { + return; + } else if (motion == BACK) { + /* Handle "go back". Look for verb which goes from game.loc to + * game.oldloc, or to game.oldlc2 If game.oldloc has + * forced-motion. te_tmp saves entry -> forced loc -> previous + * loc. */ + motion = game.oldloc; + if (FORCED(motion)) + motion = game.oldlc2; + game.oldlc2 = game.oldloc; + game.oldloc = game.loc; + if (CNDBIT(game.loc, COND_NOBACK)) { + rspeak(TWIST_TURN); + return; + } + if (motion == game.loc) { + rspeak(FORGOT_PATH); + return; } - /* We arrive here on conditional failure. - * Skip to next non-matching destination */ - int te_tmp = travel_entry; - do { - if (travel[te_tmp].stop) - BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE - ++te_tmp; - } while - (traveleq(travel_entry, te_tmp)); - travel_entry = te_tmp; - } - - /* Found an eligible rule, now execute it */ - enum desttype_t desttype = travel[travel_entry].desttype; - game.newloc = travel[travel_entry].destval; - if (desttype == dest_goto) { - return; - } - - if (desttype == dest_speak) { - /* Execute a speak rule */ - rspeak(game.newloc); - game.newloc = game.loc; - return; - } else { - switch (game.newloc) { - case 1: - /* Special travel 1. Plover-alcove passage. Can carry only - * emerald. Note: travel table must include "useless" - * entries going through passage, which can never be used - * for actual motion, but can be spotted by "go back". */ - game.newloc = (game.loc == LOC_PLOVER) - ? LOC_ALCOVE - : LOC_PLOVER; - if (game.holdng > 1 || (game.holdng == 1 && !TOTING(EMERALD))) { - game.newloc = game.loc; - rspeak(MUST_DROP); - } - return; - case 2: - /* Special travel 2. Plover transport. Drop the - * emerald (only use special travel if toting - * it), so he's forced to use the plover-passage - * to get it out. Having dropped it, go back and - * pretend he wasn't carrying it after all. */ - drop(EMERALD, game.loc); - { - int te_tmp = travel_entry; - do { - if (travel[te_tmp].stop) - BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE - ++te_tmp; - } while - (traveleq(travel_entry, te_tmp)); - travel_entry = te_tmp; - } - continue; /* goto L12 */ - case 3: - /* Special travel 3. Troll bridge. Must be done - * only as special motion so that dwarves won't - * wander across and encounter the bear. (They - * won't follow the player there because that - * region is forbidden to the pirate.) If - * game.prop[TROLL]=TROLL_PAIDONCE, he's crossed - * since paying, so step out and block him. - * (standard travel entries check for - * game.prop[TROLL]=TROLL_UNPAID.) Special stuff - * for bear. */ - if (game.objects[TROLL].prop == TROLL_PAIDONCE) { - pspeak(TROLL, look, true, TROLL_PAIDONCE); - game.objects[TROLL].prop = TROLL_UNPAID; - DESTROY(TROLL2); - move(TROLL2 + NOBJECTS, IS_FREE); - move(TROLL, objects[TROLL].plac); - move(TROLL + NOBJECTS, objects[TROLL].fixd); - juggle(CHASM); - game.newloc = game.loc; - return; - } else { - game.newloc = objects[TROLL].plac + objects[TROLL].fixd - game.loc; - if (game.objects[TROLL].prop == TROLL_UNPAID) - game.objects[TROLL].prop = TROLL_PAIDONCE; - if (!TOTING(BEAR)) { - return; + int te_tmp = 0; + for (;;) { + enum desttype_t desttype = + travel[travel_entry].desttype; + scratchloc = travel[travel_entry].destval; + if (desttype != dest_goto || scratchloc != motion) { + if (desttype == dest_goto) { + if (FORCED(scratchloc) && + travel[tkey[scratchloc]].destval == + motion) + te_tmp = travel_entry; + } + if (!travel[travel_entry].stop) { + ++travel_entry; /* go to next travel + entry for this + location */ + continue; + } + /* we've reached the end of travel entries for + * game.loc */ + travel_entry = te_tmp; + if (travel_entry == 0) { + rspeak(NOT_CONNECTED); + return; + } } - state_change(CHASM, BRIDGE_WRECKED); - game.objects[TROLL].prop = TROLL_GONE; - drop(BEAR, game.newloc); - game.objects[BEAR].fixed = IS_FIXED; - game.objects[BEAR].prop = BEAR_DEAD; - game.oldlc2 = game.newloc; - croak(); - return; - } - default: // LCOV_EXCL_LINE - BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE - } - } - break; /* Leave L12 loop */ - } - } while - (false); + + motion = travel[travel_entry].motion; + travel_entry = tkey[game.loc]; + break; /* fall through to ordinary travel */ + } + } else if (motion == LOOK) { + /* Look. Can't give more detail. Pretend it wasn't dark + * (though it may now be dark) so he won't fall into a + * pit while staring into the gloom. */ + if (game.detail < 3) { + rspeak(NO_MORE_DETAIL); + } + ++game.detail; + game.wzdark = false; + game.locs[game.loc].abbrev = 0; + return; + } else if (motion == CAVE) { + /* Cave. Different messages depending on whether above ground. + */ + rspeak((OUTSID(game.loc) && game.loc != LOC_GRATE) + ? FOLLOW_STREAM + : NEED_DETAIL); + return; + } else { + /* none of the specials */ + game.oldlc2 = game.oldloc; + game.oldloc = game.loc; + } + + /* Look for a way to fulfil the motion verb passed in - travel_entry + * indexes the beginning of the motion entries for here (game.loc). */ + for (;;) { + if ((travel[travel_entry].motion == HERE) || + travel[travel_entry].motion == motion) + break; + if (travel[travel_entry].stop) { + /* Couldn't find an entry matching the motion word + * passed in. Various messages depending on word given. + */ + switch (motion) { + case EAST: + case WEST: + case SOUTH: + case NORTH: + case NE: + case NW: + case SW: + case SE: + case UP: + case DOWN: + rspeak(BAD_DIRECTION); + break; + case FORWARD: + case LEFT: + case RIGHT: + rspeak(UNSURE_FACING); + break; + case OUTSIDE: + case INSIDE: + rspeak(NO_INOUT_HERE); + break; + case XYZZY: + case PLUGH: + rspeak(NOTHING_HAPPENS); + break; + case CRAWL: + rspeak(WHICH_WAY); + break; + default: + rspeak(CANT_APPLY); + } + return; + } + ++travel_entry; + } + + /* (ESR) We've found a destination that goes with the motion verb. + * Next we need to check any conditional(s) on this destination, and + * possibly on following entries. */ + do { + for (;;) { /* L12 loop */ + for (;;) { + enum condtype_t condtype = + travel[travel_entry].condtype; + int condarg1 = travel[travel_entry].condarg1; + int condarg2 = travel[travel_entry].condarg2; + if (condtype < cond_not) { + /* YAML N and [pct N] conditionals */ + if (condtype == cond_goto || + condtype == cond_pct) { + if (condarg1 == 0 || + PCT(condarg1)) + break; + /* else fall through */ + } + /* YAML [with OBJ] clause */ + else if (TOTING(condarg1) || + (condtype == cond_with && + AT(condarg1))) + break; + /* else fall through to check [not OBJ + * STATE] */ + } else if (game.objects[condarg1].prop != + condarg2) { + break; + } + + /* We arrive here on conditional failure. + * Skip to next non-matching destination */ + int te_tmp = travel_entry; + do { + if (travel[te_tmp].stop) + BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE + ++te_tmp; + } while (traveleq(travel_entry, te_tmp)); + travel_entry = te_tmp; + } + + /* Found an eligible rule, now execute it */ + enum desttype_t desttype = + travel[travel_entry].desttype; + game.newloc = travel[travel_entry].destval; + if (desttype == dest_goto) { + return; + } + + if (desttype == dest_speak) { + /* Execute a speak rule */ + rspeak(game.newloc); + game.newloc = game.loc; + return; + } else { + switch (game.newloc) { + case 1: + /* Special travel 1. Plover-alcove + * passage. Can carry only emerald. + * Note: travel table must include + * "useless" entries going through + * passage, which can never be used for + * actual motion, but can be spotted by + * "go back". */ + game.newloc = (game.loc == LOC_PLOVER) + ? LOC_ALCOVE + : LOC_PLOVER; + if (game.holdng > 1 || + (game.holdng == 1 && + !TOTING(EMERALD))) { + game.newloc = game.loc; + rspeak(MUST_DROP); + } + return; + case 2: + /* Special travel 2. Plover transport. + * Drop the emerald (only use special + * travel if toting it), so he's forced + * to use the plover-passage to get it + * out. Having dropped it, go back and + * pretend he wasn't carrying it after + * all. */ + drop(EMERALD, game.loc); + { + int te_tmp = travel_entry; + do { + if (travel[te_tmp].stop) + BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE + ++te_tmp; + } while (traveleq(travel_entry, + te_tmp)); + travel_entry = te_tmp; + } + continue; /* goto L12 */ + case 3: + /* Special travel 3. Troll bridge. Must + * be done only as special motion so + * that dwarves won't wander across and + * encounter the bear. (They won't + * follow the player there because that + * region is forbidden to the pirate.) + * If game.prop[TROLL]=TROLL_PAIDONCE, + * he's crossed since paying, so step + * out and block him. (standard travel + * entries check for + * game.prop[TROLL]=TROLL_UNPAID.) + * Special stuff for bear. */ + if (game.objects[TROLL].prop == + TROLL_PAIDONCE) { + pspeak(TROLL, look, true, + TROLL_PAIDONCE); + game.objects[TROLL].prop = + TROLL_UNPAID; + DESTROY(TROLL2); + move(TROLL2 + NOBJECTS, + IS_FREE); + move(TROLL, + objects[TROLL].plac); + move(TROLL + NOBJECTS, + objects[TROLL].fixd); + juggle(CHASM); + game.newloc = game.loc; + return; + } else { + game.newloc = + objects[TROLL].plac + + objects[TROLL].fixd - + game.loc; + if (game.objects[TROLL].prop == + TROLL_UNPAID) + game.objects[TROLL] + .prop = + TROLL_PAIDONCE; + if (!TOTING(BEAR)) { + return; + } + state_change(CHASM, + BRIDGE_WRECKED); + game.objects[TROLL].prop = + TROLL_GONE; + drop(BEAR, game.newloc); + game.objects[BEAR].fixed = + IS_FIXED; + game.objects[BEAR].prop = + BEAR_DEAD; + game.oldlc2 = game.newloc; + croak(); + return; + } + default: // LCOV_EXCL_LINE + BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE + } + } + break; /* Leave L12 loop */ + } + } while (false); } static void lampcheck(void) { -/* Check game limit and lamp timers */ - if (game.objects[LAMP].prop == LAMP_BRIGHT) { - --game.limit; - } - - /* Another way we can force an end to things is by having the - * lamp give out. When it gets close, we come here to warn him. - * First following arm checks if the lamp and fresh batteries are - * here, in which case we replace the batteries and continue. - * Second is for other cases of lamp dying. Even after it goes - * out, he can explore outside for a while if desired. */ - if (game.limit <= WARNTIME) { - if (HERE(BATTERY) && game.objects[BATTERY].prop == FRESH_BATTERIES && HERE(LAMP)) { - rspeak(REPLACE_BATTERIES); - game.objects[BATTERY].prop = DEAD_BATTERIES; -#ifdef __unused__ - /* This code from the original game seems to have been faulty. - * No tests ever passed the guard, and with the guard removed - * the game hangs when the lamp limit is reached. - */ - if (TOTING(BATTERY)) { - drop(BATTERY, game.loc); - } -#endif - game.limit += BATTERYLIFE; - game.lmwarn = false; - } else if (!game.lmwarn && HERE(LAMP)) { - game.lmwarn = true; - if (game.objects[BATTERY].prop == DEAD_BATTERIES) { - rspeak(MISSING_BATTERIES); - } else if (game.objects[BATTERY].place == LOC_NOWHERE) { - rspeak(LAMP_DIM); - } else { - rspeak(GET_BATTERIES); - } - } - } - if (game.limit == 0) { - game.limit = -1; - game.objects[LAMP].prop = LAMP_DARK; - if (HERE(LAMP)) { - rspeak(LAMP_OUT); + /* Check game limit and lamp timers */ + if (game.objects[LAMP].prop == LAMP_BRIGHT) { + --game.limit; + } + + /* Another way we can force an end to things is by having the + * lamp give out. When it gets close, we come here to warn him. + * First following arm checks if the lamp and fresh batteries are + * here, in which case we replace the batteries and continue. + * Second is for other cases of lamp dying. Even after it goes + * out, he can explore outside for a while if desired. */ + if (game.limit <= WARNTIME) { + if (HERE(BATTERY) && + game.objects[BATTERY].prop == FRESH_BATTERIES && + HERE(LAMP)) { + rspeak(REPLACE_BATTERIES); + game.objects[BATTERY].prop = DEAD_BATTERIES; +#ifdef __unused__ + /* This code from the original game seems to have been + * faulty. No tests ever passed the guard, and with the + * guard removed the game hangs when the lamp limit is + * reached. + */ + if (TOTING(BATTERY)) { + drop(BATTERY, game.loc); + } +#endif + game.limit += BATTERYLIFE; + game.lmwarn = false; + } else if (!game.lmwarn && HERE(LAMP)) { + game.lmwarn = true; + if (game.objects[BATTERY].prop == DEAD_BATTERIES) { + rspeak(MISSING_BATTERIES); + } else if (game.objects[BATTERY].place == LOC_NOWHERE) { + rspeak(LAMP_DIM); + } else { + rspeak(GET_BATTERIES); + } + } + } + if (game.limit == 0) { + game.limit = -1; + game.objects[LAMP].prop = LAMP_DARK; + if (HERE(LAMP)) { + rspeak(LAMP_OUT); + } } - } } /* Handle the closing of the cave. The cave closes "clock1" turns @@ -835,464 +912,503 @@ static void lampcheck(void) { * arise from the use of negative prop numbers to suppress the object * descriptions until he's actually moved the objects. */ static bool closecheck(void) { - /* If a turn threshold has been met, apply penalties and tell - * the player about it. */ - for (int i = 0; i < NTHRESHOLDS; ++i) { - if (game.turns == turn_thresholds[i].threshold + 1) { - game.trnluz += turn_thresholds[i].point_loss; - speak(turn_thresholds[i].message); - } - } - - /* Don't tick game.clock1 unless well into cave (and not at Y2). */ - if (game.tally == 0 && INDEEP(game.loc) && game.loc != LOC_Y2) { - --game.clock1; - } - - /* When the first warning comes, we lock the grate, destroy - * the bridge, kill all the dwarves (and the pirate), remove - * the troll and bear (unless dead), and set "closng" to - * true. Leave the dragon; too much trouble to move it. - * from now until clock2 runs out, he cannot unlock the - * grate, move to any location outside the cave, or create - * the bridge. Nor can he be resurrected if he dies. Note - * that the snake is already gone, since he got to the - * treasure accessible only via the hall of the mountain - * king. Also, he's been in giant room (to get eggs), so we - * can refer to it. Also also, he's gotten the pearl, so we - * know the bivalve is an oyster. *And*, the dwarves must - * have been activated, since we've found chest. */ - if (game.clock1 == 0) { - game.objects[GRATE].prop = GRATE_CLOSED; - game.objects[FISSURE].prop = UNBRIDGED; - for (int i = 1; i <= NDWARVES; i++) { - game.dwarves[i].seen = false; - game.dwarves[i].loc = LOC_NOWHERE; - } - DESTROY(TROLL); - move(TROLL + NOBJECTS, IS_FREE); - move(TROLL2, objects[TROLL].plac); - move(TROLL2 + NOBJECTS, objects[TROLL].fixd); - juggle(CHASM); - if (game.objects[BEAR].prop != BEAR_DEAD) { - DESTROY(BEAR); + /* If a turn threshold has been met, apply penalties and tell + * the player about it. */ + for (int i = 0; i < NTHRESHOLDS; ++i) { + if (game.turns == turn_thresholds[i].threshold + 1) { + game.trnluz += turn_thresholds[i].point_loss; + speak(turn_thresholds[i].message); + } } - game.objects[CHAIN].prop = CHAIN_HEAP; - game.objects[CHAIN].fixed = IS_FREE; - game.objects[AXE].prop = AXE_HERE; - game.objects[AXE].fixed = IS_FREE; - rspeak(CAVE_CLOSING); - game.clock1 = -1; - game.closng = true; - return game.closed; - } else if (game.clock1 < 0) - --game.clock2; - if (game.clock2 == 0) { - /* Once he's panicked, and clock2 has run out, we come here - * to set up the storage room. The room has two locs, - * hardwired as LOC_NE and LOC_SW. At the ne end, we - * place empty bottles, a nursery of plants, a bed of - * oysters, a pile of lamps, rods with stars, sleeping - * dwarves, and him. At the sw end we place grate over - * treasures, snake pit, covey of caged birds, more rods, and - * pillows. A mirror stretches across one wall. Many of the - * objects come from known locations and/or states (e.g. the - * snake is known to have been destroyed and needn't be - * carried away from its old "place"), making the various - * objects be handled differently. We also drop all other - * objects he might be carrying (lest he has some which - * could cause trouble, such as the keys). We describe the - * flash of light and trundle back. */ - put(BOTTLE, LOC_NE, EMPTY_BOTTLE); - put(PLANT, LOC_NE, PLANT_THIRSTY); - put(OYSTER, LOC_NE, STATE_FOUND); - put(LAMP, LOC_NE, LAMP_DARK); - put(ROD, LOC_NE, STATE_FOUND); - put(DWARF, LOC_NE, STATE_FOUND); - game.loc = LOC_NE; - game.oldloc = LOC_NE; - game.newloc = LOC_NE; - /* Leave the grate with normal (non-negative) property. - * Reuse sign. */ - move(GRATE, LOC_SW); - move(SIGN, LOC_SW); - game.objects[SIGN].prop = ENDGAME_SIGN; - put(SNAKE, LOC_SW, SNAKE_CHASED); - put(BIRD, LOC_SW, BIRD_CAGED); - put(CAGE, LOC_SW, STATE_FOUND); - put(ROD2, LOC_SW, STATE_FOUND); - put(PILLOW, LOC_SW, STATE_FOUND); - put(MIRROR, LOC_NE, STATE_FOUND); - game.objects[MIRROR].fixed = LOC_SW; + /* Don't tick game.clock1 unless well into cave (and not at Y2). */ + if (game.tally == 0 && INDEEP(game.loc) && game.loc != LOC_Y2) { + --game.clock1; + } - for (int i = 1; i <= NOBJECTS; i++) { - if (TOTING(i)) { - DESTROY(i); - } - } + /* When the first warning comes, we lock the grate, destroy + * the bridge, kill all the dwarves (and the pirate), remove + * the troll and bear (unless dead), and set "closng" to + * true. Leave the dragon; too much trouble to move it. + * from now until clock2 runs out, he cannot unlock the + * grate, move to any location outside the cave, or create + * the bridge. Nor can he be resurrected if he dies. Note + * that the snake is already gone, since he got to the + * treasure accessible only via the hall of the mountain + * king. Also, he's been in giant room (to get eggs), so we + * can refer to it. Also also, he's gotten the pearl, so we + * know the bivalve is an oyster. *And*, the dwarves must + * have been activated, since we've found chest. */ + if (game.clock1 == 0) { + game.objects[GRATE].prop = GRATE_CLOSED; + game.objects[FISSURE].prop = UNBRIDGED; + for (int i = 1; i <= NDWARVES; i++) { + game.dwarves[i].seen = false; + game.dwarves[i].loc = LOC_NOWHERE; + } + DESTROY(TROLL); + move(TROLL + NOBJECTS, IS_FREE); + move(TROLL2, objects[TROLL].plac); + move(TROLL2 + NOBJECTS, objects[TROLL].fixd); + juggle(CHASM); + if (game.objects[BEAR].prop != BEAR_DEAD) { + DESTROY(BEAR); + } + game.objects[CHAIN].prop = CHAIN_HEAP; + game.objects[CHAIN].fixed = IS_FREE; + game.objects[AXE].prop = AXE_HERE; + game.objects[AXE].fixed = IS_FREE; + rspeak(CAVE_CLOSING); + game.clock1 = -1; + game.closng = true; + return game.closed; + } else if (game.clock1 < 0) + --game.clock2; + if (game.clock2 == 0) { + /* Once he's panicked, and clock2 has run out, we come here + * to set up the storage room. The room has two locs, + * hardwired as LOC_NE and LOC_SW. At the ne end, we + * place empty bottles, a nursery of plants, a bed of + * oysters, a pile of lamps, rods with stars, sleeping + * dwarves, and him. At the sw end we place grate over + * treasures, snake pit, covey of caged birds, more rods, and + * pillows. A mirror stretches across one wall. Many of the + * objects come from known locations and/or states (e.g. the + * snake is known to have been destroyed and needn't be + * carried away from its old "place"), making the various + * objects be handled differently. We also drop all other + * objects he might be carrying (lest he has some which + * could cause trouble, such as the keys). We describe the + * flash of light and trundle back. */ + put(BOTTLE, LOC_NE, EMPTY_BOTTLE); + put(PLANT, LOC_NE, PLANT_THIRSTY); + put(OYSTER, LOC_NE, STATE_FOUND); + put(LAMP, LOC_NE, LAMP_DARK); + put(ROD, LOC_NE, STATE_FOUND); + put(DWARF, LOC_NE, STATE_FOUND); + game.loc = LOC_NE; + game.oldloc = LOC_NE; + game.newloc = LOC_NE; + /* Leave the grate with normal (non-negative) property. + * Reuse sign. */ + move(GRATE, LOC_SW); + move(SIGN, LOC_SW); + game.objects[SIGN].prop = ENDGAME_SIGN; + put(SNAKE, LOC_SW, SNAKE_CHASED); + put(BIRD, LOC_SW, BIRD_CAGED); + put(CAGE, LOC_SW, STATE_FOUND); + put(ROD2, LOC_SW, STATE_FOUND); + put(PILLOW, LOC_SW, STATE_FOUND); - rspeak(CAVE_CLOSED); - game.closed = true; - return game.closed; - } + put(MIRROR, LOC_NE, STATE_FOUND); + game.objects[MIRROR].fixed = LOC_SW; - lampcheck(); - return false; + for (int i = 1; i <= NOBJECTS; i++) { + if (TOTING(i)) { + DESTROY(i); + } + } + + rspeak(CAVE_CLOSED); + game.closed = true; + return game.closed; + } + + lampcheck(); + return false; } static void listobjects(void) { -/* Print out descriptions of objects at this location. If - * not closing and property value is negative, tally off - * another treasure. Rug is special case; once seen, its - * game.prop is RUG_DRAGON (dragon on it) till dragon is killed. - * Similarly for chain; game.prop is initially CHAINING_BEAR (locked to - * bear). These hacks are because game.prop=0 is needed to - * get full score. */ - if (!DARK(game.loc)) { - ++game.locs[game.loc].abbrev; - for (int i = game.locs[game.loc].atloc; i != 0; i = game.link[i]) { - obj_t obj = i; - if (obj > NOBJECTS) { - obj = obj - NOBJECTS; - } - if (obj == STEPS && TOTING(NUGGET)) { - continue; - } - /* (ESR) Warning: it looks like you could get away with - * running this code only on objects with the treasure - * property set. Nope. There is mystery here. - */ - if (PROP_IS_STASHED_OR_UNSEEN(obj)) { - if (game.closed) { - continue; + /* Print out descriptions of objects at this location. If + * not closing and property value is negative, tally off + * another treasure. Rug is special case; once seen, its + * game.prop is RUG_DRAGON (dragon on it) till dragon is killed. + * Similarly for chain; game.prop is initially CHAINING_BEAR (locked to + * bear). These hacks are because game.prop=0 is needed to + * get full score. */ + if (!DARK(game.loc)) { + ++game.locs[game.loc].abbrev; + for (int i = game.locs[game.loc].atloc; i != 0; + i = game.link[i]) { + obj_t obj = i; + if (obj > NOBJECTS) { + obj = obj - NOBJECTS; + } + if (obj == STEPS && TOTING(NUGGET)) { + continue; + } + /* (ESR) Warning: it looks like you could get away with + * running this code only on objects with the treasure + * property set. Nope. There is mystery here. + */ + if (PROP_IS_STASHED_OR_UNSEEN(obj)) { + if (game.closed) { + continue; + } + PROP_SET_FOUND(obj); + if (obj == RUG) { + game.objects[RUG].prop = RUG_DRAGON; + } + if (obj == CHAIN) { + game.objects[CHAIN].prop = + CHAINING_BEAR; + } + if (obj == EGGS) { + game.seenbigwords = true; + } + --game.tally; + /* Note: There used to be a test here to see + * whether the player had blown it so badly that + * he could never ever see the remaining + * treasures, and if so the lamp was zapped to + * 35 turns. But the tests were too + * simple-minded; things like killing the bird + * before the snake was gone (can never see + * jewelry), and doing it "right" was hopeless. + * E.G., could cross troll bridge several times, + * using up all available treasures, breaking + * vase, using coins to buy batteries, etc., and + * eventually never be able to get across again. + * If bottle were left on far side, could then + * never get eggs or trident, and the effects + * propagate. So the whole thing was flushed. + * anyone who makes such a gross blunder isn't + * likely to find everything else anyway (so + * goes the rationalisation). */ + } + int kk = game.objects[obj].prop; + if (obj == STEPS) { + kk = (game.loc == game.objects[STEPS].fixed) + ? STEPS_UP + : STEPS_DOWN; + } + pspeak(obj, look, true, kk); } - PROP_SET_FOUND(obj); - if (obj == RUG) { - game.objects[RUG].prop = RUG_DRAGON; - } - if (obj == CHAIN) { - game.objects[CHAIN].prop = CHAINING_BEAR; - } - if (obj == EGGS) { - game.seenbigwords = true; - } - --game.tally; - /* Note: There used to be a test here to see whether the - * player had blown it so badly that he could never ever see - * the remaining treasures, and if so the lamp was zapped to - * 35 turns. But the tests were too simple-minded; things - * like killing the bird before the snake was gone (can never - * see jewelry), and doing it "right" was hopeless. E.G., - * could cross troll bridge several times, using up all - * available treasures, breaking vase, using coins to buy - * batteries, etc., and eventually never be able to get - * across again. If bottle were left on far side, could then - * never get eggs or trident, and the effects propagate. So - * the whole thing was flushed. anyone who makes such a - * gross blunder isn't likely to find everything else anyway - * (so goes the rationalisation). */ - } - int kk = game.objects[obj].prop; - if (obj == STEPS) { - kk = (game.loc == game.objects[STEPS].fixed) - ? STEPS_UP - : STEPS_DOWN; - } - pspeak(obj, look, true, kk); - } - } + } } -/* Pre-processes a command input to see if we need to tease out a few specific cases: +/* Pre-processes a command input to see if we need to tease out a few specific + * cases: * - "enter water" or "enter stream": - * weird specific case that gets the user wet, and then kicks us back to get another command + * weird specific case that gets the user wet, and then kicks us back to get + * another command * - : - * Irregular form of input, but should be allowed. We switch back to form for - * further processing. + * Irregular form of input, but should be allowed. We switch back to + * form for further processing. * - "grate": - * If in location with grate, we move to that grate. If we're in a number of other places, - * we move to the entrance. + * If in location with grate, we move to that grate. If we're in a number of + * other places, we move to the entrance. * - "water plant", "oil plant", "water door", "oil door": * Change to "pour water" or "pour oil" based on context * - "cage bird": * If bird is present, we change to "carry bird" * - * Returns true if pre-processing is complete, and we're ready to move to the primary command - * processing, false otherwise. */ + * Returns true if pre-processing is complete, and we're ready to move to the + * primary command processing, false otherwise. */ static bool preprocess_command(command_t *command) { - if (command->word[0].type == MOTION && command->word[0].id == ENTER - && (command->word[1].id == STREAM || command->word[1].id == WATER)) { - if (LIQLOC(game.loc) == WATER) { - rspeak(FEET_WET); + if (command->word[0].type == MOTION && command->word[0].id == ENTER && + (command->word[1].id == STREAM || command->word[1].id == WATER)) { + if (LIQLOC(game.loc) == WATER) { + rspeak(FEET_WET); + } else { + rspeak(WHERE_QUERY); + } } else { - rspeak(WHERE_QUERY); + if (command->word[0].type == OBJECT) { + /* From OV to VO form */ + if (command->word[1].type == ACTION) { + command_word_t stage = command->word[0]; + command->word[0] = command->word[1]; + command->word[1] = stage; + } + + if (command->word[0].id == GRATE) { + command->word[0].type = MOTION; + if (game.loc == LOC_START || + game.loc == LOC_VALLEY || + game.loc == LOC_SLIT) { + command->word[0].id = DEPRESSION; + } + if (game.loc == LOC_COBBLE || + game.loc == LOC_DEBRIS || + game.loc == LOC_AWKWARD || + game.loc == LOC_BIRDCHAMBER || + game.loc == LOC_PITTOP) { + command->word[0].id = ENTRANCE; + } + } + if ((command->word[0].id == WATER || + command->word[0].id == OIL) && + (command->word[1].id == PLANT || + command->word[1].id == DOOR)) { + if (AT(command->word[1].id)) { + command->word[1] = command->word[0]; + command->word[0].id = POUR; + command->word[0].type = ACTION; + strncpy(command->word[0].raw, "pour", + LINESIZE - 1); + } + } + if (command->word[0].id == CAGE && + command->word[1].id == BIRD && HERE(CAGE) && + HERE(BIRD)) { + command->word[0].id = CARRY; + command->word[0].type = ACTION; + } + } + + /* If no word type is given for the first word, we assume it's a + * motion. */ + if (command->word[0].type == NO_WORD_TYPE) + command->word[0].type = MOTION; + + command->state = PREPROCESSED; + return true; } - } else { - if (command->word[0].type == OBJECT) { - /* From OV to VO form */ - if (command->word[1].type == ACTION) { - command_word_t stage = command->word[0]; - command->word[0] = command->word[1]; - command->word[1] = stage; - } - - if (command->word[0].id == GRATE) { - command->word[0].type = MOTION; - if (game.loc == LOC_START || - game.loc == LOC_VALLEY || - game.loc == LOC_SLIT) { - command->word[0].id = DEPRESSION; - } - if (game.loc == LOC_COBBLE || - game.loc == LOC_DEBRIS || - game.loc == LOC_AWKWARD || - game.loc == LOC_BIRDCHAMBER || - game.loc == LOC_PITTOP) { - command->word[0].id = ENTRANCE; - } - } - if ((command->word[0].id == WATER || command->word[0].id == OIL) && - (command->word[1].id == PLANT || command->word[1].id == DOOR)) { - if (AT(command->word[1].id)) { - command->word[1] = command->word[0]; - command->word[0].id = POUR; - command->word[0].type = ACTION; - strncpy(command->word[0].raw, "pour", LINESIZE - 1); - } - } - if (command->word[0].id == CAGE && command->word[1].id == BIRD && HERE(CAGE) && HERE(BIRD)) { - command->word[0].id = CARRY; - command->word[0].type = ACTION; - } - } - - /* If no word type is given for the first word, we assume it's a motion. */ - if (command->word[0].type == NO_WORD_TYPE) - command->word[0].type = MOTION; - - command->state = PREPROCESSED; - return true; - } - return false; + return false; } static bool do_move(void) { -/* Actually execute the move to the new location and dwarf movement */ - /* Can't leave cave once it's closing (except by main office). */ - if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) { - rspeak(EXIT_CLOSED); - game.newloc = game.loc; - if (!game.panic) { - game.clock2 = PANICTIME; + /* Actually execute the move to the new location and dwarf movement */ + /* Can't leave cave once it's closing (except by main office). */ + if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) { + rspeak(EXIT_CLOSED); + game.newloc = game.loc; + if (!game.panic) { + game.clock2 = PANICTIME; + } + game.panic = true; } - game.panic = true; - } - /* See if a dwarf has seen him and has come from where he - * wants to go. If so, the dwarf's blocking his way. If - * coming from place forbidden to pirate (dwarves rooted in - * place) let him get out (and attacked). */ - if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc, COND_NOARRR)) { - for (size_t i = 1; i <= NDWARVES - 1; i++) { - if (game.dwarves[i].oldloc == game.newloc && game.dwarves[i].seen) { - game.newloc = game.loc; - rspeak(DWARF_BLOCK); - break; - } - } - } - game.loc = game.newloc; + /* See if a dwarf has seen him and has come from where he + * wants to go. If so, the dwarf's blocking his way. If + * coming from place forbidden to pirate (dwarves rooted in + * place) let him get out (and attacked). */ + if (game.newloc != game.loc && !FORCED(game.loc) && + !CNDBIT(game.loc, COND_NOARRR)) { + for (size_t i = 1; i <= NDWARVES - 1; i++) { + if (game.dwarves[i].oldloc == game.newloc && + game.dwarves[i].seen) { + game.newloc = game.loc; + rspeak(DWARF_BLOCK); + break; + } + } + } + game.loc = game.newloc; - if (!dwarfmove()) { - croak(); - } + if (!dwarfmove()) { + croak(); + } - if (game.loc == LOC_NOWHERE) { - croak(); - } + if (game.loc == LOC_NOWHERE) { + croak(); + } - /* The easiest way to get killed is to fall into a pit in - * pitch darkness. */ - if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && PCT(PIT_KILL_PROB)) { - rspeak(PIT_FALL); - game.oldlc2 = game.loc; - croak(); - return false; - } + /* The easiest way to get killed is to fall into a pit in + * pitch darkness. */ + if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && + PCT(PIT_KILL_PROB)) { + rspeak(PIT_FALL); + game.oldlc2 = game.loc; + croak(); + return false; + } - return true; + return true; } static bool do_command(void) { -/* Get and execute a command */ - static command_t command; - clear_command(&command); + /* Get and execute a command */ + static command_t command; + clear_command(&command); - /* Describe the current location and (maybe) get next command. */ - while (command.state != EXECUTED) { - describe_location(); + /* Describe the current location and (maybe) get next command. */ + while (command.state != EXECUTED) { + describe_location(); - if (FORCED(game.loc)) { - playermove(HERE); - return true; - } - - listobjects(); - - /* Command not yet given; keep getting commands from user - * until valid command is both given and executed. */ - clear_command(&command); - while (command.state <= GIVEN) { - - if (game.closed) { - /* If closing time, check for any stashed objects - * being toted and unstash them. This way objects - * won't be described until they've been picked up - * and put down separate from their respective - * piles. */ - if ((PROP_IS_NOTFOUND(OYSTER) || PROP_IS_STASHED(OYSTER)) && TOTING(OYSTER)) { - pspeak(OYSTER, look, true, 1); - } - for (size_t i = 1; i <= NOBJECTS; i++) { - if (TOTING(i) && (PROP_IS_NOTFOUND(i) || PROP_IS_STASHED(i))) - game.objects[i].prop = PROP_STASHED(i); - } - } - - /* Check to see if the room is dark. If the knife is here, - * and it's dark, the knife permanently disappears */ - game.wzdark = DARK(game.loc); - if (game.knfloc != LOC_NOWHERE && game.knfloc != game.loc) { - game.knfloc = LOC_NOWHERE; - } - - /* Check some for hints, get input from user, increment - * turn, and pre-process commands. Keep going until - * pre-processing is done. */ - while ( command.state < PREPROCESSED ) { - checkhints(); - - /* Get command input from user */ - if (!get_command_input(&command)) { - return false; + if (FORCED(game.loc)) { + playermove(HERE); + return true; } - /* Every input, check "foobar" flag. If zero, nothing's going - * on. If pos, make neg. If neg, he skipped a word, so make it - * zero. - */ - game.foobar = (game.foobar > WORD_EMPTY) ? -game.foobar : WORD_EMPTY; + listobjects(); - ++game.turns; - preprocess_command(&command); - } + /* Command not yet given; keep getting commands from user + * until valid command is both given and executed. */ + clear_command(&command); + while (command.state <= GIVEN) { - /* check if game is closed, and exit if it is */ - if (closecheck()) { - return true; - } + if (game.closed) { + /* If closing time, check for any stashed + * objects being toted and unstash them. This + * way objects won't be described until they've + * been picked up and put down separate from + * their respective piles. */ + if ((PROP_IS_NOTFOUND(OYSTER) || + PROP_IS_STASHED(OYSTER)) && + TOTING(OYSTER)) { + pspeak(OYSTER, look, true, 1); + } + for (size_t i = 1; i <= NOBJECTS; i++) { + if (TOTING(i) && (PROP_IS_NOTFOUND(i) || + PROP_IS_STASHED(i))) + game.objects[i].prop = + PROP_STASHED(i); + } + } - /* loop until all words in command are processed */ - while (command.state == PREPROCESSED ) { - command.state = PROCESSING; + /* Check to see if the room is dark. If the knife is + * here, and it's dark, the knife permanently disappears + */ + game.wzdark = DARK(game.loc); + if (game.knfloc != LOC_NOWHERE && + game.knfloc != game.loc) { + game.knfloc = LOC_NOWHERE; + } - if (command.word[0].id == WORD_NOT_FOUND) { - /* Gee, I don't understand. */ - sspeak(DONT_KNOW, command.word[0].raw); - clear_command(&command); - continue; - } + /* Check some for hints, get input from user, increment + * turn, and pre-process commands. Keep going until + * pre-processing is done. */ + while (command.state < PREPROCESSED) { + checkhints(); - /* Give user hints of shortcuts */ - if (strncasecmp(command.word[0].raw, "west", sizeof("west")) == 0) { - if (++game.iwest == 10) { - rspeak(W_IS_WEST); - } - } - if (strncasecmp(command.word[0].raw, "go", sizeof("go")) == 0 && command.word[1].id != WORD_EMPTY) { - if (++game.igo == 10) { - rspeak(GO_UNNEEDED); - } - } + /* Get command input from user */ + if (!get_command_input(&command)) { + return false; + } - switch (command.word[0].type) { - case MOTION: - playermove(command.word[0].id); - command.state = EXECUTED; - continue; - case OBJECT: - command.part = unknown; - command.obj = command.word[0].id; - break; - case ACTION: - if (command.word[1].type == NUMERIC) { - command.part = transitive; - } else { - command.part = intransitive; - } - command.verb = command.word[0].id; - break; - case NUMERIC: - if (!settings.oldstyle) { - sspeak(DONT_KNOW, command.word[0].raw); - clear_command(&command); - continue; - } - break;// LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - case NO_WORD_TYPE: // LCOV_EXCL_LINE - BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE - } + /* Every input, check "foobar" flag. If zero, + * nothing's going on. If pos, make neg. If neg, + * he skipped a word, so make it zero. + */ + game.foobar = (game.foobar > WORD_EMPTY) + ? -game.foobar + : WORD_EMPTY; - switch (action(command)) { - case GO_TERMINATE: - command.state = EXECUTED; - break; - case GO_MOVE: - playermove(NUL); - command.state = EXECUTED; - break; - case GO_WORD2: + ++game.turns; + preprocess_command(&command); + } + + /* check if game is closed, and exit if it is */ + if (closecheck()) { + return true; + } + + /* loop until all words in command are processed */ + while (command.state == PREPROCESSED) { + command.state = PROCESSING; + + if (command.word[0].id == WORD_NOT_FOUND) { + /* Gee, I don't understand. */ + sspeak(DONT_KNOW, command.word[0].raw); + clear_command(&command); + continue; + } + + /* Give user hints of shortcuts */ + if (strncasecmp(command.word[0].raw, "west", + sizeof("west")) == 0) { + if (++game.iwest == 10) { + rspeak(W_IS_WEST); + } + } + if (strncasecmp(command.word[0].raw, "go", + sizeof("go")) == 0 && + command.word[1].id != WORD_EMPTY) { + if (++game.igo == 10) { + rspeak(GO_UNNEEDED); + } + } + + switch (command.word[0].type) { + case MOTION: + playermove(command.word[0].id); + command.state = EXECUTED; + continue; + case OBJECT: + command.part = unknown; + command.obj = command.word[0].id; + break; + case ACTION: + if (command.word[1].type == NUMERIC) { + command.part = transitive; + } else { + command.part = intransitive; + } + command.verb = command.word[0].id; + break; + case NUMERIC: + if (!settings.oldstyle) { + sspeak(DONT_KNOW, + command.word[0].raw); + clear_command(&command); + continue; + } + break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + case NO_WORD_TYPE: // LCOV_EXCL_LINE + BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE + } + + switch (action(command)) { + case GO_TERMINATE: + command.state = EXECUTED; + break; + case GO_MOVE: + playermove(NUL); + command.state = EXECUTED; + break; + case GO_WORD2: #ifdef GDEBUG - printf("Word shift\n"); + printf("Word shift\n"); #endif /* GDEBUG */ - /* Get second word for analysis. */ - command.word[0] = command.word[1]; - command.word[1] = empty_command_word; - command.state = PREPROCESSED; - break; - case GO_UNKNOWN: - /* Random intransitive verbs come here. Clear obj just in case - * (see attack()). */ - command.word[0].raw[0] = toupper(command.word[0].raw[0]); - sspeak(DO_WHAT, command.word[0].raw); - command.obj = NO_OBJECT; + /* Get second word for analysis. */ + command.word[0] = command.word[1]; + command.word[1] = empty_command_word; + command.state = PREPROCESSED; + break; + case GO_UNKNOWN: + /* Random intransitive verbs come here. + * Clear obj just in case (see + * attack()). */ + command.word[0].raw[0] = + toupper(command.word[0].raw[0]); + sspeak(DO_WHAT, command.word[0].raw); + command.obj = NO_OBJECT; - /* object cleared; we need to go back to the preprocessing step */ - command.state = GIVEN; - break; - case GO_CHECKHINT: // FIXME: re-name to be more contextual; this was previously a label - command.state = GIVEN; - break; - case GO_DWARFWAKE: - /* Oh dear, he's disturbed the dwarves. */ - rspeak(DWARVES_AWAKEN); - terminate(endgame); - case GO_CLEAROBJ: // FIXME: re-name to be more contextual; this was previously a label - clear_command(&command); - break; - case GO_TOP: // FIXME: re-name to be more contextual; this was previously a label - break; - default: // LCOV_EXCL_LINE - BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE - } - } /* while command has not been fully processed */ - } /* while command is not yet given */ - } /* while command is not executed */ + /* object cleared; we need to go back to + * the preprocessing step */ + command.state = GIVEN; + break; + case GO_CHECKHINT: // FIXME: re-name to be more + // contextual; this was + // previously a label + command.state = GIVEN; + break; + case GO_DWARFWAKE: + /* Oh dear, he's disturbed the dwarves. + */ + rspeak(DWARVES_AWAKEN); + terminate(endgame); + case GO_CLEAROBJ: // FIXME: re-name to be more + // contextual; this was + // previously a label + clear_command(&command); + break; + case GO_TOP: // FIXME: re-name to be more + // contextual; this was previously + // a label + break; + default: // LCOV_EXCL_LINE + BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE + } + } /* while command has not been fully processed */ + } /* while command is not yet given */ + } /* while command is not executed */ - /* command completely executed; we return true. */ - return true; + /* command completely executed; we return true. */ + return true; } /* @@ -1306,132 +1422,140 @@ static bool do_command(void) { * Revived 2017 as Open Adventure. */ -int main(int argc, char *argv[]) -{ - int ch; +int main(int argc, char *argv[]) { + int ch; - /* Options. */ + /* Options. */ #if defined ADVENT_AUTOSAVE - const char* opts = "dl:oa:"; - const char* usage = "Usage: %s [-l logfilename] [-o] [-a filename] [script...]\n"; - FILE *rfp = NULL; - const char* autosave_filename = NULL; + const char *opts = "dl:oa:"; + const char *usage = + "Usage: %s [-l logfilename] [-o] [-a filename] [script...]\n"; + FILE *rfp = NULL; + const char *autosave_filename = NULL; #elif !defined ADVENT_NOSAVE - const char* opts = "dl:or:"; - const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n"; - FILE *rfp = NULL; + const char *opts = "dl:or:"; + const char *usage = "Usage: %s [-l logfilename] [-o] [-r " + "restorefilename] [script...]\n"; + FILE *rfp = NULL; #else - const char* opts = "dl:o"; - const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n"; + const char *opts = "dl:o"; + const char *usage = "Usage: %s [-l logfilename] [-o] [script...]\n"; #endif - while ((ch = getopt(argc, argv, opts)) != EOF) { - switch (ch) { - case 'd': // LCOV_EXCL_LINE - settings.debug +=1; // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE - case 'l': - settings.logfp = fopen(optarg, "w"); - if (settings.logfp == NULL) { - fprintf(stderr, - "advent: can't open logfile %s for write\n", - optarg); - } - signal(SIGINT, sig_handler); - break; - case 'o': - settings.oldstyle = true; - settings.prompt = false; - break; + while ((ch = getopt(argc, argv, opts)) != EOF) { + switch (ch) { + case 'd': // LCOV_EXCL_LINE + settings.debug += 1; // LCOV_EXCL_LINE + break; // LCOV_EXCL_LINE + case 'l': + settings.logfp = fopen(optarg, "w"); + if (settings.logfp == NULL) { + fprintf( + stderr, + "advent: can't open logfile %s for write\n", + optarg); + } + signal(SIGINT, sig_handler); + break; + case 'o': + settings.oldstyle = true; + settings.prompt = false; + break; #ifdef ADVENT_AUTOSAVE - case 'a': - rfp = fopen(optarg, READ_MODE); - autosave_filename = optarg; - signal(SIGHUP, sig_handler); - signal(SIGTERM, sig_handler); - break; + case 'a': + rfp = fopen(optarg, READ_MODE); + autosave_filename = optarg; + signal(SIGHUP, sig_handler); + signal(SIGTERM, sig_handler); + break; #elif !defined ADVENT_NOSAVE - case 'r': - rfp = fopen(optarg, "r"); - if (rfp == NULL) { - fprintf(stderr, - "advent: can't open save file %s for read\n", - optarg); - } - break; + case 'r': + rfp = fopen(optarg, "r"); + if (rfp == NULL) { + fprintf(stderr, + "advent: can't open save file %s for " + "read\n", + optarg); + } + break; #endif - default: - fprintf(stderr, - usage, argv[0]); - fprintf(stderr, - " -l create a log file of your game named as specified'\n"); - fprintf(stderr, - " -o 'oldstyle' (no prompt, no command editing, displays 'Initialising...')\n"); + default: + fprintf(stderr, usage, argv[0]); + fprintf(stderr, " -l create a log file of your " + "game named as specified'\n"); + fprintf(stderr, + " -o 'oldstyle' (no prompt, no command " + "editing, displays 'Initialising...')\n"); #if defined ADVENT_AUTOSAVE - fprintf(stderr, - " -a automatic save/restore from specified saved game file\n"); + fprintf(stderr, " -a automatic save/restore " + "from specified saved game file\n"); #elif !defined ADVENT_NOSAVE - fprintf(stderr, - " -r restore from specified saved game file\n"); + fprintf(stderr, " -r restore from specified " + "saved game file\n"); #endif - exit(EXIT_FAILURE); - break; - } - } + exit(EXIT_FAILURE); + break; + } + } - /* copy invocation line part after switches */ - settings.argc = argc - optind; - settings.argv = argv + optind; - settings.optind = 0; + /* copy invocation line part after switches */ + settings.argc = argc - optind; + settings.argv = argv + optind; + settings.optind = 0; - /* Initialize game variables */ - int seedval = initialise(); + /* Initialize game variables */ + int seedval = initialise(); #if !defined ADVENT_NOSAVE - if (!rfp) { - game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); - if (game.novice) { - game.limit = NOVICELIMIT; - } - } else { - restore(rfp); + if (!rfp) { + game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], + arbitrary_messages[CAVE_NEARBY], + arbitrary_messages[NO_MESSAGE]); + if (game.novice) { + game.limit = NOVICELIMIT; + } + } else { + restore(rfp); #if defined ADVENT_AUTOSAVE - score(scoregame); + score(scoregame); #endif - } + } #if defined ADVENT_AUTOSAVE - if (autosave_filename != NULL) { - if ((autosave_fp = fopen(autosave_filename, WRITE_MODE)) == NULL) { - perror(autosave_filename); - return EXIT_FAILURE; - } - autosave(); - } + if (autosave_filename != NULL) { + if ((autosave_fp = fopen(autosave_filename, WRITE_MODE)) == + NULL) { + perror(autosave_filename); + return EXIT_FAILURE; + } + autosave(); + } #endif #else - game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); - if (game.novice) - game.limit = NOVICELIMIT; + game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], + arbitrary_messages[CAVE_NEARBY], + arbitrary_messages[NO_MESSAGE]); + if (game.novice) + game.limit = NOVICELIMIT; #endif - if (settings.logfp) { - fprintf(settings.logfp, "seed %d\n", seedval); - } - - /* interpret commands until EOF or interrupt */ - for (;;) { - // if we're supposed to move, move - if (!do_move()) { - continue; + if (settings.logfp) { + fprintf(settings.logfp, "seed %d\n", seedval); } - // get command - if (!do_command()) { - break; + /* interpret commands until EOF or interrupt */ + for (;;) { + // if we're supposed to move, move + if (!do_move()) { + continue; + } + + // get command + if (!do_command()) { + break; + } } - } - /* show score and exit */ - terminate(quitgame); + /* show score and exit */ + terminate(quitgame); } /* end */ diff --git a/misc.c b/misc.c index c853237..ad110d9 100644 --- a/misc.c +++ b/misc.c @@ -5,746 +5,754 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include +#include #include "advent.h" #include "dungeon.h" -static void* xcalloc(size_t size) -{ - void* ptr = calloc(size, 1); - if (ptr == NULL) { - // LCOV_EXCL_START - // exclude from coverage analysis because we can't simulate an out of memory error in testing - fprintf(stderr, "Out of memory!\n"); - exit(EXIT_FAILURE); - // LCOV_EXCL_STOP - } - return (ptr); +static void *xcalloc(size_t size) { + void *ptr = calloc(size, 1); + if (ptr == NULL) { + // LCOV_EXCL_START + // exclude from coverage analysis because we can't simulate an + // out of memory error in testing + fprintf(stderr, "Out of memory!\n"); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP + } + return (ptr); } /* I/O routines (speak, pspeak, rspeak, sspeak, get_input, yes) */ -static void vspeak(const char* msg, bool blank, va_list ap) -/* Engine for various speak functions */ -{ - // Do nothing if we got a null pointer. - if (msg == NULL) - return; +static void vspeak(const char *msg, bool blank, va_list ap) { + /* Engine for various speak functions */ + // Do nothing if we got a null pointer. + if (msg == NULL) { + return; + } - // Do nothing if we got an empty string. - if (strlen(msg) == 0) - return; + // Do nothing if we got an empty string. + if (strlen(msg) == 0) { + return; + } - if (blank == true) - printf("\n"); + if (blank == true) { + printf("\n"); + } - int msglen = strlen(msg); + int msglen = strlen(msg); - // Rendered string - ssize_t size = 2000; /* msglen > 50 ? msglen*2 : 100; */ - char* rendered = xcalloc(size); - char* renderp = rendered; + // Rendered string + ssize_t size = 2000; /* msglen > 50 ? msglen*2 : 100; */ + char *rendered = xcalloc(size); + char *renderp = rendered; - // Handle format specifiers (including the custom %S) by - // adjusting the parameter accordingly, and replacing the - // specifier with %s. - bool pluralize = false; - for (int i = 0; i < msglen; i++) { - if (msg[i] != '%') { - /* Ugh. Least obtrusive way to deal with artifacts "on the floor" - * being dropped outside of both cave and building. */ - if (strncmp(msg + i, "floor", 5) == 0 && strchr(" .", msg[i + 5]) && !INSIDE(game.loc)) { - strcpy(renderp, "ground"); - renderp += 6; - i += 4; - size -= 5; - } else { - *renderp++ = msg[i]; - size--; - } - } else { - i++; - // Integer specifier. - if (msg[i] == 'd') { - int32_t arg = va_arg(ap, int32_t); - int ret = snprintf(renderp, size, "%" PRId32, arg); - if (ret < size) { - renderp += ret; - size -= ret; - } - pluralize = (arg != 1); - } + // Handle format specifiers (including the custom %S) by + // adjusting the parameter accordingly, and replacing the + // specifier with %s. + bool pluralize = false; + for (int i = 0; i < msglen; i++) { + if (msg[i] != '%') { + /* Ugh. Least obtrusive way to deal with artifacts "on + * the floor" being dropped outside of both cave and + * building. */ + if (strncmp(msg + i, "floor", 5) == 0 && + strchr(" .", msg[i + 5]) && !INSIDE(game.loc)) { + strcpy(renderp, "ground"); + renderp += 6; + i += 4; + size -= 5; + } else { + *renderp++ = msg[i]; + size--; + } + } else { + i++; + // Integer specifier. + if (msg[i] == 'd') { + int32_t arg = va_arg(ap, int32_t); + int ret = + snprintf(renderp, size, "%" PRId32, arg); + if (ret < size) { + renderp += ret; + size -= ret; + } + pluralize = (arg != 1); + } - // Unmodified string specifier. - if (msg[i] == 's') { - char *arg = va_arg(ap, char *); - strncat(renderp, arg, size - 1); - size_t len = strlen(renderp); - renderp += len; - size -= len; - } + // Unmodified string specifier. + if (msg[i] == 's') { + char *arg = va_arg(ap, char *); + strncat(renderp, arg, size - 1); + size_t len = strlen(renderp); + renderp += len; + size -= len; + } - // Singular/plural specifier. - if (msg[i] == 'S') { - // look at the *previous* numeric parameter - if (pluralize) { - *renderp++ = 's'; - size--; - } - } + // Singular/plural specifier. + if (msg[i] == 'S') { + // look at the *previous* numeric parameter + if (pluralize) { + *renderp++ = 's'; + size--; + } + } - // LCOV_EXCL_START - doesn't occur in test suite. - /* Version specifier */ - if (msg[i] == 'V') { - strcpy(renderp, VERSION); - size_t len = strlen(VERSION); - renderp += len; - size -= len; - } - // LCOV_EXCL_STOP - } - } - *renderp = 0; + // LCOV_EXCL_START - doesn't occur in test suite. + /* Version specifier */ + if (msg[i] == 'V') { + strcpy(renderp, VERSION); + size_t len = strlen(VERSION); + renderp += len; + size -= len; + } + // LCOV_EXCL_STOP + } + } + *renderp = 0; - // Print the message. - printf("%s\n", rendered); + // Print the message. + printf("%s\n", rendered); - free(rendered); + free(rendered); } -void speak(const char* msg, ...) -/* speak a specified string */ -{ - va_list ap; - va_start(ap, msg); - vspeak(msg, true, ap); - va_end(ap); +void speak(const char *msg, ...) { + /* speak a specified string */ + va_list ap; + va_start(ap, msg); + vspeak(msg, true, ap); + va_end(ap); } -void sspeak(const int msg, ...) -/* Speak a message from the arbitrary-messages list */ -{ - va_list ap; - va_start(ap, msg); - fputc('\n', stdout); - vprintf(arbitrary_messages[msg], ap); - fputc('\n', stdout); - va_end(ap); +void sspeak(const int msg, ...) { + /* Speak a message from the arbitrary-messages list */ + va_list ap; + va_start(ap, msg); + fputc('\n', stdout); + vprintf(arbitrary_messages[msg], ap); + fputc('\n', stdout); + va_end(ap); } -void pspeak(vocab_t msg, enum speaktype mode, bool blank, int skip, ...) -/* Find the skip+1st message from msg and print it. Modes are: - * feel = for inventory, what you can touch - * look = the full description for the state the object is in - * listen = the sound for the state the object is in - * study = text on the object. */ -{ - va_list ap; - va_start(ap, skip); - switch (mode) { - case touch: - vspeak(objects[msg].inventory, blank, ap); - break; - case look: - vspeak(objects[msg].descriptions[skip], blank, ap); - break; - case hear: - vspeak(objects[msg].sounds[skip], blank, ap); - break; - case study: - vspeak(objects[msg].texts[skip], blank, ap); - break; - case change: - vspeak(objects[msg].changes[skip], blank, ap); - break; - } - va_end(ap); +void pspeak(vocab_t msg, enum speaktype mode, bool blank, int skip, ...) { + /* Find the skip+1st message from msg and print it. Modes are: + * feel = for inventory, what you can touch + * look = the full description for the state the object is in + * listen = the sound for the state the object is in + * study = text on the object. */ + va_list ap; + va_start(ap, skip); + switch (mode) { + case touch: + vspeak(objects[msg].inventory, blank, ap); + break; + case look: + vspeak(objects[msg].descriptions[skip], blank, ap); + break; + case hear: + vspeak(objects[msg].sounds[skip], blank, ap); + break; + case study: + vspeak(objects[msg].texts[skip], blank, ap); + break; + case change: + vspeak(objects[msg].changes[skip], blank, ap); + break; + } + va_end(ap); } -void rspeak(vocab_t i, ...) -/* Print the i-th "random" message (section 6 of database). */ -{ - va_list ap; - va_start(ap, i); - vspeak(arbitrary_messages[i], true, ap); - va_end(ap); +void rspeak(vocab_t i, ...) { + /* Print the i-th "random" message (section 6 of database). */ + va_list ap; + va_start(ap, i); + vspeak(arbitrary_messages[i], true, ap); + va_end(ap); } -void echo_input(FILE* destination, const char* input_prompt, const char* input) -{ - size_t len = strlen(input_prompt) + strlen(input) + 1; - char* prompt_and_input = (char*) xcalloc(len); - strcpy(prompt_and_input, input_prompt); - strcat(prompt_and_input, input); - fprintf(destination, "%s\n", prompt_and_input); - free(prompt_and_input); +void echo_input(FILE *destination, const char *input_prompt, + const char *input) { + size_t len = strlen(input_prompt) + strlen(input) + 1; + char *prompt_and_input = (char *)xcalloc(len); + strcpy(prompt_and_input, input_prompt); + strcat(prompt_and_input, input); + fprintf(destination, "%s\n", prompt_and_input); + free(prompt_and_input); } -static int word_count(char* str) -{ - char delims[] = " \t"; - int count = 0; - int inblanks = true; +static int word_count(char *str) { + char delims[] = " \t"; + int count = 0; + int inblanks = true; - for (char *s = str; *s; s++) - if (inblanks) { - if (strchr(delims, *s) == 0) { - ++count; - inblanks = false; - } - } else { - if (strchr(delims, *s) != 0) { - inblanks = true; - } - } + for (char *s = str; *s; s++) + if (inblanks) { + if (strchr(delims, *s) == 0) { + ++count; + inblanks = false; + } + } else { + if (strchr(delims, *s) != 0) { + inblanks = true; + } + } - return (count); + return (count); } -static char* get_input(void) -{ - // Set up the prompt - char input_prompt[] = PROMPT; - if (!settings.prompt) - input_prompt[0] = '\0'; +static char *get_input(void) { + // Set up the prompt + char input_prompt[] = PROMPT; + if (!settings.prompt) + input_prompt[0] = '\0'; - // Print a blank line - printf("\n"); + // Print a blank line + printf("\n"); - char* input; - for (;;) { - input = myreadline(input_prompt); + char *input; + for (;;) { + input = myreadline(input_prompt); - if (input == NULL) // Got EOF; return with it. - return (input); - if (input[0] == '#') { // Ignore comments. - free(input); - continue; - } - // We have a 'normal' line; leave the loop. - break; - } + if (input == NULL) // Got EOF; return with it. + return (input); + if (input[0] == '#') { // Ignore comments. + free(input); + continue; + } + // We have a 'normal' line; leave the loop. + break; + } - // Strip trailing newlines from the input - input[strcspn(input, "\n")] = 0; + // Strip trailing newlines from the input + input[strcspn(input, "\n")] = 0; - add_history(input); + add_history(input); - if (!isatty(0)) - echo_input(stdout, input_prompt, input); + if (!isatty(0)) + echo_input(stdout, input_prompt, input); - if (settings.logfp) - echo_input(settings.logfp, "", input); + if (settings.logfp) + echo_input(settings.logfp, "", input); - return (input); + return (input); } -bool silent_yes_or_no(void) -{ - bool outcome = false; +bool silent_yes_or_no(void) { + bool outcome = false; - for (;;) { - char* reply = get_input(); - if (reply == NULL) { - // LCOV_EXCL_START - // Should be unreachable. Reply should never be NULL - free(reply); - exit(EXIT_SUCCESS); - // LCOV_EXCL_STOP - } - if (strlen(reply) == 0) { - free(reply); - rspeak(PLEASE_ANSWER); - continue; - } + for (;;) { + char *reply = get_input(); + if (reply == NULL) { + // LCOV_EXCL_START + // Should be unreachable. Reply should never be NULL + free(reply); + exit(EXIT_SUCCESS); + // LCOV_EXCL_STOP + } + if (strlen(reply) == 0) { + free(reply); + rspeak(PLEASE_ANSWER); + continue; + } - char* firstword = (char*) xcalloc(strlen(reply) + 1); - sscanf(reply, "%s", firstword); + char *firstword = (char *)xcalloc(strlen(reply) + 1); + sscanf(reply, "%s", firstword); - free(reply); + free(reply); - for (int i = 0; i < (int)strlen(firstword); ++i) - firstword[i] = tolower(firstword[i]); + for (int i = 0; i < (int)strlen(firstword); ++i) + firstword[i] = tolower(firstword[i]); - int yes = strncmp("yes", firstword, sizeof("yes") - 1); - int y = strncmp("y", firstword, sizeof("y") - 1); - int no = strncmp("no", firstword, sizeof("no") - 1); - int n = strncmp("n", firstword, sizeof("n") - 1); + int yes = strncmp("yes", firstword, sizeof("yes") - 1); + int y = strncmp("y", firstword, sizeof("y") - 1); + int no = strncmp("no", firstword, sizeof("no") - 1); + int n = strncmp("n", firstword, sizeof("n") - 1); - free(firstword); + free(firstword); - if (yes == 0 || y == 0) { - outcome = true; - break; - } else if (no == 0 || n == 0) { - outcome = false; - break; - } else - rspeak(PLEASE_ANSWER); - } - return (outcome); + if (yes == 0 || y == 0) { + outcome = true; + break; + } else if (no == 0 || n == 0) { + outcome = false; + break; + } else + rspeak(PLEASE_ANSWER); + } + return (outcome); } +bool yes_or_no(const char *question, const char *yes_response, + const char *no_response) { + /* Print message X, wait for yes/no answer. If yes, print Y and return + * true; if no, print Z and return false. */ + bool outcome = false; -bool yes_or_no(const char* question, const char* yes_response, const char* no_response) -/* Print message X, wait for yes/no answer. If yes, print Y and return true; - * if no, print Z and return false. */ -{ - bool outcome = false; + for (;;) { + speak(question); - for (;;) { - speak(question); + char *reply = get_input(); + if (reply == NULL) { + // LCOV_EXCL_START + // Should be unreachable. Reply should never be NULL + free(reply); + exit(EXIT_SUCCESS); + // LCOV_EXCL_STOP + } - char* reply = get_input(); - if (reply == NULL) { - // LCOV_EXCL_START - // Should be unreachable. Reply should never be NULL - free(reply); - exit(EXIT_SUCCESS); - // LCOV_EXCL_STOP - } + if (strlen(reply) == 0) { + free(reply); + rspeak(PLEASE_ANSWER); + continue; + } - if (strlen(reply) == 0) { - free(reply); - rspeak(PLEASE_ANSWER); - continue; - } + char *firstword = (char *)xcalloc(strlen(reply) + 1); + sscanf(reply, "%s", firstword); - char* firstword = (char*) xcalloc(strlen(reply) + 1); - sscanf(reply, "%s", firstword); + free(reply); - free(reply); + for (int i = 0; i < (int)strlen(firstword); ++i) { + firstword[i] = tolower(firstword[i]); + } - for (int i = 0; i < (int)strlen(firstword); ++i) - firstword[i] = tolower(firstword[i]); + int yes = strncmp("yes", firstword, sizeof("yes") - 1); + int y = strncmp("y", firstword, sizeof("y") - 1); + int no = strncmp("no", firstword, sizeof("no") - 1); + int n = strncmp("n", firstword, sizeof("n") - 1); - int yes = strncmp("yes", firstword, sizeof("yes") - 1); - int y = strncmp("y", firstword, sizeof("y") - 1); - int no = strncmp("no", firstword, sizeof("no") - 1); - int n = strncmp("n", firstword, sizeof("n") - 1); + free(firstword); - free(firstword); + if (yes == 0 || y == 0) { + speak(yes_response); + outcome = true; + break; + } else if (no == 0 || n == 0) { + speak(no_response); + outcome = false; + break; + } else + rspeak(PLEASE_ANSWER); + } - if (yes == 0 || y == 0) { - speak(yes_response); - outcome = true; - break; - } else if (no == 0 || n == 0) { - speak(no_response); - outcome = false; - break; - } else - rspeak(PLEASE_ANSWER); - - } - - return (outcome); + return (outcome); } -/* Data structure routines */ +/* Data structure routines */ -static int get_motion_vocab_id(const char* word) -// Return the first motion number that has 'word' as one of its words. -{ - for (int i = 0; i < NMOTIONS; ++i) { - for (int j = 0; j < motions[i].words.n; ++j) { - if (strncasecmp(word, motions[i].words.strs[j], TOKLEN) == 0 && (strlen(word) > 1 || - strchr(ignore, word[0]) == NULL || - !settings.oldstyle)) - return (i); - } - } - // If execution reaches here, we didn't find the word. - return (WORD_NOT_FOUND); +static int get_motion_vocab_id(const char *word) { + // Return the first motion number that has 'word' as one of its words. + for (int i = 0; i < NMOTIONS; ++i) { + for (int j = 0; j < motions[i].words.n; ++j) { + if (strncasecmp(word, motions[i].words.strs[j], + TOKLEN) == 0 && + (strlen(word) > 1 || + strchr(ignore, word[0]) == NULL || + !settings.oldstyle)) + return (i); + } + } + // If execution reaches here, we didn't find the word. + return (WORD_NOT_FOUND); } -static int get_object_vocab_id(const char* word) -// Return the first object number that has 'word' as one of its words. -{ - for (int i = 0; i < NOBJECTS + 1; ++i) { // FIXME: the + 1 should go when 1-indexing for objects is removed - for (int j = 0; j < objects[i].words.n; ++j) { - if (strncasecmp(word, objects[i].words.strs[j], TOKLEN) == 0) - return (i); - } - } - // If execution reaches here, we didn't find the word. - return (WORD_NOT_FOUND); +static int get_object_vocab_id(const char *word) { + // Return the first object number that has 'word' as one of its words. + for (int i = 0; i < NOBJECTS + 1; + ++i) { // FIXME: the + 1 should go when 1-indexing for objects is + // removed + for (int j = 0; j < objects[i].words.n; ++j) { + if (strncasecmp(word, objects[i].words.strs[j], + TOKLEN) == 0) + return (i); + } + } + // If execution reaches here, we didn't find the word. + return (WORD_NOT_FOUND); } -static int get_action_vocab_id(const char* word) -// Return the first motion number that has 'word' as one of its words. -{ - for (int i = 0; i < NACTIONS; ++i) { - for (int j = 0; j < actions[i].words.n; ++j) { - if (strncasecmp(word, actions[i].words.strs[j], TOKLEN) == 0 && (strlen(word) > 1 || - strchr(ignore, word[0]) == NULL || - !settings.oldstyle)) - return (i); - } - } - // If execution reaches here, we didn't find the word. - return (WORD_NOT_FOUND); +static int get_action_vocab_id(const char *word) { + // Return the first motion number that has 'word' as one of its words. + for (int i = 0; i < NACTIONS; ++i) { + for (int j = 0; j < actions[i].words.n; ++j) { + if (strncasecmp(word, actions[i].words.strs[j], + TOKLEN) == 0 && + (strlen(word) > 1 || + strchr(ignore, word[0]) == NULL || + !settings.oldstyle)) { + return (i); + } + } + } + // If execution reaches here, we didn't find the word. + return (WORD_NOT_FOUND); } -static bool is_valid_int(const char *str) -/* Returns true if the string passed in is represents a valid integer, - * that could then be parsed by atoi() */ -{ - // Handle negative number - if (*str == '-') - ++str; +static bool is_valid_int(const char *str) { + /* Returns true if the string passed in is represents a valid integer, + * that could then be parsed by atoi() */ + // Handle negative number + if (*str == '-') { + ++str; + } - // Handle empty string or just "-". Should never reach this - // point, because this is only used with transitive verbs. - if (!*str) - return false; // LCOV_EXCL_LINE + // Handle empty string or just "-". Should never reach this + // point, because this is only used with transitive verbs. + if (!*str) { + return false; // LCOV_EXCL_LINE + } - // Check for non-digit chars in the rest of the string. - while (*str) { - if (!isdigit(*str)) - return false; - else - ++str; - } + // Check for non-digit chars in the rest of the string. + while (*str) { + if (!isdigit(*str)) { + return false; + } else { + ++str; + } + } - return true; + return true; } -static void get_vocab_metadata(const char* word, vocab_t* id, word_type_t* type) -{ - /* Check for an empty string */ - if (strncmp(word, "", sizeof("")) == 0) { - *id = WORD_EMPTY; - *type = NO_WORD_TYPE; - return; - } +static void get_vocab_metadata(const char *word, vocab_t *id, + word_type_t *type) { + /* Check for an empty string */ + if (strncmp(word, "", sizeof("")) == 0) { + *id = WORD_EMPTY; + *type = NO_WORD_TYPE; + return; + } - vocab_t ref_num; + vocab_t ref_num; - ref_num = get_motion_vocab_id(word); - // Second conjunct is because the magic-word placeholder is a bit special - if (ref_num != WORD_NOT_FOUND) { - *id = ref_num; - *type = MOTION; - return; - } + ref_num = get_motion_vocab_id(word); + // Second conjunct is because the magic-word placeholder is a bit + // special + if (ref_num != WORD_NOT_FOUND) { + *id = ref_num; + *type = MOTION; + return; + } - ref_num = get_object_vocab_id(word); - if (ref_num != WORD_NOT_FOUND) { - *id = ref_num; - *type = OBJECT; - return; - } + ref_num = get_object_vocab_id(word); + if (ref_num != WORD_NOT_FOUND) { + *id = ref_num; + *type = OBJECT; + return; + } - ref_num = get_action_vocab_id(word); - if (ref_num != WORD_NOT_FOUND && ref_num != PART) { - *id = ref_num; - *type = ACTION; - return; - } + ref_num = get_action_vocab_id(word); + if (ref_num != WORD_NOT_FOUND && ref_num != PART) { + *id = ref_num; + *type = ACTION; + return; + } - // Check for the reservoir magic word. - if (strcasecmp(word, game.zzword) == 0) { - *id = PART; - *type = ACTION; - return; - } + // Check for the reservoir magic word. + if (strcasecmp(word, game.zzword) == 0) { + *id = PART; + *type = ACTION; + return; + } - // Check words that are actually numbers. - if (is_valid_int(word)) { - *id = WORD_EMPTY; - *type = NUMERIC; - return; - } + // Check words that are actually numbers. + if (is_valid_int(word)) { + *id = WORD_EMPTY; + *type = NUMERIC; + return; + } - *id = WORD_NOT_FOUND; - *type = NO_WORD_TYPE; - return; + *id = WORD_NOT_FOUND; + *type = NO_WORD_TYPE; + return; } -static void tokenize(char* raw, command_t *cmd) -{ - /* - * Be careful about modifying this. We do not want to nuke the - * the speech part or ID from the previous turn. - */ - memset(&cmd->word[0].raw, '\0', sizeof(cmd->word[0].raw)); - memset(&cmd->word[1].raw, '\0', sizeof(cmd->word[1].raw)); +static void tokenize(char *raw, command_t *cmd) { + /* + * Be careful about modifying this. We do not want to nuke the + * the speech part or ID from the previous turn. + */ + memset(&cmd->word[0].raw, '\0', sizeof(cmd->word[0].raw)); + memset(&cmd->word[1].raw, '\0', sizeof(cmd->word[1].raw)); - /* Bound prefix on the %s would be needed to prevent buffer - * overflow. but we shortstop this more simply by making each - * raw-input buffer as int as the entire input buffer. */ - sscanf(raw, "%s%s", cmd->word[0].raw, cmd->word[1].raw); + /* Bound prefix on the %s would be needed to prevent buffer + * overflow. but we shortstop this more simply by making each + * raw-input buffer as int as the entire input buffer. */ + sscanf(raw, "%s%s", cmd->word[0].raw, cmd->word[1].raw); - /* (ESR) In oldstyle mode, simulate the uppercasing and truncating - * effect on raw tokens of packing them into sixbit characters, 5 - * to a 32-bit word. This is something the FORTRAN version did - * because archaic FORTRAN had no string types. Don Wood's - * mechanical translation of 2.5 to C retained the packing and - * thus this misfeature. - * - * It's philosophically questionable whether this is the right - * thing to do even in oldstyle mode. On one hand, the text - * mangling was not authorial intent, but a result of limitations - * in their tools. On the other, not simulating this misbehavior - * goes against the goal of making oldstyle as accurate as - * possible an emulation of the original UI. - */ - if (settings.oldstyle) { - cmd->word[0].raw[TOKLEN + TOKLEN] = cmd->word[1].raw[TOKLEN + TOKLEN] = '\0'; - for (size_t i = 0; i < strlen(cmd->word[0].raw); i++) - cmd->word[0].raw[i] = toupper(cmd->word[0].raw[i]); - for (size_t i = 0; i < strlen(cmd->word[1].raw); i++) - cmd->word[1].raw[i] = toupper(cmd->word[1].raw[i]); - } + /* (ESR) In oldstyle mode, simulate the uppercasing and truncating + * effect on raw tokens of packing them into sixbit characters, 5 + * to a 32-bit word. This is something the FORTRAN version did + * because archaic FORTRAN had no string types. Don Wood's + * mechanical translation of 2.5 to C retained the packing and + * thus this misfeature. + * + * It's philosophically questionable whether this is the right + * thing to do even in oldstyle mode. On one hand, the text + * mangling was not authorial intent, but a result of limitations + * in their tools. On the other, not simulating this misbehavior + * goes against the goal of making oldstyle as accurate as + * possible an emulation of the original UI. + */ + if (settings.oldstyle) { + cmd->word[0].raw[TOKLEN + TOKLEN] = + cmd->word[1].raw[TOKLEN + TOKLEN] = '\0'; + for (size_t i = 0; i < strlen(cmd->word[0].raw); i++) { + cmd->word[0].raw[i] = toupper(cmd->word[0].raw[i]); + } + for (size_t i = 0; i < strlen(cmd->word[1].raw); i++) { + cmd->word[1].raw[i] = toupper(cmd->word[1].raw[i]); + } + } - /* populate command with parsed vocabulary metadata */ - get_vocab_metadata(cmd->word[0].raw, &(cmd->word[0].id), &(cmd->word[0].type)); - get_vocab_metadata(cmd->word[1].raw, &(cmd->word[1].id), &(cmd->word[1].type)); - cmd->state = TOKENIZED; + /* populate command with parsed vocabulary metadata */ + get_vocab_metadata(cmd->word[0].raw, &(cmd->word[0].id), + &(cmd->word[0].type)); + get_vocab_metadata(cmd->word[1].raw, &(cmd->word[1].id), + &(cmd->word[1].type)); + cmd->state = TOKENIZED; } -bool get_command_input(command_t *command) -/* Get user input on stdin, parse and map to command */ -{ - char inputbuf[LINESIZE]; - char* input; +bool get_command_input(command_t *command) { + /* Get user input on stdin, parse and map to command */ + char inputbuf[LINESIZE]; + char *input; - for (;;) { - input = get_input(); - if (input == NULL) - return false; - if (word_count(input) > 2) { - rspeak(TWO_WORDS); - free(input); - continue; - } - if (strcmp(input, "") != 0) - break; - free(input); - } + for (;;) { + input = get_input(); + if (input == NULL) + return false; + if (word_count(input) > 2) { + rspeak(TWO_WORDS); + free(input); + continue; + } + if (strcmp(input, "") != 0) { + break; + } + free(input); + } - strncpy(inputbuf, input, LINESIZE - 1); - free(input); + strncpy(inputbuf, input, LINESIZE - 1); + free(input); - tokenize(inputbuf, command); + tokenize(inputbuf, command); #ifdef GDEBUG - /* Needs to stay synced with enum word_type_t */ - const char *types[] = {"NO_WORD_TYPE", "MOTION", "OBJECT", "ACTION", "NUMERIC"}; - /* needs to stay synced with enum speechpart */ - const char *roles[] = {"unknown", "intransitive", "transitive"}; - printf("Command: role = %s type1 = %s, id1 = %d, type2 = %s, id2 = %d\n", - roles[command->part], - types[command->word[0].type], - command->word[0].id, - types[command->word[1].type], - command->word[1].id); + /* Needs to stay synced with enum word_type_t */ + const char *types[] = {"NO_WORD_TYPE", "MOTION", "OBJECT", "ACTION", + "NUMERIC"}; + /* needs to stay synced with enum speechpart */ + const char *roles[] = {"unknown", "intransitive", "transitive"}; + printf( + "Command: role = %s type1 = %s, id1 = %d, type2 = %s, id2 = %d\n", + roles[command->part], types[command->word[0].type], + command->word[0].id, types[command->word[1].type], + command->word[1].id); #endif - command->state = GIVEN; - return true; + command->state = GIVEN; + return true; } -void clear_command(command_t *cmd) -/* Resets the state of the command to empty */ -{ - cmd->verb = ACT_NULL; - cmd->part = unknown; - game.oldobj = cmd->obj; - cmd->obj = NO_OBJECT; - cmd->state = EMPTY; +void clear_command(command_t *cmd) { + /* Resets the state of the command to empty */ + cmd->verb = ACT_NULL; + cmd->part = unknown; + game.oldobj = cmd->obj; + cmd->obj = NO_OBJECT; + cmd->state = EMPTY; } -void juggle(obj_t object) -/* Juggle an object by picking it up and putting it down again, the purpose - * being to get the object to the front of the chain of things at its loc. */ -{ - loc_t i, j; +void juggle(obj_t object) { + /* Juggle an object by picking it up and putting it down again, the + * purpose being to get the object to the front of the chain of things + * at its loc. */ + loc_t i, j; - i = game.objects[object].place; - j = game.objects[object].fixed; - move(object, i); - move(object + NOBJECTS, j); + i = game.objects[object].place; + j = game.objects[object].fixed; + move(object, i); + move(object + NOBJECTS, j); } -void move(obj_t object, loc_t where) -/* Place any object anywhere by picking it up and dropping it. May - * already be toting, in which case the carry is a no-op. Mustn't - * pick up objects which are not at any loc, since carry wants to - * remove objects from game atloc chains. */ -{ - loc_t from; +void move(obj_t object, loc_t where) { + /* Place any object anywhere by picking it up and dropping it. May + * already be toting, in which case the carry is a no-op. Mustn't + * pick up objects which are not at any loc, since carry wants to + * remove objects from game atloc chains. */ + loc_t from; - if (object > NOBJECTS) - from = game.objects[object - NOBJECTS].fixed; - else - from = game.objects[object].place; - /* (ESR) Used to check for !SPECIAL(from). I *think* that was wrong... */ - if (from != LOC_NOWHERE && from != CARRIED) - carry(object, from); - drop(object, where); -} - -void put(obj_t object, loc_t where, int pval) -/* put() is the same as move(), except it returns a value used to set up the - * negated game.prop values for the repository objects. */ -{ - move(object, where); - /* (ESR) Read this in combination with the macro defintions in advebt.h. - */ - game.objects[object].prop = PROP_STASHIFY(pval); -#ifdef PROP_SET_SEEN - PROP_SET_SEEN(object); -#endif -} - -void carry(obj_t object, loc_t where) -/* Start toting an object, removing it from the list of things at its former - * location. Incr holdng unless it was already being toted. If object>NOBJECTS - * (moving "fixed" second loc), don't change game.place or game.holdng. */ -{ - int temp; - - if (object <= NOBJECTS) { - if (game.objects[object].place == CARRIED) - return; - game.objects[object].place = CARRIED; - - /* - * Without this conditional your inventory is overcounted - * when you pick up the bird while it's caged. This fixes - * a cosmetic bug in the original. - * - * Possibly this check should be skipped whwn oldstyle is on. + if (object > NOBJECTS) { + from = game.objects[object - NOBJECTS].fixed; + } else { + from = game.objects[object].place; + } + /* (ESR) Used to check for !SPECIAL(from). I *think* that was wrong... */ - if (object != BIRD) - ++game.holdng; - } - if (game.locs[where].atloc == object) { - game.locs[where].atloc = game.link[object]; - return; - } - temp = game.locs[where].atloc; - while (game.link[temp] != object) { - temp = game.link[temp]; - } - game.link[temp] = game.link[object]; + if (from != LOC_NOWHERE && from != CARRIED) { + carry(object, from); + } + drop(object, where); } -void drop(obj_t object, loc_t where) -/* Place an object at a given loc, prefixing it onto the game atloc list. Decr - * game.holdng if the object was being toted. No state change on the object. */ -{ - if (object > NOBJECTS) - game.objects[object - NOBJECTS].fixed = where; - else { - if (game.objects[object].place == CARRIED) - if (object != BIRD) - /* The bird has to be weightless. This ugly hack (and the - * corresponding code in the carry function) brought to you - * by the fact that when the bird is caged, we need to be able - * to either 'take bird' or 'take cage' and have the right thing - * happen. - */ - --game.holdng; - game.objects[object].place = where; - } - if (where == LOC_NOWHERE || where == CARRIED) - return; - game.link[object] = game.locs[where].atloc; - game.locs[where].atloc = object; +void put(obj_t object, loc_t where, int pval) { + /* put() is the same as move(), except it returns a value used to set + * up the negated game.prop values for the repository objects. */ + move(object, where); + /* (ESR) Read this in combination with the macro defintions in advebt.h. + */ + game.objects[object].prop = PROP_STASHIFY(pval); +#ifdef PROP_SET_SEEN + PROP_SET_SEEN(object); +#endif } -int atdwrf(loc_t where) -/* Return the index of first dwarf at the given location, zero if no dwarf is - * there (or if dwarves not active yet), -1 if all dwarves are dead. Ignore - * the pirate (6th dwarf). */ -{ - int at; +void carry(obj_t object, loc_t where) { + /* Start toting an object, removing it from the list of things at its + * former location. Incr holdng unless it was already being toted. If + * object>NOBJECTS (moving "fixed" second loc), don't change game.place + * or game.holdng. */ + int temp; - at = 0; - if (game.dflag < 2) - return at; - at = -1; - for (int i = 1; i <= NDWARVES - 1; i++) { - if (game.dwarves[i].loc == where) - return i; - if (game.dwarves[i].loc != 0) - at = 0; - } - return at; + if (object <= NOBJECTS) { + if (game.objects[object].place == CARRIED) { + return; + } + game.objects[object].place = CARRIED; + + /* + * Without this conditional your inventory is overcounted + * when you pick up the bird while it's caged. This fixes + * a cosmetic bug in the original. + * + * Possibly this check should be skipped whwn oldstyle is on. + */ + if (object != BIRD) + ++game.holdng; + } + if (game.locs[where].atloc == object) { + game.locs[where].atloc = game.link[object]; + return; + } + temp = game.locs[where].atloc; + while (game.link[temp] != object) { + temp = game.link[temp]; + } + game.link[temp] = game.link[object]; +} + +void drop(obj_t object, loc_t where) { + /* Place an object at a given loc, prefixing it onto the game atloc + * list. Decr game.holdng if the object was being toted. No state + * change on the object. */ + if (object > NOBJECTS) { + game.objects[object - NOBJECTS].fixed = where; + } else { + if (game.objects[object].place == CARRIED) + if (object != BIRD) + /* The bird has to be weightless. This ugly + * hack (and the corresponding code in the carry + * function) brought to you by the fact that + * when the bird is caged, we need to be able to + * either 'take bird' or 'take cage' and have + * the right thing happen. + */ + --game.holdng; + game.objects[object].place = where; + } + if (where == LOC_NOWHERE || where == CARRIED) { + return; + } + game.link[object] = game.locs[where].atloc; + game.locs[where].atloc = object; +} + +int atdwrf(loc_t where) { + /* Return the index of first dwarf at the given location, zero if no + * dwarf is there (or if dwarves not active yet), -1 if all dwarves are + * dead. Ignore the pirate (6th dwarf). */ + int at; + + at = 0; + if (game.dflag < 2) { + return at; + } + at = -1; + for (int i = 1; i <= NDWARVES - 1; i++) { + if (game.dwarves[i].loc == where) { + return i; + } + if (game.dwarves[i].loc != 0) { + at = 0; + } + } + return at; } /* Utility routines (setbit, tstbit, set_seed, get_next_lcg_value, * randrange) */ -int setbit(int bit) -/* Returns 2**bit for use in constructing bit-masks. */ -{ - return (1L << bit); +int setbit(int bit) { + /* Returns 2**bit for use in constructing bit-masks. */ + return (1L << bit); } -bool tstbit(int mask, int bit) -/* Returns true if the specified bit is set in the mask. */ -{ - return (mask & (1 << bit)) != 0; +bool tstbit(int mask, int bit) { + /* Returns true if the specified bit is set in the mask. */ + return (mask & (1 << bit)) != 0; } -void set_seed(int32_t seedval) -/* Set the LCG1 seed */ -{ - game.lcg_x = seedval % LCG_M; - if (game.lcg_x < 0) { - game.lcg_x = LCG_M + game.lcg_x; - } - // once seed is set, we need to generate the Z`ZZZ word - for (int i = 0; i < 5; ++i) { - game.zzword[i] = 'A' + randrange(26); - } - game.zzword[1] = '\''; // force second char to apostrophe - game.zzword[5] = '\0'; +void set_seed(int32_t seedval) { + /* Set the LCG1 seed */ + game.lcg_x = seedval % LCG_M; + if (game.lcg_x < 0) { + game.lcg_x = LCG_M + game.lcg_x; + } + // once seed is set, we need to generate the Z`ZZZ word + for (int i = 0; i < 5; ++i) { + game.zzword[i] = 'A' + randrange(26); + } + game.zzword[1] = '\''; // force second char to apostrophe + game.zzword[5] = '\0'; } -static int32_t get_next_lcg_value(void) -/* Return the LCG's current value, and then iterate it. */ -{ - int32_t old_x = game.lcg_x; - game.lcg_x = (LCG_A * game.lcg_x + LCG_C) % LCG_M; - if (settings.debug) { - printf("# random %d\n", old_x); // LCOV_EXCL_LINE - } - return old_x; +static int32_t get_next_lcg_value(void) { + /* Return the LCG's current value, and then iterate it. */ + int32_t old_x = game.lcg_x; + game.lcg_x = (LCG_A * game.lcg_x + LCG_C) % LCG_M; + if (settings.debug) { + printf("# random %d\n", old_x); // LCOV_EXCL_LINE + } + return old_x; } -int32_t randrange(int32_t range) -/* Return a random integer from [0, range). */ -{ - return range * get_next_lcg_value() / LCG_M; +int32_t randrange(int32_t range) { + /* Return a random integer from [0, range). */ + return range * get_next_lcg_value() / LCG_M; } // LCOV_EXCL_START -void bug(enum bugtype num, const char *error_string) -{ - fprintf(stderr, "Fatal error %d, %s.\n", num, error_string); - exit(EXIT_FAILURE); +void bug(enum bugtype num, const char *error_string) { + fprintf(stderr, "Fatal error %d, %s.\n", num, error_string); + exit(EXIT_FAILURE); } // LCOV_EXCL_STOP -void state_change(obj_t obj, int state) -/* Object must have a change-message list for this to be useful; only some do */ -{ - game.objects[obj].prop = state; - pspeak(obj, change, true, state); +void state_change(obj_t obj, int state) { + /* Object must have a change-message list for this to be useful; only + * some do */ + game.objects[obj].prop = state; + pspeak(obj, change, true, state); } /* end */ diff --git a/saveresume.c b/saveresume.c index 34404c6..ea30e4d 100644 --- a/saveresume.c +++ b/saveresume.c @@ -8,243 +8,263 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include +#include #include #include -#include #include -#include #include "advent.h" /* * Use this to detect endianness mismatch. Can't be unchanged by byte-swapping. */ -#define ENDIAN_MAGIC 2317 +#define ENDIAN_MAGIC 2317 struct save_t save; -#define IGNORE(r) do{if (r){}}while(0) +#define IGNORE(r) \ + do { \ + if (r) { \ + } \ + } while (0) -int savefile(FILE *fp) -/* Save game to file. No input or output from user. */ -{ - memcpy(&save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)); - if (save.version == 0) - save.version = SAVE_VERSION; - if (save.canary == 0) - save.canary = ENDIAN_MAGIC; - - save.game = game; - IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp)); - return (0); +int savefile(FILE *fp) { + /* Save game to file. No input or output from user. */ + memcpy(&save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)); + if (save.version == 0) { + save.version = SAVE_VERSION; + } + if (save.canary == 0) { + save.canary = ENDIAN_MAGIC; + } + save.game = game; + IGNORE(fwrite(&save, sizeof(struct save_t), 1, fp)); + return (0); } /* Suspend and resume */ -static char *strip(char *name) -{ - // Trim leading whitespace - while(isspace((unsigned char)*name)) - name++; // LCOV_EXCL_LINE - if(*name != '\0') { - // Trim trailing whitespace; - // might be left there by autocomplete - char *end = name + strlen(name) - 1; - while(end > name && isspace((unsigned char)*end)) - end--; - // Write new null terminator character - end[1] = '\0'; - } +static char *strip(char *name) { + // Trim leading whitespace + while (isspace((unsigned char)*name)) { + name++; // LCOV_EXCL_LINE + } + if (*name != '\0') { + // Trim trailing whitespace; + // might be left there by autocomplete + char *end = name + strlen(name) - 1; + while (end > name && isspace((unsigned char)*end)) { + end--; + } + // Write new null terminator character + end[1] = '\0'; + } - return name; + return name; } -int suspend(void) -{ - /* Suspend. Offer to save things in a file, but charging - * some points (so can't win by using saved games to retry - * battles or to start over after learning zzword). - * If ADVENT_NOSAVE is defined, gripe instead. */ +int suspend(void) { + /* Suspend. Offer to save things in a file, but charging + * some points (so can't win by using saved games to retry + * battles or to start over after learning zzword). + * If ADVENT_NOSAVE is defined, gripe instead. */ #if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE - rspeak(SAVERESUME_DISABLED); - return GO_TOP; + rspeak(SAVERESUME_DISABLED); + return GO_TOP; #endif - FILE *fp = NULL; + FILE *fp = NULL; - rspeak(SUSPEND_WARNING); - if (!yes_or_no(arbitrary_messages[THIS_ACCEPTABLE], arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN])) - return GO_CLEAROBJ; - game.saved = game.saved + 5; + rspeak(SUSPEND_WARNING); + if (!yes_or_no(arbitrary_messages[THIS_ACCEPTABLE], + arbitrary_messages[OK_MAN], + arbitrary_messages[OK_MAN])) { + return GO_CLEAROBJ; + } + game.saved = game.saved + 5; - while (fp == NULL) { - char* name = myreadline("\nFile name: "); - if (name == NULL) - return GO_TOP; - name = strip(name); - if (strlen(name) == 0) - return GO_TOP; // LCOV_EXCL_LINE - fp = fopen(strip(name), WRITE_MODE); - if (fp == NULL) - printf("Can't open file %s, try again.\n", name); - free(name); - } + while (fp == NULL) { + char *name = myreadline("\nFile name: "); + if (name == NULL) { + return GO_TOP; + } + name = strip(name); + if (strlen(name) == 0) { + return GO_TOP; // LCOV_EXCL_LINE + } + fp = fopen(strip(name), WRITE_MODE); + if (fp == NULL) { + printf("Can't open file %s, try again.\n", name); + } + free(name); + } - savefile(fp); - fclose(fp); - rspeak(RESUME_HELP); - exit(EXIT_SUCCESS); -} - -int resume(void) -{ - /* Resume. Read a suspended game back from a file. - * If ADVENT_NOSAVE is defined, gripe instead. */ - -#if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE - rspeak(SAVERESUME_DISABLED); - return GO_TOP; -#endif - FILE *fp = NULL; - - if (game.loc != LOC_START || game.locs[LOC_START].abbrev != 1) { - rspeak(RESUME_ABANDON); - if (!yes_or_no(arbitrary_messages[THIS_ACCEPTABLE], arbitrary_messages[OK_MAN], arbitrary_messages[OK_MAN])) - return GO_CLEAROBJ; - } - - while (fp == NULL) { - char* name = myreadline("\nFile name: "); - if (name == NULL) - return GO_TOP; - name = strip(name); - if (strlen(name) == 0) - return GO_TOP; // LCOV_EXCL_LINE - fp = fopen(name, READ_MODE); - if (fp == NULL) - printf("Can't open file %s, try again.\n", name); - free(name); - } - - return restore(fp); -} - -int restore(FILE* fp) -{ - /* Read and restore game state from file, assuming - * sane initial state. - * If ADVENT_NOSAVE is defined, gripe instead. */ -#ifdef ADVENT_NOSAVE - rspeak(SAVERESUME_DISABLED); - return GO_TOP; -#endif - - IGNORE(fread(&save, sizeof(struct save_t), 1, fp)); - fclose(fp); - if (memcmp(save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)) != 0 || save.canary != ENDIAN_MAGIC) - rspeak(BAD_SAVE); - else if (save.version != SAVE_VERSION) { - rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), SAVE_VERSION / 10, MOD(SAVE_VERSION, 10)); - } else if (!is_valid(save.game)) { - rspeak(SAVE_TAMPERING); + savefile(fp); + fclose(fp); + rspeak(RESUME_HELP); exit(EXIT_SUCCESS); - } else { - game = save.game; - } - return GO_TOP; } -bool is_valid(struct game_t valgame) -{ - /* Save files can be roughly grouped into three groups: - * With valid, reachable state, with valid, but unreachable - * state and with invalid state. We check that state is - * valid: no states are outside minimal or maximal value - */ +int resume(void) { + /* Resume. Read a suspended game back from a file. + * If ADVENT_NOSAVE is defined, gripe instead. */ - /* Prevent division by zero */ - if (valgame.abbnum == 0) { - return false; // LCOV_EXCL_LINE - } +#if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE + rspeak(SAVERESUME_DISABLED); + return GO_TOP; +#endif + FILE *fp = NULL; - /* Check for RNG overflow. Truncate */ - if (valgame.lcg_x >= LCG_M) { - valgame.lcg_x %= LCG_M; // LCOV_EXCL_LINE - } + if (game.loc != LOC_START || game.locs[LOC_START].abbrev != 1) { + rspeak(RESUME_ABANDON); + if (!yes_or_no(arbitrary_messages[THIS_ACCEPTABLE], + arbitrary_messages[OK_MAN], + arbitrary_messages[OK_MAN])) { + return GO_CLEAROBJ; + } + } - /* Check for RNG underflow. Transpose */ - if (valgame.lcg_x < LCG_M) { - valgame.lcg_x = LCG_M + (valgame.lcg_x % LCG_M); - } + while (fp == NULL) { + char *name = myreadline("\nFile name: "); + if (name == NULL) + return GO_TOP; + name = strip(name); + if (strlen(name) == 0) + return GO_TOP; // LCOV_EXCL_LINE + fp = fopen(name, READ_MODE); + if (fp == NULL) { + printf("Can't open file %s, try again.\n", name); + } + free(name); + } - /* Bounds check for locations */ - if ( valgame.chloc < -1 || valgame.chloc > NLOCATIONS || - valgame.chloc2 < -1 || valgame.chloc2 > NLOCATIONS || - valgame.loc < 0 || valgame.loc > NLOCATIONS || - valgame.newloc < 0 || valgame.newloc > NLOCATIONS || - valgame.oldloc < 0 || valgame.oldloc > NLOCATIONS || - valgame.oldlc2 < 0 || valgame.oldlc2 > NLOCATIONS) { - return false; // LCOV_EXCL_LINE - } - /* Bounds check for location arrays */ - for (int i = 0; i <= NDWARVES; i++) { - if (valgame.dwarves[i].loc < -1 || valgame.dwarves[i].loc > NLOCATIONS || - valgame.dwarves[i].oldloc < -1 || valgame.dwarves[i].oldloc > NLOCATIONS) { - return false; // LCOV_EXCL_LINE - } - } + return restore(fp); +} - for (int i = 0; i <= NOBJECTS; i++) { - if (valgame.objects[i].place < -1 || valgame.objects[i].place > NLOCATIONS || - valgame.objects[i].fixed < -1 || valgame.objects[i].fixed > NLOCATIONS) { - return false; // LCOV_EXCL_LINE - } - } +int restore(FILE *fp) { + /* Read and restore game state from file, assuming + * sane initial state. + * If ADVENT_NOSAVE is defined, gripe instead. */ +#ifdef ADVENT_NOSAVE + rspeak(SAVERESUME_DISABLED); + return GO_TOP; +#endif - /* Bounds check for dwarves */ - if (valgame.dtotal < 0 || valgame.dtotal > NDWARVES || - valgame.dkill < 0 || valgame.dkill > NDWARVES) { - return false; // LCOV_EXCL_LINE - } + IGNORE(fread(&save, sizeof(struct save_t), 1, fp)); + fclose(fp); + if (memcmp(save.magic, ADVENT_MAGIC, sizeof(ADVENT_MAGIC)) != 0 || + save.canary != ENDIAN_MAGIC) { + rspeak(BAD_SAVE); + } else if (save.version != SAVE_VERSION) { + rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), + SAVE_VERSION / 10, MOD(SAVE_VERSION, 10)); + } else if (!is_valid(save.game)) { + rspeak(SAVE_TAMPERING); + exit(EXIT_SUCCESS); + } else { + game = save.game; + } + return GO_TOP; +} - /* Validate that we didn't die too many times in save */ - if (valgame.numdie >= NDEATHS) { - return false; // LCOV_EXCL_LINE - } +bool is_valid(struct game_t valgame) { + /* Save files can be roughly grouped into three groups: + * With valid, reachable state, with valid, but unreachable + * state and with invalid state. We check that state is + * valid: no states are outside minimal or maximal value + */ - /* Recalculate tally, throw the towel if in disagreement */ - int temp_tally = 0; - for (int treasure = 1; treasure <= NOBJECTS; treasure++) { - if (objects[treasure].is_treasure) { - if (PROP_IS_NOTFOUND2(valgame, treasure)) { - ++temp_tally; - } - } - } - if (temp_tally != valgame.tally) { - return false; // LCOV_EXCL_LINE - } + /* Prevent division by zero */ + if (valgame.abbnum == 0) { + return false; // LCOV_EXCL_LINE + } - /* Check that properties of objects aren't beyond expected */ - for (obj_t obj = 0; obj <= NOBJECTS; obj++) { - if (PROP_IS_INVALID(valgame.objects[obj].prop)) { - return false; // LCOV_EXCL_LINE - } - } + /* Check for RNG overflow. Truncate */ + if (valgame.lcg_x >= LCG_M) { + valgame.lcg_x %= LCG_M; // LCOV_EXCL_LINE + } - /* Check that values in linked lists for objects in locations are inside bounds */ - for (loc_t loc = LOC_NOWHERE; loc <= NLOCATIONS; loc++) { - if (valgame.locs[loc].atloc < NO_OBJECT || valgame.locs[loc].atloc > NOBJECTS * 2) { - return false; // LCOV_EXCL_LINE - } - } - for (obj_t obj = 0; obj <= NOBJECTS * 2; obj++ ) { - if (valgame.link[obj] < NO_OBJECT || valgame.link[obj] > NOBJECTS * 2) { - return false; // LCOV_EXCL_LINE - } - } + /* Check for RNG underflow. Transpose */ + if (valgame.lcg_x < LCG_M) { + valgame.lcg_x = LCG_M + (valgame.lcg_x % LCG_M); + } - return true; + /* Bounds check for locations */ + if (valgame.chloc < -1 || valgame.chloc > NLOCATIONS || + valgame.chloc2 < -1 || valgame.chloc2 > NLOCATIONS || + valgame.loc < 0 || valgame.loc > NLOCATIONS || valgame.newloc < 0 || + valgame.newloc > NLOCATIONS || valgame.oldloc < 0 || + valgame.oldloc > NLOCATIONS || valgame.oldlc2 < 0 || + valgame.oldlc2 > NLOCATIONS) { + return false; // LCOV_EXCL_LINE + } + /* Bounds check for location arrays */ + for (int i = 0; i <= NDWARVES; i++) { + if (valgame.dwarves[i].loc < -1 || + valgame.dwarves[i].loc > NLOCATIONS || + valgame.dwarves[i].oldloc < -1 || + valgame.dwarves[i].oldloc > NLOCATIONS) { + return false; // LCOV_EXCL_LINE + } + } + + for (int i = 0; i <= NOBJECTS; i++) { + if (valgame.objects[i].place < -1 || + valgame.objects[i].place > NLOCATIONS || + valgame.objects[i].fixed < -1 || + valgame.objects[i].fixed > NLOCATIONS) { + return false; // LCOV_EXCL_LINE + } + } + + /* Bounds check for dwarves */ + if (valgame.dtotal < 0 || valgame.dtotal > NDWARVES || + valgame.dkill < 0 || valgame.dkill > NDWARVES) { + return false; // LCOV_EXCL_LINE + } + + /* Validate that we didn't die too many times in save */ + if (valgame.numdie >= NDEATHS) { + return false; // LCOV_EXCL_LINE + } + + /* Recalculate tally, throw the towel if in disagreement */ + int temp_tally = 0; + for (int treasure = 1; treasure <= NOBJECTS; treasure++) { + if (objects[treasure].is_treasure) { + if (PROP_IS_NOTFOUND2(valgame, treasure)) { + ++temp_tally; + } + } + } + if (temp_tally != valgame.tally) { + return false; // LCOV_EXCL_LINE + } + + /* Check that properties of objects aren't beyond expected */ + for (obj_t obj = 0; obj <= NOBJECTS; obj++) { + if (PROP_IS_INVALID(valgame.objects[obj].prop)) { + return false; // LCOV_EXCL_LINE + } + } + + /* Check that values in linked lists for objects in locations are inside + * bounds */ + for (loc_t loc = LOC_NOWHERE; loc <= NLOCATIONS; loc++) { + if (valgame.locs[loc].atloc < NO_OBJECT || + valgame.locs[loc].atloc > NOBJECTS * 2) { + return false; // LCOV_EXCL_LINE + } + } + for (obj_t obj = 0; obj <= NOBJECTS * 2; obj++) { + if (valgame.link[obj] < NO_OBJECT || + valgame.link[obj] > NOBJECTS * 2) { + return false; // LCOV_EXCL_LINE + } + } + + return true; } /* end */ diff --git a/score.c b/score.c index 473ec6a..1d84c79 100644 --- a/score.c +++ b/score.c @@ -4,157 +4,159 @@ * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ -#include #include "advent.h" #include "dungeon.h" +#include -static int mxscor; /* ugh..the price for having score() not exit. */ +static int mxscor; /* ugh..the price for having score() not exit. */ int score(enum termination mode) { -/* mode is 'scoregame' if scoring, 'quitgame' if quitting, 'endgame' if died - * or won */ - int score = 0; + /* mode is 'scoregame' if scoring, 'quitgame' if quitting, 'endgame' if + * died or won */ + int score = 0; - /* The present scoring algorithm is as follows: - * Objective: Points: Present total possible: - * Getting well into cave 25 25 - * Each treasure < chest 12 60 - * Treasure chest itself 14 14 - * Each treasure > chest 16 224 - * Surviving (MAX-NUM)*10 30 - * Not quitting 4 4 - * Reaching "game.closng" 25 25 - * "Closed": Quit/Killed 10 - * Klutzed 25 - * Wrong way 30 - * Success 45 45 - * Came to Witt's End 1 1 - * Round out the total 2 2 - * TOTAL: 430 - * Points can also be deducted for using hints or too many turns, or for - * saving intermediate positions. */ + /* The present scoring algorithm is as follows: + * Objective: Points: Present total possible: + * Getting well into cave 25 25 + * Each treasure < chest 12 60 + * Treasure chest itself 14 14 + * Each treasure > chest 16 224 + * Surviving (MAX-NUM)*10 30 + * Not quitting 4 4 + * Reaching "game.closng" 25 25 + * "Closed": Quit/Killed 10 + * Klutzed 25 + * Wrong way 30 + * Success 45 45 + * Came to Witt's End 1 1 + * Round out the total 2 2 + * TOTAL: 430 + * Points can also be deducted for using hints or too many turns, or + * for saving intermediate positions. */ - /* First tally up the treasures. Must be in building and not broken. - * Give the poor guy 2 points just for finding each treasure. */ - mxscor = 0; - for (int i = 1; i <= NOBJECTS; i++) { - if (!objects[i].is_treasure) { - continue; + /* First tally up the treasures. Must be in building and not broken. + * Give the poor guy 2 points just for finding each treasure. */ + mxscor = 0; + for (int i = 1; i <= NOBJECTS; i++) { + if (!objects[i].is_treasure) { + continue; + } + if (objects[i].inventory != 0) { + int k = 12; + if (i == CHEST) { + k = 14; + } + if (i > CHEST) { + k = 16; + } + if (!PROP_IS_STASHED(i) && !PROP_IS_NOTFOUND(i)) { + score += 2; + } + if (game.objects[i].place == LOC_BUILDING && + PROP_IS_FOUND(i)) { + score += k - 2; + } + mxscor += k; + } } - if (objects[i].inventory != 0) { - int k = 12; - if (i == CHEST) { - k = 14; - } - if (i > CHEST) { - k = 16; - } - if (!PROP_IS_STASHED(i) && !PROP_IS_NOTFOUND(i)) { - score += 2; - } - if (game.objects[i].place == LOC_BUILDING && PROP_IS_FOUND(i)) { - score += k - 2; - } - mxscor += k; - } - } - /* Now look at how he finished and how far he got. NDEATHS and - * game.numdie tell us how well he survived. game.dflag will tell us - * if he ever got suitably deep into the cave. game.closng still - * indicates whether he reached the endgame. And if he got as far as - * "cave closed" (indicated by "game.closed"), then bonus is zero for - * mundane exits or 133, 134, 135 if he blew it (so to speak). */ - score += (NDEATHS - game.numdie) * 10; - mxscor += NDEATHS * 10; - if (mode == endgame) { - score += 4; - } - mxscor += 4; - if (game.dflag != 0) { - score += 25; - } - mxscor += 25; - if (game.closng) { - score += 25; - } - mxscor += 25; - if (game.closed) { - if (game.bonus == none) { - score += 10; + /* Now look at how he finished and how far he got. NDEATHS and + * game.numdie tell us how well he survived. game.dflag will tell us + * if he ever got suitably deep into the cave. game.closng still + * indicates whether he reached the endgame. And if he got as far as + * "cave closed" (indicated by "game.closed"), then bonus is zero for + * mundane exits or 133, 134, 135 if he blew it (so to speak). */ + score += (NDEATHS - game.numdie) * 10; + mxscor += NDEATHS * 10; + if (mode == endgame) { + score += 4; } - if (game.bonus == splatter) { - score += 25; + mxscor += 4; + if (game.dflag != 0) { + score += 25; } - if (game.bonus == defeat) { - score += 30; + mxscor += 25; + if (game.closng) { + score += 25; } - if (game.bonus == victory) { - score += 45; + mxscor += 25; + if (game.closed) { + if (game.bonus == none) { + score += 10; + } + if (game.bonus == splatter) { + score += 25; + } + if (game.bonus == defeat) { + score += 30; + } + if (game.bonus == victory) { + score += 45; + } } - } - mxscor += 45; + mxscor += 45; - /* Did he come to Witt's End as he should? */ - if (game.objects[MAGAZINE].place == LOC_WITTSEND) { - score += 1; - } - mxscor += 1; - - /* Round it off. */ - score += 2; - mxscor += 2; - - /* Deduct for hints/turns/saves. Hints < 4 are special; see database desc. */ - for (int i = 0; i < NHINTS; i++) { - if (game.hints[i].used) { - score = score - hints[i].penalty; + /* Did he come to Witt's End as he should? */ + if (game.objects[MAGAZINE].place == LOC_WITTSEND) { + score += 1; } - } - if (game.novice) { - score -= 5; - } - if (game.clshnt) { - score -= 10; - } - score = score - game.trnluz - game.saved; + mxscor += 1; - /* Return to score command if that's where we came from. */ - if (mode == scoregame) { - rspeak(GARNERED_POINTS, score, mxscor, game.turns, game.turns); - } + /* Round it off. */ + score += 2; + mxscor += 2; - return score; + /* Deduct for hints/turns/saves. Hints < 4 are special; see database + * desc. */ + for (int i = 0; i < NHINTS; i++) { + if (game.hints[i].used) { + score = score - hints[i].penalty; + } + } + if (game.novice) { + score -= 5; + } + if (game.clshnt) { + score -= 10; + } + score = score - game.trnluz - game.saved; + + /* Return to score command if that's where we came from. */ + if (mode == scoregame) { + rspeak(GARNERED_POINTS, score, mxscor, game.turns, game.turns); + } + + return score; } void terminate(enum termination mode) { -/* End of game. Let's tell him all about it. */ - int points = score(mode); + /* End of game. Let's tell him all about it. */ + int points = score(mode); #if defined ADVENT_AUTOSAVE - autosave(); + autosave(); #endif - if (points + game.trnluz + 1 >= mxscor && game.trnluz != 0) { - rspeak(TOOK_LONG); - } - if (points + game.saved + 1 >= mxscor && game.saved != 0) { - rspeak(WITHOUT_SUSPENDS); - } - rspeak(TOTAL_SCORE, points, mxscor, game.turns, game.turns); - for (int i = 1; i <= (int)NCLASSES; i++) { - if (classes[i].threshold >= points) { - speak(classes[i].message); - if (i < (int)NCLASSES) { - int nxt = classes[i].threshold + 1 - points; - rspeak(NEXT_HIGHER, nxt, nxt); - } else { - rspeak(NO_HIGHER); - } - exit(EXIT_SUCCESS); - } - } - rspeak(OFF_SCALE); - exit(EXIT_SUCCESS); + if (points + game.trnluz + 1 >= mxscor && game.trnluz != 0) { + rspeak(TOOK_LONG); + } + if (points + game.saved + 1 >= mxscor && game.saved != 0) { + rspeak(WITHOUT_SUSPENDS); + } + rspeak(TOTAL_SCORE, points, mxscor, game.turns, game.turns); + for (int i = 1; i <= (int)NCLASSES; i++) { + if (classes[i].threshold >= points) { + speak(classes[i].message); + if (i < (int)NCLASSES) { + int nxt = classes[i].threshold + 1 - points; + rspeak(NEXT_HIGHER, nxt, nxt); + } else { + rspeak(NO_HIGHER); + } + exit(EXIT_SUCCESS); + } + } + rspeak(OFF_SCALE); + exit(EXIT_SUCCESS); } /* end */ From 0175344caaadc9a7c80c17834f8b21b490a102a1 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 29 Jan 2024 12:14:56 -0500 Subject: [PATCH 169/213] 1TBS reflow, the bracening. --- actions.c | 50 +++++++++++++++++++------------ advent.h | 6 ++-- init.c | 3 +- main.c | 83 +++++++++++++++++++++++++++++++++------------------- misc.c | 42 +++++++++++++++++--------- saveresume.c | 6 ++-- 6 files changed, 122 insertions(+), 68 deletions(-) diff --git a/actions.c b/actions.c index 97e5a48..31a09c8 100644 --- a/actions.c +++ b/actions.c @@ -66,8 +66,9 @@ static phase_codes_t attack(command_t command) { ++changes; } } - if (changes >= 2) + if (changes >= 2) { return GO_UNKNOWN; + } } if (obj == BIRD) { @@ -128,8 +129,9 @@ static phase_codes_t attack(command_t command) { drop(BLOOD, LOC_SECRET5); for (obj_t i = 1; i <= NOBJECTS; i++) { if (game.objects[i].place == objects[DRAGON].plac || - game.objects[i].place == objects[DRAGON].fixd) + game.objects[i].place == objects[DRAGON].fixd) { move(i, LOC_SECRET5); + } } game.loc = LOC_SECRET5; return GO_MOVE; @@ -215,8 +217,9 @@ static phase_codes_t bigwords(vocab_t id) { * before crossing. */ if (game.objects[EGGS].place == LOC_NOWHERE && game.objects[TROLL].place == LOC_NOWHERE && - game.objects[TROLL].prop == TROLL_UNPAID) + game.objects[TROLL].prop == TROLL_UNPAID) { game.objects[TROLL].prop = TROLL_PAIDONCE; + } if (HERE(EGGS)) { pspeak(EGGS, look, true, EGGS_VANISHED); } else if (game.loc == objects[EGGS].plac) { @@ -243,9 +246,9 @@ static phase_codes_t bigwords(vocab_t id) { static void blast(void) { /* Blast. No effect unless you've got dynamite, which is a neat trick! */ - if (PROP_IS_NOTFOUND(ROD2) || !game.closed) + if (PROP_IS_NOTFOUND(ROD2) || !game.closed) { rspeak(REQUIRES_DYNAMITE); - else { + } else { if (HERE(ROD2)) { game.bonus = splatter; rspeak(SPLATTER_MESSAGE); @@ -274,8 +277,9 @@ static phase_codes_t vbreak(verb_t verb, obj_t obj) { } case VASE: if (game.objects[VASE].prop == VASE_WHOLE) { - if (TOTING(VASE)) + if (TOTING(VASE)) { drop(VASE, game.loc); + } state_change(VASE, VASE_BROKEN); game.objects[VASE].fixed = IS_FIXED; break; @@ -435,8 +439,9 @@ static int chain(verb_t verb) { } game.objects[CHAIN].prop = CHAIN_HEAP; game.objects[CHAIN].fixed = IS_FREE; - if (game.objects[BEAR].prop != BEAR_DEAD) + if (game.objects[BEAR].prop != BEAR_DEAD) { game.objects[BEAR].prop = CONTENTED_BEAR; + } switch (game.objects[BEAR].prop) { // LCOV_EXCL_START @@ -465,8 +470,9 @@ static int chain(verb_t verb) { game.objects[CHAIN].prop = CHAIN_FIXED; - if (TOTING(CHAIN)) + if (TOTING(CHAIN)) { drop(CHAIN, game.loc); + } game.objects[CHAIN].fixed = IS_FIXED; rspeak(CHAIN_LOCKED); @@ -622,8 +628,9 @@ static phase_codes_t eat(verb_t verb, obj_t obj) { */ switch (obj) { case INTRANSITIVE: - if (!HERE(FOOD)) + if (!HERE(FOOD)) { return GO_UNKNOWN; + } /* FALLTHRU */ case FOOD: DESTROY(FOOD); @@ -797,8 +804,9 @@ phase_codes_t fill(verb_t verb, obj_t obj) { speak(actions[verb].message); return GO_CLEAROBJ; } - if (obj == INTRANSITIVE && !HERE(BOTTLE)) + if (obj == INTRANSITIVE && !HERE(BOTTLE)) { return GO_UNKNOWN; + } if (HERE(URN) && game.objects[URN].prop != URN_EMPTY) { rspeak(URN_NOPOUR); @@ -891,18 +899,21 @@ static phase_codes_t inven(void) { * burden. */ bool empty = true; for (obj_t i = 1; i <= NOBJECTS; i++) { - if (i == BEAR || !TOTING(i)) + if (i == BEAR || !TOTING(i)) { continue; + } if (empty) { rspeak(NOW_HOLDING); empty = false; } pspeak(i, touch, false, -1); } - if (TOTING(BEAR)) + if (TOTING(BEAR)) { rspeak(TAME_BEAR); - if (empty) + } + if (empty) { rspeak(NO_CARRY); + } return GO_CLEAROBJ; } @@ -919,8 +930,9 @@ static phase_codes_t light(verb_t verb, obj_t obj) { obj = URN; selects++; } - if (selects != 1) + if (selects != 1) { return GO_UNKNOWN; + } } switch (obj) { @@ -1181,9 +1193,9 @@ static phase_codes_t reservoir(void) { state_change(RESER, game.objects[RESER].prop == WATERS_PARTED ? WATERS_UNPARTED : WATERS_PARTED); - if (AT(RESER)) + if (AT(RESER)) { return GO_CLEAROBJ; - else { + } else { game.oldlc2 = game.loc; game.newloc = LOC_NOWHERE; rspeak(NOT_BRIGHT); @@ -1266,8 +1278,9 @@ static phase_codes_t throwit(command_t command) { } else { if (atdwrf(game.loc) <= 0) { if (AT(DRAGON) && - game.objects[DRAGON].prop == DRAGON_BARS) + game.objects[DRAGON].prop == DRAGON_BARS) { return throw_support(DRAGON_SCALES); + } if (AT(TROLL)) { return throw_support(TROLL_RETURNS); } @@ -1357,10 +1370,11 @@ static phase_codes_t wave(verb_t verb, obj_t obj) { : FREE_FLY); return GO_CLEAROBJ; } - if (HERE(BIRD)) + if (HERE(BIRD)) { rspeak((game.objects[BIRD].prop == BIRD_CAGED) ? CAGE_FLY : FREE_FLY); + } state_change(FISSURE, game.objects[FISSURE].prop == BRIDGED ? UNBRIDGED diff --git a/advent.h b/advent.h index b263645..2a23eb9 100644 --- a/advent.h +++ b/advent.h @@ -221,9 +221,9 @@ struct game_t { /* dflag controls the level of activation of dwarves: * 0 No dwarf stuff yet (wait until reaches Hall Of Mists) * 1 Reached Hall Of Mists, but hasn't met first dwarf - * 2 Met first dwarf, others start moving, no knives thrown - *yet 3 A knife has been thrown (first set always misses) 3+ - *Dwarves are mad (increases their accuracy) */ + * 2 Met 1t dwarf, others start moving, no knives thrown yet + * 3 A knife has been thrown (first set always misses) 3+ + * Dwarves are mad (increases their accuracy) */ int32_t dflag; int32_t dkill; // dwarves killed diff --git a/init.c b/init.c index d00255d..e413fff 100644 --- a/init.c +++ b/init.c @@ -27,8 +27,9 @@ struct game_t game = { }; int initialise(void) { - if (settings.oldstyle) + if (settings.oldstyle) { printf("Initialising...\n"); + } srand(time(NULL)); int seedval = (int)rand(); diff --git a/main.c b/main.c index cff0780..7f5d8a1 100644 --- a/main.c +++ b/main.c @@ -31,8 +31,9 @@ void autosave(void) { // exclude from coverage analysis because it requires interactivity to test static void sig_handler(int signo) { if (signo == SIGINT) { - if (settings.logfp != NULL) + if (settings.logfp != NULL) { fflush(settings.logfp); + } } #if defined ADVENT_AUTOSAVE @@ -145,8 +146,9 @@ static void checkhints(void) { NO_OBJECT && game.locs[game.oldlc2].atloc == NO_OBJECT && - game.holdng > 1) + game.holdng > 1) { break; + } game.hints[hint].lc = 0; return; case 4: /* dark */ @@ -170,8 +172,9 @@ static void checkhints(void) { game.locs[game.oldloc].atloc == NO_OBJECT && game.locs[game.oldlc2].atloc == - NO_OBJECT) + NO_OBJECT) { break; + } return; case 8: /* ogre */ i = atdwrf(game.loc); @@ -323,8 +326,9 @@ static bool dwarfmove(void) { /* Dwarf activity level ratchets up */ if (game.dflag == 0) { - if (INDEEP(game.loc)) + if (INDEEP(game.loc)) { game.dflag = 1; + } return true; } @@ -373,33 +377,36 @@ static bool dwarfmove(void) { /* Fill tk array with all the places this dwarf might go. */ unsigned int j = 1; kk = tkey[game.dwarves[i].loc]; - if (kk != 0) + if (kk != 0) { do { enum desttype_t desttype = travel[kk].desttype; game.newloc = travel[kk].destval; /* Have we avoided a dwarf encounter? */ - if (desttype != dest_goto) + if (desttype != dest_goto) { continue; - else if (!INDEEP(game.newloc)) + } else if (!INDEEP(game.newloc)) { continue; - else if (game.newloc == game.dwarves[i].oldloc) + } else if (game.newloc == + game.dwarves[i].oldloc) { continue; - else if (j > 1 && game.newloc == tk[j - 1]) + } else if (j > 1 && game.newloc == tk[j - 1]) { continue; - else if (j >= DIM(tk) - 1) + } else if (j >= DIM(tk) - 1) { /* This can't actually happen. */ continue; // LCOV_EXCL_LINE - else if (game.newloc == game.dwarves[i].loc) + } else if (game.newloc == game.dwarves[i].loc) { continue; - else if (FORCED(game.newloc)) + } else if (FORCED(game.newloc)) { continue; - else if (i == PIRATE && - CNDBIT(game.newloc, COND_NOARRR)) + } else if (i == PIRATE && + CNDBIT(game.newloc, COND_NOARRR)) { continue; - else if (travel[kk].nodwarves) + } else if (travel[kk].nodwarves) { continue; + } tk[j++] = game.newloc; } while (!travel[kk++].stop); + } tk[j] = game.dwarves[i].oldloc; if (j >= 2) { --j; @@ -502,8 +509,9 @@ static void croak(void) { * where he died. */ game.objects[WATER].place = game.objects[OIL].place = LOC_NOWHERE; - if (TOTING(LAMP)) + if (TOTING(LAMP)) { game.objects[LAMP].prop = LAMP_DARK; + } for (int j = 1; j <= NOBJECTS; j++) { int i = NOBJECTS + 1 - j; if (TOTING(i)) { @@ -521,8 +529,9 @@ static void describe_location(void) { const char *msg = locations[game.loc].description.small; if (MOD(game.locs[game.loc].abbrev, game.abbnum) == 0 || - msg == NO_MESSAGE) + msg == NO_MESSAGE) { msg = locations[game.loc].description.big; + } if (!FORCED(game.loc) && DARK(game.loc)) { msg = arbitrary_messages[PITCH_DARK]; @@ -534,8 +543,9 @@ static void describe_location(void) { speak(msg); - if (game.loc == LOC_Y2 && PCT(25) && !game.closng) + if (game.loc == LOC_Y2 && PCT(25) && !game.closng) { rspeak(SAYS_PLUGH); + } } static bool traveleq(int a, int b) { @@ -569,8 +579,9 @@ static void playermove(int motion) { * forced-motion. te_tmp saves entry -> forced loc -> previous * loc. */ motion = game.oldloc; - if (FORCED(motion)) + if (FORCED(motion)) { motion = game.oldlc2; + } game.oldlc2 = game.oldloc; game.oldloc = game.loc; if (CNDBIT(game.loc, COND_NOBACK)) { @@ -591,8 +602,9 @@ static void playermove(int motion) { if (desttype == dest_goto) { if (FORCED(scratchloc) && travel[tkey[scratchloc]].destval == - motion) + motion) { te_tmp = travel_entry; + } } if (!travel[travel_entry].stop) { ++travel_entry; /* go to next travel @@ -641,8 +653,9 @@ static void playermove(int motion) { * indexes the beginning of the motion entries for here (game.loc). */ for (;;) { if ((travel[travel_entry].motion == HERE) || - travel[travel_entry].motion == motion) + travel[travel_entry].motion == motion) { break; + } if (travel[travel_entry].stop) { /* Couldn't find an entry matching the motion word * passed in. Various messages depending on word given. @@ -699,15 +712,17 @@ static void playermove(int motion) { if (condtype == cond_goto || condtype == cond_pct) { if (condarg1 == 0 || - PCT(condarg1)) + PCT(condarg1)) { break; + } /* else fall through */ } /* YAML [with OBJ] clause */ else if (TOTING(condarg1) || (condtype == cond_with && - AT(condarg1))) + AT(condarg1))) { break; + } /* else fall through to check [not OBJ * STATE] */ } else if (game.objects[condarg1].prop != @@ -719,8 +734,9 @@ static void playermove(int motion) { * Skip to next non-matching destination */ int te_tmp = travel_entry; do { - if (travel[te_tmp].stop) + if (travel[te_tmp].stop) { BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE + } ++te_tmp; } while (traveleq(travel_entry, te_tmp)); travel_entry = te_tmp; @@ -771,8 +787,10 @@ static void playermove(int motion) { { int te_tmp = travel_entry; do { - if (travel[te_tmp].stop) + if (travel[te_tmp] + .stop) { BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE + } ++te_tmp; } while (traveleq(travel_entry, te_tmp)); @@ -814,10 +832,11 @@ static void playermove(int motion) { objects[TROLL].fixd - game.loc; if (game.objects[TROLL].prop == - TROLL_UNPAID) + TROLL_UNPAID) { game.objects[TROLL] .prop = TROLL_PAIDONCE; + } if (!TOTING(BEAR)) { return; } @@ -962,8 +981,9 @@ static bool closecheck(void) { game.clock1 = -1; game.closng = true; return game.closed; - } else if (game.clock1 < 0) + } else if (game.clock1 < 0) { --game.clock2; + } if (game.clock2 == 0) { /* Once he's panicked, and clock2 has run out, we come here * to set up the storage room. The room has two locs, @@ -1159,8 +1179,9 @@ static bool preprocess_command(command_t *command) { /* If no word type is given for the first word, we assume it's a * motion. */ - if (command->word[0].type == NO_WORD_TYPE) + if (command->word[0].type == NO_WORD_TYPE) { command->word[0].type = MOTION; + } command->state = PREPROCESSED; return true; @@ -1252,9 +1273,10 @@ static bool do_command(void) { } for (size_t i = 1; i <= NOBJECTS; i++) { if (TOTING(i) && (PROP_IS_NOTFOUND(i) || - PROP_IS_STASHED(i))) + PROP_IS_STASHED(i))) { game.objects[i].prop = PROP_STASHED(i); + } } } @@ -1534,8 +1556,9 @@ int main(int argc, char *argv[]) { game.novice = yes_or_no(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); - if (game.novice) + if (game.novice) { game.limit = NOVICELIMIT; + } #endif if (settings.logfp) { diff --git a/misc.c b/misc.c index ad110d9..9e90d05 100644 --- a/misc.c +++ b/misc.c @@ -195,7 +195,7 @@ static int word_count(char *str) { int count = 0; int inblanks = true; - for (char *s = str; *s; s++) + for (char *s = str; *s; s++) { if (inblanks) { if (strchr(delims, *s) == 0) { ++count; @@ -206,6 +206,7 @@ static int word_count(char *str) { inblanks = true; } } + } return (count); } @@ -213,8 +214,9 @@ static int word_count(char *str) { static char *get_input(void) { // Set up the prompt char input_prompt[] = PROMPT; - if (!settings.prompt) + if (!settings.prompt) { input_prompt[0] = '\0'; + } // Print a blank line printf("\n"); @@ -223,8 +225,9 @@ static char *get_input(void) { for (;;) { input = myreadline(input_prompt); - if (input == NULL) // Got EOF; return with it. + if (input == NULL) { // Got EOF; return with it. return (input); + } if (input[0] == '#') { // Ignore comments. free(input); continue; @@ -238,11 +241,13 @@ static char *get_input(void) { add_history(input); - if (!isatty(0)) + if (!isatty(0)) { echo_input(stdout, input_prompt, input); + } - if (settings.logfp) + if (settings.logfp) { echo_input(settings.logfp, "", input); + } return (input); } @@ -270,8 +275,9 @@ bool silent_yes_or_no(void) { free(reply); - for (int i = 0; i < (int)strlen(firstword); ++i) + for (int i = 0; i < (int)strlen(firstword); ++i) { firstword[i] = tolower(firstword[i]); + } int yes = strncmp("yes", firstword, sizeof("yes") - 1); int y = strncmp("y", firstword, sizeof("y") - 1); @@ -286,8 +292,9 @@ bool silent_yes_or_no(void) { } else if (no == 0 || n == 0) { outcome = false; break; - } else + } else { rspeak(PLEASE_ANSWER); + } } return (outcome); } @@ -340,8 +347,9 @@ bool yes_or_no(const char *question, const char *yes_response, speak(no_response); outcome = false; break; - } else + } else { rspeak(PLEASE_ANSWER); + } } return (outcome); @@ -357,8 +365,9 @@ static int get_motion_vocab_id(const char *word) { TOKLEN) == 0 && (strlen(word) > 1 || strchr(ignore, word[0]) == NULL || - !settings.oldstyle)) + !settings.oldstyle)) { return (i); + } } } // If execution reaches here, we didn't find the word. @@ -372,8 +381,9 @@ static int get_object_vocab_id(const char *word) { // removed for (int j = 0; j < objects[i].words.n; ++j) { if (strncasecmp(word, objects[i].words.strs[j], - TOKLEN) == 0) + TOKLEN) == 0) { return (i); + } } } // If execution reaches here, we didn't find the word. @@ -529,8 +539,9 @@ bool get_command_input(command_t *command) { for (;;) { input = get_input(); - if (input == NULL) + if (input == NULL) { return false; + } if (word_count(input) > 2) { rspeak(TWO_WORDS); free(input); @@ -637,8 +648,9 @@ void carry(obj_t object, loc_t where) { * * Possibly this check should be skipped whwn oldstyle is on. */ - if (object != BIRD) + if (object != BIRD) { ++game.holdng; + } } if (game.locs[where].atloc == object) { game.locs[where].atloc = game.link[object]; @@ -658,8 +670,8 @@ void drop(obj_t object, loc_t where) { if (object > NOBJECTS) { game.objects[object - NOBJECTS].fixed = where; } else { - if (game.objects[object].place == CARRIED) - if (object != BIRD) + if (game.objects[object].place == CARRIED) { + if (object != BIRD) { /* The bird has to be weightless. This ugly * hack (and the corresponding code in the carry * function) brought to you by the fact that @@ -668,6 +680,8 @@ void drop(obj_t object, loc_t where) { * the right thing happen. */ --game.holdng; + } + } game.objects[object].place = where; } if (where == LOC_NOWHERE || where == CARRIED) { diff --git a/saveresume.c b/saveresume.c index ea30e4d..9822b76 100644 --- a/saveresume.c +++ b/saveresume.c @@ -127,11 +127,13 @@ int resume(void) { while (fp == NULL) { char *name = myreadline("\nFile name: "); - if (name == NULL) + if (name == NULL) { return GO_TOP; + } name = strip(name); - if (strlen(name) == 0) + if (strlen(name) == 0) { return GO_TOP; // LCOV_EXCL_LINE + } fp = fopen(name, READ_MODE); if (fp == NULL) { printf("Can't open file %s, try again.\n", name); From 1ef39055f3e4fb7c1bd84804a994c20b87301521 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Feb 2024 10:07:58 -0500 Subject: [PATCH 170/213] Make reflow run black. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 9c837d2..2e81dfc 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,7 @@ check: advent cheat reflow: @clang-format --style="{IndentWidth: 8, UseTab: ForIndentation}" -i $$(find . -name "*.[ch]") + @black --quiet *.py # Requires gcov, lcov, libasan6, and libubsan1 # The last two are Ubuntu names, might vary on other distributions. From 5b917084b035b815cc7b8282219ae7266f239d68 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Feb 2024 11:43:36 -0500 Subject: [PATCH 171/213] Minor repair of savefile validation code. --- saveresume.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/saveresume.c b/saveresume.c index 9822b76..100c925 100644 --- a/saveresume.c +++ b/saveresume.c @@ -184,12 +184,7 @@ bool is_valid(struct game_t valgame) { /* Check for RNG overflow. Truncate */ if (valgame.lcg_x >= LCG_M) { - valgame.lcg_x %= LCG_M; // LCOV_EXCL_LINE - } - - /* Check for RNG underflow. Transpose */ - if (valgame.lcg_x < LCG_M) { - valgame.lcg_x = LCG_M + (valgame.lcg_x % LCG_M); + return false; } /* Bounds check for locations */ From 580f409ee63779f79494188db3afdd0f455d9a6d Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Feb 2024 11:44:04 -0500 Subject: [PATCH 172/213] At this revision, make cppcheck runs clean. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2e81dfc..7521a43 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ debug: linty CSUPPRESSIONS = --suppress=missingIncludeSystem --suppress=invalidscanf cppcheck: - cppcheck -I. --template gcc --enable=all $(CSUPPRESSIONS) *.[ch] + cppcheck -I. --template gcc -UPROP_SET_SEEN --enable=all $(CSUPPRESSIONS) *.[ch] pylint: @pylint --score=n *.py */*.py From f24fcd297176c7a95e999bd34e627bb0f4159c3a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Feb 2024 12:48:33 -0500 Subject: [PATCH 173/213] Perform full code validation on every make check. --- Makefile | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 7521a43..978d5a8 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,14 @@ clean: cheat: $(CHEAT_OBJS) dungeon.o $(CC) $(CCFLAGS) $(DBX) -o cheat $(CHEAT_OBJS) dungeon.o $(LDFLAGS) $(LIBS) -check: advent cheat +CSUPPRESSIONS = --suppress=missingIncludeSystem --suppress=invalidscanf +cppcheck: + @-cppcheck -I. --quiet --template gcc -UPROP_SET_SEEN --enable=all $(CSUPPRESSIONS) *.[ch] + +pylint: + @-pylint --score=n *.py */*.py + +check: advent cheat pylint cppcheck cd tests; $(MAKE) --quiet reflow: @@ -151,9 +158,3 @@ debug: CCFLAGS += -fsanitize=address debug: CCFLAGS += -fsanitize=undefined debug: linty -CSUPPRESSIONS = --suppress=missingIncludeSystem --suppress=invalidscanf -cppcheck: - cppcheck -I. --template gcc -UPROP_SET_SEEN --enable=all $(CSUPPRESSIONS) *.[ch] - -pylint: - @pylint --score=n *.py */*.py From 43a08621e4404bb47e3bde1d0b6c12bf79d7066e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Feb 2024 15:52:03 -0500 Subject: [PATCH 174/213] asciidoc -> asciidoctor. --- Dockerfile.ci | 2 +- Makefile | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Dockerfile.ci b/Dockerfile.ci index 598687b..b8eeef5 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -9,4 +9,4 @@ FROM ubuntu ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -RUN apt-get install --yes --no-install-recommends make gcc-10 libedit-dev libasan6 libubsan1 python3 python3-yaml lcov asciidoc libxslt1.1 pkg-config docbook-xml xsltproc +RUN apt-get install --yes --no-install-recommends make gcc libedit-dev libasan6 libubsan1 python3 python3-yaml lcov asciidoctor libxslt1.1 pkg-config docbook-xml xsltproc diff --git a/Makefile b/Makefile index 978d5a8..ea8fcd4 100644 --- a/Makefile +++ b/Makefile @@ -87,15 +87,16 @@ reflow: coverage: clean debug cd tests; $(MAKE) coverage --quiet -.SUFFIXES: .adoc .html .6 +# Note: to suppress the footers with timestamps being generated in HTML, +# we use "-a nofooter". +# To debug asciidoc problems, you may need to run "xmllint --nonet --noout --valid" +# on the intermediate XML that throws an error. +.SUFFIXES: .html .adoc .6 -# Requires asciidoc and xsltproc/docbook stylesheets. .adoc.6: - a2x --doctype manpage --format manpage $< + asciidoctor -D. -a nofooter -b manpage $< .adoc.html: - asciidoc $< -.adoc: - asciidoc $< + asciidoctor -D. -a nofooter -a webfonts! $< html: advent.html history.html hints.html From a2fa136988609cfd57a0aed53b42630339e052ac Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Feb 2024 16:16:05 -0500 Subject: [PATCH 175/213] Remove unused production. --- Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Makefile b/Makefile index ea8fcd4..0da7fb8 100644 --- a/Makefile +++ b/Makefile @@ -112,9 +112,6 @@ advent-$(VERS).tar.gz: $(SOURCES) $(DOCS) (tar -T MANIFEST -czvf advent-$(VERS).tar.gz) @(rm advent-$(VERS)) -indent: - astyle -n -A3 --pad-header --min-conditional-indent=1 --pad-oper *.c - release: advent-$(VERS).tar.gz advent.html history.html hints.html notes.html shipper version=$(VERS) | sh -e -x From 6174129116ca191c5435c14853047908d05caf5a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 4 Feb 2024 16:46:43 -0500 Subject: [PATCH 176/213] Add a detail to the installation instructiions. --- INSTALL.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/INSTALL.adoc b/INSTALL.adoc index 683e2f0..5184d6b 100644 --- a/INSTALL.adoc +++ b/INSTALL.adoc @@ -21,3 +21,5 @@ You can also use pip to install PyYAML: `pip3 install PyYAML`. 4. Optionally run a regression test on the code with `make check`. 5. Run `./advent` to play. + +6. If you want to buld the documentation you will need asciidoctor. From b610a62685444a565fda09374c7d21957081f7e4 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 5 Feb 2024 07:43:23 -0500 Subject: [PATCH 177/213] Documentation polishing. --- advent.adoc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/advent.adoc b/advent.adoc index 9e628e0..d7231f6 100644 --- a/advent.adoc +++ b/advent.adoc @@ -20,9 +20,9 @@ adventure". To learn more about the changes since the 350-point original, type 'news' at the command prompt. There is an 'adventure' in the BSD games package that is a C port by -Jim Gillogly of the Don Woods's 1977 version of this game. To avoid a name -collision, this game builds as 'advent', reflecting the fact that the -PDP-10 on which the game originally ran limited filenames to 6 characters. +Jim Gillogly of the 1977 version. To avoid a name collision, this game +builds as 'advent', reflecting the fact that the PDP-10 on which the +game originally ran limited filenames to 6 characters. This version is released as open source with the permission and encouragement of the original authors. @@ -34,7 +34,8 @@ command history. Some minor bugs and message typos have been fixed. Otherwise, the "version" command is almost the only way to tell you're not running -Don's 1977 version. +Don's 1977 version until you get to the new cave sections added for +2.5. To exit the game, type Ctrl-D (EOF). @@ -44,9 +45,9 @@ There have been no gameplay changes. -l:: Log commands to specified file. --r:: Restore game from specified file +-r:: Restore game from specified save file --a:: Load from specified file and autosave to it on exit or signal. +-a:: Load from specified save file and autosave to it on exit or signal. -o:: Old-style. Reverts some minor cosmetic fixes in game messages. Restores original interface, no prompt or line editing. @@ -59,9 +60,9 @@ argument of '-' is taken as a directive to read from standard input. == BUGS == -The binary save file format is fragile, dependent on your machine word -size and endianness, and unlikely to survive through version bumps. There -is a version check. +The binary save file format is fragile, dependent on your machine's +endianness, and unlikely to survive through version bumps. There are +version and emdianness checks when attempting to restore from a save. The input parser was the first attempt *ever* at natural-language parsing in a game and has some known deficiencies. While later text From fcf6935689a83d363771c05660ecc9ff5b1e013b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 5 Feb 2024 07:47:01 -0500 Subject: [PATCH 178/213] Ready to ship 1.18. --- NEWS.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index 68aa36c..92c2f10 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,6 +2,9 @@ // SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 +1.18: 2024-02-05:: + Bring the manual page fully up to date. + 1.17: 2024-01-02:: Saying Z'ZZZ at reservoir no longer causes the waters to part and crash. From 0fafbe379f0d72a72bcecc2f946c29b562fba161 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 5 Feb 2024 07:51:00 -0500 Subject: [PATCH 179/213] Ubuntu-discuss doesn't want to see release notifications. --- control | 2 -- 1 file changed, 2 deletions(-) diff --git a/control b/control index 841e7ab..9b7fe43 100644 --- a/control +++ b/control @@ -9,8 +9,6 @@ Description: Colossal Cave Adventure, the 1995 430-point version. been known as Adventure 2.5. The original PDP-10 name 'advent' is used for the built program to avoid collision with the BSD Games version. -XBS-Destinations: mailto:ubuntu-devel-discuss@lists.ubuntu.com - Homepage: http://www.catb.org/~esr/open-adventure XBS-HTML-Target: index.html From bad34acf1ef988f77a38c7f6cad2cf1546c83d4c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 5 Feb 2024 08:07:31 -0500 Subject: [PATCH 180/213] Improve the project summary. --- control | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/control b/control index 9b7fe43..e47484d 100644 --- a/control +++ b/control @@ -5,9 +5,10 @@ Package: open-adventure Description: Colossal Cave Adventure, the 1995 430-point version. This is the last descendant of the original 1976 Colossal Cave Adventure - worked on by the original authors - Crowther & Woods. It has sometimes - been known as Adventure 2.5. The original PDP-10 name 'advent' is used - for the built program to avoid collision with the BSD Games version. + worked on by the original authors - Crowther & Woods; it is shipped with + their permission and encouragement. It has sometimes been known as + Adventure 2.5. The original PDP-10 name 'advent' is used for the + built program to avoid collision with the BSD Games version. Homepage: http://www.catb.org/~esr/open-adventure From 62cd0c78dab69bef371aec943fe78ff464ae4f15 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 15 Feb 2024 12:56:01 -0500 Subject: [PATCH 181/213] Reissue 1.18 - same code, corrected metadata. --- NEWS.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.adoc b/NEWS.adoc index 92c2f10..624f6ce 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 -1.18: 2024-02-05:: +1.18: 2024-02-15:: Bring the manual page fully up to date. 1.17: 2024-01-02:: From b51612131d7552c9629a1e843b236b5b9be096d5 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 29 Apr 2024 11:43:41 -0400 Subject: [PATCH 182/213] Typo fix. --- advent.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advent.adoc b/advent.adoc index d7231f6..f132b0c 100644 --- a/advent.adoc +++ b/advent.adoc @@ -62,7 +62,7 @@ argument of '-' is taken as a directive to read from standard input. The binary save file format is fragile, dependent on your machine's endianness, and unlikely to survive through version bumps. There are -version and emdianness checks when attempting to restore from a save. +version and endianness checks when attempting to restore from a save. The input parser was the first attempt *ever* at natural-language parsing in a game and has some known deficiencies. While later text From 7903ac1bb879208dbe4a4e3e24f21997d53f68d6 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Jun 2024 21:12:41 -0400 Subject: [PATCH 183/213] More validation, with -Wall and -Wextra. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0da7fb8..a7acbd8 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ VERS=$(shell sed -n Date: Tue, 25 Jun 2024 13:08:50 -0400 Subject: [PATCH 184/213] Incorporate Ryan Sarson's test for correct knife message. --- tests/knife.chk | 386 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/knife.log | 56 +++++++ 2 files changed, 442 insertions(+) create mode 100644 tests/knife.chk create mode 100644 tests/knife.log diff --git a/tests/knife.chk b/tests/knife.chk new file mode 100644 index 0000000..0c150ec --- /dev/null +++ b/tests/knife.chk @@ -0,0 +1,386 @@ + +Welcome to Adventure!! Would you like instructions? + +> no + +You are standing at the end of a road before a small brick building. +Around you is a forest. A small stream flows out of the building and +down a gully. + +> seed 1640849217 + +Seed set to 1640849217 + +You're in front of building. + +> e + +You are inside a building, a well house for a large spring. + +There are some keys on the ground here. + +There is a shiny brass lamp nearby. + +There is food here. + +There is a bottle of water here. + +> get lamp + +OK + +> xyzzy + +>>Foof!<< + +It is now pitch dark. If you proceed you will likely fall into a pit. + +> get rod + +OK + +> on + +Your lamp is now on. + +You are in a debris room filled with stuff washed in from the surface. +A low wide passage with cobbles becomes plugged with mud and debris +here, but an awkward canyon leads upward and west. In the mud someone +has scrawled, "MAGIC WORD XYZZY". + +> w + +You are in an awkward sloping east/west canyon. + +> w + +You are in a splendid chamber thirty feet high. The walls are frozen +rivers of orange stone. An awkward canyon and a good passage exit +from east and west sides of the chamber. + +A cheerful little bird is sitting here singing. + +> w + +At your feet is a small pit breathing traces of white mist. An east +passage ends here except for a small crack leading on. + +Rough stone steps lead down the pit. + +> d + +You are at one end of a vast hall stretching forward out of sight to +the west. There are openings to either side. Nearby, a wide stone +staircase leads downward. The hall is filled with wisps of white mist +swaying to and fro almost as if alive. A cold wind blows up the +staircase. There is a passage at the top of a dome behind you. + +Rough stone steps lead up the dome. + +> w + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +> wave rod + +A crystal bridge now spans the fissure. + +> w + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +A crystal bridge spans the fissure. + +> w + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +A crystal bridge spans the fissure. + +> w + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You are on the east bank of a fissure slicing clear across the hall. +The mist is quite thick here, and the fissure is too wide to jump. + +A crystal bridge spans the fissure. + +> w + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +You're on east bank of fissure. + +A crystal bridge spans the fissure. + +> w + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> e + +A little dwarf just walked around a corner, saw you, threw a little +axe at you which missed, cursed, and ran away. + +You're on east bank of fissure. + +There is a little axe here. + +A crystal bridge spans the fissure. + +> w + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You're on west bank of fissure. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> get knife + +The dwarves' knives vanish as they strike the walls of the cave. + +> look + +Sorry, but I am not allowed to give more detail. I will repeat the +long description of your location. + +There is a threatening little dwarf in the room with you! + +One sharp nasty knife is thrown at you! + +It misses! + +You are on the west side of the fissure in the Hall of Mists. + +There are diamonds here! + +A crystal bridge spans the fissure. + +> get knife + +The dwarves' knives vanish as they strike the walls of the cave. + +> quit + +Do you really want to quit now? + +> yes + +OK + +You scored 59 out of a possible 430, using 50 turns. + +Your score qualifies you as a novice class adventurer. + +To achieve the next higher rating, you need 62 more points. diff --git a/tests/knife.log b/tests/knife.log new file mode 100644 index 0000000..e7477e2 --- /dev/null +++ b/tests/knife.log @@ -0,0 +1,56 @@ +## Test whether KNIVES_VANISH can be issued twice +# SPDX-FileCopyrightText: Copyright Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause +no +seed 1640849217 +e +get lamp +xyzzy +get rod +on +w +w +w +d +w +wave rod +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +e +w +get knife +look +get knife +quit +yes From bd499dc53276f28994b7ffc833fb8499fb05c5eb Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 25 Jun 2024 13:23:21 -0400 Subject: [PATCH 185/213] Fix GitLab issue #69: repeated knive caveat message --- NEWS.adoc | 3 +++ main.c | 10 ++++++---- notes.adoc | 6 +++++- tests/knife.chk | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/NEWS.adoc b/NEWS.adoc index 624f6ce..28dd018 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,6 +2,9 @@ // SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 +Repository head:: + Ensore that the KNIVES_VANISH message can't issue twice. + 1.18: 2024-02-15:: Bring the manual page fully up to date. diff --git a/main.c b/main.c index 7f5d8a1..6d904f2 100644 --- a/main.c +++ b/main.c @@ -1280,11 +1280,13 @@ static bool do_command(void) { } } - /* Check to see if the room is dark. If the knife is - * here, and it's dark, the knife permanently disappears - */ + /* Check to see if the room is dark. */ game.wzdark = DARK(game.loc); - if (game.knfloc != LOC_NOWHERE && + + /* If the knife is not here it permanently disappears. + * Possibly this should fire if the knife is here but + * the room is dark? */ + if (game.knfloc > LOC_NOWHERE && game.knfloc != game.loc) { game.knfloc = LOC_NOWHERE; } diff --git a/notes.adoc b/notes.adoc index b970e7c..833682c 100644 --- a/notes.adoc +++ b/notes.adoc @@ -78,7 +78,11 @@ Bug fixes: "eying" for "eyeing", "thresholds" for "threshholds". * Under odd circumstances (dropping rug or vase outdoors) the game could - formerly say "floor" when it should say "ground" (or "dirt", or something). + formerly say "floor" when it should say "ground" (or "dirt", or + something). + +* The "knives vanish" message could formerly be emitted when "I see no + knife here." would be appropriate. Enhancements: diff --git a/tests/knife.chk b/tests/knife.chk index 0c150ec..76a3b6b 100644 --- a/tests/knife.chk +++ b/tests/knife.chk @@ -369,7 +369,7 @@ A crystal bridge spans the fissure. > get knife -The dwarves' knives vanish as they strike the walls of the cave. +I see no knife here. > quit From 86fe4bd1212c346de237755139eaf7bfcb00946f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 27 Jun 2024 13:04:33 -0400 Subject: [PATCH 186/213] Verify that tesrts still match advent430 where expected. --- tests/Makefile | 2 +- tests/knife.log | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index 2ed7431..997096a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -170,7 +170,7 @@ oldcompare: echo 1..$(words $(shell ls *.log))) | $(TAPFILTER) @rm *.ochk *-new advent430 adventure.data -# List all NOMPARE tests. +# List all NOCOMPARE tests. residuals: @grep -n NOCOMPARE *.log diff --git a/tests/knife.log b/tests/knife.log index e7477e2..1c811ea 100644 --- a/tests/knife.log +++ b/tests/knife.log @@ -1,6 +1,7 @@ ## Test whether KNIVES_VANISH can be issued twice # SPDX-FileCopyrightText: Copyright Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause +#NOCOMPARE avoide spuriuous failure on second "get knife" no seed 1640849217 e From 1080b45d391062bbaadd16900d2259c6d1b888ed Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 27 Jun 2024 13:29:28 -0400 Subject: [PATCH 187/213] Comment typo fix. --- advent.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/advent.h b/advent.h index 2a23eb9..21a521f 100644 --- a/advent.h +++ b/advent.h @@ -66,7 +66,7 @@ * can be recovered later. Various objects get this property when * the cave starts to close. Only seems to be significant for the bird * and readable objects, notably the clam/oyster - but the code around - * those test is difficult to read. + * those tests is difficult to read. */ #define PROP_STASHIFY(n) (-1 - (n)) #define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) @@ -80,7 +80,7 @@ #else /* (ESR) Only the boldest of adventurers will explore here. This * alternate set of definitions for the macros above was an attempt to - * break from out of the state encoding a per-object "found" member + * break out of the state encoding a per-object "found" member * telling whether or not the player has seen the object. * * What's broken when you try to use thus is From 63e8579f74956ca2e729311920c90a929b39176b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 27 Jun 2024 13:39:27 -0400 Subject: [PATCH 188/213] Ready to shp 1.19. --- NEWS.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.adoc b/NEWS.adoc index 28dd018..2d0dcee 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 -Repository head:: +1.19: 2024-06-27:: Ensore that the KNIVES_VANISH message can't issue twice. 1.18: 2024-02-15:: From 124e7768b45712a7c2dbd979bda88e2e54fd0ed6 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 27 Jun 2024 19:50:56 -0400 Subject: [PATCH 189/213] Cease relying on C storage starting zeroed. --- init.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/init.c b/init.c index e413fff..2fffc14 100644 --- a/init.c +++ b/init.c @@ -76,13 +76,18 @@ int initialise(void) { /* Treasure props are initially STATE_NOTFOUND, and are set to * STATE_FOUND the first time they are described. game.tally * keeps track of how many are not yet found, so we know when to - * close the cave. */ - for (int treasure = 1; treasure <= NOBJECTS; treasure++) { - if (objects[treasure].is_treasure) { + * close the cave. + * (ESR) Non-trreasures are set to STATE_FOUND explicity so we + * don't rely on the value of uninitialized storage. This is to + * make translation to future languages easier. */ + for (int object = 1; object <= NOBJECTS; object++) { + if (objects[object].is_treasure) { ++game.tally; - if (objects[treasure].inventory != 0) { - PROP_SET_NOT_FOUND(treasure); + if (objects[object].inventory != NULL) { + PROP_SET_NOT_FOUND(object); } + } else { + PROP_SET_FOUND(object); } } game.conds = setbit(COND_HBASE); From cb293f4aa4f29f0da11c1ddae9ee0712f4e1dd0a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 30 Jun 2024 14:42:06 -0400 Subject: [PATCH 190/213] Rename some macos for clarity. --- Makefile | 2 +- actions.c | 20 ++++++++++---------- advent.h | 38 +++++++++++++++++++------------------- init.c | 4 ++-- main.c | 24 ++++++++++++------------ misc.c | 6 +++--- saveresume.c | 2 +- score.c | 4 ++-- 8 files changed, 50 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index a7acbd8..88c59e6 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ cheat: $(CHEAT_OBJS) dungeon.o CSUPPRESSIONS = --suppress=missingIncludeSystem --suppress=invalidscanf cppcheck: - @-cppcheck -I. --quiet --template gcc -UPROP_SET_SEEN --enable=all $(CSUPPRESSIONS) *.[ch] + @-cppcheck -I. --quiet --template gcc -UOBJECT_SET_SEEN --enable=all $(CSUPPRESSIONS) *.[ch] pylint: @-pylint --score=n *.py */*.py diff --git a/actions.c b/actions.c index 31a09c8..27b7904 100644 --- a/actions.c +++ b/actions.c @@ -246,7 +246,7 @@ static phase_codes_t bigwords(vocab_t id) { static void blast(void) { /* Blast. No effect unless you've got dynamite, which is a neat trick! */ - if (PROP_IS_NOTFOUND(ROD2) || !game.closed) { + if (OBJECT_IS_NOTFOUND(ROD2) || !game.closed) { rspeak(REQUIRES_DYNAMITE); } else { if (HERE(ROD2)) { @@ -389,7 +389,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) { } if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && - !PROP_IS_STASHED(BIRD)) { + !OBJECT_IS_STASHED(BIRD)) { if (game.objects[BIRD].prop == BIRD_FOREST_UNCAGED) { DESTROY(BIRD); rspeak(BIRD_CRAP); @@ -407,7 +407,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) { } if ((obj == BIRD || obj == CAGE) && (game.objects[BIRD].prop == BIRD_CAGED || - PROP_STASHED(BIRD) == BIRD_CAGED)) { + OBJECT_STASHED(BIRD) == BIRD_CAGED)) { /* expression maps BIRD to CAGE and CAGE to BIRD */ carry(BIRD + CAGE - obj, game.loc); } @@ -418,8 +418,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) { game.objects[LIQUID()].place = CARRIED; } - if (GSTONE(obj) && !PROP_IS_FOUND(obj)) { - PROP_SET_FOUND(obj); + if (GSTONE(obj) && !OBJECT_IS_FOUND(obj)) { + OBJECT_SET_FOUND(obj); game.objects[CAVITY].prop = CAVITY_EMPTY; } rspeak(OK_MAN); @@ -971,7 +971,7 @@ static phase_codes_t listen(void) { } for (obj_t i = 1; i <= NOBJECTS; i++) { if (!HERE(i) || objects[i].sounds[0] == NULL || - PROP_IS_STASHED_OR_UNSEEN(i)) { + OBJECT_IS_STASHED_OR_UNSEEN(i)) { continue; } int mi = game.objects[i].prop; @@ -1151,7 +1151,7 @@ static phase_codes_t read(command_t command) command.obj = NO_OBJECT; for (int i = 1; i <= NOBJECTS; i++) { if (HERE(i) && objects[i].texts[0] != NULL && - !PROP_IS_STASHED(i)) { + !OBJECT_IS_STASHED(i)) { command.obj = command.obj * NOBJECTS + i; } } @@ -1175,7 +1175,7 @@ static phase_codes_t read(command_t command) 1); // Not really a sound, but oh well. } } else if (objects[command.obj].texts[0] == NULL || - PROP_IS_NOTFOUND(command.obj)) { + OBJECT_IS_NOTFOUND(command.obj)) { speak(actions[command.verb].message); } else { pspeak(command.obj, study, true, @@ -1351,9 +1351,9 @@ static phase_codes_t wave(verb_t verb, obj_t obj) { } if (game.objects[BIRD].prop == BIRD_UNCAGED && - game.loc == game.objects[STEPS].place && PROP_IS_NOTFOUND(JADE)) { + game.loc == game.objects[STEPS].place && OBJECT_IS_NOTFOUND(JADE)) { drop(JADE, game.loc); - PROP_SET_FOUND(JADE); + OBJECT_SET_FOUND(JADE); --game.tally; rspeak(NECKLACE_FLY); return GO_CLEAROBJ; diff --git a/advent.h b/advent.h index 21a521f..f561e89 100644 --- a/advent.h +++ b/advent.h @@ -61,7 +61,7 @@ * STATE_NOTFOUND is only set on treasures. Non-treasures start the * game in STATE_FOUND. * - * PROP_STASHED is supposed to map a state property value to a + * OBJECT_STASHED is supposed to map a state property value to a * negative range, where the object cannot be picked up but the value * can be recovered later. Various objects get this property when * the cave starts to close. Only seems to be significant for the bird @@ -69,14 +69,14 @@ * those tests is difficult to read. */ #define PROP_STASHIFY(n) (-1 - (n)) -#define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) -#define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) -#define PROP_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) -#define PROP_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) -#define PROP_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) -#define PROP_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) -#define PROP_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) #define PROP_IS_INVALID(val) (val < -MAX_STATE - 1 || val > MAX_STATE) +#define OBJECT_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) +#define OBJECT_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) +#define OBJECT_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) +#define OBJECT_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) +#define OBJECT_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) +#define OBJECT_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) +#define OBJECT_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) #else /* (ESR) Only the boldest of adventurers will explore here. This * alternate set of definitions for the macros above was an attempt to @@ -84,27 +84,27 @@ * telling whether or not the player has seen the object. * * What's broken when you try to use thus is - * PROP_IS_STASHED_OR_UNSEEN. The symptom is game.tally getting + * OBJECT_IS_STASHED_OR_UNSEEN. The symptom is game.tally getting * decremented on non-treasures. */ #define PROP_STASHIFY(n) (-(n)) -#define PROP_IS_STASHED(obj) (game.objects[obj].prop < 0) -#define PROP_IS_NOTFOUND(obj) (!game.objects[obj].found) -#define PROP_IS_FOUND(obj) \ +#define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) +#define OBJECT_IS_STASHED(obj) (game.objects[obj].prop < 0) +#define OBJECT_IS_NOTFOUND(obj) (!game.objects[obj].found) +#define OBJECT_IS_FOUND(obj) \ (game.objects[obj].found && game.objects[obj].prop == 0) -#define PROP_IS_STASHED_OR_UNSEEN(obj) \ +#define OBJECT_IS_STASHED_OR_UNSEEN(obj) \ (!game.objects[obj].found || game.objects[obj].prop < 0) -#define PROP_SET_FOUND(obj) \ +#define OBJECT_SET_FOUND(obj) \ do { \ game.objects[obj].found = true; \ game.objects[obj].prop = STATE_FOUND; \ } while (0) -#define PROP_SET_NOT_FOUND(obj) game.objects[obj].found = false -#define PROP_IS_NOTFOUND2(g, o) (!g.objects[o].found) -#define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) -#define PROP_SET_SEEN(obj) game.objects[object].found = true +#define OBJECT_SET_NOT_FOUND(obj) game.objects[obj].found = false +#define OBJECT_IS_NOTFOUND2(g, o) (!g.objects[o].found) +#define OBJECT_SET_SEEN(obj) game.objects[object].found = true #endif -#define PROP_STASHED(obj) PROP_STASHIFY(game.objects[obj].prop) +#define OBJECT_STASHED(obj) PROP_STASHIFY(game.objects[obj].prop) #define PROMPT "> " diff --git a/init.c b/init.c index 2fffc14..58bb0e8 100644 --- a/init.c +++ b/init.c @@ -84,10 +84,10 @@ int initialise(void) { if (objects[object].is_treasure) { ++game.tally; if (objects[object].inventory != NULL) { - PROP_SET_NOT_FOUND(object); + OBJECT_SET_NOT_FOUND(object); } } else { - PROP_SET_FOUND(object); + OBJECT_SET_FOUND(object); } } game.conds = setbit(COND_HBASE); diff --git a/main.c b/main.c index 6d904f2..2dfa880 100644 --- a/main.c +++ b/main.c @@ -152,8 +152,8 @@ static void checkhints(void) { game.hints[hint].lc = 0; return; case 4: /* dark */ - if (!PROP_IS_NOTFOUND(EMERALD) && - PROP_IS_NOTFOUND(PYRAMID)) { + if (!OBJECT_IS_NOTFOUND(EMERALD) && + OBJECT_IS_NOTFOUND(PYRAMID)) { break; } game.hints[hint].lc = 0; @@ -188,7 +188,7 @@ static void checkhints(void) { return; case 9: /* jade */ if (game.tally == 1 && - PROP_IS_STASHED_OR_UNSEEN(JADE)) { + OBJECT_IS_STASHED_OR_UNSEEN(JADE)) { break; } game.hints[hint].lc = 0; @@ -231,8 +231,8 @@ static bool spotted_by_pirate(int i) { * tally=1 for an unseen chest, let the pirate be spotted. Note * that game.objexts,place[CHEST] = LOC_NOWHERE might mean that he's * thrown it to the troll, but in that case he's seen the chest - * PROP_IS_FOUND(CHEST) == true. */ - if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST)) { + * OBJECT_IS_FOUND(CHEST) == true. */ + if (game.loc == game.chloc || !OBJECT_IS_NOTFOUND(CHEST)) { return true; } int snarfed = 0; @@ -1061,11 +1061,11 @@ static void listobjects(void) { * running this code only on objects with the treasure * property set. Nope. There is mystery here. */ - if (PROP_IS_STASHED_OR_UNSEEN(obj)) { + if (OBJECT_IS_STASHED_OR_UNSEEN(obj)) { if (game.closed) { continue; } - PROP_SET_FOUND(obj); + OBJECT_SET_FOUND(obj); if (obj == RUG) { game.objects[RUG].prop = RUG_DRAGON; } @@ -1266,16 +1266,16 @@ static bool do_command(void) { * way objects won't be described until they've * been picked up and put down separate from * their respective piles. */ - if ((PROP_IS_NOTFOUND(OYSTER) || - PROP_IS_STASHED(OYSTER)) && + if ((OBJECT_IS_NOTFOUND(OYSTER) || + OBJECT_IS_STASHED(OYSTER)) && TOTING(OYSTER)) { pspeak(OYSTER, look, true, 1); } for (size_t i = 1; i <= NOBJECTS; i++) { - if (TOTING(i) && (PROP_IS_NOTFOUND(i) || - PROP_IS_STASHED(i))) { + if (TOTING(i) && (OBJECT_IS_NOTFOUND(i) || + OBJECT_IS_STASHED(i))) { game.objects[i].prop = - PROP_STASHED(i); + OBJECT_STASHED(i); } } } diff --git a/misc.c b/misc.c index 9e90d05..14d0622 100644 --- a/misc.c +++ b/misc.c @@ -620,11 +620,11 @@ void put(obj_t object, loc_t where, int pval) { /* put() is the same as move(), except it returns a value used to set * up the negated game.prop values for the repository objects. */ move(object, where); - /* (ESR) Read this in combination with the macro defintions in advebt.h. + /* (ESR) Read this in combination with the macro defintions in advent.h. */ game.objects[object].prop = PROP_STASHIFY(pval); -#ifdef PROP_SET_SEEN - PROP_SET_SEEN(object); +#ifdef OBJECT_SET_SEEN + OBJECT_SET_SEEN(object); #endif } diff --git a/saveresume.c b/saveresume.c index 100c925..1c778ef 100644 --- a/saveresume.c +++ b/saveresume.c @@ -230,7 +230,7 @@ bool is_valid(struct game_t valgame) { int temp_tally = 0; for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { - if (PROP_IS_NOTFOUND2(valgame, treasure)) { + if (OBJECT_IS_NOTFOUND2(valgame, treasure)) { ++temp_tally; } } diff --git a/score.c b/score.c index 1d84c79..ad1c00a 100644 --- a/score.c +++ b/score.c @@ -49,11 +49,11 @@ int score(enum termination mode) { if (i > CHEST) { k = 16; } - if (!PROP_IS_STASHED(i) && !PROP_IS_NOTFOUND(i)) { + if (!OBJECT_IS_STASHED(i) && !OBJECT_IS_NOTFOUND(i)) { score += 2; } if (game.objects[i].place == LOC_BUILDING && - PROP_IS_FOUND(i)) { + OBJECT_IS_FOUND(i)) { score += k - 2; } mxscor += k; From e17ff128da5fc447806308eb0c62a05a9a56787b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 30 Jun 2024 17:20:46 -0400 Subject: [PATCH 191/213] Remove obsolete comment part. --- advent.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/advent.h b/advent.h index f561e89..5aadcbb 100644 --- a/advent.h +++ b/advent.h @@ -82,10 +82,6 @@ * alternate set of definitions for the macros above was an attempt to * break out of the state encoding a per-object "found" member * telling whether or not the player has seen the object. - * - * What's broken when you try to use thus is - * OBJECT_IS_STASHED_OR_UNSEEN. The symptom is game.tally getting - * decremented on non-treasures. */ #define PROP_STASHIFY(n) (-(n)) #define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) From 8dcc6e66415771d76a09a87bd5e97d21d80dc84e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 20 Sep 2024 10:03:15 -0400 Subject: [PATCH 192/213] Correct missing negative. --- adventure.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adventure.yaml b/adventure.yaml index 31988de..75d415a 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -10,7 +10,7 @@ # We define a bunch of YAML structures: # # motions: Motion words, grouped into synonyms. The 'oldstyle' -# attribute, if false, means that single-letter synonyms should be +# attribute, if false, means that single-letter synonyms should not be # accepted in oldstyle mode; it defaults to true. # # actions: Action words, grouped into synonyms, and their corresponding From 3d6c689ffa6ab95e2b59c0fc284038a41f7f598e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 20 Sep 2024 10:29:37 -0400 Subject: [PATCH 193/213] Make oldstyle correctly suppress line editing. --- NEWS.adoc | 3 +++ main.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.adoc b/NEWS.adoc index 2d0dcee..f9c70d6 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,6 +2,9 @@ // SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 +Repository head:: + Make oldstyle correctly suppress line editing. + 1.19: 2024-06-27:: Ensore that the KNIVES_VANISH message can't issue twice. diff --git a/main.c b/main.c index 2dfa880..e0e4c58 100644 --- a/main.c +++ b/main.c @@ -81,7 +81,7 @@ char *myreadline(const char *prompt) { } } - if (isatty(fileno(settings.scriptfp))) { + if (isatty(fileno(settings.scriptfp)) && !settings.oldstyle) { free(buf); // LCOV_EXCL_LINE return readline(prompt); // LCOV_EXCL_LINE } else { From acdfa96315f7c7bafce54d0e0530f4c95f3bb390 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 20 Sep 2024 10:40:22 -0400 Subject: [PATCH 194/213] Fix a busted comment. --- misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc.c b/misc.c index 14d0622..aa11786 100644 --- a/misc.c +++ b/misc.c @@ -495,8 +495,8 @@ static void tokenize(char *raw, command_t *cmd) { memset(&cmd->word[1].raw, '\0', sizeof(cmd->word[1].raw)); /* Bound prefix on the %s would be needed to prevent buffer - * overflow. but we shortstop this more simply by making each - * raw-input buffer as int as the entire input buffer. */ + * overflow. We shortstop this more simply by making each + * raw-input buffer as long as the entire input buffer. */ sscanf(raw, "%s%s", cmd->word[0].raw, cmd->word[1].raw); /* (ESR) In oldstyle mode, simulate the uppercasing and truncating From cf4adf8d028e75e041abe4850259edad54171264 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 20 Sep 2024 10:49:44 -0400 Subject: [PATCH 195/213] Repair truncation in oldstyle mode. Sure would be nice to remember while this code had TOKEN + TOKEN where one would think it should just say TOKEN. --- misc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/misc.c b/misc.c index aa11786..533735b 100644 --- a/misc.c +++ b/misc.c @@ -514,8 +514,7 @@ static void tokenize(char *raw, command_t *cmd) { * possible an emulation of the original UI. */ if (settings.oldstyle) { - cmd->word[0].raw[TOKLEN + TOKLEN] = - cmd->word[1].raw[TOKLEN + TOKLEN] = '\0'; + cmd->word[0].raw[TOKLEN] = cmd->word[1].raw[TOKLEN] = '\0'; for (size_t i = 0; i < strlen(cmd->word[0].raw); i++) { cmd->word[0].raw[i] = toupper(cmd->word[0].raw[i]); } From f1cb740c41a992c6b25a83d098b0b580cf85486c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 20 Sep 2024 22:04:16 -0400 Subject: [PATCH 196/213] Define TRUNCLEN and explain its issues. --- misc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/misc.c b/misc.c index 533735b..af88737 100644 --- a/misc.c +++ b/misc.c @@ -512,9 +512,14 @@ static void tokenize(char *raw, command_t *cmd) { * in their tools. On the other, not simulating this misbehavior * goes against the goal of making oldstyle as accurate as * possible an emulation of the original UI. + * + * The definition of TRUNCLEN is dubious. It accurately reflects the + * FORTRAN, but it's possible that was a bug and the proper definition + * is (TOKLEN). */ +#define TRUNCLEN (TOKLEN + TOKLEN) if (settings.oldstyle) { - cmd->word[0].raw[TOKLEN] = cmd->word[1].raw[TOKLEN] = '\0'; + cmd->word[0].raw[TRUNCLEN] = cmd->word[1].raw[TRUNCLEN] = '\0'; for (size_t i = 0; i < strlen(cmd->word[0].raw); i++) { cmd->word[0].raw[i] = toupper(cmd->word[0].raw[i]); } From 8c553af53e6d04462716d50a654102b028e86e96 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 20 Sep 2024 22:05:25 -0400 Subject: [PATCH 197/213] Avoid a GNUism, POSIX strncasecmp() is declarted in strings.h. --- misc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/misc.c b/misc.c index af88737..7760cc5 100644 --- a/misc.c +++ b/misc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include From 20fd7c589fcd1e9817db541e988341b4501f8305 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Fri, 20 Sep 2024 22:19:14 -0400 Subject: [PATCH 198/213] Typo fix. --- init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.c b/init.c index 58bb0e8..b4ee643 100644 --- a/init.c +++ b/init.c @@ -1,7 +1,7 @@ /* * Initialisation * - * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woodsm + * SPDX-FileCopyrightText: (C) 1977, 2005 by Will Crowther and Don Woods * SPDX-License-Identifier: BSD-2-Clause */ From 9c3f4b0c90690f35669b802a3661c3ef31460900 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 22 Sep 2024 13:08:31 -0400 Subject: [PATCH 199/213] Reflow. --- advent.h | 6 +++--- main.c | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/advent.h b/advent.h index 5aadcbb..17e02eb 100644 --- a/advent.h +++ b/advent.h @@ -87,11 +87,11 @@ #define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) #define OBJECT_IS_STASHED(obj) (game.objects[obj].prop < 0) #define OBJECT_IS_NOTFOUND(obj) (!game.objects[obj].found) -#define OBJECT_IS_FOUND(obj) \ +#define OBJECT_IS_FOUND(obj) \ (game.objects[obj].found && game.objects[obj].prop == 0) -#define OBJECT_IS_STASHED_OR_UNSEEN(obj) \ +#define OBJECT_IS_STASHED_OR_UNSEEN(obj) \ (!game.objects[obj].found || game.objects[obj].prop < 0) -#define OBJECT_SET_FOUND(obj) \ +#define OBJECT_SET_FOUND(obj) \ do { \ game.objects[obj].found = true; \ game.objects[obj].prop = STATE_FOUND; \ diff --git a/main.c b/main.c index e0e4c58..4db3836 100644 --- a/main.c +++ b/main.c @@ -1272,8 +1272,9 @@ static bool do_command(void) { pspeak(OYSTER, look, true, 1); } for (size_t i = 1; i <= NOBJECTS; i++) { - if (TOTING(i) && (OBJECT_IS_NOTFOUND(i) || - OBJECT_IS_STASHED(i))) { + if (TOTING(i) && + (OBJECT_IS_NOTFOUND(i) || + OBJECT_IS_STASHED(i))) { game.objects[i].prop = OBJECT_STASHED(i); } @@ -1282,10 +1283,10 @@ static bool do_command(void) { /* Check to see if the room is dark. */ game.wzdark = DARK(game.loc); - + /* If the knife is not here it permanently disappears. - * Possibly this should fire if the knife is here but - * the room is dark? */ + * Possibly this should fire if the knife is here but + * the room is dark? */ if (game.knfloc > LOC_NOWHERE && game.knfloc != game.loc) { game.knfloc = LOC_NOWHERE; From 354e56a69ba6671cf56a0e51950162abb2542bfd Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 22 Sep 2024 22:06:02 -0400 Subject: [PATCH 200/213] Clean up some comments. --- advent.h | 2 +- init.c | 2 +- misc.c | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/advent.h b/advent.h index 17e02eb..9f306c1 100644 --- a/advent.h +++ b/advent.h @@ -257,7 +257,7 @@ struct game_t { bool32_t found; // has the location of this object been found? #endif loc_t fixed; // fixed location of object (if not IS_FREE) - int32_t prop; // object state */ + int32_t prop; // object state loc_t place; // location of object } objects[NOBJECTS + 1]; struct { diff --git a/init.c b/init.c index b4ee643..372e494 100644 --- a/init.c +++ b/init.c @@ -77,7 +77,7 @@ int initialise(void) { * STATE_FOUND the first time they are described. game.tally * keeps track of how many are not yet found, so we know when to * close the cave. - * (ESR) Non-trreasures are set to STATE_FOUND explicity so we + * (ESR) Non-treasures are set to STATE_FOUND explicitly so we * don't rely on the value of uninitialized storage. This is to * make translation to future languages easier. */ for (int object = 1; object <= NOBJECTS; object++) { diff --git a/misc.c b/misc.c index 7760cc5..9fddfd5 100644 --- a/misc.c +++ b/misc.c @@ -622,11 +622,9 @@ void move(obj_t object, loc_t where) { } void put(obj_t object, loc_t where, int pval) { - /* put() is the same as move(), except it returns a value used to set - * up the negated game.prop values for the repository objects. */ + /* put() is the same as move(), except the object is stashed and + * can no longer be picked up. */ move(object, where); - /* (ESR) Read this in combination with the macro defintions in advent.h. - */ game.objects[object].prop = PROP_STASHIFY(pval); #ifdef OBJECT_SET_SEEN OBJECT_SET_SEEN(object); From 0157e5866872f9b2e6f0b8f875ad9696f658944b Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 22 Sep 2024 22:21:47 -0400 Subject: [PATCH 201/213] Remove an unneeded layer of macro indirection. --- actions.c | 2 +- advent.h | 3 +-- main.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/actions.c b/actions.c index 27b7904..107b298 100644 --- a/actions.c +++ b/actions.c @@ -407,7 +407,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) { } if ((obj == BIRD || obj == CAGE) && (game.objects[BIRD].prop == BIRD_CAGED || - OBJECT_STASHED(BIRD) == BIRD_CAGED)) { + PROP_STASHIFY(game.objects[BIRD].prop) == BIRD_CAGED)) { /* expression maps BIRD to CAGE and CAGE to BIRD */ carry(BIRD + CAGE - obj, game.loc); } diff --git a/advent.h b/advent.h index 9f306c1..9841037 100644 --- a/advent.h +++ b/advent.h @@ -61,7 +61,7 @@ * STATE_NOTFOUND is only set on treasures. Non-treasures start the * game in STATE_FOUND. * - * OBJECT_STASHED is supposed to map a state property value to a + * PROP_STASHIFY is supposed to map a state property value to a * negative range, where the object cannot be picked up but the value * can be recovered later. Various objects get this property when * the cave starts to close. Only seems to be significant for the bird @@ -100,7 +100,6 @@ #define OBJECT_IS_NOTFOUND2(g, o) (!g.objects[o].found) #define OBJECT_SET_SEEN(obj) game.objects[object].found = true #endif -#define OBJECT_STASHED(obj) PROP_STASHIFY(game.objects[obj].prop) #define PROMPT "> " diff --git a/main.c b/main.c index 4db3836..688cfc7 100644 --- a/main.c +++ b/main.c @@ -1276,7 +1276,7 @@ static bool do_command(void) { (OBJECT_IS_NOTFOUND(i) || OBJECT_IS_STASHED(i))) { game.objects[i].prop = - OBJECT_STASHED(i); + PROP_STASHIFY(game.objects[i].prop); } } } From 08f0351817b54e76f33609b12deec52e8efbcd4c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 22 Sep 2024 22:34:07 -0400 Subject: [PATCH 202/213] Introduce OBJECT_STASHIFY. --- advent.h | 1 + main.c | 3 +-- misc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/advent.h b/advent.h index 9841037..d1504f0 100644 --- a/advent.h +++ b/advent.h @@ -100,6 +100,7 @@ #define OBJECT_IS_NOTFOUND2(g, o) (!g.objects[o].found) #define OBJECT_SET_SEEN(obj) game.objects[object].found = true #endif +#define OBJECT_STASHIFY(obj, pval) game.objects[obj].prop = PROP_STASHIFY(pval) #define PROMPT "> " diff --git a/main.c b/main.c index 688cfc7..14c9065 100644 --- a/main.c +++ b/main.c @@ -1275,8 +1275,7 @@ static bool do_command(void) { if (TOTING(i) && (OBJECT_IS_NOTFOUND(i) || OBJECT_IS_STASHED(i))) { - game.objects[i].prop = - PROP_STASHIFY(game.objects[i].prop); + OBJECT_STASHIFY(i, game.objects[i].prop); } } } diff --git a/misc.c b/misc.c index 9fddfd5..b28949e 100644 --- a/misc.c +++ b/misc.c @@ -625,7 +625,7 @@ void put(obj_t object, loc_t where, int pval) { /* put() is the same as move(), except the object is stashed and * can no longer be picked up. */ move(object, where); - game.objects[object].prop = PROP_STASHIFY(pval); + OBJECT_STASHIFY(object, pval); #ifdef OBJECT_SET_SEEN OBJECT_SET_SEEN(object); #endif From 9a6e4406f55df92d448fcad0b54aff1902787e11 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 22 Sep 2024 23:09:16 -0400 Subject: [PATCH 203/213] Confine uses of PROP_STASHIFY() to advent.h Now it shouyld be possible to manipulate a stashed flag by only changing macros. --- actions.c | 3 +-- advent.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actions.c b/actions.c index 107b298..6f93eb0 100644 --- a/actions.c +++ b/actions.c @@ -406,8 +406,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) { game.objects[BIRD].prop = BIRD_CAGED; } if ((obj == BIRD || obj == CAGE) && - (game.objects[BIRD].prop == BIRD_CAGED || - PROP_STASHIFY(game.objects[BIRD].prop) == BIRD_CAGED)) { + OBJECT_STATE_EQUALS(BIRD, BIRD_CAGED)) { /* expression maps BIRD to CAGE and CAGE to BIRD */ carry(BIRD + CAGE - obj, game.loc); } diff --git a/advent.h b/advent.h index d1504f0..6686dfc 100644 --- a/advent.h +++ b/advent.h @@ -77,6 +77,7 @@ #define OBJECT_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) #define OBJECT_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) #define OBJECT_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) +#define OBJECT_STATE_EQUALS(obj, pval) ((game.objects[obj].prop == pval) || (game.objects[obj].prop == PROP_STASHIFY(pval))) #else /* (ESR) Only the boldest of adventurers will explore here. This * alternate set of definitions for the macros above was an attempt to From a4fd14caf710b8327d631a99c49b81f411f0161a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 22 Sep 2024 23:32:23 -0400 Subject: [PATCH 204/213] Back away from trying for the found member until we make stashed work. --- advent.h | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/advent.h b/advent.h index 6686dfc..fa3c185 100644 --- a/advent.h +++ b/advent.h @@ -47,7 +47,6 @@ #define IS_FIXED -1 #define IS_FREE 0 -#ifndef FOUNDBOOL /* (ESR) It is fitting that translation of the original ADVENT should * have left us a maze of twisty little conditionals that resists all * understanding. Setting and use of what is now the per-object state @@ -78,29 +77,6 @@ #define OBJECT_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) #define OBJECT_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) #define OBJECT_STATE_EQUALS(obj, pval) ((game.objects[obj].prop == pval) || (game.objects[obj].prop == PROP_STASHIFY(pval))) -#else -/* (ESR) Only the boldest of adventurers will explore here. This - * alternate set of definitions for the macros above was an attempt to - * break out of the state encoding a per-object "found" member - * telling whether or not the player has seen the object. - */ -#define PROP_STASHIFY(n) (-(n)) -#define PROP_IS_INVALID(val) (val < -MAX_STATE || val > MAX_STATE) -#define OBJECT_IS_STASHED(obj) (game.objects[obj].prop < 0) -#define OBJECT_IS_NOTFOUND(obj) (!game.objects[obj].found) -#define OBJECT_IS_FOUND(obj) \ - (game.objects[obj].found && game.objects[obj].prop == 0) -#define OBJECT_IS_STASHED_OR_UNSEEN(obj) \ - (!game.objects[obj].found || game.objects[obj].prop < 0) -#define OBJECT_SET_FOUND(obj) \ - do { \ - game.objects[obj].found = true; \ - game.objects[obj].prop = STATE_FOUND; \ - } while (0) -#define OBJECT_SET_NOT_FOUND(obj) game.objects[obj].found = false -#define OBJECT_IS_NOTFOUND2(g, o) (!g.objects[o].found) -#define OBJECT_SET_SEEN(obj) game.objects[object].found = true -#endif #define OBJECT_STASHIFY(obj, pval) game.objects[obj].prop = PROP_STASHIFY(pval) #define PROMPT "> " @@ -254,9 +230,6 @@ struct game_t { loc_t oldloc; // prior loc of each dwarf, initially garbage } dwarves[NDWARVES + 1]; struct { -#ifdef FOUNDBOOL - bool32_t found; // has the location of this object been found? -#endif loc_t fixed; // fixed location of object (if not IS_FREE) int32_t prop; // object state loc_t place; // location of object From 40742e112ba73e1fd98c9b898f6ce5812c7c74b7 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 23 Sep 2024 03:53:28 -0400 Subject: [PATCH 205/213] Expand a macro to simplify code. --- actions.c | 2 +- advent.h | 9 ++++----- main.c | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/actions.c b/actions.c index 6f93eb0..e5f2e70 100644 --- a/actions.c +++ b/actions.c @@ -970,7 +970,7 @@ static phase_codes_t listen(void) { } for (obj_t i = 1; i <= NOBJECTS; i++) { if (!HERE(i) || objects[i].sounds[0] == NULL || - OBJECT_IS_STASHED_OR_UNSEEN(i)) { + OBJECT_IS_STASHED(i) || OBJECT_IS_NOTFOUND(i)) { continue; } int mi = game.objects[i].prop; diff --git a/advent.h b/advent.h index fa3c185..204fce7 100644 --- a/advent.h +++ b/advent.h @@ -67,17 +67,16 @@ * and readable objects, notably the clam/oyster - but the code around * those tests is difficult to read. */ -#define PROP_STASHIFY(n) (-1 - (n)) -#define PROP_IS_INVALID(val) (val < -MAX_STATE - 1 || val > MAX_STATE) -#define OBJECT_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) #define OBJECT_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) #define OBJECT_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) -#define OBJECT_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) #define OBJECT_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) #define OBJECT_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) #define OBJECT_IS_NOTFOUND2(g, o) (g.objects[o].prop == STATE_NOTFOUND) -#define OBJECT_STATE_EQUALS(obj, pval) ((game.objects[obj].prop == pval) || (game.objects[obj].prop == PROP_STASHIFY(pval))) +#define PROP_IS_INVALID(val) (val < -MAX_STATE - 1 || val > MAX_STATE) +#define PROP_STASHIFY(n) (-1 - (n)) #define OBJECT_STASHIFY(obj, pval) game.objects[obj].prop = PROP_STASHIFY(pval) +#define OBJECT_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) +#define OBJECT_STATE_EQUALS(obj, pval) ((game.objects[obj].prop == pval) || (game.objects[obj].prop == PROP_STASHIFY(pval))) #define PROMPT "> " diff --git a/main.c b/main.c index 14c9065..c823280 100644 --- a/main.c +++ b/main.c @@ -188,7 +188,7 @@ static void checkhints(void) { return; case 9: /* jade */ if (game.tally == 1 && - OBJECT_IS_STASHED_OR_UNSEEN(JADE)) { + (OBJECT_IS_STASHED(JADE) || OBJECT_IS_NOTFOUND(JADE))) { break; } game.hints[hint].lc = 0; @@ -1061,7 +1061,7 @@ static void listobjects(void) { * running this code only on objects with the treasure * property set. Nope. There is mystery here. */ - if (OBJECT_IS_STASHED_OR_UNSEEN(obj)) { + if (OBJECT_IS_STASHED(i) || OBJECT_IS_NOTFOUND(obj)) { if (game.closed) { continue; } From 96ad6c6245bfc18fb36116717143a299b98a9c77 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 23 Sep 2024 04:38:24 -0400 Subject: [PATCH 206/213] Reflow. --- advent.h | 4 +++- main.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/advent.h b/advent.h index 204fce7..b9c98d9 100644 --- a/advent.h +++ b/advent.h @@ -76,7 +76,9 @@ #define PROP_STASHIFY(n) (-1 - (n)) #define OBJECT_STASHIFY(obj, pval) game.objects[obj].prop = PROP_STASHIFY(pval) #define OBJECT_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) -#define OBJECT_STATE_EQUALS(obj, pval) ((game.objects[obj].prop == pval) || (game.objects[obj].prop == PROP_STASHIFY(pval))) +#define OBJECT_STATE_EQUALS(obj, pval) \ + ((game.objects[obj].prop == pval) || \ + (game.objects[obj].prop == PROP_STASHIFY(pval))) #define PROMPT "> " diff --git a/main.c b/main.c index c823280..d383095 100644 --- a/main.c +++ b/main.c @@ -188,7 +188,8 @@ static void checkhints(void) { return; case 9: /* jade */ if (game.tally == 1 && - (OBJECT_IS_STASHED(JADE) || OBJECT_IS_NOTFOUND(JADE))) { + (OBJECT_IS_STASHED(JADE) || + OBJECT_IS_NOTFOUND(JADE))) { break; } game.hints[hint].lc = 0; @@ -1275,7 +1276,8 @@ static bool do_command(void) { if (TOTING(i) && (OBJECT_IS_NOTFOUND(i) || OBJECT_IS_STASHED(i))) { - OBJECT_STASHIFY(i, game.objects[i].prop); + OBJECT_STASHIFY( + i, game.objects[i].prop); } } } From 92451f1fff194355ccc4c770ddc54944ec7fda6a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 23 Sep 2024 05:08:11 -0400 Subject: [PATCH 207/213] Eliminate thew last property inequality outside a macro. --- actions.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/actions.c b/actions.c index e5f2e70..1786c53 100644 --- a/actions.c +++ b/actions.c @@ -329,8 +329,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) { if (game.objects[obj].fixed != IS_FREE) { switch (obj) { case PLANT: - /* Next guard tests whether plant is tiny or stashed */ - rspeak(game.objects[PLANT].prop <= PLANT_THIRSTY + rspeak((game.objects[PLANT].prop == PLANT_THIRSTY || OBJECT_IS_STASHED(PLANT)) ? DEEP_ROOTS : YOU_JOKING); break; From 5c90880f0a20ec7e06740e7699cd5ff9c94b44b4 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 23 Sep 2024 06:04:40 -0400 Subject: [PATCH 208/213] Comment and macro cleanup. --- actions.c | 3 ++- advent.h | 39 ++++++++++++++++++++------------------- main.c | 4 ++-- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/actions.c b/actions.c index 1786c53..96dabb3 100644 --- a/actions.c +++ b/actions.c @@ -329,7 +329,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) { if (game.objects[obj].fixed != IS_FREE) { switch (obj) { case PLANT: - rspeak((game.objects[PLANT].prop == PLANT_THIRSTY || OBJECT_IS_STASHED(PLANT)) + rspeak((game.objects[PLANT].prop == PLANT_THIRSTY || + OBJECT_IS_STASHED(PLANT)) ? DEEP_ROOTS : YOU_JOKING); break; diff --git a/advent.h b/advent.h index b9c98d9..4a6d4d3 100644 --- a/advent.h +++ b/advent.h @@ -83,23 +83,24 @@ #define PROMPT "> " /* - * DESTROY(N) = Get rid of an item by putting it in LOC_NOWHERE - * MOD(N,M) = Arithmetic modulus - * TOTING(OBJ) = true if the OBJ is being carried - * AT(OBJ) = true if on either side of two-placed object - * HERE(OBJ) = true if the OBJ is at "LOC" (or is being carried) - * CNDBIT(L,N) = true if COND(L) has bit n set (bit 0 is units bit) - * LIQUID() = object number of liquid in bottle - * LIQLOC(LOC) = object number of liquid (if any) at LOC - * FORCED(LOC) = true if LOC moves without asking for input (COND=2) - * DARK(LOC) = true if location "LOC" is dark - * PCT(N) = true N% of the time (N integer from 0 to 100) - * GSTONE(OBJ) = true if OBJ is a gemstone - * FOREST(LOC) = true if LOC is part of the forest - * OUTSID(LOC) = true if location not in the cave - * INSIDE(LOC) = true if location is in the cave or the building at the - * beginning of the game INDEEP(LOC) = true if location is in the Hall of Mists - * or deeper BUG(X) = report bug and exit + * DESTROY(N) = Get rid of an item by putting it in LOC_NOWHERE + * MOD(N,M) = Arithmetic modulus + * TOTING(OBJ) = true if the OBJ is being carried + * AT(OBJ) = true if on either side of two-placed object + * HERE(OBJ) = true if the OBJ is at "LOC" (or is being carried) + * CNDBIT(L,N) = true if COND(L) has bit n set (bit 0 is units bit) + * LIQUID() = object number of liquid in bottle + * LIQLOC(LOC) = object number of liquid (if any) at LOC + * FORCED(LOC) = true if LOC moves without asking for input (COND=2) + * DARK(LOC) = true if location "LOC" is dark + * PCT(N) = true N% of the time (N integer from 0 to 100) + * GSTONE(OBJ) = true if OBJ is a gemstone + * FOREST(LOC) = true if LOC is part of the forest + * OUTSIDE(LOC) = true if location not in the cave + * INSIDE(LOC) = true if location is in the cave or the building at the + * beginning of the game + * INDEEP(LOC) = true if location is in the Hall of Mists or deeper + * BUG(X) = report bug and exit */ #define DESTROY(N) move(N, LOC_NOWHERE) #define MOD(N, M) ((N) % (M)) @@ -124,8 +125,8 @@ #define GSTONE(OBJ) \ ((OBJ) == EMERALD || (OBJ) == RUBY || (OBJ) == AMBER || (OBJ) == SAPPH) #define FOREST(LOC) CNDBIT(LOC, COND_FOREST) -#define OUTSID(LOC) (CNDBIT(LOC, COND_ABOVE) || FOREST(LOC)) -#define INSIDE(LOC) (!OUTSID(LOC) || LOC == LOC_BUILDING) +#define OUTSIDE(LOC) (CNDBIT(LOC, COND_ABOVE) || FOREST(LOC)) +#define INSIDE(LOC) (!OUTSIDE(LOC) || LOC == LOC_BUILDING) #define INDEEP(LOC) CNDBIT((LOC), COND_DEEP) #define BUG(x) bug(x, #x) diff --git a/main.c b/main.c index d383095..3ecf65a 100644 --- a/main.c +++ b/main.c @@ -640,7 +640,7 @@ static void playermove(int motion) { } else if (motion == CAVE) { /* Cave. Different messages depending on whether above ground. */ - rspeak((OUTSID(game.loc) && game.loc != LOC_GRATE) + rspeak((OUTSIDE(game.loc) && game.loc != LOC_GRATE) ? FOLLOW_STREAM : NEED_DETAIL); return; @@ -1193,7 +1193,7 @@ static bool preprocess_command(command_t *command) { static bool do_move(void) { /* Actually execute the move to the new location and dwarf movement */ /* Can't leave cave once it's closing (except by main office). */ - if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) { + if (OUTSIDE(game.newloc) && game.newloc != 0 && game.closng) { rspeak(EXIT_CLOSED); game.newloc = game.loc; if (!game.panic) { From a2bb39dc7e9379900d4c87d8084c196ddd61b32f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 23 Sep 2024 14:17:52 -0400 Subject: [PATCH 209/213] Eliminate a confusing dummy argument in a macro. --- actions.c | 6 +++--- advent.h | 38 +++++++++++++++++++------------------- main.c | 8 ++++---- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/actions.c b/actions.c index 96dabb3..469e92f 100644 --- a/actions.c +++ b/actions.c @@ -676,7 +676,7 @@ static phase_codes_t extinguish(verb_t verb, obj_t obj) { break; case LAMP: state_change(LAMP, LAMP_DARK); - rspeak(DARK(game.loc) ? PITCH_DARK : NO_MESSAGE); + rspeak(IS_DARK_HERE() ? PITCH_DARK : NO_MESSAGE); break; case DRAGON: case VOLCANO: @@ -1155,12 +1155,12 @@ static phase_codes_t read(command_t command) } } if (command.obj > NOBJECTS || command.obj == NO_OBJECT || - DARK(game.loc)) { + IS_DARK_HERE()) { return GO_UNKNOWN; } } - if (DARK(game.loc)) { + if (IS_DARK_HERE()) { sspeak(NO_SEE, command.word[0].raw); } else if (command.obj == OYSTER) { if (!TOTING(OYSTER) || !game.closed) { diff --git a/advent.h b/advent.h index 4a6d4d3..3ae9012 100644 --- a/advent.h +++ b/advent.h @@ -83,24 +83,24 @@ #define PROMPT "> " /* - * DESTROY(N) = Get rid of an item by putting it in LOC_NOWHERE - * MOD(N,M) = Arithmetic modulus - * TOTING(OBJ) = true if the OBJ is being carried - * AT(OBJ) = true if on either side of two-placed object - * HERE(OBJ) = true if the OBJ is at "LOC" (or is being carried) - * CNDBIT(L,N) = true if COND(L) has bit n set (bit 0 is units bit) - * LIQUID() = object number of liquid in bottle - * LIQLOC(LOC) = object number of liquid (if any) at LOC - * FORCED(LOC) = true if LOC moves without asking for input (COND=2) - * DARK(LOC) = true if location "LOC" is dark - * PCT(N) = true N% of the time (N integer from 0 to 100) - * GSTONE(OBJ) = true if OBJ is a gemstone - * FOREST(LOC) = true if LOC is part of the forest - * OUTSIDE(LOC) = true if location not in the cave - * INSIDE(LOC) = true if location is in the cave or the building at the - * beginning of the game - * INDEEP(LOC) = true if location is in the Hall of Mists or deeper - * BUG(X) = report bug and exit + * DESTROY(N) = Get rid of an item by putting it in LOC_NOWHERE + * MOD(N,M) = Arithmetic modulus + * TOTING(OBJ) = true if the OBJ is being carried + * AT(OBJ) = true if on either side of two-placed object + * HERE(OBJ) = true if the OBJ is at "LOC" (or is being carried) + * CNDBIT(L,N) = true if COND(L) has bit n set (bit 0 is units bit) + * LIQUID() = object number of liquid in bottle + * LIQLOC(LOC) = object number of liquid (if any) at LOC + * FORCED(LOC) = true if LOC moves without asking for input (COND=2) + * IS_DARK_HERE() = true if location "LOC" is dark + * PCT(N) = true N% of the time (N integer from 0 to 100) + * GSTONE(OBJ) = true if OBJ is a gemstone + * FOREST(LOC) = true if LOC is part of the forest + * OUTSIDE(LOC) = true if location not in the cave + * INSIDE(LOC) = true if location is in the cave or the building at the + * beginning of the game + * INDEEP(LOC) = true if location is in the Hall of Mists or deeper + * BUG(X) = report bug and exit */ #define DESTROY(N) move(N, LOC_NOWHERE) #define MOD(N, M) ((N) % (M)) @@ -118,7 +118,7 @@ (CNDBIT((LOC), COND_FLUID) ? CNDBIT((LOC), COND_OILY) ? OIL : WATER \ : NO_OBJECT) #define FORCED(LOC) CNDBIT(LOC, COND_FORCED) -#define DARK(DUMMY) \ +#define IS_DARK_HERE() \ (!CNDBIT(game.loc, COND_LIT) && \ (game.objects[LAMP].prop == LAMP_DARK || !HERE(LAMP))) #define PCT(N) (randrange(100) < (N)) diff --git a/main.c b/main.c index 3ecf65a..835fc1b 100644 --- a/main.c +++ b/main.c @@ -534,7 +534,7 @@ static void describe_location(void) { msg = locations[game.loc].description.big; } - if (!FORCED(game.loc) && DARK(game.loc)) { + if (!FORCED(game.loc) && IS_DARK_HERE()) { msg = arbitrary_messages[PITCH_DARK]; } @@ -1047,7 +1047,7 @@ static void listobjects(void) { * Similarly for chain; game.prop is initially CHAINING_BEAR (locked to * bear). These hacks are because game.prop=0 is needed to * get full score. */ - if (!DARK(game.loc)) { + if (!IS_DARK_HERE()) { ++game.locs[game.loc].abbrev; for (int i = game.locs[game.loc].atloc; i != 0; i = game.link[i]) { @@ -1229,7 +1229,7 @@ static bool do_move(void) { /* The easiest way to get killed is to fall into a pit in * pitch darkness. */ - if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && + if (!FORCED(game.loc) && IS_DARK_HERE() && game.wzdark && PCT(PIT_KILL_PROB)) { rspeak(PIT_FALL); game.oldlc2 = game.loc; @@ -1283,7 +1283,7 @@ static bool do_command(void) { } /* Check to see if the room is dark. */ - game.wzdark = DARK(game.loc); + game.wzdark = IS_DARK_HERE(); /* If the knife is not here it permanently disappears. * Possibly this should fire if the knife is here but From 9df69fe0347d4c02956336d3659d8aa06a91dce9 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 23 Sep 2024 18:48:11 -0400 Subject: [PATCH 210/213] Ready to ship 1.20. --- NEWS.adoc | 2 +- advent.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS.adoc b/NEWS.adoc index f9c70d6..0140574 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 -Repository head:: +1.20: 2024-09-23:: Make oldstyle correctly suppress line editing. 1.19: 2024-06-27:: diff --git a/advent.h b/advent.h index 3ae9012..fa0767b 100644 --- a/advent.h +++ b/advent.h @@ -66,6 +66,8 @@ * the cave starts to close. Only seems to be significant for the bird * and readable objects, notably the clam/oyster - but the code around * those tests is difficult to read. + * + * All tests of the prop member are done with either these macros or ==. */ #define OBJECT_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) #define OBJECT_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) From 3e989aec5370beb49d49a837fc92f5b991970ece Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 25 May 2025 10:57:34 -0400 Subject: [PATCH 211/213] Spellcheck the YAML - yielded one trivial fix. --- Makefile | 3 +++ adventure.yaml | 10 ++++++++-- notes.adoc | 7 ++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 88c59e6..b0a752a 100644 --- a/Makefile +++ b/Makefile @@ -75,6 +75,9 @@ pylint: check: advent cheat pylint cppcheck cd tests; $(MAKE) --quiet +spellcheck: + @batchspell adventure.yaml + reflow: @clang-format --style="{IndentWidth: 8, UseTab: ForIndentation}" -i $$(find . -name "*.[ch]") @black --quiet *.py diff --git a/adventure.yaml b/adventure.yaml index 75d415a..141ffb7 100644 --- a/adventure.yaml +++ b/adventure.yaml @@ -1,6 +1,10 @@ # SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: BSD-2-Clause # +# batchspell: add XYZZY Twopit Bedquilt ne se sw nw dwarves dwarvish gouts +# batchspell: add Crowther add axe pinin Har har meself Hmmm Adventuredom +# batchspell: add Tsk gameplay bugfixes +# # This YAML file gets processed into a collection of data structures and # variable initializers describing Colossal Cave. It replaces an ad-hoc # text database shipped with Adventure versions up to 2.5. The format @@ -3432,7 +3436,7 @@ objects: !!omap - 'There are a few recent issues of "Spelunker Today" magazine here.' texts: - |- - I'm afraid the magazine is written in dwarvish. But pencilled on one + I'm afraid the magazine is written in dwarvish. But penciled on one cover you see, "Please leave the magazines at the construction site." - DWARF: words: ['dwarf', 'dwarv'] @@ -3940,11 +3944,13 @@ obituaries: Oh dear, you seem to have gotten yourself killed. I might be able to help you out, but I've never really done this before. Do you want me to try to reincarnate you? + # batchspell: add wr yes_response: |- All right. But don't blame me if something goes wr...... --- POOF!! --- You are engulfed in a cloud of orange smoke. Coughing and gasping, you emerge from the smoke and find.... + # batchspell: remove wr - query: |- You clumsy oaf, you've done it again! I don't know how long I can keep this up. Do you want me to try reincarnating you again? @@ -4226,7 +4232,7 @@ actions: !!omap message: |- There is a puff of orange smoke; within it, fiery runes spell out: - \tOpen Adventure %V - http://www.catb.org/esr/open-adventure/ + Open Adventure %V - http://www.catb.org/esr/open-adventure/ words: ['versi'] noaction: true diff --git a/notes.adoc b/notes.adoc index 833682c..a247e49 100644 --- a/notes.adoc +++ b/notes.adoc @@ -16,8 +16,8 @@ of Peje Nilsson in restructuring some particularly grotty gotos is gratefully acknowledged. Petr Voropaev contributed fuzz testing and code cleanups. Aaron Traas did a lot of painstaking work to improve test coverage, and factored out the last handful of gotos. Ryan -Sarson nudged us into fixing a longstannding minor bug in the -handling of incorrect magic-word sequebcesm, +Sarson nudged us into fixing a longstanding minor bug in the +handling of incorrect magic-word sequences, == Nomenclature == @@ -75,7 +75,8 @@ Bug fixes: * A few minor typos have been corrected: absence of capitalization on "Swiss" and "Persian", inconsistent spelling of "imbedded" vs. "embedded", - "eying" for "eyeing", "thresholds" for "threshholds". + "eying" for "eyeing", "thresholds" for "threshholds", "pencilled" + for "penciled". * Under odd circumstances (dropping rug or vase outdoors) the game could formerly say "floor" when it should say "ground" (or "dirt", or From 7bbf994fce39e62af8d2feee66d767f7fa9b41b0 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 25 May 2025 11:03:34 -0400 Subject: [PATCH 212/213] Spellcheck the manual page a well. No errors. --- advent.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/advent.adoc b/advent.adoc index f132b0c..a064d1a 100644 --- a/advent.adoc +++ b/advent.adoc @@ -3,6 +3,9 @@ // SPDX-FileCopyrightText: (C) Eric S. Raymond // SPDX-License-Identifier: CC-BY-4.0 +// batchspell: add advent logfile savefile roleplaying Gillogly PDP Ctrl-D +// batchspell: add EOF autosave endianness wumpus zork nethack + == NAME == advent - Colossal Cave Adventure From 7d848c89e1f771c043d99a0495836a8575d8995e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 25 May 2025 11:06:46 -0400 Subject: [PATCH 213/213] Add spell-checking to the regression tests. --- INSTALL.adoc | 2 ++ Makefile | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/INSTALL.adoc b/INSTALL.adoc index 5184d6b..fb93b7d 100644 --- a/INSTALL.adoc +++ b/INSTALL.adoc @@ -23,3 +23,5 @@ You can also use pip to install PyYAML: `pip3 install PyYAML`. 5. Run `./advent` to play. 6. If you want to buld the documentation you will need asciidoctor. + +7. Running the regression tests requires batchspell diff --git a/Makefile b/Makefile index b0a752a..e4e31cb 100644 --- a/Makefile +++ b/Makefile @@ -72,11 +72,11 @@ cppcheck: pylint: @-pylint --score=n *.py */*.py -check: advent cheat pylint cppcheck +check: advent cheat pylint cppcheck spellcheck cd tests; $(MAKE) --quiet spellcheck: - @batchspell adventure.yaml + @batchspell adventure.yaml advent.adoc reflow: @clang-format --style="{IndentWidth: 8, UseTab: ForIndentation}" -i $$(find . -name "*.[ch]")