From b51612131d7552c9629a1e843b236b5b9be096d5 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 29 Apr 2024 11:43:41 -0400 Subject: [PATCH 01/32] 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 02/32] 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 03/32] 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 04/32] 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 05/32] 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 06/32] 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 07/32] 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 08/32] 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 09/32] 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 10/32] 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 11/32] 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 12/32] 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 13/32] 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 14/32] 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 15/32] 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 16/32] 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 17/32] 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 18/32] 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 19/32] 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 20/32] 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 21/32] 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 22/32] 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 23/32] 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 24/32] 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 25/32] 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 26/32] 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 27/32] 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 28/32] 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 29/32] 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 30/32] 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 31/32] 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 32/32] 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]")