From 8407a851ae0817ddbd8418c924d316e55bb7226c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 27 Sep 2021 12:22:30 -0400 Subject: [PATCH 01/85] Clear create attr 12 in Zork1 --- frotz/src/games/zork1.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/frotz/src/games/zork1.c b/frotz/src/games/zork1.c index f206fd46..c735aa75 100644 --- a/frotz/src/games/zork1.c +++ b/frotz/src/games/zork1.c @@ -108,9 +108,8 @@ int zork1_ignore_attr_clr(zword obj_num, zword attr_idx) { void zork1_clean_world_objs(zobject* objs) { char mask; int i; - zobject* thief_obj; - zobject* thief_loc; - mask = ~(1 << 4); + zobject *thief_obj, *thief_loc; + zobject *player_obj, *player_loc; thief_obj = &objs[114]; thief_loc = &objs[thief_obj->parent]; if (thief_loc->child == 114) { @@ -119,10 +118,18 @@ void zork1_clean_world_objs(zobject* objs) { thief_obj->parent = 0; thief_obj->sibling = 0; thief_obj->child = 0; + // Zero attribute 3 for all objects + mask = ~(1 << 4); for (i=1; i<=zork1_get_num_world_objs(); ++i) { objs[i].attr[0] &= mask; } + + // Clear self/cretin attr 12. + player_obj = &objs[4]; + player_loc = &objs[player_obj->parent]; + mask = ~(1 << 3); + player_obj->attr[1] &= mask; } // Zork1-specific move count From 40d11fb490069802d2ccd1c6e23c6fb628abefe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 27 Sep 2021 12:24:53 -0400 Subject: [PATCH 02/85] If PC is different from last PC, then assume state has changed. --- frotz/src/interface/frotz_interface.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index bebc3f41..5fa64497 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -68,6 +68,7 @@ extern int getRngCounter(); extern void setRng(long, int, int); zbyte next_opcode; +int last_PC = -1; int desired_seed = 0; int ROM_IDX = 0; char world[8192] = ""; @@ -1542,6 +1543,7 @@ char* step(char *next_action) { attr_clr_cnt = 0; ram_diff_cnt = 0; update_special_ram(); + last_PC = getPC(); dumb_set_next_action(next_action); @@ -1628,7 +1630,8 @@ int world_changed() { if (ram_diff_cnt > 0) { return 1; } - return 0; + + return last_PC != getPC(); } void get_object(zobject *obj, zword obj_num) { From dcfeda53bac318b080e2ebc9892386479b5cb5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 27 Sep 2021 12:26:21 -0400 Subject: [PATCH 03/85] Add unrecognized template (from acorncourt). Add ILLEGAL action. --- jericho/defines.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jericho/defines.py b/jericho/defines.py index 4aa87c07..52dcd4b8 100644 --- a/jericho/defines.py +++ b/jericho/defines.py @@ -19,7 +19,7 @@ from .game_info import * #: List of illegal actions that manipulate game state. -ILLEGAL_ACTIONS = 'license/licence/lisense/lisence/copyright/terms/eula/info/tutorial/changes/daemons/messages/actions/normal/win/lose/quotes/replay/recording/hint/menu/walkthru/walkthrou/manual/purloin/abstract/trace/about/clue/nouns/places/objects/long/short/notify/short/long/die/noscript/full/fullscore/credit/credits/help/super/save/versio/verbos/brief/restar/restor/again/$ve/verify/version/verbose/transcrip/tw-print/showme/showverb/showheap/superbrie/script/restore/restart/quit/q/random/responses/max_scor/fullscore/score/endofobje/comma,/./,/unscri/gonear'.split('/') +ILLEGAL_ACTIONS = 'license/licence/lisense/lisence/copyright/terms/eula/info/tutorial/changes/daemons/messages/actions/normal/win/lose/quotes/replay/recording/hint/menu/walkthru/walkthrou/manual/purloin/abstract/trace/about/clue/nouns/places/objects/long/short/notify/short/long/die/noscript/full/fullscore/credit/credits/help/super/save/versio/verbos/brief/restar/restor/again/$ve/verify/version/verbose/transcrip/tw-print/showme/showverb/showheap/superb/superbrie/script/restore/restart/quit/q/random/responses/max_scor/fullscore/score/endofobje/comma,/./,/unscri/gonear'.split('/') #: List of basic actions applicable to almost any game. BASIC_ACTIONS = 'north/south/west/east/northwest/southwest/northeast/southeast/up/down/enter/exit/take all'.split('/') @@ -44,7 +44,8 @@ r".*That sentence isn't one I recognize.*", r".*What do you want to examine?.*", r".*You can't see any such thing.*", - r".*That's not something you need to refer to in the course of this game.*" + r".*That's not something you need to refer to in the course of this game.*", + r".*You can't use multiple objects with that verb.*" ] #: List of regular expressions meant to capture game responses that indicate the From 07e2bb50491b139c9f7325c474cc7ccc72f3093e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 27 Sep 2021 12:28:41 -0400 Subject: [PATCH 04/85] Add test file to bench_valid_action --- tests/bench_valid_actions.py | 153 +++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 tests/bench_valid_actions.py diff --git a/tests/bench_valid_actions.py b/tests/bench_valid_actions.py new file mode 100644 index 00000000..3da2ac81 --- /dev/null +++ b/tests/bench_valid_actions.py @@ -0,0 +1,153 @@ +import sys +import time +import argparse + +from tqdm import tqdm +from termcolor import colored + +import jericho + + +def run(rom, use_ctypes=False, use_parallel=False): + env = jericho.FrotzEnv(rom) + walkthrough = env.get_walkthrough() + start = time.time() + valid_per_step = [] + + for act in tqdm(walkthrough[:5]): + valid_acts = env.get_valid_actions(use_ctypes=use_ctypes, use_parallel=use_parallel) + valid_per_step.append(valid_acts) + + elapsed = time.time() - start + env.close() + return elapsed, valid_per_step + + +def compare(rom): + t1, gt_valids = run(rom) + t2, pred_valids_c = run(rom, use_ctypes=True) + t3, pred_valids_para = run(rom, use_parallel=True) + assert len(gt_valids) == len(pred_valids_c) + assert len(gt_valids) == len(pred_valids_para) + + for v1, v2 in zip(gt_valids, pred_valids_c): + false_negs = set(v1) - set(v2) + false_pos = set(v2) - set(v1) + for a in false_negs: + print(f"Act {a} was valid in Python but not in CTypes") + for a in false_pos: + print(f"Act {a} was valid in Ctypes but not in Python") + + for v1, v2 in zip(gt_valids, pred_valids_para): + false_negs = set(v1) - set(v2) + false_pos = set(v2) - set(v1) + for a in false_negs: + print(f"Act {a} was valid in Python but not in Para") + for a in false_pos: + print(f"Act {a} was valid in Para but not in Python") + + speedup = 100 * (t1 / t2 - 1) + print(f"Rom {rom} Python {t1:.1f} Ctypes {t2:.1f} Speedup {speedup:.1f}%") + speedup = 100 * (t1 / t3 - 1) + print(f"Rom {rom} Python {t1:.1f} Para {t3:.1f} Speedup {speedup:.1f}%") + + +KNOWN_MISSING_ACTIONS = { + "zork1.z5": {56: "read book", 214: "read label", 262: "kill thief with nasty knife", 387: "look", 389: "examine map"} +} + + +def check_correctness(rom, skip_to=0, verbose=False): + env = jericho.FrotzEnv(rom) + env_ = jericho.FrotzEnv(rom) + + walkthrough = env.get_walkthrough() + env.act_gen.templates + + # Display info about action templates for the game. + nargs_templates = {0: [], 1: [], 2: []} + for template in env.act_gen.templates: + nargs_templates[template.count("OBJ")].append(template) + + print("-= Template categories =-") + print(f" {len(env.act_gen.templates)} templates. 0-arg: {len(nargs_templates[0])}, 1-arg: {len(nargs_templates[1])}, 2-arg: {len(nargs_templates[2])}.") + if verbose: + print(f" 0-arg ({len(nargs_templates[0])}): {sorted(nargs_templates[0])}") + print(f" 1-arg ({len(nargs_templates[1])}): {sorted(nargs_templates[1])}") + print(f" 2-arg ({len(nargs_templates[2])}): {sorted(nargs_templates[2])}") + + start = time.time() + + obs, info = env.reset() + valid_acts = env.get_valid_actions() + + # class CaptureStdoutForTdqm: + # def __init__(): + + with tqdm(total=len(walkthrough)) as pbar: + pbar.set_description(rom) + + for idx, act in enumerate(walkthrough): + + last_state = env.get_state() + + obs, rew, done, info = env.step(act) + print(idx, act, info, env.get_world_state_hash()) + if idx < skip_to: + if idx == skip_to - 1: + breakpoint() + valid_acts = env.get_valid_actions() + + pbar.update(1) + continue + + found_matching_command = False + equivalent_commands = [] + for cmd in valid_acts: + env_.set_state(last_state) + env_.step(cmd) + if env_.get_world_state_hash() == env.get_world_state_hash(): + equivalent_commands.append(cmd) + found_matching_command = True + + if found_matching_command: + pbar.write(f"{idx:02d}. [{colored(act, 'green')}] found in [{', '.join([colored(a, 'green' if a in equivalent_commands else 'white') for a in valid_acts])}]") + else: + pbar.write(f"{idx:02d}. [{colored(act, 'red')}] not found in {valid_acts}") + if act != KNOWN_MISSING_ACTIONS.get(env.story_file, {}).get(idx): + print(colored("Unexpected missing action!!!", 'red')) + # breakpoint() + + valid_acts = env.get_valid_actions() + pbar.update(1) + + elapsed = time.time() - start + print(f"{elapsed:.1f} secs. Score: {info['score']} (Done: {done})") + env.close() + return elapsed + + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("filenames", + help="Path to a Z-Machine game.", nargs="+") + parser.add_argument("--skip-to", type=int, default=0, + help="Auto-play walkthrough until the nth command before dropping into interactive mode.") + + return parser.parse_args() + +if __name__ == "__main__": + args = parse_args() + + for rom in args.filenames: + print(f"\n-=# {rom} #=-") + check_correctness(rom, args.skip_to) + + # compare(rom) + # t2, pred_valids_c = run(rom, use_ctypes=True) + # t3, pred_valids_para = run(rom, use_parallel=True) + + # t2, pred_valids_para = run(rom, use_ctypes=True) + # t3, pred_valids_para = run(rom, use_parallel=True) + From cc9647558e9f2248c407f3aa608d9650cca5a973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 27 Sep 2021 16:13:39 -0400 Subject: [PATCH 05/85] Set object count according to the output of Infodump. --- frotz/src/games/advent.c | 4 ++-- frotz/src/games/ballyhoo.c | 2 +- frotz/src/games/curses.c | 2 +- frotz/src/games/cutthroat.c | 2 +- frotz/src/games/deephome.c | 4 ++-- frotz/src/games/gold.c | 2 +- frotz/src/games/infidel.c | 2 +- frotz/src/games/karn.c | 4 ++-- frotz/src/games/night.c | 4 ++-- frotz/src/games/planetfall.c | 2 +- frotz/src/games/seastalker.c | 4 ++-- frotz/src/games/spirit.c | 4 ++-- frotz/src/games/temple.c | 4 ++-- frotz/src/games/theatre.c | 4 ++-- frotz/src/games/tryst.c | 4 ++-- frotz/src/games/wishbringer.c | 2 +- frotz/src/games/zork3.c | 2 +- 17 files changed, 26 insertions(+), 26 deletions(-) diff --git a/frotz/src/games/advent.c b/frotz/src/games/advent.c index 479cef2f..7a8c902a 100644 --- a/frotz/src/games/advent.c +++ b/frotz/src/games/advent.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -84,7 +84,7 @@ int advent_max_score() { } int advent_get_num_world_objs() { - return 255; + return 276; } int advent_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/ballyhoo.c b/frotz/src/games/ballyhoo.c index 7984644a..875db94c 100644 --- a/frotz/src/games/ballyhoo.c +++ b/frotz/src/games/ballyhoo.c @@ -98,7 +98,7 @@ int ballyhoo_max_score() { } int ballyhoo_get_num_world_objs() { - return 235; + return 239; } int ballyhoo_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/curses.c b/frotz/src/games/curses.c index 9b704d14..7050eb1a 100644 --- a/frotz/src/games/curses.c +++ b/frotz/src/games/curses.c @@ -90,7 +90,7 @@ int curses_max_score() { } int curses_get_num_world_objs() { - return 255; + return 502; } int curses_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/cutthroat.c b/frotz/src/games/cutthroat.c index a069a551..ab07791c 100644 --- a/frotz/src/games/cutthroat.c +++ b/frotz/src/games/cutthroat.c @@ -76,7 +76,7 @@ int cutthroat_max_score() { } int cutthroat_get_num_world_objs() { - return 220; + return 223; } int cutthroat_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/deephome.c b/frotz/src/games/deephome.c index 76b8a5fa..5a3bc2bd 100644 --- a/frotz/src/games/deephome.c +++ b/frotz/src/games/deephome.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -82,7 +82,7 @@ int deephome_max_score() { } int deephome_get_num_world_objs() { - return 255; + return 292; } int deephome_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/gold.c b/frotz/src/games/gold.c index d0613543..77fb2bd4 100644 --- a/frotz/src/games/gold.c +++ b/frotz/src/games/gold.c @@ -88,7 +88,7 @@ int gold_max_score() { } int gold_get_num_world_objs() { - return 255; + return 268; } int gold_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/infidel.c b/frotz/src/games/infidel.c index 5bab8769..a1dccdef 100644 --- a/frotz/src/games/infidel.c +++ b/frotz/src/games/infidel.c @@ -81,7 +81,7 @@ int infidel_max_score() { } int infidel_get_num_world_objs() { - return 246; + return 249; } int infidel_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/karn.c b/frotz/src/games/karn.c index 61863da5..b21009b7 100644 --- a/frotz/src/games/karn.c +++ b/frotz/src/games/karn.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -82,7 +82,7 @@ int karn_max_score() { } int karn_get_num_world_objs() { - return 255; + return 274; } int karn_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/night.c b/frotz/src/games/night.c index d2fe25cf..c249210e 100644 --- a/frotz/src/games/night.c +++ b/frotz/src/games/night.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -76,7 +76,7 @@ int night_max_score() { } int night_get_num_world_objs() { - return 113; + return 122; } int night_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/planetfall.c b/frotz/src/games/planetfall.c index 7cef2c49..9afe82b0 100644 --- a/frotz/src/games/planetfall.c +++ b/frotz/src/games/planetfall.c @@ -92,7 +92,7 @@ int planetfall_max_score() { } int planetfall_get_num_world_objs() { - return 252; + return 255; } int planetfall_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/seastalker.c b/frotz/src/games/seastalker.c index 49605060..1783686e 100644 --- a/frotz/src/games/seastalker.c +++ b/frotz/src/games/seastalker.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -82,7 +82,7 @@ int seastalker_max_score() { } int seastalker_get_num_world_objs() { - return 249; + return 250; } int seastalker_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/spirit.c b/frotz/src/games/spirit.c index 069f0f72..b7cf3b8e 100644 --- a/frotz/src/games/spirit.c +++ b/frotz/src/games/spirit.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -96,7 +96,7 @@ int spirit_max_score() { } int spirit_get_num_world_objs() { - return 176; + return 817; } int spirit_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/temple.c b/frotz/src/games/temple.c index f1ff9be3..17ac955d 100644 --- a/frotz/src/games/temple.c +++ b/frotz/src/games/temple.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -82,7 +82,7 @@ int temple_max_score() { } int temple_get_num_world_objs() { - return 158; + return 159; } int temple_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/theatre.c b/frotz/src/games/theatre.c index 0045a5e3..d649416a 100644 --- a/frotz/src/games/theatre.c +++ b/frotz/src/games/theatre.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -83,7 +83,7 @@ int theatre_max_score() { } int theatre_get_num_world_objs() { - return 255; + return 396; } int theatre_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/tryst.c b/frotz/src/games/tryst.c index cc45c43e..dc6086aa 100644 --- a/frotz/src/games/tryst.c +++ b/frotz/src/games/tryst.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -99,7 +99,7 @@ int tryst_max_score() { } int tryst_get_num_world_objs() { - return 255; + return 359; } int tryst_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/wishbringer.c b/frotz/src/games/wishbringer.c index 52c229c6..d77c5c83 100644 --- a/frotz/src/games/wishbringer.c +++ b/frotz/src/games/wishbringer.c @@ -82,7 +82,7 @@ int wishbringer_max_score() { } int wishbringer_get_num_world_objs() { - return 247; + return 253; } int wishbringer_ignore_moved_obj(zword obj_num, zword dest_num) { diff --git a/frotz/src/games/zork3.c b/frotz/src/games/zork3.c index c305d87b..1b12c5cd 100644 --- a/frotz/src/games/zork3.c +++ b/frotz/src/games/zork3.c @@ -93,7 +93,7 @@ int zork3_max_score() { } int zork3_get_num_world_objs() { - return 219; + return 222; } int zork3_ignore_moved_obj(zword obj_num, zword dest_num) { From 48df3223d39ef41bbc189909f1fc560109d8f594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 8 Oct 2021 10:50:32 -0400 Subject: [PATCH 06/85] Making sure commands in walkthrough causes world_changed. --- frotz/Makefile | 3 +- frotz/src/common/frotz.h | 27 +- frotz/src/common/object.c | 33 +- frotz/src/games/acorncourt.c | 16 +- frotz/src/games/advent.c | 15 +- frotz/src/games/adventureland.c | 28 +- frotz/src/games/afflicted.c | 23 +- frotz/src/games/anchor.c | 27 +- frotz/src/games/awaken.c | 26 +- frotz/src/games/balances.c | 37 +- frotz/src/games/ballyhoo.c | 38 +- frotz/src/games/curses.c | 50 ++- frotz/src/games/cutthroat.c | 35 +- frotz/src/games/deephome.c | 9 +- frotz/src/games/dragon.c | 7 +- frotz/src/games/enchanter.c | 24 +- frotz/src/games/enter.c | 7 +- frotz/src/games/hhgg.c | 6 +- frotz/src/games/hollywood.c | 14 +- frotz/src/games/infidel.c | 9 +- frotz/src/games/jewel.c | 8 +- frotz/src/games/karn.c | 5 +- frotz/src/games/library.c | 10 +- frotz/src/games/lostpig.c | 7 +- frotz/src/games/nine05.c | 12 +- frotz/src/interface/frotz_interface.c | 417 +++++++++++++++++-- frotz/src/interface/frotz_interface.h | 7 +- frotz/src/interface/md5.c | 143 ++++--- frotz/src/ztools/infodump.c | 11 + frotz/src/ztools/txd.c | 2 +- jericho/defines.py | 4 +- jericho/game_info.py | 29 +- jericho/jericho.py | 80 +++- jericho/util.py | 92 +++++ tools/test_games.py | 551 +++++++++++++++++++++++++- 35 files changed, 1496 insertions(+), 316 deletions(-) diff --git a/frotz/Makefile b/frotz/Makefile index 27f3d820..ef406755 100644 --- a/frotz/Makefile +++ b/frotz/Makefile @@ -11,7 +11,8 @@ RANLIB = /usr/bin/ranlib CC ?= gcc # Enable compiler warnings. This is an absolute minimum. -CFLAGS += -Wall -Wextra -std=gnu99 -fPIC -Werror=implicit-function-declaration +#CFLAGS += -Wall -Wextra -std=gnu99 -fPIC -Werror=implicit-function-declaration +CFLAGS += -w # Define your optimization flags. # diff --git a/frotz/src/common/frotz.h b/frotz/src/common/frotz.h index df2f84c4..f32c49e2 100644 --- a/frotz/src/common/frotz.h +++ b/frotz/src/common/frotz.h @@ -550,20 +550,31 @@ extern char *option_zcode_path; /* dg */ extern long reserve_mem; + +#define MOVE_DIFF_CNT 16 +#define ATTR_SET_CNT 16 +#define ATTR_CLR_CNT 16 +#define PROP_PUT_CNT 64 + // Keep track of the last n=16 changes to object tree extern int move_diff_cnt; -extern zword move_diff_objs[16]; -extern zword move_diff_dest[16]; +extern zword move_diff_objs[MOVE_DIFF_CNT]; +extern zword move_diff_dest[MOVE_DIFF_CNT]; // Keep track of the last n=16 changes to obj attributes extern int attr_diff_cnt; -extern zword attr_diff_objs[16]; -extern zword attr_diff_nb[16]; +extern zword attr_diff_objs[ATTR_SET_CNT]; +extern zword attr_diff_nb[ATTR_SET_CNT]; // Keep track of the last n=16 clears of obj attributes extern int attr_clr_cnt; -extern zword attr_clr_objs[16]; -extern zword attr_clr_nb[16]; +extern zword attr_clr_objs[ATTR_CLR_CNT]; +extern zword attr_clr_nb[ATTR_CLR_CNT]; + +// Keep track of the last n=32 changes to obj properties +extern int prop_put_cnt; +extern zword prop_put_objs[PROP_PUT_CNT]; +extern zword prop_put_nb[PROP_PUT_CNT]; // Keep track of up to n=16 changes to special ram locations defined by the game extern int ram_diff_cnt; @@ -692,7 +703,7 @@ void z_window_style (void); void init_err (void); void runtime_error (int); - + /* Error codes */ #define ERR_TEXT_BUF_OVF 1 /* Text buffer overflow */ #define ERR_STORE_RANGE 2 /* Store out of dynamic memory */ @@ -730,7 +741,7 @@ void runtime_error (int); #define ERR_REMOVE_OBJECT_0 31 /* @remove_object called with object 0 */ #define ERR_GET_NEXT_PROP_0 32 /* @get_next_prop called with object 0 */ #define ERR_NUM_ERRORS (32) - + /* There are four error reporting modes: never report errors; report only the first time a given error type occurs; report every time an error occurs; or treat all errors as fatal diff --git a/frotz/src/common/object.c b/frotz/src/common/object.c index e7c0afb3..75afb023 100644 --- a/frotz/src/common/object.c +++ b/frotz/src/common/object.c @@ -35,14 +35,17 @@ #define O4_SIZE 14 int move_diff_cnt; -zword move_diff_objs[16]; -zword move_diff_dest[16]; +zword move_diff_objs[MOVE_DIFF_CNT]; +zword move_diff_dest[MOVE_DIFF_CNT]; int attr_diff_cnt; -zword attr_diff_objs[16]; -zword attr_diff_nb[16]; +zword attr_diff_objs[ATTR_SET_CNT]; +zword attr_diff_nb[ATTR_SET_CNT]; int attr_clr_cnt; -zword attr_clr_objs[16]; -zword attr_clr_nb[16]; +zword attr_clr_objs[ATTR_CLR_CNT]; +zword attr_clr_nb[ATTR_CLR_CNT]; +int prop_put_cnt; +zword prop_put_objs[PROP_PUT_CNT]; +zword prop_put_nb[PROP_PUT_CNT]; /* * object_address @@ -453,7 +456,7 @@ void z_clear_attr (void) /* If we are monitoring attribute assignment display a short note */ - if (attr_clr_cnt < 16) { + if (attr_clr_cnt < ATTR_CLR_CNT) { attr_clr_objs[attr_clr_cnt] = zargs[0]; attr_clr_nb[attr_clr_cnt] = zargs[1]; attr_clr_cnt++; @@ -1065,7 +1068,7 @@ void z_insert_obj (void) /* If we are monitoring object movements display a short note */ - if (move_diff_cnt < 16) { + if (move_diff_cnt < MOVE_DIFF_CNT) { move_diff_objs[move_diff_cnt] = obj1; move_diff_dest[move_diff_cnt] = obj2; move_diff_cnt++; @@ -1183,6 +1186,12 @@ void z_put_prop (void) SET_WORD (prop_addr, v) } + if (prop_put_cnt < PROP_PUT_CNT) { + prop_put_objs[prop_put_cnt] = zargs[0]; + prop_put_nb[prop_put_cnt] = zargs[1]; + prop_put_cnt++; + } + }/* z_put_prop */ @@ -1194,7 +1203,13 @@ void z_put_prop (void) */ void z_remove_obj (void) { + /* If we are monitoring object movements display a short note */ + if (move_diff_cnt < 16) { + move_diff_objs[move_diff_cnt] = zargs[0]; + move_diff_dest[move_diff_cnt] = (zword) 0; + move_diff_cnt++; + } if (f_setup.object_movement) { stream_mssg_on (); @@ -1231,7 +1246,7 @@ void z_set_attr (void) /* If we are monitoring attribute assignment display a short note */ - if (attr_diff_cnt < 16) { + if (attr_diff_cnt < ATTR_SET_CNT) { attr_diff_objs[attr_diff_cnt] = zargs[0]; attr_diff_nb[attr_diff_cnt] = zargs[1]; attr_diff_cnt++; diff --git a/frotz/src/games/acorncourt.c b/frotz/src/games/acorncourt.c index afffeb4e..5748d8f5 100644 --- a/frotz/src/games/acorncourt.c +++ b/frotz/src/games/acorncourt.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -103,11 +103,11 @@ int acorn_ignore_attr_clr(zword obj_num, zword attr_idx) { } void acorn_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 6); - // Clear attr 25 - for (i=1; i<=acorn_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + // Zero out attribute 25 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111111 11111111 10111111 + char mask3 = 0b10111111; // Attr 25. + for (int i=1; i<=acorn_get_num_world_objs(); ++i) { + objs[i].attr[3] &= mask3; + } } diff --git a/frotz/src/games/advent.c b/frotz/src/games/advent.c index 7a8c902a..e048139b 100644 --- a/frotz/src/games/advent.c +++ b/frotz/src/games/advent.c @@ -24,16 +24,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Adventure: http://ifdb.tads.org/viewgame?id=fft6pu91j85y4acv -const zword advent_special_ram_addrs[5] = { +const zword advent_special_ram_addrs[3] = { 15198, // Kill dragon - 15191, // Pour water on plant - 15287, // Give food to bear + // 15191, // Pour water on plant + //15287, // Give food to bear 15282, // Bear following you 15642, // FEE/FIE/FOE/FOO }; zword* advent_ram_addrs(int *n) { - *n = 5; + *n = 3; return advent_special_ram_addrs; } @@ -104,4 +104,11 @@ int advent_ignore_attr_clr(zword obj_num, zword attr_idx) { } void advent_clean_world_objs(zobject* objs) { + // Zero out attribute 25 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111111 11111111 10111111 + char mask = 0b10111111; // Attr 25. + for (int i=1; i<=advent_get_num_world_objs(); ++i) { + objs[i].attr[3] &= mask; + } } diff --git a/frotz/src/games/adventureland.c b/frotz/src/games/adventureland.c index e998be40..dbbe4381 100644 --- a/frotz/src/games/adventureland.c +++ b/frotz/src/games/adventureland.c @@ -24,12 +24,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Adventureland: http://ifdb.tads.org/viewgame?id=dy4ok8sdlut6ddj7 -const zword adventureland_special_ram_addrs[1] = { - 1231 // Activated take/drink water +const zword adventureland_special_ram_addrs[0] = { + // 1231 // Activated take/drink water }; zword* adventureland_ram_addrs(int *n) { - *n = 1; + *n = 0; return adventureland_special_ram_addrs; } @@ -88,23 +88,23 @@ int adventureland_ignore_moved_obj(zword obj_num, zword dest_num) { } int adventureland_ignore_attr_diff(zword obj_num, zword attr_idx) { - if (attr_idx == 2 || attr_idx == 25) - return 1; + // if (attr_idx == 2 || attr_idx == 25) + // return 1; return 0; } int adventureland_ignore_attr_clr(zword obj_num, zword attr_idx) { - if (attr_idx == 2 || attr_idx == 25) - return 1; + // if (attr_idx == 2 || attr_idx == 25) + // return 1; return 0; } void adventureland_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 6) & ~(1 << 7); - // Clear attr 24 & 25 - for (i=1; i<=adventureland_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + // Zero out attribute 25 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111111 11111111 10111111 + // char mask3 = 0b10111111; // Attr 25. + // for (int i=1; i<=adventureland_get_num_world_objs(); ++i) { + // objs[i].attr[3] &= mask3; + // } } diff --git a/frotz/src/games/afflicted.c b/frotz/src/games/afflicted.c index 72a64e93..1c18e272 100644 --- a/frotz/src/games/afflicted.c +++ b/frotz/src/games/afflicted.c @@ -26,9 +26,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. int score = 0; +const zword afflicted_special_ram_addrs[3] = { + 25038, // Nikolai's sanitation rating. Alternative: 24989, 24997, 25039 + 1880, // Angela wakes up + // 25461, // Noting things. + 24996 // Sofia is dead. +}; + zword* afflicted_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 3; + return afflicted_special_ram_addrs; } char** afflicted_intro_actions(int *n) { @@ -101,16 +108,24 @@ int afflicted_ignore_moved_obj(zword obj_num, zword dest_num) { } int afflicted_ignore_attr_diff(zword obj_num, zword attr_idx) { - if (attr_idx == 30 || attr_idx == 11 || attr_idx == 34 || attr_idx == 21) + // if (attr_idx == 30 || attr_idx == 11 || attr_idx == 34 || attr_idx == 21) + if (attr_idx == 30 || attr_idx == 29) return 1; return 0; } int afflicted_ignore_attr_clr(zword obj_num, zword attr_idx) { - if (attr_idx == 30) + if (attr_idx == 30 || attr_idx == 29) return 1; return 0; } void afflicted_clean_world_objs(zobject* objs) { + // Zero out attribute 30 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111111 11111111 11111001 + char mask3 = 0b11111001; // Attr 29 and 30. + for (int i=1; i<=afflicted_get_num_world_objs(); ++i) { + objs[i].attr[3] &= mask3; + } } diff --git a/frotz/src/games/anchor.c b/frotz/src/games/anchor.c index 63f932f5..5419f4c5 100644 --- a/frotz/src/games/anchor.c +++ b/frotz/src/games/anchor.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -27,10 +27,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *anchor_intro[] = { "\n", "\n", "\n" }; const zword anchor_special_ram_addrs[4] = { - 21922, // Combination lock + // 21922, // Combination lock 40660, // Bathe - 38470, // Transitions between days - 37992, // Sleep + // 38470, // Transitions between days + // 37992, // Sleep + 8810, // Talking to Micheal + // 18081, // Asking Bum about brother + // 24928, // Turn c, w, h and e. + 18839, // Being chased by a monster around the Old Stone Well. + // 31625, // Breaking door leading to Hallway. + // 17267, // Ritual sequence in town square + 27970, // Opening the hatch and waiting for the sound. }; zword* anchor_ram_addrs(int *n) { @@ -53,7 +60,8 @@ char* anchor_clean_observation(char* obs) { } int anchor_victory() { - char *death_text = "**** You have won ****"; + //char *death_text = "**** You have won ****"; + char *death_text = "*** You have won... for now ***"; if (strstr(world, death_text)) { return 1; } @@ -106,4 +114,13 @@ int anchor_ignore_attr_clr(zword obj_num, zword attr_idx) { } void anchor_clean_world_objs(zobject* objs) { + // Zero out attribute 25 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 01111111 11111111 10111111 + // char mask1 = 0b01111111; // Attr 8 + char mask3 = 0b10111111; // Attr 25. + for (int i=1; i<=anchor_get_num_world_objs(); ++i) { + // objs[i].attr[1] &= mask1; + objs[i].attr[3] &= mask3; + } } diff --git a/frotz/src/games/awaken.c b/frotz/src/games/awaken.c index 53a9f4ad..95121d8c 100644 --- a/frotz/src/games/awaken.c +++ b/frotz/src/games/awaken.c @@ -24,9 +24,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // The Awakening: http://www.ifwiki.org/index.php/The_Awakening + + +const zword awaken_special_ram_addrs[3] = { + 9746, // Make the guard dog in front of the church angry. Alternative: 10756 + 13298, // Read the journal on the desk in the Small Office. + 11465, // Tie rope to handle. Alternative: 11466 +}; + zword* awaken_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 3; + return awaken_special_ram_addrs; } char** awaken_intro_actions(int *n) { @@ -96,11 +104,11 @@ int awaken_ignore_attr_clr(zword obj_num, zword attr_idx) { } void awaken_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=awaken_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + // Zero out attribute 25 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111111 11111111 10111111 + char mask3 = 0b10111111; // Attr 25 + for (int i=1; i<=awaken_get_num_world_objs(); ++i) { + objs[i].attr[3] &= mask3; + } } diff --git a/frotz/src/games/balances.c b/frotz/src/games/balances.c index 98e3dc96..5aa977ae 100644 --- a/frotz/src/games/balances.c +++ b/frotz/src/games/balances.c @@ -24,19 +24,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Balances: http://ifdb.tads.org/viewgame?id=x6ne0bbd2oqm6h3a -const zword balances_special_ram_addrs[8] = { - 4162, // Write cave on cube - 1217, // urbzig snake (Also 1219, 3776) - 3760, // write chasm on cube - 5086, // Give silver to barker - 3327, // Keeps track of number of yomins memorized - 5217, // write prize on featureless - 4640, // write mace on featureless - 4589, // Process to acquire the mace cube +const zword balances_special_ram_addrs[0] = { + // 4162, // Write cave on cube + // 1217, // urbzig snake (Also 1219, 3776) + // 3760, // write chasm on cube + // 5086, // Give silver to barker + // 3327, // Keeps track of number of yomins memorized + // 5217, // write prize on featureless + // 4640, // write mace on featureless + // 4589, // Process to acquire the mace cube + // 1581, // urbzig toy and mace (Also 1583) }; zword* balances_ram_addrs(int *n) { - *n = 8; + *n = 0; return balances_special_ram_addrs; } @@ -107,11 +108,13 @@ int balances_ignore_attr_clr(zword obj_num, zword attr_idx) { } void balances_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=balances_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + // Zero out attribute 8, 25 and 31 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 01111111 11111111 11111110 + char mask1 = 0b01111111; // Attr 8 + char mask3 = 0b10111110; // Attr 25, 31 + for (int i=1; i<=balances_get_num_world_objs(); ++i) { + objs[i].attr[1] &= mask1; + objs[i].attr[3] &= mask3; + } } diff --git a/frotz/src/games/ballyhoo.c b/frotz/src/games/ballyhoo.c index 875db94c..e9c786ff 100644 --- a/frotz/src/games/ballyhoo.c +++ b/frotz/src/games/ballyhoo.c @@ -24,11 +24,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Ballyhoo: http://ifdb.tads.org/viewgame?id=b0i6bx7g4rkrekgg -const zword ballyhoo_special_ram_addrs[19] = { - 8835, // Lion +const zword ballyhoo_special_ram_addrs[23] = { + 8853, // Listen to the conversation with Munrab. + 8623, // Crossing the tightrope + 9113, // turnstile + 8835, // Lion stand 8723, // Give case to harry 9067, // buy candy 8791, // stand + 8893, // walking in the crowd 9053, // get out of line 8539, // tina 8911, // radio @@ -40,14 +44,14 @@ const zword ballyhoo_special_ram_addrs[19] = { 2735, // veil 1691, // dress 8905, // mahler - 8623, // tightrope 8543, // tightrope 8545, // wpdl - 9113, // turnstile + 8845, // read the spreadsheet + 8525, // say hello Eddit to Chuckles. }; zword* ballyhoo_ram_addrs(int *n) { - *n = 19; + *n = 23; return ballyhoo_special_ram_addrs; } @@ -106,20 +110,34 @@ int ballyhoo_ignore_moved_obj(zword obj_num, zword dest_num) { } int ballyhoo_ignore_attr_diff(zword obj_num, zword attr_idx) { - if (obj_num == 211 && attr_idx == 13) - return 1; + // if (obj_num == 211 && attr_idx == 13) + // if (obj_num == 211) + // return 1; if (attr_idx == 30) return 1; return 0; } int ballyhoo_ignore_attr_clr(zword obj_num, zword attr_idx) { - if (obj_num == 211 && attr_idx == 13) - return 1; - if (attr_idx == 20) + // if (obj_num == 211) + // return 1; + if (attr_idx == 20) // TODO: Should it be attr 30 like in ballyhoo_ignore_attr_diff ? return 1; return 0; } void ballyhoo_clean_world_objs(zobject* objs) { + // Clear out object "it" + // objs[211].parent = 0; + + // Zero out attribute 13 of object 211 ("it") + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111011 11111111 11111101 + // char mask1 = 0b11111011; // Attr 13 + char mask3 = 0b11111101; // Attr 30 + // objs[211].attr[1] &= mask1; + + for (int i=1; i<=ballyhoo_get_num_world_objs(); ++i) { + objs[i].attr[3] &= mask3; + } } diff --git a/frotz/src/games/curses.c b/frotz/src/games/curses.c index 7050eb1a..2eb72192 100644 --- a/frotz/src/games/curses.c +++ b/frotz/src/games/curses.c @@ -24,22 +24,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Curses: http://ifdb.tads.org/viewgame?id=plvzam05bmz3enh8 -const zword curses_special_ram_addrs[9] = { - 23655, // Hole - 23673, // Maze navigation - 23675, // Maze navigation - 13293, // Revolving door - 23663, // Tarot cards - 15147, // Talking to Homer - 23681, // Pacing - 23683, // Pacing - 20911, // Turn sceptre +const zword curses_special_ram_addrs[17] = { + 786, 800, 828, 842, 856, 870, 884, 898, // Interacting with the rods. + // 1469, // Clean glass ball + 23711, // get High Rod of Love (warning message) + 23655, 23657, // Hole + 23673, 23675, // Maze navigation + // 13293, // Revolving door + // 23663, // Tarot cards + 25304, 23695, // Solving the sliding puzzle + // 15147, // Talking to Homer + 23681, 23683, // Pacing + // 14201, // Set timer + // 20911, // Turn sceptre + // 23701, // Close the lid. + // 23707, // Lost inside the Palace }; const char *curses_intro[] = { "\n" }; zword* curses_ram_addrs(int *n) { - *n = 9; + *n = 17; return curses_special_ram_addrs; } @@ -86,7 +91,10 @@ short curses_get_score() { } int curses_max_score() { - return 550; + // return 550; + // Due to a bug, the max score is 554 points instead of 550. + // ref: https://raw.githubusercontent.com/heasm66/walkthroughs/main/curses_walkthrough.txt + return 554; } int curses_get_num_world_objs() { @@ -98,23 +106,23 @@ int curses_ignore_moved_obj(zword obj_num, zword dest_num) { } int curses_ignore_attr_diff(zword obj_num, zword attr_idx) { - if (attr_idx == 25) + if (attr_idx == 25)// || attr_idx == 8) return 1; return 0; } int curses_ignore_attr_clr(zword obj_num, zword attr_idx) { - if (attr_idx == 25) + if (attr_idx == 25)// || attr_idx == 8) return 1; return 0; } void curses_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=curses_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + // Zero out attribute 25 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111111 11111111 10111111 + char mask3 = 0b10111111; // Attr 25. + for (int i=1; i<=curses_get_num_world_objs(); ++i) { + objs[i].attr[3] &= mask3; + } } diff --git a/frotz/src/games/cutthroat.c b/frotz/src/games/cutthroat.c index ab07791c..02428971 100644 --- a/frotz/src/games/cutthroat.c +++ b/frotz/src/games/cutthroat.c @@ -23,10 +23,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "frotz_interface.h" // Cutthroats: http://ifdb.tads.org/viewgame?id=4ao65o1u0xuvj8jf +const zword cutthroat_special_ram_addrs[7] = { + 8785, // Lock state of bedroom door. + 8669, 9021, // Answering Johnny's questions. + 10635, // Waiting for McGinty to leave. + 8845, 8847, // Tell longitude and latitude to Johnny. + 8987, // Track most of the game progression. Needed for "Fill tank with air". +}; zword* cutthroat_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 7; + return cutthroat_special_ram_addrs; } char** cutthroat_intro_actions(int *n) { @@ -92,16 +99,22 @@ int cutthroat_ignore_attr_clr(zword obj_num, zword attr_idx) { } void cutthroat_clean_world_objs(zobject* objs) { - char mask; - int i; - zobject* weasel_obj; - zobject* weasel_loc; + zobject *weasel_obj, *weasel_loc; + zobject *player_obj, *player_loc; + + player_obj = &objs[184]; + player_loc = &objs[player_obj->parent]; weasel_obj = &objs[9]; weasel_loc = &objs[weasel_obj->parent]; - if (weasel_loc->child == 9) { - weasel_loc->child = weasel_obj->sibling; + + // Filter out Weasel when not in sight. + if (player_loc->num != weasel_loc->num) { + if (weasel_loc->child == 9) { + weasel_loc->child = weasel_obj->sibling; + } + + weasel_obj->parent = 0; + weasel_obj->sibling = 0; + weasel_obj->child = 0; } - weasel_obj->parent = 0; - weasel_obj->sibling = 0; - weasel_obj->child = 0; } diff --git a/frotz/src/games/deephome.c b/frotz/src/games/deephome.c index 5a3bc2bd..c6f7e51c 100644 --- a/frotz/src/games/deephome.c +++ b/frotz/src/games/deephome.c @@ -24,14 +24,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Deephome: A Telleen Adventure: http://ifdb.tads.org/viewgame?id=x85otcikhwp8bwup -const zword deephome_special_ram_addrs[3] = { +const zword deephome_special_ram_addrs[5] = { 12396, // Track eranti health 12262, // Open net, manaz - 12432, // Pray to kraxis + 12897, 12280, // Pray to kraxis + 12328, // Push lever }; zword* deephome_ram_addrs(int *n) { - *n = 3; + *n = 5; return deephome_special_ram_addrs; } @@ -50,7 +51,7 @@ char* deephome_clean_observation(char* obs) { } int deephome_victory() { - char *death_text = "**** You have won ****"; + char *death_text = "*** You have won ***"; if (strstr(world, death_text)) { return 1; } diff --git a/frotz/src/games/dragon.c b/frotz/src/games/dragon.c index b4187136..9b47a16e 100644 --- a/frotz/src/games/dragon.c +++ b/frotz/src/games/dragon.c @@ -24,14 +24,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Dragon Adventure: http://ifdb.tads.org/viewgame?id=sjiyffz8n5patu8l -const zword dragon_special_ram_addrs[3] = { +const zword dragon_special_ram_addrs[4] = { 16090, // Set to 1 when you buy the box 16101, // Set to 1 when you play the flute - 16102 // Set to 1 when you blow the horn + 16102, // Set to 1 when you blow the horn + 13426, // Read the booklet. }; zword* dragon_ram_addrs(int *n) { - *n = 3; + *n = 4; return dragon_special_ram_addrs; } diff --git a/frotz/src/games/enchanter.c b/frotz/src/games/enchanter.c index ee69a094..f8bf3dbd 100644 --- a/frotz/src/games/enchanter.c +++ b/frotz/src/games/enchanter.c @@ -24,9 +24,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Enchanter: http://ifdb.tads.org/viewgame?id=vu4xhul3abknifcr +const zword enchanter_special_ram_addrs[3] = { + 9082, // Move block. + 8906, // Drawing lines on the map. + 8984, // Erasing lines on the map. +}; + zword* enchanter_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 3; + return enchanter_special_ram_addrs; } char** enchanter_intro_actions(int *n) { @@ -92,11 +98,11 @@ int enchanter_ignore_attr_clr(zword obj_num, zword attr_idx) { } void enchanter_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~1; - // Clear attr 15 - for (i=1; i<=enchanter_get_num_world_objs(); ++i) { - objs[i].attr[1] &= mask; - } + // int i; + // char mask; + // mask = ~1; + // // Clear attr 15 + // for (i=1; i<=enchanter_get_num_world_objs(); ++i) { + // objs[i].attr[1] &= mask; + // } } diff --git a/frotz/src/games/enter.c b/frotz/src/games/enter.c index 89eae75e..c516bdb9 100644 --- a/frotz/src/games/enter.c +++ b/frotz/src/games/enter.c @@ -24,9 +24,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // The Enterprise Incidents: http://ifdb.tads.org/viewgame?id=ld1f3t5epeagilfz -const zword enter_special_ram_addrs[6] = { +const zword enter_special_ram_addrs[7] = { 9667, // Say -120 to garrulous - 10249, //Take candygram / talk to queenie + 10249, // Take candygram / talk to queenie + 11059, // Open door and and talk with Ms. Empirious. 11607, // Put gram in basket 11219, // Talk to Emperius / take jar 10644, // Say firefly to jim @@ -34,7 +35,7 @@ const zword enter_special_ram_addrs[6] = { }; zword* enter_ram_addrs(int *n) { - *n = 6; + *n = 7; return enter_special_ram_addrs; } diff --git a/frotz/src/games/hhgg.c b/frotz/src/games/hhgg.c index ab6c20d5..bf8ecb98 100644 --- a/frotz/src/games/hhgg.c +++ b/frotz/src/games/hhgg.c @@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Hitchhiker's Guide to the Galaxy: http://ifdb.tads.org/viewgame?id=ouv80gvsl32xlion -const zword hhgg_special_ram_addrs[16] = { +const zword hhgg_special_ram_addrs[18] = { 8767, // Lie down in front of bulldozer 8189, // Wait on bulldozer 8169, // Beer @@ -41,10 +41,12 @@ const zword hhgg_special_ram_addrs[16] = { 8187, // Prossner lie in the mud 8041, // no tea 8349, // Marvin, open hatch + 8119, // Enjoy poetry. + 8105, // Spongy gray maze }; zword* hhgg_ram_addrs(int *n) { - *n = 16; + *n = 18; return hhgg_special_ram_addrs; } diff --git a/frotz/src/games/hollywood.c b/frotz/src/games/hollywood.c index 38cc7d70..9f997f42 100644 --- a/frotz/src/games/hollywood.c +++ b/frotz/src/games/hollywood.c @@ -24,12 +24,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Hollywood Hijinx: http://ifdb.tads.org/viewgame?id=jnfkbgdgopwfqist -const zword hollywood_special_ram_addrs[5] = { - 8207, // Atomic Chihuahua - 8241, // Atomic Chihuahua - 8341, // Atomic Chihuahua +const zword hollywood_special_ram_addrs[9] = { + 8207, 8241, 8341, // Atomic Chihuahua 8323, // Breathing fire - 8381, // Safe dial + 8381, // Safe dial (Hallway) + 8277, // Push piano + 8269, // Hedge Maze + 8221, // Safe dial (Bomb Shelter) + 8363, // throw club at herman }; const char *hollywood_intro[] = { "turn statue west\n", @@ -37,7 +39,7 @@ const char *hollywood_intro[] = { "turn statue west\n", "turn statue north\n" }; zword* hollywood_ram_addrs(int *n) { - *n = 5; + *n = 9; return hollywood_special_ram_addrs; } diff --git a/frotz/src/games/infidel.c b/frotz/src/games/infidel.c index a1dccdef..4e465984 100644 --- a/frotz/src/games/infidel.c +++ b/frotz/src/games/infidel.c @@ -24,13 +24,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Infidel: http://ifdb.tads.org/viewgame?id=anu79a4n1jedg5mm -const zword infidel_special_ram_addrs[2] = { +const zword infidel_special_ram_addrs[5] = { 4333, // Dig in sand - 9512 // Activated by 'eat beef' + 9512, // Activated by 'eat beef' + 9214, // Pour liquid on torch. + 9200, // Stand on beam + 9204, // Break seal }; zword* infidel_ram_addrs(int *n) { - *n = 2; + *n = 5; return infidel_special_ram_addrs; } diff --git a/frotz/src/games/jewel.c b/frotz/src/games/jewel.c index 4294e8ea..fb73a2f8 100644 --- a/frotz/src/games/jewel.c +++ b/frotz/src/games/jewel.c @@ -26,9 +26,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *jewel_intro[] = { "bypass\n", "yes\n" }; +const zword jewel_special_ram_addrs[1] = { + 1796, // Chop ice +}; + zword* jewel_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 1; + return jewel_special_ram_addrs; } char** jewel_intro_actions(int *n) { diff --git a/frotz/src/games/karn.c b/frotz/src/games/karn.c index b21009b7..f619fc76 100644 --- a/frotz/src/games/karn.c +++ b/frotz/src/games/karn.c @@ -24,14 +24,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Return to Karn: http://ifdb.tads.org/viewgame?id=bx8118ggp6j7nslo -const zword karn_special_ram_addrs[3] = { +const zword karn_special_ram_addrs[4] = { 14066, // Tardis flying/grounded 13050, // Color sequence 1213, // k9 following player + 2194, // Pull lever and Push button }; zword* karn_ram_addrs(int *n) { - *n = 3; + *n = 4; return karn_special_ram_addrs; } diff --git a/frotz/src/games/library.c b/frotz/src/games/library.c index 26fb8492..84c035df 100644 --- a/frotz/src/games/library.c +++ b/frotz/src/games/library.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -26,9 +26,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *library_intro[] = { "\n" }; +const zword library_special_ram_addrs[1] = { + 3594, // xyzzy (bonus point) +}; + zword* library_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 1; + return library_special_ram_addrs; } char** library_intro_actions(int *n) { diff --git a/frotz/src/games/lostpig.c b/frotz/src/games/lostpig.c index f46c6f5d..5464fc7c 100644 --- a/frotz/src/games/lostpig.c +++ b/frotz/src/games/lostpig.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -54,7 +54,10 @@ char* lostpig_clean_observation(char* obs) { } int lostpig_victory() { - char *victory_text = "*** Grunk bring pig back to farm ***"; + // Winning messages change depending on the score. + // *** Grunk bring pig back to farm *** // 6 out of 7 points. + // *** Grunk bring pig back to farm and make new friend *** // 7 out of 7 points. + char *victory_text = "*** Grunk bring pig back to farm "; // Works for both 6 and 7 points. if (strstr(world, victory_text)) { return 1; } diff --git a/frotz/src/games/nine05.c b/frotz/src/games/nine05.c index 4ddfa93e..a86ff6d3 100644 --- a/frotz/src/games/nine05.c +++ b/frotz/src/games/nine05.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -99,4 +99,14 @@ int nine05_ignore_attr_clr(zword obj_num, zword attr_idx) { } void nine05_clean_world_objs(zobject* objs) { + int i; + char mask; + + // Zero out attribute 25 for all objects. + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111111 11111111 10111111 + mask = 0b10111111; // Attr 25. + for (i=1; i<=nine05_get_num_world_objs(); ++i) { + objs[i].attr[3] &= 0b10111111; + } } diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index 5fa64497..2600b8e3 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "frotz_interface.h" #include "games.h" #include "ztools.h" +#include "md5.h" extern void interpret (void); extern void interpret_until_read (void); @@ -54,7 +55,7 @@ extern void insert_tree(zword obj1, zword obj2); extern void insert_obj(zword obj1, zword obj2); extern void seed_random (int value); extern void set_random_seed (int seed); -extern void sum(FILE*, char*); +// extern void sum(FILE*, char*); extern void dumb_free(); extern zword first_property (zword); @@ -68,7 +69,7 @@ extern int getRngCounter(); extern void setRng(long, int, int); zbyte next_opcode; -int last_PC = -1; +int last_ret_pc = -1; int desired_seed = 0; int ROM_IDX = 0; char world[8192] = ""; @@ -78,9 +79,16 @@ char halted_message[] = "Emulator halted due to runtime error.\n"; int num_special_addrs = 0; zword *special_ram_addrs = NULL; zbyte *special_ram_values = NULL; + +zobject* old_objs = NULL; +zobject* new_objs = NULL; + int ram_diff_cnt; zword ram_diff_addr[16]; zword ram_diff_value[16]; +//char last_state_hash[64]; +//char current_state_hash[64]; +bool state_has_changed = FALSE; // Runs a single opcode on the Z-Machine @@ -427,6 +435,10 @@ void setFP(int v) { fp = stack + v; } +int getRetPC() { + return *(fp+2) | ((*fp+2+1) << 9); +} + int get_opcode() { return next_opcode; } @@ -1442,6 +1454,13 @@ void init_special_ram() { if (num_special_addrs > 0) { special_ram_values = (zbyte*) malloc(num_special_addrs * sizeof(zbyte)); } + + // Init objs. + if (old_objs != NULL) free(old_objs); + if (new_objs != NULL) free(new_objs); + + old_objs = calloc(get_num_world_objs() + 1, sizeof(zobject)); + new_objs = calloc(get_num_world_objs() + 1, sizeof(zobject)); } // Updates the special ram values to reflect the current memory @@ -1469,6 +1488,19 @@ void update_ram_diff() { } } +// Updates the objects list, used for tracking state changes, to reflect the current memory +void update_objs_tracker() { + + get_world_objects(new_objs, TRUE); + + // For a more robust state hash, do not include siblings and children + // since their ordering in memory may change. + for (int i=1; i<=get_num_world_objs(); ++i) { + new_objs[i].sibling = 0; + new_objs[i].child = 0; + } +} + char* setup(char *story_file, int seed, void *rom, size_t rom_size) { char* text; emulator_halted = 0; @@ -1524,6 +1556,10 @@ char* setup(char *story_file, int seed, void *rom, size_t rom_size) { run_free(); } + // Initialize last and current state hashes. + // get_world_state_hash(last_state_hash); + // get_world_state_hash(current_state_hash); + text = dumb_get_screen(); text = clean_observation(text); strcpy(world, text); @@ -1533,17 +1569,30 @@ char* setup(char *story_file, int seed, void *rom, size_t rom_size) { char* step(char *next_action) { char* text; + char last_state_hash[64]; + char current_state_hash[64]; if (emulator_halted > 0) return halted_message; + // get_world_state_hash(last_state_hash); + + // Swap old_objs and new_objs. + zobject* tmp; + tmp = old_objs; + old_objs = new_objs; + new_objs = tmp; + + // printf("%x, %x\n", old_objs, new_objs); + // Clear the object, attr, and ram diffs move_diff_cnt = 0; attr_diff_cnt = 0; attr_clr_cnt = 0; + prop_put_cnt = 0; ram_diff_cnt = 0; update_special_ram(); - last_PC = getPC(); + last_ret_pc = getRetPC(); dumb_set_next_action(next_action); @@ -1552,6 +1601,23 @@ char* step(char *next_action) { // Check for changes to special ram update_ram_diff(); + //get_world_state_hash(current_state_hash); + + update_objs_tracker(); + // // memset(new_objs, 0, (get_num_world_objs() + 1) * sizeof(zobject)); + // get_world_objects(new_objs, TRUE); + + // // For a more robust state hash, do not include siblings and children + // // since their ordering in memory may change. + // for (int i=1; i<=get_num_world_objs(); ++i) { + // new_objs[i].sibling = 0; + // new_objs[i].child = 0; + // } + + //state_has_changed = strcmp(current_state_hash, last_state_hash) != 0; + state_has_changed = memcmp(old_objs, new_objs, (get_num_world_objs() + 1) * sizeof(zobject)) != 0; + // printf("%s =(%d)= %s <== %s", current_state_hash, state_has_changed, last_state_hash, next_action); + text = dumb_get_screen(); text = clean_observation(text); strcpy(world, text); @@ -1567,6 +1633,14 @@ void set_narrative_text(char* text) { strcpy(world, text); } +bool get_state_changed() { + return state_has_changed; +} + +void set_state_changed(bool value) { + state_has_changed = value; +} + // Returns a world diff that ignores selected objects // objs and dest are a 64-length pre-zeroed arrays. void get_cleaned_world_diff(zword *objs, zword *dest) { @@ -1585,8 +1659,8 @@ void get_cleaned_world_diff(zword *objs, zword *dest) { if (ignore_attr_diff(attr_diff_objs[i], attr_diff_nb[i])) { continue; } - objs[16+j] = attr_diff_objs[i]; - dest[16+j] = attr_diff_nb[i]; + objs[MOVE_DIFF_CNT+j] = attr_diff_objs[i]; + dest[MOVE_DIFF_CNT+j] = attr_diff_nb[i]; j++; } j = 0; @@ -1594,48 +1668,74 @@ void get_cleaned_world_diff(zword *objs, zword *dest) { if (ignore_attr_clr(attr_clr_objs[i], attr_clr_nb[i])) { continue; } - objs[32+j] = attr_clr_objs[i]; - dest[32+j] = attr_clr_nb[i]; + objs[MOVE_DIFF_CNT+ATTR_SET_CNT+j] = attr_clr_objs[i]; + dest[MOVE_DIFF_CNT+ATTR_SET_CNT+j] = attr_clr_nb[i]; + j++; + } + j = 0; + for (i=0; i 0 || victory() > 0) { return 1; } + if (ram_diff_cnt > 0) { return 1; } - return last_PC != getPC(); + return objs_has_changed || last_ret_pc != getRetPC(); } + void get_object(zobject *obj, zword obj_num) { - int i; zbyte prop_value; zbyte mask; @@ -1647,12 +1747,24 @@ void get_object(zobject *obj, zword obj_num) { zbyte length; LOW_BYTE(obj_name_addr, length); - if (length <= 0 || length > 64) { - return; - } + // if (length <= 0 || length > 64) { + // return; + // } (*obj).num = obj_num; - get_text(0, obj_name_addr+1, &(*obj).name); + + if (length > 0 && length <= 64) { + get_text(0, obj_name_addr+1, &(*obj).name); + } + else if (length > 64) { + // Object's short name is limited to 765 Z-characters. + // https://inform-fiction.org/zmachine/standards/z1point1/sect12.html#four. + char* buf = calloc(length, 1); + get_text(0, obj_name_addr+1, buf); + memcpy(&(*obj).name, buf, 64); // Crop the name to the first 64 characters. + free(buf); + } + (*obj).parent = get_parent(obj_num); (*obj).sibling = get_sibling(obj_num); @@ -1660,27 +1772,76 @@ void get_object(zobject *obj, zword obj_num) { // Get the attributes of the object zword obj_addr = object_address(obj_num); - for (i=0; i<4; ++i) { + for (int i=0; i<4; ++i) { LOW_BYTE(obj_addr + i, (*obj).attr[i]); } // Get the properties of the object + zbyte value; + zbyte prop_id; + zword wprop_val; + zbyte bprop_val; + zword prop_data_addr; + + /* Property id is in bottom five (six) bits */ mask = (h_version <= V3) ? 0x1f : 0x3f; - zword prop_addr = first_property(obj_num); - LOW_BYTE(prop_addr, prop_value); - for (i=0; i<16 && prop_value != 0; ++i) { - (*obj).properties[i] = prop_value & mask; - prop_addr = next_property(prop_addr); - LOW_BYTE(prop_addr, prop_value); + zword prop_addr = first_property (obj_num); + + /* Scan down the property list */ + int i; + for (i=0; i < JERICHO_NB_PROPERTIES; ++i) { + LOW_BYTE (prop_addr, value) + prop_id = value & mask; + if (prop_id <= 0) + break; + + (*obj).prop_ids[i] = prop_id; + + /* Load property (byte or word sized) */ + prop_data_addr = prop_addr + 1; + prop_addr = next_property (prop_addr); + zbyte prop_len = prop_addr - prop_data_addr - 1; + + (*obj).prop_lengths[i] = prop_len; + + // Zero-initialized the property data. + for (int j=0; j < JERICHO_PROPERTY_LENGTH; ++j) { + (*obj).prop_data[(i*JERICHO_PROPERTY_LENGTH) + j] = 0; + } + + if (prop_len <= 2) { + if ((h_version <= V3 && !(value & 0xe0)) || (h_version >= V4 && !(value & 0xc0))) { + LOW_BYTE (prop_data_addr, bprop_val) + wprop_val = bprop_val; + (*obj).prop_data[(i*JERICHO_PROPERTY_LENGTH) + 0] = bprop_val; + } else { + LOW_WORD (prop_data_addr, wprop_val) + (*obj).prop_lengths[i] += 1; // zword is two zbytes. + (*obj).prop_data[(i*JERICHO_PROPERTY_LENGTH) + 0] = zmp[prop_data_addr]; + (*obj).prop_data[(i*JERICHO_PROPERTY_LENGTH) + 1] = zmp[prop_data_addr+1]; + } + + } else { + prop_data_addr++; // Property data starts on the next zbyte. + for (int j=0; j < prop_len; ++j) { + (*obj).prop_data[(i*JERICHO_PROPERTY_LENGTH) + j] = zmp[prop_data_addr + j]; + } + } } - for (; i<16; ++i) { - (*obj).properties[i] = 0; + + // Zero-initialize the remaining properties. + for (; i 0) { @@ -1688,6 +1849,173 @@ void get_world_objects(zobject *objs, int clean) { } } + +#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c " +#define BYTE_TO_BINARY(byte) \ + (byte & 0x80 ? '1' : '0'), \ + (byte & 0x40 ? '1' : '0'), \ + (byte & 0x20 ? '1' : '0'), \ + (byte & 0x10 ? '1' : '0'), \ + (byte & 0x08 ? '1' : '0'), \ + (byte & 0x04 ? '1' : '0'), \ + (byte & 0x02 ? '1' : '0'), \ + (byte & 0x01 ? '1' : '0') + +void print_object2(zobject* obj) { + printf("Obj%d: %s Parent%d Sibling%d Child%d", obj->num, obj->name, obj->parent, obj->sibling, obj->child); + + printf(" Attributes ["); + for (int i=0; i != 4; ++i) { + printf(BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(obj->attr[i])); + } + printf("] Properties ["); + for (int i=0; i != 64; ++i) { + if (obj->prop_ids[i] != 0) { + printf("%d ", obj->prop_ids[i]); + } + } + + printf("]\n"); + + + //printf("Obj%d: %s Parent%d Sibling%d Child%d Attributes %s Properties %s\n", obj->num, obj->name, obj->parent, obj->sibling, obj->child, obj->attr, obj->properties); + // ""\ + // .format(self.num, self.name, self.parent, self.sibling, self.child, + // np.nonzero(self.attr)[0].tolist(), [p for p in self.properties if p != 0]) + + // typedef struct { + // unsigned int num; + // char name[64]; + // int parent; + // int sibling; + // int child; + // char attr[4]; + // unsigned char properties[16]; + // } + } + + +int checksum(char* str, int len) { + int i; + int chk = 0x12345678; + + for (i = 0; i != len; i++) { + chk += ((int)(str[i]) * (i + 1)); + } + + return chk; +} + +void get_world_state_hash(char* md5_hash) { + // zobject* obj = calloc(1, sizeof(zobject)); + + // byte digest[16]; + // byte *buf = calloc(1152, 1); + // // byte digest[16]; + // // int i, n; + // MD5state *s = nil; + + // for (int i=1; i<=get_num_world_objs(); ++i) { + // get_object(obj, (zword) i); + // // TODO: call clean_obj function. + // obj->sibling = 0; + // obj->child = 0; + + // //memcpy(buf, obj, sizeof(zobject)); + // s = md5(buf, 1152, 0, s); + // } + // return 0; + + // s = md5(buf, 0, digest, s); + + // for(int j=0;j<16;j++) { + // sprintf(&md5_hash[2*j], "%.2X", digest[j]); + // } + //printf("md5 (obj ): %s\n", md5_hash); + + // for(i=0;i<16;i++) { + // sprintf(&md5_hash[2*i], "%.2X", digest[i]); + // } + + // // Compute MD5 hash. + // s = nil; + // n = 0; + + // //buf = calloc(256,64); + // for (size_t i; i <= sizeof(zobject); i += 128*64) { + // //i = fread(buf+n, 1, 128*64-n, fd); + // if(i <= 0) + // break; + // n += i; + // if(n & 0x3f) + // continue; + // s = md5(buf, n, 0, s); + // n = 0; + // } + // md5(buf, n, digest, s); + // for(i=0;i<16;i++) { + // sprintf(&hash[2*i], "%.2X", digest[i]); + // } + // free(buf); + + // free(buf); + // free(obj); + // return 0; + + //// + + int n_objs = get_num_world_objs() + 1; // Add extra spot for zero'th object + size_t objs_size = n_objs * sizeof(zobject); + zobject* objs = calloc(n_objs, sizeof(zobject)); + + size_t ram_size = get_special_ram_size() * sizeof(unsigned char); + unsigned char* ram = malloc(ram_size); + get_special_ram(ram); + + int retPC = getRetPC(); + + get_world_objects(objs, TRUE); + + // For a more robust state hash, do not include siblings and children + // since their ordering in memory may change. + for (int i=1; i<=get_num_world_objs(); ++i) { + objs[i].sibling = 0; + objs[i].child = 0; + } + + // Debug print. + // printf("\n--Start-\n"); + // for (int k=0; k != n_objs; ++k) { + // print_object2(&objs[k]); + // } + // printf("\n--End-\n"); + + // char temp_md5_hash[64]; + // FILE* tmp_fp = fmemopen(objs, objs_size, "rb"); + // sum(tmp_fp, temp_md5_hash); + // fclose(tmp_fp); + // printf("temp_md5_hash: %s", temp_md5_hash); + + size_t state_size = objs_size + ram_size + sizeof(int); + char* state = malloc(state_size); + memcpy(state, objs, objs_size); + memcpy(&state[objs_size], ram, ram_size); + memcpy(&state[objs_size+ram_size], &retPC, sizeof(int)); + + // int chk = checksum(state, state_size); + // sprintf(md5_hash, "%2X", chk); + + FILE* fp = fmemopen(state, state_size, "rb"); + sum(fp, md5_hash); + fclose(fp); + + // printf("md5 (objs): %s\n", md5_hash); + + free(objs); + free(state); + return 0; +} + // Teleports an object (and all children) to the desired destination void teleport_obj(zword obj, zword dest) { insert_obj(obj, dest); @@ -1764,6 +2092,7 @@ int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword move_diff_cnt = 0; attr_diff_cnt = 0; attr_clr_cnt = 0; + prop_put_cnt = 0; ram_diff_cnt = 0; update_special_ram(); dumb_set_next_action(act_newline); @@ -1789,7 +2118,7 @@ int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword valid_actions[v_idx++] = ';'; // Write the world diff resulting from the last action. - get_cleaned_world_diff(&diff_array[128*valid_cnt], &diff_array[(128*valid_cnt) + 64]); + get_cleaned_world_diff(&diff_array[128*valid_cnt], &diff_array[(128*valid_cnt) + 64]); // TODO: replace 128 valid_cnt++; } } diff --git a/frotz/src/interface/frotz_interface.h b/frotz/src/interface/frotz_interface.h index fb98bc36..93691993 100644 --- a/frotz/src/interface/frotz_interface.h +++ b/frotz/src/interface/frotz_interface.h @@ -20,6 +20,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef frotz_interface_h__ #define frotz_interface_h__ +#define JERICHO_NB_PROPERTIES 23 // Empirically found given Jericho's games. +#define JERICHO_PROPERTY_LENGTH 64 // Empirically found given Jericho's games. + typedef struct { unsigned int num; char name[64]; @@ -27,7 +30,9 @@ typedef struct { int sibling; int child; char attr[4]; - unsigned char properties[16]; + zbyte prop_ids[JERICHO_NB_PROPERTIES]; + zbyte prop_lengths[JERICHO_NB_PROPERTIES]; + zbyte prop_data[JERICHO_NB_PROPERTIES*JERICHO_PROPERTY_LENGTH]; } zobject; extern char* setup(char *story_file, int seed, void* rom, size_t rom_size); diff --git a/frotz/src/interface/md5.c b/frotz/src/interface/md5.c index 446a12e4..8ddd64a2 100644 --- a/frotz/src/interface/md5.c +++ b/frotz/src/interface/md5.c @@ -1,8 +1,8 @@ #include #include -#include -typedef unsigned int uint; -typedef unsigned char byte; +// #include +#include "md5.h" + extern int enc64(char*,byte*,int); /* @@ -68,92 +68,83 @@ typedef struct Table Table tab[] = { /* round 1 */ - { 0xd76aa478, 0, S11}, - { 0xe8c7b756, 1, S12}, - { 0x242070db, 2, S13}, - { 0xc1bdceee, 3, S14}, - { 0xf57c0faf, 4, S11}, - { 0x4787c62a, 5, S12}, - { 0xa8304613, 6, S13}, - { 0xfd469501, 7, S14}, - { 0x698098d8, 8, S11}, - { 0x8b44f7af, 9, S12}, - { 0xffff5bb1, 10, S13}, - { 0x895cd7be, 11, S14}, - { 0x6b901122, 12, S11}, - { 0xfd987193, 13, S12}, - { 0xa679438e, 14, S13}, + { 0xd76aa478, 0, S11}, + { 0xe8c7b756, 1, S12}, + { 0x242070db, 2, S13}, + { 0xc1bdceee, 3, S14}, + { 0xf57c0faf, 4, S11}, + { 0x4787c62a, 5, S12}, + { 0xa8304613, 6, S13}, + { 0xfd469501, 7, S14}, + { 0x698098d8, 8, S11}, + { 0x8b44f7af, 9, S12}, + { 0xffff5bb1, 10, S13}, + { 0x895cd7be, 11, S14}, + { 0x6b901122, 12, S11}, + { 0xfd987193, 13, S12}, + { 0xa679438e, 14, S13}, { 0x49b40821, 15, S14}, /* round 2 */ - { 0xf61e2562, 1, S21}, - { 0xc040b340, 6, S22}, - { 0x265e5a51, 11, S23}, - { 0xe9b6c7aa, 0, S24}, - { 0xd62f105d, 5, S21}, - { 0x2441453, 10, S22}, - { 0xd8a1e681, 15, S23}, - { 0xe7d3fbc8, 4, S24}, - { 0x21e1cde6, 9, S21}, - { 0xc33707d6, 14, S22}, - { 0xf4d50d87, 3, S23}, - { 0x455a14ed, 8, S24}, - { 0xa9e3e905, 13, S21}, - { 0xfcefa3f8, 2, S22}, - { 0x676f02d9, 7, S23}, + { 0xf61e2562, 1, S21}, + { 0xc040b340, 6, S22}, + { 0x265e5a51, 11, S23}, + { 0xe9b6c7aa, 0, S24}, + { 0xd62f105d, 5, S21}, + { 0x2441453, 10, S22}, + { 0xd8a1e681, 15, S23}, + { 0xe7d3fbc8, 4, S24}, + { 0x21e1cde6, 9, S21}, + { 0xc33707d6, 14, S22}, + { 0xf4d50d87, 3, S23}, + { 0x455a14ed, 8, S24}, + { 0xa9e3e905, 13, S21}, + { 0xfcefa3f8, 2, S22}, + { 0x676f02d9, 7, S23}, { 0x8d2a4c8a, 12, S24}, /* round 3 */ - { 0xfffa3942, 5, S31}, - { 0x8771f681, 8, S32}, - { 0x6d9d6122, 11, S33}, - { 0xfde5380c, 14, S34}, - { 0xa4beea44, 1, S31}, - { 0x4bdecfa9, 4, S32}, - { 0xf6bb4b60, 7, S33}, - { 0xbebfbc70, 10, S34}, - { 0x289b7ec6, 13, S31}, - { 0xeaa127fa, 0, S32}, - { 0xd4ef3085, 3, S33}, - { 0x4881d05, 6, S34}, - { 0xd9d4d039, 9, S31}, - { 0xe6db99e5, 12, S32}, - { 0x1fa27cf8, 15, S33}, - { 0xc4ac5665, 2, S34}, + { 0xfffa3942, 5, S31}, + { 0x8771f681, 8, S32}, + { 0x6d9d6122, 11, S33}, + { 0xfde5380c, 14, S34}, + { 0xa4beea44, 1, S31}, + { 0x4bdecfa9, 4, S32}, + { 0xf6bb4b60, 7, S33}, + { 0xbebfbc70, 10, S34}, + { 0x289b7ec6, 13, S31}, + { 0xeaa127fa, 0, S32}, + { 0xd4ef3085, 3, S33}, + { 0x4881d05, 6, S34}, + { 0xd9d4d039, 9, S31}, + { 0xe6db99e5, 12, S32}, + { 0x1fa27cf8, 15, S33}, + { 0xc4ac5665, 2, S34}, /* round 4 */ - { 0xf4292244, 0, S41}, - { 0x432aff97, 7, S42}, - { 0xab9423a7, 14, S43}, - { 0xfc93a039, 5, S44}, - { 0x655b59c3, 12, S41}, - { 0x8f0ccc92, 3, S42}, - { 0xffeff47d, 10, S43}, - { 0x85845dd1, 1, S44}, - { 0x6fa87e4f, 8, S41}, - { 0xfe2ce6e0, 15, S42}, - { 0xa3014314, 6, S43}, - { 0x4e0811a1, 13, S44}, - { 0xf7537e82, 4, S41}, - { 0xbd3af235, 11, S42}, - { 0x2ad7d2bb, 2, S43}, - { 0xeb86d391, 9, S44}, + { 0xf4292244, 0, S41}, + { 0x432aff97, 7, S42}, + { 0xab9423a7, 14, S43}, + { 0xfc93a039, 5, S44}, + { 0x655b59c3, 12, S41}, + { 0x8f0ccc92, 3, S42}, + { 0xffeff47d, 10, S43}, + { 0x85845dd1, 1, S44}, + { 0x6fa87e4f, 8, S41}, + { 0xfe2ce6e0, 15, S42}, + { 0xa3014314, 6, S43}, + { 0x4e0811a1, 13, S44}, + { 0xf7537e82, 4, S41}, + { 0xbd3af235, 11, S42}, + { 0x2ad7d2bb, 2, S43}, + { 0xeb86d391, 9, S44}, }; -typedef struct MD5state -{ - uint len; - uint state[4]; -}MD5state; -MD5state *nil; - int debug; int hex; /* print in hex? (instead of default base64) */ void encode(byte*, uint*, uint); void decode(uint*, byte*, uint); -MD5state* md5(byte*, uint, byte*, MD5state*); -void sum(FILE*, char*); void sum(FILE *fd, char *hash) @@ -239,7 +230,7 @@ md5(byte *p, uint len, byte *digest, MD5state *s) d = s->state[3]; decode(x, p, 64); - + for(i = 0; i < 64; i++){ t = tab + i; switch(i>>4){ @@ -259,7 +250,7 @@ md5(byte *p, uint len, byte *digest, MD5state *s) a += x[t->x] + t->sin; a = (a << t->rot) | (a >> (32 - t->rot)); a += b; - + /* rotate variables */ tmp = d; d = c; diff --git a/frotz/src/ztools/infodump.c b/frotz/src/ztools/infodump.c index 2cbc1861..56fca21f 100644 --- a/frotz/src/ztools/infodump.c +++ b/frotz/src/ztools/infodump.c @@ -256,6 +256,17 @@ void print_verbs (const char *name) load_cache (); fix_dictionary (); show_verbs (0); + show_objects (0); + show_header(); + close_story (); +} + +void print_action_table (const char *name) +{ + open_story (name); + configure (V1, V8); + load_cache (); + fix_dictionary (); close_story (); } diff --git a/frotz/src/ztools/txd.c b/frotz/src/ztools/txd.c index 8295ce2b..b2b25a6f 100644 --- a/frotz/src/ztools/txd.c +++ b/frotz/src/ztools/txd.c @@ -194,7 +194,7 @@ extern int optind; extern const char *optarg; #endif -static int option_labels = 1; +static int option_labels = 0; static int option_grammar = 1; static int option_dump = 0; static int option_width = 500; diff --git a/jericho/defines.py b/jericho/defines.py index 52dcd4b8..0a80cb23 100644 --- a/jericho/defines.py +++ b/jericho/defines.py @@ -45,7 +45,9 @@ r".*What do you want to examine?.*", r".*You can't see any such thing.*", r".*That's not something you need to refer to in the course of this game.*", - r".*You can't use multiple objects with that verb.*" + r".*You can't use multiple objects with that verb.*", + r".*I only understood you as far as wanting to .*", + r".*Which do you mean, .*", ] #: List of regular expressions meant to capture game responses that indicate the diff --git a/jericho/game_info.py b/jericho/game_info.py index 92b207ee..683a6110 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -38,7 +38,7 @@ "rom": "adventureland.z5", "seed": 4, # Walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip - "walkthrough": 'E/N/GET AXE/D/GET OX/BUNYON/SWIM/S/W/W/GET OX/GET AXE/GET FRUIT/E/CLIMB TREE/GET KEYS/D/CHOP TREE/DROP AXE/GO STUMP/DROP FRUIT/DROP OX/GET LAMP/GET BOTTLE/D/GET RUBIES/U/DROP RUBIES/D/D/UNLOCK DOOR with keys/DROP KEYS/open door/D/LIGHT LAMP/D/S/GET BLADDER/N/D/D/GET FLINT/W/N/GET RUG/D/GET NET/U/U/AWAY/turn off LAMP/S/DROP FLINT/DROP BLADDER/take mud/N/E/GET FISH/S/W/GO STUMP/DROP FISH/DROP NET/U/GET FLINT/GET BLADDER/GET GAS/GO STUMP/DROP MUD/D/D/D/LIGHT LAMP/D/S/U/DROP BLADDER/LIGHT GAS/GO LEDGE/JUMP/say boo/GET MIRROR/E/GET CROWN/W/JUMP/W/D/N/U/U/U/U/DROP CROWN/D/D/D/D/S/U/GET BRICKS/D/N/D/D/W/N/D/throw bricks/GET FIRESTONE/U/U/AWAY/turn off lamp/E/W/S/GO STUMP/DROP FIRESTONE/DROP RUG/DROP MIRROR/GET MUD/D/D/D/LIGHT LAMP/D/N/GET HONEY/DRINK WATER/GET BEES/S/U/U/U/U/U/N/e/take water/w/take mud/go stump/d/d/d/d/n/drink water/get bees/s/u/u/u/u/drop bottle/take bottle/n/take mud/n/DROP BEES/GET EGGS/S/get oil/GO STUMP/DROP EGGS/DROP HONEY/turn off lamp/rub lamp/rub lamp', + "walkthrough": 'E/N/GET AXE/D/GET OX/BUNYON/SWIM/W/W/GET OX/GET AXE/GET FRUIT/E/CLIMB TREE/GET KEYS/D/CHOP TREE/DROP AXE/GO STUMP/DROP FRUIT/DROP OX/GET LAMP/GET BOTTLE/D/GET RUBIES/U/DROP RUBIES/D/D/UNLOCK DOOR with keys/DROP KEYS/open door/D/LIGHT LAMP/D/S/GET BLADDER/N/D/D/GET FLINT/W/N/GET RUG/D/GET NET/U/U/AWAY/turn off LAMP/S/DROP FLINT/DROP BLADDER/take mud/N/E/GET FISH/W/GO STUMP/DROP FISH/DROP NET/U/GET FLINT/GET BLADDER/GET GAS/GO STUMP/DROP MUD/D/D/D/LIGHT LAMP/D/S/U/DROP BLADDER/LIGHT GAS/GO LEDGE/JUMP/say boo/GET MIRROR/E/GET CROWN/W/JUMP/W/D/N/U/U/U/U/DROP CROWN/D/D/D/D/S/U/GET BRICKS/D/N/D/D/W/N/D/throw bricks/GET FIRESTONE/U/U/AWAY/turn off lamp/E/W/GO STUMP/DROP FIRESTONE/DROP RUG/DROP MIRROR/GET MUD/D/D/D/LIGHT LAMP/D/N/GET HONEY/DRINK WATER/GET BEES/S/U/U/U/U/U/N/e/take water/w/take mud/go stump/d/d/d/d/n/drink water/get bees/s/u/u/u/u/drop bottle/take bottle/n/take mud/n/DROP BEES/GET EGGS/S/get oil/GO STUMP/DROP EGGS/DROP HONEY/turn off lamp/rub lamp/rub lamp', "minimal_actions": 'Light gas/Swim/Get bees/Drop firestone/Get crown/Get net/Drop fruit/Get mirror/Get lamp/Lamp off/Drop bladder/Get bottle/Get ox/Open door/Go west/Go north/Get rubies/Rub lamp/Drop keys/Go south/Drop net/Drop mirror/Go down/Drop rug/Drop bricks/Get eggs/Get flint/go down/Get bladder/Go hole/Cut tree/Get gas/Go hallway/Yell/Jump/Climb tree/Drop mud/Drink water/Catch fish/Get bricks/Get axe/Drop bees/Drop ox/Get mud/Drop honey/Drop fish/Get firestone/Drop bottle/Go up/Bunyon/get bottle/Light lamp/Get fruit/Get honey/Drop axe/Drop eggs/Drop flint/Get keys/Go east/Go throne/Away/Drop crown/Get rug/Drop rubies', "grammar" : "awake/awaken/wake;awake/awaken/wake up;away;bother/curses/darn/drat;brief/normal;bunyon;carry/get/hold/take inventory;carry/get/hold/take off;carry/get/hold/take out;close/cover/shut up;damn/fuck/shit/sod;die/q/quit;dive/swim;exit/out/outside/stand;full/fullscore;full/fullscore score;go/leave/run/walk;hear/listen;help;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;l/look;long/verbose;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;pray;restart;restore;save;score;script;script off;script on;short/superbrie;sing;smell/sniff;sorry;stand/carry/get/hold/take up;think;tsurris;verify;version;wait/z;wave;y/yes;adjust/set OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;carry/get/hold/take OBJ;carry/get/hold/take off OBJ;chop/cut/prune/slice OBJ;chop/cut/prune/slice down OBJ;chop/cut/prune/slice up OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale over OBJ;climb/scale up OBJ;close/cover/shut OBJ;cross/enter/go/leave/run/walk OBJ;damn/fuck/shit/sod OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;find OBJ;go/leave/run/walk through OBJ;go/leave/run/walk/carry/get/hold/take into OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;l/look at OBJ;l/look in OBJ;l/look inside OBJ;l/look into OBJ;l/look through OBJ;l/look under OBJ;lie/sit/go/leave/run/walk inside OBJ;lie/sit/go/leave/run/walk/carry/get/hold/take in OBJ;lie/sit/stand/carry/get/hold/take on OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;put OBJ down;put down OBJ;put on OBJ;read/check/describe/examine/watch/x OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;smell/sniff OBJ;squash/squeeze OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;wave OBJ;adjust/set OBJ to OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/get/hold/take OBJ off OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;dig OBJ with OBJ;discard/drop/throw OBJ against OBJ;discard/drop/throw OBJ at OBJ;discard/drop/throw OBJ down OBJ;discard/drop/throw/insert/put OBJ in OBJ;discard/drop/throw/insert/put OBJ into OBJ;discard/drop/throw/put OBJ on OBJ;discard/drop/throw/put OBJ onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ into OBJ;empty OBJ on OBJ;empty OBJ onto OBJ;empty OBJ to OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;lock OBJ with OBJ;put OBJ inside OBJ;remove/carry/get/hold/take OBJ from OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 @@ -67,7 +67,7 @@ "name": "anchor", "rom": "anchor.z8", "seed": 0, - "walkthrough": 'Se/Push can against wall/Climb can/Up/West/Push play/East/Look up Verlac/West/Unlock Door/West/West/West/NW/West/Read book/Show keys to Michael/East/SE/East/South/South/East/South/SW/NW/Unlock door/North/Close door/Lock door/Up/North/Undress/Drop all/West/Bathe/East/Lie in bed/Sleep/Look/wait/wait/Get wallet/Open wallet/Get card/Leave bed/Dress/Get all/Wear coat/South/Down/West/Open cupboard/Pull lining/Read journal/North/Get flashlight/Open Cabinet/Get matches/Turn on flashlight/NW/Get broom/Unlock door/Down/South/Search crates/Get box/Drop cardboardbox/Wipe web/Drop broom/Get key/Put key on keyring/North/Up/SE/East/East/Look at paintings/Look at scene/South/Get album/Look up Wilhelm in album/Look up Eustacia in album/Look up Croseus in album/West/Up/East/North/Get volume/Look at bookshelf/Get Poe/Examine safe/turn dial to 47/turn dial to 11/ turn dial to 3/Look in safe/Get puzzle box and flute/South/South/Open jewelry box/Get silver locket/Push bed/Look in hole/Get pages/Read pages/North/West/Down/North/West/Unlock door/North/NW/Unlock crypt/Down/Examine coffin/Look up William on nameplate/Open William coffin/Get skull/Up/SE/South/Close door/Lock door/East/South/Unlock door/South/SE/NE/North/West/Get newspaper/Read newspaper/South/South/SE/Look up Edward in record/Look up Mordecai in record/Look up Elijah inrecord/Look up Heinrich in record/Look up Wilhelm in record/NW/SW/Look up Edward in record/Look up Mordecai in Record/Look up Elijah inrecord/Look up Heinrich in record/ Look up Wilhelm in record/NE/North/North/North/North/West/NW/West/North/Ring bell/Show card to librarian/Ask librarian for book/Open Historical/Get slip of paper/Read slip of paper/Drop historical/South/East/SE/East/North/Get Lantern/South/Look under table/Get flask/South/NW/Read wall/West/South/Look in displaycase/Ask proprietor about amulet/Give puzzle box to proprietor/Get puzzle box/North/East/SW/South/South/East/East/Give flask to bum/Ask bum about himself/Ask bum about brother/Ask bum about Anna/Ask bum about crypt/Tell bum about skull/Show skull to bum/Give amulet to bum/Put copper key on keyring/SE/Get tin/NW/West/South/SW/NW/North/ Close door/Up/East/North/East/Get letter opener/Look at screen/Remove ring/Look at ring/Wear ring/Type 0628 on laptop/Look at screen/West/South/Pull cord/Up/Push newspaper under door/Put letter opener in keyhole/Get newspaper/Get brass key/Put brass key on keyring/Unlock door/North/Search straw/Get gold locket/South/Down/West/North/West/Get towel/East/Undress/Drop all/Lie in bed/Sleep/sleep/sleep/sleep/Leave bed/Dress/Wear coat/Get all/South/East/North/East/Look at fireplace/Turn sphere/SW/West/Look in hole/East/Look in hole/NW/Look in hole/SW/SE/Put lens in telescope/Look in telescope/SE/East/Down/West/Down/North/West/NW/Down/East/Search wine rack/Turn c/Turn w/Turn h/Turn e/Turn m/North/North/North/NE/Down/Say ialdabaoloth/North/South/Up/SW/NW/East/Down/West/Down/South/SE/NE/South/South/Look at woods/West/SW/West/Get drawing paper/Get Hook/South/Lift plywood cover/Down/Search bones/Get Teddy/Up/North/East/South/Down/Hide under bones/Wait/Up/Up/North/East/NE/East/North/East/SE/Break padlock with hook/Down/Look at shape/Search shape/Put steel key on keyring/Look at furnace/Open hatch/West/ Put all in pocket/Jump onto riser/North/Get cloth/East/Read huge tome/East/Up/Up/Get rope/Down/West/West/South/Drop robe in shaft/Tie rope to railing/Down/Drop rope/Light flashlight/Get robe/get lantern/NW/North/North/Open tin/Put oil on hatch/Open hatch/Up/East/West/NW/East/Unlock drawer/Open drawer/Get all from drawer/Read letter/Put bronze key on keyring/West/West/West/North/West/North/Knock on door 11/Give teddy to woman/Look in overalls/Get long steel key/Put long steel key on keyring/West/South/South/Search thicket/Unlock hatch/get lantern/North/Light match/Light lantern/Put towel on valve/Turn wheel/North/North/Open hatch/Wait/Wait/North/Tie chain to me/Look at controls/Pull lever/Untie chain/North/Read notes/Get caliper/Get memo/Get Blueprint/Read blueprint/Get mirror 1/Put mirror 1 in caliper/Open tin/Rub oil on mirror 1/South/Down/Jump off equipment/South/South/South/South/NE/East/East/NE/East/Up/Down/wait/wait/Break door/Break door/Get glass/Look at window pane/Put glass in crack/Cut jacket with glass/Open closet/Wear coat/Get all from closet/South/South/Unlock west door/Open west door/West/Look in tear/Get torn square/Read torn square/Get needle/East/South/South/Down/Get lantern/Light match/Light lantern/North/North/Get magazine/Give magazine to madman/Get large key/Put large key on keyring/Unlock gate/North/North/North/Remove coat/Wear robe/East/Wait/wait/wait/wait/wait/Look/Put all in pocket/Get amulet/North/Give gold locket to creature/Hit creature with hook/North/West/North/East/NE/Unlock door/Open door/East/Up/Look at device/Get real mirror/put all in pocket/Wait/Give mirror 1 to Michael/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Pick cuffs with needle/Free boy/West/SW/SW/West/West/North/Wait/South/East/South/East/South/South/Touch obelisk/Show ring to Michael/Show amulet to Michael/cover hole 3/cover hole 6/Play flute/wait/wait/Go north/Get test/Look at little window', + "walkthrough": 'Se/Push can against wall/Climb can/Up/West/Push play/East/Look up Verlac/West/Unlock Door/West/West/West/NW/West/Read book/Show keys to Michael/East/SE/East/South/South/East/South/SW/NW/Unlock door/North/Close door/Lock door/Up/North/Undress/Drop all/West/Bathe/East/Lie in bed/Sleep/Look/wait/wait/Get wallet/Open wallet/Get card/Leave bed/Dress/Get all/Wear coat/South/Down/West/Open cupboard/Pull lining/Read journal/North/Get flashlight/Open Cabinet/Get matches/Turn on flashlight/NW/Get broom/Unlock door/Down/South/Search crates/Get box/Drop cardboardbox/Wipe web/Drop broom/Get key/Put key on keyring/North/Up/SE/East/East/Look at paintings/Look at scene/South/Get album/Look up Wilhelm in album/Look up Eustacia in album/Look up Croseus in album/West/Up/East/North/Get volume/Look at bookshelf/Get Poe/Examine safe/turn dial to 47/turn dial to 11/turn dial to 3/Look in safe/Get puzzle box and flute/South/South/Open jewelry box/Get silver locket/Push bed/Look in hole/Get pages/Read pages/North/West/Down/North/West/Unlock door/North/NW/Unlock crypt/Down/Examine coffin/Look up William on nameplate/Open William coffin/Get skull/Up/SE/South/Close door/Lock door/East/South/Unlock door/South/SE/NE/North/West/Get newspaper/Read newspaper/South/South/SE/Look up Edward in record/Look up Mordecai in record/Look up Elijah inrecord/Look up Heinrich in record/Look up Wilhelm in record/NW/SW/Look up Edward in record/Look up Mordecai in Record/Look up Elijah inrecord/Look up Heinrich in record/Look up Wilhelm in record/NE/North/North/North/North/West/NW/West/North/Ring bell/Show card to librarian/Ask librarian for book/Open Historical/Get slip of paper/Read slip of paper/Drop historical/South/East/SE/East/North/Get Lantern/South/Look under table/Get flask/South/NW/Read wall/West/South/Look in displaycase/Ask proprietor about amulet/Give puzzle box to proprietor/Get puzzle box/North/East/SW/South/South/East/East/Give flask to bum/Ask bum about himself/Ask bum about brother/Ask bum about Anna/Ask bum about crypt/Tell bum about skull/Show skull to bum/Give amulet to bum/Put copper key on keyring/SE/Get tin/NW/West/South/SW/NW/North/Close door/Up/East/North/East/Get letter opener/Look at screen/Remove ring/Look at ring/Wear ring/Type 0628 on laptop/Look at screen/West/South/Pull cord/Up/Push newspaper under door/Put letter opener in keyhole/Get newspaper/Get brass key/Put brass key on keyring/Unlock door/North/Search straw/Get gold locket/South/Down/West/North/West/Get towel/East/Undress/Drop all/Lie in bed/Sleep/sleep/sleep/sleep/Leave bed/Dress/Wear coat/Get all/South/East/North/East/Look at fireplace/Turn sphere/SW/West/Look in hole/East/Look in hole/NW/Look in hole/SW/SE/Put lens in telescope/Look in telescope/SE/East/Down/West/Down/North/West/NW/Down/East/Search wine rack/Turn c/Turn w/Turn h/Turn e/Turn m/North/North/North/NE/Down/Say ialdabaoloth/North/South/Up/SW/NW/East/Down/West/Down/South/SE/NE/South/South/Look at woods/West/SW/West/Get drawing paper/Get Hook/South/Lift plywood cover/Down/Search bones/Get Teddy/Up/North/East/South/Down/Hide under bones/Wait/Up/Up/North/East/NE/East/North/East/SE/Break padlock with hook/Down/Look at shape/Search shape/Put steel key on keyring/Look at furnace/Open hatch/West/Put all in pocket/Jump onto riser/North/Get cloth/East/Read huge tome/East/Up/Up/Get rope/Down/West/West/South/Drop robe in shaft/Tie rope to railing/Down/Drop rope/Light flashlight/Get robe/get lantern/NW/North/North/Open tin/Put oil on hatch/Open hatch/Up/East/West/NW/East/Unlock drawer/Open drawer/Get all from drawer/Read letter/Put bronze key on keyring/West/West/West/North/West/North/Knock on door 11/Give teddy to woman/Look in overalls/Get long steel key/Put long steel key on keyring/West/South/South/Search thicket/Unlock hatch/get lantern/North/Light match/Light lantern/Put towel on valve/Turn wheel/North/North/Open hatch/Wait/Wait/North/Tie chain to me/Look at controls/Pull lever/Untie chain/North/Read notes/Get caliper/Get memo/Get Blueprint/Read blueprint/Get mirror 1/Put mirror 1 in caliper/Open tin/Rub oil on mirror 1/South/Down/Jump off equipment/South/South/South/South/NE/East/East/NE/East/Up/Down/wait/wait/Break door/Break door/Get glass/Look at window pane/Put glass in crack/Cut jacket with glass/Open closet/Wear coat/Get all from closet/South/South/Unlock west door/Open west door/West/Look in tear/Get torn square/Read torn square/Get needle/East/South/South/Down/Get lantern/Light match/Light lantern/North/North/Get magazine/Give magazine to madman/Get large key/Put large key on keyring/Unlock gate/North/North/North/Remove coat/Wear robe/East/Wait/wait/wait/wait/wait/Look/Put all in pocket/Get amulet/North/Give gold locket to creature/Hit creature with hook/North/West/North/East/NE/Unlock door/Open door/East/Up/Look at device/Get real mirror/put all in pocket/Wait/Give mirror 1 to Michael/look/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Pick cuffs with needle/Free boy/West/SW/SW/West/West/North/Wait/South/East/South/East/South/South/Touch obelisk/Show ring to Michael/Show amulet to Michael/cover hole 3/cover hole 6/Play flute/wait/wait/Go north/Get test/Look at little window', "grammar" : "about/author/credit/credits/help/hint/hints/menu;awake/awaken/wake;awake/awaken/wake up;bathe/shower;bother/curses/darn/drat;brief/normal;chant/sing;crawl/go/run/walk to bed;crawl/go/run/walk to sleep;cry/scream/shout/shriek/yell;damn/fuck/shit/sod;describe off;describe on;die/q/quit;dive/swim;doze/nap/sleep;dress;exit/out/outside;fall asleep;fool/mess/play around;full/fullscore;full/fullscore score;get dressed;get out/off/down;get out/off/up;get undressed;hear/listen;hello/hi;hide;hop/jump/leap/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;ialdabaol;in/inside/cross/enter;l/look;l/look around;leave/crawl/go/run/walk;lie/sit;lie/sit down;long/verbose;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;play;pray;remember/think;restart;restore/resume;save;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie;smell/sniff;sorry;speak;speak/answer/say ialdabaol;stand;stand/get up;swing;take inventory/inv/i;undress;verify;version;wait/z;wave;y/yes;adjust/set OBJ;ask for OBJ;attack/break/crack/destroy/fight/hit/kick/kill/murder/punch/scratch/smash/strike/swat/thump/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;bend/straighte OBJ;bite/chew/devour/eat OBJ;blow/breathe OBJ;blow/breathe OBJ up;blow/breathe in/into OBJ;blow/breathe out/on OBJ;blow/breathe up OBJ;blow/breathe/lay/place/put/stick OBJ out;bother/curses/darn/drat OBJ;burn/ignite/light OBJ;bury OBJ;buy/purchase OBJ;call/dial/phone/telephone OBJ;check/examine/inspect/watch/x OBJ;chop/cut/prune/rip/slice/tear OBJ;chuck/discard/drop/throw/toss OBJ;clean/dust/polish/rub/scrub/shine/smear/sweep/wipe OBJ;clear/move/press/push/rock/roll/shift/shove/slide OBJ;climb/scale OBJ;climb/scale down/up/over/on/onto OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;crawl/go/run/walk around/to/by/toward/towards/near/behind OBJ;crawl/go/run/walk close/closer to OBJ;crawl/go/run/walk down/up OBJ;crawl/go/run/walk into/in/inside/through/under OBJ;crease/fold/unfold OBJ;cross/enter/crawl/go/run/walk OBJ;damn/fuck/shit/sod OBJ;dangle/hang from/off/on OBJ;dangle/hang on to OBJ;dig OBJ;dig in OBJ;disrobe/doff/shed/remove OBJ;dive/swim/climb/scale in/into OBJ;don/wear OBJ;drag/haul/pull/yank OBJ;drag/haul/pull/yank on OBJ;draw/have OBJ;drink/gulp/imbibe/sip/swallow OBJ;dump/pour/spill OBJ;dump/pour/spill OBJ out;dump/pour/spill out OBJ;embrace/hug/kiss/smooch OBJ;empty OBJ out;empty out OBJ;exit/out/outside/leave OBJ;extinguis/snuff OBJ;feel/fondle/grope/touch/taste OBJ;find OBJ;flip/switch OBJ;flip/switch/rotate/screw/spin/turn/twist/unscrew OBJ off;flip/switch/rotate/screw/spin/turn/twist/unscrew OBJ on;flip/switch/rotate/screw/spin/turn/twist/unscrew on OBJ;flip/switch/rotate/screw/spin/turn/twist/unscrew/close/cover/shut off OBJ;fool/mess OBJ;fool/mess/play around with OBJ;fool/mess/play with OBJ;free/loosen/untie OBJ;get down from OBJ;get in/into/inside OBJ;get off OBJ;get off of OBJ;get on/onto OBJ;get under OBJ;get up from OBJ;get/carry/catch/grab/hold/hook/snag/take OBJ;grip/squash/squeeze OBJ;grip/squash/squeeze/leave through OBJ;hear/listen OBJ;hear/listen to OBJ;hello/hi OBJ;hide in/among/under/behind/inside OBJ;hop/jump/leap/skip in/on/onto/to/into OBJ;hop/jump/leap/skip off OBJ;hop/jump/leap/skip over OBJ;hop/jump/leap/skip/get out of OBJ;jiggle/rattle/shake OBJ;jimmy/pick lock with OBJ;knock/rap on/at OBJ;l/look at OBJ;l/look behind OBJ;l/look inside/in/into/through/on/out OBJ;l/look under OBJ;l/look up/for OBJ;latch/lock OBJ;lay/place/put/stick OBJ down;lay/place/put/stick OBJ on;lay/place/put/stick down OBJ;lay/place/put/stick finger/fingers on/over/in OBJ;lay/place/put/stick on OBJ;lay/place/put/stick out OBJ;lean on/against OBJ;let go of OBJ;lie/sit down in/on OBJ;lie/sit down on/at OBJ;lie/sit in/inside OBJ;lie/sit on/at OBJ;lift/raise OBJ;lift/raise/take finger/fingers from/off OBJ;lift/raise/take finger/fingers off of OBJ;lower OBJ;measure OBJ;open/uncover/unwrap OBJ;pack OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;play OBJ;play on OBJ;pray to OBJ;read OBJ;read about OBJ;remember/think OBJ;remember/think about OBJ;remove finger/fingers from OBJ;ring OBJ;rotate/screw/spin/turn/twist/unscrew OBJ;search OBJ;search for OBJ;set OBJ down;set down OBJ;set fire to OBJ;smell/sniff OBJ;stand on OBJ;swing OBJ;swing on OBJ;take OBJ off;take off OBJ;trip OBJ;type OBJ;unlock OBJ;unpack/empty OBJ;wave OBJ;wave at/to OBJ;affix/attach/fasten/fix/tie OBJ to/on/onto OBJ;answer/say OBJ to OBJ;ask OBJ for OBJ;attack/break/crack/destroy/fight/hit/kick/kill/murder/punch/scratch/smash/strike/swat/thump/wreck OBJ with OBJ;burn/ignite/light OBJ with OBJ;bury OBJ in/under OBJ;chop/cut/prune/rip/slice/tear OBJ with OBJ;chuck/discard/drop/throw/toss OBJ at/against/on/onto OBJ;chuck/discard/drop/throw/toss OBJ in/into/down OBJ;chuck/discard/drop/throw/toss/lay/place/put/stick OBJ on/onto OBJ;clean/dust/polish/rub/scrub/shine/smear/sweep/wipe OBJ on/onto OBJ;clean/dust/polish/rub/scrub/shine/smear/sweep/wipe OBJ with OBJ;clear/move/press/push/rock/roll/shift/shove/slide OBJ to/under/underneat/beneath/against/by/near OBJ;clear/move/press/push/rock/roll/shift/shove/slide OBJ with OBJ;clear/move/press/push/rock/roll/shift/shove/slide/drag/haul/pull/yank/lay/place/put/stick OBJ close/closer to OBJ;consult OBJ about OBJ;consult OBJ on OBJ;dig OBJ with OBJ;dig in OBJ with OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;drag/haul/pull/yank/lay/place/put/stick OBJ under/underneat/beneath OBJ;dump/pour/spill OBJ into/in/onto/on/over OBJ;feed/give/hand/offer/pay OBJ OBJ;feed/give/hand/offer/pay OBJ to OBJ;feed/give/hand/offer/pay over OBJ to OBJ;fill OBJ with OBJ;get/carry/catch/grab/hold/hook/snag/take OBJ with OBJ;hide OBJ in/under OBJ;insert OBJ in/into OBJ;jimmy/pick OBJ with OBJ;latch/lock OBJ with OBJ;lay/place/put/stick OBJ in/inside/into OBJ;lay/place/put/stick OBJ in/into/inside/between OBJ;lay/place/put/stick OBJ on/onto/across/over OBJ;measure OBJ with OBJ;rotate/screw/spin/turn/twist/unscrew/adjust/set OBJ to OBJ;set OBJ on OBJ;set OBJ on/across/over OBJ;set fire to OBJ with OBJ;speak OBJ to OBJ;unlock/open/uncover/unwrap OBJ with OBJ;unpack/remove/get/take OBJ from/off OBJ;wave OBJ at OBJ;", "max_word_length" : 9 } @@ -76,7 +76,7 @@ "name": "awaken", "rom": "awaken.z5", "seed": 0, - "walkthrough": 'u/take limb/e/se/n/hit dog/nw/n/e/s/n/push railing/take section/n/n/n/read book/take book/n/search desk/take stopper/take ash/put ash on journal/read journal/move bookshelf/take old book/read old book/take robe/s/s/s/put ladder under trap/climb ladder/climb rope/tie rope to branch/d/tie rope to handle/d/take ladder/s/s/put ladder under tree/climb ladder/n/push bell/s/d/get ladder/n/n/put ladder under trap/climb ladder/n/take lantern/n/take green bottle/open green bottle', + "walkthrough": 'u/take limb/e/se/n/hit dog/nw/n/e/s/n/push railing/take section/n/n/n/read book/take book/n/search desk/take stopper/take ash/put ash on journal/read journal/move bookshelf/take old book/read old book/take robe/s/s/s/put ladder under trap/climb ladder/climb rope/d/tie rope to handle/d/take ladder/s/s/put ladder under tree/climb ladder/n/push bell/s/d/get ladder/n/n/put ladder under trap/climb ladder/n/take lantern/n/take green bottle/open green bottle', "grammar" : "about/help;awake/awaken/wake;awake/awaken/wake up;bother/curses/darn/drat;brief/normal;carry/hold/take inventory;clue/clues/hint/hints;clue/clues/hint/hints off;damn/fuck/shit/sod;die/q/quit;dive/swim;exit/out/outside/stand;full/fullscore;full/fullscore score;get out/off/up;hear/listen;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;l/look;leave/go/run/walk;long/verbose;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;pray;restart;restore;save;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie;sing;smell/sniff;sorry;stand up;think;verify;version;wait/z;wave;xyzzy;y/yes;adjust/set OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kick/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;carry/hold/take off OBJ;check/describe/examine/watch/x OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;cross/enter/go/run/walk OBJ;damn/fuck/shit/sod OBJ;detach/untie OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/pet/touch OBJ;fill OBJ;get in/into/on/onto OBJ;get off OBJ;get/carry/hold/take OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;l/look at OBJ;l/look inside/in/into/through OBJ;l/look under OBJ;leave OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;put OBJ down;put down OBJ;put on OBJ;read OBJ;ring OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;smell/sniff OBJ;squash/squeeze OBJ;stand on OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;wave OBJ;adjust/set OBJ to OBJ;answer/say/shout/speak OBJ to OBJ;ask OBJ about OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/hold/take OBJ off OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ on OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ with OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;consult OBJ about OBJ;consult OBJ on OBJ;detach/untie OBJ from OBJ;dig OBJ with OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ to/into/on/onto OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;put OBJ in/inside/into OBJ;put OBJ under/below/beneath/against OBJ;read OBJ in OBJ;read about OBJ in OBJ;remove/get/carry/hold/take OBJ from OBJ;tell OBJ about OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } @@ -85,7 +85,7 @@ "name": "balances", "rom": "balances.z5", "seed": 0, - "walkthrough": 'search furniture/learn rezrov/rezrov box/get grimoire from box/examine grimoire/out/north/search oats/examine shiny scroll/gnusto shiny scroll/learn bozbar/bozbar horse/mount horse/north/learn yomin/yomin tortoise/learn bozbar/bozbar tortoise/get chewed scroll/northwest/take sapphire/examine sapphire/examine book/caskly chewed scroll/gnusto scroll/n/take carpet/s/learn rezrov/rezrov door/w/learn frotz/frotz coin/take cube/write cave on cube/take crumpled/gnusto crumpled/take gold coin from right pan/take bronze coin from left pan/put gold coin on right/put silver coin on left/e/se/s/learn urbzig/urbzig snake/take cube/write chasm on featureless cube/drop carpet/sit on carpet/stand/sit on carpet/stand/take carpet/e/listen/learn lobal/lobal me/listen/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/take feather/w/nw/w/take silver/put bronze on left/put feather on left/e/se/drop carpet/sit on carpet/stand/take carpet/learn yomin/drop carpet/sit on carpet/learn yomin/learn yomin/learn yomin/stand/sit on carpet/stand/give silver to barker/yomin barker/take ticket 2306/yomin barker/take ticket 5802/give ticket 2306 to barker/give ticket 5802 to barker/write prize on featureless/sit on carpet/stand/take carpet/learn urbzig/learn lleps/lleps urbzig/drop toy/urbzig toy/learn urbzig/urbzig mace/take cube/write mace on featureless/e/learn frotz/frotz temple/clean podium/put chasm cube in bottom left socket/put cave cube in bottom right socket/put prize cube in top left socket/put mace cube in top right socket', + "walkthrough": 'search furniture/learn rezrov/rezrov box/get grimoire from box/examine grimoire/out/north/search oats/examine shiny scroll/gnusto shiny scroll/learn bozbar/bozbar horse/mount horse/north/learn yomin/yomin tortoise/learn bozbar/bozbar tortoise/get chewed scroll/northwest/take sapphire/examine sapphire/examine book/caskly chewed scroll/gnusto scroll/n/take carpet/s/learn rezrov/rezrov door/w/learn frotz/frotz coin/take cube/write cave on cube/take crumpled/gnusto crumpled/take gold coin from right pan/take bronze coin from left pan/put gold coin on right/put silver coin on left/e/se/s/learn urbzig/urbzig snake/take cube/write chasm on featureless cube/drop carpet/sit on carpet/stand/sit on carpet/stand/take carpet/e/listen/learn lobal/lobal me/listen/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/take feather/w/nw/w/take silver/put bronze on left/put feather on left/e/se/drop carpet/sit on carpet/stand/take carpet/drop carpet/sit on carpet/learn yomin/learn yomin/learn yomin/stand/sit on carpet/stand/give silver to barker/yomin barker/take ticket 2306/yomin barker/take ticket 5802/give ticket 2306 to barker/give ticket 5802 to barker/write prize on featureless/sit on carpet/stand/take carpet/learn urbzig/learn lleps/lleps urbzig/drop toy/urbzig toy/learn urbzig/urbzig mace/take cube/write mace on featureless/e/learn frotz/frotz temple/clean podium/put chasm cube in bottom left socket/put cave cube in bottom right socket/put prize cube in top left socket/put mace cube in top right socket', "grammar" : "awake/awaken/wake;awake/awaken/wake up;bother/curses/darn/drat;brief/normal;c,cast;carry/get/hold/take inventory;carry/get/hold/take out/off/up;close/cover/shut up;damn/fuck/shit/sod;diagnose/health;die/q/quit;dive/swim;exit/out/outside/stand;full/fullscore;full/fullscore score;hear/listen;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;l/look;leave/go/run/walk;long/verbose;memory/spells;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;pray;restart;restore;save;score;script;script off;script on;short/superbrie;sing;smell/sniff;sorry;stand up;think;verify;version;wait/z;wave;y/yes;adjust/set OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;c,cast OBJ;carry/get/hold/take OBJ;carry/get/hold/take in/into/on/onto OBJ;carry/get/hold/take off OBJ;cast OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;cross/enter/go/run/walk OBJ;damn/fuck/shit/sod OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;flip/toss OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;l/look at OBJ;l/look inside/in/into/through OBJ;l/look under OBJ;leave OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;mount/ride/straddle OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;put OBJ down;put down OBJ;put on OBJ;read/check/describe/examine/watch/x OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;smell/sniff OBJ;squash/squeeze OBJ;stand on OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;wave OBJ;adjust/set OBJ to OBJ;answer/say/shout/speak OBJ to OBJ;ask OBJ about OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/get/hold/take OBJ from/off OBJ;cast OBJ at OBJ;cast OBJ on OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;consult OBJ about OBJ;consult OBJ on OBJ;dig OBJ with OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ to/into/on/onto OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;put OBJ in/inside/into OBJ;read OBJ in OBJ;read about OBJ in OBJ;remove OBJ from OBJ;tell OBJ about OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } @@ -104,8 +104,8 @@ "name": "curses", "rom": "curses.z5", "seed": 0, - # Walkthrough adapted from https://ifarchive.org/if-archive/solutions/Curses.step and http://mirror.ifarchive.org/if-archive/solutions/CursesR16.sol - "walkthrough": "drop biscuit, paper/south/get parcel from cupboard/unwrap parcel/north/north/west/south/examine sheets/turn wireless on/push wireless north/west/give box of chocolates to jemima/say yellow/wait/wait/wait/wait/wait/wait/wait/get gloves/wear gloves/east/east/east/get wrench/west/south/south/southeast/east/examine rolls/open torch/empty torch/get new battery/put new battery in torch/close torch/south/take sack/north/open door/north/get all/turn handle/south/west/west/get flash/east/south/west/get wrench/tighten joint/get novel/get poetry/east/north/northwest/get all from cupboard/north/close trapdoor/get jewellery box/open trapdoor/north/open demijohn/get all from demijohn/west/west/east/east/east/turn wheel off/turn wheel/get medicine bottle/put medicine bottle in shaft/turn wheel/enter dumb waiter/get all/pull ropes/out/mouse, south/south/mouse, west/hole, w/hole, w/hole, w/hole, n/hole, w/hole, n/hole, s/hole, e/hole, s/hole, e/hole, e/hole, e/hole, e/get key/north/enter dumb waiter/pull ropes/out/wear gas mask/north/unlock door with brass key/open door/north/remove gas mask/read poetry/west/take handkerchief/wave handkerchief/west/say time/take poetry/northwest/west/west/get bottle/get implement/enter roller/turn roller on/e/e/e/w/n/n/w/w/n/n/n/n/w/w/w/get out/get etching/enter roller/e/e/e/s/s/s/s/s/e/e/s/s/get out/southeast/south/south/enter dumb waiter/pull ropes/out/west/south/south/southeast/east/north/up/northwest/take gothic key/throw wishbone at ghost/southeast/down/put all in fireplace/west/down/get all/unlock hatch with brass key/open hatch/down/east/turn wheel off/turn wheel/enter dumb waiter/pull ropes/pull ropes/out/west/south/south/southeast/south/south/turn projector on/get ace/put ace in projector/south/examine cups/pull anchor/put ship in mounted bottle/examine ship/fore/get branch/aft/up/take flag/port/get flag/get spar/aft/turn wheel/down/get ace/north/north/east/south/push south wall/south/put flag on bed/break windows/south/look under sill/take gold key/north/lie on bed/sleep/east/east/east/turn wheel/pinch me/get up/north/north/west/northwest/north/north/east/enter dumb waiter/pull ropes/pull ropes/out/north/east/east/break frame/unlock jewellery box with gold key/open jewellery box/take sketch/take spar/take clover/wave spar/wave clover/open coffin/put rods in coffin/close lid/open lid/close lid/open lid/get rods from coffin/southeast/get sceptre/up/up/look up 1420 in map/turn door/northeast/push ball southwest/push ball south/get tarot box/east/break cabinet/get all from cabinet/get rod of returning/strike it/wait/wait/eat tablet/get crook/point rod of returning at me/s/se/s/s/get etching/put it in projector/south/e/e/s/s/s/s/e/e/e/e/e/squeeze weed killer bottle/w/w/w/w/w/n/n/n/n/w/w/take bean pole/strike returning/point it at me/read poetry/north/open tarot box/get eight/get star/get maiden/up/put eight on pack/put maiden on pack/put star on pack/push bell/say even/north/up/get all cards/down/south/west/west/say time/south/east/east/get stick/get crook/get staff/wave stick/wave crook/wave staff/put rods in coffin/close lid/open lid/close lid/open lid/close lid/open lid/get all from coffin/west/west/north/northwest/enter roller/n/n/e/e/e/get out/get rose/down/strike rod of bronze/point it at mural/down/get wrought iron key/down/smell/smell/down/turn switch off/up/west/strike rod of bronze/point it at metal/north/slide i/slide k/slide c/slide a/slide n/slide e/slide l/slide o/slide s/slide t/south/slide k/slide k/get rod of returning/strike it/point it at me/se/s/s/get etching/get maiden/put maiden in projector/south/up/east/get fire/get husbandry/get luck/strike rod of husbandry/point it at goats/south/strike rod of fire/point it at thorns/south/strike rod of luck/point it at me/south/get coin/southeast/get stone/southwest/wake homer/say agamemnon/say ptolemy/say yellow/north/northwest/push dionysus southeast/push dionysus southwest/push poseidon northeast/again/push demeter southwest/push demeter northwest/southeast/put stone in opening/down/get amber/up/south/northeast/northwest/north/north/north/east/south/give coin to bartender/get ekmek/north/get fig/west/west/southwest/play syrinx/put fig in urn/oracle, hello/northeast/down/give ekmek to andromeda/wave hairband/get rod of returning/strike it/point it at me/n/get book/s/east/down/down/northeast/east/east/get implement/walk 4 paces west/walk 4 paces south/dig/get box/unlock it with gothic key/open it/west/west/southwest/up/up/w/s/se/s/s//get maiden/get sketch/put sketch in projector/jump/south/north/take stone/put round stone into grating/wait/wait/wait/wait/wait/wait/south/southeast/southwest/blow whistle/take amber/put amber in socket/get cloak/wear it/south/north/northeast/northeast/southeast/south/anoint me/north/southeast/get spindle/northwest/wait/get alpha/get kappa/get epic poem/get short poem/put epic poem in kappa/put short poem in alpha/east/give kappa to callimachus/south/give alpha to apollonius/get sash/north/west/northwest/north/west/get rusty key/east/south/southwest/southwest/down/lie on couch/sleep/lie on couch/sleep/lie on couch/sleep/lie on couch/sleep/z/z/z/z/z/z/z/z/w/get up/w/get up/w/get up/w/get up/twist nose/west/west/north/east/west/take oak/take sceptre/put sceptre in first socket/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/get sceptre/put sceptre in second socket/[ Repeatedly \"turn sceptre\" until the coffin opens ]/turn sceptre/turn sceptre/turn sceptre/turn sceptre/east/east/up/northeast/southeast/remove cloak/turn it/wear it/open door/up/put oak on table/northwest/northwest/north/unlock grating with rusty key/open grating/down/get heart from boat/up/south/southeast/southwest/down/west/west/enter coffin/close lid/again/up/west/west/up/up/enter roller/w/w/w/s/s/get out/east/get orb/west/southeast/south/east/east/get featureless rod/get spindle/put featureless rod in coffin/wave spindle/put it in coffin/get eight of wands/wave it/put it in coffin/get bean pole/wave bean pole/put it in coffin/close lid/open lid/close lid/open lid/close lid/open lid/close lid/open lid/get all from coffin/west/west/north/northwest/east/east/mosaic, lagach/mural, lagach/still life, lagach/north/remove cloak/turn it/wear cloak/northeast/northeast/north/north/remove cloak/wear sash/north/northeast/east/south/anoppe/take astrolabe/put astrolabe in mounting/look through astrolabe/get hand/down/down/west/put skull on statue/turn it/put hand on statue/turn it/put heart in statue/get rod of fire/get rod of ice/strike rod of fire/point it at knight/point east/east/point east/east/give rose to knight/show keepsake to knight/point west/west/knight, open flagstone/point down/strike rod of ice/point it at rod of life/get rod of life/again/south/south/down/northwest/west/west/southeast/south/south/enter dumb waiter/pull ropes/again/out/west/unlock door with wrought iron key/open door/northwest/polish orb/get rod of sacrifice/strike it/point sacrifice at board/get rods from sack/put rods in socket/get rods from sack/put rods in socket/get rods from sack/put rods in socket/get orb/put it in opening/strike rod of infinity/point it at lemniscus/west/down/swing rope/get daisy/wear it/up/east/get torch/northeast/east/south/south/east/wear sandals/west/south/north/west/open cover/put torch in well/down/east/z/z/z/z/z/z/z/z/west/up/z/z/z/z/get pole/east/get stone/wave pole/strike it/point it at me/read poetry/east/down/wave stone/give note to man/say carte/up/west/west/west/say time/get torch/southeast/east/enter dumb waiter/pull ropes/again/out/west/south/down", + # Walkthrough adapted from https://raw.githubusercontent.com/heasm66/walkthroughs/main/curses_walkthrough.txt + "walkthrough": "n/w/s/x sheets/push radio n/turn it on/w/z/z/z/z/z/get gloves/wear gloves/e/e/open demijohn/s/s/se/e/x rolls/get battery/open torch/empty it/put new battery in torch/close torch/s/get rucksack/n/open cupboard/n/get painting/get mask/s/w/nw/n/n/get red battery, map/e/get wrench/enter dumbwaiter/get wishbone/pull rope/get out/get mouse/s/drop mouse/mouse, w/hole, w/hole, w/hole, w/hole, n/hole, w/hole, n/hole, s/hole, e/hole, s/hole, e/hole, e/hole, e/hole, e/get key/n/enter dumbwaiter/pull rope/get out/wear mask/n/unlock door with brass key/open door/s/enter dumbwaiter/pull rope/get out/w/s/x teachest/look inside it/e/lie down/sleep/e/n/get mascot/drop mascot/s/w/sw/e/get up/get all/w/s/get all from cupboard/open parcel/n/n/w/x calendar/turn calendar/turn calendar/turn calendar/turn calendar/turn calendar/turn calendar/turn calendar/turn calendar/w/give chocolate to jemima/remove mask/say yellow/e/e/s/s/se/w/pull cord/x postcard/get flash/open flash/get nasty battery/put nasty battery in flash/close flash/x photograph/read about roger in history book/e/e/n/turn crank/u/nw/get key/give wishbone to ghost/se/d/get brass key/put torch, brass key in fireplace/drop all/enter fireplace/d/get all/unlock hatch with brass key/open hatch/d/e/turn off wheel/turn wheel/enter dumbwaiter/pull rope/pull rope/get out/w/s/s/se/e/n/drop all/get rucksack/get all/s/w/nw/n/n/w/w/e/e/e/turn off wheel/turn wheel/get bottle/drop bottle in shaft/turn wheel/enter dumbwaiter/get tablet/get out/w/s/s/se/d/clean glass ball/w/get wrench/fix pipe/get books/read romance novel/read poetry book/n/u/push bell/say even/n/u/get tarot cards/d/e/x mural/w/s/w/get handkerchief/wave it/board boat/say time/nw/climb tree/x maze/d/w/w/get all/board roller/turn it on/e/e/e/w/n/n/w/w/n/n/n/n/w/w/w/get off/get miniature/board roller/e/e/e/s/s/s/s/e/e/s/s/turn off roller/get off/wear mask/se/s/s/d/turn wheel/enter dumbwaiter/pull rope/pull rope/get out/w/s/s/se/s/s/turn on projector/turn dial/get ace of cups/put it in slot/s/search crates/get bottle/pull anchor/put ship in mounted bottle/x ship/climb mast/get flag/go port/get all/go fore/get branch/go aft/go aft/turn wheel/d/get ace of cups/get fool/put fool in slot/n/n/e/s/e/ne/n/x cross/read about alison in history book/s/sw/w/push s wall/s/lie down/get flag/put flag on bed/sleep/z/e/e/turn wheel/pinch me/get out/get stick/wave stick/break window/s/look under window/get gold key/n/n/n/w/nw/n/close door/get box/open door/unlock box with gold key/open box/get clover/n/e/enter dumbwaiter/pull rope/pull rope/get out/n/e/e/get sketch/break frame/get letter, sketch/open coffin/wait/read inscription/read letter/get rod/put rod in coffin/close coffin/open coffin/get fire/get spar/wave it/put it in coffin/close coffin/open coffin/get returning/get clover/wave it/put it in coffin/close coffin/open coffin/get luck/get scroll/se/get painting/hang it on hook/look in umbrella stand/get sceptre/u/u/read about 1420 in map/turn door/ne/push ball sw/push ball s/get tarot box/open it/e/remove mask/break cabinet/get all from cabinet/get tablet, returning/strike returning/z/z/eat tablet/get crook/point returning at me/s/s/get fool/get miniature/put it in slot/get returning/strike it/s/e/e/e/e/e/s/e/s/e/e/s/s/w/get weed bottle/squeeze it/e/n/n/w/w/n/w/n/w/w/w/w/w/get bean pole/point returning at me/s/s/se/s/w/get book/e/n/nw/n/n/e/turn wheel/enter dumbwaiter/pull rope/pull rope/get out/n/n/nw/board roller/turn on roller/n/n/e/e/e/get off/get rose/d/x mural/read poetry book/get tarot cards from tarot box/n/u/put wands on deck/put maiden on deck/put star on deck/push bell/n/u/get cards/d/s/w/board boat/say time/s/e/e/get quarterstaff/wave it/put it in coffin/close coffin/open it/get bronze/get crook/wave it/put it in coffin/close coffin/open it/get husbandry/get bean pole/wave it/put it in coffin/close coffin/open it/get stalking/get wands/wave it/put it in coffin/close coffin/open it/get infinity/se/painting, lagach/get poetry book/get bronze rod/strike it/point it at mural/d/get key/e/e/read tombstone/w/w/s/smell/smell/d/x switch/turn switch off/u/w/x panel/x bronze wall/strike bronze rod/point it at bronze wall/n/x panel/slide i/slide k/slide c/slide a/slide n/slide e/slide l/slide o/slide s/slide t/s/slide k/slide k/e/u/u/u/board roller/w/w/w/s/s/e/turn off roller/get off/get orb/w/se/s/e/e/se/u/u/w/s/se/s/s/get miniature/get maiden/put it in slot/s/u/e/s/get fire/strike it/point it at wall/get luck/strike it/point it at me/s/s/get coin/se/get stone/x it/sw/wake homer/say agamemnon/say ptolemy/say yellow/north/northwest/push dionysus southeast/push dionysus southwest/push poseidon northeast/push poseidon northeast/push demeter southwest/push demeter northwest/southeast/put inscribed stone in opening/d/get gem/u/u/ne/nw/n/n/n/get husbandry/strike it/point it at goats/e/get fig/s/give coin to bartender/get dessert/n/w/w/d/give dessert to andromeda/u/sw/play syrinx/put fig in urn/priestess, tell me about fig/get returning/strike it/point it at me/s/s/get maiden/get castle/put it in slot/s/look under table/x scarf/pull blue wire/pull green wire/pull black wire/pull red wire/z/z/z/z/strike returning rod/point it at me/se/s/s/get castle/get star/put it in slide/s/d/x frieze/u/get flash/open flash/set timer/put timer in flash/close flash/put flash in device/z/z/z/z/z/z/z/e/e/mosaic, lagach/mural, lagach/mural, lagach/painting, lagach/painting, lagach/u/get rucksack/get all/get returning/strike it/point it at me/s/s/se/s/s/get star/get sketch/put it in slide/n/z/push austin s/jump/s/n/get smooth stone/drop it in grating/s/se/sw/s/x writings/n/blow bird whistle/get cloak/wear it/ne/ne/se/s/anoint me/n/se/get spindle/nw/z/get tubes/look in alpha/look in kappa/get short poem, epic poem/put short poem in alpha/put epic poem in kappa/e/give kappa to callimachus/s/give alpha to apollonius/get all/n/w/nw/n/w/get stone/get key/e/s/sw/nw/n/unlock grating with key/open grating/d/get heart/board skiff/sail/sail/sail/get off/s/e/e/wear gloves/get spindle/wave it/put it in coffin/close coffin/open it/get ice/get hairband/wave it/put it in coffin/close coffin/open it/get sacrifice/se/u/u/w/s/se/e/s/e/ne/d/wave green branch/get nuts/nw/x mosaic/get ball/mosaic, lagach/mural, lagach/painting, lagach/painting, lagach/writings, lagach/ne/e/n/get mallet/s/e/walk 4 paces west/walk 4 paces south/get implement/x it/dig/unlock strongbox with gothic key/open it/get astrolabe/fill hole/get ball/drop it/hit it with mallet/nw/get nuts/put nuts in crack/s/blow bird whistle/get watch/s/w/sw/painting, lagach/frieze, lagach/mosaic, lagach/mural, lagach/mural, lagach/painting, lagach/n/get gem/put gem in socket/d/lie down on couch/sleep/lie down on couch/sleep/lie down on couch/sleep/lie down on couch/sleep/z/z/z/z/z/z/z/z/w/get up/w/get up/w/get up/w/get up/twist nose/w/get model/w/n/get oak/get sceptre/put sceptre in first socket/turn sceptre/turn sceptre/get sceptre/put sceptre in second socket/turn sceptre/get sceptre/put sceptre in third socket/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/turn sceptre/enter coffin/close lid/close lid/u/w/w/u/mural, lagach/mural, lagach/painting, lagach/n/ne/se/remove cloak/turn it/wear it/open door/u/put oak on table/nw/remove cloak/turn it/wear it/ne/n/n/remove cloak/wear sash/n/ne/e/s/anoppe/get astrolabe/put it on mounting/look in eyepiece/get hand/d/d/w/put hand on statue/tighten hand/get skull/put it on statue/tighten it/get heart/put it in statue/get fire/strike it/point it at statue/point e/e/point e/e/get rose/give it to knight/get keepsake/show it to knight/point w/w/knight, open moonstone/point d/get ice/strike it/point it at love/get love/get love/s/get watch/hypnotize evans/evans, give me mascot/s/sw/w/s/get model/look in mirror/n/e/ne/n/get orb/clean it/get sacrifice rod/strike sacrifice rod/point it at black/s/sw/w/n/w/nw/n/n/e/turn wheel/enter dumbwaiter/pull rope/get out/w/get wrought iron key/unlock door with it/open door/nw/put sacrifice rod in socket/get ice/put it in socket/get love/put it in socket/get fire/put it in socket/get returning/put it in socket/get husbandry/put it in socket/get luck/put it in socket/get bronze/put it in socket/get stalking/put it in socket/put orb in opening/get infinity rod/strike it/point it at lemniscus/get torch/w/d/swing rope/get daisy/wear it/u/e/ne/e/s/get horn/s/e/wear sandals/w/s/n/w/open cover/put torch in well/d/e/wave horn/z/w/u/z/z/z/z/get pole/e/get blue stone/wave pole/strike rod/point it at me/get rucksack/get all/read poetry book/e/d/get blue stone/wave it/give note to man/say carte/u/w/w/board boat/say time/se/e/enter dumbwaiter/pull rope/pull rope/get out/w/w/w/kiss her/e/e/s/d", "grammar" : "anoppe/eppona;answer/say/shout/speak;awake/awaken/wake;awake/awaken/wake up;beep/bleep/chirp;bet/gamble/wager;bother/curses/darn/drat;brief/normal;carry/get/hold/take inventory;carry/get/hold/take off;carry/get/hold/take out;close/cover/shut up;damn/fuck/shit/sod;diagnose;die/q/quit;dig;display/present/show off;dive/swim;drink/sip/swallow;exhibit/reveal/sing;exit/out/outside/stand;float/sail;float/sail away;full/fullscore;full/fullscore score;go/leave/run/walk;hear/listen;help;hint/hints;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;l/look;lagach;lie/sit;lie/sit down;long/verbose;make/wish;make/wish a wish;make/wish wish;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;pace;places;plain;play croquet;plover/plugh/xyzzy;pray;pretty;restart;restore;rip/tear;save;score;script;script off;script on;shantih;short/superbrie;smell/sniff;sorry;stand/carry/get/hold/take up;think;time;verify;version;wait/z;wave;y/yes;achetez/buy/purchase OBJ;add/join/mend/repair/attach/fasten/fix/tie OBJ;adjust/set OBJ;anoint/oil OBJ;answer/say/shout/speak lagach to OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;beckon/direct/gesture/point OBJ;beckon/direct/gesture/point at OBJ;bet/gamble/wager with OBJ;board/embark/cross/enter/go/leave/run/walk OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;carry/get/hold/take OBJ;carry/get/hold/take off OBJ;change/flip/switch OBJ;check/describe/examine/watch/x reflectio of OBJ;chop/cut/prune/slice OBJ;climb/scale OBJ;climb/scale over OBJ;climb/scale up OBJ;close/cover/shut OBJ;damn/fuck/shit/sod OBJ;dance/tango/waltz with OBJ;dig OBJ;dig with OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;etch/inscribe/scribe/write OBJ;fill OBJ;frisk OBJ;go/leave/run/walk through OBJ;go/leave/run/walk/carry/get/hold/take into OBJ;hear/listen OBJ;hear/listen to OBJ;help OBJ;hop/jump/skip over OBJ;hypnotise/hypnotize OBJ;kick/attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;knock at OBJ;knock on OBJ;l/look at OBJ;l/look in OBJ;l/look inside OBJ;l/look into OBJ;l/look through OBJ;l/look under OBJ;lie/sit down on OBJ;lie/sit/go/leave/run/walk inside OBJ;lie/sit/go/leave/run/walk/carry/get/hold/take in OBJ;lie/sit/stand/carry/get/hold/take on OBJ;make/wish for OBJ;milk OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pet/stroke/tickle/feel/fondle/grope/touch OBJ;pick OBJ up;pick up OBJ;pinch/slap OBJ;play with OBJ;play/blow OBJ;put OBJ down;put down OBJ;put on OBJ;ram OBJ;read/check/describe/examine/watch/x OBJ;reverse/revolve/tighten/tweak/unwind/wind/wrench/rotate/screw/turn/twist/unscrew OBJ;ring/clear/move/press/push/shift OBJ;rip/tear OBJ;rip/tear down OBJ;roll/shoot/toss OBJ;rotate/screw/turn/twist/unscrew OBJ around;rotate/screw/turn/twist/unscrew OBJ inside out;rotate/screw/turn/twist/unscrew round OBJ;scratch/clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;search OBJ;shantih OBJ;smell/sniff OBJ;squash/squeeze OBJ;stack OBJ;start/stop OBJ;strike OBJ;swing OBJ;swing on OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;wash mouth out with OBJ;wash mouth with OBJ;wash my mouth out with OBJ;wash my mouth with OBJ;wave OBJ;add/join/mend/repair/attach/fasten/fix/tie OBJ to OBJ;adjust/set OBJ to OBJ;ask OBJ for OBJ;beckon/direct/gesture/point OBJ at OBJ;burn/light OBJ with OBJ;carry/get/hold/take OBJ off OBJ;check/describe/examine/watch/x OBJ in OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;close/cover/shut OBJ with OBJ;discard/drop/throw OBJ against OBJ;discard/drop/throw OBJ at OBJ;discard/drop/throw OBJ down OBJ;discard/drop/throw/insert/put OBJ in OBJ;discard/drop/throw/insert/put OBJ into OBJ;discard/drop/throw/put OBJ on OBJ;discard/drop/throw/put OBJ onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ into OBJ;empty OBJ on OBJ;empty OBJ onto OBJ;empty OBJ to OBJ;etch/inscribe/scribe/write OBJ on OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;hang/mount OBJ on OBJ;hang/mount OBJ onto OBJ;hang/mount OBJ up on OBJ;hang/mount OBJ up onto OBJ;hang/mount up OBJ on OBJ;hang/mount up OBJ onto OBJ;hypnotise/hypnotize OBJ with OBJ;lay OBJ on OBJ;lean/prop/rest/support OBJ against OBJ;lean/prop/rest/support OBJ on OBJ;lean/prop/rest/support OBJ with OBJ;lean/prop/rest/support up OBJ with OBJ;lock OBJ with OBJ;put OBJ inside OBJ;remove/carry/get/hold/take OBJ from OBJ;rotate/screw/turn/twist/unscrew OBJ with OBJ;shantih OBJ OBJ;stack OBJ in OBJ;stack OBJ on OBJ;stack OBJ onto OBJ;stack OBJ with OBJ;strike/attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ with OBJ;tighten/tweak/unwind/wind/wrench OBJ with OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } @@ -115,7 +115,7 @@ "rom": "cutthroat.z3", "seed": 10, # walkthrough adapted from https://ifarchive.org/if-archive/solutions/Sols3.zip and http://www.eristic.net/games/infocom/cutthroats.html - "walkthrough": 'look out window/wind watch/get out of bed/read note/open dresser/get passbook and room key/look in closet/i/open door/n/close door/lock door/wait/n/n/e/e/e/e/s/sit/order food/order drink/eat food/drink drink/yes/get out of chair/n/w/w/s/s/w/w/e/e/e/e/ne/s/s/sw/w/w/e/e/wait/n/withdraw $603/s/ne/n/nw/w/w/w/open window/look through window/w/drop passbook/e/e/n/n/w/w/sw/sw/nw/wait/examine plate/se/ne/ne/e/s/n/e/e/s/n/e/s/buy drink/drink drink/n/se/s/s/se/i/wait for johnny/YES/YES/YES/YES/YES/YES/yes/show $500/no/nw/n/n/nw/w/s/wait/wait/look/give $56/buy flashlight and repellent/buy c battery and putty/buy electromagnet/rent compressor/i/n/e/s/sit/order food/order drink/eat food/drink drink/get out of chair/n/se/s/s/sw/w/w/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/e/e/ne/n/n/nw/w/w/s/s/w/wait/look through window/w/e/wait/look through window/open window/enter window/get envelope/n/w/s/s/unlock door/open door/s/read envelope/get all from closet/i/n/close door/lock door/n/n/e/e/s/s/w/w/drop room key/e/e/e/e/ne/nw/s/sit/order drink/drink drink/wait/wait/get off chair/n/w/s/wait/n/w/n/w/s/d/n/n/n/get drill/open panel/get c battery/put c battery in drill/close panel/s/hide envelope under bunk/s/s/s/wait/wait/wait/latitude is 25/longitude is 25/n/u/n/s/drop wet suit/drop flippers/drop mask/drop drill/i/w/n/d/n/get all/examine compressor/examine air tank/fill tank with air/get air tank/s/s/drink water/s/d/u/s/n/n/n/look under bunk/n/s/u/w/s/examine drill/n/wait/get out of bunk/get all/get envelope/s/s/s/show envelope to johnny/n/u/d/n/eat stew/s/u/drop all/get watch/wear watch/get wet suit/wear wet suit/get air tank/wear air tank/get flippers/wear flippers/get mask/wear mask/i/look/get tube/get flashlight/get canister/get drill/get electromagnet/i/look/dive in ocean/open shark repellent/d/turn on flashlight/d/d/d/s/open door/s/put magnet on mine/turn on magnet/drop magnet/u/remove tank/s/s/turn drill on/drill safe with drill/turn drill off/grab case/n/n/wear air tank/d/n/u/examine glass case/examine stamps/turn drill on/drill case with drill/open tube/put glob on case/d/n/u/u/u/u/u', + "walkthrough": 'look out window/wind watch/get out of bed/read note/open dresser/get passbook and room key/look in closet/i/open door/n/close door/lock door/wait/n/n/e/e/e/e/s/sit/order food/order drink/eat food/drink drink/yes/get out of chair/n/w/w/s/s/w/w/e/e/e/e/ne/s/s/sw/w/w/e/e/wait/n/withdraw $603/s/ne/n/nw/w/w/w/open window/look through window/w/drop passbook/e/e/n/n/w/w/sw/sw/nw/wait/examine plate/se/ne/ne/e/s/n/e/e/s/n/e/s/buy drink/drink drink/n/se/s/s/se/i/wait for johnny/YES/YES/YES/YES/YES/YES/yes/show $500/no/nw/n/n/nw/w/s/wait/wait/look/give $56/buy flashlight and repellent/buy c battery and putty/buy electromagnet/rent compressor/n/e/s/sit/order food/order drink/eat food/drink drink/get out of chair/n/se/s/s/sw/w/w/wait/wait/wait/wait/wait/wait/wait/wait/e/e/ne/n/n/nw/w/w/s/s/w/wait/look through window/w/e/wait/look through window/enter window/get envelope/n/w/s/s/unlock door/open door/s/read envelope/get all from closet/i/n/close door/lock door/n/n/e/e/s/s/w/w/drop room key/e/e/e/e/ne/nw/s/sit/order drink/drink drink/wait/wait/get off chair/n/w/s/wait/n/w/n/w/s/d/n/n/n/get drill/open panel/get c battery/put c battery in drill/close panel/s/hide envelope under bunk/s/s/s/wait/wait/wait/latitude is 25/longitude is 25/n/u/n/s/drop wet suit/drop flippers/drop mask/drop drill/i/w/n/d/n/get all/examine compressor/examine air tank/fill tank with air/s/s/s/d/u/s/n/n/n/look under bunk/n/s/u/w/s/examine drill/n/wait/get out of bunk/get all/get envelope/s/s/s/show envelope to johnny/n/u/d/n/eat stew/s/u/drop all/get watch/wear watch/get wet suit/wear wet suit/get air tank/wear air tank/get flippers/wear flippers/get mask/wear mask/i/look/get tube/get flashlight/get canister/get drill/get electromagnet/i/look/dive in ocean/open shark repellent/d/turn on flashlight/d/d/d/s/open door/s/put magnet on mine/turn on magnet/drop magnet/u/remove tank/s/s/turn drill on/drill safe with drill/turn drill off/grab case/n/n/wear air tank/d/n/u/examine glass case/examine stamps/turn drill on/drill case with drill/open tube/put glob on case/d/n/u/u/u/u/u', "grammar" : "affirm/ok/okay/sure/uh-hu/y/yeah/yes/yup;again/g;back;barf/chomp/lose;bathe/swim/wade;breath;brief;bye/goodby;chase/come/follow/pursue;chat/say/speak/talk;curse/cuss/damn/fuck/hell/shit/swear;diagno;disemb/exit;dive;dunno/maybe;enter;gaze/l/look/peer/stare;hello/hi;help;hop/skip;i/invent;jump/leap;leave/withdr;lie/nap/rest/sleep;mumble/sigh;negati/no/nope/uh-uh;pray;progre/rating/score;q/quit;restar;restor;save;scream/shout/yell;script;stand;stay;super/superb;t/time;unscri;verbos;versio;wait/z;what/what'/whats/who/who's/whos;win/winnag;ask/inquir/questi OBJ;ask/inquir/questi about OBJ;ask/inquir/questi for OBJ;awake/startl/surpri/wake OBJ;awake/startl/surpri/wake up OBJ;bathe/swim/wade OBJ;bathe/swim/wade in OBJ;bite/chew/consum/eat/munch/nibble OBJ;blow out OBJ;board OBJ;brandi/wave OBJ;brandi/wave at OBJ;brandi/wave to OBJ;break/chip/chop/damage/destro/hit/smash in OBJ;breath OBJ;buy/order/purcha OBJ;bye/goodby OBJ;call OBJ;call to OBJ;carry/get/grab/hold/remove/take OBJ;carry/get/grab/hold/remove/take off OBJ;carry/get/grab/hold/remove/take out OBJ;cast/chuck/hurl/throw/toss OBJ;chase/come/follow/pursue OBJ;chat/say/speak/talk to OBJ;chat/say/speak/talk with OBJ;check OBJ;check/gaze/l/look/peer/stare/search for OBJ;clean/polish/scrub OBJ;climb OBJ;climb down OBJ;climb out OBJ;climb throug OBJ;climb up OBJ;climb/carry/get/grab/hold/remove/take in OBJ;climb/carry/get/grab/hold/remove/take on OBJ;close/shut OBJ;count OBJ;cross/ford OBJ;curse/cuss/damn/fuck/hell/shit/swear OBJ;deflat OBJ;deposi OBJ;descri/examin OBJ;detach/discon/free/unfast/unhook/untie OBJ;disemb OBJ;dive in OBJ;douse/exting OBJ;drink/guzzle/imbibe/sip/swallo OBJ;drop/releas OBJ;empty OBJ;enter OBJ;exit OBJ;feel/pat/pet/rub/touch OBJ;fill OBJ;find/see/seek/where OBJ;flip/set/turn OBJ;flip/set/turn off OBJ;flip/set/turn on OBJ;flip/set/turn over OBJ;fold OBJ;fold up OBJ;gaze/l/look/peer/stare OBJ;gaze/l/look/peer/stare around OBJ;gaze/l/look/peer/stare at OBJ;gaze/l/look/peer/stare behind OBJ;gaze/l/look/peer/stare in OBJ;gaze/l/look/peer/stare on OBJ;gaze/l/look/peer/stare out OBJ;gaze/l/look/peer/stare throug OBJ;gaze/l/look/peer/stare under OBJ;gaze/l/look/peer/stare with OBJ;go/procee/run/step/walk OBJ;go/procee/run/step/walk around OBJ;go/procee/run/step/walk down OBJ;go/procee/run/step/walk in OBJ;go/procee/run/step/walk on OBJ;go/procee/run/step/walk throug OBJ;go/procee/run/step/walk to OBJ;go/procee/run/step/walk up OBJ;hello/hi OBJ;help OBJ;hide behind OBJ;hide in OBJ;hide under OBJ;insert/place/put/stuff/wedge down OBJ;insert/place/put/stuff/wedge on OBJ;jump/leap across OBJ;jump/leap from OBJ;jump/leap in OBJ;jump/leap off OBJ;jump/leap/go/procee/run/step/walk over OBJ;kick OBJ;kiss OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;knock/rap over OBJ;latitu OBJ;launch OBJ;lean on OBJ;lease/rent OBJ;leave OBJ;lie/nap/rest/sleep down OBJ;lie/nap/rest/sleep in OBJ;lie/nap/rest/sleep on OBJ;lift/raise OBJ;light/start/strike OBJ;listen for OBJ;listen to OBJ;longit OBJ;lower OBJ;make OBJ;molest/rape OBJ;move/roll/pull/tug/yank OBJ;open OBJ;open up OBJ;pick OBJ;pick up OBJ;play OBJ;pour/spill OBJ;pray for OBJ;press/push/shove OBJ;press/push/shove on OBJ;press/push/shove/lift/raise up OBJ;pull/tug/yank on OBJ;pump up OBJ;reach in OBJ;read/skim OBJ;read/skim in OBJ;rob OBJ;roll up OBJ;scream/shout/yell at OBJ;search OBJ;search in OBJ;send OBJ;send for OBJ;shake OBJ;sit down OBJ;sit in OBJ;sit on OBJ;sit with OBJ;slide OBJ;smell/sniff OBJ;smoke OBJ;spin OBJ;squeez OBJ;stand on OBJ;stand/carry/get/grab/hold/remove/take up OBJ;swing/thrust OBJ;taste OBJ;tell OBJ;unfold OBJ;unlock OBJ;wait/z OBJ;wait/z for OBJ;wear OBJ;weigh OBJ;what/what'/whats/who/who's/whos OBJ;wind OBJ;wind up OBJ;withdr OBJ;aim/point OBJ at OBJ;apply OBJ to OBJ;ask/inquir/questi OBJ about OBJ;ask/inquir/questi OBJ for OBJ;attach/connec/fasten/secure/tie OBJ around OBJ;attach/connec/fasten/secure/tie OBJ to OBJ;attach/connec/fasten/secure/tie up OBJ with OBJ;attack/fight/hurt/injure OBJ with OBJ;blind/jab/poke OBJ with OBJ;blow up OBJ with OBJ;brace/suppor OBJ with OBJ;brandi/wave OBJ at OBJ;break/chip/chop/damage/destro/hit/smash OBJ with OBJ;break/chip/chop/damage/destro/hit/smash down OBJ with OBJ;break/chip/chop/damage/destro/hit/smash in OBJ with OBJ;burn/ignite/incine OBJ with OBJ;burn/ignite/incine down OBJ with OBJ;buy/order/purcha OBJ from OBJ;carry/get/grab/hold/remove/take OBJ from OBJ;carry/get/grab/hold/remove/take OBJ off OBJ;carry/get/grab/hold/remove/take OBJ out OBJ;cast/chuck/hurl/throw/toss OBJ at OBJ;cast/chuck/hurl/throw/toss OBJ down OBJ;cast/chuck/hurl/throw/toss OBJ in OBJ;cast/chuck/hurl/throw/toss OBJ off OBJ;cast/chuck/hurl/throw/toss OBJ on OBJ;cast/chuck/hurl/throw/toss OBJ over OBJ;cast/chuck/hurl/throw/toss OBJ with OBJ;cut/pierce/scrape/slice OBJ with OBJ;deposi OBJ in OBJ;deposi/insert/place/put/stuff/wedge OBJ on OBJ;detach/discon/free/unfast/unhook/untie OBJ from OBJ;dig OBJ in OBJ;dig OBJ with OBJ;dig in OBJ with OBJ;dispat/kill/murder/slay/stab OBJ with OBJ;donate/feed/give/hand/offer/pay OBJ OBJ;donate/feed/give/hand/offer/pay OBJ to OBJ;drill OBJ in OBJ;drill OBJ with OBJ;drop/releas OBJ down OBJ;drop/releas OBJ in OBJ;drop/releas OBJ on OBJ;feel/pat/pet/rub/touch OBJ to OBJ;feel/pat/pet/rub/touch OBJ with OBJ;fill OBJ with OBJ;fix/glue/patch/plug/repair OBJ with OBJ;flash/show OBJ OBJ;flash/show OBJ to OBJ;flip/set/turn OBJ for OBJ;flip/set/turn OBJ to OBJ;flip/set/turn OBJ with OBJ;gaze/l/look/peer/stare at OBJ with OBJ;grease/lubric OBJ with OBJ;hide OBJ behind OBJ;hide OBJ in OBJ;hide OBJ under OBJ;inflat OBJ with OBJ;insert/place/put/stuff/wedge OBJ across OBJ;insert/place/put/stuff/wedge OBJ agains OBJ;insert/place/put/stuff/wedge OBJ at OBJ;insert/place/put/stuff/wedge OBJ behind OBJ;insert/place/put/stuff/wedge OBJ betwee OBJ;insert/place/put/stuff/wedge OBJ by OBJ;insert/place/put/stuff/wedge OBJ in OBJ;insert/place/put/stuff/wedge OBJ over OBJ;insert/place/put/stuff/wedge OBJ under OBJ;lease/rent OBJ from OBJ;lift/raise OBJ with OBJ;light/start OBJ with OBJ;liquif/melt OBJ with OBJ;lock OBJ with OBJ;lower OBJ down OBJ;move OBJ with OBJ;move/roll/pull/tug/yank/press/push/shove/slide OBJ OBJ;open OBJ with OBJ;pick OBJ with OBJ;pour/spill OBJ from OBJ;pour/spill OBJ in OBJ;pour/spill OBJ on OBJ;press/push/shove OBJ off OBJ;press/push/shove OBJ throug OBJ;press/push/shove OBJ under OBJ;pump up OBJ with OBJ;read/skim OBJ with OBJ;roll/press/push/shove/slide OBJ to OBJ;slide OBJ under OBJ;spray OBJ on OBJ;spray OBJ with OBJ;squeez OBJ on OBJ;strike OBJ with OBJ;swing/thrust OBJ at OBJ;tell OBJ about OBJ;unlock OBJ with OBJ;what/what'/whats/who/who's/whos OBJ OBJ;", "max_word_length" : 6 } @@ -125,7 +125,7 @@ "rom": "deephome.z5", "seed": 0, # walkthrough adapted from http://www.ifarchive.org/if-archive/solutions/deephome.sol - "walkthrough": "read note/x door/push mountain/sw/open cabinet/l in cabinet/take shield/take sword/search table/read letter/sw/read warning note/get torch/wait/wait/s/s/s/s/s/s/get pickaxe/n/e/dig rock with axe/take coal/w/n/e/open furnace/put coal in furnace/close furnace/x generator/pull lever/w/n/n/n/n/w/enter car/push yellow/out/nw/sw/get gear/ne/w/e/nw/se/n/s/ne/sw/e/w/se/enter car/push green button/out/w/sw/sw/x terrock/ne/ne/w/e/s/n/e/enter car/push yellow button/out/e/s/s/e/l up terrock in leshosh/w/s/w/w/get moss/e/e/n/n/n/w/enter car/push green button/out/w/sw/sw/put moss in nest/x pipe/push rod/ne/ne/e/enter car/push yellow button/out/e/s/s/s/s/sw/turn wheel/ne/n/e/se/x panel/open hatch/l in hatch/put gear on post/push lever/push button/s/s/s/s/w/e/s/w/ask man about hammer/ask man about eranti/e/s/wear shield/wield sword/kill eranti/kill eranti/kill eranti/kill eranti/n/w/get hammer/e/n/n/n/n/w/w/read sign/w/sw/w/s/e/n/w/e/x clover/get clover/read sign/s/e/e/e/n/nw/w/n/n/n/w/enter car/push yellow button/out/nw/sw/get scraps/open forge/light coal/put scraps in forge/wait/wait/get scraps/put scraps on anvil/hammer scraps/get sharp pick/ne/se/enter car/push red button/out/sw/n/x box/pick lock with sharp pick/open box/l in box/take key/s/unlock door with key/open door/w/ask spirit for name/search valuables/get coin/e/ne/enter car/push yellow button/out/e/s/s/w/ask spirit for name/e/s/w/s/n/w/n/s/w/w/ask spirit for name/e/e/e/e/n/e/look up Kebarn in Leshosh/look up Partaim in Fresto/look up Indanaz in Leshosh/look up Ternalim in Fresto/look up Cholok in Leshosh/look up Yetzuiz in Fresto/look up squirrel in Leshosh/w/s/e/se/s/s/s/s/s/e/x chest/pick lock with sharp pick/open chest/drop sword/drop shield/get net/w/n/n/dig ground with axe/put net on hole/get acorns/put acorns in net/climb tree/climb down/get net/n/n/n/nw/w/w/w/w/w/open net/e/e/e/e/n/n/w/open desk/get paper/e/e/drop hammer/drop pickaxe/get bottle/fill bottle/w/s/w/burn paper/drop coin/pour water on coin/put ashes on coin/put clover on coin/pray to kraxis/manaz/take coin/e/n/e/fill bottle/w/ne/sw/n/u/d/w/enter car/push red button/out/sw/w/drop net/open net/put coin in net/pour water on net/get coin/pray to kraxis/manaz", + "walkthrough": "read note/x door/push mountain/sw/open cabinet/examine cabinet/take shield/take sword/search table/read letter/sw/read warning note/get torch/wait/wait/s/s/s/s/s/s/get pickaxe/n/e/dig rock with axe/take coal/w/n/e/open furnace/put coal in furnace/close furnace/x generator/pull lever/w/n/n/n/n/w/enter car/push yellow/out/nw/sw/get gear/ne/w/e/nw/se/n/s/ne/sw/e/w/se/enter car/push green button/out/w/sw/sw/x terrock/ne/ne/w/e/s/n/e/enter car/push yellow button/out/e/s/s/e/look up terrock in leshosh/w/s/w/w/get moss/e/e/n/n/n/w/enter car/push green button/out/w/sw/sw/put moss in nest/x pipe/push rod/ne/ne/e/enter car/push yellow button/out/e/s/s/s/s/sw/turn wheel/ne/n/e/se/x panel/open hatch/examine hatch/put gear on post/push lever/push button/s/s/s/s/w/e/s/w/ask man about hammer/ask man about eranti/e/s/wear shield/wield sword/kill eranti/kill eranti/kill eranti/kill eranti/n/w/get hammer/e/n/n/n/n/w/w/read sign/w/sw/w/s/e/n/w/e/x clover/get clover/read sign/s/e/e/e/n/nw/w/n/n/n/w/enter car/push yellow button/out/nw/sw/get scraps/open forge/light coal/put scraps in forge/wait/wait/get scraps/put scraps on anvil/hammer scraps/get sharp pick/ne/se/enter car/push red button/out/sw/n/x box/pick lock with sharp pick/open box/look in box/take key/s/unlock door with key/open door/w/ask spirit for name/search valuables/get coin/e/ne/enter car/push yellow button/out/e/s/s/w/ask spirit for name/e/s/w/s/n/w/n/s/w/w/ask spirit for name/e/e/e/e/n/e/look up Kebarn in Leshosh/look up Partaim in Fresto/look up Indanaz in Leshosh/look up Ternalim in Fresto/look up Cholok in Leshosh/look up Yetzuiz in Fresto/look up squirrel in Leshosh/w/s/e/se/s/s/s/s/s/e/x chest/pick lock with sharp pick/open chest/drop sword/drop shield/get net/w/n/n/dig ground with axe/put net on hole/get acorns/put acorns in net/climb tree/climb down/get net/n/n/n/nw/w/w/w/w/w/open net/e/e/e/e/n/n/w/open desk/get paper/e/e/drop hammer/drop pickaxe/get bottle/fill bottle/w/s/w/burn paper/drop coin/pour water on coin/put ashes on coin/put clover on coin/pray to kraxis/manaz/take coin/e/n/e/fill bottle/w/ne/sw/n/u/d/w/enter car/push red button/out/sw/w/drop net/open net/put coin in net/pour water on net/get coin/pray to kraxis/manaz", "grammar" : "answer/say/shout/speak manaz;awake/awaken/wake;awake/awaken/wake up;bother/curses/darn/drat;brief/normal;carry/hold/take inventory;climb/scale down;credits;damn/fuck/shit/sod;diag/diagnose/health;die/q/quit;dive/swim;exit/out/outside/stand;exits;flip;full/fullscore;full/fullscore score;get out/off/up;hear/listen;help;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;l/look;leave/go/run/walk;long/verbose;manaz;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;plugh;pray;restart;restore;save;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie;sing;smell/sniff;sorry;stand up;think;verify;version;wait/z;wave;xyzzy;y/yes;adjust/set OBJ;answer/say/shout/speak OBJ;answer/say/shout/speak manaz to OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;beat/hammer OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;carry/hold/take off OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;cross/enter/go/run/walk OBJ;damn/fuck/shit/sod OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;flip OBJ;get in/into/on/onto OBJ;get off OBJ;get out of OBJ;get/carry/hold/take OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;l/look at OBJ;l/look inside/in/into/through OBJ;l/look under OBJ;leave OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit at OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ;pick OBJ up;pick up OBJ;pour OBJ;pray to OBJ;put OBJ down;put down OBJ;put on OBJ;read/check/describe/examine/watch/x OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;smell/sniff OBJ;spread OBJ;squash/squeeze OBJ;stand on OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;use OBJ;wave OBJ;wield OBJ;adjust/set OBJ to OBJ;attach/fasten/fix/tie OBJ to OBJ;beat/hammer OBJ with OBJ;burn/light OBJ with OBJ;carry/hold/take OBJ off OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;consult OBJ about OBJ;consult OBJ on OBJ;dig OBJ with OBJ;dig hole in OBJ with OBJ;dig hole with OBJ in OBJ;dig in OBJ with OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ to/into/on/onto OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;pick OBJ with OBJ;pour OBJ on OBJ;put OBJ in/inside/into OBJ;put OBJ over OBJ;read OBJ in OBJ;read about OBJ in OBJ;remove/get/carry/hold/take OBJ from OBJ;spread OBJ on OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } @@ -135,7 +135,7 @@ "rom": "detective.z5", "seed": 0, # Walkthrough adapted from https://solutionarchive.com/file/id,1554/ - "walkthrough": "TAKE PAPER/READ PAPER/DROP PAPER/INVENTORY/W/TAKE GUN/E/N/W/E/E/TAKE WOOD/W/W/TAKE NOTE/READ NOTE/E/N/N/W/N/N/W/E/N/E/E/E/S/TAKE HAMBURGER/N/N/E/N/N/N/N/E/W/W/E/N/W/N/W/N/N/w/n/n/up", + "walkthrough": "TAKE PAPER/READ PAPER/DROP PAPER/INVENTORY/W/TAKE GUN/E/N/W/E/E/TAKE WOOD/W/W/TAKE NOTE/READ NOTE/E/N/N/W/N/N/W/E/N/E/E/E/S/TAKE HAMBURGER/N/N/E/N/N/N/N/E/W/W/E/N/N/W/N/w/n/n/up", "grammar" : "about/help/info/informati;actions;actions off;actions on;awake/awaken/wake;awake/awaken/wake up;bother/curses/darn/drat;brief/normal;carry/hold/take inventory;changes;changes off;changes on;daemons/timers;daemons/timers off;daemons/timers on;damn/fuck/shit/sod;die/q/quit;dive/swim;exit/out/outside/stand;footnote/note;full/fullscore;full/fullscore score;get out/off/up;hear/listen;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;l/look;leave/go/run/walk;long/verbose;manual;manual pronouns;manual pronouns off;manual pronouns on;melenkuri/noside/plover/plugh/samoht/xyzzy/zorton;messages/routines;messages/routines off;messages/routines on;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;nouns/pronouns off;nouns/pronouns on;objects;places;pray;random;read footnote;read footnotes;recording;recording off;recording on;replay;restart;restore;save;scope;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie;showobj;sing;smell/sniff;sorry;stand up;think;trace;trace off;trace on;tree;verify;version;wait/z;wave;y/yes;adjust/set OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;carry/hold/take off OBJ;check/describe/examine/watch/x OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;cross/enter/go/run/walk OBJ;damn/fuck/shit/sod OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;footnote/note OBJ;get in/into/on/onto OBJ;get off OBJ;get/carry/hold/take OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;l/look at OBJ;l/look inside/in/into/through OBJ;l/look under OBJ;leave OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;purloin OBJ;put OBJ down;put down OBJ;put on OBJ;read OBJ;read footnote OBJ;read note OBJ;rotate/screw/turn/twist/unscrew OBJ;scope OBJ;search OBJ;showobj OBJ;showverb OBJ;smell/sniff OBJ;squash/squeeze OBJ;stand on OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;trace OBJ;tree OBJ;wave OBJ;abstract OBJ to OBJ;adjust/set OBJ to OBJ;answer/say/shout/speak OBJ to OBJ;ask OBJ about OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/hold/take OBJ off OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;consult OBJ about OBJ;consult OBJ on OBJ;dig OBJ with OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ to/into/on/onto OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;put OBJ in/inside/into OBJ;read OBJ in OBJ;read about OBJ in OBJ;remove/get/carry/hold/take OBJ from OBJ;shoot OBJ at OBJ;shoot OBJ with OBJ;tell OBJ about OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } @@ -155,7 +155,7 @@ "rom" : "enchanter.z3", "seed" : 0, # Walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip - "walkthrough": "NE/enter shack/OPEN OVEN/GET BREAD/take JUG/take LANTERN/exit shack/NE/SE/NE/FILL JUG/SW/SE/SW/SW/S/READ SCROLL/GNUSTO REZROV SPELL/NE/NE/E/E/LEARN REZROV/REZROV GATE/E/N/FROTZ LANTERN/N/U/GET EGG/EXAMINE IT/TURN HANDLE/PRESS KNOB/PULL SLIDE/MOVE CRANK/PUSH BUTTON/GET SHREDDED SCROLL/READ IT/D/E/E/E/E/E/LEARN REZROV/REZROV GATE/N/GET CRUMPLED SCROLL/READ IT/GNUSTO KREBF SPELL/LEARN KREBF/KREBF SHREDDED SCROLL/READ FADED SCROLL/GNUSTO ZIFMIA SPELL/E/LEARN NITFOL/NITFOL FROGS/LOOK UNDER LILY PAD/READ DAMP SCROLL/GNUSTO CLEESH SPELL/W/drink water/S/S/EXAMINE TRACKS/REACH INTO HOLE/Take book/EAT BREAD/N/EXAMINE dusty book/READ OF UNSEEN TERROR/DROP DUSTY BOOK/READ FRAYED SCROLL/GNUSTO GONDAR SPELL/W/W/W/W/W/S/S/S/S/U/wait/LIE DOWN/STAND UP/EXAMINE POST/PRESS BUTTON/GET GOLD LEAF SCROLL/READ IT/GNUSTO VAXUM SPELL/D/E/S/OPEN DOOR/N/READ WRITINGS/MOVE BLOCK/E/GET STAINED SCROLL/READ IT/GNUSTO EXEX SPELL/W/S/U/E/E/S/SE/LEARN NITFOL/NITFOL TURTLE/TURTLE, FOLLOW ME/NW/N/E/U/LEARN EXEX/EXEX TURTLE/drink water/TURTLE, SE AND GET SCROLL THEN NW/READ BRITTLE SCROLL/GET IT/D/W/W/TURN OFF LANTERN/LOOK/MOVE LIGHTED PORTRAIT/GET BLACK SCROLL/READ IT/GNUSTO OZMOO SPELL/GET CANDLE/LEARN FROTZ/FROTZ CANDLE/LEARN FROTZ/LEARN OZMOO/W/N/FROTZ LANTERN/DROP ALL BUT CANDLE/eat bread/S/E/E/N/N/N/WAIT/OZMOO MYSELF/WAIT/D/W/W/S/CUT ROPE WITH DAGGER/DROP DAGGER/GET ALL BUT DAGGER/S/W/U/LIE DOWN/STAND UP/D/N/N/N/N/LEARN ZIFMIA/LEARN VAXUM/E/E/E/E/ZIFMIA ADVENTURER/LEARN BLORB/VAXUM ADVENTURER/SHOW EGG TO ADVENTURER THEN EAST/E/ADVENTURER, OPEN DOOR/WAIT/BLORB ADVENTURER/U/DROP EGG/drink water/GET PENCIL/GET MAP/D/W/W/W/W/W/W/S/S/S/S/EAT BREAD/E/S/D/READ MAP/DRAW LINE FROM F TO P/WAIT/ERASE LINE BETWEEN B AND R/ERASE LINE BETWEEN M AND V/DRAW LINE FROM B TO J/E/SE/SE/SW/DROP MAP/DROP PENCIL/GET SCROLL/READ IT/NE/NW/NW/W/U/U/N/OPEN BOX/GET VELLUM SCROLL/READ IT/GNUSTO MELBOR SPELL/N/W/W/W/drink water/W/NW/NE/FILL JUG/SW/SE/E/E/E/S/S/LEARN MELBOR/SLEEP/LEARN VAXUM/LEARN GONDAR/LEARN MELBOR/E/E/MELBOR MYSELF/EAT BREAD/E/N/N/N/E/E/KULCAD STAIRS/READ ORNATE SCROLL/IZYUK MYSELF/E/GONDAR DRAGON/VAXUM BEING/GUNCHO KRILL", + "walkthrough": "NE/enter shack/OPEN OVEN/GET BREAD/take JUG/take LANTERN/exit shack/NE/SE/NE/FILL JUG/SW/SE/SW/SW/S/READ SCROLL/GNUSTO REZROV SPELL/NE/NE/E/E/LEARN REZROV/REZROV GATE/E/N/FROTZ LANTERN/N/U/GET EGG/EXAMINE IT/TURN HANDLE/PRESS KNOB/PULL SLIDE/MOVE CRANK/PUSH BUTTON/GET SHREDDED SCROLL/READ SHREDDED SCROLL/D/E/E/E/E/E/LEARN REZROV/REZROV GATE/N/GET CRUMPLED SCROLL/READ CRUMPLED SCROLL/GNUSTO KREBF SPELL/LEARN KREBF/KREBF SHREDDED SCROLL/READ FADED SCROLL/GNUSTO ZIFMIA SPELL/E/LEARN NITFOL/NITFOL FROGS/LOOK UNDER LILY PAD/READ DAMP SCROLL/GNUSTO CLEESH SPELL/W/drink water/S/S/EXAMINE TRACKS/REACH INTO HOLE/Take book/EAT BREAD/N/EXAMINE dusty book/READ OF UNSEEN TERROR/DROP DUSTY BOOK/READ FRAYED SCROLL/GNUSTO GONDAR SPELL/W/W/W/W/W/S/S/S/S/U/wait/LIE DOWN/STAND UP/EXAMINE POST/PRESS BUTTON/GET GOLD LEAF SCROLL/READ GOLD LEAF SCROLL/GNUSTO VAXUM SPELL/D/E/S/OPEN DOOR/N/READ WRITINGS/MOVE BLOCK/E/GET STAINED SCROLL/READ STAINED SCROLL/GNUSTO EXEX SPELL/W/S/U/E/E/S/SE/LEARN NITFOL/NITFOL TURTLE/TURTLE, FOLLOW ME/NW/N/E/U/LEARN EXEX/EXEX TURTLE/drink water/TURTLE, SE AND GET SCROLL THEN NW/READ BRITTLE SCROLL/GET IT/D/W/W/TURN OFF LANTERN/LOOK/MOVE LIGHTED PORTRAIT/GET BLACK SCROLL/READ BLACK SCROLL/GNUSTO OZMOO SPELL/GET CANDLE/LEARN FROTZ/FROTZ CANDLE/LEARN FROTZ/LEARN OZMOO/W/N/FROTZ LANTERN/DROP ALL BUT CANDLE/eat bread/S/E/E/N/N/N/WAIT/OZMOO MYSELF/WAIT/D/W/W/S/CUT ROPE WITH DAGGER/DROP DAGGER/GET ALL BUT DAGGER/S/W/U/LIE DOWN/STAND UP/D/N/N/N/N/LEARN ZIFMIA/LEARN VAXUM/E/E/E/E/ZIFMIA ADVENTURER/LEARN BLORB/VAXUM ADVENTURER/SHOW EGG TO ADVENTURER THEN EAST/E/ADVENTURER, OPEN DOOR/WAIT/BLORB ADVENTURER/U/DROP EGG/drink water/GET PENCIL/GET MAP/D/W/W/W/W/W/W/S/S/S/S/EAT BREAD/E/S/D/READ MAP/DRAW LINE FROM F TO P/WAIT/ERASE LINE BETWEEN B AND R/ERASE LINE BETWEEN M AND V/DRAW LINE FROM B TO J/E/SE/SE/SW/DROP MAP/DROP PENCIL/GET SCROLL/READ POWERFUL SCROLL/NE/NW/NW/W/U/U/N/OPEN BOX/GET VELLUM SCROLL/READ VELLUM SCROLL/GNUSTO MELBOR SPELL/N/W/W/W/drink water/W/NW/NE/FILL JUG/SW/SE/E/E/E/S/S/LEARN MELBOR/SLEEP/LEARN VAXUM/LEARN GONDAR/LEARN MELBOR/E/E/MELBOR MYSELF/EAT BREAD/E/N/N/N/E/E/KULCAD STAIRS/READ ORNATE SCROLL/IZYUK MYSELF/E/GONDAR DRAGON/VAXUM BEING/GUNCHO KRILL", "grammar" : "again/g;answer/reply;back;bathe/swim/wade;brief;call/say/talk;chase/come/follow/pursue;concea/hide;curse/damn;diagno;dive/jump/leap;enter;filfre;gaze/l/look/stare;hello/hi;hop/skip;i/invent;krebf;leave;mumble/sigh;nap/sleep/snooze;plugh/xyzzy;pray;q/quit;repent;restar;restor;save;score;scream/shout/yell;script;spells;stand;stay;super/superb;t/time;thank/thanks;unscri;verbos;versio;wait/z;zork;answer/reply OBJ;attack/fight/hit/hurt/injure OBJ;avoid OBJ;awake/startl/surpri/wake OBJ;awake/startl/surpri/wake up OBJ;banish/begone/drive/exorci OBJ;banish/begone/drive/exorci away OBJ;banish/begone/drive/exorci out OBJ;bathe/swim/wade in OBJ;beckon/brandi/motion/wave OBJ;beckon/brandi/motion/wave to OBJ;beckon/brandi/motion/wave/scream/shout/yell at OBJ;bite/kick OBJ;blorb OBJ;blow out OBJ;board OBJ;break/crack/damage/destro/hatch/smash OBJ;call/say/talk to OBJ;carry/get/grab/hold/remove/take OBJ;carry/get/grab/hold/remove/take off OBJ;carry/get/grab/hold/remove/take out OBJ;cast/incant OBJ;chase/come/follow/pursue OBJ;cleesh OBJ;climb/scale/sit OBJ;climb/scale/sit/carry/get/grab/hold/remove/take in OBJ;climb/scale/sit/carry/get/grab/hold/remove/take on OBJ;climb/scale/sit/go/procee/run/step/walk down OBJ;climb/scale/sit/go/procee/run/step/walk up OBJ;close OBJ;concea/hide OBJ;connec OBJ;consum/eat/taste OBJ;count OBJ;cross/ford OBJ;curse/damn OBJ;deflat OBJ;descri/examin/inspec/what/whats OBJ;descri/examin/inspec/what/whats on OBJ;descri/examin/inspec/what/whats/gaze/l/look/stare in OBJ;dig in OBJ;dig with OBJ;discon/erase/rub OBJ;discon/erase/rub betwee OBJ;discon/erase/rub from OBJ;discon/erase/rub out OBJ;disemb OBJ;dispat/kill/murder/slay/stab OBJ;dive/jump/leap across OBJ;dive/jump/leap from OBJ;dive/jump/leap in OBJ;dive/jump/leap off OBJ;dive/jump/leap/go/procee/run/step/walk over OBJ;douse/exting OBJ;draw/make betwee OBJ;draw/make from OBJ;draw/make on OBJ;drink/sip/swallo OBJ;drink/sip/swallo from OBJ;drop/exit/releas OBJ;enter OBJ;escape OBJ;escape from OBJ;exex OBJ;feel/pat/pet/touch OBJ;filfre OBJ;fill OBJ;find/see/seek/where OBJ;flip/set/shut/turn OBJ;flip/set/shut/turn off OBJ;flip/set/shut/turn on OBJ;fly/go/procee/run/step/walk OBJ;forget/unlear/unmemo OBJ;free/unatta/unfast/unhook/untie OBJ;frotz OBJ;gaze/l/look/stare OBJ;gaze/l/look/stare around OBJ;gaze/l/look/stare at OBJ;gaze/l/look/stare behind OBJ;gaze/l/look/stare out OBJ;gaze/l/look/stare throug OBJ;gaze/l/look/stare under OBJ;gaze/l/look/stare with OBJ;gaze/l/look/stare/search for OBJ;gestur/point at OBJ;gestur/point to OBJ;gnusto OBJ;go/procee/run/step/walk around OBJ;go/procee/run/step/walk behind OBJ;go/procee/run/step/walk in OBJ;go/procee/run/step/walk on OBJ;go/procee/run/step/walk to OBJ;go/procee/run/step/walk under OBJ;go/procee/run/step/walk with OBJ;gondar OBJ;gross out OBJ;guncho OBJ;hello/hi OBJ;insert/lay/place/put/stuff down OBJ;insert/lay/place/put/stuff on OBJ;izyuk OBJ;kiss OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;krebf OBJ;kulcad OBJ;launch OBJ;lean on OBJ;learn OBJ;leave OBJ;lie down OBJ;lift/raise OBJ;lift/raise up OBJ;light OBJ;listen for OBJ;listen to OBJ;lower OBJ;melbor OBJ;memori OBJ;molest/rape OBJ;move/pull/tug OBJ;nap/sleep/snooze in OBJ;nap/sleep/snooze on OBJ;nitfol OBJ;open OBJ;open up OBJ;ozmoo OBJ;pick OBJ;pick up OBJ;play OBJ;pour/spill OBJ;press/push OBJ;press/push on OBJ;pull/tug on OBJ;pump up OBJ;reach in OBJ;read/skim OBJ;rezrov OBJ;roll up OBJ;search OBJ;search in OBJ;send for OBJ;shake OBJ;slide OBJ;smell/sniff OBJ;spin OBJ;squeez OBJ;stand/carry/get/grab/hold/remove/take up OBJ;stay OBJ;strike OBJ;swing/thrust OBJ;tell OBJ;thank/thanks OBJ;vaxum OBJ;wait/z for OBJ;wear OBJ;who OBJ;wind OBJ;wind up OBJ;write on OBJ;write with OBJ;zifmia OBJ;apply OBJ to OBJ;ask OBJ for OBJ;attach/fasten/secure/tie OBJ to OBJ;attach/fasten/secure/tie up OBJ with OBJ;attack/fight/hit/hurt/injure OBJ with OBJ;beckon/brandi/motion/wave OBJ at OBJ;blind/jab/poke OBJ with OBJ;break/crack/damage/destro/hatch/smash OBJ with OBJ;break/crack/damage/destro/hatch/smash down OBJ with OBJ;burn/ignite OBJ with OBJ;burn/ignite down OBJ with OBJ;carry/get/grab/hold/remove/take OBJ from OBJ;carry/get/grab/hold/remove/take OBJ off OBJ;carry/get/grab/hold/remove/take OBJ out OBJ;carry/get/grab/hold/remove/take/bring OBJ OBJ;cast/incant OBJ at OBJ;cast/incant OBJ on OBJ;chuck/hurl/throw/toss OBJ at OBJ;chuck/hurl/throw/toss OBJ in OBJ;chuck/hurl/throw/toss OBJ off OBJ;chuck/hurl/throw/toss OBJ on OBJ;chuck/hurl/throw/toss OBJ over OBJ;chuck/hurl/throw/toss OBJ with OBJ;concea/hide OBJ from OBJ;connec OBJ to OBJ;connec OBJ with OBJ;cut/pierce/slice OBJ with OBJ;cut/pierce/slice with OBJ with OBJ;dig OBJ with OBJ;dig in OBJ with OBJ;discon/erase/rub betwee OBJ to OBJ;discon/erase/rub betwee OBJ with OBJ;discon/erase/rub from OBJ to OBJ;discon/erase/rub from OBJ with OBJ;discon/erase/rub out OBJ with OBJ;dispat/kill/murder/slay/stab OBJ with OBJ;donate/feed/give/hand/offer OBJ OBJ;donate/feed/give/hand/offer OBJ to OBJ;draw/make betwee OBJ to OBJ;draw/make betwee OBJ with OBJ;draw/make from OBJ to OBJ;draw/make from OBJ with OBJ;draw/make on OBJ with OBJ;drop/exit/releas OBJ down OBJ;drop/exit/releas OBJ on OBJ;drop/exit/releas/insert/lay/place/put/stuff OBJ in OBJ;feel/pat/pet/touch OBJ with OBJ;fill OBJ at OBJ;fill OBJ with OBJ;fix/glue/patch/plug/repair OBJ with OBJ;flip/set/shut/turn OBJ for OBJ;flip/set/shut/turn OBJ to OBJ;flip/set/shut/turn OBJ with OBJ;free/unatta/unfast/unhook/untie OBJ from OBJ;gag OBJ with OBJ;gaze/l/look/stare at OBJ with OBJ;grease/lubric/oil OBJ with OBJ;hone/sharpe OBJ with OBJ;inflat OBJ with OBJ;insert/lay/place/put/stuff OBJ behind OBJ;insert/lay/place/put/stuff OBJ on OBJ;insert/lay/place/put/stuff OBJ under OBJ;light OBJ with OBJ;liquif/melt OBJ with OBJ;lock OBJ with OBJ;open OBJ with OBJ;pick OBJ with OBJ;pour/spill OBJ from OBJ;pour/spill OBJ in OBJ;pour/spill OBJ on OBJ;pump up OBJ with OBJ;read/skim OBJ with OBJ;show OBJ OBJ;show OBJ to OBJ;slide/press/push OBJ OBJ;slide/press/push OBJ to OBJ;slide/press/push OBJ under OBJ;spray OBJ on OBJ;spray OBJ with OBJ;squeez OBJ on OBJ;strike OBJ with OBJ;swing/thrust OBJ at OBJ;unlock OBJ with OBJ;write on OBJ with OBJ;", "max_word_length" : 6 } @@ -185,7 +185,7 @@ "rom": "hhgg.z3", "seed" : 4, # Walkthrough adapted from http://www.eristic.net/games/infocom/hhg.html - 'walkthrough': 'Get Up/Turn on Light/Get Gown/Wear Gown/Look in pocket/take analgesic/Get all/South/Get Mail/South/Lie Down In Front Of Bulldozer/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Follow Ford/Enter Pub/Look Shelf/Buy Sandwich/Drink Beer/Drink Beer/Drink Beer/Exit/Feed dog sandwich/Get towel/Wait/wait/wait/wait/wait/wait/wait/wait/get device/push green button/n/s/n/s/smell/examine shadow/Eat Peanuts/Take off gown/Put Gown on hook/put towel over drain/wait/get satchel/put satchel in front of panel/put mail on satchel/push dispenser button/get gown/wear gown/get all/push switch/z/z/z/z/z/z/z/enjoy poetry/z/z/z/z/z/type \"bleem\"/get plotter/z/z/z/examine thumb/press green button/n/s/n/s/listen/Aft/read brochure/z/z/inventory/take pincer/put all into thing/d/port/touch pad/get cup/starboard/aft/aft/yes/yes/aft/no/look/look/drop thing/get rasp/get pliers/put rasp into thing/put pliers into thing/get improbability drive/fore/fore/up/drop drive/drop cup/drop plotter/z/drop plotter/z/drop plotter/put small plug in plotter/put bit in cup/turn on drive/n/s/n/s/smell/look at shadow/say my name/e/examine memorial/get sharp stone/put towel on your head/carve my name on the memorial/remove towel/drop stone/w/sw/get interface/z/z/z/z/z/hear the dark/aft/aft/up/d/port/open panel/take circuit/insert interface in nutrimat/close panel/touch pad/starboard/up/put large plug in large receptacle/z/turn on drive/d/port/get tea/starboard/up/drop tea/z/z/z/z/z/z/z/z/z/z/remove bit/put bit in tea/turn on drive/z/touch/touch/drink liquid/examine arthur/drop wine/get fluff/open bag/put fluff in bag/get wine/z/z/z/z/z/z/hear/aft/aft/up/open handbag/get tweezers/get fluff/put all in thing/turn on drive/z/touch/touch/touch/touch/drink liquid/get flowerpot/put it in thing/examine thumb/press red button/give thumb to robot/z/show warranty/press green button/z/z/z/z/hear/aft/aft/up/turn on drive/see/see/see/see/examine light/look under seat/unlock box with key/get glass/get wrench/push autopilot button/steer towards rocky spire/z/z/z/stand up/out/wave at crowd/z/z/z/guards, drop rifles/Trillian, shoot rifles/enter/z/z/z/z/hear/aft/aft/aft/down/get fluff/get tools/up/fore/up/turn on drive/see/examine light/n/open satchel/get fluff/get towel/give towel to Arthur/idiot/walk around bulldozer/Prosser, lie in the mud/s/w/buy beer/buy peanuts/drink beer/drink beer/e/n/give fluff to Arthur/z/z/z/z/z/z/z/hear/aft/aft/up/i/turn on drive/hear/hear/hear/z/hear/hear/hear/hear/aft/get awl/z/z/z/z/n/n/n/get particule/z/z/z/z/hear/aft/aft/up/remove bit/take tea/i/take no tea/i/plant fluff in flowerpot/seat/plant fluff in flowerpot/satchel/plant fluff in flowerpot/jacket/plant fluff in flowerpot/z/z/z/port/examine plant/get fruit/d/aft/port/open door/drink tea/port/get chisel/Marvin, open the hatch/starboard/d/eat fruit/drop all but pincer/take pincer/drop thing/i/starboard/z/z/give pincer to Marvin/port/d', + 'walkthrough': 'Get Up/Turn on Light/Get Gown/Wear Gown/Look in pocket/take analgesic/Get all/South/Get Mail/South/Lie Down In Front Of Bulldozer/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Follow Ford/Enter Pub/Look Shelf/Buy Sandwich/Drink Beer/Drink Beer/Drink Beer/Exit/Feed dog sandwich/Get towel/Wait/wait/wait/wait/wait/wait/wait/wait/get device/push green button/wait/wait/wait/wait/smell/examine shadow/Eat Peanuts/Take off gown/Put Gown on hook/put towel over drain/wait/get satchel/put satchel in front of panel/put mail on satchel/push dispenser button/get gown/wear gown/get all/push switch/wait/wait/wait/wait/wait/wait/wait/enjoy poetry/wait/wait/wait/wait/wait/type \"bleem\"/get plotter/wait/wait/wait/examine thumb/press green button/wait/wait/wait/wait/listen/Aft/read brochure/wait/wait/inventory/take pincer/put all into thing/d/port/touch pad/get cup/starboard/aft/aft/yes/yes/aft/no/look/look/drop thing/get rasp/get pliers/put rasp into thing/put pliers into thing/get improbability drive/fore/fore/up/drop drive/drop cup/wait/wait/drop plotter/put small plug in plotter/put bit in cup/turn on drive/wait/wait/wait/wait/smell/look at shadow/say my name/e/examine memorial/get sharp stone/put towel on your head/carve my name on the memorial/remove towel/drop stone/w/sw/get interface/z/z/z/z/z/hear the dark/aft/aft/up/d/port/open panel/take circuit/insert interface in nutrimat/close panel/touch pad/starboard/up/put large plug in large receptacle/z/turn on drive/d/port/get tea/starboard/up/drop tea/z/z/z/z/z/z/z/z/z/z/remove bit/put bit in tea/turn on drive/z/touch/touch/drink liquid/examine arthur/drop wine/get fluff/open bag/put fluff in bag/get wine/z/z/z/z/z/z/hear/aft/aft/up/open handbag/get tweezers/get fluff/put all in thing/turn on drive/z/touch/touch/touch/touch/drink liquid/get flowerpot/put it in thing/examine thumb/press red button/give thumb to robot/z/show warranty/press green button/z/z/z/z/hear/aft/aft/up/turn on drive/see/see/see/see/examine light/look under seat/unlock box with key/get glass/get wrench/push autopilot button/steer towards rocky spire/z/z/z/stand up/out/wave at crowd/z/z/z/guards, drop rifles/Trillian, shoot rifles/enter/z/z/z/z/hear/aft/aft/aft/down/get fluff/get tools/up/fore/up/turn on drive/see/examine light/n/open satchel/get fluff/get towel/give towel to Arthur/idiot/walk around bulldozer/Prosser, lie in the mud/s/w/buy beer/buy peanuts/drink beer/drink beer/e/n/give fluff to Arthur/z/z/z/z/z/z/z/hear/aft/aft/up/i/turn on drive/hear/hear/hear/z/hear/hear/hear/hear/aft/get awl/z/z/z/z/n/n/n/get particule/z/z/z/z/hear/aft/aft/up/remove bit/take tea/i/take no tea/i/plant seat fluff in flowerpot/plant satchel fluff in flowerpot/plant jacket fluff in flowerpot/plant pocket fluff in flowerpot/z/z/z/port/examine plant/get fruit/d/aft/open door/drink tea/port/get chisel/Marvin, open the hatch/starboard/d/eat fruit/drop all but pincer/take pincer/drop thing/i/starboard/z/z/give pincer to Marvin/port/d', "grammar" : "again/g;answer/reply;applau/cheer/clap;argue/protes;blast/fire/shoot;bleem/frippi/gashee/lyshus/misera/morpho/thou/venchi/wimbgu;brief;crawl/kneel/peek;depart/exit/withdr;diagno;disrob;dive/jump/leap;doze/nap/snooze;enter;escape/flee;footno;gaze/l/look/stare;go/procee/run/step/walk;hello/hi;help/hint/hints;hide;hitch/hitchh;hop/skip;howl/scream/shout/yell;idiot;invent/i/i'm/im;leave;no;ok/okay/sure/y/yes;panic;q/quit;relax;restar;restor;rise/stand;save;say/speak/talk;score;script;sleep;smile;stay/wait/z;super/superb;type;unscri;verbos;versio;wave;why;activa/start OBJ;addres/tell OBJ;answer/reply OBJ;answer/reply to OBJ;apprec OBJ;approa OBJ;assaul/attack/fight/hit/kill/murder/punch/slap/strike OBJ;attach/fasten/secure/tie OBJ;attach/fasten/secure/tie togeth OBJ;awake/rouse/wake OBJ;awake/rouse/wake up OBJ;bite OBJ;blast/fire/shoot OBJ;block/stop OBJ;board/embark OBJ;break/crack/damage/demoli/destro/smash/wreck OBJ;break/crack/damage/demoli/destro/smash/wreck down OBJ;brush OBJ;buy/order/purcha OBJ;call/phone OBJ;carry/catch/get/grab/hold/take OBJ;carry/catch/get/grab/hold/take dresse OBJ;carry/catch/get/grab/hold/take drunk OBJ;carry/catch/get/grab/hold/take off OBJ;carry/catch/get/grab/hold/take out OBJ;carry/catch/get/grab/hold/take undres OBJ;chase/follow/pursue OBJ;clean/tidy/wash OBJ;clean/tidy/wash up OBJ;climb/scale OBJ;climb/scale down OBJ;climb/scale over OBJ;climb/scale up OBJ;climb/scale/dive/jump/leap/go/procee/run/step/walk throug OBJ;climb/scale/rest/sit/squat/carry/catch/get/grab/hold/take in OBJ;climb/scale/rest/sit/squat/carry/catch/get/grab/hold/take on OBJ;close/shut OBJ;close/shut off OBJ;count OBJ;debark/disemb OBJ;depart/exit/withdr OBJ;descen OBJ;descri/examin/inspec/observ/scour/see/study OBJ;descri/examin/inspec/observ/scour/see/study on OBJ;descri/examin/inspec/observ/scour/see/study/gaze/l/look/stare in OBJ;descri/examin/inspec/observ/scour/see/study/gaze/l/look/stare/frisk/rummag/search for OBJ;devour/eat/gobble/ingest OBJ;dig in OBJ;dig throug OBJ;dig with OBJ;discon/unplug OBJ;dive/jump/leap across OBJ;dive/jump/leap from OBJ;dive/jump/leap off OBJ;dive/jump/leap/go/procee/run/step/walk in OBJ;dive/jump/leap/go/procee/run/step/walk out OBJ;dive/jump/leap/go/procee/run/step/walk over OBJ;doff/remove/shed OBJ;don/wear OBJ;donate/give/hand/offer/sell up OBJ;draw/open/part OBJ;draw/open/part up OBJ;drink/guzzle/imbibe/quaff/sip/swallo/swill OBJ;drink/guzzle/imbibe/quaff/sip/swallo/swill from OBJ;drop OBJ;enjoy OBJ;enter OBJ;escape/flee OBJ;escape/flee from OBJ;exting OBJ;feed OBJ;feel/pat/pet/rub/touch OBJ;fill OBJ;find/seek OBJ;fix/repair/unjam OBJ;flick/flip/switch/toggle/turn OBJ;flick/flip/switch/toggle/turn around OBJ;flick/flip/switch/toggle/turn off OBJ;flick/flip/switch/toggle/turn on OBJ;footno OBJ;free/unatta/unfast/unknot/untie OBJ;frisk/rummag/search OBJ;frisk/rummag/search in OBJ;gaze/l/look/stare OBJ;gaze/l/look/stare around OBJ;gaze/l/look/stare at OBJ;gaze/l/look/stare behind OBJ;gaze/l/look/stare down OBJ;gaze/l/look/stare on OBJ;gaze/l/look/stare out OBJ;gaze/l/look/stare throug OBJ;gaze/l/look/stare under OBJ;gaze/l/look/stare up OBJ;go/procee/run/step/walk OBJ;go/procee/run/step/walk around OBJ;go/procee/run/step/walk away OBJ;go/procee/run/step/walk behind OBJ;go/procee/run/step/walk down OBJ;go/procee/run/step/walk on OBJ;go/procee/run/step/walk to OBJ;go/procee/run/step/walk up OBJ;hear OBJ;hello/hi OBJ;hide behind OBJ;hide under OBJ;howl/scream/shout/yell at OBJ;howl/scream/shout/yell to OBJ;hurl/throw/toss OBJ;hurl/throw/toss in OBJ;i/i'm/im OBJ;insert/lay/place/put/stuff down OBJ;insert/lay/place/put/stuff on OBJ;kick OBJ;kiss OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;leave OBJ;lick/taste OBJ;lie/reclin before OBJ;lie/reclin down OBJ;lie/reclin in OBJ;lie/reclin on OBJ;lift/raise OBJ;lift/raise up OBJ;light OBJ;listen to OBJ;lock OBJ;lower OBJ;make OBJ;move/pull OBJ;move/pull togeth OBJ;pay for OBJ;pick OBJ;pick up OBJ;point/steer at OBJ;point/steer to OBJ;pour/spill/sprink OBJ;press/push on OBJ;press/push/slide OBJ;rape OBJ;read/skim OBJ;refuse OBJ;replac OBJ;rest/sit/squat down OBJ;rise/stand before OBJ;rise/stand in OBJ;rise/stand on OBJ;rise/stand/carry/catch/get/grab/hold/take up OBJ;rotate/spin/whirl OBJ;save/help/hint/hints OBJ;say/speak/talk OBJ;say/speak/talk to OBJ;shake OBJ;sleep in OBJ;sleep on OBJ;smell/sniff/whiff OBJ;smile at OBJ;stay/wait/z for OBJ;thank/thanks OBJ;type on OBJ;unlock OBJ;wave OBJ;wave at OBJ;wave to OBJ;what/what'/whats OBJ;what/what'/whats about OBJ;where/wheres OBJ;who/whos OBJ;ask/consul/query OBJ about OBJ;ask/consul/query OBJ for OBJ;ask/consul/query OBJ on OBJ;assaul/attack/fight/hit/kill/murder/punch/slap/strike OBJ with OBJ;blast/fire/shoot OBJ at OBJ;blast/fire/shoot OBJ with OBJ;block/stop OBJ with OBJ;break/crack/damage/demoli/destro/smash/wreck OBJ with OBJ;brush OBJ with OBJ;bury/plant OBJ in OBJ;call/phone OBJ on OBJ;call/phone OBJ with OBJ;carry/catch/get/grab/hold/take OBJ in OBJ;carry/catch/get/grab/hold/take OBJ off OBJ;carry/catch/get/grab/hold/take OBJ out OBJ;carve/inscri/scratc/write OBJ in OBJ;carve/inscri/scratc/write OBJ on OBJ;carve/inscri/scratc/write OBJ with OBJ;connec/plug/attach/fasten/secure/tie OBJ to OBJ;cover OBJ with OBJ;cut/slice OBJ with OBJ;cut/slice throug OBJ with OBJ;dangle/drop/hang/insert/lay/place/put/stuff OBJ in OBJ;descri/examin/inspec/observ/scour/see/study OBJ throug OBJ;doff/remove/shed/carry/catch/get/grab/hold/take OBJ from OBJ;drape/wrap OBJ in OBJ;draw/open/part OBJ with OBJ;drop OBJ down OBJ;drop/insert/lay/place/put/stuff OBJ before OBJ;drop/insert/lay/place/put/stuff/drape/wrap OBJ on OBJ;feed/donate/give/hand/offer/sell OBJ OBJ;feed/donate/give/hand/offer/sell OBJ to OBJ;feel/pat/pet/rub/touch OBJ with OBJ;flick/flip/switch/toggle/turn OBJ to OBJ;flick/flip/switch/toggle/turn OBJ with OBJ;flick/flip/switch/toggle/turn off OBJ OBJ;flick/flip/switch/toggle/turn on OBJ OBJ;gaze/l/look/stare at OBJ throug OBJ;hang OBJ from OBJ;hang OBJ on OBJ;hurl/throw/toss OBJ at OBJ;hurl/throw/toss OBJ in OBJ;hurl/throw/toss OBJ off OBJ;hurl/throw/toss OBJ over OBJ;hurl/throw/toss OBJ throug OBJ;hurl/throw/toss OBJ to OBJ;hurl/throw/toss OBJ up OBJ;insert/lay/place/put/stuff OBJ across OBJ;insert/lay/place/put/stuff OBJ at OBJ;insert/lay/place/put/stuff OBJ behind OBJ;insert/lay/place/put/stuff OBJ down OBJ;insert/lay/place/put/stuff/attach/fasten/secure/tie/drape/wrap OBJ around OBJ;insert/lay/place/put/stuff/drape/wrap OBJ over OBJ;lock OBJ with OBJ;move/pull/press/push/flick/flip/switch/toggle/turn/hurl/throw/toss OBJ OBJ;my OBJ OBJ;pick OBJ with OBJ;plug OBJ in OBJ;plug in OBJ in OBJ;plug in OBJ to OBJ;point/steer OBJ at OBJ;point/steer OBJ to OBJ;pour/spill/sprink OBJ in OBJ;pour/spill/sprink OBJ on OBJ;pour/spill/sprink OBJ over OBJ;press/push/insert/lay/place/put/stuff/slide OBJ under OBJ;read/skim OBJ throug OBJ;read/skim OBJ with OBJ;shake OBJ with OBJ;show OBJ OBJ;show OBJ to OBJ;tell OBJ OBJ;tell OBJ about OBJ;tell OBJ to OBJ;unlock OBJ with OBJ;water OBJ with OBJ;what/what'/whats OBJ OBJ;", "max_word_length" : 6 } @@ -195,7 +195,7 @@ "rom": "hollywood.z3", "seed" : 0, # walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip - "walkthrough": "N/OPEN MAILBOX/GET PIECE OF PAPER AND BUSINESS CARD/OPEN DOOR/N/TURN ON FLASHLIGHT/N/EXAMINE MODEL/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS BLACK/PRESS BLACK/PRESS WHITE/PRESS WHITE/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS BLACK/PRESS BLUE/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS RED/PRESS RED/PRESS RED/GET RING/E/E/S/GET FILM AND SLIDE/EXAMINE FILM PROJECTOR/REMOVE CAP/DROP IT/TURN ON SLIDE PROJECTOR/INSERT SLIDE IN IT/FOCUS SLIDE LENS/INSERT FILM IN FILM PROJECTOR/TURN ON FILM PROJECTOR/EXAMINE SCREEN/N/GET YELLOW CARD/W/W/S/W/EXAMINE RED STATUETTE/EXAMINE WHITE STATUETTE/EXAMINE BLUE STATUETTE/E/E/LOOK BEHIND PAINTING/GET GREEN CARD/EXAMINE SAFE/TURN DIAL RIGHT 3/TURN IT LEFT 7/TURN IT RIGHT 5/OPEN SAFE/GET GRATER/E/PLAY people/PUSH PIANO NORTH/D/S/GET PILLAR/DROP IT/N/U/PUSH PIANO SOUTH/AGAIN/D/N/GET METER/S/U/OPEN PIANO/GET VIOLET CARD/W/W/DROP RING/DROP GRATER/DROP METER/N/UNLOCK DOOR/OPEN IT/N/GET ORANGE CARD/S/S/OPEN CLOSET/IN/PULL THIRD PEG/OPEN DOOR/OUT/TURN NEWEL/W/S/LOOK UNDER MAT/GET RED CARD/N/E/E/GET SACK/OPEN WINDOW/OPEN SACK/S/GET BLUE CARD/N/W/D/DROP SACK/W/IN/REMOVE BRICK/DROP IT/GET INDIGO CARD/drop all but flashlight/U/U/U/E/D/GET PENGUIN/U/W/D/D/D/take all/OUT/N/W/D/READ BUSINESS CARD/DROP IT/EXAMINE COMPUTER/TURN IT ON/INSERT RED CARD IN SLOT/INSERT ORANGE CARD IN SLOT/INSERT YELLOW CARD IN SLOT/INSERT GREEN CARD IN SLOT/INSERT BLUE CARD IN SLOT/INSERT INDIGO CARD IN SLOT/INSERT VIOLET CARD IN SLOT/EXAMINE LIGHTS/U/GET MATCHBOX/E/GET PAPER/PUT IT ON YELLOWED PAPER/S/GET RED STATUETTE/DIAL 576-3190/E/N/W/W/D/TAKE TOUPEE/U/E/E/S/U/IN/GET SKIS/PULL SECOND PEG/OPEN DOOR/OUT/N/W/W/D/U/E/E/S/DROP TOUPEE/DROP PHOTO/DROP LETTER/GET FINCH/DROP FINCH/N/N/N/NW/GET SHOVEL/NE/N/N/W/N/W/N/W/S/W/W/N/W/S/E/S/E/N/E/S/W/N/W/S/W/N/W/S/W/N/E/N/E/N/E/E/N/E/S/E/E/S/E/N/E/N/E/S/S/S/W/W/S/E/N/W/S/DIG IN GROUND/DROP SHOVEL/GET STAMP/N/E/S/W/N/E/E/N/N/N/W/S/W/S/W/N/W/W/N/W/S/W/W/S/W/S/W/S/E/N/E/S/E/N/E/S/E/N/W/S/W/N/W/N/E/S/E/E/N/E/S/E/S/E/S/S/N/E/N/GET BALL/PUT IT IN CANNON/OPEN MATCHBOX/GET MATCH/LIGHT IT/LIGHT FUSE WITH MATCH/OPEN COMPARTMENT/GET MASK/E/E/DROP FLASHLIGHT/WEAR SKIS/D/REMOVE SKIS/DROP THEM/GET MATCH/LIGHT CANDLE WITH FIRE/PUT MATCH IN WAX/S/W/DIVE/D/D/W/U/U/N/LIGHT MATCH/LIGHT CANDLE WITH MATCH/N/U/PULL CHAIN/BURN ROPE WITH CANDLE/ENTER RIGHT END OF PLANK/WAIT/DROP ALL BUT CANDLE/GET LADDER/PUT IT IN HOLE/D/GET LADDER/HANG IT ON HOOKS/EXAMINE SAFE/READ PLAQUE/TURN DIAL LEFT 4/TURN IT RIGHT 5/TURN IT LEFT 7/OPEN SAFE/GET FILM/U/GET ALL/U/E/E/GET FLASHLIGHT/W/W/S/GET BUCKET/FILL IT WITH WATER/SE/SW/S/S/S/IN/HANG BUCKET ON THIRD PEG/OUT/U/OPEN DOOR/IN/WAIT/WAIT/OPEN DOOR/OUT/OPEN PANEL/GET HYDRANT/GET PEG/READ NOTE/D/OPEN DOOR/IN/PUT PEG IN HOLE/take gun/throw gun at herman/take stick/throw stick at herman/take club/throw club at herman/stop blade/throw club at belt/turn off saw", + "walkthrough": "N/OPEN MAILBOX/GET PIECE OF PAPER AND BUSINESS CARD/OPEN DOOR/N/TURN ON FLASHLIGHT/N/EXAMINE MODEL/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS BLACK/PRESS BLACK/PRESS WHITE/PRESS WHITE/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS BLACK/PRESS BLUE/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS RED/PRESS RED/PRESS RED/GET RING/E/E/S/GET FILM AND SLIDE/EXAMINE FILM PROJECTOR/REMOVE CAP/DROP IT/TURN ON SLIDE PROJECTOR/INSERT SLIDE IN IT/FOCUS SLIDE LENS/INSERT FILM IN FILM PROJECTOR/TURN ON FILM PROJECTOR/EXAMINE SCREEN/N/GET YELLOW CARD/W/W/S/W/EXAMINE RED STATUETTE/EXAMINE WHITE STATUETTE/EXAMINE BLUE STATUETTE/E/E/LOOK BEHIND PAINTING/GET GREEN CARD/EXAMINE SAFE/TURN DIAL RIGHT 3/TURN IT LEFT 7/TURN IT RIGHT 5/OPEN SAFE/GET GRATER/E/PLAY people/PUSH PIANO NORTH/D/S/GET PILLAR/DROP IT/N/U/PUSH PIANO SOUTH/AGAIN/D/N/GET METER/S/U/OPEN PIANO/GET VIOLET CARD/W/W/DROP RING/DROP GRATER/DROP METER/N/UNLOCK DOOR/OPEN IT/N/GET ORANGE CARD/S/S/OPEN CLOSET/IN/PULL THIRD PEG/OPEN DOOR/OUT/TURN NEWEL/W/S/LOOK UNDER MAT/GET RED CARD/N/E/E/GET SACK/OPEN WINDOW/OPEN SACK/S/GET BLUE CARD/N/W/D/DROP SACK/W/IN/REMOVE BRICK/DROP IT/GET INDIGO CARD/drop all but flashlight/U/U/U/E/D/GET PENGUIN/U/W/D/D/D/take all/OUT/N/W/D/READ BUSINESS CARD/DROP IT/EXAMINE COMPUTER/TURN IT ON/INSERT RED CARD IN SLOT/INSERT ORANGE CARD IN SLOT/INSERT YELLOW CARD IN SLOT/INSERT GREEN CARD IN SLOT/INSERT BLUE CARD IN SLOT/INSERT INDIGO CARD IN SLOT/INSERT VIOLET CARD IN SLOT/EXAMINE LIGHTS/U/GET MATCHBOX/E/GET PAPER/PUT IT ON YELLOWED PAPER/S/GET RED STATUETTE/DIAL 576-3190/E/N/W/W/D/TAKE TOUPEE/U/E/E/S/U/IN/GET SKIS/PULL SECOND PEG/OPEN DOOR/OUT/N/W/W/D/U/E/E/S/DROP TOUPEE/DROP PHOTO/DROP LETTER/GET FINCH/DROP FINCH/N/N/N/NW/GET SHOVEL/NE/N/N/W/N/W/N/W/S/W/W/N/W/S/E/S/E/N/E/S/W/N/W/S/W/N/W/S/W/N/E/N/E/N/E/E/N/E/S/E/E/S/E/N/E/N/E/S/S/S/W/W/S/E/N/W/S/DIG IN GROUND/DROP SHOVEL/GET STAMP/N/E/S/W/N/E/E/N/N/N/W/S/W/S/W/N/W/W/N/W/S/W/W/S/W/S/W/S/E/N/E/S/E/N/E/S/E/N/W/S/W/N/W/N/E/S/E/E/N/E/S/E/S/E/S/S/N/E/N/GET BALL/PUT IT IN CANNON/OPEN MATCHBOX/GET MATCH/LIGHT IT/LIGHT FUSE WITH MATCH/OPEN COMPARTMENT/GET MASK/E/E/DROP FLASHLIGHT/WEAR SKIS/D/REMOVE SKIS/DROP THEM/GET MATCH/LIGHT CANDLE WITH FIRE/PUT MATCH IN WAX/S/W/DIVE/D/D/W/U/U/N/LIGHT MATCH/LIGHT CANDLE WITH MATCH/N/U/PULL CHAIN/BURN ROPE WITH CANDLE/ENTER RIGHT END OF PLANK/WAIT/DROP ALL BUT CANDLE/GET LADDER/PUT IT IN HOLE/D/GET LADDER/HANG IT ON HOOKS/EXAMINE SAFE/READ PLAQUE/TURN DIAL LEFT 4/TURN IT RIGHT 5/TURN IT LEFT 7/OPEN SAFE/GET FILM/U/GET ALL/U/E/E/GET FLASHLIGHT/W/W/S/GET BUCKET/FILL IT WITH WATER/SE/SW/S/S/S/IN/HANG BUCKET ON THIRD PEG/OUT/U/OPEN DOOR/IN/WAIT/WAIT/OPEN DOOR/OUT/OPEN PANEL/GET HYDRANT/GET PEG/READ NOTE/D/OPEN DOOR/IN/PUT PEG IN HOLE/take gun/throw gun at herman/take stick/throw stick at herman/take club/throw club at herman/turn off saw", "grammar" : "aftern/bye/farewe/goodby/greet/greeti/hello/hi/salute/affirm/aye/naw/nay/negati/no/nope/ok/okay/positi/sure/y/yes/yup;back/ski/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk;bathe/swim;brief;diagno;fly;gaze/l/look/peek/peer/stare;hint/hints/aid/help/pray;i/invent;loiter/wait/z;nap/rest/sleep/snooze;play;q/quit;restar;restor;rise/stand;save;score;script;super/superb;t/time;tten;unscri;verbos;versio;advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk off OBJ;affirm/aye/naw/nay/negati/no/nope/ok/okay/positi/sure/y/yes/yup OBJ;aftern/bye/farewe/goodby/greet/greeti/hello/hi/salute OBJ;aid/help/save OBJ;answer/reply/respon OBJ;answer/reply/respon to OBJ;ascend OBJ;ask/interr/query/questi/quiz OBJ;assaul/attack/fight/hit/hurt/injure/kill/murder/punch/slap/slay/stab/strike/whack/wound OBJ;awake/awaken/rouse/startl/surpri/wake OBJ;awake/awaken/rouse/startl/surpri/wake up OBJ;bathe/swim OBJ;bathe/swim in OBJ;bathe/swim to OBJ;bite OBJ;blow OBJ;blow in OBJ;blow out OBJ;blow throug OBJ;blow up OBJ;board/embark OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck in OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck throug OBJ;brush/clean/sweep OBJ;brush/clean/sweep off OBJ;buy OBJ;call/dial/phone OBJ;call/dial/phone up OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take off OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take out OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take up OBJ;chase/follow/pursue OBJ;check/descri/examin/inspec/observ/see/study/survey/watch OBJ;check/descri/examin/inspec/observ/see/study/survey/watch/gaze/l/look/peek/peer/stare in OBJ;check/descri/examin/inspec/observ/see/study/survey/watch/gaze/l/look/peek/peer/stare on OBJ;check/descri/examin/inspec/observ/see/study/survey/watch/gaze/l/look/peek/peer/stare/frisk/ransac/rummag/search for OBJ;chuck/fling/hurl/pitch/throw/toss OBJ;climb/scale OBJ;climb/scale over OBJ;climb/scale throug OBJ;climb/scale under OBJ;climb/scale/carry/catch/confis/get/grab/hold/seize/snatch/steal/take in OBJ;climb/scale/carry/catch/confis/get/grab/hold/seize/snatch/steal/take on OBJ;climb/scale/go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk down OBJ;climb/scale/go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk up OBJ;climb/scale/go/dive/jump/leap/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk out OBJ;close/shut/slam OBJ;concea/hide OBJ;concea/hide behind OBJ;concea/hide under OBJ;consum/devour/eat/gobble/nibble/swallo OBJ;count/tally OBJ;cross/traver OBJ;crush/squash/squeez OBJ;debark/disemb OBJ;defile/molest/rape OBJ;depart/exit/scram/withdr OBJ;descen OBJ;detach/free/unatta/undo/unfast/unhook/untie OBJ;dig/excava at OBJ;dig/excava in OBJ;dig/excava throug OBJ;dig/excava up OBJ;dig/excava with OBJ;distur/feel/pat/pet/rub/touch OBJ;dive/jump/leap OBJ;dive/jump/leap from OBJ;dive/jump/leap off OBJ;dive/jump/leap over OBJ;doff/remove/shed OBJ;don/wear OBJ;douse/exting/quench/snuff OBJ;drag/pull/shove/tug/yank OBJ;drag/pull/shove/tug/yank down OBJ;drag/pull/shove/tug/yank on OBJ;drag/pull/shove/tug/yank up OBJ;drink/guzzle/sip OBJ;drink/guzzle/sip from OBJ;drop/dump OBJ;elevat/hoist/lift/raise OBJ;elevat/hoist/lift/raise up OBJ;employ/exploi/use OBJ;empty OBJ;empty out OBJ;enter OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ;face/flip/rotate/set/spin/turn/twist/whirl off OBJ;face/flip/rotate/set/spin/turn/twist/whirl on OBJ;fill OBJ;find/seek OBJ;fire/shoot OBJ;flush OBJ;fly OBJ;fly on OBJ;fly with OBJ;focus OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge down OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge on OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge out OBJ;frisk/ransac/rummag/search OBJ;frisk/ransac/rummag/search in OBJ;gaze/l/look/peek/peer/stare OBJ;gaze/l/look/peek/peer/stare around OBJ;gaze/l/look/peek/peer/stare at OBJ;gaze/l/look/peek/peer/stare behind OBJ;gaze/l/look/peek/peer/stare down OBJ;gaze/l/look/peek/peer/stare out OBJ;gaze/l/look/peek/peer/stare throug OBJ;gaze/l/look/peek/peer/stare up OBJ;gaze/l/look/peek/peer/stare/frisk/ransac/rummag/search under OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk around OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk behind OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk over OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk throug OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk to OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk under OBJ;go/dive/jump/leap/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk in OBJ;grin/laugh/nod/smile/sneer/wave at OBJ;grin/laugh/nod/smile/sneer/wave to OBJ;hang OBJ;hang up OBJ;hear OBJ;howl/scream/shout/yell OBJ;howl/scream/shout/yell at OBJ;howl/scream/shout/yell to OBJ;ignite/light OBJ;jostle/rattle/shake OBJ;kick OBJ;kick down OBJ;kick in OBJ;kiss/smooch OBJ;knock/pound/rap at OBJ;knock/pound/rap down OBJ;knock/pound/rap on OBJ;leave OBJ;let go OBJ;lie/reclin down OBJ;lie/reclin in OBJ;lie/reclin on OBJ;listen OBJ;listen for OBJ;listen in OBJ;listen to OBJ;lock OBJ;loiter/wait/z for OBJ;lower OBJ;move/roll/shift OBJ;move/roll/shift up OBJ;nap/rest/sleep/snooze in OBJ;nap/rest/sleep/snooze on OBJ;nudge/press/push/ring/thrust OBJ;nudge/press/push/ring/thrust down OBJ;nudge/press/push/ring/thrust on OBJ;nudge/press/push/ring/thrust up OBJ;open/pry/unseal OBJ;open/pry/unseal up OBJ;pick OBJ;pick up OBJ;play OBJ;reach in OBJ;read/skim OBJ;releas OBJ;replac OBJ;ride OBJ;ride in OBJ;ride on OBJ;rise/stand under OBJ;rise/stand up OBJ;rise/stand/dive/jump/leap/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk on OBJ;say/speak/talk/utter OBJ;scrape off OBJ;sit/squat OBJ;sit/squat at OBJ;sit/squat down OBJ;sit/squat in OBJ;sit/squat on OBJ;ski OBJ;ski down OBJ;smell/sniff OBJ;splice OBJ;swing OBJ;swing on OBJ;taste OBJ;tell OBJ;unlock OBJ;unroll OBJ;ask/interr/query/questi/quiz OBJ about OBJ;ask/interr/query/questi/quiz OBJ for OBJ;assaul/attack/fight/hit/hurt/injure/kill/murder/punch/slap/slay/stab/strike/whack/wound OBJ with OBJ;attach/fasten/hook/secure/tie OBJ to OBJ;attach/fasten/hook/secure/tie up OBJ with OBJ;bestow/delive/donate/give/hand/offer/presen OBJ OBJ;bestow/delive/donate/give/hand/offer/presen OBJ to OBJ;blind/jab/poke OBJ with OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck OBJ off OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck OBJ with OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck down OBJ with OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck in OBJ with OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck throug OBJ with OBJ;burn OBJ with OBJ;burn down OBJ with OBJ;buy OBJ with OBJ;call/dial/phone OBJ on OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ from OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ in OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ off OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ on OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ out OBJ;check/descri/examin/inspec/observ/see/study/survey/watch OBJ throug OBJ;check/descri/examin/inspec/observ/see/study/survey/watch OBJ with OBJ;chuck/fling/hurl/pitch/throw/toss OBJ at OBJ;chuck/fling/hurl/pitch/throw/toss OBJ down OBJ;chuck/fling/hurl/pitch/throw/toss OBJ in OBJ;chuck/fling/hurl/pitch/throw/toss OBJ off OBJ;chuck/fling/hurl/pitch/throw/toss OBJ on OBJ;chuck/fling/hurl/pitch/throw/toss OBJ out OBJ;chuck/fling/hurl/pitch/throw/toss OBJ over OBJ;chuck/fling/hurl/pitch/throw/toss OBJ throug OBJ;chuck/fling/hurl/pitch/throw/toss OBJ to OBJ;clip/cut/slash OBJ with OBJ;clip/cut/slash throug OBJ with OBJ;compar OBJ to OBJ;concea/hide OBJ behind OBJ;concea/hide OBJ from OBJ;concea/hide OBJ under OBJ;cover OBJ with OBJ;crush/squash/squeez OBJ on OBJ;detach/free/unatta/undo/unfast/unhook/untie OBJ from OBJ;dig/excava OBJ in OBJ;dig/excava OBJ with OBJ;dig/excava in OBJ with OBJ;distur/feel/pat/pet/rub/touch OBJ with OBJ;doff/remove/shed OBJ from OBJ;drag/pull/shove/tug/yank OBJ out OBJ;drip/pour/spill/sprink OBJ from OBJ;drip/pour/spill/sprink OBJ in OBJ;drip/pour/spill/sprink OBJ on OBJ;drip/pour/spill/sprink out OBJ in OBJ;drop/dump OBJ down OBJ;drop/dump OBJ in OBJ;drop/dump OBJ on OBJ;empty OBJ from OBJ;empty OBJ out OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ left OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ right OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ to OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ with OBJ;feed OBJ OBJ;feed OBJ to OBJ;feed OBJ with OBJ;fill OBJ with OBJ;fire/shoot OBJ at OBJ;fire/shoot OBJ with OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ behind OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ down OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ in OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ on OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ over OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ under OBJ;gaze/l/look/peek/peer/stare at OBJ throug OBJ;hang OBJ from OBJ;hang OBJ on OBJ;hang up OBJ from OBJ;hang up OBJ on OBJ;ignite/light OBJ with OBJ;leave OBJ in OBJ;leave OBJ on OBJ;lock OBJ with OBJ;move/roll/shift OBJ down OBJ;nudge/press/push/ring/thrust OBJ down OBJ;nudge/press/push/ring/thrust OBJ under OBJ;nudge/press/push/ring/thrust OBJ up OBJ;nudge/press/push/ring/thrust/move/roll/shift OBJ OBJ;nudge/press/push/ring/thrust/move/roll/shift OBJ to OBJ;open/pry/unseal OBJ with OBJ;pick OBJ with OBJ;play OBJ on OBJ;read/skim OBJ throug OBJ;read/skim OBJ to OBJ;scrape OBJ off OBJ;show OBJ OBJ;show OBJ to OBJ;splice OBJ with OBJ;swing OBJ at OBJ;tell OBJ about OBJ;unlock OBJ with OBJ;", "max_word_length" : 6 } @@ -269,7 +269,8 @@ "name": "lostpig", "rom": "lostpig.z8", "seed" : 0, - "walkthrough" : "X ME/INVENTORY/X FARM/X FOREST/LOOK FOR PIG/LISTEN/NORTHEAST/X STAIRS/X METAL THING/TAKE TUBE AND TORCH/LOOK INSIDE TUBE/BLOW IN TUBE/X CRACK/EAST/X PIG/FOLLOW PIG/CATCH IT/X FOUNTAIN/X BOWL/X COIN/X CURTAIN/X MAN/NORTH/X WEST MURAL/X EAST MURAL/X STATUE/X HAT/TAKE IT/WEAR IT/SOUTH/SOUTHWEST/X BOX/PUT COIN IN SLOT/PULL LEVER/X BRICK/TAKE IT/SMELL IT/TASTE IT/EAT IT/X DENT/HIT BOX/TAKE COIN/PUT COIN IN SLOT/PULL LEVER/HIT BOX/TAKE ALL FROM BASKET/PUT COIN IN SLOT/TAKE ALL FROM BASKET/X CHAIR/TAKE IT/EAST/X SHADOW/LISTEN/SHOUT/GREET GNOME/TELL GNOME ABOUT GRUNK/ASK GNOME ABOUT STATUE/ASK WHAT GNOME LOOKING FOR/LOOK UNDER BED/TALK TO GNOME ABOUT MOGGLEV/LOOK/LOOK UNDER BED/OPEN TRUNK/X BALL/TAKE BALL/SHOW TORCH TO GNOME/ASK GNOME ABOUT FIRE/SHOW BRICK TO GNOME/ASK GNOME ABOUT MOTHER/EAST/X SHELF/X TOP SHELF/DROP CHAIR/STAND ON CHAIR/X TOP SHELF/TAKE BOOK/X IT/GET DOWN/OPEN CHEST/TAKE POLE/X IT/WEST/SHOW POLE TO GNOME/ASK GNOME ABOUT COLOR MAGNET/SHOW BOOK TO GNOME/GIVE BOOK TO GNOME/EAST/ASK GNOME ABOUT PAGE/EAST/NORTHWEST/EAST/X RIVER/X THING/TAKE THING/CROSS RIVER/TOUCH THING WITH POLE/X KEY/TAKE WATER/FILL HAT WITH WATER/WEST/SOUTHEAST/UNLOCK CHEST/OPEN IT/POUR WATER ON POWDER/LIGHT TORCH WITH FIRE/NORTHWEST/WEST/X CRACK/TAKE PAPER/TAKE PAPER WITH POLE/BURN POLE WITH TORCH/TAKE PAPER WITH POLE/EAST/SOUTHWEST/EAST/GIVE PAPER TO GNOME/WAIT/GO TO PIG/SHOW BRICK TO PIG/DROP ALL BRICKS/Z/Z/Z/Z/TAKE PIG/GO TO STATUE/X HAND/PUT TORCH IN HAND/NORTH/X WINDY TUNNEL/NORTH/SOUTH/TAKE TORCH/GO TO GNOME/ASK GNOME FOR BALL/GIVE TORCH TO GNOME/THANK GNOME/GO TO WINDY CAVE/NORTH/EAST/DROP POLE/NORTHWEST/PLAY WHISTLE/SOUTHEAST/ENTER HOLE/FOLLOW GNOME", + # Adapted from https://jayisgames.com/review/lost-pig.php#walkthrough + "walkthrough" : "X ME/INVENTORY/X FARM/X FOREST/LOOK FOR PIG/LISTEN/NORTHEAST/X STAIRS/X METAL THING/TAKE TUBE AND TORCH/LOOK INSIDE TUBE/BLOW IN TUBE/X CRACK/EAST/X PIG/FOLLOW PIG/CATCH IT/X FOUNTAIN/X BOWL/X COIN/X CURTAIN/X MAN/NORTH/X WEST MURAL/X EAST MURAL/X STATUE/X HAT/TAKE IT/WEAR IT/SOUTH/SOUTHWEST/X BOX/PUT COIN IN SLOT/PULL LEVER/X BRICK/TAKE IT/SMELL IT/TASTE IT/EAT IT/X DENT/HIT BOX/TAKE COIN/PUT COIN IN SLOT/PULL LEVER/HIT BOX/TAKE ALL FROM BASKET/PUT COIN IN SLOT/TAKE ALL FROM BASKET/X CHAIR/TAKE IT/EAST/X SHADOW/LISTEN/SHOUT/GREET GNOME/TELL GNOME ABOUT GRUNK/ASK GNOME ABOUT STATUE/ASK WHAT GNOME LOOKING FOR/LOOK UNDER BED/TALK TO GNOME ABOUT MOGGLEV/LOOK/LOOK UNDER BED/OPEN TRUNK/X BALL/TAKE BALL/SHOW TORCH TO GNOME/ASK GNOME ABOUT FIRE/SHOW BRICK TO GNOME/ASK GNOME ABOUT MOTHER/EAST/X SHELF/X TOP SHELF/DROP CHAIR/STAND ON CHAIR/X TOP SHELF/TAKE BOOK/X IT/GET DOWN/get chair/OPEN CHEST/TAKE POLE/X IT/WEST/SHOW POLE TO GNOME/ASK GNOME ABOUT COLOR MAGNET/SHOW BOOK TO GNOME/GIVE BOOK TO GNOME/EAST/ASK GNOME ABOUT PAGE/EAST/NORTHWEST/EAST/X RIVER/X THING/TAKE THING/CROSS RIVER/TOUCH THING WITH POLE/X KEY/TAKE WATER/FILL HAT WITH WATER/WEST/SOUTHEAST/UNLOCK CHEST/OPEN IT/POUR WATER ON POWDER/LIGHT TORCH WITH FIRE/NORTHWEST/WEST/X CRACK/TAKE PAPER/TAKE PAPER WITH POLE/BURN POLE WITH TORCH/TAKE PAPER WITH POLE/drop whistle/EAST/SOUTHWEST/EAST/GIVE PAPER TO GNOME/WAIT/GO TO PIG/SHOW BRICK TO PIG/DROP ALL BRICKS/Z/Z/Z/Z/TAKE PIG/give brick to pig/Go to table room/drop chair/drop pole/drop key/go to fountain/put coin in fountain/GO TO STATUE/X HAND/PUT TORCH IN HAND/NORTH/X WINDY TUNNEL/NORTH/SOUTH/TAKE TORCH/GO TO GNOME/ASK GNOME FOR BALL/GIVE TORCH TO GNOME/THANK GNOME/GO TO WINDY CAVE/close door/NORTH/EAST/NORTHWEST/SOUTHEAST/N/E/FOLLOW GNOME/FOLLOW GNOME/FOLLOW GNOME", "grammar" : "a/t/talk piglish;about/author/clue/clues/credit/credits/help/hint/hints/info/menu/walkthrou/walkthru;arr/arrr/arrrr/growl/grr/grrr/grrrr/rar/rarr/rarrr/roar/rrr/rrrr/scream/yell/shout;awake/awaken/wake;awake/awaken/wake up;back/step/stand;back/step/stand back;back/step/stand up;bah/grumble/sigh;bathe/dive/swim;burp/fart;bye/farewell/good-bye/goodbye;consider/contempla/think;cough;crap/pee/piss/poop/wee/wizz;cry/frown/grimace/scowl/sniffle/sob;curse/dummy/idiot/stupid/damn/fuck/shit/sod;dance;declaim/deliver;declaim/deliver at wall;declaim/deliver from table top;declaim/deliver from table/tabletop;declaim/deliver monologue/monologue;declaim/deliver monologue/monologue at wall;declaim/deliver monologue/monologue from table/tabletop/top;declaim/deliver monologue/monologue to wall;declaim/deliver to wall;die/q/quit;dig;drink/sip;drool/spit;dross/bother/curses/darn/drat;dunno/shrug;exit/out/outside;exits;fly;fly away;fly up;frotz/plover/plugh/rezrov/wazzum/xyzzy/yoho/zarf/zork;full/fullscore;full/fullscore score;get down;get out/off/up;good bye;greet/hello/hi/a/t/talk/wave;grin/smile/smirk;groan/ugh/ugh!/uh/um;ha/ha!/haw/hee/laugh;ha/ha!/haw/hee/laugh ha/haw/ha!/hee;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/ha!/hee;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/hee ha/haw/ha!/hee;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/hee ha/haw/hee ha/haw/ha!/hee;have/take a bath;have/take bath;hear/listen;heat/warm up;hiccough/hiccup;hide;hooray/hurrah/hurray/woo/woohoo/wooo/woot/yay;hop/jump/skip;i dont/don't know/know!;i dunno/dunno!;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/enter;l/look;la/lalala la;la/lalala la la;la/lalala/sing;leave/go/run/walk;nah/never/nope/no;nod/ok/sure/yeah/yup/y/yes;noscript/unscript;notify;notify off;notify on;nouns/pronouns;objects;places;play;pray;recording;recording off;recording on;relax/rest/wait/z;replay;restart;restore;save;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie/long/verbose/brief/normal;smell/sniff;sneeze;snooze/nap/sleep;snort/grunt/knio/oink/squeal;sorry;stand by;stick out tongue;stick tongue out;stretch;stretch out;take inventory;thank/thanks;thank/thanks you;topic/topics;topic/topics off;topic/topics on;verify;version;whistle;win;win game;win lost pig;win story;yawn;zobleb;ztorf;a/t/talk piglish at/to OBJ;a/t/talk/answer/say/speak to OBJ;adjust/set OBJ;adjust/set/burn/light OBJ on fire;answer OBJ;apologise/apologize to OBJ;arr/arrr/arrrr/growl/grr/grrr/grrrr/rar/rarr/rarrr/roar/rrr/rrrr/scream/yell at OBJ;attach/fasten/tie OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;back/step/stand away from OBJ;bah/grumble/sigh at/to OBJ;beat/kick/poke/prod/slap/spank/attack/break/crack/destroy/fight/hit/murder/punch/smash/thump/wreck OBJ;bite/chew/lick/taste/eat OBJ;blow OBJ;blow on/at/in OBJ;bother/curses/darn/drat OBJ;buy/purchase OBJ;call OBJ;call to/for OBJ;carry/hold OBJ;chase OBJ;chase after OBJ;check/describe/examine/watch/x OBJ;chop/cut/prune/slice OBJ;climb/scale OBJ;climb/scale into/in/inside OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;complain to/at OBJ;consider/contempla OBJ;consider/contempla/think about OBJ;cook/burn/light/burn/light OBJ;count OBJ;crap/pee/piss/poop/wee/wizz on/in OBJ;cry/frown/grimace/scowl/sniffle/sob at/to OBJ;curse/damn/fuck/shit/sod OBJ;dance with OBJ;discard/drop OBJ;disrobe/doff/shed/remove OBJ;dive/swim OBJ;dive/swim in OBJ;don/wear OBJ;douse/extinguis/smother OBJ;drag/pull OBJ;draw OBJ;draw OBJ;drink/sip OBJ;drink/sip from OBJ;drool/spit at/in/on OBJ;drown/splash OBJ;dry OBJ;dry OBJ off;dry off OBJ;dummy/idiot/stupid OBJ;dust/polish/rub/scrub/shine/sweep/wipe OBJ;earn OBJ;empty OBJ out;equip/wield OBJ;feel/fondle/grope/touch in/inside OBJ;fill OBJ;flip OBJ;frotz/plover/plugh/rezrov/wazzum/xyzzy/yoho/zarf/zork OBJ;get in/into/on/onto OBJ;get off OBJ;get/catch/grab/pin/steal/swipe/trap/take OBJ;go/run/walk back to OBJ;go/run/walk to OBJ;go/run/walk/enter OBJ;goto/find/follow/seek/go/run/walk OBJ;greet/hello/hi OBJ;grin/smile/smirk at/to OBJ;groan/ugh/ugh!/uh/um OBJ;grunt/knio/oink/squeal at OBJ;ha/ha!/haw/hee/laugh OBJ;ha/ha!/haw/hee/laugh at OBJ;ha/ha!/haw/hee/laugh ha/haw/hee OBJ;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/ha!/hee OBJ;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/hee ha/haw/ha!/hee OBJ;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/hee ha/haw/hee ha/haw/hee OBJ;hear/listen OBJ;hear/listen for OBJ;hear/listen to OBJ;heat/warm OBJ;heat/warm OBJ up;heat/warm up OBJ;heat/warm up by OBJ;heat/warm up over by OBJ;heat/warm up with OBJ;hide/get/go/run/walk behind/under/in OBJ;hooray/hurrah/hurray/woo/woohoo/wooo/woot/yay OBJ;hooray/hurrah/hurray/woo/woohoo/wooo/woot/yay for OBJ;hop/jump/skip on/at OBJ;huff/puff and puff at OBJ;huff/puff at OBJ;kill OBJ;l/look at OBJ;l/look behind OBJ;l/look inside/in/into/through/on OBJ;l/look under OBJ;leave/exit/out/outside OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit at OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;lock OBJ;molest/embrace/hug/kiss OBJ;nod/ok/sure/yeah/yup at/to OBJ;nudge/straighte/clear/move/press/push/shift OBJ;open/uncover/undo/unwrap OBJ;paw OBJ;paw at OBJ;peel off OBJ;pet/scratch/feel/fondle/grope/touch OBJ;pick OBJ up;pick up OBJ;play OBJ;play with/on/in OBJ;pour/empty OBJ;pour/empty out OBJ;put OBJ down;put down OBJ;put on OBJ;put/blow OBJ out;put/blow out OBJ;reach into/in OBJ;read OBJ;remember OBJ;repair/fix OBJ;rip/tear OBJ;rock/shake OBJ;rotate/screw/turn/twist/unscrew OBJ;rotate/screw/turn/twist/unscrew/switch OBJ off;rotate/screw/turn/twist/unscrew/switch OBJ on;rotate/screw/turn/twist/unscrew/switch on OBJ;rotate/screw/turn/twist/unscrew/switch/close/cover/shut off OBJ;scare/threaten OBJ;scoop up OBJ;scoop/peel OBJ;search OBJ;search/l/look for OBJ;shout at/to OBJ;shout for OBJ;sing at/to OBJ;smoke OBJ;snort/smell/sniff OBJ;stand by OBJ;stand in OBJ;stand on OBJ;step in/into OBJ;step on/onto OBJ;step/stand near OBJ;step/stand next to OBJ;stick out tongue at OBJ;stick tongue out at OBJ;swallow OBJ;switch OBJ;take OBJ off;take off OBJ;thank/thanks OBJ;thank/thanks you OBJ;topic/topics OBJ;torture OBJ;toss/throw OBJ;unlock OBJ;vault/cross/hop/jump/skip OBJ;vault/hop/jump/skip over OBJ;wash/clean OBJ;wave at/to OBJ;wave/swing OBJ;waylay/wrestle OBJ;wrestle with OBJ;wring/squash/squeeze OBJ out;wring/squash/squeeze out OBJ;wring/squidge/squish/squash/squeeze OBJ;adjust/set OBJ to OBJ;adjust/set/burn/light OBJ on fire with/using OBJ;answer/say/speak OBJ to OBJ;attach/fasten/tie OBJ to OBJ;beat/kick/poke/prod/slap/spank OBJ at OBJ;beat/kick/poke/prod/slap/spank/attack/break/crack/destroy/fight/hit/murder/punch/smash/thump/wreck OBJ with OBJ;burn/light OBJ with/using OBJ;catch/grab/pin/steal/swipe/trap/take OBJ off OBJ;chase OBJ OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift OBJ in/into/to/toward OBJ;consult OBJ about OBJ;consult OBJ on OBJ;cook/burn/light OBJ with OBJ;dip/dunk OBJ in/inside/into OBJ;discard/drop OBJ at/against/on/onto OBJ;discard/drop OBJ in/into/down OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;display/present/show/display/present/show OBJ OBJ;display/present/show/display/present/show OBJ to OBJ;douse/extinguis/smother OBJ with/in OBJ;draw OBJ with OBJ;drown/splash OBJ on/at OBJ;drown/splash OBJ with/in OBJ;dry OBJ off on OBJ;dry OBJ off on OBJ;dry OBJ off with OBJ;dry OBJ off with OBJ;dry OBJ on OBJ;dry OBJ on OBJ;dry OBJ with OBJ;dry OBJ with OBJ;dry off OBJ with OBJ;dry off OBJ with OBJ;dust/polish/rub/scrub/shine/sweep/wipe OBJ on/over/across OBJ;empty OBJ on/onto OBJ;empty OBJ to/in/into OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feel/fondle/grope/touch OBJ to OBJ;feel/fondle/grope/touch in/inside OBJ with OBJ;fill OBJ from/with OBJ;force/jemmy/lever/prise/prize/pry OBJ apart/open with OBJ;force/jemmy/lever/prise/prize/pry apart/open OBJ with OBJ;get/catch/grab/pin/steal/swipe/trap/take/remove OBJ from OBJ;get/catch/grab/pin/steal/swipe/trap/take/remove/peel OBJ with OBJ;get/take OBJ in OBJ;give/offer/pay OBJ and OBJ;give/offer/pay over OBJ to OBJ;heat/warm OBJ up with OBJ;heat/warm OBJ up with OBJ;heat/warm OBJ with OBJ;heat/warm OBJ with OBJ;heat/warm up OBJ with OBJ;heat/warm up OBJ with OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;open/uncover/undo/unwrap OBJ with OBJ;pick OBJ up in OBJ;pick OBJ up with OBJ;pick up OBJ in OBJ;pick up OBJ with OBJ;point OBJ at OBJ;point at OBJ with OBJ;pour OBJ into/in OBJ;pour OBJ onto/on OBJ;pour out OBJ into/in OBJ;pour out OBJ onto/on OBJ;put OBJ out with/in OBJ;put out OBJ with/in OBJ;reach OBJ in/into OBJ;reach into/in OBJ with OBJ;reach/feel/fondle/grope/touch/dust/polish/rub/scrub/shine/sweep/wipe/clear/move/press/push/shift OBJ with OBJ;rip/tear/chop/cut/prune/slice OBJ with OBJ;scoop OBJ up with/into OBJ;scoop OBJ with/into OBJ;scoop up OBJ with/into OBJ;shout OBJ at/to OBJ;stick/put OBJ over/across OBJ;stick/put/discard/drop OBJ on/onto OBJ;take OBJ off of OBJ;torture/kill OBJ with OBJ;toss/throw OBJ at/against/on/onto OBJ;toss/throw/stick/put OBJ in/inside/into OBJ;transfer OBJ to OBJ;unlock/force/jemmy/lever/prise/prize/pry OBJ with OBJ;vault OBJ with OBJ;vault over OBJ with OBJ;wash/clean OBJ with/in OBJ;wring/squash/squeeze OBJ out over/into OBJ;wring/squidge/squish/squash/squeeze OBJ over/into OBJ;", "max_word_length" : 9 } @@ -417,7 +418,7 @@ "rom": "sorcerer.z3", "seed" : 0, # Walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip - "walkthrough": "WAIT/FROTZ BOOK/GET UP/W/READ NOTE/DROP IT/W/OPEN DESK/GET BOX AND JOURNAL/LOOK BEHIND TAPESTRY/GET KEY/OPEN JOURNAL/READ IT/DROP JOURNAL AND KEY/E/S/S/W/GET VIAL, CALENDAR AND MATCHBOOK/E/OPEN RECEPTACLE/READ MATCHBOOK/PUT IT IN RECEPTACLE/E/GET SCROLL/READ IT/GNUSTO MEEF SPELL/W/D/PRESS white, gray, black, red, black/GET SCROLL/READ IT/OPEN VIAL/DRINK OCHRE POTION/DROP VIAL/U/OPEN RECEPTACLE/GET ORANGE VIAL/N/W/GET SCROLL/READ IT/GNUSTO GASPAR SPELL/AIMFIZ BELBOZ/NE/E/NE/LEARN PULVER/PULVER RIVER/D/NE/GET GUANO, SCROLL AND AMBER VIAL/READ SCROLL/GNUSTO FWEEP SPELL/D/S/GET INDIGO VIAL/W/D/W/SW/SW/W/LEARN IZYUK SPELL/AGAIN/IZYUK ME/W/W/N/GET COIN/S/E/IZYUK ME/E/E/NE/NE/E/E/WAKE GNOME/GIVE COIN TO GNOME/SEARCH GNOME/E/E/N/N/SLEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/DROP ALL/E/FWEEP ME/N/E/S/S/W/D/E/E/N/N/U/U/S/E/GET SCROLL/READ IT/PUT IT IN HOLE/FWEEP ME/W/W/S/E/D/D/W/W/U/U/N/N/D/E/FWEEP ME/S/E/N/D/W/S/W/U/W/WAIT/WAIT/GET ALL/S/S/E/OPEN BOX/DROP BOX/GET AMULET AND SCROLL/GNUSTO SWANZO SPELL/LEARN IZYUK/W/W/W/W/U/U/W/W/IZYUK ME/NE/SE/E/LOWER FLAG/EXAMINE IT/DROP CALENDAR/GET AQUA VIAL/E/LOOK IN CANNON/PUT GUANO IN CANNON/GET SCROLL/READ IT/W/W/LEARN IZYUK/IZYUK ME/NW/SW/W/D/D/S/S/SW/W/GIVE COIN TO GNOME/W/W/S/SLEEP/OPEN AQUA VIAL/DRINK POTION/DROP AQUA VIAL/GET BALL/THROW IT AT RABBIT/READ GLITTERING SCROLL/GNUSTO MALYON SPELL/N/E/E/NE/S/YONK MALYON SPELL/LEARN MALYON/MALYON DRAGON/S/OPEN ORANGE VIAL/FROTZ ME/E/DRINK POTION/THROW ALL BUT BOOK INTO LOWER CHUTE/GIVE BOOK TO TWIN/E/TURN DIAL TO 639/OPEN DOOR/E/GET ROPE/U/NW/GET TIMBER/NW/W/TIE ROPE TO TIMBER/PUT TIMBER ACROSS CHUTE/THROW ROPE INTO CHUTE/D/GET SHIMMERING SCROLL/READ IT/GOLMAC ME/OPEN LAMP/GET SMELLY SCROLL/D/WAIT/WAIT/SAY TO TWIN \"THE COMBINATION IS 639\"/D/WAIT/SLEEP/LEARN MEEF, MEEF AND SWANZO/DROP ALL/E/D/MEEF WEEDS/OPEN CRATE/GET SUIT/U/W/GET ALL/WEAR SUIT/NE/N/MEEF VINES/W/W/OPEN WHITE DOOR/VARDIK ME/SWANZO BELBOZ", + "walkthrough": "WAIT/FROTZ BOOK/GET UP/W/READ NOTE/DROP IT/W/OPEN DESK/GET BOX AND JOURNAL/LOOK BEHIND TAPESTRY/GET KEY/OPEN JOURNAL/READ JOURNAL/DROP JOURNAL AND KEY/E/S/S/W/GET VIAL, CALENDAR AND MATCHBOOK/E/OPEN RECEPTACLE/READ MATCHBOOK/PUT IT IN RECEPTACLE/E/GET SCROLL/READ IT/GNUSTO MEEF SPELL/W/D/PRESS white, gray, black, red, black/GET SCROLL/READ IT/OPEN VIAL/DRINK OCHRE POTION/DROP VIAL/U/OPEN RECEPTACLE/GET ORANGE VIAL/N/W/GET SCROLL/READ IT/GNUSTO GASPAR SPELL/AIMFIZ BELBOZ/NE/E/NE/LEARN PULVER/PULVER RIVER/D/NE/GET GUANO, SCROLL AND AMBER VIAL/READ SCROLL/GNUSTO FWEEP SPELL/D/S/GET INDIGO VIAL/W/D/W/SW/SW/W/LEARN IZYUK SPELL/AGAIN/IZYUK ME/W/W/N/GET COIN/S/E/IZYUK ME/E/E/NE/NE/E/E/WAKE GNOME/GIVE COIN TO GNOME/SEARCH GNOME/E/E/N/N/SLEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/DROP ALL/E/FWEEP ME/N/E/S/S/W/D/E/E/N/N/U/U/S/E/GET SCROLL/READ IT/PUT IT IN HOLE/FWEEP ME/W/W/S/E/D/D/W/W/U/U/N/N/D/E/FWEEP ME/S/E/N/D/W/S/W/U/W/WAIT/WAIT/GET ALL/S/S/E/OPEN BOX/DROP BOX/GET AMULET AND SCROLL/GNUSTO SWANZO SPELL/LEARN IZYUK/W/W/W/W/U/U/W/W/IZYUK ME/NE/SE/E/LOWER FLAG/EXAMINE IT/DROP CALENDAR/GET AQUA VIAL/E/LOOK IN CANNON/PUT GUANO IN CANNON/GET SCROLL/READ IT/W/W/LEARN IZYUK/IZYUK ME/NW/SW/W/D/D/S/S/SW/W/GIVE COIN TO GNOME/W/W/S/SLEEP/OPEN AQUA VIAL/DRINK POTION/DROP AQUA VIAL/GET BALL/THROW IT AT RABBIT/READ GLITTERING SCROLL/GNUSTO MALYON SPELL/N/E/E/NE/S/YONK MALYON SPELL/LEARN MALYON/MALYON DRAGON/S/OPEN ORANGE VIAL/FROTZ ME/E/DRINK POTION/THROW ALL BUT BOOK INTO LOWER CHUTE/GIVE BOOK TO TWIN/E/TURN DIAL TO 639/OPEN DOOR/E/GET ROPE/U/NW/GET TIMBER/NW/W/TIE ROPE TO TIMBER/PUT TIMBER ACROSS CHUTE/THROW ROPE INTO CHUTE/D/GET SHIMMERING SCROLL/READ IT/GOLMAC ME/OPEN LAMP/GET SMELLY SCROLL/D/WAIT/WAIT/SAY TO TWIN \"THE COMBINATION IS 639\"/D/WAIT/SLEEP/LEARN MEEF, MEEF AND SWANZO/DROP ALL/E/D/MEEF WEEDS/OPEN CRATE/GET SUIT/U/W/GET ALL/WEAR SUIT/NE/N/MEEF VINES/W/W/OPEN WHITE DOOR/VARDIK ME/SWANZO BELBOZ", "grammar" : "advanc/go/hike/procee/run/step/tramp/trudge/walk;answer/reply/respon;bathe/swim/wade;bound/dive/hurdle/jump/leap/vault;brief;call/procla/say/talk/utter;cavort/gambol/hop/skip;chase/follow/pursue;concea/enscon/hide/secret/stash;damn/fuck/shit;depart/exit/withdr;diagno;enter;fly;fweep;gaspar;gaze/l/look/stare;greeti/hello/hi/saluta;help/hint/hints;howl/scream/shout/yell;i/invent;land;leave;nap/snooze/sleep;q/quit;restar;restor;rise/stand;save;score;script;spells;super/superb;t/time;thank/thanks;unscri;verbos;versio;vezza;wait/z;advanc/go/hike/procee/run/step/tramp/trudge/walk OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk around OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk down OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk in OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk on OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk throug OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk to OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk up OBJ;aimfiz OBJ;answer/reply/respon OBJ;assaul/attack/fight/hit/hurt/injure OBJ;awake/rouse/startl/surpri/wake OBJ;awake/rouse/startl/surpri/wake up OBJ;banish/drive/exorci OBJ;banish/drive/exorci away OBJ;banish/drive/exorci out OBJ;bathe/swim/wade in OBJ;beckon/brandi/motion/wave OBJ;beckon/brandi/motion/wave to OBJ;beckon/brandi/motion/wave/howl/scream/shout/yell at OBJ;bite OBJ;blow out OBJ;blow up OBJ;board/embark/ride OBJ;bound/dive/hurdle/jump/leap/vault across OBJ;bound/dive/hurdle/jump/leap/vault from OBJ;bound/dive/hurdle/jump/leap/vault in OBJ;bound/dive/hurdle/jump/leap/vault off OBJ;bound/dive/hurdle/jump/leap/vault/advanc/go/hike/procee/run/step/tramp/trudge/walk over OBJ;break/crack/damage/demoli/destro/smash/wreck OBJ;call/procla/say/talk/utter to OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take off OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take out OBJ;cast/incant/invoke OBJ;chase/follow/pursue OBJ;check/descri/examin/inspec/observ/study/survey/watch OBJ;check/descri/examin/inspec/observ/study/survey/watch on OBJ;check/descri/examin/inspec/observ/study/survey/watch/gaze/l/look/stare in OBJ;check/descri/examin/inspec/observ/study/survey/watch/gaze/l/look/stare/frisk/ransac/rummag/search for OBJ;climb/scale OBJ;climb/scale down OBJ;climb/scale over OBJ;climb/scale up OBJ;climb/scale/rest/sit/squat/carry/catch/confis/get/grab/hold/seize/snatch/take in OBJ;climb/scale/rest/sit/squat/carry/catch/confis/get/grab/hold/seize/snatch/take on OBJ;close/shut OBJ;combin/combo OBJ;concea/enscon/hide/secret/stash OBJ;concea/enscon/hide/secret/stash behind OBJ;concea/enscon/hide/secret/stash under OBJ;consum/devour/eat/gobble/ingest/nibble/taste OBJ;count/tally OBJ;cross/ford/traver OBJ;debark/disemb OBJ;defile/molest/rape/ravish OBJ;deflat OBJ;depart/exit/withdr OBJ;descen OBJ;dig/excava in OBJ;dig/excava throug OBJ;dig/excava with OBJ;discha/fire/shoot OBJ;disloc/displa/move/shift/drag/pull/shove/tug/yank OBJ;dispat/kill/murder/slay/stab/vanqui OBJ;doff/remove/shed OBJ;don/wear OBJ;douse/exting/quench OBJ;drag/pull/shove/tug/yank down OBJ;drag/pull/shove/tug/yank on OBJ;drink/guzzle/imbibe/quaff/sip/swallo/swill OBJ;drink/guzzle/imbibe/quaff/sip/swallo/swill from OBJ;drop/dump/releas OBJ;elevat/hoist/lift/raise OBJ;elevat/hoist/lift/raise up OBJ;enter OBJ;feel/pat/pet/rub/touch OBJ;fill OBJ;find/see/seek OBJ;flip/set/turn OBJ;flip/set/turn off OBJ;flip/set/turn on OBJ;fly OBJ;forget/unlear/unmemo OBJ;free/unatta/unfast/unhook/untie OBJ;frisk/ransac/rummag/search OBJ;frisk/ransac/rummag/search in OBJ;frotz OBJ;fweep OBJ;gaspar OBJ;gaze/l/look/stare OBJ;gaze/l/look/stare around OBJ;gaze/l/look/stare at OBJ;gaze/l/look/stare behind OBJ;gaze/l/look/stare down OBJ;gaze/l/look/stare on OBJ;gaze/l/look/stare throug OBJ;gaze/l/look/stare under OBJ;gaze/l/look/stare up OBJ;gestur/point at OBJ;gestur/point to OBJ;gnusto OBJ;golmac OBJ;greeti/hello/hi/saluta OBJ;gyrate/rotate/spin/whirl OBJ;harken/listen for OBJ;harken/listen to OBJ;inflat OBJ;insert/lay/place/put/stuff down OBJ;insert/lay/place/put/stuff on OBJ;izyuk OBJ;jostle/rattle/shake OBJ;kick OBJ;kiss/smooch OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;know/learn/memori OBJ;launch OBJ;lean on OBJ;leave OBJ;lie/reclin/repose down OBJ;lie/reclin/repose on OBJ;light OBJ;lower OBJ;malyon OBJ;meef OBJ;nap/snooze/sleep in OBJ;nap/snooze/sleep on OBJ;nudge/press/push/thrust OBJ;nudge/press/push/thrust on OBJ;open OBJ;open up OBJ;pay OBJ;pick OBJ;pick up OBJ;play OBJ;polish/shine/wax OBJ;pour/spill/sprink OBJ;pulver OBJ;pump up OBJ;reach in OBJ;read/skim OBJ;read/skim about OBJ;rest/sit/squat at OBJ;rest/sit/squat down OBJ;rezrov OBJ;rise/stand on OBJ;rise/stand/carry/catch/confis/get/grab/hold/seize/snatch/take up OBJ;roll up OBJ;send for OBJ;slide OBJ;smell/sniff/whiff OBJ;spray OBJ;squeez OBJ;strike OBJ;swanzo OBJ;swing OBJ;tell OBJ;thank/thanks OBJ;tortur OBJ;vardik OBJ;vezza OBJ;wait/z for OBJ;what/whats OBJ;where/wheres OBJ;who/whos OBJ;yomin OBJ;yonk OBJ;aimfiz OBJ to OBJ;apply OBJ to OBJ;ask/interr/query/quiz OBJ about OBJ;ask/interr/query/quiz OBJ for OBJ;assaul/attack/fight/hit/hurt/injure OBJ with OBJ;attach/fasten/secure/tie OBJ to OBJ;attach/fasten/secure/tie up OBJ with OBJ;beckon/brandi/motion/wave OBJ at OBJ;bestow/donate/feed/give/hand/offer/presen OBJ OBJ;bestow/donate/feed/give/hand/offer/presen OBJ to OBJ;blind/jab/poke OBJ with OBJ;break/crack/damage/demoli/destro/smash/wreck OBJ with OBJ;break/crack/damage/demoli/destro/smash/wreck down OBJ with OBJ;burn/combus/ignite/kindle OBJ with OBJ;burn/combus/ignite/kindle down OBJ with OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ from OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ in OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ off OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ out OBJ;cast/incant/invoke OBJ at OBJ;cast/incant/invoke OBJ on OBJ;chuck/fling/hurl/pitch/throw/toss OBJ at OBJ;chuck/fling/hurl/pitch/throw/toss OBJ off OBJ;chuck/fling/hurl/pitch/throw/toss OBJ over OBJ;chuck/fling/hurl/pitch/throw/toss OBJ throug OBJ;cleave/cut/gash/lacera/sever/slash/slice/split OBJ with OBJ;cleave/cut/gash/lacera/sever/slash/slice/split throug OBJ with OBJ;clog/fix/glue/patch/plug/repair OBJ with OBJ;compar OBJ to OBJ;concea/enscon/hide/secret/stash OBJ from OBJ;dig/excava OBJ with OBJ;dig/excava in OBJ with OBJ;dispat/kill/murder/slay/stab/vanqui OBJ with OBJ;dissol/liquif/melt/thaw OBJ with OBJ;drop/dump/releas/chuck/fling/hurl/pitch/throw/toss/insert/lay/place/put/stuff OBJ down OBJ;drop/dump/releas/chuck/fling/hurl/pitch/throw/toss/insert/lay/place/put/stuff OBJ in OBJ;feel/pat/pet/rub/touch OBJ with OBJ;fill OBJ at OBJ;fill OBJ with OBJ;flip/set/turn OBJ for OBJ;flip/set/turn OBJ to OBJ;flip/set/turn OBJ with OBJ;free/unatta/unfast/unhook/untie OBJ from OBJ;gaze/l/look/stare at OBJ throug OBJ;gaze/l/look/stare up OBJ in OBJ;hone/sharpe OBJ with OBJ;insert/lay/place/put/stuff OBJ across OBJ;insert/lay/place/put/stuff OBJ behind OBJ;insert/lay/place/put/stuff OBJ on OBJ;insert/lay/place/put/stuff OBJ over OBJ;insert/lay/place/put/stuff OBJ under OBJ;light OBJ with OBJ;lock OBJ with OBJ;lower OBJ down OBJ;lower OBJ in OBJ;open OBJ with OBJ;pay OBJ OBJ;pay OBJ to OBJ;pay OBJ with OBJ;pick OBJ with OBJ;polish/shine/wax OBJ with OBJ;pour/spill/sprink OBJ from OBJ;pour/spill/sprink OBJ in OBJ;pour/spill/sprink OBJ on OBJ;pump up OBJ with OBJ;read/skim OBJ throug OBJ;read/skim about OBJ in OBJ;show OBJ OBJ;show OBJ to OBJ;slide/nudge/press/push/thrust OBJ OBJ;slide/nudge/press/push/thrust OBJ to OBJ;slide/nudge/press/push/thrust OBJ under OBJ;spray OBJ on OBJ;spray OBJ with OBJ;squeez/drop/dump/releas/chuck/fling/hurl/pitch/throw/toss OBJ on OBJ;strike OBJ with OBJ;swing OBJ at OBJ;unlock OBJ with OBJ;", "max_word_length" : 6 } diff --git a/jericho/jericho.py b/jericho/jericho.py index 38e14ec3..0744f749 100644 --- a/jericho/jericho.py +++ b/jericho/jericho.py @@ -33,6 +33,10 @@ from .template_action_generator import TemplateActionGenerator from jericho.util import chunk + +JERICHO_NB_PROPERTIES = 23 # As defined in frotz_interface.h +JERICHO_PROPERTY_LENGTH = 64 # As defined in frotz_interface.h + JERICHO_PATH = importlib.resources.files("jericho") FROTZ_LIB_PATH = os.path.join(JERICHO_PATH, 'libfrotz.so') @@ -89,7 +93,9 @@ class ZObject(Structure): ("sibling", c_int), ("child", c_int), ("_attr", c_byte*4), - ("properties", c_ubyte*16)] + ("_prop_ids", c_ubyte*JERICHO_NB_PROPERTIES), + ("_prop_lengths", c_ubyte*JERICHO_NB_PROPERTIES), + ("_prop_data", (c_ubyte*JERICHO_PROPERTY_LENGTH)*JERICHO_NB_PROPERTIES)] def __init__(self): self.num = -1 @@ -97,7 +103,9 @@ def __init__(self): def __str__(self): return "Obj{}: {} Parent{} Sibling{} Child{} Attributes {} Properties {}"\ .format(self.num, self.name, self.parent, self.sibling, self.child, - np.nonzero(self.attr)[0].tolist(), [p for p in self.properties if p != 0]) + np.nonzero(self.attr)[0].tolist(), + {k: " ".join(f"{v:02x}" for v in p) for k, p in self.properties.items()} + ) def __repr__(self): return str(self) @@ -113,7 +121,9 @@ def __eq__(self, other): self._attr[1] == other._attr[1] and \ self._attr[2] == other._attr[2] and \ self._attr[3] == other._attr[3] and \ - self.properties[:] == other.properties[:] + self._prop_ids[:] == other._prop_ids[:] and \ + self._prop_lengths[:] == other._prop_lengths[:] and \ + np.array_equal(self._prop_data, other._prop_data) return False def __hash__(self): @@ -127,6 +137,11 @@ def name(self): def attr(self): return np.unpackbits(np.array(self._attr, dtype=np.uint8)) + @property + def properties(self): + return {i: d[:l] for i, d, l in zip(self._prop_ids, self._prop_data, self._prop_lengths) if i != 0} + + class DictionaryWord(Structure): """ @@ -252,6 +267,10 @@ def _load_frotz_lib(): frotz_lib.restore_str.restype = int frotz_lib.world_changed.argtypes = [] frotz_lib.world_changed.restype = int + + frotz_lib.get_world_state_hash.argtypes = [] + frotz_lib.get_world_state_hash.restype = int + frotz_lib.get_cleaned_world_diff.argtypes = [c_void_p, c_void_p] frotz_lib.get_cleaned_world_diff.restype = None frotz_lib.game_over.argtypes = [] @@ -279,6 +298,11 @@ def _load_frotz_lib(): frotz_lib.set_narrative_text.argtypes = [c_char_p] frotz_lib.set_narrative_text.restype = None + frotz_lib.get_state_changed.argtypes = [] + frotz_lib.get_state_changed.restype = int + frotz_lib.set_state_changed.argtypes = [c_int] + frotz_lib.set_state_changed.restype = None + frotz_lib.getPC.argtypes = [] frotz_lib.getPC.restype = int frotz_lib.setPC.argtypes = [c_int] @@ -336,6 +360,10 @@ def _load_frotz_lib(): frotz_lib.get_dictionary.restype = None frotz_lib.ztools_cleanup.argtypes = [] frotz_lib.ztools_cleanup.restype = None + + frotz_lib.update_objs_tracker.argtypes = [] + frotz_lib.update_objs_tracker.restype = None + return frotz_lib @@ -488,7 +516,7 @@ def step(self, action): score = self.frotz_lib.get_score() reward = score - old_score return next_state, reward, (self.game_over() or self.victory()),\ - {'moves':self.get_moves(), 'score':score} + {'moves':self.get_moves(), 'score':score, 'victory': self.victory()} def close(self): ''' Cleans up the FrotzEnv, freeing any allocated memory. ''' @@ -591,7 +619,7 @@ def set_state(self, state): >>> env.set_state(state) # Whew, let's try something else ''' - ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative = state + ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative, state_changed = state self.frotz_lib.setRng(*rng) self.frotz_lib.setRAM(as_ctypes(ram)) self.frotz_lib.setStack(as_ctypes(stack)) @@ -601,6 +629,8 @@ def set_state(self, state): self.frotz_lib.set_opcode(opcode) self.frotz_lib.setFrameCount(frame_count) self.frotz_lib.set_narrative_text(narrative) + self.frotz_lib.set_state_changed(state_changed) + self.frotz_lib.update_objs_tracker() def get_state(self): ''' @@ -628,7 +658,8 @@ def get_state(self): frame_count = self.frotz_lib.getFrameCount() rng = self.frotz_lib.getRngA(), self.frotz_lib.getRngInterval(), self.frotz_lib.getRngCounter() narrative = self.frotz_lib.get_narrative_text() - state = ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative + state_changed = self.frotz_lib.get_state_changed() + state = ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative, state_changed return state def get_max_score(self): @@ -729,10 +760,26 @@ def get_world_state_hash(self): '79c750fff4368efef349b02ff50ffc23' """ + md5_hash = np.zeros(64, dtype=np.uint8) + self.frotz_lib.get_world_state_hash(as_ctypes(md5_hash)) + md5_hash = (b"").join(md5_hash.view(c_char)).decode('cp1252') + return md5_hash + + def get_world_state_hash_old(self): + import hashlib world_objs_str = ', '.join([str(o) for o in self.get_world_objects(clean=True)]) special_ram_addrs = self._get_special_ram() - world_state_str = world_objs_str + str(special_ram_addrs) + + ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative = self.get_state() + # Return address of current routine call. (See frotz/src/common/process.c:569) + stack = stack.view("uint16") + ret_pc = stack[fp+2] | (stack[fp+2+1] << 9) + + # print(sum(stack), pc, sp, fp, ret_pc, frame_count, opcode) + # print(pc, str(special_ram_addrs) + str(ret_pc)) + + world_state_str = world_objs_str + str(special_ram_addrs) + str(ret_pc) m = hashlib.md5() m.update(world_state_str.encode('utf-8')) return m.hexdigest() @@ -789,13 +836,13 @@ def _get_world_diff(self): changed, 3) tuple of world objects whose attributes have been cleared, and 4) tuple of special ram locations whose values have changed. ''' - objs = np.zeros(64, dtype=np.uint16) - dest = np.zeros(64, dtype=np.uint16) + objs = np.zeros(64+64, dtype=np.uint16) + dest = np.zeros(64+64, dtype=np.uint16) self.frotz_lib.get_cleaned_world_diff(as_ctypes(objs), as_ctypes(dest)) # First 16 spots allocated for objects that have moved moved_objs = [] for i in range(16): - if objs[i] == 0 or dest[i] == 0: + if objs[i] == 0 and dest[i] == 0: break moved_objs.append((objs[i], dest[i])) # Second 16 spots allocated for objects that have had attrs set @@ -811,12 +858,18 @@ def _get_world_diff(self): break cleared_attrs.append((objs[i], dest[i])) # Fourth 16 spots allocated to ram locations & values that have changed + prop_diffs = [] + for i in range(48, 48+64): + if objs[i] == 0: + break + prop_diffs.append((objs[i], dest[i])) + # Fourth 16 spots allocated to ram locations & values that have changed ram_diffs = [] - for i in range(48, 64): + for i in range(48+64, 48+64+16): if objs[i] == 0: break ram_diffs.append((objs[i], dest[i])) - return (tuple(moved_objs), tuple(set_attrs), tuple(cleared_attrs), tuple(ram_diffs)) + return (tuple(moved_objs), tuple(set_attrs), tuple(cleared_attrs), tuple(prop_diffs), tuple(ram_diffs)) def _score_object_names(self, interactive_objs): """ Attempts to choose a sensible name for an object, typically a noun. """ @@ -918,18 +971,21 @@ def _identify_interactive_objects(self, observation='', use_object_tree=False): desc2obj = {} # Filter out objs that aren't examinable name2desc = {} + for obj in objs: if obj[0] in name2desc: ex = name2desc[obj[0]] else: self.set_state(state) ex = utl.clean(self.step('examine ' + obj[0])[0]) + name2desc[obj[0]] = ex if utl.recognized(ex): if ex in desc2obj: desc2obj[ex].append(obj) else: desc2obj[ex] = [obj] + # Add 'all' as a wildcard object desc2obj['all'] = [('all', 'NOUN', 'LOC')] self.set_state(state) diff --git a/jericho/util.py b/jericho/util.py index 5eda77ea..66572e42 100644 --- a/jericho/util.py +++ b/jericho/util.py @@ -14,7 +14,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +import io import os +import sys +import time +import threading + from typing import List from . import defines @@ -225,3 +230,90 @@ def chunk(items: List, n: int) -> List[List]: """ k, m = divmod(len(items), n) return list(items[i*k+min(i, m):(i+1)*k+min(i+1, m)] for i in range(n)) + + +class CaptureStdout: + """ + Capture the standard output stream from Python and shared libraries. + + References + ---------- + https://stackoverflow.com/a/29834357 + """ + escape_char = b"\b" + + def __init__(self, threaded=True): + self.threaded = threaded + self._stdout_fd = os.dup(1) # Keep a copy of the handle. + self._stdout_io = sys.stdout # Keep a reference to the text buffer. + + self.text_c = "" + self.text_py = "" + + # Create a pipe so the stream can be captured: + self.pipe_out, self.pipe_in = os.pipe() + + def __enter__(self): + self.start() + return self + + def __exit__(self, type, value, traceback): + self.stop() + + def start(self): + """ + Start capturing the stream data. + """ + + self.text_c = "" + sys.stdout = io.StringIO() + + # Replace the original stream with our write pipe: + os.dup2(self.pipe_in, 1) + if self.threaded: + # Start thread that will read the stream: + self.workerThread = threading.Thread(target=self.readOutput) + self.workerThread.start() + # Make sure that the thread is running and os.read() has executed: + time.sleep(0.01) + + def stop(self): + """ + Stop capturing the stream data and save the text in `capturedtext`. + """ + # Print the escape character to make the readOutput method stop: + os.write(self.pipe_in, self.escape_char) + + if self.threaded: + # wait until the thread finishes so we are sure that + # we have until the last character: + self.workerThread.join() + else: + self.readOutput() + + # Close the pipe + os.close(self.pipe_in) + os.close(self.pipe_out) + os.dup2(self._stdout_fd, 1) + + sys.stdout.seek(0) + self.text_py = sys.stdout.read() + + sys.stdout = self._stdout_io + + def readOutput(self): + """ + Read the stream data (one byte at a time) + and save the text in `capturedtext`. + """ + while True: + char = os.read(self.pipe_out, 1) + if not char or self.escape_char in char: + break + + try: + self.text_c += char.decode(errors='replace') + except UnicodeDecodeError: + pass + #self.text_c += str(char) + #self.text_c += f"*** UnicodeDecodeError {str(char)} at c{len(self.text_c)}!" diff --git a/tools/test_games.py b/tools/test_games.py index 1d38b18c..1533618f 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -2,26 +2,427 @@ import textwrap import argparse +from tqdm import tqdm from termcolor import colored + import jericho +SKIP_PRECHECK_STATE = { + "905.z5": { }, + "acorncourt.z5": {}, + "adventureland.z5": { + "ignore_objects": [ + 49, # chigger bites (You get bitten by chiggers.) + 45, # evil smelling mud (The mud dried up and fell off.) + 71, # large African bees (The bees in the bottle all suffocated.) + ] + }, + "advent.z5": { + 39: "yes", # Answering 'With what? Your bare hands?'. + 167: "u", # Otherwise the dwarf kills the player. + 169: "u", # Otherwise the dwarf kills the player. + 180: "d", # Otherwise the dwarf kills the player. + 202: "u", # Otherwise the dwarf kills the player. + 270: "u", # Otherwise the dwarf kills the player. + '*': range(270, 276+1), # Waiting. Nothing happens. + 'ignore_objects': [ + 264, # Little Dwarf + 265, # Little axe + 268, # endgame_timer (prop 40) + ] + }, + "afflicted.z8": { + "*": [5, 6], # Angela is moving and unlocking the door. + 'ignore_objects': [ + 143, # Ice (The ice has completely melted.) + 204, 205, 206, 207, # no-name objects. + ] + }, + "anchor.z8": { + '*': [ + 1, 2, 3, # Examining fence enables going through it. + 15, # Examining book initiate conversation with Micheal + 26, 27, # Examining notice enables new topic of conversation? + 39, 40, 41, # Sleeping sequence + 77, # Examine paintings (One scene in particular catches your eye). + 78, # Examine scene. + 243, 244, 245, # While sleeping. + 259, # Some light shine through a small hole in the wall. + 277, # Examine wine bottles + 303, # From deep within the forest, you hear the deranged cry of a lone whippoorwill. + 317, 318, 319, # The sound of tearing undergrowth grows louder. + 400, # Ticking sound after lowering the hatch's handle. + 431, # Last night transition + 513, # Boy is moving from Shanty Town to Mill Town Road. + 521, # Micheal is strangling you. + 526, # Ending sequence + + ], + 'ignore_objects': [ + 141, # Train (at time 0, the train is put on Obj129 Railroad Tracks.) + 158, # pale, frightened woman (prop 40) + 210, # (gang) + 221, # Footprints (set attr 8) + 245, # decapitated corpse (set attr 8) + 251, # church_stairs (prop 41) + 252, # Broken Stairs (clear attr 24) + 370, # Flashlight (clear attr 9 and 13) + 372, # book of matches (clear attr 9) + 395, # Wine Cellar (prop 40) + 471, # hatch (clear attr 11) + 472, # metal handle (clear attr 8) + 487, # mill machinery (set attr 8) + 496, # printed memo (move to player's inventory) + 509, # Top of the Lighthouse (change prop 41) + 516, # Island of Flesh (change prop 41) + 27, # (appearence) (change prop 41) + 462, # ghost of Croseus Verlac (change prop 41 - counter for battle sequence?) + 467, # pressure gauge (prop 41) + 231, # Home (change prop 41 - Micheal asking about pregnancy test) + ], + }, + "awaken.z5": {}, + "balances.z5": { + '*': [ + 20, 21, # Examining the sapphire causes it to break. + 109, 110 # The cyclops is losing patience. + ], + "ignore_objects": [ + 57, # Shiny scroll (examining the pile of oats gives you the scroll). + 51, # cedarwood box (examining the furniture gives you the box) + 67, # tortoise feather (A tortoise-feather flutters to the ground before you!) + 65, # (lobal_spell) (prop 40) + 86, # buck-toothed cyclops (prop 40) + ] + }, + "ballyhoo.z3": { + "*": [ + 6, 7, 8, # Listening to the conversation with Munrab. + 41, 62, 88, 122, 125, 126, 249, # Turnstile's state changes. + 110, 111, 112, 113, # Lion stand state changes. + 278, 279, # Playing cardsrn + 200, 214, # Rewinding the tape + 260, 261, 262, 263, 264, 265, # Sequence for "search desk" (addr. 8629). + 266, # Examining the spreadsheet triggers (addr. 8845). + 297, 298, 299, 301, # Ladder is being moved. + 396, 405, 406, # Triggering Turnstile (addr. 9113) + 415, # Game ending (slip off the wire). + ], + "ignore_objects": [ + 113, # Chuckles is moving around. + 122, # ticket is revealed while examining the garbage + 20, # leatsofa (examine leather, set attr 12) + 78, # hawker appears + 17, # short line (Right next to the long line a much shorter line begins to form.) + 162, # Jerry + 42, # groballplayers + 211, # it + 142, # concessistand (you see the line you first entered suddenly kicking into gear) + 163, # one-dollar-and-85-cent granola bar (examine garbage -> picks it up) + 9, # Mahler (screams, clear attr 12) + 141, # elephant (thunders out of the tent) + 175, # Menagerie (set attr 18) + 95, # blackjack table (set attr 12) + 212, # secret panel (attr 15, opens/closes it) + 219, # Comrade Thumb (appears in the room) + 116, # dealer (appears/disappears) + 300, # elephant prod (moving) + 218, # Gottfried Wilhelm vKatzenjammer (moving) + 84, # Chelsea (moving) + ] + }, + "curses.z5": { + '*': [ + 877, 878, 879, # enter coffin (You are so distracted that common sense takes over and you clamber out of the mummy case.) + 1024, # druidical figure sequence + 1063, 1064, 1065, # Ending + ], + "z": [386, 387], # Waiting + "ignore_objects": [ + 111, # antiquated wireless + 76, # new-lookty (examine insulation -> discover battery) + 58, # Austin the cat walking around. + 114, # Jemima (Jemima hums along) + 154, # Unreal City (examine book/poetry -> transport you?!) + 298, # spade (examine agricultural -> let's just call a spade a spade.) + 216, # model ship (examine ship -> you pick it up from force of habit) + 211, # Cups Glasses (look -> hear noise and voices) + 195, # Coven Cell (look -> attr 8, prop 23.) + 309, # beanle (look -> prop 23) + 2, # north (moving from compass to flagpole?!) + 371, # flurries ofeen luminescence (fading away) + 200, # glass cabinet + 70, # book of Twentiesetry (examine book/poetry -> transport you?!) + 206, # timer-detonator (timer runs out) + 205, # complicated-look bomb (counter prop 23) + 396, # Causeway (counter prop 23) + 448, # BirdcagfMuses (counter prop 23) + 401, # skiff (drifting) + 420, # Napoleonic officers (appears) + 496, # adamantinend (The hand wobbles and falls off the knight again.) + 432, # adamantinkull (The skull wobbles and falls off the knight again.) + 394, # InsideOrb (attr 8) + 353, # Tentle (prop 23) + 354, # Saxon spy appears + 355, # Encampment (prop 23) + + ] + }, + +} + +SKIP_CHECK_STATE = { + "905.z5": {}, + "acorncourt.z5": { + 13: "look in bucket", # State didn't change. + }, + "adventureland.z5": {}, + "advent.z5": { + 52: "nw", # Random outcome, state didn't change. + 'wait': range(255, 276+1), # Nothing happens. + }, + "afflicted.z8": { + "noop": [ + "search grate", # Like a examine. + "search window", # Like a examine. + "note it", # Need to open the chopper and examine the blade + "open cover", # The cover is held in place by a large screw. + "turn screw", # The screw is rusted in place. + "read killing", # You read: Killing Vampires + "read culture", # You read: Vampire Culture + "ask angela about affliction", # Angela whispers, ..., I think. + ] + }, + "anchor.z8": { + "noop": [ + "read newspaper",# "read news in newspaper", "read sports in newspaper", "read features in newspaper", + "Look up Wilhelm in album", #"Look up Eustacia in album", "Look up Croseus in album", + "read slip of paper", + "read wall", + "ask bum about himself", "ask bum about anna", "ask bum about crypt", "tell bum about skull", + "put mirror 1 in caliper" + ] + }, + "awaken.z5": { + 4: "n", # Dog blocks your path. + "noop": [ + "read book", # Read the book on the pulpit. + "read old book", # Read the old grimoire on the bookshelf in the Small Office. + ] + }, + "balances.z5": { + "noop": [ + "wait", # Nothing happens. + "listen", # Not needed. + ] + }, + "ballyhoo.z3": { + "noop": [ + "wait", # You hear a loud growl nearby. + "ask pitchman about dr nostrum", # Not needed to complete the game. + "read note", # Not needed to complete the game. + ] + }, + "curses.z5": { + 868: "turn sceptre", # Stochastic outcome. The word didn't change. + 873: "turn sceptre", # Stochastic outcome. The word didn't change. + 875: "turn sceptre", # Stochastic outcome. The word didn't change. + "noop": [ + "z", "wait", # wave splashes against the sea front. + "read romance novel", # Not needed to complete the game. + "read about alison in history book", # Not needed to complete the game. + "read inscription", # Not needed to complete the game. + "read letter", # Not needed to complete the game. + "read tombstone", # Not needed to complete the game. + ] + }, + "cutthroat.z3": { + 1: "wind watch", # Could be replaced by wait. + "wait": [12, 132, 133, 150, 190, 191, 216, 217, 218], # Needed for timing the actions. + "noop": [ + "read envelope", # Not needed to complete the game. + ] + }, + "deephome.z5": { + "wait": [13, 183], # Needed for timing the actions. + "noop": [ + "read letter", # Not needed to complete the game. + "read warning note", # Not needed to complete the game. + "ask man about hammer", # Not needed to complete the game. + "ask man about eranti", # Not needed to complete the game. + "read sign", # Not needed to complete the game. + "ask spirit for name", # Not needed to complete the game. + ] + }, + "detective.z5": { + "noop": [ + "read paper", # Not needed to complete the game. + "read note", # Not needed to complete the game. + ] + }, + "dragon.z5": { + "noop": [ + "break bottle", # Not needed to complete the game. + ] + }, + "enchanter.z3": { + 16: "read scroll", # Not actually needed for learning the spell. + 202: "read map", # Not actually needed for completing the game. + "wait": [84], # Needed for timing the actions. + "noop": [ + "read shredded scroll", # Not needed to complete the game. + "read crumpled scroll", # Not needed to complete the game. + "read faded scroll", # Not needed to complete the game. + "read damp scroll", # Not needed to complete the game. + "read of unseen terror", # Not needed to complete the game. + "read frayed scroll", # Not needed to complete the game. + "read gold leaf scroll", # Not needed to complete the game. + "read stained scroll", # Not needed to complete the game. + "read brittle scroll", # Not needed to complete the game. + "read black scroll", # Not needed to complete the game. + "read powerful scroll", # Not needed to complete the game. + "read vellum scroll", # Not needed to complete the game. + "read ornate scroll", # Not needed to complete the game. + ] + }, + "enter.z5": { + 6: "1", # Could also say nothing, i.e. '0'. + 20: "read list", # Not needed to complete the game. + 62: "w", # Not needed to complete the game. + }, + "gold.z5": { + 146: "open washing machine", # (door is jammed) Not needed to complete the game. + 178: "plug in television", # (already plugged in) Not needed to complete the game. + 179: "watch television", # (nothing on the screen) Not needed to complete the game. + 309: "ask fairy godmother about horse", # Not needed to complete the game. + }, + "hhgg.z3": { + 56: "push switch", # Not needed to complete the game. + "noop": [ + "z", "wait", # Needed for timing the actions. + ] + }, + "hollywood.z3": { + 133: "read business card", # Not needed to complete the game. + 149: "put it on yellowed paper", # (revealing drawing of a maze) Not actually needed for completing the game. + 348: "read plaque", # Not needed for completing the game. + 376: "wait", # Waiting for the closet's door to swing shut. + 383: "read note", # Not needed to complete the game. + }, + "huntdark.z5": { + "noop": [ + "wait", # Waiting for the bat to show the way out. + ] + }, + "infidel.z3": { + 9: "read note", # Not needed to complete the game. + 26: "drink water", # Not needed to complete the game. + 129: "read hieroglyphs", # Not needed to complete the game. + 145: "read hieroglyphs", # Not needed to complete the game. + 159: "read hieroglyphs", # Not needed to complete the game. + 173: "read hieroglyphs", # Not needed to complete the game. + 184: "read scroll", # Not needed to complete the game. + }, + "inhumane.z5": {}, + "jewel.z5": { + 22: "smell dirty floor", # Not needed to complete the game. + 91: "get treasure", # Not needed to complete the game. + 124: "read book", # Not needed to complete the game. + 125: "ask allarah about white", # Not needed to complete the game. + 127: "ask allarah about red", # Not needed to complete the game. + 128: "ask allarah about jewel", # Not needed to complete the game. + }, + "karn.z5": { + 46: "read sign", # Not needed to complete the game. + 93: "ask k9 about k9", # Not needed to complete the game. + 155: "k9, follow me", # Not needed to complete the game.? + 163: "ask k9 about door", # Not needed to complete the game. + 232: "ask k9 about door", # Not needed to complete the game. + 237: "ask k9 about reactor", # Not needed to complete the game. + 238: "ask k9 about control", # Not needed to complete the game. + 239: "ask k9 about sequence", # Not actually needed for completing the game (important information). + 320: "ask k9 about cybermen", # Not needed to complete the game. + "noop": [ + "z" + ], + }, + "library.z5": { + 2: "read tag", # Not needed to complete the game. + 3: "ask alan about novel", # Not needed to complete the game. + 4: "ask him about nelson", # Not needed to complete the game. + 5: "ask him about librarian", # Not needed to complete the game. + 8: "read tag", # Not needed to complete the game. + 9: "ask marion about nelson", # Not needed to complete the game. + 10: "ask her about rare books", # Not needed to complete the game. + 11: "ask her about key", # Not needed to complete the game. + 13: "ask alan about key", # Not needed to complete the game. + 19: "smell", # Not needed to complete the game. + 41: "ask marion about encyclopedia", # Not needed to complete the game. + 50: "ask technician about security gates", # Not needed to complete the game. + }, + "loose.z5": {}, + "lostpig.z8": { + 15: "follow pig", # Not needed to complete the game. + 28: "wear it", # Not needed to complete the game. + 36: "smell it", # Not needed to complete the game. + 52: "listen", # Not needed to complete the game. + 94: "take thing", # Not needed to complete the game. + 95: "cross river", # Not needed to complete the game. + 98: "take water", # Not needed to complete the game. + 109: "take paper", # Not needed to complete the game. + 110: "take paper with pole", # Not needed to complete the game. + }, + + +} + + +def test_walkthrough(env, walkthrough): + env.reset() + for cmd in walkthrough: + obs, score, done, info = env.step(cmd) + + if not env.victory(): + msg = "FAIL\tScore {}/{}".format(info["score"], env.get_max_score()) + print(colored(msg, 'red')) + elif info["score"] != env.get_max_score(): + msg = "FAIL\tDone but score {}/{}".format(info["score"], env.get_max_score()) + print(colored(msg, 'yellow')) + else: + print(colored("PASS", 'green')) + + def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("filenames", nargs="+", help="Path to a Z-Machine game(s).") + parser.add_argument("--interactive", action="store_true", + help="Type the command.") + parser.add_argument("--skip-to", type=int, default=0, + help="Do not perform checks before the ith command.") parser.add_argument("--debug", action="store_true", help="Launch ipdb on FAIL.") + parser.add_argument("--debug-at", type=int, + help="Launch after the ith command.") parser.add_argument("-v", "--verbose", action="store_true", help="Print the last observation when not achieving max score.") + parser.add_argument("-vv", "--very-verbose", action="store_true", + help="Print the last observation when not achieving max score.") + parser.add_argument("--check-state", action="store_true", + help="Check if each command changes the state.") + parser.add_argument("--no-precheck", action="store_true", + help="Skip checking 'examine ' actions.") return parser.parse_args() args = parse_args() + filename_max_length = max(map(len, args.filenames)) for filename in sorted(args.filenames): - print(filename.ljust(filename_max_length), end=" ") + rom = os.path.basename(filename) + print(filename.ljust(filename_max_length))#, end=" ") env = jericho.FrotzEnv(filename) if not env.is_fully_supported: @@ -34,21 +435,159 @@ def parse_args(): env.reset() - #walkthrough = bindings['walkthrough'].split('/') - for cmd in env.get_walkthrough(): + # history = [] + # history.append((0, 'reset', env.get_state())) + + walkthrough = env.get_walkthrough() + for i, cmd in tqdm(list(enumerate(walkthrough))): + cmd = cmd.lower() + last_hash = env.get_world_state_hash() + + precheck_state = (args.check_state and not args.no_precheck and i >= args.skip_to + and cmd not in SKIP_PRECHECK_STATE.get(rom, {}).get(i, {}) + and i not in SKIP_PRECHECK_STATE.get(rom, {}).get("*", [])) + + if precheck_state: + env_ = env.copy() + state = env_.get_state() + objs = env_._identify_interactive_objects(use_object_tree=True) + cmds = ["look", "inv"] + cmds += ["examine " + obj[0][0] for obj in objs.values()] + for cmd_ in cmds: + env_.set_state(state) + obs_, _, _, _ = env_.step(cmd_) + + env_objs = env.get_world_objects(clean=True) + env_objs_ = env_.get_world_objects(clean=True) + changed_objs = [o1 for o1, o2 in zip(env_objs_, env_objs) if o1 != o2] + + skip = False + for obj in changed_objs: + if obj.num in SKIP_PRECHECK_STATE.get(rom, {}).get("ignore_objects", []): + skip = True + break + + # world_diff = env_._get_world_diff() + # moved_objs, set_attrs, cleared_attrs, changed_props, _ = world_diff + # skip = False + # for obj in moved_objs + set_attrs + cleared_attrs + changed_props: + # if obj[0] in SKIP_PRECHECK_STATE.get(rom, {}).get("ignore_objects", []): + # skip = True + # break + + if skip: + break + + if env_._world_changed(): + # if last_hash != env_.get_world_state_hash(): + # env_objs = env.get_world_objects(clean=True) + # env_objs_ = env_.get_world_objects(clean=True) + objs1 = env.get_world_objects(clean=False) + objs2 = env_.get_world_objects(clean=False) + + # for o1, o2 in zip(objs1, objs2): print(colored(f"{o1}\n{o2}", "red" if o1 != o2 else "white")) + print(colored(f'{i}. [{cmd_}]: world hash has changed.\n"""\n{obs_}\n"""', 'red')) + for o1, o2 in zip(env_objs, env_objs_): + if o1 != o2: + print(colored(f"{o1}\n{o2}", "red")) + + breakpoint() + break + + # if env_._world_changed(): + # print(colored(f'{i}. [{cmd_}]: world state has changed.\n"""\n{obs_}\n"""', 'red')) + # breakpoint() + + if args.interactive: + tmp = input(f"{i}. [{cmd}] >") + if tmp.strip(): + cmd = tmp + + last_env_objs = env.get_world_objects(clean=False) + last_env_objs_cleaned = env.get_world_objects(clean=True) + obs, rew, done, info = env.step(cmd) - if not done: + env_objs = env.get_world_objects(clean=False) + env_objs_cleaned = env.get_world_objects(clean=True) + + # state = env.get_state() + # history.append((i, cmd, state)) + + if args.very_verbose: + print(f"{i}. >", cmd) + print(obs) + + if i == args.debug_at: + breakpoint() + + check_state = (args.check_state and i >= args.skip_to + and cmd not in SKIP_CHECK_STATE.get(rom, {}).get(i, {}) + and i not in SKIP_CHECK_STATE.get(rom, {}).get(cmd, []) + and cmd not in SKIP_CHECK_STATE.get(rom, {}).get('noop', {})) + + if check_state: + # if not env._world_changed(): + # print(colored(f'{i}. [{cmd}]: world state hasn\'t changed.\n"""\n{obs}\n"""', 'red')) + # breakpoint() + + if not env._world_changed(): + # if last_hash == env.get_world_state_hash(): + if cmd.split(" ")[0] not in {"look", "x", "search", "examine", "i", "inventory"}: + + print(colored(f'{i}. [{cmd}]: world hash hasn\'t changed.\n"""\n{obs}\n"""', 'red')) + + print("Objects diff:") + for o1, o2 in zip(last_env_objs, env_objs): + if o1 != o2: + print(colored(f"{o1}\n{o2}", "red")) + + print("Cleaned objects diff:") + for o1, o2 in zip(last_env_objs_cleaned, env_objs_cleaned): + if o1 != o2: + print(colored(f"{o1}\n{o2}", "red")) + + print(f"Testing walkthrough without '{cmd}'...") + test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) + print(f"Testing walkthrough replacing '{cmd}' with 'wait'...") + test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) + print(f"Testing walkthrough replacing '{cmd}' with '0'...") + test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) + breakpoint() + # else: + # world_diff = env._get_world_diff() + # if len(world_diff[-1]) > 1: + # print(colored("Multiple special RAM addressed have been triggered!", 'yellow')) + # print(f"RAM: {world_diff[-1]}") + # breakpoint() + + # else: + # changed_objs = [(o1, o2) for o1, o2 in zip(env_objs_cleaned, last_env_objs_cleaned) if o1 != o2] + + # world_diff = env._get_world_diff() + # if len(changed_objs) > 0 and len(world_diff[-1]) > 0: + # print(colored("Special RAM address triggered as well as object modifications!", 'yellow')) + # print(colored("Is the special RAM address really needed, then?", 'yellow')) + # print(f"RAM: {world_diff[-1]}") + # for o1, o2 in changed_objs: + # print(o2) # New + # print(o1) # Old + + # breakpoint() + + + if not env.victory(): print(colored("FAIL", 'red')) if args.debug: from ipdb import set_trace; set_trace() elif info["score"] != env.get_max_score(): msg = "FAIL\tDone but score {}/{}".format(info["score"], env.get_max_score()) - print(colored(msg, 'red')) + print(colored(msg, 'yellow')) if args.verbose: print(textwrap.indent(obs, prefix=" ")) if args.debug: from ipdb import set_trace; set_trace() else: - print(colored("PASS", 'green')) + msg = "PASS\t Score {}/{}".format(info["score"], env.get_max_score()) + print(colored(msg, 'green')) From 8402e620a71d086a23d0992c09745799c30c42e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 10 Nov 2021 16:57:49 -0500 Subject: [PATCH 07/85] Add script to help finding special ram. --- tools/find_special_ram.py | 244 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 tools/find_special_ram.py diff --git a/tools/find_special_ram.py b/tools/find_special_ram.py new file mode 100644 index 00000000..94849906 --- /dev/null +++ b/tools/find_special_ram.py @@ -0,0 +1,244 @@ +import os +import textwrap +import argparse + +import numpy as np +from tqdm import tqdm +from termcolor import colored + +import jericho + + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("filenames", nargs="+", + help="Path to a Z-Machine game(s).") + parser.add_argument("--index", type=int, help="Index of the walkthrough command to investigate.") + parser.add_argument("--interactive", action="store_true", + help="Type the command.") + parser.add_argument("--debug", action="store_true", + help="Launch ipdb on FAIL.") + parser.add_argument("-v", "--verbose", action="store_true", + help="Print the last observation when not achieving max score.") + parser.add_argument("-vv", "--very-verbose", action="store_true", + help="Print the last observation when not achieving max score.") + parser.add_argument("--check-state", action="store_true", + help="Check if each command changes the state.") + return parser.parse_args() + +args = parse_args() + + +def get_zmp(env): + zmp = env.get_state()[0] + #start = zmp.view(">u2")[6] # ref: https://inform-fiction.org/zmachine/standards/z1point1/sect06.html#two + #length = 240 * 2 # 240 2-byte global variables. + #globals = zmp[start:start + length].view(">i2") + return zmp + + +def display_indices(indices): + indices = sorted(indices) + + NB_COLS = 16 + for row in range(int(np.ceil(len(indices) / NB_COLS))): + for col in range(NB_COLS): + idx = (row * NB_COLS) + col + if idx >= len(indices): + break + + text = f"{indices[idx]:6d}" + print(text, end=",") + + print() + + +def display_relevant(G, changed, relevant, noise): + relevant = sorted(relevant) + + NB_COLS = 16 + for row in range(int(np.ceil(len(relevant) / NB_COLS))): + for col in range(NB_COLS): + idx = (row * NB_COLS) + col + if idx >= len(relevant): + break + + color = 'white' + # assert len(relevant & noise) == 0 + #if idx in relevant: + color = 'green' + if idx in noise: + color = 'red' + + bg_color = None + attrs = [] + if idx in changed: + attrs.append("bold") + bg_color = "on_grey" + + text = colored(f"{relevant[idx]:5x}", color, bg_color) + print(text, end=",") + + print() + +def display_ram(G, changed, relevant, noise): + NB_COLS = 150 + for row in range(int(np.ceil(len(G) / NB_COLS))): + for col in range(NB_COLS): + idx = (row * NB_COLS) + col + color = 'white' + assert len(relevant & noise) == 0 + if idx in relevant: + color = 'green' + if idx in noise: + color = 'red' + + bg_color = None + attrs = [] + if idx in changed: + attrs.append("bold") + bg_color = "on_grey" + + text = colored(f".", color, bg_color) + print(text, end="") + + print() + + +def show_mem_diff(M0, M1, M2, start=24985, length=240*2): + # TODO: start can be obtained from ZMP.view('>i2')[6] + import numpy as np + + M1 = M1[start:start+length].view(">i2") + M2 = M2[start:start+length].view(">i2") + indices = np.nonzero(M1 != M2)[0] + + if M0 is not None: + M0 = M0[start:start+length].view(">i2") + to_print = sorted(set(indices) - set(np.nonzero(M0 != M1)[0])) + to_print += [None] + to_print += sorted(set(indices) & set(np.nonzero(M0 != M1)[0])) + + for i in to_print: + if i is None: + print("--") + continue + + print(f"{i:3d} [{start+i*2:5d}]: {M1[i]:5d} -> {M2[i]:5d}") + + +filename_max_length = max(map(len, args.filenames)) +for filename in sorted(args.filenames): + rom = os.path.basename(filename) + print(filename.ljust(filename_max_length))#, end=" ") + + env = jericho.FrotzEnv(filename) + if not env.is_fully_supported: + print(colored("SKIP\tUnsupported game", 'yellow')) + continue + + if "walkthrough" not in env.bindings: + print(colored("SKIP\tMissing walkthrough", 'yellow')) + continue + + env.reset() + Z = get_zmp(env) + + history = [] + history.append((0, 'reset', env.get_state(), Z)) + + walkthrough = env.get_walkthrough() + cmd_no = 0 + + noise_indices = set() + relevant_indices = set() + changes_history = [] + cpt = 0 + while True: + if cmd_no >= len(walkthrough): + break + + cmd = walkthrough[cmd_no].lower() + + if args.interactive: + manual_cmd = input(f"{cpt}. [{cmd}]> ") + if manual_cmd.strip(): + cmd = manual_cmd.lower() + else: + print(f"{cpt}. > {cmd}") + + if cmd == walkthrough[cmd_no].lower(): + cmd_no += 1 + + last_env_objs = env.get_world_objects(clean=False) + last_env_objs_cleaned = env.get_world_objects(clean=True) + + last_Z = Z + obs, rew, done, info = env.step(cmd) + cpt += 1 + # print(">", cmd) + print(obs) + + env_objs = env.get_world_objects(clean=False) + env_objs_cleaned = env.get_world_objects(clean=True) + + Z = get_zmp(env) + + changes = set(np.nonzero(Z != last_Z)[0]) + + history.append((cmd, env.get_state())) + changes_history.append(changes) + + # ans = "" + # while ans not in {'y', 'n', 's'}: + # ans = input("State has changed? [y/n/s]> ").lower() + + # if ans == "y": + # relevant_indices |= changes - noise_indices + # elif ans == "s": + # pass + # elif ans == "n": + # noise_indices |= changes + # relevant_indices -= noise_indices + # else: + # assert False + + #print(special_indices) + + # display_relevant(Z, changes, relevant_indices, noise_indices) + + def display_objs_diff(): + print("Objects diff:") + for o1, o2 in zip(last_env_objs, env_objs): + if o1 != o2: + print(colored(f"{o1}\n{o2}", "red")) + + print("Cleaned objects diff:") + for o1, o2 in zip(last_env_objs_cleaned, env_objs_cleaned): + if o1 != o2: + print(colored(f"{o1}\n{o2}", "red")) + + # breakpoint() + + def search_unique_changes(idx): + counter = {idx: 0 for idx in changes_history[idx]} + matches = {idx: [] for idx in changes_history[idx]} + for i, changes in enumerate(changes_history): + for idx in changes: + if idx in counter: + counter[idx] += 1 + matches[idx].append((i, history[i+1][0])) + + for idx, count in sorted(counter.items(), key=lambda e: e[::-1]): + if matches[idx][0][0] == 0: + continue + + print(f"{idx:6d}: {count:3d} : " + ", ".join(f"{i}.{cmd}" for i, cmd in matches[idx][:10])) + + #if len(changes_history) > : + print(f"Ram changes unique to command: {args.index}. > {history[args.index+1][0]}") + search_unique_changes(args.index) + # display_indices(search_unique_changes(args.index)) + if args.debug: + breakpoint() From d42e6abde9817c8a98ab5805d0b85d99b53ca3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 10 Nov 2021 21:50:18 -0500 Subject: [PATCH 08/85] Testing more games --- frotz/src/games/lurking.c | 10 ++++++++-- frotz/src/games/moonlit.c | 16 ++++++++-------- frotz/src/games/murdac.c | 7 ++++--- frotz/src/games/night.c | 8 ++++++-- jericho/game_info.py | 2 +- tools/test_games.py | 22 +++++++++++++++++++--- 6 files changed, 46 insertions(+), 19 deletions(-) diff --git a/frotz/src/games/lurking.c b/frotz/src/games/lurking.c index cae09554..5ebb0ec4 100644 --- a/frotz/src/games/lurking.c +++ b/frotz/src/games/lurking.c @@ -25,8 +25,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // The Lurking Horror: http://ifdb.tads.org/viewgame?id=jhbd0kja1t57uop -const zword lurking_special_ram_addrs[6] = { +const zword lurking_special_ram_addrs[11] = { + 883, // Cut line with axe + 756, // knock on door + 859, // Read page, click on more + 813, // Throw axe at cord + 1047, // Lower ladder (alt. 1163, 1333) 11251, // Microwave timer + 11235, // press up/down button 961, // Microwave setting 1145, // Cleaning up junk 4889, // Drinking coke @@ -40,7 +46,7 @@ const char *lurking_intro[] = { "sit on chair\n", "password uhlersoth\n" }; zword* lurking_ram_addrs(int *n) { - *n = 6; + *n = 11; return lurking_special_ram_addrs; } diff --git a/frotz/src/games/moonlit.c b/frotz/src/games/moonlit.c index 1c6d498c..5da51e06 100644 --- a/frotz/src/games/moonlit.c +++ b/frotz/src/games/moonlit.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -103,11 +103,11 @@ int moonlit_ignore_attr_clr(zword obj_num, zword attr_idx) { } void moonlit_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7) & ~1; - // Clear attr 24 & 31 - for (i=1; i<=moonlit_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + // int i; + // char mask; + // mask = ~(1 << 7) & ~1; + // // Clear attr 24 & 31 + // for (i=1; i<=moonlit_get_num_world_objs(); ++i) { + // objs[i].attr[3] &= mask; + // } } diff --git a/frotz/src/games/murdac.c b/frotz/src/games/murdac.c index 363e4f60..569c17bd 100644 --- a/frotz/src/games/murdac.c +++ b/frotz/src/games/murdac.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Monsters of Murdac: http://ifdb.tads.org/viewgame?id=q36lh5np0q9nak28 -const zword murdac_special_ram_addrs[9] = { +const zword murdac_special_ram_addrs[10] = { 3909, // Blow shawm; Also 525 3587, // Tracks state of door. Also 3626 4659, // Tracks throwing plank, rod. @@ -34,10 +34,11 @@ const zword murdac_special_ram_addrs[9] = { 3042, // Tracks lion health 2548, // Fill bowl, look 3365, // Prick dummy, exodus + 6387, // Running away from the poltergeist. }; zword* murdac_ram_addrs(int *n) { - *n = 9; + *n = 10; return murdac_special_ram_addrs; } diff --git a/frotz/src/games/night.c b/frotz/src/games/night.c index c249210e..b593a82b 100644 --- a/frotz/src/games/night.c +++ b/frotz/src/games/night.c @@ -24,9 +24,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Night at the Computer Center: http://ifdb.tads.org/viewgame?id=ydhwa11st460g9u3 +const zword night_special_ram_addrs[1] = { + 6837, // listen +}; + zword* night_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 1; + return night_special_ram_addrs; } char** night_intro_actions(int *n) { diff --git a/jericho/game_info.py b/jericho/game_info.py index 683a6110..21e498c5 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -316,7 +316,7 @@ "name": "night", "rom": "night.z5", "seed" : 0, - "walkthrough" : "ne/s/e/open box/pull hose/take light/w/n/w/d/d/e/s/e/open door/s/listen/n/w/n/w/u/e/s/push fountain/open panel/turn on light/go panel/go panel/e/z/z/follow mouse/follow mouse/follow mouse/follow mouse/follow mouse/get printer/ask gnome about prinout/w/x sign/w/w/w/e/e/w/u/n/w/u/e/sw/click ftp/click if-archive/click designers_manual/click lpr/take manual/ne/w/d/e/s/d/z/z/z/z/z/follow mouse/follow mouse/follow mouse/follow mouse/follow mouse/follow mouse/give manual/take printer/w/w/w/e/e/w/u/n/w/u/e/sw/put printer on table", + "walkthrough" : "ne/s/e/open box/pull hose/take light/w/n/w/d/d/e/s/e/open door/s/listen/n/w/n/w/u/e/s/push fountain/open panel/turn on light/go panel/go panel/e/z/z/follow mouse/follow mouse/follow mouse/follow mouse/follow mouse/get printer/ask gnome about printer/w/x sign/w/w/w/e/e/w/u/n/w/u/e/sw/click ftp/click if-archive/click designers_manual/click lpr/take manual/ne/w/d/e/s/d/z/z/z/z/z/follow mouse/follow mouse/follow mouse/follow mouse/follow mouse/follow mouse/give manual/take printer/w/w/w/e/e/w/u/n/w/u/e/sw/put printer on table", "grammar" : "allhints;allpuzzle/puzzles;awake/awaken/wake;awake/awaken/wake up;bother/curses/darn/drat;brief/normal;carry/get/hold/take inventory;carry/get/hold/take off;carry/get/hold/take out;close/cover/shut up;damn/fuck/shit/sod;die/q/quit;dive/swim;exit/out/outside/stand;full/fullscore;full/fullscore score;go/leave/run/walk;hear/listen;help;hint/hints;hints off;hints on;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;l/look;long/verbose;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;off;on;places;pray;restart;restore;review;save;score;script;script off;script on;short/superbrie;sing;smell/sniff;sorry;stand/carry/get/hold/take up;think;verify;version;wait/z;wave;xyzzy;y/yes;adjust/set OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;carry/get/hold/take OBJ;carry/get/hold/take off OBJ;chase/follow/pursue/trail OBJ;chase/follow/pursue/trail after OBJ;check/describe/examine/watch/x OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;click OBJ;click on OBJ;climb/scale OBJ;climb/scale over OBJ;climb/scale up OBJ;close/cover/shut OBJ;cross/enter/go/leave/run/walk OBJ;damn/fuck/shit/sod OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;drink/sip/swallow at OBJ;drink/sip/swallow from OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;go/leave/run/walk through OBJ;go/leave/run/walk/carry/get/hold/take into OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;l/look at OBJ;l/look behind OBJ;l/look in OBJ;l/look inside OBJ;l/look into OBJ;l/look through OBJ;l/look under OBJ;lie/sit/go/leave/run/walk inside OBJ;lie/sit/go/leave/run/walk/carry/get/hold/take in OBJ;lie/sit/stand/carry/get/hold/take on OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;put OBJ down;put down OBJ;put on OBJ;read OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;smell/sniff OBJ;squash/squeeze OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;unfold OBJ;wave OBJ;adjust/set OBJ to OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/get/hold/take OBJ off OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;click OBJ on OBJ;dig OBJ with OBJ;discard/drop/throw OBJ against OBJ;discard/drop/throw OBJ at OBJ;discard/drop/throw OBJ down OBJ;discard/drop/throw/insert/put OBJ in OBJ;discard/drop/throw/insert/put OBJ into OBJ;discard/drop/throw/put OBJ on OBJ;discard/drop/throw/put OBJ onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ into OBJ;empty OBJ on OBJ;empty OBJ onto OBJ;empty OBJ to OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;lock OBJ with OBJ;put OBJ inside OBJ;remove/carry/get/hold/take OBJ from OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index 1533618f..c989af76 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -373,8 +373,24 @@ 109: "take paper", # Not needed to complete the game. 110: "take paper with pole", # Not needed to complete the game. }, - - + "ludicorp.z5": { + 7: "smell car", # Not needed to complete the game. + 50: "open door", # (it is locked) Not needed to complete the game. + 140: "shoot window", # (glass is bulletproof) Not needed to complete the game. + 239: "play arcade", # (you died) Not needed to complete the game. + 241: "play pool", # (no ball nor cues) Not needed to complete the game. + 255: "w", # (outer airlock door blocks your way) Not needed to complete the game. + }, + "lurking.z3": { + "noop": ["z"] + }, + "moonlit.z5": {}, + "murdac.z5": {}, + "night.z5": { + 37: "get printer", # Not needed to complete the game. + 38: "ask gnome about printer", # Not needed to complete the game. + "noop": ["z"] + }, } @@ -533,7 +549,7 @@ def parse_args(): if not env._world_changed(): # if last_hash == env.get_world_state_hash(): - if cmd.split(" ")[0] not in {"look", "x", "search", "examine", "i", "inventory"}: + if cmd.split(" ")[0] not in {"look", "l", "x", "search", "examine", "i", "inventory"}: print(colored(f'{i}. [{cmd}]: world hash hasn\'t changed.\n"""\n{obs}\n"""', 'red')) From b3688bc26bfd0ae36c090ec7b1815591bca47c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 11 Nov 2021 10:41:09 -0500 Subject: [PATCH 09/85] Testing more games + better handle leading newlines/whitespaces --- frotz/src/games/partyfoul.c | 14 ++++++++++---- jericho/jericho.py | 3 +++ tools/test_games.py | 7 +++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/frotz/src/games/partyfoul.c b/frotz/src/games/partyfoul.c index 146a46b1..61200bfe 100644 --- a/frotz/src/games/partyfoul.c +++ b/frotz/src/games/partyfoul.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -24,12 +24,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Party Foul - http://ifdb.tads.org/viewgame?id=cqwq699i9qiqdju +const zword partyfoul_special_ram_addrs[3] = { + 17509, // Spread peanut butter on frank (alt. 17755, 19428, 21423, 47829) + 1923, // plug the toaster + 28036, // Waiting for your husband to be prepared to leave the party (alt. 28037, 32186) +}; + const char *partyfoul_intro[] = { "\n", "no\n" }; zword* partyfoul_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 3; + return partyfoul_special_ram_addrs; } char** partyfoul_intro_actions(int *n) { @@ -43,7 +49,7 @@ char* partyfoul_clean_observation(char* obs) { if (pch != NULL) { *(pch-2) = '\0'; } - return obs+1; + return obs + strspn(obs, "\n "); // Skip leading newlines and whitespaces. } int partyfoul_victory() { diff --git a/jericho/jericho.py b/jericho/jericho.py index 0744f749..041df662 100644 --- a/jericho/jericho.py +++ b/jericho/jericho.py @@ -345,6 +345,9 @@ def _load_frotz_lib(): frotz_lib.getStackSize.argtypes = [] frotz_lib.getStackSize.restype = int + frotz_lib.getRetPC.argtypes = [] + frotz_lib.getRetPC.restype = int + frotz_lib.get_opcode.argtypes = [] frotz_lib.get_opcode.restype = int frotz_lib.set_opcode.argtypes = [c_int] diff --git a/tools/test_games.py b/tools/test_games.py index c989af76..9cd20840 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -391,6 +391,13 @@ 38: "ask gnome about printer", # Not needed to complete the game. "noop": ["z"] }, + "omniquest.z5": {}, + "partyfoul.z8": { + "z": [53, 54], # Ending sequence. + }, + "pentari.z5": { + + } } From 489220f6dc30d9a03ee4198c391a08a3c04041d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 11 Nov 2021 19:53:22 -0500 Subject: [PATCH 10/85] Add missing md5.h file --- frotz/src/interface/md5.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 frotz/src/interface/md5.h diff --git a/frotz/src/interface/md5.h b/frotz/src/interface/md5.h new file mode 100644 index 00000000..4fe8e852 --- /dev/null +++ b/frotz/src/interface/md5.h @@ -0,0 +1,20 @@ +#ifndef MD5_H +#define MD5_H + +#include + +typedef unsigned int uint; +typedef unsigned char byte; + +typedef struct MD5state +{ + uint len; + uint state[4]; +} MD5state; + +MD5state *nil; + +MD5state* md5(byte*, uint, byte*, MD5state*); +void sum(FILE*, char*); + +#endif MD5_H \ No newline at end of file From 15bf5e63f4cb04ddd846692396845ff930f8f7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 17 Nov 2021 10:27:49 -0500 Subject: [PATCH 11/85] Improve testing tools + planetfall --- frotz/src/games/planetfall.c | 30 +++++++++++++++++++----------- tools/find_special_ram.py | 10 +++++----- tools/test_games.py | 10 +++++++--- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/frotz/src/games/planetfall.c b/frotz/src/games/planetfall.c index 9afe82b0..c1bb396c 100644 --- a/frotz/src/games/planetfall.c +++ b/frotz/src/games/planetfall.c @@ -24,24 +24,32 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Planetfall: http://ifdb.tads.org/viewgame?id=xe6kb3cuqwie2q38 -const zword planetfall_special_ram_addrs[13] = { - 10741, // Blue button - 10234, // Enable elevator +const zword planetfall_special_ram_addrs[26] = { + 10052, // Laser + 10058, // Dial + 10060, // Bye laser 10218, // Pour fluid in hole - 10408, // Hunger - 10711, // Red button - 10420, // Pull lever + 10234, 10702, 10690, // Sliding card through slot + 10254, // Turn on floyd 10404, // Sickness + 10408, // Hunger + 10430, 10432, // Pull lever and wait. 10444, // Teleportation Card - 10642, // Miniaturization card - 10058, // Dial - 10052, // Laser - 10060, // Bye laser + 10454, // Timer before the pod lands. + 10456, // Timer before mothership explodes. + 10608, // Call the Cryo-Elevator 10612, // Emergency button + 10642, // Miniaturization card + 10668, // Let Floyd go inside the laboratory + 10710, // Red button and wait + 10728, 10698, // Elevator button + waiting + 10732, // Enable elevator. + 10740, // Blue button and waiting for door to open + 10788, // Timer before explosion. }; zword* planetfall_ram_addrs(int *n) { - *n = 13; + *n = 26; return planetfall_special_ram_addrs; } diff --git a/tools/find_special_ram.py b/tools/find_special_ram.py index 94849906..a6235368 100644 --- a/tools/find_special_ram.py +++ b/tools/find_special_ram.py @@ -187,7 +187,7 @@ def show_mem_diff(M0, M1, M2, start=24985, length=240*2): changes = set(np.nonzero(Z != last_Z)[0]) - history.append((cmd, env.get_state())) + history.append((cmd, env.get_state(), Z)) changes_history.append(changes) # ans = "" @@ -228,13 +228,13 @@ def search_unique_changes(idx): for idx in changes: if idx in counter: counter[idx] += 1 - matches[idx].append((i, history[i+1][0])) + matches[idx].append((i, history[i+1][0], history[i+1][2][idx])) for idx, count in sorted(counter.items(), key=lambda e: e[::-1]): - if matches[idx][0][0] == 0: - continue + # if matches[idx][0][0] == 0: + # continue - print(f"{idx:6d}: {count:3d} : " + ", ".join(f"{i}.{cmd}" for i, cmd in matches[idx][:10])) + print(f"{idx:6d}: {count:3d} : " + ", ".join(f"{i}.{cmd}({value})" for i, cmd, value in matches[idx][:20])) #if len(changes_history) > : print(f"Ram changes unique to command: {args.index}. > {history[args.index+1][0]}") diff --git a/tools/test_games.py b/tools/test_games.py index 9cd20840..48383dee 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -395,8 +395,9 @@ "partyfoul.z8": { "z": [53, 54], # Ending sequence. }, - "pentari.z5": { - + "pentari.z5": {}, + "planetfall.z3": { + 216: "eat brown goo", # Not needed to complete the game. } } @@ -456,7 +457,10 @@ def parse_args(): print(colored("SKIP\tMissing walkthrough", 'yellow')) continue - env.reset() + obs, _ = env.reset() + + if args.very_verbose: + print(obs) # history = [] # history.append((0, 'reset', env.get_state())) From 483c7b625fb2b40d569f526a6893fb7da9ab3085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 17 Nov 2021 16:14:31 -0500 Subject: [PATCH 12/85] Disable status line for z3 or lower. --- frotz/src/common/screen.c | 2 +- frotz/src/dumb/dumb_output.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frotz/src/common/screen.c b/frotz/src/common/screen.c index ada2e0a7..fde27487 100644 --- a/frotz/src/common/screen.c +++ b/frotz/src/common/screen.c @@ -1554,7 +1554,7 @@ void z_show_status (void) /* One V5 game (Wishbringer Solid Gold) contains this opcode by accident, so just return if the version number does not fit */ - if (h_version >= V4) + if (h_version >= V4 || h_config & CONFIG_NOSTATUSLINE) return; /* Read all relevant global variables from the memory of the diff --git a/frotz/src/dumb/dumb_output.c b/frotz/src/dumb/dumb_output.c index 29a5ad8e..acc1ba30 100644 --- a/frotz/src/dumb/dumb_output.c +++ b/frotz/src/dumb/dumb_output.c @@ -522,6 +522,7 @@ void dumb_init_output(void) { if (h_version == V3) { h_config |= CONFIG_SPLITSCREEN; + h_config |= CONFIG_NOSTATUSLINE; h_flags &= ~OLD_SOUND_FLAG; } From 3fd22297fdf2324d6e11ea162aecc7322e6211a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 17 Nov 2021 16:14:59 -0500 Subject: [PATCH 13/85] Fix getRetPC --- frotz/src/interface/frotz_interface.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index 2600b8e3..da67a99d 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -436,7 +436,7 @@ void setFP(int v) { } int getRetPC() { - return *(fp+2) | ((*fp+2+1) << 9); + return *(fp+2) | (*(fp+2+1) << 9); } int get_opcode() { @@ -1421,11 +1421,17 @@ int is_supported(char *story_file) { void take_intro_actions() { int num_actions = 0; char **intro_actions = NULL; - int i; intro_actions = get_intro_actions(&num_actions); if (num_actions <= 0 || intro_actions == NULL) return; - for (i=0; i Date: Wed, 17 Nov 2021 16:15:26 -0500 Subject: [PATCH 14/85] Refactor find_special_ram --- tools/find_special_ram.py | 183 +++++++++++++++++--------------------- 1 file changed, 84 insertions(+), 99 deletions(-) diff --git a/tools/find_special_ram.py b/tools/find_special_ram.py index a6235368..bf5fe091 100644 --- a/tools/find_special_ram.py +++ b/tools/find_special_ram.py @@ -12,22 +12,17 @@ def parse_args(): parser = argparse.ArgumentParser() - parser.add_argument("filenames", nargs="+", - help="Path to a Z-Machine game(s).") + parser.add_argument("filename", + help="Path to a Z-Machine game.") parser.add_argument("--index", type=int, help="Index of the walkthrough command to investigate.") - parser.add_argument("--interactive", action="store_true", - help="Type the command.") - parser.add_argument("--debug", action="store_true", - help="Launch ipdb on FAIL.") + parser.add_argument("--alternative-command", + help="Type the command to replace the one at '--index'.") parser.add_argument("-v", "--verbose", action="store_true", help="Print the last observation when not achieving max score.") parser.add_argument("-vv", "--very-verbose", action="store_true", help="Print the last observation when not achieving max score.") - parser.add_argument("--check-state", action="store_true", - help="Check if each command changes the state.") return parser.parse_args() -args = parse_args() def get_zmp(env): @@ -128,32 +123,19 @@ def show_mem_diff(M0, M1, M2, start=24985, length=240*2): print(f"{i:3d} [{start+i*2:5d}]: {M1[i]:5d} -> {M2[i]:5d}") -filename_max_length = max(map(len, args.filenames)) -for filename in sorted(args.filenames): - rom = os.path.basename(filename) - print(filename.ljust(filename_max_length))#, end=" ") - - env = jericho.FrotzEnv(filename) - if not env.is_fully_supported: - print(colored("SKIP\tUnsupported game", 'yellow')) - continue - - if "walkthrough" not in env.bindings: - print(colored("SKIP\tMissing walkthrough", 'yellow')) - continue - +def collect_zmp(env, walkthrough, verbose=False): env.reset() Z = get_zmp(env) history = [] - history.append((0, 'reset', env.get_state(), Z)) + # history.append((0, 'reset', env.get_state(), Z)) + history.append({"cmd": 'reset', "state": env.get_state(), "zmp": Z}) - walkthrough = env.get_walkthrough() cmd_no = 0 - noise_indices = set() - relevant_indices = set() - changes_history = [] + # noise_indices = set() + # relevant_indices = set() + # changes_history = [] cpt = 0 while True: if cmd_no >= len(walkthrough): @@ -161,84 +143,87 @@ def show_mem_diff(M0, M1, M2, start=24985, length=240*2): cmd = walkthrough[cmd_no].lower() - if args.interactive: - manual_cmd = input(f"{cpt}. [{cmd}]> ") - if manual_cmd.strip(): - cmd = manual_cmd.lower() - else: + if verbose: print(f"{cpt}. > {cmd}") if cmd == walkthrough[cmd_no].lower(): cmd_no += 1 - last_env_objs = env.get_world_objects(clean=False) - last_env_objs_cleaned = env.get_world_objects(clean=True) + # last_Z = Z + obs, _, _, _ = env.step(cmd) + cpt += 1 + if verbose: + print(obs) + Z = get_zmp(env) + + # changes = set(np.nonzero(Z != last_Z)[0]) + + history.append({'cmd': cmd, "state": env.get_state(), "zmp": Z}) + # changes_history.append(changes) + + return history#, changes_history + + +def compute_zmp_changes(history): + last_Z = history[0]['zmp'] + changes = [] + for state in history[1:]: + Z = state['zmp'] + changes.append(set(np.nonzero(Z != last_Z)[0])) last_Z = Z - obs, rew, done, info = env.step(cmd) - cpt += 1 - # print(">", cmd) - print(obs) - env_objs = env.get_world_objects(clean=False) - env_objs_cleaned = env.get_world_objects(clean=True) + return changes + + +def display_unique_changes(idx, history, changes_history): + counter = {idx: 0 for idx in changes_history[idx]} + matches = {idx: [] for idx in changes_history[idx]} + for i, changes in enumerate(changes_history): + for idx in changes: + if idx in counter: + counter[idx] += 1 + matches[idx].append((i, history[i+1]["cmd"], history[i+1]["zmp"][idx])) + + for idx, count in sorted(counter.items(), key=lambda e: e[::-1]): + if matches[idx][0][0] == 0: + continue + + print(f"{idx:6d}: {count:3d} : " + ", ".join(f"{i}.{cmd}({value})" for i, cmd, value in matches[idx][:20])) + + +def main(): + args = parse_args() + + env = jericho.FrotzEnv(args.filename) + print(args.filename) + if not env.is_fully_supported: + print(colored("SKIP\tUnsupported game", 'yellow')) + return + + if "walkthrough" not in env.bindings: + print(colored("SKIP\tMissing walkthrough", 'yellow')) + return + + walkthrough = env.get_walkthrough() + history = collect_zmp(env, walkthrough, verbose=False) + changes_history = compute_zmp_changes(history) + + print(f"Ram changes unique to command: {args.index}. > {history[args.index+1]['cmd']}") + if args.alternative_command: + walkthrough_ = walkthrough[:args.index] + [args.alternative_command] + walkthrough[args.index+1:] + history2 = collect_zmp(env, walkthrough_, verbose=False) + changes_history2 = compute_zmp_changes(history2) + assert len(changes_history) == len(changes_history2) + + for i in range(len(changes_history)): + changes_history[i] = changes_history[i] & changes_history2[i] + + print(f"intersected with ram changes unique to command: {args.index}. > {args.alternative_command}") + + + display_unique_changes(args.index, history, changes_history) - Z = get_zmp(env) - changes = set(np.nonzero(Z != last_Z)[0]) - - history.append((cmd, env.get_state(), Z)) - changes_history.append(changes) - - # ans = "" - # while ans not in {'y', 'n', 's'}: - # ans = input("State has changed? [y/n/s]> ").lower() - - # if ans == "y": - # relevant_indices |= changes - noise_indices - # elif ans == "s": - # pass - # elif ans == "n": - # noise_indices |= changes - # relevant_indices -= noise_indices - # else: - # assert False - - #print(special_indices) - - # display_relevant(Z, changes, relevant_indices, noise_indices) - - def display_objs_diff(): - print("Objects diff:") - for o1, o2 in zip(last_env_objs, env_objs): - if o1 != o2: - print(colored(f"{o1}\n{o2}", "red")) - - print("Cleaned objects diff:") - for o1, o2 in zip(last_env_objs_cleaned, env_objs_cleaned): - if o1 != o2: - print(colored(f"{o1}\n{o2}", "red")) - - # breakpoint() - - def search_unique_changes(idx): - counter = {idx: 0 for idx in changes_history[idx]} - matches = {idx: [] for idx in changes_history[idx]} - for i, changes in enumerate(changes_history): - for idx in changes: - if idx in counter: - counter[idx] += 1 - matches[idx].append((i, history[i+1][0], history[i+1][2][idx])) - - for idx, count in sorted(counter.items(), key=lambda e: e[::-1]): - # if matches[idx][0][0] == 0: - # continue - - print(f"{idx:6d}: {count:3d} : " + ", ".join(f"{i}.{cmd}({value})" for i, cmd, value in matches[idx][:20])) - - #if len(changes_history) > : - print(f"Ram changes unique to command: {args.index}. > {history[args.index+1][0]}") - search_unique_changes(args.index) - # display_indices(search_unique_changes(args.index)) - if args.debug: - breakpoint() +if __name__ == "__main__": + main() From 9d79eb274b2d547553ae161025a56e7a89850363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 17 Nov 2021 16:16:08 -0500 Subject: [PATCH 15/85] Add get_calls_stack as a more precise alternative to getRetPC --- jericho/jericho.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/jericho/jericho.py b/jericho/jericho.py index 041df662..6480cc8c 100644 --- a/jericho/jericho.py +++ b/jericho/jericho.py @@ -665,6 +665,25 @@ def get_state(self): state = ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative, state_changed return state + def get_calls_stack(self): + "TODO: this might be more precise than RetPC" + stack = np.zeros(self.frotz_lib.getStackSize(), dtype=np.uint8) + self.frotz_lib.getStack(as_ctypes(stack)) + stack = stack.view("uint16") + + frame_count = self.frotz_lib.getFrameCount() + fp = self.frotz_lib.getFP() + + calls = [] + for _ in range(frame_count, 0, -1): + sp = fp; sp += 1 + fp = 0 + 1 + stack[sp]; sp += 1 + pc = stack[sp]; sp += 1 + pc = (stack[sp] << 9) | pc; sp += 1 + calls.append(pc) + + return calls[::-1] + def get_max_score(self): ''' Returns the integer maximum possible score for the game. ''' return self.frotz_lib.get_max_score() From 52c33368e71881878a6a9a864392e860be7b12e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 17 Nov 2021 16:16:17 -0500 Subject: [PATCH 16/85] Planetfall and plundered --- frotz/src/games/planetfall.c | 13 +++++++------ frotz/src/games/plundered.c | 28 +++++++++++++++++++--------- jericho/game_info.py | 2 +- tools/test_games.py | 17 +++++++++++++++-- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/frotz/src/games/planetfall.c b/frotz/src/games/planetfall.c index c1bb396c..e1f0053d 100644 --- a/frotz/src/games/planetfall.c +++ b/frotz/src/games/planetfall.c @@ -59,12 +59,13 @@ char** planetfall_intro_actions(int *n) { } char* planetfall_clean_observation(char* obs) { - char* pch; - pch = strchr(obs, '\n'); - if (pch != NULL) { - return pch+1; - } - return obs; + // char* pch; + + // pch = + // if (pch != NULL) { + // return pch+1; + // } + return obs + strspn(obs, "> \n"); // Skip leading prompt, whitespaces, and newlines. } int planetfall_victory() { diff --git a/frotz/src/games/plundered.c b/frotz/src/games/plundered.c index 892292ba..9ecb1880 100644 --- a/frotz/src/games/plundered.c +++ b/frotz/src/games/plundered.c @@ -24,27 +24,37 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Plundered Hearts: http://ifdb.tads.org/viewgame?id=ddagftras22bnz8h -const zword plundered_special_ram_addrs[1] = { +const zword plundered_special_ram_addrs[10] = { 729, // Tracks how far you have climbed the ladder + 863, // Dip rag in water. + 687, // Interacting with Lafond. + 881, // Wait for Crulley to come back. + 889, // Hit Crulley with coffer + 1003, // Butler's falling asleep + 1071, // Dialog with Jamison + 1133, // In the cask, current pulling you. + 1143, // Crocodile falling asleep. + 9603, // Mast falls to the deck }; +const char *plundered_intro[] = { "\n" }; + zword* plundered_ram_addrs(int *n) { - *n = 1; + *n = 10; return plundered_special_ram_addrs; } char** plundered_intro_actions(int *n) { - *n = 0; - return NULL; + *n = 1; + return plundered_intro; } char* plundered_clean_observation(char* obs) { - char* pch; - pch = strchr(obs, '\n'); - if (pch != NULL) { - return pch+1; + if (strstr(obs, ">SHOOT") != NULL){ + return obs; } - return obs; + + return obs + strspn(obs, "> \n"); // Skip leading prompt, whitespaces, and newlines. } int plundered_victory() { diff --git a/jericho/game_info.py b/jericho/game_info.py index 21e498c5..fc3408da 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -363,7 +363,7 @@ "rom": "plundered.z3", "seed" : 0, # Walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip - "walkthrough": "Z/STAND UP/Z/Z/GET COFFER/Z/HIT CRULLEY WITH COFFER/Z/Z/READ MISSIVE/YES/Z/Z/STAND UP/Z/Z/Z/N/OPEN CUPBOARD/IN/GET CLOTHES/REMOVE FROCK/TEAR IT/WEAR BREECHES/WEAR SHIRT/OUT/Z/D/N/N/GET BOTTLE/S/S/OPEN COFFER/GET INVITATION/U/S/SMASH WINDOW WITH COFFER/S/CLIMB ROPE/U/U/U/U/N/N/EXAMINE BARRELS/DIP RAG IN WATER/OPEN HATCH/D/THROW RAG AT FIRE/U/N/EXAMINE WINCH/RAISE LEVER/IN/GET DAGGER/OUT/S/S/SIT IN CASK/CUT LINE WITH DAGGER/CUT LINE WITH DAGGER/GET PORK/Z/Z/GET OUT OF CASK/W/N/W/N/E/Z/GET GARTER/W/S/NE/U/REMOVE CLOTHES/GET GOWN/WEAR IT/N/E/D/SHOW INVITATION TO BUTLER/S/Z/Z/Z/Z/E/N/N/EXAMINE BOOKCASE/GET TREATISE/GET HAT/PRESS ISLAND/N/D/E/E/GET KEY/GET HORN/W/W/S/EXAMINE BOTTLE/READ LABEL/PUT LAUDANUM ON PORK/GIVE PORK TO CROCODILE/Z/Z/S/W/UNLOCK DOOR WITH KEY/OPEN IT/N/GIVE GARTER TO PAPA/S/E/N/N/U/S/S/W/S/Z/Z/Z/N/Z/Z/Z/N/U/E/OPEN DOOR/N/DRINK WINE/POUR WINE IN GREEN GOBLET/POUR WINE IN BLUE GOBLET/PUT LAUDANUM IN BLUE GOBLET/GET SPICES/BLOW SPICES AT LAFOND/GET TRAY/WAVE IT IN MOONLIGHT/S/GIVE BLUE GOBLET TO BUTLER/Z/Z/Z/Z/S/W/D/E/N/Open portrait/N/D/S/S/GET RAPIER/ATTACK CRULLEY/AGAIN/WAKE FALCON WITH SALTS/UNLOCK CHAIN WITH BROOCH/N/N/U/S/S/W/U/E/S/UNTIE ROPE/CLIMB DOWN ROPE/GET ALL/S/S/S/Z/Z/YES/GET PISTOL/LOAD IT/SHOOT CRULLEY", + "walkthrough": "STAND UP/Z/Z/GET COFFER/Z/HIT CRULLEY WITH COFFER/Z/Z/READ MISSIVE/YES/Z/Z/STAND UP/Z/Z/Z/N/OPEN CUPBOARD/IN/GET CLOTHES/REMOVE FROCK/TEAR IT/WEAR BREECHES/WEAR SHIRT/OUT/Z/D/N/N/GET BOTTLE/S/S/OPEN COFFER/GET INVITATION/U/S/SMASH WINDOW WITH COFFER/S/CLIMB ROPE/U/U/U/U/N/N/EXAMINE BARRELS/DIP RAG IN WATER/OPEN HATCH/D/THROW RAG AT FIRE/U/N/EXAMINE WINCH/RAISE LEVER/IN/GET DAGGER/OUT/S/S/SIT IN CASK/CUT LINE WITH DAGGER/CUT LINE WITH DAGGER/GET PORK/Z/Z/GET OUT OF CASK/W/N/W/N/E/Z/GET GARTER/W/S/NE/U/REMOVE CLOTHES/GET GOWN/WEAR IT/N/E/D/SHOW INVITATION TO BUTLER/S/Z/Z/Z/Z/E/N/N/EXAMINE BOOKCASE/GET TREATISE/GET HAT/PRESS ISLAND/N/D/E/E/GET KEY/GET HORN/W/W/S/EXAMINE BOTTLE/READ LABEL/PUT LAUDANUM ON PORK/GIVE PORK TO CROCODILE/Z/Z/S/W/UNLOCK DOOR WITH KEY/OPEN IT/N/GIVE GARTER TO PAPA/S/E/N/N/U/S/S/W/S/Z/Z/Z/N/Z/Z/Z/N/U/E/OPEN DOOR/N/DRINK WINE/POUR WINE IN GREEN GOBLET/POUR WINE IN BLUE GOBLET/PUT LAUDANUM IN BLUE GOBLET/GET SPICES/BLOW SPICES AT LAFOND/GET TRAY/WAVE IT IN MOONLIGHT/S/GIVE BLUE GOBLET TO BUTLER/Z/Z/Z/Z/S/W/D/E/N/Open portrait/N/D/S/S/GET RAPIER/ATTACK CRULLEY/AGAIN/WAKE FALCON WITH SALTS/UNLOCK CHAIN WITH BROOCH/N/N/U/S/S/W/U/E/S/UNTIE ROPE/CLIMB DOWN ROPE/GET ALL/S/S/S/Z/Z/YES/GET PISTOL/LOAD IT/SHOOT CRULLEY", "grammar" : "aaieee/scream/shout/shriek/yell;applau/clap;brief;cry/gasp/sob/weep;debark/disemb;depart/exit/withdr;disrob/strip/undres;dive/jump/leap/vault;doze/nap/sleep/snooze;dress;duck/go/wade;enter;greet/hello/hi;help/hint/warn;hide;i/invent;l/look/watch;laugh/smile;leave;listen;moan/sigh;nay/never/no/nope;nod/ok/okay/sure/y/yes/yup;procee/run/sidle/step/walk;q/quit;rescue/save;restar;restor;rise/stand;score;script;smell/sniff/whiff;super/superb;swim;thank/thanks;unscri;verbos;versio;wait/z;aaieee/scream/shout/shriek/yell at OBJ;aaieee/scream/shout/shriek/yell to OBJ;aim/point/shine/signal OBJ;applau/clap OBJ;approa OBJ;ask for OBJ;attack/bash/fight/hit/kill/murder/punch/slap/strike/whack OBJ;awake/revive/rouse/wake OBJ;awake/revive/rouse/wake up OBJ;bind/fetter/hobble/manacl/shackl OBJ;bite OBJ;blow OBJ;blow/dip/hang/insert/lay/place/put/sprink/stick out OBJ;board/mount/ride OBJ;boost/lift/raise OBJ;bounce/shake OBJ;bow/curtse/curtsy to OBJ;break/crush/damage/demoli/destro/smash/trampl/wreck OBJ;break/crush/damage/demoli/destro/smash/trampl/wreck down OBJ;break/crush/damage/demoli/destro/smash/trampl/wreck out OBJ;bribe OBJ;browse/read/skim OBJ;browse/read/skim throug OBJ;burn/melt OBJ;burn/melt up OBJ;carry/get/grab/hold/take OBJ;carry/get/grab/hold/take down OBJ;carry/get/grab/hold/take dresse OBJ;carry/get/grab/hold/take drunk OBJ;carry/get/grab/hold/take off OBJ;carry/get/grab/hold/take on OBJ;carry/get/grab/hold/take out OBJ;carry/get/grab/hold/take undres OBJ;chase/follow/pursue OBJ;circle OBJ;clean/wash/wipe OBJ;clean/wash/wipe off OBJ;clean/wash/wipe up OBJ;climb/crawl/scale OBJ;climb/crawl/scale off OBJ;climb/crawl/scale on OBJ;climb/crawl/scale out OBJ;climb/crawl/scale over OBJ;climb/crawl/scale up OBJ;climb/crawl/scale/carry/get/grab/hold/take in OBJ;climb/crawl/scale/duck/go/wade under OBJ;climb/crawl/scale/duck/go/wade/dive/jump/leap/vault/procee/run/sidle/step/walk throug OBJ;climb/crawl/scale/slide down OBJ;close/shut OBJ;close/shut off OBJ;close/shut up OBJ;cut/slice/stab OBJ;dance/piroue/twirl OBJ;dance/piroue/twirl with OBJ;deacti/douse/exting OBJ;debark/disemb OBJ;depart/exit/withdr OBJ;descen OBJ;descri/examin/inspec/observ/study/x OBJ;devour/eat/nibble/taste OBJ;dig in OBJ;dig throug OBJ;dip/hang/insert/lay/place/put/sprink/stick down OBJ;dip/hang/insert/lay/place/put/sprink/stick on OBJ;disrob/strip/undres OBJ;dive/jump/leap/vault down OBJ;dive/jump/leap/vault off OBJ;dive/jump/leap/vault out OBJ;dive/jump/leap/vault over OBJ;dive/jump/leap/vault overbo OBJ;dive/jump/leap/vault to OBJ;dive/jump/leap/vault up OBJ;dive/jump/leap/vault/dive/jump/leap/vault across OBJ;don/wear OBJ;doze/nap/sleep/snooze in OBJ;doze/nap/sleep/snooze on OBJ;dress OBJ;drink/quaff/sip/swallo OBJ;drink/quaff/sip/swallo from OBJ;drop/dump OBJ;dry/squeez/wring OBJ;duck/go/wade OBJ;duck/go/wade/come with OBJ;duck/go/wade/dive/jump/leap/vault/procee/run/sidle/step/walk in OBJ;duck/go/wade/hide/rise/stand/procee/run/sidle/step/walk behind OBJ;duck/go/wade/move/pull/procee/run/sidle/step/walk around OBJ;duck/go/wade/procee/run/sidle/step/walk away OBJ;duck/go/wade/procee/run/sidle/step/walk down OBJ;duck/go/wade/procee/run/sidle/step/walk to OBJ;duck/go/wade/procee/run/sidle/step/walk up OBJ;embrac/hug OBJ;empty OBJ;empty out OBJ;enter OBJ;faint/swoon OBJ;feed OBJ;feel/grip/rub/smooth/touch throug OBJ;fiddle/joggle/wiggle with OBJ;fill/load OBJ;find/locate/seek OBJ;fire/shoot/sling OBJ;fire/shoot/sling at OBJ;fix/repair/sharpe/whet OBJ;flick/flip/rotate/set/spin/switch/turn OBJ;flick/flip/rotate/set/spin/switch/turn around OBJ;flick/flip/rotate/set/spin/switch/turn off OBJ;flick/flip/rotate/set/spin/switch/turn on OBJ;free/loosen/unatta/unknot/untie/unweav OBJ;greet/hello/hi OBJ;hear OBJ;help/hint/warn OBJ;hide under OBJ;hurl/throw/toss OBJ;hurl/throw/toss away OBJ;hurl/throw/toss overbo OBJ;i/invent love OBJ;kick OBJ;kiss OBJ;knock/pound/rap at OBJ;knock/pound/rap down OBJ;knock/pound/rap on OBJ;knock/pound/rap over OBJ;l/look/watch OBJ;l/look/watch around OBJ;l/look/watch at OBJ;l/look/watch behind OBJ;l/look/watch down OBJ;l/look/watch in OBJ;l/look/watch on OBJ;l/look/watch out OBJ;l/look/watch over OBJ;l/look/watch throug OBJ;l/look/watch to OBJ;l/look/watch up OBJ;l/look/watch/rummag/search for OBJ;l/look/watch/rummag/search under OBJ;laugh/smile at OBJ;launch OBJ;lean agains OBJ;leave OBJ;let go OBJ;lie down OBJ;lie in OBJ;lie on OBJ;light OBJ;listen to OBJ;lock OBJ;lower OBJ;make love OBJ;make out OBJ;marry/wed OBJ;move/pull OBJ;move/pull down OBJ;move/pull in OBJ;move/pull up OBJ;oar/row OBJ;oar/row to OBJ;open OBJ;open up OBJ;pick OBJ;pick up OBJ;play with OBJ;pour/spill OBJ;press/push OBJ;press/push down OBJ;press/push on OBJ;press/push/boost/lift/raise up OBJ;procee/run/sidle/step/walk OBJ;procee/run/sidle/step/walk across OBJ;procee/run/sidle/step/walk out OBJ;procee/run/sidle/step/walk over OBJ;rape OBJ;reach in OBJ;remove OBJ;rescue/save OBJ;return OBJ;rip/tear OBJ;rip/tear up OBJ;rise/stand in OBJ;rise/stand on OBJ;rise/stand/carry/get/grab/hold/take up OBJ;roll/tip OBJ;rummag/search OBJ;rummag/search in OBJ;rummag/search throug OBJ;sink OBJ;sit down OBJ;sit in OBJ;sit on OBJ;smell/sniff/whiff OBJ;soak/wet OBJ;speak/talk to OBJ;stop OBJ;swim in OBJ;swing OBJ;swing down OBJ;swing from OBJ;swing on OBJ;tap on OBJ;tap/feel/grip/rub/smooth/touch OBJ;tell OBJ;thank/thanks OBJ;unbar/unlock OBJ;unroll OBJ;use OBJ;wave OBJ;wave at OBJ;what/what'/whats/who/whos OBJ;where/wheres/whithe OBJ;zzmgck OBJ;aim/point/shine/signal OBJ at OBJ;aim/point/shine/signal OBJ from OBJ;aim/point/shine/signal OBJ in OBJ;aim/point/shine/signal OBJ on OBJ;aim/point/shine/signal OBJ out OBJ;aim/point/shine/signal OBJ with OBJ;ask OBJ about OBJ;ask OBJ for OBJ;ask OBJ to OBJ;attach/fasten/moor/secure/tie/weave OBJ around OBJ;attach/fasten/moor/secure/tie/weave OBJ to OBJ;attach/fasten/moor/secure/tie/weave OBJ with OBJ;attach/fasten/moor/secure/tie/weave up OBJ with OBJ;attack/bash/fight/hit/kill/murder/punch/slap/strike/whack OBJ with OBJ;awake/revive/rouse/wake OBJ with OBJ;blow OBJ at OBJ;blow OBJ on OBJ;bounce/shake OBJ with OBJ;break/crush/damage/demoli/destro/smash/trampl/wreck OBJ with OBJ;bribe OBJ with OBJ;browse/read/skim OBJ throug OBJ;browse/read/skim OBJ with OBJ;burn/melt OBJ in OBJ;carry/get/grab/hold/take OBJ from OBJ;carry/get/grab/hold/take OBJ in OBJ;carry/get/grab/hold/take OBJ off OBJ;carry/get/grab/hold/take OBJ on OBJ;carry/get/grab/hold/take OBJ out OBJ;carry/get/grab/hold/take OBJ with OBJ;close/shut OBJ on OBJ;cover OBJ with OBJ;cut/slice/stab OBJ with OBJ;cut/slice/stab throug OBJ with OBJ;dip/hang/insert/lay/place/put/sprink/stick OBJ around OBJ;dip/hang/insert/lay/place/put/sprink/stick OBJ behind OBJ;dip/hang/insert/lay/place/put/sprink/stick OBJ over OBJ;dip/hang/insert/lay/place/put/sprink/stick OBJ throug OBJ;drink/quaff/sip/swallo OBJ from OBJ;drop/dump OBJ down OBJ;drop/dump OBJ in OBJ;drop/dump OBJ throug OBJ;drop/dump/dip/hang/insert/lay/place/put/sprink/stick OBJ out OBJ;dry/squeez/wring OBJ from OBJ;dry/squeez/wring OBJ in OBJ;dry/squeez/wring OBJ on OBJ;dry/squeez/wring OBJ out OBJ;empty OBJ from OBJ;empty OBJ in OBJ;empty OBJ on OBJ;feed OBJ OBJ;feed OBJ with OBJ;feel/grip/rub/smooth/touch OBJ on OBJ;feel/grip/rub/smooth/touch OBJ with OBJ;fill/load OBJ in OBJ;fill/load OBJ with OBJ;find/locate/seek OBJ on OBJ;fire/shoot/sling OBJ at OBJ;fire/shoot/sling OBJ in OBJ;fire/shoot/sling OBJ with OBJ;flick/flip/rotate/set/spin/switch/turn OBJ to OBJ;give/hand/offer/presen OBJ OBJ;give/hand/offer/presen OBJ with OBJ;give/hand/offer/presen/pay/feed/pass OBJ to OBJ;hurl/throw/toss OBJ OBJ;hurl/throw/toss OBJ at OBJ;hurl/throw/toss OBJ down OBJ;hurl/throw/toss OBJ in OBJ;hurl/throw/toss OBJ on OBJ;hurl/throw/toss OBJ out OBJ;hurl/throw/toss OBJ over OBJ;hurl/throw/toss OBJ throug OBJ;hurl/throw/toss OBJ to OBJ;hurl/throw/toss OBJ with OBJ;leave/dip/hang/insert/lay/place/put/sprink/stick OBJ in OBJ;leave/drop/dump/dip/hang/insert/lay/place/put/sprink/stick OBJ on OBJ;light OBJ in OBJ;light OBJ on OBJ;light OBJ with OBJ;lock OBJ with OBJ;lower OBJ out OBJ;lower OBJ throug OBJ;move/pull OBJ to OBJ;muzzle OBJ with OBJ;oar/row OBJ OBJ;oar/row OBJ to OBJ;open OBJ with OBJ;pick OBJ with OBJ;pour/spill OBJ from OBJ;pour/spill OBJ in OBJ;pour/spill OBJ on OBJ;pour/spill OBJ out OBJ;press/push OBJ in OBJ;press/push OBJ on OBJ;press/push/dip/hang/insert/lay/place/put/sprink/stick OBJ under OBJ;press/push/move/pull OBJ OBJ;press/push/move/pull OBJ down OBJ;press/push/move/pull OBJ up OBJ;reflec OBJ in OBJ;remove OBJ from OBJ;return OBJ to OBJ;rip/tear OBJ in OBJ;rip/tear OBJ with OBJ;roll/tip/press/push OBJ to OBJ;show OBJ OBJ;show OBJ to OBJ;soak/wet OBJ in OBJ;soak/wet OBJ with OBJ;swing OBJ at OBJ;tell OBJ OBJ;tell OBJ about OBJ;unbar/unlock OBJ with OBJ;use OBJ on OBJ;wave OBJ at OBJ;wave OBJ in OBJ;wrap OBJ around OBJ;wrap OBJ in OBJ;", "max_word_length" : 6 } diff --git a/tools/test_games.py b/tools/test_games.py index 48383dee..9b1b6ff0 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -398,7 +398,17 @@ "pentari.z5": {}, "planetfall.z3": { 216: "eat brown goo", # Not needed to complete the game. - } + }, + "plundered.z3": { + # 11: "z", # Dialog. [Press RETURN or ENTER to continue.] + 61: "cut line with dagger", # Not needed. + 106: "read label", # Not needed. + 116: "give garter to papa", # Not needed. + 129: "n", # Not needed. + 131: "z", # Not needed. + 151: "z", # Not needed. + }, + } @@ -414,7 +424,8 @@ def test_walkthrough(env, walkthrough): msg = "FAIL\tDone but score {}/{}".format(info["score"], env.get_max_score()) print(colored(msg, 'yellow')) else: - print(colored("PASS", 'green')) + msg = "PASS\tScore {}/{}".format(info["score"], env.get_max_score()) + print(colored(msg, 'green')) def parse_args(): @@ -534,6 +545,8 @@ def parse_args(): last_env_objs_cleaned = env.get_world_objects(clean=True) obs, rew, done, info = env.step(cmd) + # calls = env.get_calls_stack() + # print(" -> ".join(map(hex, calls))) env_objs = env.get_world_objects(clean=False) env_objs_cleaned = env.get_world_objects(clean=True) From 64d1c28f95878385938d68385bda1d0bdee4d1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 17 Nov 2021 16:18:03 -0500 Subject: [PATCH 17/85] Reverb --- tools/test_games.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/test_games.py b/tools/test_games.py index 9b1b6ff0..c3f10728 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -408,6 +408,10 @@ 131: "z", # Not needed. 151: "z", # Not needed. }, + "reverb.z5": { + 1: "read note", # Not needed. + "z": [50, 51], # Not needed. + }, } From 59c0a725ec3574da3f0e0b24525a6da3a6345a07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 17 Nov 2021 16:33:42 -0500 Subject: [PATCH 18/85] seastalker --- frotz/src/games/seastalker.c | 10 ++++++---- tools/test_games.py | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/frotz/src/games/seastalker.c b/frotz/src/games/seastalker.c index 1783686e..3b364d06 100644 --- a/frotz/src/games/seastalker.c +++ b/frotz/src/games/seastalker.c @@ -26,13 +26,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *seastalker_intro[] = { "John\n", "Wayne\n", "yes\n" }; -const zword seastalker_special_ram_addrs[1] = { - 9740, // Tracks scimitar location +const zword seastalker_special_ram_addrs[5] = { + 9736, 9740, 9742, // Tracks scimitar location + 9490, // Fill tank + 9668, // Change throttle }; zword* seastalker_ram_addrs(int *n) { - *n = 1; - return seastalker_ram_addrs; + *n = 5; + return seastalker_special_ram_addrs; } char** seastalker_intro_actions(int *n) { diff --git a/tools/test_games.py b/tools/test_games.py index c3f10728..acde348c 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -410,8 +410,19 @@ }, "reverb.z5": { 1: "read note", # Not needed. - "z": [50, 51], # Not needed. - }, + "z": [50, 51], # Not needed. + }, + "seastalker.z3": { + 4: "ask bly about problem", # Not needed. + 5: "ask bly about monster", # Not needed. + 11: "ask computestor about videophone", # Not needed. + 18: "ask kemp about circuit breaker", # Not needed. + 27: "push test button", # Not needed. + 28: "read sign", # Not needed. + 105: "e", # Can't go. + 128: "s", # Can't go. + 151: "s", # Too crowed. Have to wait. + } } From bf64560e8fcc949ddf633fa8650a5a4626ec23f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Tue, 23 Nov 2021 14:33:25 -0500 Subject: [PATCH 19/85] ENH: separate buffer for upper (status line) and lower screen --- frotz/src/dumb/dumb_frotz.h | 1 + frotz/src/dumb/dumb_output.c | 60 +++++++++++++++++++++++---- frotz/src/interface/frotz_interface.c | 40 +++++++++++------- frotz/src/interface/frotz_interface.h | 2 +- 4 files changed, 78 insertions(+), 25 deletions(-) diff --git a/frotz/src/dumb/dumb_frotz.h b/frotz/src/dumb/dumb_frotz.h index 67fa12a2..166b65da 100644 --- a/frotz/src/dumb/dumb_frotz.h +++ b/frotz/src/dumb/dumb_frotz.h @@ -44,6 +44,7 @@ void dumb_set_picture_cell(int row, int col, char c); void dumb_row_to_str(char *s); void dumb_clear_output(void); char* dumb_get_screen(void); +char* dumb_get_lower_screen(void); void dumb_clear_screen(void); /* dumb-pic.c */ diff --git a/frotz/src/dumb/dumb_output.c b/frotz/src/dumb/dumb_output.c index acc1ba30..c28ebc12 100644 --- a/frotz/src/dumb/dumb_output.c +++ b/frotz/src/dumb/dumb_output.c @@ -50,9 +50,13 @@ static cell make_cell(int style, char c) {return (style << 8) | (0xff & c);} static char cell_char(cell c) {return c & 0xff;} static int cell_style(cell c) {return c >> 8;} +#define UPPER_SCREEN_BUFF_SIZE 256 #define SCREEN_BUFF_SIZE 8192 -static char screen_buffer[SCREEN_BUFF_SIZE]; +static char screen_buffer[SCREEN_BUFF_SIZE]; // aka window 0 (lower screen) +static char upper_screen_buffer[UPPER_SCREEN_BUFF_SIZE]; // aka window 1 (upper screen) + char* screen_buffer_ptr = screen_buffer; +char* upper_screen_buffer_ptr = upper_screen_buffer; /* A cell's style is REVERSE_STYLE, normal (0), or PICTURE_STYLE. * PICTURE_STYLE means the character is part of an ascii image outline @@ -114,7 +118,12 @@ int os_string_width (const zchar *s) void os_set_cursor(int row, int col) { - cursor_row = row - 1; cursor_col = col - 1; + //printf("\n--> win:%d\trow:%d\tcol:%d MAX_COLS:%d<--\n", cwin, row, col, h_screen_cols); + if (cwin == 1 && row == 1) { + upper_screen_buffer_ptr = upper_screen_buffer + (col-1); + } + + cursor_row = row - 1; cursor_col = col - 1; // 0-index if (cursor_row >= h_screen_rows) cursor_row = h_screen_rows - 1; } @@ -148,9 +157,16 @@ void os_set_text_style(int x) /* put a character in the cell at the cursor and advance the cursor. */ static void dumb_display_char(char c) { - if ((screen_buffer_ptr - screen_buffer) < (SCREEN_BUFF_SIZE - 1)) { - *screen_buffer_ptr++ = c; - } + if (cwin == 1 && cursor_row == 0) { + if ((upper_screen_buffer_ptr - upper_screen_buffer) < (UPPER_SCREEN_BUFF_SIZE - 1)) { + *upper_screen_buffer_ptr++ = c; + } + } + else { + if ((screen_buffer_ptr - screen_buffer) < (SCREEN_BUFF_SIZE - 1)) { + *screen_buffer_ptr++ = c; + } + } } void dumb_display_user_input(char *s) @@ -210,7 +226,7 @@ void os_display_string (const zchar *s) } } -void os_erase_area (int top, int left, int bottom, int right, int UNUSED (win)) +void os_erase_area (int top, int left, int bottom, int right, int win) { int row, col; top--; left--; bottom--; right--; @@ -222,9 +238,16 @@ void os_erase_area (int top, int left, int bottom, int right, int UNUSED (win)) void os_scroll_area (int top, int left, int bottom, int right, int units) { - if ((screen_buffer_ptr - screen_buffer) < (SCREEN_BUFF_SIZE - 1)) { - *screen_buffer_ptr++ = '\n'; - } + if (cwin == 1) { + if ((upper_screen_buffer_ptr - upper_screen_buffer) < (UPPER_SCREEN_BUFF_SIZE - 1)) { + *upper_screen_buffer_ptr++ = '\n'; + } + } + else { + if ((screen_buffer_ptr - screen_buffer) < (SCREEN_BUFF_SIZE - 1)) { + *screen_buffer_ptr++ = '\n'; + } + } } int os_font_data(int font, int *height, int *width) @@ -557,6 +580,25 @@ void dumb_clear_screen(void) { screen_buffer_ptr = screen_buffer; } + +char* dumb_get_lower_screen(void) { + *screen_buffer_ptr = '\0'; + return screen_buffer; +} + +void dumb_clear_lower_screen(void) { + screen_buffer_ptr = screen_buffer; +} + +char* dumb_get_upper_screen(void) { + upper_screen_buffer[UPPER_SCREEN_BUFF_SIZE-1] = '\0'; + return upper_screen_buffer; +} + +void dumb_clear_upper_screen(void) { + upper_screen_buffer_ptr = upper_screen_buffer; +} + void dumb_free(void) { if (screen_data) { free(screen_data); diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index da67a99d..4fa2b231 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -37,6 +37,10 @@ extern void dumb_set_next_action (char *a); extern void dumb_show_screen (int a); extern char* dumb_get_screen(void); extern void dumb_clear_screen(void); +extern char* dumb_get_lower_screen(void); +extern void dumb_clear_lower_screen(void); +extern char* dumb_get_upper_screen(void); +extern void dumb_clear_upper_screen(void); extern void z_save (void); extern void load_story(char *s); extern void load_story_rom(char *s, void* rom, size_t rom_size); @@ -72,7 +76,9 @@ zbyte next_opcode; int last_ret_pc = -1; int desired_seed = 0; int ROM_IDX = 0; -char world[8192] = ""; + +char world[256 + 8192] = ""; // Upper + lower screens. + int emulator_halted = 0; char halted_message[] = "Emulator halted due to runtime error.\n"; // Track the addresses and values of special per-game ram locations. @@ -1427,10 +1433,8 @@ void take_intro_actions() { char* text; for (int i=0; i Date: Wed, 24 Nov 2021 09:59:26 -0500 Subject: [PATCH 20/85] Tweak find_special_ram.py --- tools/find_special_ram.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/find_special_ram.py b/tools/find_special_ram.py index bf5fe091..be41b1f3 100644 --- a/tools/find_special_ram.py +++ b/tools/find_special_ram.py @@ -186,8 +186,8 @@ def display_unique_changes(idx, history, changes_history): matches[idx].append((i, history[i+1]["cmd"], history[i+1]["zmp"][idx])) for idx, count in sorted(counter.items(), key=lambda e: e[::-1]): - if matches[idx][0][0] == 0: - continue + # if matches[idx][0][0] == 0: + # continue print(f"{idx:6d}: {count:3d} : " + ", ".join(f"{i}.{cmd}({value})" for i, cmd, value in matches[idx][:20])) @@ -206,7 +206,7 @@ def main(): return walkthrough = env.get_walkthrough() - history = collect_zmp(env, walkthrough, verbose=False) + history = collect_zmp(env, walkthrough, verbose=True) changes_history = compute_zmp_changes(history) print(f"Ram changes unique to command: {args.index}. > {history[args.index+1]['cmd']}") From 16c0a9e5f3e28ecb51199d9ad130763e5e1a0409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 24 Nov 2021 09:59:40 -0500 Subject: [PATCH 21/85] Sherlock --- frotz/src/games/sherlock.c | 40 ++++++++++++++++++++++++++++++++++++-- jericho/game_info.py | 4 +++- tools/test_games.py | 16 +++++++++++++-- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/frotz/src/games/sherlock.c b/frotz/src/games/sherlock.c index f3fd3e54..a4a20c99 100644 --- a/frotz/src/games/sherlock.c +++ b/frotz/src/games/sherlock.c @@ -26,9 +26,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *sherlock_intro[] = { "\n" }; +const zword sherlock_special_ram_addrs[12] = { + 4500, // Light matches. + 4752, // light pipe with match + 15839, // Light newspaper with pipe, light torch with newspaper. + 779, // Haggling with salesman + 883, // Track bell reachability (swinging) + 1051, // First blows of the whistle to call a cab. + 5676, // Wearing the cotton balls. + 4948, // Wearing the stethoscope. + 1151, // Listen to the girl's heartbeat and give her the pill. + 1083, // tell pigeon to get ruby + 785, 1039, // Turning the dial of bank's vault door. + // 16088, // Track seconds (alt. 16084) + // 16089, // Track minutes (alt. 16085) + // 16090, // Track hours +}; + zword* sherlock_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 12; + return sherlock_special_ram_addrs; } char** sherlock_intro_actions(int *n) { @@ -37,6 +54,25 @@ char** sherlock_intro_actions(int *n) { } char* sherlock_clean_observation(char* obs) { + char* pch; + pch = strrchr(obs, '\n'); + if (pch != NULL) { + // Extract time from status line. E.g. + // " Vestibule [...] Saturday 5:01:00 a.m. Score: 0" + // ^ ^ + // 88 117 + memcpy(pch, + pch + 88, // Beginning of Time. + 117-88); // Beginning of Score - Beginning of Time. + pch += (117-88); // Add termination character after the Time. + *(pch) = '\0'; + } + + pch = strchr(obs, '>'); + if (pch != NULL) { + return pch + 1; + } + return obs; } diff --git a/jericho/game_info.py b/jericho/game_info.py index fc3408da..44936379 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -399,7 +399,9 @@ "rom": "sherlock.z5", "seed" : 0, # Walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip - "walkthrough": "KNOCK ON DOOR/U/N/GET NEWSPAPER/SHOW IT TO HOLMES/EXAMINE SLIPPER/GET TOBACCO,KNIFE,PIPE/WAIT/No/READ PAPER/WAIT/No/W/GET LAMP, GLASS AND AMPOULE/E/S/D/N/GET MATCHBOOK/S/OPEN DOOR/E/LIGHT LAMP/N/E/TURN OFF LAMP/DROP IT/PUT TOBACCO IN PIPE/OPEN MATCHBOOK/GET MATCH/STRIKE IT/LIGHT PIPE WITH MATCH/DROP MATCH/N/ASK HOLMES ABOUT ASH/W/EXAMINE STATUES/EXAMINE FAWKES/GET TORCH/LIGHT NEWSPAPER WITH PIPE/LIGHT TORCH WITH NEWSPAPER/EXAMINE CHARLES/GET HEAD/MELT HEAD WITH TORCH/GET GEM/E/S/GET LAMP/LIGHT IT/E/Z/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO WHITEHALL/GET OUT/E/D/LOOK IN ROWBOAT/GET OAR/U/W/S/W/HAGGLE WITH SALESMAN/HAGGLE WITH SALESMAN/BUY TELESCOPE/E/Z/SE/U/OPEN BAG/OPEN BLUE BOTTLE/GET BALLS/WEAR BALLS/WAIT/WAIT/GET SAPPHIRE/GET SAPPHIRE/GET SAPPHIRE/EXAMINE SAPPHIRE/READ SAPPHIRE SCRATCH WITH GLASS/READ EMERALD SCRATCH WITH GLASS/D/NW/TURN OFF LAMP/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO COVENT GARDEN/GET OUT/REMOVE BALLS/DROP THEM/REMOVE HAT/DROP MATCHBOOK/GET STETHOSCOPE/WEAR IT/LISTEN TO GIRL/OPEN BROWN BOTTLE/TAKE YELLOW PILL/GIVE IT TO GIRL/REMOVE STETHOSCOPE/PUT IT IN HAT/WEAR HAT/N/E/S/W/ASK FOR PIGEON/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO TRAFALGAR SQUARE/GET OUT/LOOK AT STATUE THROUGH TELESCOPE/SHOW RUBY TO PIGEON/TELL PIGEON TO GET RUBY/THROW IT/DROP TELESCOPE/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO PINCHIN LANE/GET OUT/W/ASK FOR PIGEON/READ RUBY SCRATCH WITH GLASS/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO THE EMBANKMENT/GET/OUT/ENTER BOAT/INSERT OAR IN OARLOCK/WEIGH ANCHOR/S/ROW EAST/ROW EAST/DROP/ANCHOR/EXAMINE BRIDGE/EXAMINE MOSS/GET MOSS/READ OPAL SCRATCH WITH GLASS/WEIGH ANCHOR/ROW WEST/ROW WEST/N/GET OUT/N/W/N/Z/N/W/NE/N/E/OPEN BOOK/SHUT UP/OPEN BOOK/READ BOOK/W/S/SW/S/S/S/SW/E/S/SE/DROP PIPE/GET PACQUET, PAPER AND CRAYON/NW/OPEN DOOR/S/W/READ SIGN/E/N/N/EXAMINE TOMB/OPEN PACQUET OF PAPER/GET BROWN PAPER/PUT IT ON TOMB/RUB IT WITH CRAYON/GET IT/E/N/N/LOOK/HEAT BROWN PAPER OVER/CANDLES/READ BACK OF BROWN PAPER/PUT IT IN BAG/S/E/EXAMINE TOMB/GET YELLOW/PAPER/PUT IT ON TOMB/RUB IT WITH CRAYON/GET IT/S/W/EXAMINE TOMBS/GET BLUE PAPER/PUT IT ON HENRY'S TOMB/RUB IT WITH CRAYON/GET IT/DROP CRAYON AND PACQUET/E/N/W/N/HEAT YELLOW PAPER OVER CANDLES/READ BACK OF YELLOW PAPER/HEAT BLUE PAPER OVER CANDLES/READ BACK OF BLUE PAPER/DROP BLUE PAPER AND YELLOW PAPER/S/S/W/W/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO THE MONUMENT/z/GET OUT/READ PLAQUE/NW/NW/EXAMINE URCHIN/GIVE SHILLING TO WIGGINS/ASK WIGGINS TO STEAL KEYS/N/GIVE OPAL, RUBY, SAPPHIRE AND EMERALD TO GUARD/N/EXAMINE DOOR/REMOVE HAT/GET STETHOSCOPE/WEAR IT/LISTEN TO DIAL/TURN DIAL RIGHT/TURN DIAL RIGHT/TURN DIAL LEFT/TURN DIAL RIGHT/TURN DIAL RIGHT/W/UNLOCK BOX 600 WITH KEY/GET TOPAZ/READ TOPAZ SCRATCH WITH GLASS/E/S/W/W/W/S/W/ASK FOR MYCROFT HOLMES/GIVE RING TO BUTLER/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO TOWER OF LONDON/GET OUT/E/E/Aragon/N/N/SE/U/GET MACE/D/NW/NE/EXAMINE KEG/HIT BUNG WITH MACE/LOOK IN KEG/ASK WIGGINS TO GET GARNET/READ GARNET SCRATCH WITH GLASS/SW/E/D/WEAR ARMOUR/U/W/S/S/S/GET PADDLE/PULL CHAIN/S/ENTER BOAT/WEIGH ANCHOR/S/PADDLE WEST/PADDLE WEST/PADDLE WEST/N/REMOVE ARMOUR/E/E/D/W/REMOVE STETHOSCOPE/DROP IT/GET AMPOULE/PUT IT IN HAT/WEAR HAT/WAIT FOR 36 HOURS/WAIT FOR 35 MINUTES/ASK FOR AKBAR/swordfish/GIVE GARNET TO AKBAR/REMOVE HAT/GET AMPOULE/HOLD BREATH/BREAK AMPOULE/GET KNIFE/CUT ROPE WITH KNIFE/TIE MORIARTY AND AKBAR WITH ROPE/GET KEY, JEWELS AND WHISTLE/UNLOCK DOOR WITH KEY/OPEN IT/OUT/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO BUCKINGHAM PALACE/GET OUT/GIVE JEWELS TO GUARD", + "walkthrough": "KNOCK ON DOOR/U/N/GET NEWSPAPER/SHOW IT TO HOLMES/EXAMINE SLIPPER/GET TOBACCO,KNIFE,PIPE/WAIT/No/READ PAPER/WAIT/No/W/GET LAMP, GLASS AND AMPOULE/E/S/D/N/GET MATCHBOOK/S/OPEN DOOR/E/LIGHT LAMP/N/E/TURN OFF LAMP/DROP IT/PUT TOBACCO IN PIPE/OPEN MATCHBOOK/GET MATCH/STRIKE IT/LIGHT PIPE WITH MATCH/DROP MATCH/N/ASK HOLMES ABOUT ASH/W/EXAMINE STATUES/EXAMINE FAWKES/GET TORCH/LIGHT NEWSPAPER WITH PIPE/LIGHT TORCH WITH NEWSPAPER/EXAMINE CHARLES/GET HEAD/MELT HEAD WITH TORCH/GET GEM/E/S/GET LAMP/LIGHT IT/E/Z/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO WHITEHALL/GET OUT/E/D/LOOK IN ROWBOAT/GET OAR/U/W/S/W/HAGGLE WITH SALESMAN/HAGGLE WITH SALESMAN/BUY TELESCOPE/E/Z/SE/U/OPEN BAG/OPEN BLUE BOTTLE/GET BALLS/WEAR BALLS/WAIT/WAIT/GET SAPPHIRE/GET SAPPHIRE/GET SAPPHIRE/EXAMINE SAPPHIRE/READ SAPPHIRE SCRATCH WITH GLASS/READ EMERALD SCRATCH WITH GLASS/D/NW/TURN OFF LAMP/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO COVENT GARDEN/GET OUT/REMOVE BALLS/DROP THEM/REMOVE HAT/DROP MATCHBOOK/GET STETHOSCOPE/WEAR IT/LISTEN TO GIRL/OPEN BROWN BOTTLE/TAKE YELLOW PILL/GIVE IT TO GIRL/REMOVE STETHOSCOPE/PUT IT IN HAT/WEAR HAT/N/E/S/W/ASK FOR PIGEON/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO TRAFALGAR SQUARE/GET OUT/LOOK AT STATUE THROUGH TELESCOPE/SHOW RUBY TO PIGEON/TELL PIGEON TO GET RUBY/THROW IT/DROP TELESCOPE/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO PINCHIN LANE/GET OUT/W/ASK FOR PIGEON/READ RUBY SCRATCH WITH GLASS/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO THE EMBANKMENT/GET OUT/ENTER BOAT/INSERT OAR IN OARLOCK/WEIGH ANCHOR/S/ROW EAST/ROW EAST/DROP ANCHOR/EXAMINE BRIDGE/EXAMINE MOSS/GET MOSS/READ OPAL SCRATCH WITH GLASS/WEIGH ANCHOR/ROW WEST/ROW WEST/N/GET OUT/N/W/N/Z/N/W/NE/N/E/OPEN BOOK/SHUT UP/OPEN BOOK/READ BOOK/W/S/SW/S/S/S/SW/E/S/SE/DROP PIPE/GET PACQUET, PAPER AND CRAYON/NW/OPEN DOOR/S/W/READ SIGN/E/N/N/EXAMINE TOMB/OPEN PACQUET OF PAPER/GET BROWN PAPER/PUT IT ON TOMB/RUB IT WITH CRAYON/GET IT/E/N/N/LOOK/HEAT BROWN PAPER OVER CANDLES/READ BACK OF BROWN PAPER/PUT IT IN BAG/S/E/EXAMINE TOMB/GET YELLOW PAPER/PUT IT ON TOMB/RUB IT WITH CRAYON/GET IT/PUT IT IN BAG/S/W/EXAMINE TOMBS/GET BLUE PAPER/PUT IT ON HENRY'S TOMB/RUB IT WITH CRAYON/GET IT/DROP CRAYON AND PACQUET/E/N/W/N/GET YELLOW PAPER/HEAT YELLOW PAPER OVER CANDLES/READ BACK OF YELLOW PAPER/HEAT BLUE PAPER OVER CANDLES/READ BACK OF BLUE PAPER/DROP BLUE PAPER AND YELLOW PAPER/S/S/W/W/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO THE MONUMENT/z/GET OUT/READ PLAQUE/NW/NW/EXAMINE URCHIN/GIVE SHILLING TO WIGGINS/ASK WIGGINS TO STEAL KEYS/N/GIVE OPAL, RUBY, SAPPHIRE AND EMERALD TO GUARD/N/EXAMINE DOOR/REMOVE HAT/GET STETHOSCOPE/WEAR IT/LISTEN TO DIAL/TURN DIAL RIGHT/TURN DIAL RIGHT/TURN DIAL LEFT/TURN DIAL RIGHT/TURN DIAL RIGHT/W/UNLOCK BOX 600 WITH KEY/GET TOPAZ/READ TOPAZ SCRATCH WITH GLASS/E/S/W/W/W/S/z/W/ASK FOR MYCROFT HOLMES/GIVE RING TO BUTLER/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO TOWER OF LONDON/GET OUT/E/E/Aragon/N/N/SE/U/GET MACE/D/NW/NE/EXAMINE KEG/HIT BUNG WITH MACE/LOOK IN KEG/ASK WIGGINS TO GET GARNET/READ GARNET SCRATCH WITH GLASS/SW/E/D/WEAR ARMOUR/U/W/S/S/S/GET PADDLE/PULL CHAIN/S/z/ENTER BOAT/WEIGH ANCHOR/S/PADDLE WEST/PADDLE WEST/PADDLE WEST/N/REMOVE ARMOUR/E/E/D/W/REMOVE STETHOSCOPE/DROP IT/PUT AMPOULE IN HAT/WEAR HAT/WAIT FOR 36 HOURS/WAIT FOR 32 MINUTES/ASK FOR AKBAR/swordfish/GIVE GARNET TO AKBAR/REMOVE HAT/GET AMPOULE/HOLD BREATH/BREAK AMPOULE/GET KNIFE/CUT ROPE WITH KNIFE/TIE MORIARTY AND AKBAR WITH ROPE/GET KEY, JEWELS AND WHISTLE/UNLOCK DOOR WITH KEY/OPEN IT/OUT/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO BUCKINGHAM PALACE/GET OUT/GIVE JEWELS TO GUARD", + # "walkthrough": "KNOCK ON DOOR/U/N/GET NEWSPAPER/SHOW IT TO HOLMES/EXAMINE SLIPPER/GET TOBACCO,KNIFE,PIPE/WAIT/No/READ PAPER/WAIT/No/W/GET LAMP, GLASS AND AMPOULE/E/S/D/N/GET MATCHBOOK/S/OPEN DOOR/E/LIGHT LAMP/N/E/TURN OFF LAMP/DROP IT/PUT TOBACCO IN PIPE/OPEN MATCHBOOK/GET MATCH/STRIKE IT/LIGHT PIPE WITH MATCH/DROP MATCH/N/ASK HOLMES ABOUT ASH/W/EXAMINE STATUES/EXAMINE FAWKES/GET TORCH/LIGHT NEWSPAPER WITH PIPE/LIGHT TORCH WITH NEWSPAPER/EXAMINE CHARLES/GET HEAD/MELT HEAD WITH TORCH/GET GEM/E/S/GET LAMP/LIGHT IT/E/Z/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO WHITEHALL/GET OUT/E/D/LOOK IN ROWBOAT/GET OAR/U/W/S/W/HAGGLE WITH SALESMAN/HAGGLE WITH SALESMAN/BUY TELESCOPE/E/Z/SE/U/OPEN BAG/OPEN BLUE BOTTLE/GET BALLS/WEAR BALLS/WAIT/WAIT/GET SAPPHIRE/GET SAPPHIRE/GET SAPPHIRE/EXAMINE SAPPHIRE/READ SAPPHIRE SCRATCH WITH GLASS/READ EMERALD SCRATCH WITH GLASS/D/NW/TURN OFF LAMP/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO COVENT GARDEN/GET OUT/REMOVE BALLS/DROP THEM/REMOVE HAT/DROP MATCHBOOK/GET STETHOSCOPE/WEAR IT/LISTEN TO GIRL/OPEN BROWN BOTTLE/TAKE YELLOW PILL/GIVE IT TO GIRL/REMOVE STETHOSCOPE/PUT IT IN HAT/WEAR HAT/N/E/S/W/ASK FOR PIGEON/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO TRAFALGAR SQUARE/GET OUT/LOOK AT STATUE THROUGH TELESCOPE/SHOW RUBY TO PIGEON/TELL PIGEON TO GET RUBY/THROW IT/DROP TELESCOPE/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO PINCHIN LANE/GET OUT/W/ASK FOR PIGEON/READ RUBY SCRATCH WITH GLASS/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO THE EMBANKMENT/GET OUT/ENTER BOAT/INSERT OAR IN OARLOCK/WEIGH ANCHOR/S/ROW EAST/ROW EAST/DROP/ANCHOR/EXAMINE BRIDGE/EXAMINE MOSS/GET MOSS/READ OPAL SCRATCH WITH GLASS/WEIGH ANCHOR/ROW WEST/ROW WEST/N/GET OUT/N/W/N/Z/N/W/NE/N/E/OPEN BOOK/SHUT UP/OPEN BOOK/READ BOOK/W/S/SW/S/S/S/SW/E/S/SE/DROP PIPE/GET PACQUET, PAPER AND CRAYON/NW/OPEN DOOR/S/W/READ SIGN/E/N/N/EXAMINE TOMB/OPEN PACQUET OF PAPER/GET BROWN PAPER/PUT IT ON TOMB/RUB IT WITH CRAYON/GET IT/E/N/N/LOOK/HEAT BROWN PAPER OVER/CANDLES/READ BACK OF BROWN PAPER/PUT IT IN BAG/S/E/EXAMINE TOMB/GET YELLOW/PAPER/PUT IT ON TOMB/RUB IT WITH CRAYON/GET IT/S/W/EXAMINE TOMBS/GET BLUE PAPER/PUT IT ON HENRY'S TOMB/RUB IT WITH CRAYON/GET IT/DROP CRAYON AND PACQUET/E/N/W/N/HEAT YELLOW PAPER OVER CANDLES/READ BACK OF YELLOW PAPER/HEAT BLUE PAPER OVER CANDLES/READ BACK OF BLUE PAPER/DROP BLUE PAPER AND YELLOW PAPER/S/S/W/W/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO THE MONUMENT/z/GET OUT/READ PLAQUE/NW/NW/EXAMINE URCHIN/GIVE SHILLING TO WIGGINS/ASK WIGGINS TO STEAL KEYS/N/GIVE OPAL, RUBY, SAPPHIRE AND EMERALD TO GUARD/N/EXAMINE DOOR/REMOVE HAT/GET STETHOSCOPE/WEAR IT/LISTEN TO DIAL/TURN DIAL RIGHT/TURN DIAL RIGHT/TURN DIAL LEFT/TURN DIAL RIGHT/TURN DIAL RIGHT/W/UNLOCK BOX 600 WITH KEY/GET TOPAZ/READ TOPAZ SCRATCH WITH GLASS/E/S/W/W/W/S/W/ASK FOR MYCROFT HOLMES/GIVE RING TO BUTLER/E/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO TOWER OF LONDON/GET OUT/E/E/Aragon/N/N/SE/U/GET MACE/D/NW/NE/EXAMINE KEG/HIT BUNG WITH MACE/LOOK IN KEG/ASK WIGGINS TO GET GARNET/READ GARNET SCRATCH WITH GLASS/SW/E/D/WEAR ARMOUR/U/W/S/S/S/GET PADDLE/PULL CHAIN/S/ENTER BOAT/WEIGH ANCHOR/S/PADDLE WEST/PADDLE WEST/PADDLE WEST/N/REMOVE ARMOUR/E/E/D/W/REMOVE STETHOSCOPE/DROP IT/GET AMPOULE/PUT IT IN HAT/WEAR HAT/WAIT FOR 36 HOURS/WAIT FOR 35 MINUTES/ASK FOR AKBAR/swordfish/GIVE GARNET TO AKBAR/REMOVE HAT/GET AMPOULE/HOLD BREATH/BREAK AMPOULE/GET KNIFE/CUT ROPE WITH KNIFE/TIE MORIARTY AND AKBAR WITH ROPE/GET KEY, JEWELS AND WHISTLE/UNLOCK DOOR WITH KEY/OPEN IT/OUT/BLOW WHISTLE/BLOW WHISTLE/ENTER CAB/DRIVE TO BUCKINGHAM PALACE/GET OUT/GIVE JEWELS TO GUARD", + # "walkthrough": "look/examine house/wait 5 seconds/wait 13 seconds/wait 7 minutes/look/wait/wait/wait/wait/wait/wait/wait", "grammar" : "aragon;boleyn;brief/super/superbrie/verbose;chico/echo/groucho/gummo/harpo/hum/marx/punt/sing/whistle/zeppo;cleves;clue/clues/help/hint/hints/invisiclu;fly;gaze/l/look/peek/peer/stare;gin;go/back/retreat/hike/proceed/step/trudge/walk;howard;hush/quiet/shh/shhh/shhhh/shush/sshh/sshhh;i/inventory;maybe;nap/rest/sleep/snooze;no;notify;parr;pray;q/quit;restart;restore;rise/stand;save;score;script/unscript;seymour;swordfish;thank/thanks;version;y/yes;aid/assist/preserve/rescue OBJ;answer OBJ;approach OBJ;arrest OBJ;ask/interroga/query/question OBJ;ask/interroga/query/question about OBJ;ask/interroga/query/question for OBJ;awake/awaken/revive/rouse/wake OBJ;awake/awaken/revive/rouse/wake up OBJ;bargain/deal/dicker/haggle/negotiate with OBJ;bathe/swim/wade OBJ;bathe/swim/wade in OBJ;bathe/swim/wade over OBJ;bathe/swim/wade through OBJ;bathe/swim/wade to OBJ;bathe/swim/wade under OBJ;bathe/swim/wade/dive down OBJ;bite/eat/swallow OBJ;blow OBJ;blow in OBJ;blow on OBJ;blow out OBJ;blow through OBJ;blow up OBJ;board/mount OBJ;bound/hurdle/jump/leap/vault OBJ;bound/hurdle/jump/leap/vault from OBJ;bound/hurdle/jump/leap/vault in OBJ;bound/hurdle/jump/leap/vault off OBJ;bound/hurdle/jump/leap/vault over OBJ;bound/hurdle/jump/leap/vault through OBJ;bound/hurdle/jump/leap/vault to OBJ;bound/hurdle/jump/leap/vault up OBJ;bow/genuflect/kneel before OBJ;bow/genuflect/kneel to OBJ;breathe in OBJ;breathe out OBJ;breathe/hypervent/inhale OBJ;browse/leaf/read/skim OBJ;browse/leaf/read/skim through OBJ;brush/clean/polish/smear/sweep/wipe OBJ;brush/clean/polish/smear/sweep/wipe off OBJ;burn/ignite/kindle OBJ;buy OBJ;bye/farewell/goodbye OBJ;call/hail OBJ;carry/catch/grab/keep/retrieve/seize/snatch/take down OBJ;carry/catch/grab/keep/retrieve/seize/snatch/take off OBJ;carry/catch/grab/keep/retrieve/seize/snatch/take up OBJ;cast off OBJ;chase/follow/pursue OBJ;check/describe/examine/inspect/see/study/survey/trace/x OBJ;check/describe/examine/inspect/see/study/survey/trace/x on OBJ;check/describe/examine/inspect/see/study/survey/trace/x/gaze/l/look/peek/peer/stare in OBJ;check/describe/examine/inspect/see/study/survey/trace/x/gaze/l/look/peek/peer/stare/frisk/ransack/rummage/search/sift for OBJ;chuck/fling/hurl/pitch/throw/toss OBJ;chuck/fling/hurl/pitch/throw/toss away OBJ;clear/empty OBJ;clear/empty off OBJ;clear/empty/shake out OBJ;climb through OBJ;climb under OBJ;climb/get in OBJ;climb/get on OBJ;climb/go/bound/hurdle/jump/leap/vault/hike/proceed/step/trudge/walk out OBJ;climb/go/scale/hike/proceed/step/trudge/walk down OBJ;climb/go/scale/hike/proceed/step/trudge/walk up OBJ;climb/scale over OBJ;climb/scale/ascend OBJ;close/slam/rotate/toggle/turn/twist/shut off OBJ;close/slam/shut OBJ;clue/clues/help/hint/hints/invisiclu off OBJ;count/tally OBJ;crouch/settle/sit/squat OBJ;crouch/settle/sit/squat at OBJ;crouch/settle/sit/squat down OBJ;crouch/settle/sit/squat in OBJ;crouch/settle/sit/squat on OBJ;cry/howl/scream/shout/yell OBJ;cry/howl/scream/shout/yell at OBJ;cry/howl/scream/shout/yell to OBJ;depart/exit/scram/withdraw/leave/disembark OBJ;descend OBJ;detonate/explode OBJ;discover/find/seek OBJ;disembark from OBJ;disembark out OBJ;dislocate/move/roll/shift OBJ;disrobe/strip/undress OBJ;dive OBJ;dive in OBJ;dive over OBJ;dive under OBJ;don/wear OBJ;douse/extinguis/quench/snuff OBJ;drag/pull/tug/yank OBJ;drag/pull/tug/yank on OBJ;drag/pull/tug/yank out OBJ;dress OBJ;drink/guzzle/imbibe/quaff/sip/swill OBJ;drink/guzzle/imbibe/quaff/sip/swill from OBJ;drive OBJ;drive to OBJ;drop/dump OBJ;elevate/hoist/lift/raise OBJ;elevate/hoist/lift/raise up OBJ;embark on OBJ;embark/enter OBJ;employ/exploit/operate/use OBJ;escape/flee OBJ;escape/flee from OBJ;exhale OBJ;extend/unflatten/unfold OBJ;fasten/secure/tie OBJ;feel/grope/reach in OBJ;fiddle/play/toy OBJ;fiddle/play/toy with OBJ;fire/shoot OBJ;flip OBJ;fly OBJ;fly on OBJ;fly over OBJ;fly with OBJ;focus on OBJ;focus/adjust OBJ;fold/wrap OBJ;fold/wrap out OBJ;fold/wrap up OBJ;foo OBJ;frisk/ransack/rummage/search/sift OBJ;frisk/ransack/rummage/search/sift in OBJ;frisk/ransack/rummage/search/sift through OBJ;gaze/l/look/peek/peer/stare OBJ;gaze/l/look/peek/peer/stare around OBJ;gaze/l/look/peek/peer/stare at OBJ;gaze/l/look/peek/peer/stare behind OBJ;gaze/l/look/peek/peer/stare down OBJ;gaze/l/look/peek/peer/stare on OBJ;gaze/l/look/peek/peer/stare out OBJ;gaze/l/look/peek/peer/stare over OBJ;gaze/l/look/peek/peer/stare through OBJ;gaze/l/look/peek/peer/stare to OBJ;gaze/l/look/peek/peer/stare up OBJ;gaze/l/look/peek/peer/stare/frisk/ransack/rummage/search/sift under OBJ;get down OBJ;get off OBJ;get out OBJ;get under OBJ;get up OBJ;get/carry/catch/grab/keep/retrieve/seize/snatch/take OBJ;go/get/back/retreat/escape/flee/hike/proceed/step/trudge/walk away OBJ;go/hike/proceed/step/trudge/walk OBJ;go/hike/proceed/step/trudge/walk around OBJ;go/hike/proceed/step/trudge/walk behind OBJ;go/hike/proceed/step/trudge/walk in OBJ;go/hike/proceed/step/trudge/walk over OBJ;go/hike/proceed/step/trudge/walk through OBJ;go/hike/proceed/step/trudge/walk to OBJ;go/hike/proceed/step/trudge/walk under OBJ;go/retreat/hike/proceed/step/trudge/walk from OBJ;go/rise/stand/bound/hurdle/jump/leap/vault/hike/proceed/step/trudge/walk on OBJ;greet/greetings/hello/hi/salute OBJ;grope/reach through OBJ;guess OBJ;haul OBJ;haul in OBJ;haul up OBJ;hear OBJ;hide OBJ;hide behind OBJ;hide in OBJ;hide/rise/stand under OBJ;hold OBJ;hold down OBJ;hold on OBJ;hold up OBJ;hold/carry/catch/grab/keep/retrieve/seize/snatch/take/drag/pull/tug/yank apart OBJ;insert/lay/place/put/stuff down OBJ;insert/lay/place/put/stuff on OBJ;insert/lay/place/put/stuff out OBJ;kick OBJ;kick around OBJ;kick down OBJ;kick in OBJ;kiss/smooch OBJ;knock/pound/rap/tap at OBJ;knock/pound/rap/tap on OBJ;land OBJ;launch OBJ;lean on OBJ;let go OBJ;lick/taste OBJ;lie down OBJ;lie in OBJ;lie on OBJ;light OBJ;listen OBJ;listen for OBJ;listen in OBJ;listen to OBJ;loiter/stay/wait/z OBJ;loiter/stay/wait/z for OBJ;loiter/stay/wait/z until OBJ;lower OBJ;make OBJ;make up OBJ;nap/rest/sleep/snooze in OBJ;nap/rest/sleep/snooze on OBJ;nudge/press/push/shove/stick/thrust OBJ;nudge/press/push/shove/stick/thrust in OBJ;nudge/press/push/shove/stick/thrust off OBJ;nudge/press/push/shove/stick/thrust on OBJ;nudge/press/push/shove/stick/thrust/drag/pull/tug/yank down OBJ;nudge/press/push/shove/stick/thrust/drag/pull/tug/yank up OBJ;observe/watch OBJ;open OBJ;open up OBJ;paddle OBJ;paddle with OBJ;password OBJ;pet/pat/feel/disturb/scratch/touch OBJ;pick OBJ;pick up OBJ;pinch/steal OBJ;pocket OBJ;point OBJ;point at OBJ;point to OBJ;pour/spill/sprinkle OBJ;pour/spill/sprinkle out OBJ;proclaim/say/speak/talk/utter OBJ;proclaim/say/speak/talk/utter to OBJ;refuse OBJ;remove OBJ;rent OBJ;replace OBJ;reply/respond to OBJ;retract OBJ;ride OBJ;ride in OBJ;ride on OBJ;ring OBJ;rip/tear off OBJ;rise/stand in OBJ;rise/stand up OBJ;rob OBJ;rotate/toggle/turn/twist around OBJ;rotate/toggle/turn/twist down OBJ;rotate/toggle/turn/twist on OBJ;rotate/toggle/turn/twist over OBJ;rotate/toggle/turn/twist through OBJ;rotate/toggle/turn/twist to OBJ;rotate/toggle/turn/twist up OBJ;save/clue/clues/help/hint/hints/invisiclu OBJ;set off OBJ;shut up OBJ;slide OBJ;slide/bound/hurdle/jump/leap/vault down OBJ;smell/sniff/whiff OBJ;smoke OBJ;spin/whirl OBJ;start OBJ;stop OBJ;swing OBJ;swing on OBJ;tell OBJ;tell about OBJ;thank/thanks OBJ;tip OBJ;translate OBJ;undo/unfasten/unhook/untie OBJ;wave OBJ;wave/grin/laugh/motion/nod/smile/sneer at OBJ;wave/grin/laugh/motion/nod/smile/sneer to OBJ;weigh OBJ;what/what's/whats OBJ;what/what's/whats about OBJ;where/where's/wheres OBJ;who/who's/whos OBJ;wind OBJ;wind up OBJ;ask/interroga/query/question OBJ about OBJ;ask/interroga/query/question OBJ for OBJ;blind/jab/poke OBJ with OBJ;block/cover/shield OBJ with OBJ;block/cover/shield over OBJ with OBJ;block/cover/shield up OBJ with OBJ;break/damage/destroy/erase/smash/trash/wreck OBJ off OBJ;break/damage/destroy/erase/smash/trash/wreck OBJ with OBJ;break/damage/destroy/erase/smash/trash/wreck down OBJ with OBJ;break/damage/destroy/erase/smash/trash/wreck in OBJ with OBJ;break/damage/destroy/erase/smash/trash/wreck through OBJ with OBJ;bribe/entice/pay OBJ to OBJ;bribe/entice/pay OBJ with OBJ;browse/leaf/read/skim OBJ OBJ;browse/leaf/read/skim OBJ through OBJ;browse/leaf/read/skim OBJ to OBJ;browse/leaf/read/skim OBJ with OBJ;brush/clean/polish/smear/sweep/wipe OBJ off OBJ;brush/clean/polish/smear/sweep/wipe OBJ on OBJ;brush/clean/polish/smear/sweep/wipe OBJ over OBJ;brush/clean/polish/smear/sweep/wipe off OBJ on OBJ;brush/clean/polish/smear/sweep/wipe off OBJ over OBJ;burn/ignite/kindle OBJ with OBJ;burn/ignite/kindle down OBJ with OBJ;burn/ignite/kindle up OBJ with OBJ;buy OBJ from OBJ;buy OBJ with OBJ;call/hail OBJ with OBJ;carry/catch/grab/keep/retrieve/seize/snatch/take OBJ to OBJ;check/describe/examine/inspect/see/study/survey/trace/x OBJ through OBJ;check/describe/examine/inspect/see/study/survey/trace/x OBJ with OBJ;chop/cut/slash down OBJ with OBJ;chop/cut/slash off OBJ with OBJ;chop/cut/slash through OBJ with OBJ;chop/cut/slash up OBJ with OBJ;chuck/fling/hurl/pitch/throw/toss OBJ OBJ;chuck/fling/hurl/pitch/throw/toss OBJ at OBJ;chuck/fling/hurl/pitch/throw/toss OBJ down OBJ;chuck/fling/hurl/pitch/throw/toss OBJ in OBJ;chuck/fling/hurl/pitch/throw/toss OBJ off OBJ;chuck/fling/hurl/pitch/throw/toss OBJ on OBJ;chuck/fling/hurl/pitch/throw/toss OBJ over OBJ;chuck/fling/hurl/pitch/throw/toss OBJ through OBJ;chuck/fling/hurl/pitch/throw/toss OBJ to OBJ;clear/empty OBJ from OBJ;clear/empty OBJ out OBJ;clear/empty out OBJ from OBJ;clear/empty/pour/spill/sprinkle OBJ in OBJ;clear/empty/pour/spill/sprinkle OBJ on OBJ;clear/empty/pour/spill/sprinkle out OBJ on OBJ;clear/empty/shake/pour/spill/sprinkle out OBJ in OBJ;conceal OBJ in OBJ;conceal/hide OBJ behind OBJ;conceal/hide OBJ under OBJ;deliver/give/hand/lend/loan/offer OBJ to OBJ;deliver/give/hand/lend/loan/offer/bribe/entice/pay OBJ OBJ;diagnose OBJ with OBJ;display/show OBJ OBJ;display/show OBJ to OBJ;disturb/scratch/touch OBJ with OBJ;drag/pull/tug/yank OBJ from OBJ;drag/pull/tug/yank OBJ out OBJ;drag/pull/tug/yank OBJ with OBJ;drag/pull/tug/yank down OBJ with OBJ;drag/pull/tug/yank on OBJ with OBJ;drag/pull/tug/yank up OBJ with OBJ;drop/dump OBJ down OBJ;drop/dump OBJ in OBJ;drop/dump OBJ on OBJ;employ/exploit/operate/use OBJ on OBJ;fasten/secure/tie OBJ to OBJ;fasten/secure/tie OBJ with OBJ;fasten/secure/tie up OBJ with OBJ;feed OBJ OBJ;feed OBJ to OBJ;feed OBJ with OBJ;fell/chop/cut/slash OBJ with OBJ;fill OBJ at OBJ;fill OBJ with OBJ;fire/shoot OBJ at OBJ;fire/shoot OBJ with OBJ;fix up OBJ with OBJ;fix/repair/service OBJ with OBJ;focus OBJ at OBJ;focus OBJ on OBJ;fold/wrap OBJ in OBJ;fold/wrap/wind OBJ around OBJ;fold/wrap/wind up OBJ in OBJ;force/wedge OBJ in OBJ;force/wedge/elevate/hoist/lift/raise up OBJ with OBJ;force/wedge/nudge/press/push/shove/stick/thrust/dislocate/move/roll/shift/elevate/hoist/lift/raise OBJ with OBJ;free/release/unjam OBJ from OBJ;free/release/unjam OBJ with OBJ;gaze/l/look/peek/peer/stare at OBJ through OBJ;gaze/l/look/peek/peer/stare at OBJ with OBJ;gaze/l/look/peek/peer/stare in OBJ through OBJ;gaze/l/look/peek/peer/stare in OBJ with OBJ;gaze/l/look/peek/peer/stare through OBJ at OBJ;get/bring OBJ OBJ;get/bring OBJ for OBJ;get/bring OBJ to OBJ;get/carry/catch/grab/keep/retrieve/seize/snatch/take OBJ from OBJ;get/carry/catch/grab/keep/retrieve/seize/snatch/take OBJ in OBJ;get/carry/catch/grab/keep/retrieve/seize/snatch/take OBJ off OBJ;get/carry/catch/grab/keep/retrieve/seize/snatch/take OBJ on OBJ;get/carry/catch/grab/keep/retrieve/seize/snatch/take OBJ out OBJ;get/carry/catch/grab/keep/retrieve/seize/snatch/take OBJ with OBJ;grope/reach OBJ with OBJ;grope/reach for OBJ with OBJ;grope/reach out OBJ with OBJ;grope/reach to OBJ with OBJ;heat/warm OBJ over OBJ;heat/warm OBJ with OBJ;hit/slap/swat/whack at OBJ with OBJ;hit/slap/swat/whack/knock/pound/rap/tap OBJ with OBJ;hold OBJ in OBJ;hold OBJ on OBJ;hold OBJ over OBJ;hold OBJ up OBJ;hold/disturb/scratch/touch OBJ to OBJ;hold/insert/lay/place/put/stuff OBJ against OBJ;hook/jiggle/loosen/wiggle/wobble OBJ with OBJ;illuminat OBJ with OBJ;insert/lay/place/put/stuff OBJ behind OBJ;insert/lay/place/put/stuff OBJ down OBJ;insert/lay/place/put/stuff OBJ in OBJ;insert/lay/place/put/stuff OBJ on OBJ;insert/lay/place/put/stuff OBJ over OBJ;insert/lay/place/put/stuff OBJ through OBJ;insert/lay/place/put/stuff OBJ under OBJ;kill/murder/punch/stab/wound/attack/fight/hurt OBJ with OBJ;knock/pound/rap/tap down OBJ with OBJ;knock/pound/rap/tap out OBJ with OBJ;leave OBJ in OBJ;leave OBJ on OBJ;let OBJ go OBJ;light OBJ from OBJ;light OBJ with OBJ;light up OBJ from OBJ;light up OBJ with OBJ;listen to OBJ through OBJ;listen to OBJ with OBJ;lock OBJ with OBJ;make OBJ OBJ;melt OBJ with OBJ;nudge/press/push/shove/stick/thrust OBJ at OBJ;nudge/press/push/shove/stick/thrust OBJ in OBJ;nudge/press/push/shove/stick/thrust OBJ on OBJ;nudge/press/push/shove/stick/thrust OBJ over OBJ;nudge/press/push/shove/stick/thrust OBJ under OBJ;nudge/press/push/shove/stick/thrust down OBJ with OBJ;nudge/press/push/shove/stick/thrust on OBJ with OBJ;nudge/press/push/shove/stick/thrust/dislocate/move/roll/shift/drag/pull/tug/yank OBJ OBJ;nudge/press/push/shove/stick/thrust/dislocate/move/roll/shift/drag/pull/tug/yank OBJ to OBJ;observe/watch OBJ through OBJ;observe/watch OBJ with OBJ;open OBJ with OBJ;open up OBJ with OBJ;paddle OBJ with OBJ;pick OBJ with OBJ;pinch/steal OBJ from OBJ;pinch/steal OBJ out OBJ;point at OBJ for OBJ;point out OBJ to OBJ;point to OBJ for OBJ;point/aim OBJ at OBJ;point/aim OBJ to OBJ;point/aim at OBJ with OBJ;pour/spill/sprinkle OBJ from OBJ;pour/spill/sprinkle OBJ out OBJ;proclaim/say/speak/talk/utter OBJ to OBJ;remove OBJ from OBJ;remove OBJ in OBJ;remove OBJ on OBJ;remove OBJ with OBJ;rip/tear through OBJ with OBJ;rip/tear up OBJ with OBJ;rob OBJ from OBJ;rotate/toggle/turn/twist OBJ with OBJ;rotate/toggle/turn/twist/spin/whirl OBJ OBJ;rotate/toggle/turn/twist/spin/whirl/set/dial OBJ to OBJ;row OBJ OBJ;rub OBJ with OBJ;sell OBJ OBJ;sell OBJ to OBJ;set OBJ at OBJ;shake OBJ with OBJ;shake/pour/spill/sprinkle out OBJ from OBJ;shine OBJ at OBJ;shine OBJ in OBJ;shine OBJ on OBJ;shine OBJ over OBJ;shine in OBJ with OBJ;shine on OBJ with OBJ;shine over OBJ with OBJ;slide OBJ down OBJ;slide OBJ in OBJ;slide OBJ to OBJ;slide OBJ under OBJ;start OBJ with OBJ;strike OBJ with OBJ;swing OBJ at OBJ;tell OBJ about OBJ;unlock OBJ with OBJ;unscrew OBJ from OBJ;unscrew OBJ out OBJ;wind OBJ in OBJ;work on OBJ with OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index acde348c..7f0795b4 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -421,9 +421,19 @@ 28: "read sign", # Not needed. 105: "e", # Can't go. 128: "s", # Can't go. - 151: "s", # Too crowed. Have to wait. + 151: "s", # Too crowded. Have to wait. + }, + "sherlock.z5": { + "wait": [75], # Needed for timing the actions. + 9: "read paper", + 34: "ask holmes about ash", # Can be replaced with 'wait 1 minute'. + 159: "open book", # The librarian launches off into another speech. + 162: "read book", # Not actually needed. + 179: "read sign", # Not actually needed. + 232: "read plaque", # Not actually needed. + 238: "n", # Guard stops you and ask not to bribe them. + 318: "ask for akbar", # Denkeeper is asking for the password. } - } @@ -608,6 +618,8 @@ def parse_args(): test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) print(f"Testing walkthrough replacing '{cmd}' with '0'...") test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) + print(f"Testing walkthrough replacing '{cmd}' with 'wait 1 minute'...") + test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) breakpoint() # else: # world_diff = env._get_world_diff() From c2bd1de0c3c25e91c8cc2b488507a73106746d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 24 Nov 2021 10:10:30 -0500 Subject: [PATCH 22/85] Snacktime --- frotz/src/games/snacktime.c | 10 ++++++---- tools/test_games.py | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/frotz/src/games/snacktime.c b/frotz/src/games/snacktime.c index 47aa43fe..92a12ffe 100644 --- a/frotz/src/games/snacktime.c +++ b/frotz/src/games/snacktime.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -26,13 +26,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *snacktime_intro[] = { "\n" }; -const zword snacktime_special_ram_addrs[2] = { +const zword snacktime_special_ram_addrs[5] = { 20743, // Used to quantify how awake the pet is - 8445 // Set when pet is fully awake + 8445, // Set when pet is fully awake + 20744, 9159, // Pushing the wand. + 23769, // pet finished cleaning up }; zword* snacktime_ram_addrs(int *n) { - *n = 2; + *n = 5; return snacktime_special_ram_addrs; } diff --git a/tools/test_games.py b/tools/test_games.py index 7f0795b4..5e36e9fd 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -433,7 +433,8 @@ 232: "read plaque", # Not actually needed. 238: "n", # Guard stops you and ask not to bribe them. 318: "ask for akbar", # Denkeeper is asking for the password. - } + }, + "snacktime.z8": {}, } From 3b4a2b1b80d922dfd1a25723c95a63303c581a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 24 Nov 2021 16:03:23 -0500 Subject: [PATCH 23/85] Sorcerer --- frotz/src/games/sorcerer.c | 10 ++++++++-- jericho/game_info.py | 2 +- tools/test_games.py | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/frotz/src/games/sorcerer.c b/frotz/src/games/sorcerer.c index 7f6cec3d..3d4c1128 100644 --- a/frotz/src/games/sorcerer.c +++ b/frotz/src/games/sorcerer.c @@ -24,12 +24,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Sorcerer: http://ifdb.tads.org/viewgame?id=lidg5nx9ig0bwk55 -const zword sorcerer_special_ram_addrs[1] = { +const zword sorcerer_special_ram_addrs[7] = { 9807, // Inside glass maze + 9917, // Read matchbook, open vial, and drink potion + 9875, // Wake up gnome and give them the coin. + 9925, // Sleeping + 9725, // Turn dial + 9977, // Interactions with younger self + 9871, // Effects of the vilstu potion }; zword* sorcerer_ram_addrs(int *n) { - *n = 1; + *n = 7; return sorcerer_special_ram_addrs; } diff --git a/jericho/game_info.py b/jericho/game_info.py index 44936379..ad08d8bd 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -420,7 +420,7 @@ "rom": "sorcerer.z3", "seed" : 0, # Walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip - "walkthrough": "WAIT/FROTZ BOOK/GET UP/W/READ NOTE/DROP IT/W/OPEN DESK/GET BOX AND JOURNAL/LOOK BEHIND TAPESTRY/GET KEY/OPEN JOURNAL/READ JOURNAL/DROP JOURNAL AND KEY/E/S/S/W/GET VIAL, CALENDAR AND MATCHBOOK/E/OPEN RECEPTACLE/READ MATCHBOOK/PUT IT IN RECEPTACLE/E/GET SCROLL/READ IT/GNUSTO MEEF SPELL/W/D/PRESS white, gray, black, red, black/GET SCROLL/READ IT/OPEN VIAL/DRINK OCHRE POTION/DROP VIAL/U/OPEN RECEPTACLE/GET ORANGE VIAL/N/W/GET SCROLL/READ IT/GNUSTO GASPAR SPELL/AIMFIZ BELBOZ/NE/E/NE/LEARN PULVER/PULVER RIVER/D/NE/GET GUANO, SCROLL AND AMBER VIAL/READ SCROLL/GNUSTO FWEEP SPELL/D/S/GET INDIGO VIAL/W/D/W/SW/SW/W/LEARN IZYUK SPELL/AGAIN/IZYUK ME/W/W/N/GET COIN/S/E/IZYUK ME/E/E/NE/NE/E/E/WAKE GNOME/GIVE COIN TO GNOME/SEARCH GNOME/E/E/N/N/SLEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/DROP ALL/E/FWEEP ME/N/E/S/S/W/D/E/E/N/N/U/U/S/E/GET SCROLL/READ IT/PUT IT IN HOLE/FWEEP ME/W/W/S/E/D/D/W/W/U/U/N/N/D/E/FWEEP ME/S/E/N/D/W/S/W/U/W/WAIT/WAIT/GET ALL/S/S/E/OPEN BOX/DROP BOX/GET AMULET AND SCROLL/GNUSTO SWANZO SPELL/LEARN IZYUK/W/W/W/W/U/U/W/W/IZYUK ME/NE/SE/E/LOWER FLAG/EXAMINE IT/DROP CALENDAR/GET AQUA VIAL/E/LOOK IN CANNON/PUT GUANO IN CANNON/GET SCROLL/READ IT/W/W/LEARN IZYUK/IZYUK ME/NW/SW/W/D/D/S/S/SW/W/GIVE COIN TO GNOME/W/W/S/SLEEP/OPEN AQUA VIAL/DRINK POTION/DROP AQUA VIAL/GET BALL/THROW IT AT RABBIT/READ GLITTERING SCROLL/GNUSTO MALYON SPELL/N/E/E/NE/S/YONK MALYON SPELL/LEARN MALYON/MALYON DRAGON/S/OPEN ORANGE VIAL/FROTZ ME/E/DRINK POTION/THROW ALL BUT BOOK INTO LOWER CHUTE/GIVE BOOK TO TWIN/E/TURN DIAL TO 639/OPEN DOOR/E/GET ROPE/U/NW/GET TIMBER/NW/W/TIE ROPE TO TIMBER/PUT TIMBER ACROSS CHUTE/THROW ROPE INTO CHUTE/D/GET SHIMMERING SCROLL/READ IT/GOLMAC ME/OPEN LAMP/GET SMELLY SCROLL/D/WAIT/WAIT/SAY TO TWIN \"THE COMBINATION IS 639\"/D/WAIT/SLEEP/LEARN MEEF, MEEF AND SWANZO/DROP ALL/E/D/MEEF WEEDS/OPEN CRATE/GET SUIT/U/W/GET ALL/WEAR SUIT/NE/N/MEEF VINES/W/W/OPEN WHITE DOOR/VARDIK ME/SWANZO BELBOZ", + "walkthrough": "WAIT/FROTZ BOOK/GET UP/W/READ NOTE/DROP IT/W/OPEN DESK/GET BOX AND JOURNAL/LOOK BEHIND TAPESTRY/GET KEY/OPEN JOURNAL/READ JOURNAL/DROP JOURNAL AND KEY/E/S/S/W/GET VIAL, CALENDAR AND MATCHBOOK/E/OPEN RECEPTACLE/READ MATCHBOOK/PUT IT IN RECEPTACLE/E/z/GET SCROLL/READ DUSTY SCROLL/GNUSTO MEEF SPELL/W/D/PRESS white, gray, black, red, black/GET SCROLL/READ MOLDY SCROLL/OPEN VIAL/DRINK OCHRE POTION/DROP VIAL/U/OPEN RECEPTACLE/GET ORANGE VIAL/N/W/GET SCROLL/READ SHINY SCROLL/GNUSTO GASPAR SPELL/AIMFIZ BELBOZ/NE/E/NE/LEARN PULVER/PULVER RIVER/D/NE/GET GUANO, SCROLL AND AMBER VIAL/READ SOILED SCROLL/GNUSTO FWEEP SPELL/D/S/GET INDIGO VIAL/W/D/W/SW/SW/W/LEARN IZYUK SPELL/AGAIN/IZYUK ME/W/W/N/GET COIN/S/E/IZYUK ME/E/E/NE/NE/E/E/WAKE GNOME/GIVE COIN TO GNOME/SEARCH GNOME/E/E/N/N/SLEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/LEARN FWEEP/DROP ALL/E/FWEEP ME/N/E/S/S/W/D/E/E/N/N/U/U/S/E/GET SCROLL/READ PARCHMENT SCROLL/PUT IT IN HOLE/FWEEP ME/W/W/S/E/D/D/W/W/U/U/N/N/D/E/FWEEP ME/S/E/N/D/W/S/W/U/W/WAIT/WAIT/GET ALL/S/S/E/OPEN BOX/DROP BOX/GET AMULET AND SCROLL/GNUSTO SWANZO SPELL/LEARN IZYUK/W/W/W/W/U/U/W/W/IZYUK ME/NE/SE/E/LOWER FLAG/EXAMINE IT/DROP CALENDAR/GET AQUA VIAL/E/LOOK IN CANNON/PUT GUANO IN CANNON/GET SCROLL/READ ORDINARY SCROLL/W/W/LEARN IZYUK/IZYUK ME/NW/SW/W/D/D/S/S/SW/W/GIVE COIN TO GNOME/W/W/S/SLEEP/OPEN AQUA VIAL/DRINK POTION/DROP AQUA VIAL/GET BALL/THROW IT AT RABBIT/READ GLITTERING SCROLL/GNUSTO MALYON SPELL/N/E/E/NE/S/YONK MALYON SPELL/LEARN MALYON/MALYON DRAGON/S/OPEN ORANGE VIAL/FROTZ ME/E/DRINK POTION/THROW ALL BUT BOOK INTO LOWER CHUTE/GIVE BOOK TO TWIN/E/TURN DIAL TO 639/OPEN DOOR/E/GET ROPE/U/NW/GET TIMBER/NW/W/TIE ROPE TO TIMBER/PUT TIMBER ACROSS CHUTE/THROW ROPE INTO CHUTE/D/GET SHIMMERING SCROLL/READ SHIMMERING SCROLL/GOLMAC ME/OPEN LAMP/GET SMELLY SCROLL/D/WAIT/WAIT/SAY TO TWIN \"THE COMBINATION IS 639\"/D/WAIT/SLEEP/LEARN MEEF, MEEF AND SWANZO/DROP ALL/E/D/MEEF WEEDS/OPEN CRATE/GET SUIT/U/W/GET ALL/NE/N/MEEF VINES/W/W/OPEN WHITE DOOR/VARDIK ME/SWANZO BELBOZ", "grammar" : "advanc/go/hike/procee/run/step/tramp/trudge/walk;answer/reply/respon;bathe/swim/wade;bound/dive/hurdle/jump/leap/vault;brief;call/procla/say/talk/utter;cavort/gambol/hop/skip;chase/follow/pursue;concea/enscon/hide/secret/stash;damn/fuck/shit;depart/exit/withdr;diagno;enter;fly;fweep;gaspar;gaze/l/look/stare;greeti/hello/hi/saluta;help/hint/hints;howl/scream/shout/yell;i/invent;land;leave;nap/snooze/sleep;q/quit;restar;restor;rise/stand;save;score;script;spells;super/superb;t/time;thank/thanks;unscri;verbos;versio;vezza;wait/z;advanc/go/hike/procee/run/step/tramp/trudge/walk OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk around OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk down OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk in OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk on OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk throug OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk to OBJ;advanc/go/hike/procee/run/step/tramp/trudge/walk up OBJ;aimfiz OBJ;answer/reply/respon OBJ;assaul/attack/fight/hit/hurt/injure OBJ;awake/rouse/startl/surpri/wake OBJ;awake/rouse/startl/surpri/wake up OBJ;banish/drive/exorci OBJ;banish/drive/exorci away OBJ;banish/drive/exorci out OBJ;bathe/swim/wade in OBJ;beckon/brandi/motion/wave OBJ;beckon/brandi/motion/wave to OBJ;beckon/brandi/motion/wave/howl/scream/shout/yell at OBJ;bite OBJ;blow out OBJ;blow up OBJ;board/embark/ride OBJ;bound/dive/hurdle/jump/leap/vault across OBJ;bound/dive/hurdle/jump/leap/vault from OBJ;bound/dive/hurdle/jump/leap/vault in OBJ;bound/dive/hurdle/jump/leap/vault off OBJ;bound/dive/hurdle/jump/leap/vault/advanc/go/hike/procee/run/step/tramp/trudge/walk over OBJ;break/crack/damage/demoli/destro/smash/wreck OBJ;call/procla/say/talk/utter to OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take off OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take out OBJ;cast/incant/invoke OBJ;chase/follow/pursue OBJ;check/descri/examin/inspec/observ/study/survey/watch OBJ;check/descri/examin/inspec/observ/study/survey/watch on OBJ;check/descri/examin/inspec/observ/study/survey/watch/gaze/l/look/stare in OBJ;check/descri/examin/inspec/observ/study/survey/watch/gaze/l/look/stare/frisk/ransac/rummag/search for OBJ;climb/scale OBJ;climb/scale down OBJ;climb/scale over OBJ;climb/scale up OBJ;climb/scale/rest/sit/squat/carry/catch/confis/get/grab/hold/seize/snatch/take in OBJ;climb/scale/rest/sit/squat/carry/catch/confis/get/grab/hold/seize/snatch/take on OBJ;close/shut OBJ;combin/combo OBJ;concea/enscon/hide/secret/stash OBJ;concea/enscon/hide/secret/stash behind OBJ;concea/enscon/hide/secret/stash under OBJ;consum/devour/eat/gobble/ingest/nibble/taste OBJ;count/tally OBJ;cross/ford/traver OBJ;debark/disemb OBJ;defile/molest/rape/ravish OBJ;deflat OBJ;depart/exit/withdr OBJ;descen OBJ;dig/excava in OBJ;dig/excava throug OBJ;dig/excava with OBJ;discha/fire/shoot OBJ;disloc/displa/move/shift/drag/pull/shove/tug/yank OBJ;dispat/kill/murder/slay/stab/vanqui OBJ;doff/remove/shed OBJ;don/wear OBJ;douse/exting/quench OBJ;drag/pull/shove/tug/yank down OBJ;drag/pull/shove/tug/yank on OBJ;drink/guzzle/imbibe/quaff/sip/swallo/swill OBJ;drink/guzzle/imbibe/quaff/sip/swallo/swill from OBJ;drop/dump/releas OBJ;elevat/hoist/lift/raise OBJ;elevat/hoist/lift/raise up OBJ;enter OBJ;feel/pat/pet/rub/touch OBJ;fill OBJ;find/see/seek OBJ;flip/set/turn OBJ;flip/set/turn off OBJ;flip/set/turn on OBJ;fly OBJ;forget/unlear/unmemo OBJ;free/unatta/unfast/unhook/untie OBJ;frisk/ransac/rummag/search OBJ;frisk/ransac/rummag/search in OBJ;frotz OBJ;fweep OBJ;gaspar OBJ;gaze/l/look/stare OBJ;gaze/l/look/stare around OBJ;gaze/l/look/stare at OBJ;gaze/l/look/stare behind OBJ;gaze/l/look/stare down OBJ;gaze/l/look/stare on OBJ;gaze/l/look/stare throug OBJ;gaze/l/look/stare under OBJ;gaze/l/look/stare up OBJ;gestur/point at OBJ;gestur/point to OBJ;gnusto OBJ;golmac OBJ;greeti/hello/hi/saluta OBJ;gyrate/rotate/spin/whirl OBJ;harken/listen for OBJ;harken/listen to OBJ;inflat OBJ;insert/lay/place/put/stuff down OBJ;insert/lay/place/put/stuff on OBJ;izyuk OBJ;jostle/rattle/shake OBJ;kick OBJ;kiss/smooch OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;know/learn/memori OBJ;launch OBJ;lean on OBJ;leave OBJ;lie/reclin/repose down OBJ;lie/reclin/repose on OBJ;light OBJ;lower OBJ;malyon OBJ;meef OBJ;nap/snooze/sleep in OBJ;nap/snooze/sleep on OBJ;nudge/press/push/thrust OBJ;nudge/press/push/thrust on OBJ;open OBJ;open up OBJ;pay OBJ;pick OBJ;pick up OBJ;play OBJ;polish/shine/wax OBJ;pour/spill/sprink OBJ;pulver OBJ;pump up OBJ;reach in OBJ;read/skim OBJ;read/skim about OBJ;rest/sit/squat at OBJ;rest/sit/squat down OBJ;rezrov OBJ;rise/stand on OBJ;rise/stand/carry/catch/confis/get/grab/hold/seize/snatch/take up OBJ;roll up OBJ;send for OBJ;slide OBJ;smell/sniff/whiff OBJ;spray OBJ;squeez OBJ;strike OBJ;swanzo OBJ;swing OBJ;tell OBJ;thank/thanks OBJ;tortur OBJ;vardik OBJ;vezza OBJ;wait/z for OBJ;what/whats OBJ;where/wheres OBJ;who/whos OBJ;yomin OBJ;yonk OBJ;aimfiz OBJ to OBJ;apply OBJ to OBJ;ask/interr/query/quiz OBJ about OBJ;ask/interr/query/quiz OBJ for OBJ;assaul/attack/fight/hit/hurt/injure OBJ with OBJ;attach/fasten/secure/tie OBJ to OBJ;attach/fasten/secure/tie up OBJ with OBJ;beckon/brandi/motion/wave OBJ at OBJ;bestow/donate/feed/give/hand/offer/presen OBJ OBJ;bestow/donate/feed/give/hand/offer/presen OBJ to OBJ;blind/jab/poke OBJ with OBJ;break/crack/damage/demoli/destro/smash/wreck OBJ with OBJ;break/crack/damage/demoli/destro/smash/wreck down OBJ with OBJ;burn/combus/ignite/kindle OBJ with OBJ;burn/combus/ignite/kindle down OBJ with OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ from OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ in OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ off OBJ;carry/catch/confis/get/grab/hold/seize/snatch/take OBJ out OBJ;cast/incant/invoke OBJ at OBJ;cast/incant/invoke OBJ on OBJ;chuck/fling/hurl/pitch/throw/toss OBJ at OBJ;chuck/fling/hurl/pitch/throw/toss OBJ off OBJ;chuck/fling/hurl/pitch/throw/toss OBJ over OBJ;chuck/fling/hurl/pitch/throw/toss OBJ throug OBJ;cleave/cut/gash/lacera/sever/slash/slice/split OBJ with OBJ;cleave/cut/gash/lacera/sever/slash/slice/split throug OBJ with OBJ;clog/fix/glue/patch/plug/repair OBJ with OBJ;compar OBJ to OBJ;concea/enscon/hide/secret/stash OBJ from OBJ;dig/excava OBJ with OBJ;dig/excava in OBJ with OBJ;dispat/kill/murder/slay/stab/vanqui OBJ with OBJ;dissol/liquif/melt/thaw OBJ with OBJ;drop/dump/releas/chuck/fling/hurl/pitch/throw/toss/insert/lay/place/put/stuff OBJ down OBJ;drop/dump/releas/chuck/fling/hurl/pitch/throw/toss/insert/lay/place/put/stuff OBJ in OBJ;feel/pat/pet/rub/touch OBJ with OBJ;fill OBJ at OBJ;fill OBJ with OBJ;flip/set/turn OBJ for OBJ;flip/set/turn OBJ to OBJ;flip/set/turn OBJ with OBJ;free/unatta/unfast/unhook/untie OBJ from OBJ;gaze/l/look/stare at OBJ throug OBJ;gaze/l/look/stare up OBJ in OBJ;hone/sharpe OBJ with OBJ;insert/lay/place/put/stuff OBJ across OBJ;insert/lay/place/put/stuff OBJ behind OBJ;insert/lay/place/put/stuff OBJ on OBJ;insert/lay/place/put/stuff OBJ over OBJ;insert/lay/place/put/stuff OBJ under OBJ;light OBJ with OBJ;lock OBJ with OBJ;lower OBJ down OBJ;lower OBJ in OBJ;open OBJ with OBJ;pay OBJ OBJ;pay OBJ to OBJ;pay OBJ with OBJ;pick OBJ with OBJ;polish/shine/wax OBJ with OBJ;pour/spill/sprink OBJ from OBJ;pour/spill/sprink OBJ in OBJ;pour/spill/sprink OBJ on OBJ;pump up OBJ with OBJ;read/skim OBJ throug OBJ;read/skim about OBJ in OBJ;show OBJ OBJ;show OBJ to OBJ;slide/nudge/press/push/thrust OBJ OBJ;slide/nudge/press/push/thrust OBJ to OBJ;slide/nudge/press/push/thrust OBJ under OBJ;spray OBJ on OBJ;spray OBJ with OBJ;squeez/drop/dump/releas/chuck/fling/hurl/pitch/throw/toss OBJ on OBJ;strike OBJ with OBJ;swing OBJ at OBJ;unlock OBJ with OBJ;", "max_word_length" : 6 } diff --git a/tools/test_games.py b/tools/test_games.py index 5e36e9fd..72491341 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -435,6 +435,18 @@ 318: "ask for akbar", # Denkeeper is asking for the password. }, "snacktime.z8": {}, + "sorcerer.z3": { + "wait": [138, 139], # Needed for timing the actions. + 12: "read journal", # Can be replaced with 'wait'. + 26: "read dusty scroll", # meef spell: cause plants to wilt + 32: "read moldy scroll", # aimfiz spell: transport caster to someone else's location + 42: "read shiny scroll", # gaspar spell: provide for your own resurrection + 53: "read soiled scroll", # fweep spell: turn caster into a bat + 111: "read parchment scroll", # swanzo spell: exorcise an inhabiting presence + 169: "read ordinary scroll", # yonk spell: augment the power of certain spells + 193: "read glittering scroll", # malyon spell: bring life to inanimate objects + 225: "read shimmering scroll", # golmac spell: travel temporally + }, } @@ -621,6 +633,8 @@ def parse_args(): test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) print(f"Testing walkthrough replacing '{cmd}' with 'wait 1 minute'...") test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) + print(f"Testing walkthrough replacing '{cmd}' with 'look'...") + test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) breakpoint() # else: # world_diff = env._get_world_diff() From 0571736084a833d04ebea8c4865feaa238c25e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 24 Nov 2021 17:17:38 -0500 Subject: [PATCH 24/85] Spellbrkr --- frotz/src/games/spellbrkr.c | 18 +++++++++++++++--- jericho/game_info.py | 2 +- tools/test_games.py | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/frotz/src/games/spellbrkr.c b/frotz/src/games/spellbrkr.c index b3404eda..342ffe09 100644 --- a/frotz/src/games/spellbrkr.c +++ b/frotz/src/games/spellbrkr.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -24,9 +24,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Spellbreaker: http://ifdb.tads.org/viewgame?id=wqsmrahzozosu3r +const zword spellbrkr_special_ram_addrs[9] = { + 8987, // Notice the hole in the floor opens into thin air + 8737, // Falling + carried by huge bird + 8935, // Flying + 9007, //: 2 : 104.sleep(5), 247.sleep(6) + 8969, // Buying blue carpet. + 8961, // water level in channel. + 8857, // Move rock around. + 8997, // ask belboz about me (alt. 9111) + 8979, // Dialog with shadow. +}; + zword* spellbrkr_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 9; + return spellbrkr_special_ram_addrs; } char** spellbrkr_intro_actions(int *n) { diff --git a/jericho/game_info.py b/jericho/game_info.py index ad08d8bd..d1ac5bbd 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -429,7 +429,7 @@ "name": "spellbrkr", "rom": "spellbrkr.z3", "seed" : 0, - "walkthrough" : "z/z/z/z/s/take bread/s/learn lesoch/cast lesoch/take cube/write 1 on cube/learn blorple/blorple 1/frotz burin/d/d/z/z/z/z/z/z/get stained scroll/read stained scroll/gnusto caskly/learn blorple/blorple 1/e/s/take zipper/open zipper/reach in zipper/look in zipper/take flimsy scroll/read flimsy scroll/learn blorple/blorple 1/s/take dirty scroll/read dirty scroll/gnusto throck/u/z/z/z/cast girgol/u/u/u/u/take coin/examine coin/w/learn caskly/caskly hut/take cube/e/put coin in zipper/put bread in zipper/put knife in zipper/write 2 on cube/learn blorple/blorple 2/s/pull weed/pull weed/learn blorple/blorple 1/w/n/learn yomin/yomin ogre/plant weed/learn throck/throck weed/d/take dusty scroll/take gold box/u/s/read dusty scroll/gnusto espnis/open box/take cube/put box in zipper/write 3 on cube/learn blorple/blorple 3/take bread from zipper/learn blorple/drop all except bread/s/drop bread/take cube/take bottle/blorple 3/open bottle/look in bottle/take damp scroll/read damp scroll/take all/gnusto liskon/take 1/n/sleep/enter outflow pipe/learn liskon/liskon self/enter inflow pipe/z/z/z/learn liskon/liskon me/z/z/learn liskon/liskon me/frotz bottle/learn blorple/drop all except bottle/take 3/enter outflow pipe/w/take cube/w/climb out of pipe/blorple 3/n/take all/put bottle in zipper/write 4 on cube/learn blorple/blorple 1/e/n/learn liskon/liskon snake/n/n/take cube/learn malyon/malyon idol/learn espnis/learn malyon/malyon idol/z/espnis idol/z/climb idol/look in mouth/take cube/d/write 5 on cube/learn blorple/blorple 5/n/take white scroll/learn blorple/blorple 5/w/read white scroll/gnusto tinsot/e/examine blue carpet/take coin from zipper/point at blue carpet/buy blue carpet/offer 300/offer 400/offer 500/take blue carpet/exit/learn blorple/blorple 3/learn tinsot/learn tinsot/learn tinsot/learn tinsot/put all in zipper/take burin/close zipper/n/rezrov door/tinsot channel/tinsot channel/tinsot channel/z/z/z/tinsot water/enter/u/take cube/open zipper/get book/write 6 on cube/e/n/rezrov cabinet/take moldy book/learn caskly/caskly moldy book/read moldy book/gnusto snavig/s/w/u/drop carpet/sit on carpet/u/w/w/w/w/d/get off carpet/pick up cube/sit on carpet/u/e/e/e/e/d/get off carpet/take carpet/write 7 on cube/d/learn blorple/blorple 3/sleep/learn snavig/learn blorple/put spell book in zipper/close zipper/s/get 3/snavig grouper/d/z/z/z/z/get all/u/blorple 3/sleep/write 8 on cube/open zipper/take spell book from zipper/n/learn blorple/blorple 8/w/learn tinsot/tinsot fragment/take fragment/put all in zipper except book/learn blorple/take 4/blorple 4/n/take compass rose/learn blorple/blorple 4/w/put compass rose in carving/take compass rose/n/touch nw rune with rose/nw/touch w rune with rose/w/touch ne rune with rose/ne/rezrov alabaster/w/take cube/take burin from zipper/write 9 on cube/learn blorple/blorple 9/s/take fragment from zipper/give fragment to green rock/sit on green rock/l/rock, n/rock, sw/rock, e/rock, s/rock, e/rock, e/jump to brown rock/get cube/write 10 on cube/learn blorple/blorple 10/d/learn snavig/drop all except 10, book/d/snavig grue/d/climb pillar/take cube/z/z/z/learn blorple/blorple 10/d/take all/write 11 on cube/learn blorple/blorple 11/n/take box/examine box/put 10 in box/take 10/throw box at outcropping/learn blorple/blorple 10/u/take box/take cube/write 12 on cube/put all in zipper/take book/take 7/learn blorple/blorple 7/s/ask belboz about me/berknip/ask belboz about cube/ask belboz about figure/take 9/learn blorple/blorple 9/e/rezrov door/put all except book in zipper/n/learn jindak/learn jindak/learn jindak/learn blorple/take x1,x2,x7,x8/jindak/put x1, x2, x7 on first pile/get x3, x4, x5, x6/put x8 on second pile/get x12/put x12 on first pile/l/jindak/drop all cubes/take x1, x2, x7, x12/drop all cubes/take x8, x9, x10, x11/drop all cubes/take x1, x10/put x1 in first/put x10 in second/jindak/take x10/blorple x10/d/take key from zipper/unlock cabinet with key/open cabinet/take vellum scroll/read vellum scroll/learn rezrov/learn blorple/learn blorple/learn girgol/put book in cabinet/close cabinet/lock cabinet with key/rezrov door/blorple x10/u/open sack/take flimsy scroll/take burin/copy flimsy scroll to vellum scroll/take sack/empty zipper into sack/put flimsy scroll in zipper/close zipper/drop zipper/take 12/blorple 12/e/z/z/z/take knife/z/z/z/z/z/z/cast girgol/take 12/put sack in tesseract/z", + "walkthrough" : "z/z/z/z/s/take bread/s/learn lesoch/cast lesoch/take cube/write 1 on cube/learn blorple/blorple 1/frotz burin/d/d/z/z/z/z/z/z/get stained scroll/read stained scroll/gnusto caskly/learn blorple/blorple 1/e/s/take zipper/open zipper/reach in zipper/look in zipper/take flimsy scroll/read flimsy scroll/learn blorple/blorple 1/s/take dirty scroll/read dirty scroll/gnusto throck/u/z/z/z/cast girgol/u/u/u/u/take coin/examine coin/w/learn caskly/caskly hut/take cube/e/put coin in zipper/put bread in zipper/put knife in zipper/write 2 on cube/learn blorple/blorple 2/s/pull weed/pull weed/learn blorple/blorple 1/w/n/learn yomin/yomin ogre/plant weed/learn throck/throck weed/d/take dusty scroll/take gold box/u/s/read dusty scroll/gnusto espnis/open box/take cube/put box in zipper/write 3 on cube/learn blorple/blorple 3/take bread from zipper/learn blorple/drop all except bread/s/drop bread/take cube/take bottle/blorple 3/open bottle/look in bottle/take damp scroll/read damp scroll/take all/gnusto liskon/take 1/n/sleep/learn liskon/liskon self/z/z/learn liskon/liskon me/z/z/learn liskon/liskon me/frotz bottle/learn blorple/drop all except bottle/take 3/enter outflow pipe/w/take cube/w/climb out of pipe/blorple 3/n/take all/put bottle in zipper/write 4 on cube/learn blorple/blorple 1/e/n/learn liskon/liskon snake/n/n/learn malyon/malyon idol/learn espnis/learn malyon/malyon idol/z/espnis idol/z/climb idol/look in mouth/take cube/d/write 5 on cube/learn blorple/blorple 5/n/take white scroll/learn blorple/blorple 5/w/read white scroll/gnusto tinsot/e/examine blue carpet/take coin from zipper/point at blue carpet/buy blue carpet/offer 300/offer 400/offer 500/take blue carpet/exit/learn blorple/blorple 3/learn tinsot/learn tinsot/learn tinsot/learn tinsot/put all in zipper/take burin/close zipper/n/rezrov door/tinsot channel/tinsot channel/tinsot channel/z/tinsot water/enter/u/take cube/open zipper/get book/write 6 on cube/e/n/rezrov cabinet/take moldy book/learn caskly/caskly moldy book/read moldy book/gnusto snavig/s/w/u/drop carpet/sit on carpet/u/w/w/w/w/d/get off carpet/pick up cube/sit on carpet/u/e/e/e/e/d/get off carpet/take carpet/write 7 on cube/d/learn blorple/blorple 3/learn snavig/learn blorple/put spell book in zipper/close zipper/s/get 3/snavig grouper/d/z/z/z/z/get all/u/blorple 3/sleep/write 8 on cube/open zipper/take spell book from zipper/n/learn blorple/blorple 8/w/learn tinsot/tinsot fragment/take fragment/put all in zipper except book/learn blorple/take 4/blorple 4/n/take compass rose/learn blorple/blorple 4/w/put compass rose in carving/take compass rose/n/touch nw rune with rose/nw/touch w rune with rose/w/touch ne rune with rose/ne/rezrov alabaster/w/take cube/take burin from zipper/write 9 on cube/learn blorple/blorple 9/s/take fragment from zipper/give fragment to green rock/sit on green rock/l/rock, n/rock, sw/rock, e/rock, s/rock, e/rock, e/jump to brown rock/get cube/write 10 on cube/learn blorple/blorple 10/d/learn snavig/drop all except 10, book/d/snavig grue/d/climb pillar/take cube/z/z/z/learn blorple/blorple 10/d/take all/write 11 on cube/learn blorple/blorple 11/n/take box/examine box/put 10 in box/take 10/throw box at outcropping/learn blorple/blorple 10/u/take box/take cube/write 12 on cube/put all in zipper/take book/take 7/learn blorple/blorple 7/s/ask belboz about me/berknip/ask belboz about cube/ask belboz about figure/take 9/learn blorple/blorple 9/e/rezrov door/put all except book in zipper/n/learn jindak/learn jindak/learn jindak/learn blorple/take x1,x2,x7,x8/jindak/put x1, x2, x7 on first pile/get x3, x4, x5, x6/put x8 on second pile/get x12/put x12 on first pile/l/jindak/drop all cubes/take x1, x2, x7, x12/drop all cubes/take x8, x9, x10, x11/drop all cubes/take x1, x10/put x1 in first/put x10 in second/jindak/take x10/blorple x10/d/take key from zipper/unlock cabinet with key/open cabinet/take vellum scroll/read vellum scroll/learn blorple/learn blorple/put book in cabinet/close cabinet/lock cabinet with key/rezrov door/blorple x10/u/open sack/take flimsy scroll/take burin/copy flimsy scroll to vellum scroll/take sack/empty zipper into sack/put flimsy scroll in zipper/close zipper/drop zipper/take 12/blorple 12/e/z/z/z/take knife/z/z/z/z/z/z/cast girgol/take 12/put sack in tesseract/z", "grammar" : "answer/reply/respon;bathe/swim/wade;brief;call/say/talk;cavort/gambol/hop/skip;chase/follow/pursue;concea/hide;damn/fuck/shit;debark/disemb;depart/exit/withdr;diagno;dive/jump/leap;enter;fly;gaze/l/look/stare;girgol;hello/hi;help/hint;i/invent;jindak;land;leave;lesoch;listen;lurk/drool/gurgle/saliva/slaver;move/shift/go/procee/run/step/walk;nap/snooze/sleep;no/nope;okay/y/yes;q/quit;restar;restor;rise/stand;save;score;scream/shout/yell;script;smell/sniff;snavig;spells;super/superb;t/time;thank/thanks;unscri;verbos;versio;wait/z;where;who;yawn;admire/compli OBJ;answer/reply/respon OBJ;ask/query/quiz about OBJ;ask/query/quiz for OBJ;assaul/attack/fight/hit/strike OBJ;awake/rouse/startl/surpri/wake OBJ;awake/rouse/startl/surpri/wake up OBJ;bargai/haggle with OBJ;bathe/swim/wade in OBJ;beckon/wave OBJ;beckon/wave to OBJ;beckon/wave/scream/shout/yell at OBJ;bite OBJ;blorpl OBJ;blow out OBJ;blow up OBJ;board/embark/ride OBJ;break/crack/destro/scratc/smash/wreck OBJ;bury/plant OBJ;call/say/talk to OBJ;carry/catch/get/grab/hold/snatch/take OBJ;carry/catch/get/grab/hold/snatch/take off OBJ;carry/catch/get/grab/hold/snatch/take out OBJ;caskly OBJ;cast/incant/invoke OBJ;chase/follow/pursue OBJ;check/descri/examin/inspec/observ/watch OBJ;check/descri/examin/inspec/observ/watch/gaze/l/look/stare in OBJ;check/descri/examin/inspec/observ/watch/gaze/l/look/stare on OBJ;check/descri/examin/inspec/observ/watch/gaze/l/look/stare/rummag/search for OBJ;climb/scale OBJ;climb/scale down OBJ;climb/scale off OBJ;climb/scale out OBJ;climb/scale over OBJ;climb/scale up OBJ;climb/scale/carry/catch/get/grab/hold/snatch/take on OBJ;climb/scale/medita/rest/sit/carry/catch/get/grab/hold/snatch/take in OBJ;close/shut/zip OBJ;concea/hide OBJ;concea/hide behind OBJ;concea/hide from OBJ;concea/hide in OBJ;concea/hide under OBJ;consum/eat/gobble/taste OBJ;copy OBJ;count OBJ;cross/ford/traver OBJ;debark/disemb OBJ;depart/exit/withdr OBJ;descen OBJ;dig/excava in OBJ;dig/excava throug OBJ;dig/excava with OBJ;dive/jump/leap across OBJ;dive/jump/leap down OBJ;dive/jump/leap from OBJ;dive/jump/leap in OBJ;dive/jump/leap off OBJ;dive/jump/leap on OBJ;dive/jump/leap to OBJ;dive/jump/leap/go/procee/run/step/walk over OBJ;drag/pull/tug down OBJ;drag/pull/tug on OBJ;drink/sip/swallo OBJ;drink/sip/swallo from OBJ;drop/dump/releas OBJ;empty/pour/spill OBJ;enter OBJ;erase OBJ;espnis OBJ;exting OBJ;feel/pat/pet/rub/touch OBJ;fill OBJ;find OBJ;fire/shoot OBJ;fit/insert/lay/place/put/stuff/wedge down OBJ;fit/insert/lay/place/put/stuff/wedge on OBJ;fix/patch/repair OBJ;flip/set/turn OBJ;flip/set/turn off OBJ;flip/set/turn on OBJ;flip/set/turn over OBJ;fly OBJ;forget/unlear OBJ;free/unatta/unfast/untie OBJ;frotz OBJ;gaze/l/look/stare OBJ;gaze/l/look/stare around OBJ;gaze/l/look/stare at OBJ;gaze/l/look/stare behind OBJ;gaze/l/look/stare down OBJ;gaze/l/look/stare throug OBJ;gaze/l/look/stare under OBJ;gaze/l/look/stare up OBJ;gestur/point at OBJ;gestur/point to OBJ;girgol OBJ;gnusto OBJ;go/procee/run/step/walk OBJ;go/procee/run/step/walk around OBJ;go/procee/run/step/walk down OBJ;go/procee/run/step/walk in OBJ;go/procee/run/step/walk on OBJ;go/procee/run/step/walk throug OBJ;go/procee/run/step/walk to OBJ;go/procee/run/step/walk up OBJ;hello/hi OBJ;help/hint OBJ;inflat OBJ;inscri/print/scribe/write OBJ;inscri/print/scribe/write in OBJ;inscri/print/scribe/write on OBJ;jindak OBJ;kick OBJ;kill/murder/slay/stab OBJ;kiss OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;label OBJ;lean on OBJ;learn/memori OBJ;leave OBJ;lesoch OBJ;lie down OBJ;lie on OBJ;lift/raise OBJ;lift/raise up OBJ;liskon OBJ;listen for OBJ;listen to OBJ;lower OBJ;lurk behind OBJ;lurk in OBJ;malyon OBJ;medita/rest/sit at OBJ;medita/rest/sit down OBJ;medita/rest/sit on OBJ;move/shift/drag/pull/tug OBJ;nap/snooze/sleep in OBJ;nap/snooze/sleep on OBJ;open/unzip OBJ;open/unzip up OBJ;pay OBJ;pick OBJ;pick up OBJ;play OBJ;press/push/shove OBJ;press/push/shove on OBJ;pump up OBJ;rattle/shake OBJ;reach in OBJ;read OBJ;read about OBJ;remove/shed OBJ;rezrov OBJ;rise/stand on OBJ;rise/stand/carry/catch/get/grab/hold/snatch/take up OBJ;roll up OBJ;rotate/spin/whirl OBJ;rummag/search OBJ;rummag/search in OBJ;send for OBJ;smell/sniff OBJ;snavig OBJ;squeez OBJ;swing/thrust OBJ;tell OBJ;tell about OBJ;thank/thanks OBJ;throck OBJ;tinsot OBJ;tortur OBJ;trade OBJ;wait/z for OBJ;wear OBJ;what OBJ;where OBJ;who OBJ;yomin OBJ;apply OBJ to OBJ;ask/query/quiz OBJ about OBJ;ask/query/quiz OBJ for OBJ;assaul/attack/fight/hit/strike OBJ with OBJ;attach/fasten/tie OBJ to OBJ;attach/fasten/tie up OBJ with OBJ;beckon/wave OBJ at OBJ;blind/jab/poke OBJ with OBJ;block/clog/plug OBJ with OBJ;break/crack/destro/scratc/smash/wreck OBJ with OBJ;break/crack/destro/scratc/smash/wreck down OBJ with OBJ;burn/ignite OBJ with OBJ;burn/ignite down OBJ with OBJ;bury/plant OBJ in OBJ;buy/purcha OBJ from OBJ;buy/purcha OBJ with OBJ;carry/catch/get/grab/hold/snatch/take OBJ from OBJ;carry/catch/get/grab/hold/snatch/take OBJ in OBJ;carry/catch/get/grab/hold/snatch/take OBJ off OBJ;carry/catch/get/grab/hold/snatch/take OBJ out OBJ;cast/incant/invoke OBJ at OBJ;cast/incant/invoke OBJ on OBJ;compar OBJ to OBJ;compar OBJ with OBJ;concea/hide OBJ from OBJ;copy OBJ on OBJ;copy OBJ to OBJ;copy OBJ with OBJ;count OBJ in OBJ;cut/divide/prune/sever/slash/slice/split OBJ with OBJ;cut/divide/prune/sever/slash/slice/split throug OBJ with OBJ;dig/excava OBJ with OBJ;dig/excava in OBJ with OBJ;drop/dump/releas/fit/insert/lay/place/put/stuff/wedge OBJ down OBJ;drop/dump/releas/fit/insert/lay/place/put/stuff/wedge OBJ in OBJ;empty/pour/spill OBJ from OBJ;empty/pour/spill OBJ in OBJ;empty/pour/spill OBJ on OBJ;feed/give/hand/offer OBJ OBJ;feed/give/hand/offer OBJ for OBJ;feed/give/hand/offer OBJ to OBJ;feed/give/hand/offer OBJ with OBJ;feel/pat/pet/rub/touch OBJ to OBJ;feel/pat/pet/rub/touch OBJ with OBJ;fill OBJ at OBJ;fill OBJ with OBJ;fit/insert/lay/place/put/stuff/wedge OBJ across OBJ;fit/insert/lay/place/put/stuff/wedge OBJ behind OBJ;fit/insert/lay/place/put/stuff/wedge OBJ on OBJ;fit/insert/lay/place/put/stuff/wedge OBJ over OBJ;fit/insert/lay/place/put/stuff/wedge OBJ under OBJ;fix/patch/repair OBJ with OBJ;flip/set/turn OBJ to OBJ;flip/set/turn OBJ with OBJ;free/unatta/unfast/untie OBJ from OBJ;gaze/l/look/stare at OBJ throug OBJ;gaze/l/look/stare up OBJ in OBJ;hurl/pitch/throw/toss OBJ at OBJ;hurl/pitch/throw/toss OBJ down OBJ;hurl/pitch/throw/toss OBJ in OBJ;hurl/pitch/throw/toss OBJ off OBJ;hurl/pitch/throw/toss OBJ on OBJ;hurl/pitch/throw/toss OBJ over OBJ;hurl/pitch/throw/toss OBJ throug OBJ;hurl/pitch/throw/toss OBJ to OBJ;inscri/print/scribe/write OBJ in OBJ;inscri/print/scribe/write OBJ on OBJ;inscri/print/scribe/write in OBJ with OBJ;inscri/print/scribe/write on OBJ with OBJ;kill/murder/slay/stab OBJ with OBJ;label OBJ with OBJ;lock OBJ with OBJ;lower OBJ down OBJ;lower OBJ in OBJ;melt/thaw OBJ with OBJ;open/unzip OBJ with OBJ;pay OBJ OBJ;pay OBJ to OBJ;pay OBJ with OBJ;pick OBJ with OBJ;press/push/shove OBJ OBJ;press/push/shove OBJ to OBJ;pry OBJ with OBJ;pry out OBJ with OBJ;pump up OBJ with OBJ;rattle/shake OBJ at OBJ;read OBJ throug OBJ;read about OBJ in OBJ;sell OBJ OBJ;sell OBJ to OBJ;sharpe OBJ with OBJ;show OBJ OBJ;show OBJ to OBJ;slide/press/push/shove OBJ under OBJ;squeez/drop/dump/releas OBJ on OBJ;swing/thrust OBJ at OBJ;tell OBJ OBJ;tell OBJ about OBJ;trade OBJ for OBJ;trade OBJ with OBJ;unlock OBJ with OBJ;", "max_word_length" : 6 } diff --git a/tools/test_games.py b/tools/test_games.py index 72491341..64e3bc2b 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -447,6 +447,20 @@ 193: "read glittering scroll", # malyon spell: bring life to inanimate objects 225: "read shimmering scroll", # golmac spell: travel temporally }, + "spellbrkr.z3": { + "z": [1, 2, 16, 42, 43, 44, 107, 108, 109, 110, 111, 112, 142, 233, 234, 235, 236, 300, 301, 302], # Needed for timing the actions. + 23: "read stained scroll", # caskly spell: cause perfection + 34: "read flimsy scroll", # girgol spell: stop time + 39: "read dirty scroll", # throck spell: cause plants to grow. + 80: "read dusty scroll", # espnis spell: sleep. + 99: "read damp scroll", # liskon spell: shrink a living thing. + 157: "read white scroll", # tinsot spell: freeze. + 162: "point at blue carpet", + 197: "read moldy book", # snavig spell: shape change + 330: "ask belboz about cube", + 331: "ask belboz about figure", + 368: "read vellum scroll", # empty + } } From e2d7cf74becda72f5fcde7e489ee9cc1b1e03c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 24 Nov 2021 17:22:16 -0500 Subject: [PATCH 25/85] temple --- tools/test_games.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/test_games.py b/tools/test_games.py index 64e3bc2b..7b31539f 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -460,7 +460,13 @@ 330: "ask belboz about cube", 331: "ask belboz about figure", 368: "read vellum scroll", # empty + }, + "temple.z5": { + 32: "ask charles about temple", + 77: "ask charles about chest", + 84: "listen", } + } From 49e81e28411874f23ed0755deeb4217f86e9ccc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 10:44:39 -0500 Subject: [PATCH 26/85] theatre --- frotz/src/games/theatre.c | 6 ++++-- tools/test_games.py | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/frotz/src/games/theatre.c b/frotz/src/games/theatre.c index d649416a..a25a213c 100644 --- a/frotz/src/games/theatre.c +++ b/frotz/src/games/theatre.c @@ -24,15 +24,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Theatre: http://ifdb.tads.org/viewgame?id=bv8of8y9xeo7307g -const zword theatre_special_ram_addrs[2] = { +const zword theatre_special_ram_addrs[4] = { 17830, // Tracks dial location 17834, // Track watch hand + 17832, // Hearing gibberish + 18122, // Push the chandelier }; const char *theatre_intro[] = { "\n" }; zword* theatre_ram_addrs(int *n) { - *n = 2; + *n = 4; return theatre_special_ram_addrs; } diff --git a/tools/test_games.py b/tools/test_games.py index 7b31539f..364231a8 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -465,6 +465,14 @@ 32: "ask charles about temple", 77: "ask charles about chest", 84: "listen", + }, + "theatre.z5": { + "z": [15], + "wait": [15, 249], + 190: "read newspaper", + 271: "show earth crystal to trent", + 272: "show star crystal to trent", + 274: "ask trent about elizabeth", } } From 0f5ba622dc5359a8d6e6d1cade379dd75398f6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 11:31:37 -0500 Subject: [PATCH 27/85] trinity --- frotz/src/games/trinity.c | 28 ++++++++++++++++++---------- jericho/game_info.py | 3 ++- tools/test_games.py | 26 +++++++++++++++++++------- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/frotz/src/games/trinity.c b/frotz/src/games/trinity.c index 57224c7b..4fbee7a7 100644 --- a/frotz/src/games/trinity.c +++ b/frotz/src/games/trinity.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -26,9 +26,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *trinity_intro[] = { "\n" }; +const zword trinity_special_ram_addrs[5] = { + 34327, // Push lever. + 37319, // Listen to the magpie. + 3218, // Wear boots (alt. 4926) + 1090, // Wear shroud + 33931, // Enter dory and give silver coin to oarsman. +}; + zword* trinity_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 5; + return trinity_special_ram_addrs; } char** trinity_intro_actions(int *n) { @@ -91,11 +99,11 @@ int trinity_ignore_attr_clr(zword obj_num, zword attr_idx) { } void trinity_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~1; - // Clear attr 23 - for (i=1; i<=trinity_get_num_world_objs(); ++i) { - objs[i].attr[2] &= mask; - } + // int i; + // char mask; + // mask = ~1; + // // Clear attr 23 + // for (i=1; i<=trinity_get_num_world_objs(); ++i) { + // objs[i].attr[2] &= mask; + // } } diff --git a/jericho/game_info.py b/jericho/game_info.py index d1ac5bbd..4b1f5038 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -465,7 +465,8 @@ "name": "trinity", "rom": "trinity.z4", "seed" : 0, - "walkthrough" : "i/examine watch/take coin/examine coin/e/examine memorial/examine blossoms/take ball/nw/examine sundial/examine gnomon/unscrew gnomon/take gnomon/nw/examine woman/examine pigeons/buy bag/take bag/take coin/feed birds/take ruby/ask woman about roadrunner/ask woman about ruby/e/examine boats/take bird/examine bird/open bird/read paper/nw/examine pram/open pram/look in pram/push pram east/examine boy/push pram east/examine woman/throw ball at umbrella/take umbrella/push pram south/examine notice/e/enter pram/open umbrella/take all but pram/examine statue/examine missile/e/e/i/fold paper/examine meteor/put paper in pocket/put coin in pocket/examine watch/take card/read card/put card in pocket/n/examine toadstools/ne/examine log/take log/examine splinter/take splinter/e/drop bag/drop umbrella/u/u/examine shadow/examine sundial/examine symbols/examine rose/examine hole/examine ring/put gnomon in hole/d/d/s/sw/e/examine sculpture/reach in sculpture/n/u/take axe/examine axe/s/d/w/ne/n/u/u/put gnomon in hole/push lever/turn ring/d/d/s/sw/e/n/u/s/d/w/ne/n/nw/examine flytrap/e/examine tree/examine chasm/examine mesa/examine toadstool/chop tree/push tree north/sw/e/drop axe/take umbrella/w/w/examine waterfall/w/enter waterfall/search waterfall/w/examine icicles/hit icicle with umbrella/take icicle/e/e/e/u/u/d/d/ne/e/e/put icicle on lump/take lump/examine lump/w/w/examine hive/sw/drop lump/drop umbrella/w/w/n/examine crypt/read crypt/open crypt/examine statues/examine barrow/n/examine wight/examine hole/examine door/n/examine bones/search bones/take key/examine key/s/put key in hole/turn key/d/e/e/n/n/examine boy/examine bubble/examine wand/examine dish/examine headphones/talk to boy/se/ne/examine cottage/knock on door/open door/e/examine map/examine cauldron/look in cauldron/smell/examine book/read book/examine pedestal/turn page/read book/examine magpie/examine cage/wait/wait/wait/wait/wait/wait/wait/wait/open cage/take cage/open back door/e/examine herbs/examine fence/examine thyme/take thyme/examine refuse/search refuse/take garlic/examine garlic/examine toadstool/examine white door/w/w/se/w/put hand in hive/w/w/examine flytrap/e/e/put hand in hive/e/nw/e/put honey in cauldron/put hand in cauldron/w/se/sw/w/drop garlic/drop birdcage/drop splinter/take umbrella/u/u/turn ring to sixth symbol/d/d/e/e/enter door/open umbrella/take all/examine teachers/examine children/e/examine spade/take spade/w/wait/give umbrella to girl/e/give paper to girl/w/ride bird/enter door/w/w/w/w/n/open lid with spade/look in crypt/examine corpse/examine bandage/take bandage/examine mouth/take silver coin/examine silver coin/put silver coin in pocket/examine boots/take boots/wear boots/examine shroud/take shroud/examine corpse/kiss corpse/s/e/e/drop shroud/drop bandage/drop spade/take splinter/u/u/turn ring to third symbol/d/d/w/w/n/n/n/enter door/examine cylinder/take lantern/w/turn on lantern/drop lantern/w/put splinter into crevice/take skink/put skink in pocket/e/take all/e/e/s/turn key/d/e/e/e/turn off lantern/drop lantern/examine walkie/drop walkie/take axe/take lump/u/u/turn ring to second symbol/d/d/nw/n/enter dish/z/z/s/sw/enter door/take skink/kill skink/examine satellite/examine stars/examine door/break bubble with axe/e/e/drop skink/drop axe/u/u/turn ring to fourth symbol/d/d/nw/e/n/enter door/d/open box/examine switch/push switch/push button/s/nw/examine islet/examine tree/w/examine crabs/examine fin/look/w/examine coconuts/point at coconut/examine tide/examine tide/examine tide/point to coconut/take coconut/se/n/u/enter door/s/w/se/take axe/take skink/take garlic/ne/e/nw/e/drop coconut/cut coconut with axe/take coconut/pour milk in cauldron/put skink in cauldron/put garlic in cauldron/w/z/e/look in cauldron/examine emerald/take emerald/put emerald in green boot/w/se/w/sw/drop coconut/drop axe/take cage/u/u/turn ring to fifth symbol/d/d/ne/e/nw/e/e/enter white door/d/ne/ne/look in fissure/take lemming/put lemming in cage/close cage/sw/sw/u/enter door/examine lemming/w/w/se/w/sw/take shroud/wear shroud/take walkie/take lantern/take bag/u/u/turn ring to seventh symbol/d/d/se/z/z/enter dory/give silver coin to oarsman/s/drop shroud/enter door/open book/take slip/examine slip/examine diagram/drop slip/w/d/d/take ruby/put ruby in red boot/nw/nw/nw/open jeep/in/examine radio/examine dial/set slider to 31/pull antenna/turn on walkie/out/se/se/se/se/se/open gate/se/s/open door/e/take knife/e/n/n/close door/open cage/open door/drop cage/s/search workbench/take screwdriver/open front door/e/e/se/u/drop walkie/drop bag/d/ne/u/turn on lantern/take binoculars/d/take all but lantern/u/u/take all/s/w/w/sw/sw/s/look through binoculars at shelter/wait/point to key/take key/examine thin man/n/n/n/n/unlock box with key/examine panel/pull breaker/close breaker/sw/sw/sw/sw/examine dog/examine searchlight/drop bag/ne/ne/ne/ne/u/u/e/examine enclosure/examine panel/unscrew panel/look in panel/turn on bulb/look in panel/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/cut blue wire/i/e/take ball/nw/examine sundial/turn gnomon/take gnomon/nw/ask woman about roadrunner/ask woman about ruby/give card to woman/buy bag/take bag/take coin/feed birds/take ruby/e/examine boats/take paper bird/open bird/read paper/examine watch/nw/open pram/push pram e/take dish/push pram e/examine woman/", + # Helpful walkthroughs: http://www.plover.net/~davidw/sol/t/trini86.html, http://www.eristic.net/games/infocom/trinity.html + "walkthrough" : "i/examine watch/take coin/examine coin/e/examine memorial/examine blossoms/take ball/nw/examine sundial/examine gnomon/unscrew gnomon/take gnomon/nw/examine woman/examine pigeons/buy bag/take bag/take coin/feed birds/take ruby/ask woman about roadrunner/ask woman about ruby/e/examine boats/take bird/examine bird/open bird/read paper/nw/examine pram/open pram/look in pram/push pram east/examine boy/push pram east/examine woman/throw ball at umbrella/take umbrella/push pram south/examine notice/e/enter pram/open umbrella/take all but pram/examine statue/examine missile/e/e/i/fold paper/examine meteor/put paper in pocket/put coin in pocket/examine watch/take card/read card/put card in pocket/n/examine toadstools/ne/examine log/take log/examine splinter/take splinter/e/drop bag/drop umbrella/u/u/examine shadow/examine sundial/examine symbols/examine rose/examine hole/examine ring/put gnomon in hole/d/d/s/sw/e/examine sculpture/reach in sculpture/n/u/take axe/examine axe/s/d/w/ne/n/u/u/put gnomon in hole/push lever/turn ring/d/d/s/sw/e/n/u/s/d/w/ne/n/nw/examine flytrap/e/examine tree/examine chasm/examine mesa/examine toadstool/chop tree/push tree north/sw/e/drop axe/take umbrella/w/w/examine waterfall/search waterfall/w/examine icicles/hit icicle with umbrella/take icicle/e/e/e/u/u/d/d/ne/e/e/put icicle on lump/take lump/examine lump/w/w/examine hive/sw/drop lump/drop umbrella/w/w/n/examine crypt/read crypt/open crypt/examine statues/examine barrow/n/examine wight/examine hole/examine door/n/examine bones/search bones/take key/examine key/s/put key in hole/turn key/d/e/e/n/n/examine boy/examine bubble/examine wand/examine dish/examine headphones/talk to boy/se/ne/examine cottage/knock on door/open door/e/examine map/examine cauldron/look in cauldron/smell/examine book/read book/examine pedestal/turn page/read book/examine magpie/examine cage/wait/wait/wait/wait/wait/wait/wait/wait/open cage/take cage/open back door/e/examine herbs/examine fence/examine thyme/examine refuse/search refuse/take garlic/examine garlic/examine toadstool/examine white door/w/w/se/w/put hand in hive/w/w/examine flytrap/e/e/put hand in hive/e/nw/e/put honey in cauldron/put hand in cauldron/w/se/sw/w/drop garlic/drop birdcage/drop splinter/take umbrella/u/u/turn ring to sixth symbol/d/d/e/e/enter door/open umbrella/take all/examine teachers/examine children/e/examine spade/take spade/w/wait/give umbrella to girl/e/give paper to girl/w/ride bird/enter door/w/w/w/w/n/open lid with spade/look in crypt/examine corpse/examine bandage/take bandage/examine mouth/take silver coin/examine silver coin/put silver coin in pocket/examine boots/take boots/wear boots/examine shroud/take shroud/examine corpse/s/e/e/drop shroud/drop bandage/drop spade/take splinter/u/u/turn ring to third symbol/d/d/w/w/n/n/n/enter door/examine cylinder/take lantern/w/turn on lantern/drop lantern/w/put splinter into crevice/take skink/put skink in pocket/e/take all/e/e/s/turn key/d/e/e/e/turn off lantern/drop lantern/examine walkie/drop walkie/take axe/take lump/u/u/turn ring to second symbol/d/d/nw/n/enter dish/z/z/s/sw/enter door/take skink/kill skink/examine satellite/examine stars/examine door/break bubble with axe/e/e/drop skink/drop axe/u/u/turn ring to fourth symbol/d/d/nw/e/n/enter door/d/open box/examine switch/push switch/push button/s/nw/examine islet/examine tree/w/examine crabs/examine fin/look/w/examine coconuts/point at coconut/examine tide/examine tide/examine tide/point to coconut/take coconut/se/n/u/enter door/s/w/se/take axe/take skink/take garlic/ne/e/nw/e/drop coconut/cut coconut with axe/take coconut/pour milk in cauldron/put skink in cauldron/put garlic in cauldron/w/z/e/look in cauldron/examine emerald/take emerald/put emerald in green boot/w/se/w/sw/drop coconut/drop axe/take cage/u/u/turn ring to fifth symbol/d/d/ne/e/nw/e/e/enter white door/d/ne/ne/look in fissure/take lemming/put lemming in cage/close cage/sw/sw/u/enter door/examine lemming/w/w/se/w/sw/take shroud/wear shroud/take walkie/take lantern/take bag/u/u/turn ring to seventh symbol/d/d/se/z/z/enter dory/give silver coin to oarsman/s/drop shroud/enter door/open book/take slip/examine slip/examine diagram/drop slip/w/d/d/take ruby/put ruby in red boot/nw/nw/nw/open jeep/in/examine radio/examine dial/set slider to 41/pull antenna/turn on walkie/out/se/se/se/se/se/open gate/se/s/open door/e/take knife/e/n/n/close door/open cage/open door/drop cage/s/search workbench/take screwdriver/open front door/e/e/se/u/drop walkie/drop bag/d/ne/u/turn on lantern/take binoculars/d/take all but lantern/u/u/take all/s/w/w/sw/sw/s/look through binoculars at shelter/wait/point to key/take key/examine thin man/n/n/n/n/unlock box with key/examine panel/pull breaker/close breaker/sw/sw/sw/sw/examine dog/examine searchlight/drop bag/ne/ne/ne/ne/u/u/e/examine enclosure/examine panel/unscrew panel/look in panel/turn on bulb/look in panel/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/cut blue wire/i/e/take ball/nw/examine sundial/turn gnomon/take gnomon/nw/ask woman about roadrunner/ask woman about ruby/give card to woman/buy bag/take bag/take coin/feed birds/take ruby/e/examine boats/take paper bird/open bird/read paper/examine watch/nw/open pram/push pram e/take dish/push pram e/examine woman/", "grammar" : "brief;diagnose;duck;fly;gaze/l/look/peek/peer/stare;go/back/retreat/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk;hint/hints/aid/help/pray;i/inventory;loiter/wait/z;nap/rest/sleep/snooze;notify;q/quit;restart;restore;rise/stand;save;score;script;super/superbrie;surface;t/time;thank/thanks;unscript;verbose;version;aid/help/save OBJ;answer OBJ;approach OBJ;arouse/frighten/scare/startle/surprise OBJ;ask/interroga/query/question/quiz OBJ;ask/interroga/query/question/quiz about OBJ;ask/interroga/query/question/quiz for OBJ;awake/awaken/rouse/wake OBJ;awake/awaken/rouse/wake up OBJ;bandage OBJ;bathe/swim/wade OBJ;bathe/swim/wade in OBJ;bathe/swim/wade over OBJ;bathe/swim/wade through OBJ;bathe/swim/wade to OBJ;bathe/swim/wade under OBJ;bathe/swim/wade up OBJ;bathe/swim/wade/dive down OBJ;bite OBJ;blow in OBJ;blow on OBJ;blow out OBJ;blow through OBJ;blow up OBJ;board/mount OBJ;bounce/dribble OBJ;bounce/dribble around OBJ;bound/hurdle/jump/leap/vault OBJ;bound/hurdle/jump/leap/vault from OBJ;bound/hurdle/jump/leap/vault in OBJ;bound/hurdle/jump/leap/vault off OBJ;bound/hurdle/jump/leap/vault over OBJ;bound/hurdle/jump/leap/vault through OBJ;bound/hurdle/jump/leap/vault to OBJ;bound/hurdle/jump/leap/vault up OBJ;bow/genuflect/grovel/kneel before OBJ;bow/genuflect/grovel/kneel to OBJ;breathe in OBJ;breathe out OBJ;breathe/hypervent/inhale OBJ;browse/leaf/read/skim OBJ;browse/leaf/read/skim through OBJ;brush/clean/polish/smear/sweep/wipe OBJ;brush/clean/polish/smear/sweep/wipe off OBJ;buy OBJ;bye/farewell/goodbye OBJ;call/maybe/proclaim/say/speak/talk/utter OBJ;call/maybe/proclaim/say/speak/talk/utter to OBJ;carry/catch/confiscat/grab/keep/seize/snatch/steal/take down OBJ;carry/catch/confiscat/grab/keep/seize/snatch/steal/take off OBJ;carry/catch/confiscat/grab/keep/seize/snatch/steal/take up OBJ;cavort/fiddle/play/toy OBJ;cavort/fiddle/play/toy with OBJ;chase/follow/pursue OBJ;check/describe/examine/inspect/see/study/survey/trace OBJ;check/describe/examine/inspect/see/study/survey/trace on OBJ;check/describe/examine/inspect/see/study/survey/trace/gaze/l/look/peek/peer/stare in OBJ;check/describe/examine/inspect/see/study/survey/trace/gaze/l/look/peek/peer/stare/frisk/ransack/rummage/search/sift for OBJ;chuck/fling/hurl/pitch/throw/toss away OBJ;clear/empty OBJ;clear/empty off OBJ;clear/empty/shake out OBJ;climb through OBJ;climb under OBJ;climb/get in OBJ;climb/get on OBJ;climb/go/bound/hurdle/jump/leap/vault/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk out OBJ;climb/go/scale/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk down OBJ;climb/go/scale/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk up OBJ;climb/scale over OBJ;climb/scale/ascend OBJ;close/shut/slam OBJ;close/shut/slam/flip/rotate/toggle/turn/twist off OBJ;consume/devour/eat/gobble/ingest/nibble/swallow OBJ;count/tabulate/tally OBJ;cross/traverse OBJ;crouch/settle/sit/squat OBJ;crouch/settle/sit/squat at OBJ;crouch/settle/sit/squat down OBJ;crouch/settle/sit/squat in OBJ;crouch/settle/sit/squat on OBJ;crumple/crush/squash/squeeze/squish OBJ;defile/hump/molest/rape/ravish OBJ;deflate OBJ;depart/exit/scram/withdraw/disembark OBJ;descend OBJ;detach/disconnec/disengage/unattach/unplug OBJ;detonate/explode/fire OBJ;disassemb/open/unseal OBJ;disassemb/open/unseal up OBJ;discover/find/seek OBJ;disembark from OBJ;disembark out OBJ;dislocate/move/roll/shift OBJ;dispatch/kill/murder/punch/slay/stab/vanquish/wound OBJ;disrobe/strip/undress OBJ;dive OBJ;dive in OBJ;dive over OBJ;dive under OBJ;don/wear OBJ;douse/extinguis/quench/snuff OBJ;drag/pull/tug/yank OBJ;drag/pull/tug/yank on OBJ;drag/pull/tug/yank out OBJ;dress OBJ;drink/guzzle/imbibe/quaff/sip/swill OBJ;drink/guzzle/imbibe/quaff/sip/swill from OBJ;drive OBJ;drop/dump OBJ;duck/hide/rise/stand under OBJ;elevate/hoist/lift/raise OBJ;elevate/hoist/lift/raise up OBJ;embark on OBJ;embark/enter OBJ;employ/exploit/operate/use OBJ;escape/flee OBJ;escape/flee from OBJ;exhale OBJ;extend/unflatten/unfold OBJ;fasten/secure/tie OBJ;feel/grope/reach in OBJ;flatten out OBJ;flip/rotate/toggle/turn/twist around OBJ;flip/rotate/toggle/turn/twist down OBJ;flip/rotate/toggle/turn/twist on OBJ;flip/rotate/toggle/turn/twist over OBJ;flip/rotate/toggle/turn/twist through OBJ;flip/rotate/toggle/turn/twist to OBJ;flush OBJ;fly OBJ;fly on OBJ;fly over OBJ;fly with OBJ;focus on OBJ;focus/adjust OBJ;fold/wrap out OBJ;fold/wrap up OBJ;fold/wrap/flatten OBJ;frisk/ransack/rummage/search/sift OBJ;frisk/ransack/rummage/search/sift in OBJ;frisk/ransack/rummage/search/sift through OBJ;gaze/l/look/peek/peer/stare OBJ;gaze/l/look/peek/peer/stare around OBJ;gaze/l/look/peek/peer/stare at OBJ;gaze/l/look/peek/peer/stare behind OBJ;gaze/l/look/peek/peer/stare down OBJ;gaze/l/look/peek/peer/stare on OBJ;gaze/l/look/peek/peer/stare out OBJ;gaze/l/look/peek/peer/stare over OBJ;gaze/l/look/peek/peer/stare through OBJ;gaze/l/look/peek/peer/stare to OBJ;gaze/l/look/peek/peer/stare up OBJ;gaze/l/look/peek/peer/stare/frisk/ransack/rummage/search/sift under OBJ;get down OBJ;get off OBJ;get out OBJ;get under OBJ;get up OBJ;get/hold/carry/catch/confiscat/grab/keep/seize/snatch/steal/take OBJ;go/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk OBJ;go/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk around OBJ;go/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk behind OBJ;go/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk in OBJ;go/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk through OBJ;go/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk to OBJ;go/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk under OBJ;go/cross/traverse/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk over OBJ;go/get/back/retreat/escape/flee/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk away OBJ;go/retreat/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk from OBJ;go/rise/stand/bound/hurdle/jump/leap/vault/advance/crawl/hike/hop/jog/proceed/run/saunter/skip/step/stroll/tramp/trudge/walk on OBJ;greet/greetings/hello/hi/salute/affirmati/aye/naw/nay/negative/no/nope/ok/okay/positive/positivel/sure/y/yes/yup OBJ;grope/reach through OBJ;hear OBJ;heel OBJ;hide OBJ;hide behind OBJ;hide in OBJ;hold down OBJ;hold on OBJ;hold up OBJ;hold/carry/catch/confiscat/grab/keep/seize/snatch/steal/take/drag/pull/tug/yank apart OBJ;howl/scream/shout/yell OBJ;howl/scream/shout/yell at OBJ;howl/scream/shout/yell to OBJ;inflate/blow OBJ;insert/lay/place/put/stash/stuff down OBJ;insert/lay/place/put/stash/stuff on OBJ;insert/lay/place/put/stash/stuff out OBJ;kick OBJ;kick around OBJ;kick in OBJ;kick/stamp/trample down OBJ;kiss/smooch OBJ;knock/pound/rap at OBJ;knock/pound/rap on OBJ;lean on OBJ;leave OBJ;let go OBJ;lick/taste OBJ;lie/recline/repose down OBJ;lie/recline/repose in OBJ;lie/recline/repose on OBJ;listen OBJ;listen for OBJ;listen in OBJ;listen to OBJ;loiter/wait/z for OBJ;lower OBJ;make OBJ;make up OBJ;melt OBJ;nap/rest/sleep/snooze in OBJ;nap/rest/sleep/snooze on OBJ;nudge/press/push/shove/stick/thrust OBJ;nudge/press/push/shove/stick/thrust in OBJ;nudge/press/push/shove/stick/thrust on OBJ;nudge/press/push/shove/stick/thrust/drag/pull/tug/yank down OBJ;nudge/press/push/shove/stick/thrust/drag/pull/tug/yank up OBJ;observe/watch OBJ;pee/urinate/piss OBJ;pee/urinate/piss on OBJ;pet/pat/feel/disturb/rub/touch OBJ;pick up OBJ;piss off OBJ;plug in OBJ;pocket OBJ;point OBJ;point at OBJ;point to OBJ;pour/spill/sprinkle OBJ;pour/spill/sprinkle out OBJ;preserve/rescue OBJ;refuse OBJ;remove OBJ;replace OBJ;reply/respond/retort to OBJ;retract OBJ;ride OBJ;ride in OBJ;ride on OBJ;rip/tear off OBJ;rise/stand in OBJ;rise/stand up OBJ;set off OBJ;shoot OBJ;shoot off OBJ;slide OBJ;slide/bound/hurdle/jump/leap/vault down OBJ;smell/sniff/whiff OBJ;spin/whirl OBJ;stamp/trample on OBJ;stamp/trample over OBJ;start OBJ;stop OBJ;suck OBJ;suck in OBJ;suck on OBJ;swing OBJ;swing on OBJ;tell OBJ;thank/thanks OBJ;undo/unfasten/unhook/untie OBJ;untangle OBJ;wave OBJ;wave/beckon/grin/laugh/motion/nod/smile/sneer at OBJ;wave/beckon/grin/laugh/motion/nod/smile/sneer to OBJ;what/what's/whats OBJ;what/what's/whats about OBJ;where/where's/wheres OBJ;who/who's/whos OBJ;wind OBJ;wind up OBJ;wish for OBJ;ask/interroga/query/question/quiz OBJ about OBJ;ask/interroga/query/question/quiz OBJ for OBJ;assault/attack/fight/hurt/injure OBJ with OBJ;attach/connect OBJ to OBJ;bestow/deliver/donate/give/hand/offer/present OBJ OBJ;bestow/deliver/donate/give/hand/offer/present OBJ to OBJ;blind/jab/poke OBJ with OBJ;block/cover/shield OBJ with OBJ;block/cover/shield over OBJ with OBJ;block/cover/shield up OBJ with OBJ;break/crack/crumble/damage/demolish/destroy/erase/smash/trash/wreck OBJ off OBJ;break/crack/crumble/damage/demolish/destroy/erase/smash/trash/wreck OBJ with OBJ;break/crack/crumble/damage/demolish/destroy/erase/smash/trash/wreck down OBJ with OBJ;break/crack/crumble/damage/demolish/destroy/erase/smash/trash/wreck in OBJ with OBJ;break/crack/crumble/damage/demolish/destroy/erase/smash/trash/wreck through OBJ with OBJ;bribe/entice/pay/renumerat OBJ with OBJ;browse/leaf/read/skim OBJ through OBJ;browse/leaf/read/skim OBJ to OBJ;brush/clean/polish/smear/sweep/wipe OBJ off OBJ;brush/clean/polish/smear/sweep/wipe OBJ on OBJ;brush/clean/polish/smear/sweep/wipe OBJ over OBJ;brush/clean/polish/smear/sweep/wipe off OBJ on OBJ;brush/clean/polish/smear/sweep/wipe off OBJ over OBJ;burn/char/combust/cremate/ignite/incinerat/kindle/scorch OBJ with OBJ;burn/char/combust/cremate/ignite/incinerat/kindle/scorch down OBJ with OBJ;burn/char/combust/cremate/ignite/incinerat/kindle/scorch up OBJ with OBJ;burst/pop OBJ with OBJ;buy OBJ from OBJ;buy OBJ with OBJ;charge OBJ with OBJ;check/describe/examine/inspect/see/study/survey/trace OBJ through OBJ;check/describe/examine/inspect/see/study/survey/trace OBJ with OBJ;chop/cleave/cut/gash/lacerate/sever/slash/slice/split down OBJ with OBJ;chop/cleave/cut/gash/lacerate/sever/slash/slice/split through OBJ with OBJ;chop/cleave/cut/gash/lacerate/sever/slash/slice/split up OBJ with OBJ;chuck/fling/hurl/pitch/throw/toss OBJ OBJ;chuck/fling/hurl/pitch/throw/toss OBJ at OBJ;chuck/fling/hurl/pitch/throw/toss OBJ down OBJ;chuck/fling/hurl/pitch/throw/toss OBJ in OBJ;chuck/fling/hurl/pitch/throw/toss OBJ off OBJ;chuck/fling/hurl/pitch/throw/toss OBJ on OBJ;chuck/fling/hurl/pitch/throw/toss OBJ over OBJ;chuck/fling/hurl/pitch/throw/toss OBJ through OBJ;chuck/fling/hurl/pitch/throw/toss OBJ to OBJ;clear/empty OBJ from OBJ;clear/empty OBJ out OBJ;clear/empty out OBJ from OBJ;clear/empty/pour/spill/sprinkle OBJ in OBJ;clear/empty/pour/spill/sprinkle OBJ on OBJ;clear/empty/pour/spill/sprinkle out OBJ on OBJ;clear/empty/shake/pour/spill/sprinkle out OBJ in OBJ;conceal OBJ in OBJ;conceal/hide OBJ behind OBJ;conceal/hide OBJ under OBJ;crumple/crush/squash/squeeze/squish OBJ on OBJ;detach/disconnec/disengage/unattach/unplug OBJ from OBJ;dig/excavate OBJ with OBJ;dig/excavate at OBJ with OBJ;dig/excavate through OBJ with OBJ;dig/excavate up OBJ with OBJ;dig/excavate with OBJ in OBJ;dig/excavate/dig/excavate in OBJ with OBJ;disassemb/open/unseal OBJ with OBJ;disassemb/open/unseal up OBJ with OBJ;dispatch/kill/murder/punch/slay/stab/vanquish/wound OBJ with OBJ;display/show OBJ OBJ;display/show OBJ to OBJ;disturb/rub/touch OBJ to OBJ;disturb/rub/touch OBJ with OBJ;drag/pull/tug/yank OBJ out OBJ;drag/pull/tug/yank OBJ with OBJ;drag/pull/tug/yank down OBJ with OBJ;drag/pull/tug/yank on OBJ with OBJ;drag/pull/tug/yank up OBJ with OBJ;drop/dump OBJ down OBJ;drop/dump OBJ in OBJ;drop/dump OBJ on OBJ;fasten/secure/tie OBJ to OBJ;fasten/secure/tie up OBJ with OBJ;feed OBJ OBJ;feed OBJ to OBJ;feed OBJ with OBJ;fell/chop/cleave/cut/gash/lacerate/sever/slash/slice/split OBJ with OBJ;fill OBJ at OBJ;fill OBJ with OBJ;fix up OBJ with OBJ;fix/repair/service OBJ with OBJ;flash/shine OBJ at OBJ;flash/shine OBJ in OBJ;flash/shine OBJ on OBJ;flash/shine OBJ over OBJ;flip/rotate/toggle/turn/twist OBJ OBJ;flip/rotate/toggle/turn/twist OBJ with OBJ;flip/rotate/toggle/turn/twist/dial/tune/change/set OBJ to OBJ;focus OBJ at OBJ;focus OBJ on OBJ;fold/wrap OBJ in OBJ;fold/wrap/wind OBJ around OBJ;fold/wrap/wind up OBJ in OBJ;force/wedge OBJ in OBJ;force/wedge/elevate/hoist/lift/raise up OBJ with OBJ;force/wedge/nudge/press/push/shove/stick/thrust/dislocate/move/roll/shift/elevate/hoist/lift/raise OBJ with OBJ;free/release OBJ from OBJ;free/release OBJ with OBJ;gaze/l/look/peek/peer/stare at OBJ through OBJ;gaze/l/look/peek/peer/stare at OBJ with OBJ;gaze/l/look/peek/peer/stare in OBJ through OBJ;gaze/l/look/peek/peer/stare in OBJ with OBJ;gaze/l/look/peek/peer/stare through OBJ at OBJ;get/bring OBJ OBJ;get/bring OBJ for OBJ;get/bring OBJ to OBJ;get/carry/catch/confiscat/grab/keep/seize/snatch/steal/take OBJ from OBJ;get/carry/catch/confiscat/grab/keep/seize/snatch/steal/take OBJ in OBJ;get/carry/catch/confiscat/grab/keep/seize/snatch/steal/take OBJ off OBJ;get/carry/catch/confiscat/grab/keep/seize/snatch/steal/take OBJ on OBJ;get/carry/catch/confiscat/grab/keep/seize/snatch/steal/take OBJ out OBJ;get/carry/catch/confiscat/grab/keep/seize/snatch/steal/take OBJ with OBJ;grope/reach OBJ with OBJ;grope/reach for OBJ with OBJ;grope/reach out OBJ with OBJ;grope/reach to OBJ with OBJ;hit/slap/strike/swat/whack at OBJ with OBJ;hit/slap/strike/swat/whack/knock/pound/rap OBJ with OBJ;hold OBJ against OBJ;hold OBJ in OBJ;hold OBJ on OBJ;hold OBJ over OBJ;hook/jiggle/loosen/wiggle/wobble/pry OBJ with OBJ;illuminat OBJ with OBJ;insert/lay/place/put/stash/stuff OBJ against OBJ;insert/lay/place/put/stash/stuff OBJ behind OBJ;insert/lay/place/put/stash/stuff OBJ down OBJ;insert/lay/place/put/stash/stuff OBJ in OBJ;insert/lay/place/put/stash/stuff OBJ on OBJ;insert/lay/place/put/stash/stuff OBJ over OBJ;insert/lay/place/put/stash/stuff OBJ through OBJ;insert/lay/place/put/stash/stuff OBJ under OBJ;jostle/rattle/shake OBJ with OBJ;knock/pound/rap down OBJ with OBJ;leave OBJ in OBJ;leave OBJ on OBJ;let OBJ go OBJ;light OBJ with OBJ;light up OBJ with OBJ;lock OBJ with OBJ;nudge/press/push/shove/stick/thrust OBJ at OBJ;nudge/press/push/shove/stick/thrust OBJ in OBJ;nudge/press/push/shove/stick/thrust OBJ on OBJ;nudge/press/push/shove/stick/thrust OBJ over OBJ;nudge/press/push/shove/stick/thrust OBJ under OBJ;nudge/press/push/shove/stick/thrust down OBJ with OBJ;nudge/press/push/shove/stick/thrust on OBJ with OBJ;nudge/press/push/shove/stick/thrust/dislocate/move/roll/shift/drag/pull/tug/yank OBJ OBJ;nudge/press/push/shove/stick/thrust/dislocate/move/roll/shift/drag/pull/tug/yank OBJ to OBJ;observe/watch OBJ through OBJ;observe/watch OBJ with OBJ;pick OBJ with OBJ;plug OBJ in OBJ;point at OBJ for OBJ;point out OBJ to OBJ;point to OBJ for OBJ;point/aim OBJ at OBJ;point/aim OBJ to OBJ;point/aim at OBJ with OBJ;pour/spill/sprinkle OBJ from OBJ;pour/spill/sprinkle OBJ out OBJ;pry out OBJ with OBJ;pry up OBJ with OBJ;remove OBJ from OBJ;remove OBJ in OBJ;remove OBJ on OBJ;remove OBJ with OBJ;rip/tear OBJ with OBJ;rip/tear down OBJ with OBJ;rip/tear through OBJ with OBJ;rip/tear up OBJ with OBJ;screw/tighten OBJ in OBJ;screw/tighten OBJ on OBJ;screw/tighten OBJ with OBJ;screw/tighten down OBJ in OBJ;screw/tighten down OBJ on OBJ;screw/tighten down OBJ with OBJ;screw/tighten in OBJ on OBJ;screw/tighten in OBJ with OBJ;sell OBJ OBJ;sell OBJ to OBJ;set OBJ at OBJ;shake/pour/spill/sprinkle out OBJ from OBJ;shine in OBJ with OBJ;shine on OBJ with OBJ;shine over OBJ with OBJ;slide OBJ down OBJ;slide OBJ in OBJ;slide OBJ to OBJ;slide OBJ under OBJ;start OBJ with OBJ;suck OBJ from OBJ;suck OBJ out OBJ;suck out OBJ from OBJ;swing OBJ at OBJ;tell OBJ about OBJ;unlock OBJ with OBJ;unscrew OBJ from OBJ;unscrew OBJ out OBJ;unscrew OBJ with OBJ;wind OBJ in OBJ;work on OBJ with OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index 364231a8..f864c4d1 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -239,13 +239,13 @@ }, "cutthroat.z3": { 1: "wind watch", # Could be replaced by wait. - "wait": [12, 132, 133, 150, 190, 191, 216, 217, 218], # Needed for timing the actions. + "wait": [12, 132, 133, 150, 190, 191, 216, 217, 218], # Needed to time the actions. "noop": [ "read envelope", # Not needed to complete the game. ] }, "deephome.z5": { - "wait": [13, 183], # Needed for timing the actions. + "wait": [13, 183], # Needed to time the actions. "noop": [ "read letter", # Not needed to complete the game. "read warning note", # Not needed to complete the game. @@ -269,7 +269,7 @@ "enchanter.z3": { 16: "read scroll", # Not actually needed for learning the spell. 202: "read map", # Not actually needed for completing the game. - "wait": [84], # Needed for timing the actions. + "wait": [84], # Needed to time the actions. "noop": [ "read shredded scroll", # Not needed to complete the game. "read crumpled scroll", # Not needed to complete the game. @@ -300,7 +300,7 @@ "hhgg.z3": { 56: "push switch", # Not needed to complete the game. "noop": [ - "z", "wait", # Needed for timing the actions. + "z", "wait", # Needed to time the actions. ] }, "hollywood.z3": { @@ -424,7 +424,7 @@ 151: "s", # Too crowded. Have to wait. }, "sherlock.z5": { - "wait": [75], # Needed for timing the actions. + "wait": [75], # Needed to time the actions. 9: "read paper", 34: "ask holmes about ash", # Can be replaced with 'wait 1 minute'. 159: "open book", # The librarian launches off into another speech. @@ -436,7 +436,7 @@ }, "snacktime.z8": {}, "sorcerer.z3": { - "wait": [138, 139], # Needed for timing the actions. + "wait": [138, 139], # Needed to time the actions. 12: "read journal", # Can be replaced with 'wait'. 26: "read dusty scroll", # meef spell: cause plants to wilt 32: "read moldy scroll", # aimfiz spell: transport caster to someone else's location @@ -448,7 +448,7 @@ 225: "read shimmering scroll", # golmac spell: travel temporally }, "spellbrkr.z3": { - "z": [1, 2, 16, 42, 43, 44, 107, 108, 109, 110, 111, 112, 142, 233, 234, 235, 236, 300, 301, 302], # Needed for timing the actions. + "z": [1, 2, 16, 42, 43, 44, 107, 108, 109, 110, 111, 112, 142, 233, 234, 235, 236, 300, 301, 302], # Needed to time the actions. 23: "read stained scroll", # caskly spell: cause perfection 34: "read flimsy scroll", # girgol spell: stop time 39: "read dirty scroll", # throck spell: cause plants to grow. @@ -473,6 +473,18 @@ 271: "show earth crystal to trent", 272: "show star crystal to trent", 274: "ask trent about elizabeth", + }, + "trinity.z4": { + 28: "read paper", + 56: "read card", + 83: "reach in sculpture", + 154: "read crypt", + 155: "open crypt", + 180: "talk to boy", + 184: "knock on door", + 233: "put honey in cauldron", + 376: "point at coconut", # Needed to time the actions. + 573: "wait", } } From d9503605d15262c33c4bde36f50c65e942d8c176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 13:03:14 -0500 Subject: [PATCH 28/85] tryst205 --- frotz/src/games/tryst.c | 6 ++++-- tools/test_games.py | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/frotz/src/games/tryst.c b/frotz/src/games/tryst.c index dc6086aa..b5e324bd 100644 --- a/frotz/src/games/tryst.c +++ b/frotz/src/games/tryst.c @@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Tryst of Fate: http://ifdb.tads.org/viewgame?id=ic0ebhbi70bdmyc2 -const zword tryst_special_ram_addrs[18] = { +const zword tryst_special_ram_addrs[20] = { 10890, // Sharpen rock 8624, // Move rail 8499, // Oil handcar @@ -43,12 +43,14 @@ const zword tryst_special_ram_addrs[18] = { 15531, // Beetlebaum 9116, // Digging 9362, // Door + 15541, // Cuss (shouting "Horsefeathers!") + 15547, // Waiting for the Sheriff to come back and let you out. }; const char *tryst_intro[] = { "\n" }; zword* tryst_ram_addrs(int *n) { - *n = 18; + *n = 20; return tryst_special_ram_addrs; } diff --git a/tools/test_games.py b/tools/test_games.py index f864c4d1..da30dab1 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -485,8 +485,37 @@ 233: "put honey in cauldron", 376: "point at coconut", # Needed to time the actions. 573: "wait", - } - + }, + "tryst205.z5": { + 5: "ask george about bag", + 6: "ask george about beetlebaum", + 7: "ask george about frank", + 13: "open bag", # The zipper is too rusted to move. + 47: "read label", + 70: "shake safe", # There is something rattling around in there. + 71: "open safe", # Concentrate as you may, but you can't come up with the combination. + 90: "s", # The mosquitos and gnats start to eat you alive, forcing you to leave while you still can. + 96: "read sign", # The mosquitos and gnats start to eat you alive, forcing you to leave while you still can. + 111: "s", # You can't, since the jail door is in the way. + 129: "read green", + 136: "clean table with cloth", # You move the dust around with the dry cloth, but not much else. + 138: "read crumpled", + 141: "set second wheel to 2", # Second wheel already set to 2. + 188: "read writing", + 192: "n", # You can't, since the livery door is in the way. + 193: "open door", # It seems to be locked. + 228: "read note", + 244: "read sign", + 245: "read book", + 253: "ask george about dehlila", + 254: "ask george about gumball", + 255: "ask george about town", + 387: "read lettering", + 404: "read sign", + 444: "read sign", + 448: "read plaque", + 496: "wait", # Waiting to be not invisible anymore. + }, } From 114ab23da91bee833d71a6837b9fd8455597f48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 13:05:45 -0500 Subject: [PATCH 29/85] weapon --- tools/test_games.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/test_games.py b/tools/test_games.py index da30dab1..7ea7ef4b 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -516,6 +516,10 @@ 448: "read plaque", 496: "wait", # Waiting to be not invisible anymore. }, + "weapon.z5": { + 9: "touch information", # ... better not activate it unless you've got some way to stop her. + 56: "pull rods", # .. you can not do anything else while holding them together... + } } From 0643307859b0713c1b206567776a7d6ecb51d3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 13:11:41 -0500 Subject: [PATCH 30/85] wishbringer --- frotz/src/games/wishbringer.c | 6 ++++-- tools/test_games.py | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/frotz/src/games/wishbringer.c b/frotz/src/games/wishbringer.c index d77c5c83..a3f4c692 100644 --- a/frotz/src/games/wishbringer.c +++ b/frotz/src/games/wishbringer.c @@ -24,14 +24,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Wishbringer: http://ifdb.tads.org/viewgame?id=z02joykzh66wfhcl -const zword wishbringer_special_ram_addrs[3] = { +const zword wishbringer_special_ram_addrs[5] = { 9384, // Insert wishbringer into statue 9678, // Yes/No questions 11154, // Press button in arcade + 9348, // Steep Trail maze + fog + 9952, // Give letter to woman and read it to her. }; zword* wishbringer_ram_addrs(int *n) { - *n = 3; + *n = 5; return wishbringer_special_ram_addrs; } diff --git a/tools/test_games.py b/tools/test_games.py index 7ea7ef4b..f0c3cc64 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -519,6 +519,9 @@ "weapon.z5": { 9: "touch information", # ... better not activate it unless you've got some way to stop her. 56: "pull rods", # .. you can not do anything else while holding them together... + }, + "wishbringer.z3": { + 38: "wait", # Waiting for the curtain to open. } } From 20904dc85110c5c5b6a1c1c3ce7a68a9091aa6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 14:14:59 -0500 Subject: [PATCH 31/85] yomomma --- frotz/src/games/yomomma.c | 12 +++++++++--- jericho/game_info.py | 2 +- tools/test_games.py | 8 ++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/frotz/src/games/yomomma.c b/frotz/src/games/yomomma.c index a0ae0d6e..fe9d4e7a 100644 --- a/frotz/src/games/yomomma.c +++ b/frotz/src/games/yomomma.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -24,14 +24,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Raising the Flag on Mount Yomomma - http://ifdb.tads.org/viewgame?id=1iqmpkn009h9gbug -const zword yomomma_special_ram_addrs[3] = { +const zword yomomma_special_ram_addrs[8] = { 21060, // Climb on stage 16005, // Counts stage victories 36238, // Discovered Ralph's secrets + 21072, // Insult Vincent. + 15643, // Set thermostat to warm + 16638, // Take Gus' sweater. + 36226, // Talk to britney to learn Gus' secret. (alt. 26050, 36202) + 14110, // Turn music up. + // 36248, // Set thermostat to warm + give cola to guard }; zword* yomomma_ram_addrs(int *n) { - *n = 3; + *n = 8; return yomomma_special_ram_addrs; } diff --git a/jericho/game_info.py b/jericho/game_info.py index 4b1f5038..988866d2 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -503,7 +503,7 @@ "name": "yomomma", "rom": "yomomma.z8", "seed" : 0, - "walkthrough" : "d/se/x stranger/sit on chair/insult joe/yes/stand/w/w/insult vincent/norbert/search machines/e/set thermostat to warm/n/ne/x posse/wait/take sweater/remove jacket/wear sweater/wear jacket/sw/w/talk to sleaze/talk to sleaze/talk to sleaze/talk to sleaze/talk to sleaze/point at cola/e/w/take cola/n/give cola to guard/look under sofa/take pass/s/give pass to sleaze/n/search guard/tase sleaze/s/point at cola/point at vodka/pour vodka in cola/n/give cola to britney/talk to britney/se/ne/look under loudspeaker/s/look under jukebox/x knob/turn knob to high/put coin in jukebox/press techno/n/take lens/sw/look under table/n/climb on stage///se/put sweater on table/look at tag through lens/nw/n/climb on stage///norbert/give lens to norbert/sw/insult vincent/sleaze/s/insult vincent/sleaze/n/take card/x card/e/scrape gum with card/e/put gum on ass/put coin in jukebox/push ass/open satchel/x books/x wallet/open wallet/stage//", + "walkthrough" : "d/se/x stranger/sit on chair/insult joe/yes/stand/w/w/insult vincent/norbert/search machines/e/set thermostat to warm/n/ne/x posse/take sweater/remove jacket/wear sweater/wear jacket/sw/w/talk to sleaze/talk to sleaze/talk to sleaze/talk to sleaze/talk to sleaze/point at cola/e/w/take cola/n/give cola to guard/look under sofa/s/give pass to sleaze/n/search guard/tase sleaze/s/point at cola/point at vodka/pour vodka in cola/n/give cola to britney/talk to britney/se/ne/look under loudspeaker/s/look under jukebox/x knob/turn knob to high/put coin in jukebox/press techno/n/take lens/sw/look under table/n/climb on stage///se/put sweater on table/look at tag through lens/nw/n/climb on stage///give lens to norbert/sw/insult vincent/sleaze/n/take card/x card/e/ne/show card to gus/sw/w/e/scrape gum with card/e/put gum on ass/put coin in jukebox/push ass/open satchel/x books/x wallet/open wallet/stage//", "grammar" : "bother/curses/darn/drat;bust a/some/few move/moves;bust moves/move;carry/hold/take inventory;chat/t/talk;chat/t/talk to;climb/scale down;credits;damn/fuck/shit;eula/terms/copyright/lisence/lisense/licence/license;exit/leave/out/stand;full score;full/score;get out/off/up;go/run/walk;help/info/about;hint/think;hop/jump;i/inv/inventory;jam/dance;l/look;listen;long/verbose;map;no;normal/brief;notify;notify off;notify on;point;point at/to;pronouns/nouns;q/quit;restart;restore;save;short/superbrie;sing;smell/sniff;sorry;stand up;transcrip/script;transcrip/script off;transcrip/script on;verify;version;wait/z;y/yes;abuse/insult/mock/offend/ridicule/slander/taunt OBJ;attack/break/crack/destroy/fight/hit/punch/smash/wreck OBJ;bust a/some/few move/moves with OBJ;bust moves/move with OBJ;buy/order/purchase OBJ;carry/hold/take off OBJ;challenge OBJ;change/switch OBJ;change/switch/rotate/turn/twist OBJ off;change/switch/rotate/turn/twist OBJ on;change/switch/rotate/turn/twist on OBJ;change/switch/rotate/turn/twist/close/shut off OBJ;chat/t/talk OBJ;chat/t/talk to/with OBJ;chew/eat/lick/taste OBJ;chew/eat/lick/taste on OBJ;climb/scale OBJ;climb/scale down/off OBJ;climb/scale down/off from/of OBJ;climb/scale on/up/to OBJ;climb/scale up/over OBJ;close/shut OBJ;close/shut up OBJ;discard/drop/throw OBJ;disrobe/doff/shed/strip/remove OBJ;don/wear OBJ;drink/sip/swallow OBJ;embrace/hug/kiss OBJ;enter/go/run/walk OBJ;feel/touch OBJ;get in/into/on/onto OBJ;get off OBJ;get/carry/hold/take OBJ;go/run/walk into/in/inside/through OBJ;hear OBJ;jam/dance with OBJ;l/look at OBJ;l/look behind OBJ;l/look inside/in/into/through OBJ;l/look thru OBJ;l/look under OBJ;listen to OBJ;move/drag/pull OBJ;open/uncover/unwrap OBJ;pick OBJ up;pick up OBJ;place/put OBJ down;place/put down OBJ;place/put on OBJ;play OBJ;play with OBJ;point OBJ;point at/to OBJ;press/push/shift OBJ;read/check/describe/examine/watch/x OBJ;rotate/turn/twist OBJ;search OBJ;sit on top of OBJ;sit on/in/inside OBJ;smell/sniff OBJ;stand on OBJ;answer/say/shout/speak OBJ to OBJ;ask OBJ about OBJ;ask OBJ for OBJ;ask OBJ for OBJ;carry/hold/take OBJ off OBJ;change/switch/rotate/turn/twist/adjust/set OBJ to OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/place/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;give/offer/pay OBJ OBJ;give/offer/pay OBJ to OBJ;insert OBJ in/into OBJ;jam OBJ with OBJ;l/look at OBJ thru/with/using OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;mix/pour OBJ into/with/in/to/on/onto OBJ;place/put OBJ in/inside/into OBJ;place/put OBJ under OBJ;read OBJ in OBJ;read about OBJ in OBJ;read/check/describe/examine/watch/x OBJ thru/with/using OBJ;remove/get/carry/hold/take OBJ from OBJ;scrape OBJ off OBJ;scrape/get/carry/hold/take OBJ off with OBJ;scrape/get/carry/hold/take OBJ with OBJ;stun/tase/taze/zap/attack/break/crack/destroy/fight/hit/punch/smash/wreck OBJ with OBJ;tell OBJ about OBJ;unlock/open/uncover/unwrap OBJ with OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index f0c3cc64..fa47a624 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -522,7 +522,15 @@ }, "wishbringer.z3": { 38: "wait", # Waiting for the curtain to open. + }, + "yomomma.z8": { + "talk to sleaze": [24, 25, 26, 27], + 54: "put coin in jukebox", # Not needed. + 60: "n", # When you feel you're ready to challenge Gus again you can CLIMB ON STAGE. + 68: "n", # When you feel you're ready to challenge Gus again you can CLIMB ON STAGE. + 88: "put coin in jukebox", # Not needed. } + } From e3b3271dbb0b7089d0dd085cb33c9e8a2df027d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 14:22:37 -0500 Subject: [PATCH 32/85] zenon --- tools/test_games.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/test_games.py b/tools/test_games.py index fa47a624..515105d6 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -529,6 +529,16 @@ 60: "n", # When you feel you're ready to challenge Gus again you can CLIMB ON STAGE. 68: "n", # When you feel you're ready to challenge Gus again you can CLIMB ON STAGE. 88: "put coin in jukebox", # Not needed. + }, + "zenon.z5": { + 44: "n", # cannot pass without proper paperwork! + 45: "ask male about female", + 46: "ask male about work", + 47: "ask male about officer", + 48: "ask male about invitation", + 49: "ask male about daddy", + 50: "ask female about male", + 51: "ask female about bar", } } From e708fb0d13efae9a65564e2b8b53403f651b272b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 14:27:15 -0500 Subject: [PATCH 33/85] Zork1 --- frotz/src/games/zork1.c | 8 +++++--- tools/test_games.py | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frotz/src/games/zork1.c b/frotz/src/games/zork1.c index c735aa75..40025f5e 100644 --- a/frotz/src/games/zork1.c +++ b/frotz/src/games/zork1.c @@ -24,14 +24,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Zork I: http://ifdb.tads.org/viewgame?id=0dbnusxunq7fw5ro -const zword zork1_special_ram_addrs[3] = { +const zword zork1_special_ram_addrs[5] = { 2842, // Activated after 'read prayer' to dispel spirits; Alternative: 9108 8856, // Activated by 'dig sand' - 5657 // Tracks thief health + 5657, // Tracks thief health + 8898, // Press yellow buttom at the dam + 8896, // Turn bolt with wrench at the dam }; zword* zork1_ram_addrs(int *n) { - *n = 3; + *n = 5; return zork1_special_ram_addrs; } diff --git a/tools/test_games.py b/tools/test_games.py index 515105d6..b97491de 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -539,6 +539,11 @@ 49: "ask male about daddy", 50: "ask female about male", 51: "ask female about bar", + }, + "zork1.z5": { + 56: "read book", + 214: "read label", # FROBOZZ MAGIC BOAT COMPANY + } } From 3a62063f1e81778e3f5721f7cad21e218601e879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 14:47:37 -0500 Subject: [PATCH 34/85] Zork2 --- frotz/src/games/zork2.c | 10 +++++++--- tools/test_games.py | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/frotz/src/games/zork2.c b/frotz/src/games/zork2.c index 711daf48..daf35d17 100644 --- a/frotz/src/games/zork2.c +++ b/frotz/src/games/zork2.c @@ -24,12 +24,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Zork II: http://ifdb.tads.org/viewgame?id=yzzm4puxyjakk8c4 -const zword zork2_special_ram_addrs[1] = { - 9346, // Say float +const zword zork2_special_ram_addrs[5] = { + 9354, // Point at menhir and say "float" + 9024, // Unlock door to the Dreary Room + 8970, // Unlock door to the Wizard's Workshop + 8996, // Lure dragon to the Ice Room (hit dragon and move) + 9414, // Wait in the Gazebo with the princess to lure Shyly the unicorn. }; zword* zork2_ram_addrs(int *n) { - *n = 1; + *n = 5; return zork2_special_ram_addrs; } diff --git a/tools/test_games.py b/tools/test_games.py index b97491de..303ea778 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -543,7 +543,9 @@ "zork1.z5": { 56: "read book", 214: "read label", # FROBOZZ MAGIC BOAT COMPANY - + }, + "zork2.z5": { + "wait": [167, 168, 169, 238, 239] # Needed to time the actions. } } From 0fa2b4a9a459bf4f7b67674073d2ce032f437572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 15:10:21 -0500 Subject: [PATCH 35/85] Zork3 --- frotz/src/games/zork3.c | 8 ++++++-- jericho/game_info.py | 2 ++ tools/test_games.py | 13 +++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/frotz/src/games/zork3.c b/frotz/src/games/zork3.c index 1b12c5cd..3587e66b 100644 --- a/frotz/src/games/zork3.c +++ b/frotz/src/games/zork3.c @@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Zork III: http://ifdb.tads.org/viewgame?id=vrsot1zgy1wfcdru -const zword zork3_special_ram_addrs[14] = { +const zword zork3_special_ram_addrs[16] = { 8081, // Old man awake 7995, // Diving for amulet 7973, // Wearing grue repellent @@ -39,10 +39,14 @@ const zword zork3_special_ram_addrs[14] = { 8380, // DM waiting 8089, // Unlock door 7956, // Find hiding spot + // 8145, // Press south wall to make it slide. + 8165, // Room in a Puzzle + 8111, // Press button in the Button Room. + // 8501, // Indicator cycling through I, II, III, and IV (In the Scenic Vista) }; zword* zork3_ram_addrs(int *n) { - *n = 14; + *n = 16; return zork3_special_ram_addrs; } diff --git a/jericho/game_info.py b/jericho/game_info.py index 988866d2..291471d2 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -543,6 +543,8 @@ "seed" : 0, # Walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip "walkthrough": "GET LAMP/S/LIGHT LAMP/W/W/GET BREAD/E/E/E/NE/SE/W/NE/WAKE UP OLD MAN/GIVE BREAD TO OLD MAN/SW/W/S/S/S/TURN OFF LAMP/DROP LAMP/JUMP LAKE/D/GET AMULET/GET AMULET/W/S/GET TORCH/WAIT/WAIT/WAIT/TOUCH TABLE/GET CAN/WAIT/WAIT/TOUCH TABLE/DROP TORCH/WAIT/N/JUMP LAKE/D/GET CAN/GET CAN/S/S/SPRAY REPELLANT ON MYSELF/S/E/GET KEY/MOVE COVER/D/N/N/N/GET TORCH/W/W/W/D/WAIT/WAIT/TIE CHEST TO ROPE/WAIT/WAIT/WAIT/WAIT/GRAB ROPE/GET CHEST/D/D/S/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/HELLO SAILOR/GET VIAL/E/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/WAIT/KILL FIGURE WITH SWORD/KILL FIGURE WITH SWORD/KILL FIGURE WITH SWORD/KILL FIGURE WITH SWORD/KILL FIGURE WITH SWORD/KILL FIGURE WITH SWORD/REMOVE HOOD/DROP SWORD/GET CLOAK/NE/E/E/N/E/NE/OPEN DOOR/N/N/DROP CHEST/S/S/SW/W/S/E/E/S/S/E/N/PUSH GOLDEN MACHINE SOUTH/OPEN STONE DOOR/PUSH GOLDEN MACHINE EAST/EXAMINE MACHINE/READ PLAQUE/GET IN MACHINE/SET DIAL TO 776/PRESS BUTTON/WAIT/WAIT/WAIT/WAIT/WAIT/GET RING/OPEN DOOR/W/OPEN WOODEN DOOR/N/LIFT SEAT/HIDE RING UNDER SEAT/GET IN GOLDEN MACHINE/SET DIAL TO 948/PRESS BUTTON/GET OUT OF GOLDEN MACHINE/LIFT SEAT/OPEN WOODEN DOOR/S/OPEN STONE DOOR/E/GET ALL/W/S/D/PRESS SOUTH WALL/E/S/E/E/PRESS SOUTH WALL/GET BOOK/PRESS SOUTH WALL/PRESS WEST WALL/AGAIN/E/E/N/N/N/N/PRESS EAST WALL/W/S/S/S/S/E/E/N/N/N/PRESS WEST WALL/N/W/PRESS SOUTH WALL/E/E/S/S/S/W/W/N/PRESS EAST WALL/W/W/W/N/N/W/N/PRESS EAST WALL/AGAIN/AGAIN/S/PRESS SOUTH WALL/N/E/E/S/PRESS SOUTH WALL/W/PRESS WEST WALL/AGAIN/S/W/PRESS NORTH WALL/AGAIN/AGAIN/W/N/U/N/W/N/N/W/W/N/E/NE/N/PRESS BUTTON/N/N/N/RAISE SHORT POLE/PRESS WHITE PANEL/AGAIN/LOWER SHORT POLE/PUSH PINE PANEL/N/OPEN VIAL/DRINK LIQUID/N/N/N/KNOCK ON DOOR/N/E/N/N/READ BOOK/TURN DIAL TO 4/PRESS BUTTON/DUNGEON MASTER, WAIT/S/OPEN CELL DOOR/S/DUNGEON MASTER, TURN DIAL TO 8 AND PRESS BUTTON/UNLOCK BRONZE DOOR WITH KEY/OPEN IT/S", + # "walkthrough": "wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/wait/", + # "walkthrough": "GET LAMP/S/LIGHT LAMP/W/W/GET BREAD/E/E/E/NE/SE/W/NE/WAKE UP OLD MAN/GIVE BREAD TO OLD MAN/SW/W/S/S/S/TURN OFF LAMP/DROP LAMP/JUMP LAKE/D/GET AMULET/GET AMULET/W/S/GET TORCH/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/look/", "grammar" : "again/g;answer/reply;back;barf/chomp/lose;bathe/swim/wade;blast;brief;bug;chant/incant;chase/come/follow/pursue;curse/damn;diagno;dive/jump/leap;enter;exit;gaze/l/look/stare;hello/hi;hop/skip;i/invent;leave;mumble/sigh;plugh/xyzzy;pray;q/quit;repent;restar;restor;save;say/talk;score;scream/shout/yell;script;stand;stay;super/superb;unscri;verbos;versio;wait/z;win/winnag;zork;answer/reply OBJ;ask/tell OBJ;awake/startl/surpri/wake OBJ;awake/startl/surpri/wake up OBJ;banish/begone/cast/drive/exorci OBJ;banish/begone/cast/drive/exorci away OBJ;banish/begone/cast/drive/exorci out OBJ;bathe/swim/wade in OBJ;bite/kick/taunt OBJ;blow out OBJ;blow up OBJ;board OBJ;brandi/wave OBJ;carry/get/grab/hold/remove/take OBJ;carry/get/grab/hold/remove/take out OBJ;chase/come/follow/pursue OBJ;climb/sit OBJ;climb/sit/carry/get/grab/hold/remove/take in OBJ;climb/sit/carry/get/grab/hold/remove/take on OBJ;climb/sit/go/procee/run/step/walk down OBJ;climb/sit/go/procee/run/step/walk up OBJ;close OBJ;consum/eat/taste OBJ;count OBJ;cross/ford OBJ;curse/damn OBJ;deflat OBJ;descri/examin/what/whats OBJ;descri/examin/what/whats on OBJ;descri/examin/what/whats/gaze/l/look/stare in OBJ;dig in OBJ;disemb OBJ;dive/jump/leap across OBJ;dive/jump/leap from OBJ;dive/jump/leap in OBJ;dive/jump/leap off OBJ;dive/jump/leap/go/procee/run/step/walk over OBJ;douse/exting OBJ;drink/imbibe/swallo OBJ;drink/imbibe/swallo from OBJ;drop/releas OBJ;enter OBJ;exit OBJ;feel/pat/pet/rub/touch OBJ;fill OBJ;find/see/seek/where OBJ;flip/set/shut/turn OBJ;flip/set/shut/turn off OBJ;flip/set/shut/turn on OBJ;free/unatta/unfast/unhook/untie OBJ;gaze/l/look/stare around OBJ;gaze/l/look/stare at OBJ;gaze/l/look/stare behind OBJ;gaze/l/look/stare throug OBJ;gaze/l/look/stare under OBJ;gaze/l/look/stare with OBJ;gaze/l/look/stare/search for OBJ;go/procee/run/step/walk OBJ;go/procee/run/step/walk around OBJ;go/procee/run/step/walk in OBJ;go/procee/run/step/walk on OBJ;go/procee/run/step/walk to OBJ;go/procee/run/step/walk with OBJ;hello/hi OBJ;hide/insert/place/put/stuff down OBJ;hide/insert/place/put/stuff on OBJ;kiss OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;launch OBJ;lean on OBJ;leave OBJ;lift/raise OBJ;lift/raise up OBJ;light OBJ;listen for OBJ;listen to OBJ;lower OBJ;make OBJ;molest/rape OBJ;move/pull/tug OBJ;open OBJ;open up OBJ;pick OBJ;pick up OBJ;play OBJ;pour/spill OBJ;press/push OBJ;press/push on OBJ;pull/tug on OBJ;pump up OBJ;read/skim OBJ;roll up OBJ;say/talk to OBJ;search OBJ;search in OBJ;send for OBJ;shake OBJ;slide OBJ;smell/sniff OBJ;spin OBJ;squeez OBJ;stand/carry/get/grab/hold/remove/take up OBJ;strike OBJ;swing/thrust OBJ;wear OBJ;wind OBJ;wind up OBJ;apply OBJ to OBJ;attach/fasten/secure/tie OBJ to OBJ;attach/fasten/secure/tie up OBJ with OBJ;attack/fight/hit/hurt/injure OBJ with OBJ;blind/jab/poke OBJ with OBJ;block/break/damage/destro/smash OBJ with OBJ;block/break/damage/destro/smash down OBJ with OBJ;blow up OBJ with OBJ;brandi/wave OBJ at OBJ;burn/ignite/incine OBJ with OBJ;burn/ignite/incine down OBJ with OBJ;carry/get/grab/hold/remove/take OBJ from OBJ;carry/get/grab/hold/remove/take OBJ off OBJ;carry/get/grab/hold/remove/take OBJ out OBJ;chuck/hurl/throw/toss OBJ at OBJ;chuck/hurl/throw/toss OBJ in OBJ;chuck/hurl/throw/toss OBJ off OBJ;chuck/hurl/throw/toss OBJ on OBJ;chuck/hurl/throw/toss OBJ over OBJ;chuck/hurl/throw/toss OBJ with OBJ;cut/pierce/slice OBJ with OBJ;dig OBJ with OBJ;dig in OBJ with OBJ;dispat/kill/murder/slay/stab OBJ with OBJ;donate/feed/give/hand/offer OBJ OBJ;donate/feed/give/hand/offer OBJ to OBJ;drop/releas OBJ down OBJ;drop/releas OBJ on OBJ;drop/releas/hide/insert/place/put/stuff OBJ in OBJ;feel/pat/pet/rub/touch OBJ with OBJ;fill OBJ with OBJ;fix/glue/patch/plug/repair OBJ with OBJ;flip/set/shut/turn OBJ for OBJ;flip/set/shut/turn OBJ to OBJ;flip/set/shut/turn OBJ with OBJ;free/unatta/unfast/unhook/untie OBJ from OBJ;gaze/l/look/stare at OBJ with OBJ;grease/lubric/oil OBJ with OBJ;hide/insert/place/put/stuff OBJ behind OBJ;hide/insert/place/put/stuff OBJ on OBJ;hide/insert/place/put/stuff OBJ under OBJ;inflat OBJ with OBJ;is OBJ in OBJ;is OBJ on OBJ;light OBJ with OBJ;liquif/melt OBJ with OBJ;lock OBJ with OBJ;open OBJ with OBJ;pick OBJ with OBJ;pour/spill OBJ from OBJ;pour/spill OBJ in OBJ;pour/spill OBJ on OBJ;press/push/slide OBJ OBJ;press/push/slide OBJ to OBJ;press/push/slide OBJ under OBJ;pump up OBJ with OBJ;read/skim OBJ with OBJ;spray OBJ on OBJ;spray OBJ with OBJ;squeez OBJ on OBJ;strike OBJ with OBJ;swing/thrust OBJ at OBJ;unlock OBJ with OBJ;", "max_word_length" : 6 } diff --git a/tools/test_games.py b/tools/test_games.py index 303ea778..1172631f 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -546,6 +546,19 @@ }, "zork2.z5": { "wait": [167, 168, 169, 238, 239] # Needed to time the actions. + }, + "zork3.z5": { + "wait": [ + # Needed for the indicator to cycle through I, II, III, and IV. + 29, 30, 31, 35, + 60, 61, # Not needed. + 64, 65, 66, # Waiting to hear a voice. + *range(72, 80+1), # Waiting for an old boat to pass alongside the shore. + *range(85, 99+1), + 139, 140, 141, 142, 143, # Waiting for guard to march away + ], + 135: "read plaque", + 262: "read book", } } From ef6306fa54d39f945daed2300c6d4ed95ce17f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 25 Nov 2021 16:08:14 -0500 Subject: [PATCH 36/85] spirit --- jericho/game_info.py | 2 +- tools/test_games.py | 73 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/jericho/game_info.py b/jericho/game_info.py index 291471d2..f792aecc 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -438,7 +438,7 @@ "name": "spirit", "rom": "spirit.z5", "seed" : 0, - "walkthrough" : "z/z/z/z/z/read note/take pallet/n/w/w/take sand/w/n/n/wear amulet/read prayer/learn frotz/cast frotz on amulet/learn frotz/cast frotz on amulet/s/s/e/e/e/e/e/s/take scroll/read scroll/gnusto espnis/read diary/n/w/s/read page/n/n/read journal/push west wall/w/take scroll/read scroll/gnusto foblub/read faded/e/s/w/w/u/e/ne/open window/sw/e/read scriptures/consult scriptures about planes/w/w/d/d/e/n/read paper/s/e/take flour/move barrel/open trapdoor/w/w/u/w/w/s/s/drop all/drop amulet/e/u/w/yell/take scroll/read scroll/enter window/sw/w/d/w/w/s/s/take all/wear amulet/gnusto swanko/s/s/w/d/put pallet on boulder/u/climb tree/shake branch/d/d/take egg/u/e/s/s/throw sand/s/s/s/s/se/push dusty s/n/push moldy s/n/push filthy s/push dusty s/n/push moldy s/n/push filthy s/n/n/take key/x floorboards/move floorboards/s/s/push dusty n/s/push moldy n/s/push filthy n/push filthy n/s/push dusty s/n/push moldy s/n/n/unlock icebox with square key/open icebox/open blue box/take scroll/read scroll/gnusto zemdor/learn zemdor/zemdor blue box/open royal-blue box/take wrapper/open wrapper/read notice/drop notice/open navy-blue box/take whistle/take crunchy cereal/take packet/take butter/hit board/u/s/s/push moldy n/s/push dusty n/n/nw/sw/search couch/take coin/x clock/turn knob/turn knob/turn knob/turn knob/turn knob/turn knob/take clock/take ledger/read ledger/read subway/open door/s/ask governor about key/take key/n/ne/s/d/put coin in slot/se/z/e/learn espnis/spells/espnis thug/search seat/take newspaper/read newspaper/read news in newspaper/read sports in newspaper/read features in newspaper/drop newspaper/w/d/z/z/s/search seat/z/n/n/u/e/e/e/se/e/touch waterfall/e/put egg in pot/put flour in pot/put butter in pot/put packet in pot/put whistle in pot/put shiny in pot/put cereal in pot/put volcano in pot/put clock in pot/put ledger in pot/take pot/take small key/w/n/take glasses/search fountain/s/w/s/unlock toolshed with small key/drop small key/drop glasses/open toolshed/take all from toolshed/wear gloves/wear cap/read cracked/drop cracked/n/n/clip monster/drop cap/drop clipper/s/nw/w/s/look in telescope/open telescope/take scroll/read scroll/gnusto fiznav/n/w/s/ask delbin about ale/ask morgan about dragon/offer coin to delbin/learn zemdor/zemdor ale/take rag/take headdress/put rag in pot/put headdress in pot/n/w/d/put coin in slot/s/z/z/s/z/z/n/u/w/learn foblub/foblub yupple/search seat/z/z/z/z/z/z/z/e/ne/u/n/take scroll/read scroll/gnusto gloth/w/n/n/w/take flat key/e/e/read history book/look up index in history book/look up trophy in history book/w/n/w/search mess/take all/put cube in pot/put decaf in pot/e/n/w/unlock northern door with flat key/drop flat key/open northern door/n/open book/read book/take card/s/e/n/n/turn on switch/open notebook/take term paper/read term paper/s/s/s/e/take scroll/read scroll/w/show card to librarian/drop card/w/gnusto taclor/n/e/e/e/read journal/w/read research paper/w/w/s/s/s/s/e/s/d/put coin in slot/sw/z/z/z/z/z/z/w/z/z/z/z/z/z/e/ne/u/ne/ne/n/z/show term paper to frobar/read scroll/gnusto feeyuk/e/read journal/read twisted/w/s/sw/sw/w/take toy/put toy in pot/s/take coin/read sign/take clock/pull knob/turn knob/push knob/turn knob/turn knob/read scroll/gnusto wigro/drop clock/n/w/sw/sw/take scroll/read muddy scroll/gnusto throck/s/s/x natives/x shaman/take headdress/give headdress to shaman/n/read map/search grass/drop map/n/ne/ne/e/e/d/put coin in slot/sw/z/z/z/w/z/z/z/e/ne/u/take umbrella/se/s/z/l/take coin/s/e/e/d/take scroll/read gray scroll/gnusto tossio/give gloves to zombie/take wire/u/w/w/n/n/nw/d/put coin in slot/put wire in slot/drop wire/sw/d/s/z/z/z/z/z/z/n/u/e/z/z/z/z/z/z/z/z/z/z/w/nw/u/n/w/take rag/ask skier about scroll/give rag to skier/take scroll/read waxy scroll/gnusto egdelp/e/s/d/put coin in slot/se/e/z/z/z/z/z/z/w/nw/u/sw/sw/w/take scroll/read spotted scroll/gnusto bekdab/learn bekdab/gnusto bekdab/x hermit/take cereal/give cereal to hermit/ask hermit about exit/ask hermit about entrance/s/read parchment/drop parchment/ne/ask farmer about oyster/e/e/se/nw/w/take sack/x boat/enter boat/take volcano/s/drop volcano in water/n/exit/n/s/x boat/learn fiznav/fiznav boat/enter boat/s/ne/exit/learn swanko/e/swanko spirit/take gray rod/put gray rod in pot/w/enter boat/sw/n/exit/w/put silver sphere in pot/ne/n/read memo/open fur sack/put coins in fur sack/take all from basis/put coins in fur sack/take coin from basis/put coin in interest/take coin from basis/put coin in loans/take seven coins from basis/put six coins in overhead/s/d/put coin in slot/se/e/z/z/w/d/z/z/z/z/z/z/s/z/z/n/n/u/e/e/e/se/n/learn throck/throck shrub/take dornberries/put dornberries in pot/s/nw/w/nw/read sign/n/n/learn foblub/foblub man/n/take scroll/read pale scroll/gnusto shazok/n/learn egdelp/egdelp golem/learn tossio/tossio golem/learn bekdab/bekdab golem/learn taclor/taclor me/s/x coach/ask coach for trophy/s/s/s/s/sw/s/ask delbin about minirva/n/w/d/take coin/put coin in slot/s/z/s/z/z/z/z/z/z/z/z/z/z/n/u/ne/u/se/ne/x treant/gnusto shazok/learn shazok/shazok storm/put red sphere in pot/sw/s/s/e/e/e/n/take pan/s/take sticker/read sticker/drop sticker/take flour from pot/put flour in pan/take butter from pot/put butter in pan/take packet from pot/put packet in pan/take sugar from pot/put sugar in pan/take egg from pot/put egg in pan/take berries from pot/put berries in pan/mix pan/learn gloth/gloth dough/open oven/put pan in oven/close oven/turn dial/turn dial/turn dial/turn dial/turn dial/turn dial/turn dial/turn dial/push button/open oven/take pan/w/w/w/n/n/nw/d/take coin/take wire/put coin in slot/put wire in slot/drop wire/sw/d/z/z/z/z/s/z/z/z/z/z/z/n/u/nw/u/s/read sign/give pan to guard/s/w/read sign/d/learn feeyuk/feeyuk me/learn feeyuk/feeyuk me/take ebony/w/w/s/s/take ebony/w/e/take balsa beam from northern niche/put ebony in northern niche/n/n/take ebony/w/e/take balsa beam/put ebony in southern niche/s/s/take ebony/take beam from southern niche/put ebony in southern niche/s/s/take beam from eastern niche/put ebony in eastern niche/learn swanko/e/e/swanko spirit/take smoke rod/put smoke rod in pot/enter hole/u/e/s/e/take key/unlock cabinet with shiny key/drop shiny key/open cabinet/learn egdelp/egdelp cabinet/open cabinet/look in cabinet/take crumpled scroll/read crumpled scroll/gnusto ledak/read warped/d/s/take ledger/show ledger to magistrate/x sydney/take toy/give toy to sydney/ask sydney for hat/put brown sphere in pot/drop red hat/n/n/e/s/take vase/n/n/n/x painting/take whistle/blow whistle/drop whistle/take door/s/w/n/n/d/take coin/put coin in slot/se/d/z/z/z/z/z/s/z/z/z/z/z/z/n/u/w/z/z/e/ne/u/n/e/learn ledak/drop door/open door/e/u/n/w/read journal/w/ledak painting/take painting/e/e/s/d/w/search painting/read white scroll/gnusto huncho/drop painting/w/n/n/nw/n/take coin/n/n/drop balsa wood beam/take red flag/take red flag/put red flag on speckled/put red flag on spotted/x cage/pull lever/yes/n/nw/learn taclor/taclor kobold/take green sphere/put green sphere in pot/se/ne/n/n/e/e/e/read torn/w/n/n/u/e/put trophy in depression/take trophy/w/w/put trophy in depression/take trophy/e/s/put trophy in depression/take trophy/n/n/put trophy in depression/learn swanko/s/swanko spirit/take white rod/put white rod in pot/d/s/s/w/w/s/s/sw/s/s/s/s/se/s/s/w/n/n/n/n/e/e/x dials/set left dial to 7/set center dial to 3/set right dial to 4/push button/s/x contraption/stand on disc/sw/sw/s/take briefcase/s/open briefcase/take red scroll/read red scroll/gnusto luncho/drop briefcase/w/z/z/z/z/z/z/z/z/z/z/e/ne/u/w/w/sw/sw/s/w/n/e/push statue w/push statue n/push statue n/n/e/put vase in opening/w/u/e/open umbrella/put umbrella on pool/w/learn swanko/u/swanko spirit/drop all/drop amulet/e/take black rod/put black rod in hole/w/take all/wear amulet/d/d/e/learn huncho/huncho vase/w/s/s/s/e/n/ne/ne/e/e/d/put coin in slot/sw/z/z/w/z/z/z/z/z/z/e/ne/u/n/w/n/n/n/n/e/e/s/stand on disc/se/se/read ripped/sw/sw/take black rod/take smoke rod/take white rod/take gray rod/learn huncho/l/huncho me/take decaf from pot/e/take can/drop decaf/w/listen/listen/enter curtain/z/z/z/z/exit/listen/open door/w/x machine/yes/drop can/x implementor/wake implementor/ne/n/l/enter square/take scrawled/w/n/n/n/n/n/n/n/read scrawled/drop scrawled/s/e/e/d/e/e/d/e/se/read blackened/take silver rod/push purple/jump/z/z/put silver rod in top/take green rod/push purple/say minirva/drop green rod/take red rod/push purple/put red rod in hole/z/take brown rod/push purple/take dusty brick/e/take thick brick/drop dusty brick/put brown rod in hole/x dusty brick/x hole/break wall/take all but parchment/wear amulet/nw/w/u/w/w/u/w/w/s/s/s/s/search snow/search top/take silver rod/s/s/s/s/s/s/s/d/take coin/put coin in slot/se/z/z/z/e/z/z/z/z/z/z/w/nw/u/s/enter boat/s/se/exit/s/search wreck/take green rod/n/enter boat/nw/n/exit/n/d/take coin/put coin in slot/se/z/e/z/z/z/w/d/s/z/z/n/n/u/e/ne/push statue/l/take red rod/sw/w/d/sw/w/d/take coin/put coin in slot/s/s/z/z/z/z/z/z/z/z/z/z/n/u/ne/u/se/s/s/e/e/d/search foundation/l/take brown rod/join red rod to silver rod/join golden rod to green rod/join golden rod to brown rod/take all from pot/throw red at smoke/throw silver at white/throw green at gray/throw brown at black", + "walkthrough" : "z/z/z/z/z/read note/take pallet/n/w/w/take sand/w/n/n/wear amulet/read prayer/learn frotz/cast frotz on amulet/learn frotz/cast frotz on amulet/s/s/e/e/e/e/e/s/take scroll/read scroll/gnusto espnis/read diary/n/w/s/read page/n/n/read journal/push west wall/w/take scroll/read scroll/gnusto foblub/read faded/e/s/w/w/u/e/ne/open window/sw/e/read scriptures/consult scriptures about planes/w/w/d/d/e/n/read paper/s/e/take flour/move barrel/open trapdoor/w/w/u/w/w/s/s/drop all/drop amulet/e/u/w/yell/take scroll/read scroll/enter window/sw/w/d/w/w/s/s/take all/wear amulet/gnusto swanko/s/s/w/d/put pallet on boulder/u/climb tree/shake branch/d/d/take egg/u/e/s/s/throw sand/s/s/s/s/se/push dusty s/n/push moldy s/n/push filthy s/push dusty s/n/push moldy s/n/push filthy s/n/n/take key/x floorboards/move floorboards/s/s/push dusty n/s/push moldy n/s/push filthy n/push filthy n/s/push dusty s/n/push moldy s/n/n/unlock icebox with square key/open icebox/open blue box/take scroll/read scroll/gnusto zemdor/learn zemdor/zemdor blue box/open royal-blue box/take wrapper/open wrapper/read notice/drop notice/open navy-blue box/take whistle/take crunchy cereal/take packet/take butter/hit board/u/s/s/push moldy n/s/push dusty n/n/nw/sw/search couch/take coin/x clock/turn knob/turn knob/turn knob/turn knob/turn knob/turn knob/take clock/take ledger/read ledger/read subway/open door/s/ask governor about key/take key/n/ne/s/d/put coin in slot/se/z/e/learn espnis/spells/espnis thug/search seat/take newspaper/read newspaper/read news in newspaper/read sports in newspaper/read features in newspaper/drop newspaper/w/d/z/z/s/search seat/z/n/n/u/e/e/e/se/e/touch waterfall/e/put egg in pot/put flour in pot/put butter in pot/put packet in pot/put whistle in pot/put shiny in pot/put cereal in pot/put volcano in pot/put clock in pot/put ledger in pot/take pot/take small key/w/n/take glasses/search fountain/s/w/s/unlock toolshed with small key/drop small key/drop glasses/open toolshed/take all from toolshed/wear gloves/wear cap/read cracked/drop cracked/n/n/clip monster/drop cap/drop clipper/s/nw/w/s/look in telescope/open telescope/take scroll/read scroll/gnusto fiznav/n/w/s/ask delbin about ale/ask morgan about dragon/offer coin to delbin/learn zemdor/zemdor ale/take rag/take headdress/put rag in pot/put headdress in pot/n/w/d/put coin in slot/s/z/z/s/z/z/n/u/w/learn foblub/foblub yupple/search seat/z/z/z/z/z/z/z/e/ne/u/n/take scroll/read scroll/gnusto gloth/w/n/n/w/take flat key/e/e/read history book/look up index in history book/look up trophy in history book/w/n/w/search mess/take all/put cube in pot/put decaf in pot/e/n/w/unlock northern door with flat key/drop flat key/open northern door/n/open book/read book/take card/s/e/n/n/turn on switch/open notebook/take term paper/read term paper/s/s/s/e/take scroll/read scroll/w/show card to librarian/drop card/w/gnusto taclor/n/e/e/e/read journal/w/read research paper/w/w/s/s/s/s/e/s/d/put coin in slot/sw/z/z/z/z/z/z/w/z/z/z/z/z/z/e/ne/u/ne/ne/n/z/show term paper to frobar/read scroll/gnusto feeyuk/e/read journal/read twisted/w/s/sw/sw/w/take toy/put toy in pot/s/take coin/read sign/take clock/pull knob/turn knob/push knob/turn knob/turn knob/read scroll/gnusto wigro/drop clock/n/w/sw/sw/take scroll/read muddy scroll/gnusto throck/s/s/x natives/x shaman/take headdress/give headdress to shaman/n/read map/search grass/drop map/n/ne/ne/e/e/d/put coin in slot/sw/z/z/z/w/z/z/z/e/ne/u/take umbrella/se/s/z/l/take coin/s/e/e/d/take scroll/read gray scroll/gnusto tossio/give gloves to zombie/take wire/u/w/w/n/n/nw/d/put coin in slot/put wire in slot/drop wire/sw/d/s/z/z/z/z/z/z/n/u/e/z/z/z/z/z/z/z/z/z/z/w/nw/u/n/w/take rag/ask skier about scroll/give rag to skier/take scroll/read waxy scroll/gnusto egdelp/e/s/d/put coin in slot/se/e/z/z/z/z/z/z/w/nw/u/sw/sw/w/take scroll/read spotted scroll/gnusto bekdab/gnusto bekdab/x hermit/take cereal/give cereal to hermit/ask hermit about exit/ask hermit about entrance/s/read parchment/drop parchment/ne/ask farmer about oyster/e/e/se/nw/w/take sack/x boat/enter boat/take volcano/s/drop volcano in water/n/exit/n/s/x boat/learn fiznav/fiznav boat/enter boat/s/ne/exit/learn swanko/e/swanko spirit/take gray rod/put gray rod in pot/w/enter boat/sw/n/exit/w/put silver sphere in pot/ne/n/read memo/open fur sack/put coins in fur sack/take all from basis/put coins in fur sack/take coin from basis/put coin in interest/take coin from basis/put coin in loans/take seven coins from basis/put six coins in overhead/s/d/put coin in slot/se/e/z/z/w/d/z/z/z/z/z/z/s/z/z/n/n/u/e/e/e/se/n/learn throck/throck shrub/take dornberries/put dornberries in pot/s/nw/w/nw/read sign/n/n/learn foblub/foblub man/n/take scroll/read pale scroll/gnusto shazok/n/learn egdelp/egdelp golem/learn tossio/tossio golem/learn bekdab/bekdab golem/learn taclor/taclor me/s/x coach/ask coach for trophy/s/s/s/s/sw/s/ask delbin about minirva/n/w/d/take coin/put coin in slot/s/z/s/z/z/z/z/z/z/z/z/z/z/n/u/ne/u/se/ne/x treant/gnusto shazok/learn shazok/shazok storm/put red sphere in pot/sw/s/s/e/e/e/n/take pan/s/take sticker/read sticker/drop sticker/take flour from pot/put flour in pan/take butter from pot/put butter in pan/take packet from pot/put packet in pan/take sugar from pot/put sugar in pan/take egg from pot/put egg in pan/take berries from pot/put berries in pan/mix pan/learn gloth/gloth dough/open oven/put pan in oven/close oven/turn dial/turn dial/turn dial/turn dial/turn dial/turn dial/turn dial/turn dial/push button/open oven/take pan/w/w/w/n/n/nw/d/take coin/take wire/put coin in slot/put wire in slot/drop wire/sw/d/z/z/z/z/s/z/z/z/z/z/z/n/u/nw/u/s/read sign/give pan to guard/s/w/read sign/d/learn feeyuk/feeyuk me/learn feeyuk/feeyuk me/take ebony/w/w/s/s/take ebony/w/e/take balsa beam from northern niche/put ebony in northern niche/n/n/take ebony/w/e/take balsa beam/put ebony in southern niche/s/s/take ebony/take beam from southern niche/put ebony in southern niche/s/s/take beam from eastern niche/put ebony in eastern niche/learn swanko/e/e/swanko spirit/take smoke rod/put smoke rod in pot/enter hole/u/e/s/e/take key/unlock cabinet with shiny key/drop shiny key/open cabinet/learn egdelp/egdelp cabinet/open cabinet/look in cabinet/take crumpled scroll/read crumpled scroll/gnusto ledak/read warped/d/s/take ledger/show ledger to magistrate/x sydney/take toy/give toy to sydney/ask sydney for hat/put brown sphere in pot/drop red hat/n/n/e/s/take vase/n/n/n/x painting/take whistle/blow whistle/drop whistle/take door/s/w/n/n/d/take coin/put coin in slot/se/d/z/z/z/z/z/s/z/z/z/z/z/z/n/u/w/z/z/e/ne/u/n/e/learn ledak/drop door/open door/e/u/n/w/read journal/w/ledak painting/take painting/e/e/s/d/w/search painting/read white scroll/gnusto huncho/drop painting/w/n/n/nw/n/take coin/n/n/drop balsa wood beam/take red flag/take red flag/put red flag on speckled/put red flag on spotted/x cage/pull lever/yes/n/nw/learn taclor/taclor kobold/take green sphere/put green sphere in pot/se/ne/n/n/e/e/e/read torn/w/n/n/u/e/put trophy in depression/take trophy/w/w/put trophy in depression/take trophy/e/s/put trophy in depression/take trophy/n/n/put trophy in depression/learn swanko/s/swanko spirit/take white rod/put white rod in pot/d/s/s/w/w/s/s/sw/s/s/s/s/se/s/s/w/n/n/n/n/e/e/x dials/set left dial to 7/set center dial to 3/set right dial to 4/push button/s/x contraption/stand on disc/sw/sw/s/take briefcase/s/open briefcase/take red scroll/read red scroll/gnusto luncho/drop briefcase/w/z/z/z/z/z/z/z/z/z/z/e/ne/u/w/w/sw/sw/s/w/n/e/push statue w/push statue n/push statue n/n/e/put vase in opening/w/u/e/open umbrella/put umbrella on pool/w/learn swanko/u/swanko spirit/drop all/drop amulet/e/take black rod/put black rod in hole/w/take all/wear amulet/d/d/e/learn huncho/huncho vase/w/s/s/s/e/n/ne/ne/e/e/d/put coin in slot/sw/z/z/w/z/z/z/z/z/z/e/ne/u/n/w/n/n/n/n/e/e/s/stand on disc/se/se/read ripped/sw/sw/take black rod/take smoke rod/take white rod/take gray rod/learn huncho/l/huncho me/take decaf from pot/e/take can/drop decaf/w/listen/listen/enter curtain/z/z/z/z/exit/listen/open door/w/x machine/yes/drop can/x implementor/wake implementor/ne/n/l/enter square/take scrawled/w/n/n/n/n/n/n/n/read scrawled/drop scrawled/s/e/e/d/e/e/d/e/se/read blackened/take silver rod/push purple/jump/z/z/put silver rod in top/take green rod/push purple/say minirva/drop green rod/take red rod/push purple/put red rod in hole/z/take brown rod/push purple/take dusty brick/e/take thick brick/drop dusty brick/put brown rod in hole/x dusty brick/x hole/break wall/take all but parchment/wear amulet/nw/w/u/w/w/u/w/w/s/s/s/s/search snow/search top/take silver rod/s/s/s/s/s/s/s/d/take coin/put coin in slot/se/z/z/z/e/z/z/z/z/z/z/w/nw/u/s/enter boat/s/se/exit/s/search wreck/take green rod/n/enter boat/nw/n/exit/n/d/take coin/put coin in slot/se/z/e/z/z/z/w/d/s/z/z/n/n/u/e/ne/push statue/l/take red rod/sw/w/d/take coin/put coin in slot/s/s/z/z/n/u/ne/u/se/s/s/e/e/d/search foundation/l/take brown rod/join red rod to silver rod/join golden rod to green rod/join golden rod to brown rod/take all from pot/throw red at smoke/throw silver at white/throw green at gray/throw brown at black", "grammar" : "awake/awaken/wake;awake/awaken/wake up;beg;bellow/scream/yell;bother/curses/darn/drat;brief/normal;c,cast;carry/get/hold/take inventory;carry/get/hold/take off;carry/get/hold/take out;chants/memory/spells;chuckle/laugh;close/cover/shut up;cough/sneeze;damn/fuck/shit/sod;diagnose/health/status;die/q/quit;dive/swim;exit/out/outside/stand;full/fullscore;full/fullscore score;go/leave/run/walk;hear/listen;help/hint;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;l/look;long/verbose;meditate;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;plover/plugh/treasure/xyzzy/yoho;pray;restart;restore;save;score;script;script off;script on;short/superbrie;sing;smell/sniff;sorry;stand/carry/get/hold/take up;think;verify;version;wait/z;wave;y/yes;yawn;adjust/set OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;c,cast OBJ;carry/get/hold/take OBJ;carry/get/hold/take off OBJ;cast/chant OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale over OBJ;climb/scale up OBJ;clip/trim/chop/cut/prune/slice OBJ;close/cover/shut OBJ;cross/enter/go/leave/run/walk OBJ;damn/fuck/shit/sod OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;fold OBJ;go/leave/run/walk through OBJ;go/leave/run/walk/carry/get/hold/take into OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;l/look at OBJ;l/look in OBJ;l/look inside OBJ;l/look into OBJ;l/look through OBJ;l/look under OBJ;lie/sit/go/leave/run/walk inside OBJ;lie/sit/go/leave/run/walk/carry/get/hold/take in OBJ;lie/sit/stand/carry/get/hold/take on OBJ;mix/stir OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;play/blow OBJ;put OBJ down;put down OBJ;put on OBJ;read/check/describe/examine/watch/x OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;shake/yank OBJ;smell/sniff OBJ;squash/squeeze OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;wave OBJ;adjust/set OBJ to OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/get/hold/take OBJ off OBJ;cast/chant OBJ at OBJ;cast/chant OBJ on OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;connect/join OBJ to OBJ;connect/join OBJ with OBJ;dig OBJ with OBJ;discard/drop/throw OBJ against OBJ;discard/drop/throw OBJ at OBJ;discard/drop/throw OBJ down OBJ;discard/drop/throw/insert/put OBJ in OBJ;discard/drop/throw/insert/put OBJ into OBJ;discard/drop/throw/put OBJ on OBJ;discard/drop/throw/put OBJ onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ into OBJ;empty OBJ on OBJ;empty OBJ onto OBJ;empty OBJ to OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;lock OBJ with OBJ;put OBJ inside OBJ;remove/carry/get/hold/take OBJ from OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index 1172631f..09fd87ec 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -461,6 +461,50 @@ 331: "ask belboz about figure", 368: "read vellum scroll", # empty }, + "spirit.z5": { + "noop": ["z"], + 5: "read note", + 15: "read prayer", + 31: "read diary", + 35: "read page", + 38: "read journal", + 44: "read faded", + 55: "read scriptures", + 56: "consult scriptures about planes", + 63: "read paper", + 156: "read notice", + 184: "read ledger", + 185: "read subway", + 188: "ask governor about key", + 204: "read news in newspaper", + 206: "read features in newspaper", + 210: "z", # Waiting for the train. + 251: "read cracked", + 270: "ask delbin about ale", + 271: "ask morgan about dragon", + 298: "z", # Waiting for the doors to close. + 300: "z", # Waiting for the train to stop. + 316: "read history book", + 350: "w", # Some strange invisible force stops you + 359: "read journal", + 361: "read research paper", + "z": [ + *range(373, 378+1), # In the train. + *range(380, 385+1), # In the train. + ], + 397: "read journal", + 408: "read sign", + 432: "read map", + 506: "ask skier about scroll", + 531: "gnusto bekdab", # First attempt fails. + 579: "read memo", + 624: "read sign", + 651: "ask delbin about minirva", + 756: "read sign", + 1065: "read ripped", + 1109: "read scrawled", + 1120: "read blackened", + }, "temple.z5": { 32: "ask charles about temple", 77: "ask charles about chest", @@ -559,8 +603,8 @@ ], 135: "read plaque", 262: "read book", - } - + }, + "ztuu.z5": {} } @@ -572,12 +616,15 @@ def test_walkthrough(env, walkthrough): if not env.victory(): msg = "FAIL\tScore {}/{}".format(info["score"], env.get_max_score()) print(colored(msg, 'red')) + return False elif info["score"] != env.get_max_score(): msg = "FAIL\tDone but score {}/{}".format(info["score"], env.get_max_score()) print(colored(msg, 'yellow')) + return False else: msg = "PASS\tScore {}/{}".format(info["score"], env.get_max_score()) print(colored(msg, 'green')) + return True def parse_args(): @@ -740,16 +787,24 @@ def parse_args(): print(colored(f"{o1}\n{o2}", "red")) print(f"Testing walkthrough without '{cmd}'...") - test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) + alt1 = test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) print(f"Testing walkthrough replacing '{cmd}' with 'wait'...") - test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) - print(f"Testing walkthrough replacing '{cmd}' with '0'...") - test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) - print(f"Testing walkthrough replacing '{cmd}' with 'wait 1 minute'...") - test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) + alt2 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) + # print(f"Testing walkthrough replacing '{cmd}' with '0'...") + # test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) + # print(f"Testing walkthrough replacing '{cmd}' with 'wait 1 minute'...") + # test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) print(f"Testing walkthrough replacing '{cmd}' with 'look'...") - test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) + alt3 = test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) + + # if alt1 or alt2 or alt3: + # print(f"$$$ {i}: \"{cmd}\"") + # else: + # breakpoint() + # pass + breakpoint() + # else: # world_diff = env._get_world_diff() # if len(world_diff[-1]) > 1: From c1aba4ff7f6846336b1c379b9630eaedfbbc4a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 26 Nov 2021 14:06:08 -0500 Subject: [PATCH 37/85] FIX: step -> jericho_step to avoid name clashing with regexp.c:step function; ENH: filter_candidate_actions relies on state hashes instead world_diff. --- frotz/Makefile | 3 +- frotz/src/interface/frotz_interface.c | 126 ++++---------------------- frotz/src/interface/frotz_interface.h | 5 +- jericho/jericho.py | 16 ++-- tests/bench_valid_actions.py | 103 +++------------------ 5 files changed, 41 insertions(+), 212 deletions(-) diff --git a/frotz/Makefile b/frotz/Makefile index ef406755..b38b2b72 100644 --- a/frotz/Makefile +++ b/frotz/Makefile @@ -21,7 +21,8 @@ CFLAGS += -w # OPTS = -O3 -fomit-frame-pointer -falign-functions=2 -falign-loops=2 -falign-jumps=2 -fPIC OPTS = -O3 -fPIC # These are handy for debugging. -# OPTS = $(CFLAGS) -g -fPIC +# OPTS = $(CFLAGS) -O3 -g -fPIC # With optimization (faster code) +# OPTS = $(CFLAGS) -g -fPIC # Without optimization (slower code) # These are handy for profiling # OPTS = $(CFLAGS) -pg -fPIC diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index 4fa2b231..afa1a7c5 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -92,8 +92,6 @@ zobject* new_objs = NULL; int ram_diff_cnt; zword ram_diff_addr[16]; zword ram_diff_value[16]; -//char last_state_hash[64]; -//char current_state_hash[64]; bool state_has_changed = FALSE; @@ -187,7 +185,7 @@ enum SUPPORTED { // Set ROM_IDX according to the story_file. void load_rom_bindings(char *story_file) { - char md5_hash[64]; + char md5_hash[32]; char *start; FILE * f = fopen (story_file, "r"); @@ -333,6 +331,14 @@ void shutdown() { free(special_ram_values); special_ram_values = NULL; } + if (new_objs != NULL) { + free(new_objs); + new_objs = NULL; + } + if (old_objs != NULL) { + free(old_objs); + old_objs = NULL; + } } // Save the state of the game into a string buffer @@ -1568,10 +1574,6 @@ char* setup(char *story_file, int seed, void *rom, size_t rom_size) { run_free(); } - // Initialize last and current state hashes. - // get_world_state_hash(last_state_hash); - // get_world_state_hash(current_state_hash); - // Concatenate upper and lower screens. strcat(world, dumb_get_lower_screen()); strcat(world, dumb_get_upper_screen()); @@ -1583,24 +1585,16 @@ char* setup(char *story_file, int seed, void *rom, size_t rom_size) { return world; } -char* step(char *next_action) { - char* text; - char last_state_hash[64]; - char current_state_hash[64]; - +char* jericho_step(char *next_action) { if (emulator_halted > 0) return halted_message; - // get_world_state_hash(last_state_hash); - // Swap old_objs and new_objs. zobject* tmp; tmp = old_objs; old_objs = new_objs; new_objs = tmp; - // printf("%x, %x\n", old_objs, new_objs); - // Clear the object, attr, and ram diffs move_diff_cnt = 0; attr_diff_cnt = 0; @@ -1617,20 +1611,7 @@ char* step(char *next_action) { // Check for changes to special ram update_ram_diff(); - //get_world_state_hash(current_state_hash); - update_objs_tracker(); - // // memset(new_objs, 0, (get_num_world_objs() + 1) * sizeof(zobject)); - // get_world_objects(new_objs, TRUE); - - // // For a more robust state hash, do not include siblings and children - // // since their ordering in memory may change. - // for (int i=1; i<=get_num_world_objs(); ++i) { - // new_objs[i].sibling = 0; - // new_objs[i].child = 0; - // } - - //state_has_changed = strcmp(current_state_hash, last_state_hash) != 0; state_has_changed = memcmp(old_objs, new_objs, (get_num_world_objs() + 1) * sizeof(zobject)) != 0; // printf("%s =(%d)= %s <== %s", current_state_hash, state_has_changed, last_state_hash, next_action); @@ -1715,33 +1696,7 @@ char* get_current_state() { // Returns 1 if the last action changed the state of the world. int world_changed() { int objs_has_changed = state_has_changed; - //return state_has_changed; - - // int i; - // for (i=0; i 0 || victory() > 0) { return 1; } @@ -1766,10 +1721,6 @@ void get_object(zobject *obj, zword obj_num) { zbyte length; LOW_BYTE(obj_name_addr, length); - // if (length <= 0 || length > 64) { - // return; - // } - (*obj).num = obj_num; if (length > 0 && length <= 64) { @@ -1985,7 +1936,6 @@ void get_world_state_hash(char* md5_hash) { int n_objs = get_num_world_objs() + 1; // Add extra spot for zero'th object size_t objs_size = n_objs * sizeof(zobject); - zobject* objs = calloc(n_objs, sizeof(zobject)); size_t ram_size = get_special_ram_size() * sizeof(unsigned char); unsigned char* ram = malloc(ram_size); @@ -1993,46 +1943,19 @@ void get_world_state_hash(char* md5_hash) { int retPC = getRetPC(); - get_world_objects(objs, TRUE); - - // For a more robust state hash, do not include siblings and children - // since their ordering in memory may change. - for (int i=1; i<=get_num_world_objs(); ++i) { - objs[i].sibling = 0; - objs[i].child = 0; - } - - // Debug print. - // printf("\n--Start-\n"); - // for (int k=0; k != n_objs; ++k) { - // print_object2(&objs[k]); - // } - // printf("\n--End-\n"); - - // char temp_md5_hash[64]; - // FILE* tmp_fp = fmemopen(objs, objs_size, "rb"); - // sum(tmp_fp, temp_md5_hash); - // fclose(tmp_fp); - // printf("temp_md5_hash: %s", temp_md5_hash); - size_t state_size = objs_size + ram_size + sizeof(int); char* state = malloc(state_size); - memcpy(state, objs, objs_size); + memcpy(state, new_objs, objs_size); memcpy(&state[objs_size], ram, ram_size); memcpy(&state[objs_size+ram_size], &retPC, sizeof(int)); - // int chk = checksum(state, state_size); - // sprintf(md5_hash, "%2X", chk); - FILE* fp = fmemopen(state, state_size, "rb"); sum(fp, md5_hash); fclose(fp); // printf("md5 (objs): %s\n", md5_hash); - free(objs); free(state); - return 0; } // Teleports an object (and all children) to the desired destination @@ -2063,9 +1986,10 @@ void test() { // candidate_actions contains a string with all the candidate actions, seperated by ';' // valid_actions will be written with each of the identified valid actions seperated by ';' // diff_array will be written with the world_diff for each valid_action indicating -// which of the valid actions are equivalent to each other in terms of their world diffs. +// which of the valid actions are equivalent to each other in terms of their state hashes. // Returns the number of valid actions found. -int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword *diff_array) { +int filter_candidate_actions(char *candidate_actions, char *valid_actions, char *hashes) { + char *act = NULL; char *act_newline = NULL; char *text; @@ -2106,22 +2030,7 @@ int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword act_newline = malloc(strlen(act) + 2); strcpy(act_newline, act); strcat(act_newline, "\n"); - - // Step: Code is copied due to inexplicable segfault when calling step() directly; Ugh! - move_diff_cnt = 0; - attr_diff_cnt = 0; - attr_clr_cnt = 0; - prop_put_cnt = 0; - ram_diff_cnt = 0; - update_special_ram(); - dumb_set_next_action(act_newline); - zstep(); - run_free(); - update_ram_diff(); - text = dumb_get_screen(); - text = clean_observation(text); - strcpy(world, text); - dumb_clear_screen(); + text = jericho_step(act_newline); if (emulator_halted > 0) { printf("Emulator halted on action: %s\n", act); @@ -2137,7 +2046,7 @@ int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword valid_actions[v_idx++] = ';'; // Write the world diff resulting from the last action. - get_cleaned_world_diff(&diff_array[128*valid_cnt], &diff_array[(128*valid_cnt) + 64]); // TODO: replace 128 + get_world_state_hash(&hashes[32*valid_cnt]); valid_cnt++; } } @@ -2151,6 +2060,7 @@ int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword setFP(fp_cpy); set_opcode(next_opcode_cpy); setFrameCount(frame_count_cpy); + update_objs_tracker(); act = strtok(NULL, ";"); free(act_newline); diff --git a/frotz/src/interface/frotz_interface.h b/frotz/src/interface/frotz_interface.h index 5160f27a..b4894ede 100644 --- a/frotz/src/interface/frotz_interface.h +++ b/frotz/src/interface/frotz_interface.h @@ -39,7 +39,7 @@ extern char* setup(char *story_file, int seed, void* rom, size_t rom_size); extern void shutdown(); -extern char* step(char *next_action); +extern char* jericho_step(char *next_action); extern int save(char *filename); @@ -51,7 +51,8 @@ extern int getRAMSize(); extern void getRAM(unsigned char *ram); -int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword *diff_array); +// int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword *diff_array); +int filter_candidate_actions(char *candidate_actions, char *valid_actions, char *hashes); extern char world[256 + 8192]; diff --git a/jericho/jericho.py b/jericho/jericho.py index 6480cc8c..f8a95b73 100644 --- a/jericho/jericho.py +++ b/jericho/jericho.py @@ -241,8 +241,8 @@ def _load_frotz_lib(): frotz_lib.setup.restype = c_char_p frotz_lib.shutdown.argtypes = [] frotz_lib.shutdown.restype = None - frotz_lib.step.argtypes = [c_char_p] - frotz_lib.step.restype = c_char_p + frotz_lib.jericho_step.argtypes = [c_char_p] + frotz_lib.jericho_step.restype = c_char_p frotz_lib.save.argtypes = [c_char_p] frotz_lib.save.restype = int frotz_lib.restore.argtypes = [c_char_p] @@ -515,7 +515,7 @@ def step(self, action): warnings.warn(msg, TruncatedInputActionWarning) old_score = self.frotz_lib.get_score() - next_state = self.frotz_lib.step(action_bytes + b'\n').decode('cp1252') + next_state = self.frotz_lib.jericho_step(action_bytes + b'\n').decode('cp1252') score = self.frotz_lib.get_score() reward = score - old_score return next_state, reward, (self.game_over() or self.victory()),\ @@ -782,7 +782,7 @@ def get_world_state_hash(self): '79c750fff4368efef349b02ff50ffc23' """ - md5_hash = np.zeros(64, dtype=np.uint8) + md5_hash = np.zeros(32, dtype=np.uint8) self.frotz_lib.get_world_state_hash(as_ctypes(md5_hash)) md5_hash = (b"").join(md5_hash.view(c_char)).decode('cp1252') return md5_hash @@ -1051,20 +1051,18 @@ def _filter_candidate_actions(self, candidate_actions, use_ctypes=False, use_par candidate_str = (";".join(candidate_actions)).encode('utf-8') valid_str = (' '*(len(candidate_str)+1)).encode('utf-8') - DIFF_SIZE = 128 - diff_array = np.zeros(len(candidate_actions) * DIFF_SIZE, dtype=np.uint16) + hashes = np.zeros(len(candidate_actions), dtype='S32') valid_cnt = self.frotz_lib.filter_candidate_actions( candidate_str, valid_str, - as_ctypes(diff_array) + as_ctypes(hashes.view(np.uint8)) ) if self._emulator_halted(): self.reset() valid_acts = valid_str.decode('cp1252').strip().split(';')[:-1] for i in range(valid_cnt): - diff = tuple(diff_array[i*DIFF_SIZE:(i+1)*DIFF_SIZE]) - diff2acts[diff].append(valid_acts[i]) + diff2acts[hashes[i]].append(valid_acts[i]) else: orig_score = self.get_score() diff --git a/tests/bench_valid_actions.py b/tests/bench_valid_actions.py index 3da2ac81..1bbb74a2 100644 --- a/tests/bench_valid_actions.py +++ b/tests/bench_valid_actions.py @@ -8,13 +8,14 @@ import jericho -def run(rom, use_ctypes=False, use_parallel=False): +def run(rom, args, use_ctypes=False, use_parallel=False): env = jericho.FrotzEnv(rom) walkthrough = env.get_walkthrough() start = time.time() valid_per_step = [] - for act in tqdm(walkthrough[:5]): + limit = args.limit or len(walkthrough) + for act in tqdm(walkthrough[:limit]): valid_acts = env.get_valid_actions(use_ctypes=use_ctypes, use_parallel=use_parallel) valid_per_step.append(valid_acts) @@ -23,10 +24,10 @@ def run(rom, use_ctypes=False, use_parallel=False): return elapsed, valid_per_step -def compare(rom): - t1, gt_valids = run(rom) - t2, pred_valids_c = run(rom, use_ctypes=True) - t3, pred_valids_para = run(rom, use_parallel=True) +def compare(rom, args): + t1, gt_valids = run(rom, args) + t2, pred_valids_c = run(rom, args, use_ctypes=True) + t3, pred_valids_para = run(rom, args, use_parallel=True) assert len(gt_valids) == len(pred_valids_c) assert len(gt_valids) == len(pred_valids_para) @@ -52,102 +53,20 @@ def compare(rom): print(f"Rom {rom} Python {t1:.1f} Para {t3:.1f} Speedup {speedup:.1f}%") -KNOWN_MISSING_ACTIONS = { - "zork1.z5": {56: "read book", 214: "read label", 262: "kill thief with nasty knife", 387: "look", 389: "examine map"} -} - - -def check_correctness(rom, skip_to=0, verbose=False): - env = jericho.FrotzEnv(rom) - env_ = jericho.FrotzEnv(rom) - - walkthrough = env.get_walkthrough() - env.act_gen.templates - - # Display info about action templates for the game. - nargs_templates = {0: [], 1: [], 2: []} - for template in env.act_gen.templates: - nargs_templates[template.count("OBJ")].append(template) - - print("-= Template categories =-") - print(f" {len(env.act_gen.templates)} templates. 0-arg: {len(nargs_templates[0])}, 1-arg: {len(nargs_templates[1])}, 2-arg: {len(nargs_templates[2])}.") - if verbose: - print(f" 0-arg ({len(nargs_templates[0])}): {sorted(nargs_templates[0])}") - print(f" 1-arg ({len(nargs_templates[1])}): {sorted(nargs_templates[1])}") - print(f" 2-arg ({len(nargs_templates[2])}): {sorted(nargs_templates[2])}") - - start = time.time() - - obs, info = env.reset() - valid_acts = env.get_valid_actions() - - # class CaptureStdoutForTdqm: - # def __init__(): - - with tqdm(total=len(walkthrough)) as pbar: - pbar.set_description(rom) - - for idx, act in enumerate(walkthrough): - - last_state = env.get_state() - - obs, rew, done, info = env.step(act) - print(idx, act, info, env.get_world_state_hash()) - if idx < skip_to: - if idx == skip_to - 1: - breakpoint() - valid_acts = env.get_valid_actions() - - pbar.update(1) - continue - - found_matching_command = False - equivalent_commands = [] - for cmd in valid_acts: - env_.set_state(last_state) - env_.step(cmd) - if env_.get_world_state_hash() == env.get_world_state_hash(): - equivalent_commands.append(cmd) - found_matching_command = True - - if found_matching_command: - pbar.write(f"{idx:02d}. [{colored(act, 'green')}] found in [{', '.join([colored(a, 'green' if a in equivalent_commands else 'white') for a in valid_acts])}]") - else: - pbar.write(f"{idx:02d}. [{colored(act, 'red')}] not found in {valid_acts}") - if act != KNOWN_MISSING_ACTIONS.get(env.story_file, {}).get(idx): - print(colored("Unexpected missing action!!!", 'red')) - # breakpoint() - - valid_acts = env.get_valid_actions() - pbar.update(1) - - elapsed = time.time() - start - print(f"{elapsed:.1f} secs. Score: {info['score']} (Done: {done})") - env.close() - return elapsed - - def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("filenames", help="Path to a Z-Machine game.", nargs="+") - parser.add_argument("--skip-to", type=int, default=0, - help="Auto-play walkthrough until the nth command before dropping into interactive mode.") + parser.add_argument("--limit", metavar="K", type=int, + help="Stop comparison after the first K commands.") return parser.parse_args() + if __name__ == "__main__": args = parse_args() for rom in args.filenames: print(f"\n-=# {rom} #=-") - check_correctness(rom, args.skip_to) - - # compare(rom) - # t2, pred_valids_c = run(rom, use_ctypes=True) - # t3, pred_valids_para = run(rom, use_parallel=True) - - # t2, pred_valids_para = run(rom, use_ctypes=True) - # t3, pred_valids_para = run(rom, use_parallel=True) - + compare(rom, args) From 89d5fc336f0551488cc1c50b4b9083ba4ecbc9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 16 Dec 2021 10:00:21 -0500 Subject: [PATCH 38/85] Tidy up the PR --- frotz/Makefile | 4 +- frotz/src/common/frotz.h | 30 +- frotz/src/common/object.c | 50 ---- frotz/src/interface/frotz_interface.c | 399 ++++++++------------------ frotz/src/interface/frotz_interface.h | 3 +- frotz/src/interface/md5.c | 129 +++++---- frotz/src/ztools/infodump.c | 11 - jericho/jericho.py | 126 +++----- jericho/util.py | 92 ------ tools/test_games.py | 32 --- 10 files changed, 222 insertions(+), 654 deletions(-) diff --git a/frotz/Makefile b/frotz/Makefile index b38b2b72..2cc20d32 100644 --- a/frotz/Makefile +++ b/frotz/Makefile @@ -11,8 +11,8 @@ RANLIB = /usr/bin/ranlib CC ?= gcc # Enable compiler warnings. This is an absolute minimum. -#CFLAGS += -Wall -Wextra -std=gnu99 -fPIC -Werror=implicit-function-declaration -CFLAGS += -w +CFLAGS += -Wall -Wextra -std=gnu99 -fPIC -Werror=implicit-function-declaration +CFLAGS = -w # Define your optimization flags. # diff --git a/frotz/src/common/frotz.h b/frotz/src/common/frotz.h index f32c49e2..36da3508 100644 --- a/frotz/src/common/frotz.h +++ b/frotz/src/common/frotz.h @@ -550,32 +550,6 @@ extern char *option_zcode_path; /* dg */ extern long reserve_mem; - -#define MOVE_DIFF_CNT 16 -#define ATTR_SET_CNT 16 -#define ATTR_CLR_CNT 16 -#define PROP_PUT_CNT 64 - -// Keep track of the last n=16 changes to object tree -extern int move_diff_cnt; -extern zword move_diff_objs[MOVE_DIFF_CNT]; -extern zword move_diff_dest[MOVE_DIFF_CNT]; - -// Keep track of the last n=16 changes to obj attributes -extern int attr_diff_cnt; -extern zword attr_diff_objs[ATTR_SET_CNT]; -extern zword attr_diff_nb[ATTR_SET_CNT]; - -// Keep track of the last n=16 clears of obj attributes -extern int attr_clr_cnt; -extern zword attr_clr_objs[ATTR_CLR_CNT]; -extern zword attr_clr_nb[ATTR_CLR_CNT]; - -// Keep track of the last n=32 changes to obj properties -extern int prop_put_cnt; -extern zword prop_put_objs[PROP_PUT_CNT]; -extern zword prop_put_nb[PROP_PUT_CNT]; - // Keep track of up to n=16 changes to special ram locations defined by the game extern int ram_diff_cnt; extern zword ram_diff_addr[16]; @@ -703,7 +677,7 @@ void z_window_style (void); void init_err (void); void runtime_error (int); - + /* Error codes */ #define ERR_TEXT_BUF_OVF 1 /* Text buffer overflow */ #define ERR_STORE_RANGE 2 /* Store out of dynamic memory */ @@ -741,7 +715,7 @@ void runtime_error (int); #define ERR_REMOVE_OBJECT_0 31 /* @remove_object called with object 0 */ #define ERR_GET_NEXT_PROP_0 32 /* @get_next_prop called with object 0 */ #define ERR_NUM_ERRORS (32) - + /* There are four error reporting modes: never report errors; report only the first time a given error type occurs; report every time an error occurs; or treat all errors as fatal diff --git a/frotz/src/common/object.c b/frotz/src/common/object.c index 75afb023..f33fdac9 100644 --- a/frotz/src/common/object.c +++ b/frotz/src/common/object.c @@ -34,19 +34,6 @@ #define O4_PROPERTY_OFFSET 12 #define O4_SIZE 14 -int move_diff_cnt; -zword move_diff_objs[MOVE_DIFF_CNT]; -zword move_diff_dest[MOVE_DIFF_CNT]; -int attr_diff_cnt; -zword attr_diff_objs[ATTR_SET_CNT]; -zword attr_diff_nb[ATTR_SET_CNT]; -int attr_clr_cnt; -zword attr_clr_objs[ATTR_CLR_CNT]; -zword attr_clr_nb[ATTR_CLR_CNT]; -int prop_put_cnt; -zword prop_put_objs[PROP_PUT_CNT]; -zword prop_put_nb[PROP_PUT_CNT]; - /* * object_address * @@ -454,14 +441,6 @@ void z_clear_attr (void) if (zargs[1] > ((h_version <= V3) ? 31 : 47)) runtime_error (ERR_ILL_ATTR); - /* If we are monitoring attribute assignment display a short note */ - - if (attr_clr_cnt < ATTR_CLR_CNT) { - attr_clr_objs[attr_clr_cnt] = zargs[0]; - attr_clr_nb[attr_clr_cnt] = zargs[1]; - attr_clr_cnt++; - } - if (f_setup.attribute_assignment) { stream_mssg_on (); print_string ("@clear_attr "); @@ -1066,14 +1045,6 @@ void z_insert_obj (void) zword obj1_addr; zword obj2_addr; - /* If we are monitoring object movements display a short note */ - - if (move_diff_cnt < MOVE_DIFF_CNT) { - move_diff_objs[move_diff_cnt] = obj1; - move_diff_dest[move_diff_cnt] = obj2; - move_diff_cnt++; - } - if (f_setup.object_movement) { stream_mssg_on (); print_string ("@move_obj "); @@ -1186,12 +1157,6 @@ void z_put_prop (void) SET_WORD (prop_addr, v) } - if (prop_put_cnt < PROP_PUT_CNT) { - prop_put_objs[prop_put_cnt] = zargs[0]; - prop_put_nb[prop_put_cnt] = zargs[1]; - prop_put_cnt++; - } - }/* z_put_prop */ @@ -1204,13 +1169,6 @@ void z_put_prop (void) void z_remove_obj (void) { - /* If we are monitoring object movements display a short note */ - if (move_diff_cnt < 16) { - move_diff_objs[move_diff_cnt] = zargs[0]; - move_diff_dest[move_diff_cnt] = (zword) 0; - move_diff_cnt++; - } - if (f_setup.object_movement) { stream_mssg_on (); print_string ("@remove_obj "); @@ -1244,14 +1202,6 @@ void z_set_attr (void) if (zargs[1] > ((h_version <= V3) ? 31 : 47)) runtime_error (ERR_ILL_ATTR); - /* If we are monitoring attribute assignment display a short note */ - - if (attr_diff_cnt < ATTR_SET_CNT) { - attr_diff_objs[attr_diff_cnt] = zargs[0]; - attr_diff_nb[attr_diff_cnt] = zargs[1]; - attr_diff_cnt++; - } - if (f_setup.attribute_assignment) { stream_mssg_on (); print_string ("@set_attr "); diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index afa1a7c5..36be2521 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -59,7 +59,7 @@ extern void insert_tree(zword obj1, zword obj2); extern void insert_obj(zword obj1, zword obj2); extern void seed_random (int value); extern void set_random_seed (int seed); -// extern void sum(FILE*, char*); +extern void sum(FILE*, char*); extern void dumb_free(); extern zword first_property (zword); @@ -81,18 +81,17 @@ char world[256 + 8192] = ""; // Upper + lower screens. int emulator_halted = 0; char halted_message[] = "Emulator halted due to runtime error.\n"; -// Track the addresses and values of special per-game ram locations. -int num_special_addrs = 0; -zword *special_ram_addrs = NULL; -zbyte *special_ram_values = NULL; -zobject* old_objs = NULL; -zobject* new_objs = NULL; +// Track the objects. +zobject* prev_objs_state = NULL; +zobject* curr_objs_state = NULL; -int ram_diff_cnt; -zword ram_diff_addr[16]; -zword ram_diff_value[16]; -bool state_has_changed = FALSE; +// Track the value of special per-game ram locations. +zbyte* prev_special_ram = NULL; +zbyte* curr_special_ram = NULL; + +bool objects_state_changed = FALSE; +bool special_ram_changed = FALSE; // Runs a single opcode on the Z-Machine @@ -327,18 +326,11 @@ void shutdown() { reset_memory(); dumb_free(); free_setup(); - if (special_ram_values != NULL) { - free(special_ram_values); - special_ram_values = NULL; - } - if (new_objs != NULL) { - free(new_objs); - new_objs = NULL; - } - if (old_objs != NULL) { - free(old_objs); - old_objs = NULL; - } + + free(prev_objs_state); prev_objs_state = NULL; + free(curr_objs_state); curr_objs_state = NULL; + free(prev_special_ram); prev_special_ram = NULL; + free(curr_special_ram); curr_special_ram = NULL; } // Save the state of the game into a string buffer @@ -1408,18 +1400,6 @@ int halted() { return emulator_halted; } -int ignore_moved_obj(zword obj_num, zword dest_num) { - return (*ignore_moved_obj_fns[ROM_IDX])(obj_num, dest_num); -} - -int ignore_attr_diff(zword obj_num, zword dest_num) { - return (*ignore_attr_diff_fns[ROM_IDX])(obj_num, dest_num); -} - -int ignore_attr_clr(zword obj_num, zword dest_num) { - return (*ignore_attr_clr_fns[ROM_IDX])(obj_num, dest_num); -} - void clean_world_objs(zobject* objs) { return (*clean_world_objs_fns[ROM_IDX])(objs); } @@ -1450,70 +1430,67 @@ void take_intro_actions() { // Returns the number of special ram addresses int get_special_ram_size() { + int num_special_addrs; + get_ram_addrs(&num_special_addrs); return num_special_addrs; } // Returns the current values of the special ram addresses -void get_special_ram(unsigned char *ram) { - int i; - for (i=0; i 0) { - special_ram_values = (zbyte*) malloc(num_special_addrs * sizeof(zbyte)); - } - - // Init objs. - if (old_objs != NULL) free(old_objs); - if (new_objs != NULL) free(new_objs); - - old_objs = calloc(get_num_world_objs() + 1, sizeof(zobject)); - new_objs = calloc(get_num_world_objs() + 1, sizeof(zobject)); -} +// Create memory used to hold the special ram values. +void init_special_ram_tracker() { + free(prev_special_ram); prev_special_ram = NULL; + free(curr_special_ram); curr_special_ram = NULL; + prev_special_ram = malloc(get_special_ram_size() * sizeof(zbyte)); + curr_special_ram = malloc(get_special_ram_size() * sizeof(zbyte)); +} + +// Create memory used to hold the objects' state. +void init_objects_tracker() { + free(prev_objs_state); prev_objs_state = NULL; + free(curr_objs_state); curr_objs_state = NULL; + prev_objs_state = calloc(get_num_world_objs() + 1, sizeof(zobject)); + curr_objs_state = calloc(get_num_world_objs() + 1, sizeof(zobject)); +} + +// // Records changes to the special ram addresses and updates their values. +// void update_ram_diff() { +// int i; +// zbyte curr_ram_value; +// zword addr; +// for (i=0; i 0) return halted_message; - // Swap old_objs and new_objs. - zobject* tmp; - tmp = old_objs; - old_objs = new_objs; - new_objs = tmp; + // Swap prev_objs_state and curr_objs_state. + zobject* tmp_objs_state; + tmp_objs_state = prev_objs_state; + prev_objs_state = curr_objs_state; + curr_objs_state = tmp_objs_state; + + // Swap prev_special_ram and curr_special_ram. + zword* tmp_special_ram; + tmp_special_ram = prev_special_ram; + prev_special_ram = curr_special_ram; + curr_special_ram = tmp_special_ram; // Clear the object, attr, and ram diffs - move_diff_cnt = 0; - attr_diff_cnt = 0; - attr_clr_cnt = 0; - prop_put_cnt = 0; - ram_diff_cnt = 0; - update_special_ram(); + // ram_diff_cnt = 0; + //update_special_ram(); last_ret_pc = getRetPC(); dumb_set_next_action(next_action); @@ -1610,10 +1590,12 @@ char* jericho_step(char *next_action) { run_free(); // Check for changes to special ram - update_ram_diff(); + //update_ram_diff(); update_objs_tracker(); - state_has_changed = memcmp(old_objs, new_objs, (get_num_world_objs() + 1) * sizeof(zobject)) != 0; - // printf("%s =(%d)= %s <== %s", current_state_hash, state_has_changed, last_state_hash, next_action); + update_special_ram_tracker(); + + objects_state_changed = memcmp(prev_objs_state, curr_objs_state, (get_num_world_objs() + 1) * sizeof(zobject)) != 0; + special_ram_changed = memcmp(prev_special_ram, curr_special_ram, get_special_ram_size() * sizeof(zword)) != 0; // Retrieve and concatenate upper and lower screens. strcpy(world, dumb_get_lower_screen()); @@ -1633,60 +1615,20 @@ void set_narrative_text(char* text) { strcpy(world, text); } -bool get_state_changed() { - return state_has_changed; +bool get_objects_state_changed() { + return objects_state_changed; } -void set_state_changed(bool value) { - state_has_changed = value; +void set_objects_state_changed(bool value) { + objects_state_changed = value; } -// Returns a world diff that ignores selected objects -// objs and dest are a 64-length pre-zeroed arrays. -void get_cleaned_world_diff(zword *objs, zword *dest) { - int i; - int j = 0; - for (i=0; i 0 || victory() > 0) { return 1; } - if (ram_diff_cnt > 0) { - return 1; - } + // if (ram_diff_cnt > 0) { + // return 1; + // } - return objs_has_changed || last_ret_pc != getRetPC(); + return objects_state_changed || special_ram_changed || last_ret_pc != getRetPC(); } @@ -1735,7 +1675,6 @@ void get_object(zobject *obj, zword obj_num) { free(buf); } - (*obj).parent = get_parent(obj_num); (*obj).sibling = get_sibling(obj_num); (*obj).child = get_child(obj_num); @@ -1831,7 +1770,10 @@ void get_world_objects(zobject *objs, int clean) { (byte & 0x02 ? '1' : '0'), \ (byte & 0x01 ? '1' : '0') -void print_object2(zobject* obj) { +// Print all information related to a given object. +// Useful for debugging. +void print_zobject(zobject* obj) { + // printf("Obj%d: %s Parent%d Sibling%d Child%d", obj->num, obj->name, obj->parent, obj->sibling, obj->child); printf(" Attributes ["); @@ -1846,114 +1788,27 @@ void print_object2(zobject* obj) { } printf("]\n"); - - - //printf("Obj%d: %s Parent%d Sibling%d Child%d Attributes %s Properties %s\n", obj->num, obj->name, obj->parent, obj->sibling, obj->child, obj->attr, obj->properties); - // ""\ - // .format(self.num, self.name, self.parent, self.sibling, self.child, - // np.nonzero(self.attr)[0].tolist(), [p for p in self.properties if p != 0]) - - // typedef struct { - // unsigned int num; - // char name[64]; - // int parent; - // int sibling; - // int child; - // char attr[4]; - // unsigned char properties[16]; - // } - } - - -int checksum(char* str, int len) { - int i; - int chk = 0x12345678; - - for (i = 0; i != len; i++) { - chk += ((int)(str[i]) * (i + 1)); } - return chk; -} - void get_world_state_hash(char* md5_hash) { - // zobject* obj = calloc(1, sizeof(zobject)); - - // byte digest[16]; - // byte *buf = calloc(1152, 1); - // // byte digest[16]; - // // int i, n; - // MD5state *s = nil; - - // for (int i=1; i<=get_num_world_objs(); ++i) { - // get_object(obj, (zword) i); - // // TODO: call clean_obj function. - // obj->sibling = 0; - // obj->child = 0; - - // //memcpy(buf, obj, sizeof(zobject)); - // s = md5(buf, 1152, 0, s); - // } - // return 0; - - // s = md5(buf, 0, digest, s); - - // for(int j=0;j<16;j++) { - // sprintf(&md5_hash[2*j], "%.2X", digest[j]); - // } - //printf("md5 (obj ): %s\n", md5_hash); - - // for(i=0;i<16;i++) { - // sprintf(&md5_hash[2*i], "%.2X", digest[i]); - // } - - // // Compute MD5 hash. - // s = nil; - // n = 0; - - // //buf = calloc(256,64); - // for (size_t i; i <= sizeof(zobject); i += 128*64) { - // //i = fread(buf+n, 1, 128*64-n, fd); - // if(i <= 0) - // break; - // n += i; - // if(n & 0x3f) - // continue; - // s = md5(buf, n, 0, s); - // n = 0; - // } - // md5(buf, n, digest, s); - // for(i=0;i<16;i++) { - // sprintf(&hash[2*i], "%.2X", digest[i]); - // } - // free(buf); - - // free(buf); - // free(obj); - // return 0; - - //// - int n_objs = get_num_world_objs() + 1; // Add extra spot for zero'th object size_t objs_size = n_objs * sizeof(zobject); - size_t ram_size = get_special_ram_size() * sizeof(unsigned char); - unsigned char* ram = malloc(ram_size); - get_special_ram(ram); int retPC = getRetPC(); size_t state_size = objs_size + ram_size + sizeof(int); char* state = malloc(state_size); - memcpy(state, new_objs, objs_size); - memcpy(&state[objs_size], ram, ram_size); + + memcpy(state, curr_objs_state, objs_size); + memcpy(&state[objs_size], curr_special_ram, ram_size); memcpy(&state[objs_size+ram_size], &retPC, sizeof(int)); FILE* fp = fmemopen(state, state_size, "rb"); sum(fp, md5_hash); fclose(fp); - // printf("md5 (objs): %s\n", md5_hash); + // printf("md5 (objs): %s\n", md5_hash); // For debugging. free(state); } @@ -1969,23 +1824,10 @@ void teleport_tree(zword obj, zword dest) { insert_tree(obj, dest); } -void test() { - int i; - for (i=0; i %d\n", i, move_diff_objs[i], move_diff_dest[i]); - } - for (i=0; i %d\n", i, attr_diff_objs[i], attr_diff_nb[i]); - } - for (i=0; i %d\n", i, attr_clr_objs[i], attr_clr_nb[i]); - } -} - // Given a list of action candidates, find the ones that lead to valid world changes. -// candidate_actions contains a string with all the candidate actions, seperated by ';' -// valid_actions will be written with each of the identified valid actions seperated by ';' -// diff_array will be written with the world_diff for each valid_action indicating +// 'candidate_actions' contains a string with all the candidate actions, seperated by ';' +// 'valid_actions' will be written with each of the identified valid actions seperated by ';' +// 'hashes' will be written with the resulting state hashe for each valid action indicating // which of the valid actions are equivalent to each other in terms of their state hashes. // Returns the number of valid actions found. int filter_candidate_actions(char *candidate_actions, char *valid_actions, char *hashes) { @@ -1993,35 +1835,28 @@ int filter_candidate_actions(char *candidate_actions, char *valid_actions, char char *act = NULL; char *act_newline = NULL; char *text; - short orig_score; int valid_cnt = 0; int v_idx = 0; // Variables used to store & reset game state unsigned char ram_cpy[h_dynamic_size]; unsigned char stack_cpy[STACK_SIZE*sizeof(zword)]; - int pc_cpy; - int sp_cpy; - int fp_cpy; - int next_opcode_cpy; - int frame_count_cpy; - long rngA_cpy; - int rngInterval_cpy; - int rngCounter_cpy; // Save the game state getRAM(ram_cpy); getStack(stack_cpy); - pc_cpy = getPC(); - sp_cpy = getSP(); - fp_cpy = getFP(); - next_opcode_cpy = get_opcode(); - frame_count_cpy = getFrameCount(); - rngA_cpy = getRngA(); - rngInterval_cpy = getRngInterval(); - rngCounter_cpy = getRngCounter(); - - orig_score = get_score(); + int pc_cpy = getPC(); + int sp_cpy = getSP(); + int fp_cpy = getFP(); + int next_opcode_cpy = get_opcode(); + int frame_count_cpy = getFrameCount(); + long rngA_cpy = getRngA(); + int rngInterval_cpy = getRngInterval(); + int rngCounter_cpy = getRngCounter(); + bool objects_state_changed_cpy = get_objects_state_changed(); + bool special_ram_changed_cpy = get_special_ram_changed(); + + short orig_score = get_score(); act = strtok(candidate_actions, ";"); while (act != NULL) @@ -2061,9 +1896,13 @@ int filter_candidate_actions(char *candidate_actions, char *valid_actions, char set_opcode(next_opcode_cpy); setFrameCount(frame_count_cpy); update_objs_tracker(); + update_special_ram_tracker(); + set_objects_state_changed(objects_state_changed_cpy); + set_special_ram_changed(special_ram_changed_cpy); act = strtok(NULL, ";"); free(act_newline); } + return valid_cnt; } diff --git a/frotz/src/interface/frotz_interface.h b/frotz/src/interface/frotz_interface.h index b4894ede..50a914bc 100644 --- a/frotz/src/interface/frotz_interface.h +++ b/frotz/src/interface/frotz_interface.h @@ -51,10 +51,9 @@ extern int getRAMSize(); extern void getRAM(unsigned char *ram); -// int filter_candidate_actions(char *candidate_actions, char *valid_actions, zword *diff_array); int filter_candidate_actions(char *candidate_actions, char *valid_actions, char *hashes); -extern char world[256 + 8192]; +extern char world[256 + 8192]; // Upper + lower screens. extern int tw_max_score; diff --git a/frotz/src/interface/md5.c b/frotz/src/interface/md5.c index 8ddd64a2..97f7f010 100644 --- a/frotz/src/interface/md5.c +++ b/frotz/src/interface/md5.c @@ -1,6 +1,5 @@ #include #include -// #include #include "md5.h" extern int enc64(char*,byte*,int); @@ -68,76 +67,76 @@ typedef struct Table Table tab[] = { /* round 1 */ - { 0xd76aa478, 0, S11}, - { 0xe8c7b756, 1, S12}, - { 0x242070db, 2, S13}, - { 0xc1bdceee, 3, S14}, - { 0xf57c0faf, 4, S11}, - { 0x4787c62a, 5, S12}, - { 0xa8304613, 6, S13}, - { 0xfd469501, 7, S14}, - { 0x698098d8, 8, S11}, - { 0x8b44f7af, 9, S12}, - { 0xffff5bb1, 10, S13}, - { 0x895cd7be, 11, S14}, - { 0x6b901122, 12, S11}, - { 0xfd987193, 13, S12}, - { 0xa679438e, 14, S13}, + { 0xd76aa478, 0, S11}, + { 0xe8c7b756, 1, S12}, + { 0x242070db, 2, S13}, + { 0xc1bdceee, 3, S14}, + { 0xf57c0faf, 4, S11}, + { 0x4787c62a, 5, S12}, + { 0xa8304613, 6, S13}, + { 0xfd469501, 7, S14}, + { 0x698098d8, 8, S11}, + { 0x8b44f7af, 9, S12}, + { 0xffff5bb1, 10, S13}, + { 0x895cd7be, 11, S14}, + { 0x6b901122, 12, S11}, + { 0xfd987193, 13, S12}, + { 0xa679438e, 14, S13}, { 0x49b40821, 15, S14}, /* round 2 */ - { 0xf61e2562, 1, S21}, - { 0xc040b340, 6, S22}, - { 0x265e5a51, 11, S23}, - { 0xe9b6c7aa, 0, S24}, - { 0xd62f105d, 5, S21}, - { 0x2441453, 10, S22}, - { 0xd8a1e681, 15, S23}, - { 0xe7d3fbc8, 4, S24}, - { 0x21e1cde6, 9, S21}, - { 0xc33707d6, 14, S22}, - { 0xf4d50d87, 3, S23}, - { 0x455a14ed, 8, S24}, - { 0xa9e3e905, 13, S21}, - { 0xfcefa3f8, 2, S22}, - { 0x676f02d9, 7, S23}, + { 0xf61e2562, 1, S21}, + { 0xc040b340, 6, S22}, + { 0x265e5a51, 11, S23}, + { 0xe9b6c7aa, 0, S24}, + { 0xd62f105d, 5, S21}, + { 0x2441453, 10, S22}, + { 0xd8a1e681, 15, S23}, + { 0xe7d3fbc8, 4, S24}, + { 0x21e1cde6, 9, S21}, + { 0xc33707d6, 14, S22}, + { 0xf4d50d87, 3, S23}, + { 0x455a14ed, 8, S24}, + { 0xa9e3e905, 13, S21}, + { 0xfcefa3f8, 2, S22}, + { 0x676f02d9, 7, S23}, { 0x8d2a4c8a, 12, S24}, /* round 3 */ - { 0xfffa3942, 5, S31}, - { 0x8771f681, 8, S32}, - { 0x6d9d6122, 11, S33}, - { 0xfde5380c, 14, S34}, - { 0xa4beea44, 1, S31}, - { 0x4bdecfa9, 4, S32}, - { 0xf6bb4b60, 7, S33}, - { 0xbebfbc70, 10, S34}, - { 0x289b7ec6, 13, S31}, - { 0xeaa127fa, 0, S32}, - { 0xd4ef3085, 3, S33}, - { 0x4881d05, 6, S34}, - { 0xd9d4d039, 9, S31}, - { 0xe6db99e5, 12, S32}, - { 0x1fa27cf8, 15, S33}, - { 0xc4ac5665, 2, S34}, + { 0xfffa3942, 5, S31}, + { 0x8771f681, 8, S32}, + { 0x6d9d6122, 11, S33}, + { 0xfde5380c, 14, S34}, + { 0xa4beea44, 1, S31}, + { 0x4bdecfa9, 4, S32}, + { 0xf6bb4b60, 7, S33}, + { 0xbebfbc70, 10, S34}, + { 0x289b7ec6, 13, S31}, + { 0xeaa127fa, 0, S32}, + { 0xd4ef3085, 3, S33}, + { 0x4881d05, 6, S34}, + { 0xd9d4d039, 9, S31}, + { 0xe6db99e5, 12, S32}, + { 0x1fa27cf8, 15, S33}, + { 0xc4ac5665, 2, S34}, /* round 4 */ - { 0xf4292244, 0, S41}, - { 0x432aff97, 7, S42}, - { 0xab9423a7, 14, S43}, - { 0xfc93a039, 5, S44}, - { 0x655b59c3, 12, S41}, - { 0x8f0ccc92, 3, S42}, - { 0xffeff47d, 10, S43}, - { 0x85845dd1, 1, S44}, - { 0x6fa87e4f, 8, S41}, - { 0xfe2ce6e0, 15, S42}, - { 0xa3014314, 6, S43}, - { 0x4e0811a1, 13, S44}, - { 0xf7537e82, 4, S41}, - { 0xbd3af235, 11, S42}, - { 0x2ad7d2bb, 2, S43}, - { 0xeb86d391, 9, S44}, + { 0xf4292244, 0, S41}, + { 0x432aff97, 7, S42}, + { 0xab9423a7, 14, S43}, + { 0xfc93a039, 5, S44}, + { 0x655b59c3, 12, S41}, + { 0x8f0ccc92, 3, S42}, + { 0xffeff47d, 10, S43}, + { 0x85845dd1, 1, S44}, + { 0x6fa87e4f, 8, S41}, + { 0xfe2ce6e0, 15, S42}, + { 0xa3014314, 6, S43}, + { 0x4e0811a1, 13, S44}, + { 0xf7537e82, 4, S41}, + { 0xbd3af235, 11, S42}, + { 0x2ad7d2bb, 2, S43}, + { 0xeb86d391, 9, S44}, }; int debug; @@ -230,7 +229,7 @@ md5(byte *p, uint len, byte *digest, MD5state *s) d = s->state[3]; decode(x, p, 64); - + for(i = 0; i < 64; i++){ t = tab + i; switch(i>>4){ @@ -250,7 +249,7 @@ md5(byte *p, uint len, byte *digest, MD5state *s) a += x[t->x] + t->sin; a = (a << t->rot) | (a >> (32 - t->rot)); a += b; - + /* rotate variables */ tmp = d; d = c; diff --git a/frotz/src/ztools/infodump.c b/frotz/src/ztools/infodump.c index 56fca21f..2cbc1861 100644 --- a/frotz/src/ztools/infodump.c +++ b/frotz/src/ztools/infodump.c @@ -256,17 +256,6 @@ void print_verbs (const char *name) load_cache (); fix_dictionary (); show_verbs (0); - show_objects (0); - show_header(); - close_story (); -} - -void print_action_table (const char *name) -{ - open_story (name); - configure (V1, V8); - load_cache (); - fix_dictionary (); close_story (); } diff --git a/jericho/jericho.py b/jericho/jericho.py index f8a95b73..c2fe84ed 100644 --- a/jericho/jericho.py +++ b/jericho/jericho.py @@ -271,8 +271,6 @@ def _load_frotz_lib(): frotz_lib.get_world_state_hash.argtypes = [] frotz_lib.get_world_state_hash.restype = int - frotz_lib.get_cleaned_world_diff.argtypes = [c_void_p, c_void_p] - frotz_lib.get_cleaned_world_diff.restype = None frotz_lib.game_over.argtypes = [] frotz_lib.game_over.restype = int frotz_lib.victory.argtypes = [] @@ -298,10 +296,15 @@ def _load_frotz_lib(): frotz_lib.set_narrative_text.argtypes = [c_char_p] frotz_lib.set_narrative_text.restype = None - frotz_lib.get_state_changed.argtypes = [] - frotz_lib.get_state_changed.restype = int - frotz_lib.set_state_changed.argtypes = [c_int] - frotz_lib.set_state_changed.restype = None + frotz_lib.get_objects_state_changed.argtypes = [] + frotz_lib.get_objects_state_changed.restype = int + frotz_lib.set_objects_state_changed.argtypes = [c_int] + frotz_lib.set_objects_state_changed.restype = None + + frotz_lib.get_special_ram_changed.argtypes = [] + frotz_lib.get_special_ram_changed.restype = int + frotz_lib.set_special_ram_changed.argtypes = [c_int] + frotz_lib.set_special_ram_changed.restype = None frotz_lib.getPC.argtypes = [] frotz_lib.getPC.restype = int @@ -367,6 +370,9 @@ def _load_frotz_lib(): frotz_lib.update_objs_tracker.argtypes = [] frotz_lib.update_objs_tracker.restype = None + frotz_lib.update_special_ram_tracker.argtypes = [] + frotz_lib.update_special_ram_tracker.restype = None + return frotz_lib @@ -519,7 +525,7 @@ def step(self, action): score = self.frotz_lib.get_score() reward = score - old_score return next_state, reward, (self.game_over() or self.victory()),\ - {'moves':self.get_moves(), 'score':score, 'victory': self.victory()} + {'moves':self.get_moves(), 'score':score} def close(self): ''' Cleans up the FrotzEnv, freeing any allocated memory. ''' @@ -602,8 +608,8 @@ def get_valid_actions(self, use_object_tree=True, use_ctypes=True, use_parallel= interactive_objs = self._identify_interactive_objects(use_object_tree=use_object_tree) best_obj_names = self._score_object_names(interactive_objs) candidate_actions = self.act_gen.generate_actions(best_obj_names) - diff2acts = self._filter_candidate_actions(candidate_actions, use_ctypes, use_parallel) - valid_actions = [max(v, key=utl.verb_usage_count) for v in diff2acts.values()] + hash2acts = self._filter_candidate_actions(candidate_actions, use_ctypes, use_parallel) + valid_actions = [max(v, key=utl.verb_usage_count) for v in hash2acts.values()] return valid_actions def set_state(self, state): @@ -622,7 +628,7 @@ def set_state(self, state): >>> env.set_state(state) # Whew, let's try something else ''' - ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative, state_changed = state + ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative, objs_state_changed, special_ram_changed = state self.frotz_lib.setRng(*rng) self.frotz_lib.setRAM(as_ctypes(ram)) self.frotz_lib.setStack(as_ctypes(stack)) @@ -632,8 +638,10 @@ def set_state(self, state): self.frotz_lib.set_opcode(opcode) self.frotz_lib.setFrameCount(frame_count) self.frotz_lib.set_narrative_text(narrative) - self.frotz_lib.set_state_changed(state_changed) + self.frotz_lib.set_objects_state_changed(objs_state_changed) + self.frotz_lib.set_special_ram_changed(special_ram_changed) self.frotz_lib.update_objs_tracker() + self.frotz_lib.update_special_ram_tracker() def get_state(self): ''' @@ -661,8 +669,9 @@ def get_state(self): frame_count = self.frotz_lib.getFrameCount() rng = self.frotz_lib.getRngA(), self.frotz_lib.getRngInterval(), self.frotz_lib.getRngCounter() narrative = self.frotz_lib.get_narrative_text() - state_changed = self.frotz_lib.get_state_changed() - state = ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative, state_changed + objs_state_changed = self.frotz_lib.get_objects_state_changed() + special_ram_changed = self.frotz_lib.get_special_ram_changed() + state = ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative, objs_state_changed, special_ram_changed return state def get_calls_stack(self): @@ -787,25 +796,6 @@ def get_world_state_hash(self): md5_hash = (b"").join(md5_hash.view(c_char)).decode('cp1252') return md5_hash - def get_world_state_hash_old(self): - - import hashlib - world_objs_str = ', '.join([str(o) for o in self.get_world_objects(clean=True)]) - special_ram_addrs = self._get_special_ram() - - ram, stack, pc, sp, fp, frame_count, opcode, rng, narrative = self.get_state() - # Return address of current routine call. (See frotz/src/common/process.c:569) - stack = stack.view("uint16") - ret_pc = stack[fp+2] | (stack[fp+2+1] << 9) - - # print(sum(stack), pc, sp, fp, ret_pc, frame_count, opcode) - # print(pc, str(special_ram_addrs) + str(ret_pc)) - - world_state_str = world_objs_str + str(special_ram_addrs) + str(ret_pc) - m = hashlib.md5() - m.update(world_state_str.encode('utf-8')) - return m.hexdigest() - def get_moves(self): ''' Returns the integer number of moves taken by the player in the current episode. ''' return self.frotz_lib.get_moves() @@ -848,51 +838,6 @@ def _world_changed(self): ''' return self.frotz_lib.world_changed() > 0 - def _get_world_diff(self): - ''' - Returns the difference in the world object tree, set attributes, and\ - cleared attributes for the last timestep. - - :returns: A Tuple of tuples containing 1) tuple of world objects that \ - have moved in the Object Tree, 2) tuple of objects whose attributes have\ - changed, 3) tuple of world objects whose attributes have been cleared, and - 4) tuple of special ram locations whose values have changed. - ''' - objs = np.zeros(64+64, dtype=np.uint16) - dest = np.zeros(64+64, dtype=np.uint16) - self.frotz_lib.get_cleaned_world_diff(as_ctypes(objs), as_ctypes(dest)) - # First 16 spots allocated for objects that have moved - moved_objs = [] - for i in range(16): - if objs[i] == 0 and dest[i] == 0: - break - moved_objs.append((objs[i], dest[i])) - # Second 16 spots allocated for objects that have had attrs set - set_attrs = [] - for i in range(16, 32): - if objs[i] == 0 or dest[i] == 0: - break - set_attrs.append((objs[i], dest[i])) - # Third 16 spots allocated for objects that have had attrs cleared - cleared_attrs = [] - for i in range(32, 48): - if objs[i] == 0 or dest[i] == 0: - break - cleared_attrs.append((objs[i], dest[i])) - # Fourth 16 spots allocated to ram locations & values that have changed - prop_diffs = [] - for i in range(48, 48+64): - if objs[i] == 0: - break - prop_diffs.append((objs[i], dest[i])) - # Fourth 16 spots allocated to ram locations & values that have changed - ram_diffs = [] - for i in range(48+64, 48+64+16): - if objs[i] == 0: - break - ram_diffs.append((objs[i], dest[i])) - return (tuple(moved_objs), tuple(set_attrs), tuple(cleared_attrs), tuple(prop_diffs), tuple(ram_diffs)) - def _score_object_names(self, interactive_objs): """ Attempts to choose a sensible name for an object, typically a noun. """ def score_fn(obj): @@ -993,21 +938,18 @@ def _identify_interactive_objects(self, observation='', use_object_tree=False): desc2obj = {} # Filter out objs that aren't examinable name2desc = {} - for obj in objs: if obj[0] in name2desc: ex = name2desc[obj[0]] else: self.set_state(state) ex = utl.clean(self.step('examine ' + obj[0])[0]) - name2desc[obj[0]] = ex if utl.recognized(ex): if ex in desc2obj: desc2obj[ex].append(obj) else: desc2obj[ex] = [obj] - # Add 'all' as a wildcard object desc2obj['all'] = [('all', 'NOUN', 'LOC')] self.set_state(state) @@ -1015,9 +957,9 @@ def _identify_interactive_objects(self, observation='', use_object_tree=False): def _filter_candidate_actions(self, candidate_actions, use_ctypes=False, use_parallel=False): """ - Given a list of candidate actions, returns a dictionary mapping world_diff - to the list of candidate actions that cause this diff. Only actions that - cause a valid world diff are returned. + Given a list of candidate actions, returns a dictionary mapping state hashes + to the list of candidate actions that cause this state change. Only actions that + cause a valid world change are returned. :param candidate_actions: Candidate actions to test for validity. :type candidate_actions: list @@ -1025,7 +967,7 @@ def _filter_candidate_actions(self, candidate_actions, use_ctypes=False, use_par :type use_ctypes: boolean :param use_parallel: Uses the parallized implementation of valid action filtering. :type use_parallel: boolean - :returns: Dictionary of world_diff to list of actions. + :returns: Dictionary of state hash to list of actions. """ if self.game_over() or self.victory() or self._emulator_halted(): @@ -1034,7 +976,7 @@ def _filter_candidate_actions(self, candidate_actions, use_ctypes=False, use_par candidate_actions = [act.action if isinstance(act, defines.TemplateAction) else act for act in candidate_actions] state = self.get_state() - diff2acts = defaultdict(list) + hash2acts = defaultdict(list) if use_parallel: state = self.get_state() @@ -1042,10 +984,10 @@ def _filter_candidate_actions(self, candidate_actions, use_ctypes=False, use_par self.pool = mp.Pool(initializer=init_worker, initargs=(self.story_file.decode(), self._seed)) args = [(state, actions, use_ctypes) for actions in chunk(candidate_actions, n=self.pool._processes)] - list_diff2acts = self.pool.map(worker, args) - for d in list_diff2acts: + list_hash2acts = self.pool.map(worker, args) + for d in list_hash2acts: for k, v in d.items(): - diff2acts[k].extend(v) + hash2acts[k].extend(v) elif use_ctypes: candidate_str = (";".join(candidate_actions)).encode('utf-8') @@ -1062,7 +1004,7 @@ def _filter_candidate_actions(self, candidate_actions, use_ctypes=False, use_par valid_acts = valid_str.decode('cp1252').strip().split(';')[:-1] for i in range(valid_cnt): - diff2acts[hashes[i]].append(valid_acts[i]) + hash2acts[hashes[i].decode('cp1252')].append(valid_acts[i]) else: orig_score = self.get_score() @@ -1079,11 +1021,11 @@ def _filter_candidate_actions(self, candidate_actions, use_ctypes=False, use_par if '(Taken)' in obs: continue - diff = self._get_world_diff() - diff2acts[diff].append(act) + hash = self.get_world_state_hash() + hash2acts[hash].append(act) self.set_state(state) - return diff2acts + return hash2acts def _get_ram(self): """ diff --git a/jericho/util.py b/jericho/util.py index 66572e42..5eda77ea 100644 --- a/jericho/util.py +++ b/jericho/util.py @@ -14,12 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -import io import os -import sys -import time -import threading - from typing import List from . import defines @@ -230,90 +225,3 @@ def chunk(items: List, n: int) -> List[List]: """ k, m = divmod(len(items), n) return list(items[i*k+min(i, m):(i+1)*k+min(i+1, m)] for i in range(n)) - - -class CaptureStdout: - """ - Capture the standard output stream from Python and shared libraries. - - References - ---------- - https://stackoverflow.com/a/29834357 - """ - escape_char = b"\b" - - def __init__(self, threaded=True): - self.threaded = threaded - self._stdout_fd = os.dup(1) # Keep a copy of the handle. - self._stdout_io = sys.stdout # Keep a reference to the text buffer. - - self.text_c = "" - self.text_py = "" - - # Create a pipe so the stream can be captured: - self.pipe_out, self.pipe_in = os.pipe() - - def __enter__(self): - self.start() - return self - - def __exit__(self, type, value, traceback): - self.stop() - - def start(self): - """ - Start capturing the stream data. - """ - - self.text_c = "" - sys.stdout = io.StringIO() - - # Replace the original stream with our write pipe: - os.dup2(self.pipe_in, 1) - if self.threaded: - # Start thread that will read the stream: - self.workerThread = threading.Thread(target=self.readOutput) - self.workerThread.start() - # Make sure that the thread is running and os.read() has executed: - time.sleep(0.01) - - def stop(self): - """ - Stop capturing the stream data and save the text in `capturedtext`. - """ - # Print the escape character to make the readOutput method stop: - os.write(self.pipe_in, self.escape_char) - - if self.threaded: - # wait until the thread finishes so we are sure that - # we have until the last character: - self.workerThread.join() - else: - self.readOutput() - - # Close the pipe - os.close(self.pipe_in) - os.close(self.pipe_out) - os.dup2(self._stdout_fd, 1) - - sys.stdout.seek(0) - self.text_py = sys.stdout.read() - - sys.stdout = self._stdout_io - - def readOutput(self): - """ - Read the stream data (one byte at a time) - and save the text in `capturedtext`. - """ - while True: - char = os.read(self.pipe_out, 1) - if not char or self.escape_char in char: - break - - try: - self.text_c += char.decode(errors='replace') - except UnicodeDecodeError: - pass - #self.text_c += str(char) - #self.text_c += f"*** UnicodeDecodeError {str(char)} at c{len(self.text_c)}!" diff --git a/tools/test_games.py b/tools/test_games.py index 09fd87ec..d54cbaa9 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -704,21 +704,11 @@ def parse_args(): skip = True break - # world_diff = env_._get_world_diff() - # moved_objs, set_attrs, cleared_attrs, changed_props, _ = world_diff - # skip = False - # for obj in moved_objs + set_attrs + cleared_attrs + changed_props: - # if obj[0] in SKIP_PRECHECK_STATE.get(rom, {}).get("ignore_objects", []): - # skip = True - # break - if skip: break if env_._world_changed(): # if last_hash != env_.get_world_state_hash(): - # env_objs = env.get_world_objects(clean=True) - # env_objs_ = env_.get_world_objects(clean=True) objs1 = env.get_world_objects(clean=False) objs2 = env_.get_world_objects(clean=False) @@ -805,28 +795,6 @@ def parse_args(): breakpoint() - # else: - # world_diff = env._get_world_diff() - # if len(world_diff[-1]) > 1: - # print(colored("Multiple special RAM addressed have been triggered!", 'yellow')) - # print(f"RAM: {world_diff[-1]}") - # breakpoint() - - # else: - # changed_objs = [(o1, o2) for o1, o2 in zip(env_objs_cleaned, last_env_objs_cleaned) if o1 != o2] - - # world_diff = env._get_world_diff() - # if len(changed_objs) > 0 and len(world_diff[-1]) > 0: - # print(colored("Special RAM address triggered as well as object modifications!", 'yellow')) - # print(colored("Is the special RAM address really needed, then?", 'yellow')) - # print(f"RAM: {world_diff[-1]}") - # for o1, o2 in changed_objs: - # print(o2) # New - # print(o1) # Old - - # breakpoint() - - if not env.victory(): print(colored("FAIL", 'red')) if args.debug: From 9d2af0efe120b1c8689ebbd5eaa363dea0877f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 16 Dec 2021 15:01:03 -0500 Subject: [PATCH 39/85] Add Matthew's script to test walkthrough. --- tools/test_walkthrough.py | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tools/test_walkthrough.py diff --git a/tools/test_walkthrough.py b/tools/test_walkthrough.py new file mode 100644 index 00000000..f076b956 --- /dev/null +++ b/tools/test_walkthrough.py @@ -0,0 +1,68 @@ +import argparse + +from termcolor import colored + +import jericho +from jericho.util import clean + + +def get_detected_hashes(env): + interactive_objs = env._identify_interactive_objects(use_object_tree=True) + best_obj_names = env._score_object_names(interactive_objs) + candidate_actions = env.act_gen.generate_actions(best_obj_names) + hash2acts = env._filter_candidate_actions(candidate_actions, use_ctypes=True, use_parallel=True) + return hash2acts + + +def analyze_step(idx, env, gold_act): + """ + Checks to ensure the resulting hash from playing the walkthrough action (gold_act) is amoung the state hashes + considered by get_valid_actions. + + """ + hash2acts = get_detected_hashes(env) + obs, _, _, _ = env.step(gold_act) + gold_hash = env.get_world_state_hash() + + if gold_act.startswith('x ') or gold_act.startswith('examine ') or gold_act == 'z': + return + + if not env._world_changed(): + print(colored('{}. NoWorldChange gold_act: {}, obs: {}'.format(idx, gold_act, clean(obs)), 'magenta')) + + if gold_hash not in hash2acts: + print(colored('{}. gold_act: {}-{} not in valids. Obs: {}'.format(idx, gold_act, gold_hash, clean(obs)), 'red')) + + +def run_walkthrough(rom): + """ + Runs the walkthrough checking for two main things: + 1) Is the state hash from the walkthrough action among the state hashes in get_valid_actions()? + 2) Is the world state hash for the current state been encountered before or is unique? + + """ + env = jericho.FrotzEnv(rom) + obs, _ = env.reset() + walkthrough = env.get_walkthrough() + hashes = {} + for idx, gold_act in enumerate(walkthrough): + whash = env.get_world_state_hash() + if not whash in hashes: + hashes[whash] = [idx] + else: + print(colored('{}: {} States with same hash: {}'.format(idx, obs, hashes[whash]), 'cyan')) + hashes[whash].append(idx) + print(f'Step {idx} - {gold_act}') + analyze_step(idx, env, gold_act) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('rom', type=str, help='Rom File') + args = parser.parse_args() + return args + + +if __name__ == "__main__": + args = parse_args() + run_walkthrough(args.rom) From b9fc0a00aa2afc289417e3f99774a3a4657e94c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 16 Dec 2021 15:38:33 -0500 Subject: [PATCH 40/85] Fix memory issue. --- frotz/src/interface/frotz_interface.c | 34 ++++------------------ tools/test_games.py | 42 +++++++-------------------- 2 files changed, 15 insertions(+), 61 deletions(-) diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index 36be2521..bc87acd8 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -1436,7 +1436,7 @@ int get_special_ram_size() { } // Returns the current values of the special ram addresses -void get_special_ram(zword *ram) { +void get_special_ram(zbyte *ram) { int num_special_addrs; zword* special_ram_addrs = get_ram_addrs(&num_special_addrs); for (int i=0; i 0) { - // return 1; - // } - return objects_state_changed || special_ram_changed || last_ret_pc != getRetPC(); } diff --git a/tools/test_games.py b/tools/test_games.py index d54cbaa9..3955066b 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -672,9 +672,6 @@ def parse_args(): if args.very_verbose: print(obs) - # history = [] - # history.append((0, 'reset', env.get_state())) - walkthrough = env.get_walkthrough() for i, cmd in tqdm(list(enumerate(walkthrough))): cmd = cmd.lower() @@ -708,7 +705,6 @@ def parse_args(): break if env_._world_changed(): - # if last_hash != env_.get_world_state_hash(): objs1 = env.get_world_objects(clean=False) objs2 = env_.get_world_objects(clean=False) @@ -721,10 +717,6 @@ def parse_args(): breakpoint() break - # if env_._world_changed(): - # print(colored(f'{i}. [{cmd_}]: world state has changed.\n"""\n{obs_}\n"""', 'red')) - # breakpoint() - if args.interactive: tmp = input(f"{i}. [{cmd}] >") if tmp.strip(): @@ -740,9 +732,6 @@ def parse_args(): env_objs = env.get_world_objects(clean=False) env_objs_cleaned = env.get_world_objects(clean=True) - # state = env.get_state() - # history.append((i, cmd, state)) - if args.very_verbose: print(f"{i}. >", cmd) print(obs) @@ -756,12 +745,7 @@ def parse_args(): and cmd not in SKIP_CHECK_STATE.get(rom, {}).get('noop', {})) if check_state: - # if not env._world_changed(): - # print(colored(f'{i}. [{cmd}]: world state hasn\'t changed.\n"""\n{obs}\n"""', 'red')) - # breakpoint() - if not env._world_changed(): - # if last_hash == env.get_world_state_hash(): if cmd.split(" ")[0] not in {"look", "l", "x", "search", "examine", "i", "inventory"}: print(colored(f'{i}. [{cmd}]: world hash hasn\'t changed.\n"""\n{obs}\n"""', 'red')) @@ -776,24 +760,18 @@ def parse_args(): if o1 != o2: print(colored(f"{o1}\n{o2}", "red")) - print(f"Testing walkthrough without '{cmd}'...") - alt1 = test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) - print(f"Testing walkthrough replacing '{cmd}' with 'wait'...") - alt2 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) + # For debugging. + # print(f"Testing walkthrough without '{cmd}'...") + # alt1 = test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) + # print(f"Testing walkthrough replacing '{cmd}' with 'wait'...") + # alt2 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) # print(f"Testing walkthrough replacing '{cmd}' with '0'...") - # test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) + # alt3 = test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) # print(f"Testing walkthrough replacing '{cmd}' with 'wait 1 minute'...") - # test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) - print(f"Testing walkthrough replacing '{cmd}' with 'look'...") - alt3 = test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) - - # if alt1 or alt2 or alt3: - # print(f"$$$ {i}: \"{cmd}\"") - # else: - # breakpoint() - # pass - - breakpoint() + # alt4 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) + # print(f"Testing walkthrough replacing '{cmd}' with 'look'...") + # alt5 = test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) + # breakpoint() if not env.victory(): print(colored("FAIL", 'red')) From 514373112b9d64f97edb2a105405eb05e1e1107f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Tue, 11 Jan 2022 14:36:21 -0500 Subject: [PATCH 41/85] FIX: wrong memcmp size for special_ram. --- frotz/src/interface/frotz_interface.c | 36 +++++++++++++-------------- tools/test_games.py | 6 +++++ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index bc87acd8..223ce661 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -398,23 +398,6 @@ void setRAM(unsigned char *ram) { memcpy(zmp, ram, h_dynamic_size); } -int zmp_diff(int addr) { - if (zmp[addr] != prev_zmp[addr]) { - return 1; - } - return 0; -} - -int zmp_diff_range(int start, int end) { - int i; - for (i=start; i Date: Wed, 12 Jan 2022 15:58:04 -0500 Subject: [PATCH 42/85] Noop checks for curses.z5 --- frotz/src/games/curses.c | 59 ++++++++++++++++++++++++++++++++---- tools/test_games.py | 64 ++++++++++++++++++++-------------------- 2 files changed, 86 insertions(+), 37 deletions(-) diff --git a/frotz/src/games/curses.c b/frotz/src/games/curses.c index 2eb72192..379e69d7 100644 --- a/frotz/src/games/curses.c +++ b/frotz/src/games/curses.c @@ -24,8 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Curses: http://ifdb.tads.org/viewgame?id=plvzam05bmz3enh8 -const zword curses_special_ram_addrs[17] = { - 786, 800, 828, 842, 856, 870, 884, 898, // Interacting with the rods. +const zword curses_special_ram_addrs[20] = { + 786, 800, 828, 842, 856, 870, 884, 898, 926, // Interacting with the rods. // 1469, // Clean glass ball 23711, // get High Rod of Love (warning message) 23655, 23657, // Hole @@ -37,14 +37,14 @@ const zword curses_special_ram_addrs[17] = { 23681, 23683, // Pacing // 14201, // Set timer // 20911, // Turn sceptre - // 23701, // Close the lid. - // 23707, // Lost inside the Palace + 23701, // Close the lid. + 23707, // Lost inside the Palace }; const char *curses_intro[] = { "\n" }; zword* curses_ram_addrs(int *n) { - *n = 17; + *n = 20; return curses_special_ram_addrs; } @@ -125,4 +125,53 @@ void curses_clean_world_objs(zobject* objs) { for (int i=1; i<=curses_get_num_world_objs(); ++i) { objs[i].attr[3] &= mask3; } + + int N; + // Zero out the antiquated wireless' counter. + N = 2; // Prop23. + memset(&objs[111].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[111].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the glass cabinet' alarm counter. + N = 2; // Prop23. + memset(&objs[200].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[200].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the Coven Cell's sacrifice counter. + N = 3; // Prop23. + memset(&objs[195].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[195].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the "beanle"'s counter before avalanche of stones. + N = 4; // Prop23. + memset(&objs[309].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[309].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the complicated-look bomb's counter. + N = 3; // Prop23. + memset(&objs[205].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[205].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the time-detonator's counter. + N = 5; // Prop23. + memset(&objs[206].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[206].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out Causeway's counter that controls Austin (the cat) reactions. + N = 3; // Prop23. + memset(&objs[396].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[396].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out BirdcagfMuses's counter until messenger-boy arrives. + N = 3; // Prop23. + memset(&objs[448].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[448].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out Buried Alive's counter until the player suffocates. + N = 3; // Prop23. + memset(&objs[431].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[431].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out tentle's counter before Saxon spy arrives. + N = 3; // Prop23. + memset(&objs[353].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[353].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out unconscious Saxon spy's counter before the guards takes the spy away. + N = 2; // Prop23. + memset(&objs[354].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[354].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out Encampment's counter before one of the druids sees you. + N = 3; // Prop23. + memset(&objs[355].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[355].prop_lengths[N-1] * sizeof(zbyte)); } diff --git a/tools/test_games.py b/tools/test_games.py index 53a0a59f..6dcc563b 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -135,39 +135,35 @@ }, "curses.z5": { '*': [ + 386, # Waiting to get caught after triggering the alarm. + 387, # Arriving in the Coven Cell -> This sets Attr8 for rself and Coven Cell. + 648, # Waiting for the bomb's timer runs out. + 673, # Waiting for the magnesium-flare flash at the lighthouse. + 721, # Waiting for the messenger-boy comes feed the pigeons. + 838, # Waiting for the Napoleonic officers to arrive. + 843, # Waiting for the Napoleonic officers to tweak the nose of the sphinx. + 918, # Doing something else causes the hand to fall off the knight. + 921, # Doing something else causes the skull to fall off the knight. 877, 878, 879, # enter coffin (You are so distracted that common sense takes over and you clamber out of the mummy case.) 1024, # druidical figure sequence + 1032, # Waiting for the Sazon spy to show up. 1063, 1064, 1065, # Ending ], - "z": [386, 387], # Waiting + "ignore_commands": [ + "examine mirror", "examine vanity", "examine long", "examine long vanity mirror", # The monkey leaps from your arms, revelling in its new life + "examine book", "examine poetry", "examine books", "examine a", # teleports you to Unreal City. + "examine sheets", "examine pile", # exposes the radio. + "examine rolls", "examine insulation", # discovers a battery. + "examine agricultural", "examine implement", "examine bladed", # changes the name of the object to "spade". + ], "ignore_objects": [ - 111, # antiquated wireless - 76, # new-lookty (examine insulation -> discover battery) + 111, # antiquated wireless (i.e., a radio) 58, # Austin the cat walking around. 114, # Jemima (Jemima hums along) - 154, # Unreal City (examine book/poetry -> transport you?!) - 298, # spade (examine agricultural -> let's just call a spade a spade.) - 216, # model ship (examine ship -> you pick it up from force of habit) 211, # Cups Glasses (look -> hear noise and voices) - 195, # Coven Cell (look -> attr 8, prop 23.) - 309, # beanle (look -> prop 23) - 2, # north (moving from compass to flagpole?!) - 371, # flurries ofeen luminescence (fading away) - 200, # glass cabinet - 70, # book of Twentiesetry (examine book/poetry -> transport you?!) - 206, # timer-detonator (timer runs out) - 205, # complicated-look bomb (counter prop 23) - 396, # Causeway (counter prop 23) - 448, # BirdcagfMuses (counter prop 23) + 371, # flurries ofeen luminescence (appearing or fading away) 401, # skiff (drifting) - 420, # Napoleonic officers (appears) - 496, # adamantinend (The hand wobbles and falls off the knight again.) - 432, # adamantinkull (The skull wobbles and falls off the knight again.) - 394, # InsideOrb (attr 8) - 353, # Tentle (prop 23) - 354, # Saxon spy appears - 355, # Encampment (prop 23) - + 394, # InsideOrb (The sphere rotates and displays images.) ] }, @@ -686,9 +682,12 @@ def parse_args(): env_ = env.copy() state = env_.get_state() objs = env_._identify_interactive_objects(use_object_tree=True) - cmds = ["look", "inv"] + cmds = ["look", "inventory", "wait", "examine me", "asd"] cmds += ["examine " + obj[0][0] for obj in objs.values()] for cmd_ in cmds: + if cmd_ in SKIP_PRECHECK_STATE.get(rom, {}).get("ignore_commands", []): + continue + env_.set_state(state) obs_, _, _, _ = env_.step(cmd_) @@ -720,6 +719,7 @@ def parse_args(): if any(rams1 != rams2): print(np.array(rams1, rams2).T) + breakpoint() break @@ -767,17 +767,17 @@ def parse_args(): print(colored(f"{o1}\n{o2}", "red")) # For debugging. - # print(f"Testing walkthrough without '{cmd}'...") - # alt1 = test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) - # print(f"Testing walkthrough replacing '{cmd}' with 'wait'...") - # alt2 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) + print(f"Testing walkthrough without '{cmd}'...") + alt1 = test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) + print(f"Testing walkthrough replacing '{cmd}' with 'wait'...") + alt2 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) # print(f"Testing walkthrough replacing '{cmd}' with '0'...") # alt3 = test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) # print(f"Testing walkthrough replacing '{cmd}' with 'wait 1 minute'...") # alt4 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) - # print(f"Testing walkthrough replacing '{cmd}' with 'look'...") - # alt5 = test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) - # breakpoint() + print(f"Testing walkthrough replacing '{cmd}' with 'look'...") + alt5 = test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) + breakpoint() if not env.victory(): print(colored("FAIL", 'red')) From 732b0f2112eee42a9dd2849bd8e139a95d60c4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 17 Jan 2022 09:54:25 -0500 Subject: [PATCH 43/85] Noop check: advent.z5 --- tools/test_games.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/test_games.py b/tools/test_games.py index 6dcc563b..9f4cfcf2 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -25,8 +25,7 @@ 169: "u", # Otherwise the dwarf kills the player. 180: "d", # Otherwise the dwarf kills the player. 202: "u", # Otherwise the dwarf kills the player. - 270: "u", # Otherwise the dwarf kills the player. - '*': range(270, 276+1), # Waiting. Nothing happens. + 270: "wait", # The cave is now closed. 'ignore_objects': [ 264, # Little Dwarf 265, # Little axe @@ -717,8 +716,7 @@ def parse_args(): rams1 = env._get_special_ram() rams2 = env_._get_special_ram() if any(rams1 != rams2): - print(np.array(rams1, rams2).T) - + print(np.array([rams1, rams2]).T) breakpoint() break From a04c2894b26f91ea0dcd9855e6ff35bb9548d70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 17 Jan 2022 10:56:51 -0500 Subject: [PATCH 44/85] Noop check: afflicted.z8 --- frotz/src/games/afflicted.c | 9 +++++++++ tools/test_games.py | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frotz/src/games/afflicted.c b/frotz/src/games/afflicted.c index 1c18e272..7762d4f1 100644 --- a/frotz/src/games/afflicted.c +++ b/frotz/src/games/afflicted.c @@ -128,4 +128,13 @@ void afflicted_clean_world_objs(zobject* objs) { for (int i=1; i<=afflicted_get_num_world_objs(); ++i) { objs[i].attr[3] &= mask3; } + + // Zero out Prop28 some objects with no name. + int N; + N = 5; // Prop28. + memset(&objs[204].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[204].prop_lengths[N-1] * sizeof(zbyte)); + memset(&objs[205].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[205].prop_lengths[N-1] * sizeof(zbyte)); + memset(&objs[206].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[206].prop_lengths[N-1] * sizeof(zbyte)); + memset(&objs[207].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[207].prop_lengths[N-1] * sizeof(zbyte)); + } diff --git a/tools/test_games.py b/tools/test_games.py index 9f4cfcf2..25de4662 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -36,7 +36,6 @@ "*": [5, 6], # Angela is moving and unlocking the door. 'ignore_objects': [ 143, # Ice (The ice has completely melted.) - 204, 205, 206, 207, # no-name objects. ] }, "anchor.z8": { From 5870a2f13ab66f7a72c7540d39869fdb5477ea67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Tue, 18 Jan 2022 15:06:54 -0500 Subject: [PATCH 45/85] Improve test_games.py script to display better diff between objects and ram changes. --- frotz/src/interface/frotz_interface.c | 9 +++ jericho/jericho.py | 12 ++++ tools/test_games.py | 97 +++++++++++++++++---------- 3 files changed, 81 insertions(+), 37 deletions(-) diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index 223ce661..49c99f08 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -1427,6 +1427,15 @@ void get_special_ram(zbyte *ram) { } } +// Returns the special ram addresses. +void get_special_ram_addrs(zword *ram_addrs) { + int num_special_addrs; + zword* special_ram_addrs = get_ram_addrs(&num_special_addrs); + for (int i=0; i Date: Tue, 18 Jan 2022 15:07:20 -0500 Subject: [PATCH 46/85] Noop check: anchor.z8 --- frotz/src/games/anchor.c | 88 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/frotz/src/games/anchor.c b/frotz/src/games/anchor.c index 5419f4c5..5a586c73 100644 --- a/frotz/src/games/anchor.c +++ b/frotz/src/games/anchor.c @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *anchor_intro[] = { "\n", "\n", "\n" }; -const zword anchor_special_ram_addrs[4] = { +const zword anchor_special_ram_addrs[3] = { // 21922, // Combination lock 40660, // Bathe // 38470, // Transitions between days @@ -37,11 +37,11 @@ const zword anchor_special_ram_addrs[4] = { 18839, // Being chased by a monster around the Old Stone Well. // 31625, // Breaking door leading to Hallway. // 17267, // Ritual sequence in town square - 27970, // Opening the hatch and waiting for the sound. + // 27970, // Opening the hatch and waiting for the sound. }; zword* anchor_ram_addrs(int *n) { - *n = 4; + *n = 3; return anchor_special_ram_addrs; } @@ -117,10 +117,90 @@ void anchor_clean_world_objs(zobject* objs) { // Zero out attribute 25 for all objects. // attr[0] attr[1] attr[2] attr[3] // 11111111 01111111 11111111 10111111 - // char mask1 = 0b01111111; // Attr 8 char mask3 = 0b10111111; // Attr 25. for (int i=1; i<=anchor_get_num_world_objs(); ++i) { // objs[i].attr[1] &= mask1; objs[i].attr[3] &= mask3; } + + // Train's location according to its schedule. + objs[141].parent = 0; + + char maskAttr8 = 0b01111111; // Attr 8 + // Zero out Attr8 of the handcuffs. + objs[518].attr[1] &= maskAttr8; + + int N; + // Zero out the Wine Cellar's counter. + N = 5; // Prop40. + memset(&objs[395].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[395].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the Flashlight's battery counter. + N = 5; // Prop41. + memset(&objs[370].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[370].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the pale, frightened woman's counter before she slams the door shut. + N = 3; // Prop40. + memset(&objs[158].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[158].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the pressure gauge's counter controlling the noise it makes. + N = 2; // Prop41. + memset(&objs[467].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[467].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the book of matches's counter before the match burns down completely. + N = 4; // Prop40. + memset(&objs[372].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[372].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the metal handle's counter before its snaps back to an upright position. + N = 2; // Prop41. + memset(&objs[472].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[472].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the Island of Flesh's counter. + N = 3; // Prop41. + memset(&objs[516].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[516].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the rain's counter controlling lighting. + N = 4; // Prop41. + memset(&objs[82].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[82].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the madman's counter. + N = 4; // Prop41. + memset(&objs[578].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[578].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the Town Square's counter controlling the old man's faith. + N = 3; // Prop41. + memset(&objs[172].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[172].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the (appearance)'s counter. + N = 1; // Prop41. + memset(&objs[27].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[27].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the monster's counter. + N = 3; // Prop41. + memset(&objs[171].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[171].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the Lighthouse's counter controlling Michael's actions. + N = 3; // Prop41. + memset(&objs[509].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[509].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the Burial Mound's counter. + N = 3; // Prop40. + memset(&objs[447].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[447].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the stone obelisk's counter. + N = 2; // Prop41. + memset(&objs[174].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[174].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out Michael's counter. + N = 4; // Prop41. + memset(&objs[524].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[524].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out ghost of Croseus Verlac's counter. + N = 2; // Prop41. + memset(&objs[462].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[462].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out Home's counter. + N = 2; // Prop41. + memset(&objs[231].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[231].prop_lengths[N-1] * sizeof(zbyte)); + } From a956daa392dc2e7b19cbaf2d35b445c86313442e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Tue, 18 Jan 2022 15:19:40 -0500 Subject: [PATCH 47/85] Noop check: balances.z5 --- frotz/src/games/balances.c | 9 +++++++++ tools/test_games.py | 15 ++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/frotz/src/games/balances.c b/frotz/src/games/balances.c index 5aa977ae..866dbf65 100644 --- a/frotz/src/games/balances.c +++ b/frotz/src/games/balances.c @@ -117,4 +117,13 @@ void balances_clean_world_objs(zobject* objs) { objs[i].attr[1] &= mask1; objs[i].attr[3] &= mask3; } + + int N; + // Zero out the lobal_spell's counter. + N = 4; // Prop40. + memset(&objs[65].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[65].prop_lengths[N-1] * sizeof(zbyte)); + + // Zero out the buck-toothed cyclops's counter. + N = 3; // Prop40. + memset(&objs[86].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[86].prop_lengths[N-1] * sizeof(zbyte)); } diff --git a/tools/test_games.py b/tools/test_games.py index bf99f52f..c9eb6bee 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -81,16 +81,13 @@ "awaken.z5": {}, "balances.z5": { '*': [ - 20, 21, # Examining the sapphire causes it to break. - 109, 110 # The cyclops is losing patience. + 71, # A tortoise-feather flutters to the ground before you! + ], + "ignore_commands": [ + "examine furniture", # Discover a cedarwood box. + "examine oats", "examine pile", "examine of", # Discover a shiny scroll. + "examine perfect sapphire", "examine sapphire", "examine perfect", # Causes to break the sapphire and learn the caskly spell. ], - "ignore_objects": [ - 57, # Shiny scroll (examining the pile of oats gives you the scroll). - 51, # cedarwood box (examining the furniture gives you the box) - 67, # tortoise feather (A tortoise-feather flutters to the ground before you!) - 65, # (lobal_spell) (prop 40) - 86, # buck-toothed cyclops (prop 40) - ] }, "ballyhoo.z3": { "*": [ From bb3b6e917133599a9d517768401f7187c816e940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 19 Jan 2022 16:26:29 -0500 Subject: [PATCH 48/85] Util function to clear_attr of a zobject --- frotz/src/interface/frotz_interface.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index 49c99f08..59de995d 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -1335,6 +1335,23 @@ void (*clean_world_objs_fns[]) (zobject* objs) = { }; +//================================// +// ZObject Manipulation Functions // +//================================// + +void clear_attr(zobject* obj, unsigned char attr_id) { + // attr[0] attr[1] attr[2] attr[3] + // 11111111 11111011 11111111 11111111 + // ^ ^ ^ ^ ^ + // 0 8 13 16 24 + // + // bit = 8 - (13 % 8) - 1 = 2 + // mask = ~(1 << 2) = 0b11111011 + char bit = 8 - (attr_id % 8) - 1; + char mask = ~(1 << bit); + obj->attr[attr_id / 8] &= mask; +} + //==========================// // Function Instantiations // //==========================// From de131aef34701df47544d1422d8b5d73de0bf488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 19 Jan 2022 16:26:47 -0500 Subject: [PATCH 49/85] Noop check: ballyhoo.z3 --- frotz/src/games/ballyhoo.c | 32 +++++++++-------- tools/test_games.py | 70 ++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/frotz/src/games/ballyhoo.c b/frotz/src/games/ballyhoo.c index e9c786ff..27400fab 100644 --- a/frotz/src/games/ballyhoo.c +++ b/frotz/src/games/ballyhoo.c @@ -24,13 +24,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Ballyhoo: http://ifdb.tads.org/viewgame?id=b0i6bx7g4rkrekgg -const zword ballyhoo_special_ram_addrs[23] = { +const zword ballyhoo_special_ram_addrs[22] = { 8853, // Listen to the conversation with Munrab. 8623, // Crossing the tightrope 9113, // turnstile 8835, // Lion stand 8723, // Give case to harry - 9067, // buy candy + 8639, // give money to hawker to buy candy 8791, // stand 8893, // walking in the crowd 9053, // get out of line @@ -38,7 +38,7 @@ const zword ballyhoo_special_ram_addrs[23] = { 8911, // radio 8643, // tape 9047, // radio on/off - 8629, // search desk + // 8629, // search desk 8759, // cards 8989, // ladder 2735, // veil @@ -51,7 +51,7 @@ const zword ballyhoo_special_ram_addrs[23] = { }; zword* ballyhoo_ram_addrs(int *n) { - *n = 23; + *n = 22; return ballyhoo_special_ram_addrs; } @@ -127,17 +127,19 @@ int ballyhoo_ignore_attr_clr(zword obj_num, zword attr_idx) { } void ballyhoo_clean_world_objs(zobject* objs) { - // Clear out object "it" - // objs[211].parent = 0; - - // Zero out attribute 13 of object 211 ("it") - // attr[0] attr[1] attr[2] attr[3] - // 11111111 11111011 11111111 11111101 - // char mask1 = 0b11111011; // Attr 13 - char mask3 = 0b11111101; // Attr 30 - // objs[211].attr[1] &= mask1; - + // Clear Attr30 for all objects. for (int i=1; i<=ballyhoo_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask3; + clear_attr(&objs[i], 30); } + + clear_attr(&objs[211], 13); // it + clear_attr(&objs[175], 18); // Menagerie + clear_attr(&objs[142], 12); // concessistand + + // Ignore Chuckles (the clown) movements. + objs[113].parent = 0; + + // Ignore hawker movements. + objs[78].parent = 0; + } diff --git a/tools/test_games.py b/tools/test_games.py index c9eb6bee..34076ae4 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -91,39 +91,39 @@ }, "ballyhoo.z3": { "*": [ - 6, 7, 8, # Listening to the conversation with Munrab. - 41, 62, 88, 122, 125, 126, 249, # Turnstile's state changes. + 6, 7, 8, # Listening to the conversation with Munrab. + 40, 41, 62, 88, 122, 125, 126, 249, # Turnstile's state changes. + 44, # the trailer door is slammed shut. + 48, 49, # You get kicked out of the trailer by Chuckles. + 64, # Observe the detective fo through the turnstile. 110, 111, 112, 113, # Lion stand state changes. - 278, 279, # Playing cardsrn - 200, 214, # Rewinding the tape - 260, 261, 262, 263, 264, 265, # Sequence for "search desk" (addr. 8629). - 266, # Examining the spreadsheet triggers (addr. 8845). - 297, 298, 299, 301, # Ladder is being moved. - 396, 405, 406, # Triggering Turnstile (addr. 9113) + 149, # Right next to the long line a much shorter line begins to form. + 152, # Jerry yelling to a group of people. + 153, # You get pushed aside. + 200, 214, # The tape stops rewinding. + 225, # Not moving, causes you to die. + 226, 227, # headphones being reduced to dust in the ape's tense grip. + 253, # Hannibal of the Jungle thunders out of the tent + 260, # You can hear someone, presumably Mr. Munrab, barge into the office. + 275, 281, 289, 293, # The spring-loaded secret panel slides shut + 278, 279, # Playing cards + 285, # Comrade Thumb arrives. + 290, 291, 292, # Dealer and Billy are moving. + 297, 298, 299, 300, 301, # Ladder is being moved. + 342, # Gottfried arrives + 356, 357, # Chelsea moves + 361, # Follow Chelsea. + 368, 369, # roustabout comes sprinting 415, # Game ending (slip off the wire). ], - "ignore_objects": [ - 113, # Chuckles is moving around. - 122, # ticket is revealed while examining the garbage - 20, # leatsofa (examine leather, set attr 12) - 78, # hawker appears - 17, # short line (Right next to the long line a much shorter line begins to form.) - 162, # Jerry - 42, # groballplayers - 211, # it - 142, # concessistand (you see the line you first entered suddenly kicking into gear) - 163, # one-dollar-and-85-cent granola bar (examine garbage -> picks it up) - 9, # Mahler (screams, clear attr 12) - 141, # elephant (thunders out of the tent) - 175, # Menagerie (set attr 18) - 95, # blackjack table (set attr 12) - 212, # secret panel (attr 15, opens/closes it) - 219, # Comrade Thumb (appears in the room) - 116, # dealer (appears/disappears) - 300, # elephant prod (moving) - 218, # Gottfried Wilhelm vKatzenjammer (moving) - 84, # Chelsea (moving) - ] + "ignore_commands": [ + "examine flower", # the daisy spritzes some water in your face + "examine garbage", # find an unmarked ticket + "examine chandelier", "examine leather", "examine sofa", # Rimshaw the Incomparable speaks + "examine spreadsheet", # Discover Chuckles' real name. + "examine Comrade Thumb", # You can see a trembling midget hand pull the tablecloth back down. + "examine andrew", # Triggering Turnstile (addr. 9113) + ], }, "curses.z5": { '*': [ @@ -218,6 +218,8 @@ "wait", # You hear a loud growl nearby. "ask pitchman about dr nostrum", # Not needed to complete the game. "read note", # Not needed to complete the game. + "buy candy from hawker", # Doesn't work. Need to give the money instead. + "look into cage", "look into wagon", "search desk", ] }, "curses.z5": { @@ -623,10 +625,12 @@ def display_diff(A, B): print(line2) -def test_walkthrough(env, walkthrough): +def test_walkthrough(env, walkthrough, verbose=False): env.reset() - for cmd in walkthrough: + for i, cmd in enumerate(walkthrough): obs, score, done, info = env.step(cmd) + if verbose: + print(colored(f"{i}. > {cmd}\n{obs}", "yellow")) if not env.victory(): msg = "FAIL\tScore {}/{}".format(info["score"], env.get_max_score()) @@ -769,7 +773,7 @@ def parse_args(): if check_state: if not env._world_changed(): - if cmd.split(" ")[0] not in {"look", "l", "x", "search", "examine", "i", "inventory"}: + if True: #cmd != "look" and cmd.split(" ")[0] not in {"l", "i", "inventory"}: print(colored(f'{i}. [{cmd}]: world hash hasn\'t changed.\n"""\n{obs}\n"""', 'red')) From 7cfe88e9670bacdeb1a683e5882653ed7bd8caa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Thu, 20 Jan 2022 11:49:34 -0500 Subject: [PATCH 50/85] Flush buffer before getting screen. Trim leading/trailing whitespace of observations. --- frotz/src/dumb/dumb_output.c | 2 ++ frotz/src/interface/frotz_interface.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/frotz/src/dumb/dumb_output.c b/frotz/src/dumb/dumb_output.c index c28ebc12..16b3aae6 100644 --- a/frotz/src/dumb/dumb_output.c +++ b/frotz/src/dumb/dumb_output.c @@ -572,6 +572,7 @@ void dumb_init_output(void) } char* dumb_get_screen(void) { + flush_buffer(); *screen_buffer_ptr = '\0'; return screen_buffer; } @@ -582,6 +583,7 @@ void dumb_clear_screen(void) { char* dumb_get_lower_screen(void) { + flush_buffer(); *screen_buffer_ptr = '\0'; return screen_buffer; } diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index 59de995d..f51e7ea2 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -120,6 +120,18 @@ void replace_newlines_with_spaces(char *s) { } } +char* trim_whitespaces(char* obs) { + // Trim trailing whitespace. + char* pch = obs + strlen(obs) - 1; + while (pch > obs && isspace(*pch)) { + pch = pch - 1; + } + *(pch+1) = '\0'; + + // Trim leading whitespaces. + return obs + strspn(obs, "\n\r "); +} + enum SUPPORTED { DEFAULT_, ACORNCOURT_, @@ -1365,7 +1377,10 @@ char** get_intro_actions(int* num_actions) { } char* clean_observation(char* obs) { - return (*clean_observation_fns[ROM_IDX])(obs); + char* out = (*clean_observation_fns[ROM_IDX])(obs); + out = trim_whitespaces(out); + // printf("--\n%s\n--", out); // For debugging. + return out; } short get_score() { From bfa92a3c034ac9d887972da534ff6e2fa2c9a3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 21 Jan 2022 10:35:28 -0500 Subject: [PATCH 51/85] Noop check: cutthroat --- frotz/src/games/cutthroat.c | 55 ++++++++++++++++++++++++++++++++----- jericho/game_info.py | 2 +- tools/test_games.py | 53 +++++++++++++++++++++++++++++++++-- 3 files changed, 99 insertions(+), 11 deletions(-) diff --git a/frotz/src/games/cutthroat.c b/frotz/src/games/cutthroat.c index 02428971..6ea29ea3 100644 --- a/frotz/src/games/cutthroat.c +++ b/frotz/src/games/cutthroat.c @@ -23,16 +23,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "frotz_interface.h" // Cutthroats: http://ifdb.tads.org/viewgame?id=4ao65o1u0xuvj8jf -const zword cutthroat_special_ram_addrs[7] = { +const zword cutthroat_special_ram_addrs[9] = { 8785, // Lock state of bedroom door. - 8669, 9021, // Answering Johnny's questions. - 10635, // Waiting for McGinty to leave. + // 8669, 9021, // Answering Johnny's questions. + 8922, // Deal with money. + 9021, // Answering Johnny's questions. + // 10635, // Waiting for McGinty to leave. 8845, 8847, // Tell longitude and latitude to Johnny. - 8987, // Track most of the game progression. Needed for "Fill tank with air". + // 8775, // Track amount of air in the air tank. (see cutthroat_clean_world_objs). + 9011, // Hunger status. + 8771, // Turn on magnet. + 8753, // Turn drill on/off. + 8747, // Track diving depth. }; zword* cutthroat_ram_addrs(int *n) { - *n = 7; + *n = 9; return cutthroat_special_ram_addrs; } @@ -43,9 +49,9 @@ char** cutthroat_intro_actions(int *n) { char* cutthroat_clean_observation(char* obs) { char* pch; - pch = strchr(obs, '\n'); + pch = strrchr(obs, '>'); if (pch != NULL) { - return pch+1; + *(pch) = '\0'; } return obs; } @@ -117,4 +123,39 @@ void cutthroat_clean_world_objs(zobject* objs) { weasel_obj->sibling = 0; weasel_obj->child = 0; } + + clear_attr(&objs[184], 19); // cretin, a.k.a. the player. + clear_attr(&objs[9], 29); // Weasel + clear_attr(&objs[155], 30); // ferry + clear_attr(&objs[133], 30); // envelope + clear_attr(&objs[90], 30); // Orange line + clear_attr(&objs[33], 31); // collectirstamps + clear_attr(&objs[124], 31); // C battery + + int N; + // Zero out + N = 1; // Prop18. + memset(&objs[217].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[217].prop_lengths[N-1] * sizeof(zbyte)); + N = 2; // Prop17. + memset(&objs[217].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[217].prop_lengths[N-1] * sizeof(zbyte)); + N = 3; // Prop15. + memset(&objs[217].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH], 0, objs[217].prop_lengths[N-1] * sizeof(zbyte)); + + objs[14].parent = 0; // McGinty + objs[12].parent = 0; // Johnny Red + objs[11].parent = 0; // Rat + objs[155].parent = 0; // ferry + objs[7].parent = 0; // Merchant Seaman's card + objs[5].parent = 0; // Delivery boy + objs[104].parent = 0; // Delivery boy's cart? + objs[105].parent = 0; // meal + objs[8].parent = 0; // Weasel's knife + objs[28].parent = 0; // Orange line + objs[90].parent = 0; // Orange line + + // Track whether air tank has air in it. + N = 23; + objs[136].prop_ids[N-1] = 63; + objs[136].prop_lengths[N-1] = 1; + objs[136].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH] = (zmp[8775] > 0); } diff --git a/jericho/game_info.py b/jericho/game_info.py index f792aecc..90da5e28 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -115,7 +115,7 @@ "rom": "cutthroat.z3", "seed": 10, # walkthrough adapted from https://ifarchive.org/if-archive/solutions/Sols3.zip and http://www.eristic.net/games/infocom/cutthroats.html - "walkthrough": 'look out window/wind watch/get out of bed/read note/open dresser/get passbook and room key/look in closet/i/open door/n/close door/lock door/wait/n/n/e/e/e/e/s/sit/order food/order drink/eat food/drink drink/yes/get out of chair/n/w/w/s/s/w/w/e/e/e/e/ne/s/s/sw/w/w/e/e/wait/n/withdraw $603/s/ne/n/nw/w/w/w/open window/look through window/w/drop passbook/e/e/n/n/w/w/sw/sw/nw/wait/examine plate/se/ne/ne/e/s/n/e/e/s/n/e/s/buy drink/drink drink/n/se/s/s/se/i/wait for johnny/YES/YES/YES/YES/YES/YES/yes/show $500/no/nw/n/n/nw/w/s/wait/wait/look/give $56/buy flashlight and repellent/buy c battery and putty/buy electromagnet/rent compressor/n/e/s/sit/order food/order drink/eat food/drink drink/get out of chair/n/se/s/s/sw/w/w/wait/wait/wait/wait/wait/wait/wait/wait/e/e/ne/n/n/nw/w/w/s/s/w/wait/look through window/w/e/wait/look through window/enter window/get envelope/n/w/s/s/unlock door/open door/s/read envelope/get all from closet/i/n/close door/lock door/n/n/e/e/s/s/w/w/drop room key/e/e/e/e/ne/nw/s/sit/order drink/drink drink/wait/wait/get off chair/n/w/s/wait/n/w/n/w/s/d/n/n/n/get drill/open panel/get c battery/put c battery in drill/close panel/s/hide envelope under bunk/s/s/s/wait/wait/wait/latitude is 25/longitude is 25/n/u/n/s/drop wet suit/drop flippers/drop mask/drop drill/i/w/n/d/n/get all/examine compressor/examine air tank/fill tank with air/s/s/s/d/u/s/n/n/n/look under bunk/n/s/u/w/s/examine drill/n/wait/get out of bunk/get all/get envelope/s/s/s/show envelope to johnny/n/u/d/n/eat stew/s/u/drop all/get watch/wear watch/get wet suit/wear wet suit/get air tank/wear air tank/get flippers/wear flippers/get mask/wear mask/i/look/get tube/get flashlight/get canister/get drill/get electromagnet/i/look/dive in ocean/open shark repellent/d/turn on flashlight/d/d/d/s/open door/s/put magnet on mine/turn on magnet/drop magnet/u/remove tank/s/s/turn drill on/drill safe with drill/turn drill off/grab case/n/n/wear air tank/d/n/u/examine glass case/examine stamps/turn drill on/drill case with drill/open tube/put glob on case/d/n/u/u/u/u/u', + "walkthrough": 'look out window/wind watch/get out of bed/read note/open dresser/get passbook and room key/look in closet/i/open door/n/close door/lock door/wait/n/n/e/e/e/e/s/sit/order food/order drink/eat food/drink drink/yes/get out of chair/n/w/w/s/s/w/w/e/e/e/e/ne/s/s/sw/w/w/e/e/wait/n/withdraw $603/s/ne/n/nw/w/w/w/open window/look through window/w/drop passbook/e/e/n/n/w/w/sw/sw/nw/wait/examine plate/se/ne/ne/e/s/n/e/e/s/n/e/s/buy drink/drink drink/n/se/s/s/se/i/wait for johnny/YES/YES/YES/YES/YES/show $500/no/nw/n/n/nw/w/s/wait/wait/look/give $56/buy flashlight and repellent/buy c battery and putty/buy electromagnet/rent compressor/n/e/s/sit/order food/order drink/eat food/drink drink/get out of chair/n/se/s/s/sw/w/w/wait/wait/wait/wait/wait/wait/wait/wait/e/e/ne/n/n/nw/w/w/s/s/w/wait/look through window/w/e/wait/look through window/enter window/get envelope/n/w/s/s/unlock door/open door/s/read envelope/get all from closet/i/n/close door/lock door/n/n/e/e/s/s/w/w/drop room key/e/e/e/e/ne/nw/s/sit/order drink/drink drink/wait/wait/get off chair/n/w/s/wait/n/w/n/w/s/d/n/n/n/get drill/open panel/get c battery/put c battery in drill/close panel/s/hide envelope under bunk/s/s/s/wait/wait/wait/latitude is 25/longitude is 25/n/u/n/s/drop wet suit/drop flippers/drop mask/drop drill/i/w/n/d/n/get all/examine compressor/examine air tank/fill tank with air/s/s/s/d/u/s/n/n/n/look under bunk/n/s/u/w/s/examine drill/n/wait/get out of bunk/get all/get envelope/s/s/s/show envelope to johnny/n/u/d/n/eat stew/s/u/drop all/get watch/wear watch/get wet suit/wear wet suit/get air tank/wear air tank/get flippers/wear flippers/get mask/wear mask/get tube/get flashlight/get canister/get drill/get electromagnet/dive in ocean/open shark repellent/d/turn on flashlight/d/d/d/s/open door/s/put magnet on mine/turn on magnet/drop magnet/u/remove tank/s/s/turn drill on/drill safe with drill/turn drill off/grab case/n/n/wear air tank/d/n/u/examine glass case/examine stamps/turn drill on/drill case with drill/open tube/put glob on case/d/n/u/u/u/u/u', "grammar" : "affirm/ok/okay/sure/uh-hu/y/yeah/yes/yup;again/g;back;barf/chomp/lose;bathe/swim/wade;breath;brief;bye/goodby;chase/come/follow/pursue;chat/say/speak/talk;curse/cuss/damn/fuck/hell/shit/swear;diagno;disemb/exit;dive;dunno/maybe;enter;gaze/l/look/peer/stare;hello/hi;help;hop/skip;i/invent;jump/leap;leave/withdr;lie/nap/rest/sleep;mumble/sigh;negati/no/nope/uh-uh;pray;progre/rating/score;q/quit;restar;restor;save;scream/shout/yell;script;stand;stay;super/superb;t/time;unscri;verbos;versio;wait/z;what/what'/whats/who/who's/whos;win/winnag;ask/inquir/questi OBJ;ask/inquir/questi about OBJ;ask/inquir/questi for OBJ;awake/startl/surpri/wake OBJ;awake/startl/surpri/wake up OBJ;bathe/swim/wade OBJ;bathe/swim/wade in OBJ;bite/chew/consum/eat/munch/nibble OBJ;blow out OBJ;board OBJ;brandi/wave OBJ;brandi/wave at OBJ;brandi/wave to OBJ;break/chip/chop/damage/destro/hit/smash in OBJ;breath OBJ;buy/order/purcha OBJ;bye/goodby OBJ;call OBJ;call to OBJ;carry/get/grab/hold/remove/take OBJ;carry/get/grab/hold/remove/take off OBJ;carry/get/grab/hold/remove/take out OBJ;cast/chuck/hurl/throw/toss OBJ;chase/come/follow/pursue OBJ;chat/say/speak/talk to OBJ;chat/say/speak/talk with OBJ;check OBJ;check/gaze/l/look/peer/stare/search for OBJ;clean/polish/scrub OBJ;climb OBJ;climb down OBJ;climb out OBJ;climb throug OBJ;climb up OBJ;climb/carry/get/grab/hold/remove/take in OBJ;climb/carry/get/grab/hold/remove/take on OBJ;close/shut OBJ;count OBJ;cross/ford OBJ;curse/cuss/damn/fuck/hell/shit/swear OBJ;deflat OBJ;deposi OBJ;descri/examin OBJ;detach/discon/free/unfast/unhook/untie OBJ;disemb OBJ;dive in OBJ;douse/exting OBJ;drink/guzzle/imbibe/sip/swallo OBJ;drop/releas OBJ;empty OBJ;enter OBJ;exit OBJ;feel/pat/pet/rub/touch OBJ;fill OBJ;find/see/seek/where OBJ;flip/set/turn OBJ;flip/set/turn off OBJ;flip/set/turn on OBJ;flip/set/turn over OBJ;fold OBJ;fold up OBJ;gaze/l/look/peer/stare OBJ;gaze/l/look/peer/stare around OBJ;gaze/l/look/peer/stare at OBJ;gaze/l/look/peer/stare behind OBJ;gaze/l/look/peer/stare in OBJ;gaze/l/look/peer/stare on OBJ;gaze/l/look/peer/stare out OBJ;gaze/l/look/peer/stare throug OBJ;gaze/l/look/peer/stare under OBJ;gaze/l/look/peer/stare with OBJ;go/procee/run/step/walk OBJ;go/procee/run/step/walk around OBJ;go/procee/run/step/walk down OBJ;go/procee/run/step/walk in OBJ;go/procee/run/step/walk on OBJ;go/procee/run/step/walk throug OBJ;go/procee/run/step/walk to OBJ;go/procee/run/step/walk up OBJ;hello/hi OBJ;help OBJ;hide behind OBJ;hide in OBJ;hide under OBJ;insert/place/put/stuff/wedge down OBJ;insert/place/put/stuff/wedge on OBJ;jump/leap across OBJ;jump/leap from OBJ;jump/leap in OBJ;jump/leap off OBJ;jump/leap/go/procee/run/step/walk over OBJ;kick OBJ;kiss OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;knock/rap over OBJ;latitu OBJ;launch OBJ;lean on OBJ;lease/rent OBJ;leave OBJ;lie/nap/rest/sleep down OBJ;lie/nap/rest/sleep in OBJ;lie/nap/rest/sleep on OBJ;lift/raise OBJ;light/start/strike OBJ;listen for OBJ;listen to OBJ;longit OBJ;lower OBJ;make OBJ;molest/rape OBJ;move/roll/pull/tug/yank OBJ;open OBJ;open up OBJ;pick OBJ;pick up OBJ;play OBJ;pour/spill OBJ;pray for OBJ;press/push/shove OBJ;press/push/shove on OBJ;press/push/shove/lift/raise up OBJ;pull/tug/yank on OBJ;pump up OBJ;reach in OBJ;read/skim OBJ;read/skim in OBJ;rob OBJ;roll up OBJ;scream/shout/yell at OBJ;search OBJ;search in OBJ;send OBJ;send for OBJ;shake OBJ;sit down OBJ;sit in OBJ;sit on OBJ;sit with OBJ;slide OBJ;smell/sniff OBJ;smoke OBJ;spin OBJ;squeez OBJ;stand on OBJ;stand/carry/get/grab/hold/remove/take up OBJ;swing/thrust OBJ;taste OBJ;tell OBJ;unfold OBJ;unlock OBJ;wait/z OBJ;wait/z for OBJ;wear OBJ;weigh OBJ;what/what'/whats/who/who's/whos OBJ;wind OBJ;wind up OBJ;withdr OBJ;aim/point OBJ at OBJ;apply OBJ to OBJ;ask/inquir/questi OBJ about OBJ;ask/inquir/questi OBJ for OBJ;attach/connec/fasten/secure/tie OBJ around OBJ;attach/connec/fasten/secure/tie OBJ to OBJ;attach/connec/fasten/secure/tie up OBJ with OBJ;attack/fight/hurt/injure OBJ with OBJ;blind/jab/poke OBJ with OBJ;blow up OBJ with OBJ;brace/suppor OBJ with OBJ;brandi/wave OBJ at OBJ;break/chip/chop/damage/destro/hit/smash OBJ with OBJ;break/chip/chop/damage/destro/hit/smash down OBJ with OBJ;break/chip/chop/damage/destro/hit/smash in OBJ with OBJ;burn/ignite/incine OBJ with OBJ;burn/ignite/incine down OBJ with OBJ;buy/order/purcha OBJ from OBJ;carry/get/grab/hold/remove/take OBJ from OBJ;carry/get/grab/hold/remove/take OBJ off OBJ;carry/get/grab/hold/remove/take OBJ out OBJ;cast/chuck/hurl/throw/toss OBJ at OBJ;cast/chuck/hurl/throw/toss OBJ down OBJ;cast/chuck/hurl/throw/toss OBJ in OBJ;cast/chuck/hurl/throw/toss OBJ off OBJ;cast/chuck/hurl/throw/toss OBJ on OBJ;cast/chuck/hurl/throw/toss OBJ over OBJ;cast/chuck/hurl/throw/toss OBJ with OBJ;cut/pierce/scrape/slice OBJ with OBJ;deposi OBJ in OBJ;deposi/insert/place/put/stuff/wedge OBJ on OBJ;detach/discon/free/unfast/unhook/untie OBJ from OBJ;dig OBJ in OBJ;dig OBJ with OBJ;dig in OBJ with OBJ;dispat/kill/murder/slay/stab OBJ with OBJ;donate/feed/give/hand/offer/pay OBJ OBJ;donate/feed/give/hand/offer/pay OBJ to OBJ;drill OBJ in OBJ;drill OBJ with OBJ;drop/releas OBJ down OBJ;drop/releas OBJ in OBJ;drop/releas OBJ on OBJ;feel/pat/pet/rub/touch OBJ to OBJ;feel/pat/pet/rub/touch OBJ with OBJ;fill OBJ with OBJ;fix/glue/patch/plug/repair OBJ with OBJ;flash/show OBJ OBJ;flash/show OBJ to OBJ;flip/set/turn OBJ for OBJ;flip/set/turn OBJ to OBJ;flip/set/turn OBJ with OBJ;gaze/l/look/peer/stare at OBJ with OBJ;grease/lubric OBJ with OBJ;hide OBJ behind OBJ;hide OBJ in OBJ;hide OBJ under OBJ;inflat OBJ with OBJ;insert/place/put/stuff/wedge OBJ across OBJ;insert/place/put/stuff/wedge OBJ agains OBJ;insert/place/put/stuff/wedge OBJ at OBJ;insert/place/put/stuff/wedge OBJ behind OBJ;insert/place/put/stuff/wedge OBJ betwee OBJ;insert/place/put/stuff/wedge OBJ by OBJ;insert/place/put/stuff/wedge OBJ in OBJ;insert/place/put/stuff/wedge OBJ over OBJ;insert/place/put/stuff/wedge OBJ under OBJ;lease/rent OBJ from OBJ;lift/raise OBJ with OBJ;light/start OBJ with OBJ;liquif/melt OBJ with OBJ;lock OBJ with OBJ;lower OBJ down OBJ;move OBJ with OBJ;move/roll/pull/tug/yank/press/push/shove/slide OBJ OBJ;open OBJ with OBJ;pick OBJ with OBJ;pour/spill OBJ from OBJ;pour/spill OBJ in OBJ;pour/spill OBJ on OBJ;press/push/shove OBJ off OBJ;press/push/shove OBJ throug OBJ;press/push/shove OBJ under OBJ;pump up OBJ with OBJ;read/skim OBJ with OBJ;roll/press/push/shove/slide OBJ to OBJ;slide OBJ under OBJ;spray OBJ on OBJ;spray OBJ with OBJ;squeez OBJ on OBJ;strike OBJ with OBJ;swing/thrust OBJ at OBJ;tell OBJ about OBJ;unlock OBJ with OBJ;what/what'/whats/who/who's/whos OBJ OBJ;", "max_word_length" : 6 } diff --git a/tools/test_games.py b/tools/test_games.py index 34076ae4..1566a9d2 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -158,7 +158,29 @@ 394, # InsideOrb (The sphere rotates and displays images.) ] }, - + "cutthroat.z3": { + '*': [ + 13, 14, 15, # Weasel arrives and leaves the player's location. + 69, # Talking with Johnny Red. + 92, 93, 94, 95, 96, # Waiting for Johnny Red. + 104, # McGinty + 133, 134, 135, 136, # Ferry arrives and leaves. + 203, # Causes a lot of changes. + 204, # Causes hunger. + 251, 252, # Weasel moves. + 262, # Causes hunger. + 285, # The sharks get you. + ], + "wait": [ + 5, 6, 7, 8, 9, 10, 11, 12, # You begin to feel hungry. + 105, # Causes hunger. + 210, 211, 212, 213, 244, 245, 246, 248, # Weasel's movements + 250, 253, # boat moves with you and other objects on it. + 254, 255, 256, 257, 258, 259, 260, 261, # Causes hunger. + ], + "ignore_commands": [ + ], + }, } SKIP_CHECK_STATE = { @@ -237,9 +259,27 @@ }, "cutthroat.z3": { 1: "wind watch", # Could be replaced by wait. - "wait": [12, 132, 133, 150, 190, 191, 216, 217, 218], # Needed to time the actions. + "look": [107], # Needed to time the actions. + "yes": [92, 93, 94, 95], # Waiting for Johnny Red. + "wait": [ # Needed to time the actions. + 12, 46, + 105, 106, # Wait for McGinty to leave. + 129, 130, 131, 132, 133, 134, 136, # Wait for the ferry to arrive and leave. + 148, 150, 152, 188, 189, 190, 191, + 194, # Waiting for delivery boy. + 214, 215, 216, 217, 218, # Waiting for Johnny Red to ask you the coordinates. + ], "noop": [ + "i", "read envelope", # Not needed to complete the game. + "look in closet", + "examine plate", + "look through window", + "look under bunk", + "examine compressor", + "examine air tank", + "examine glass case", + "examine stamps", ] }, "deephome.z5": { @@ -707,7 +747,13 @@ def parse_args(): cmds = ["look", "inventory", "wait", "examine me", "asd"] cmds += ["examine " + obj[0][0] for obj in objs.values()] for cmd_ in cmds: - if cmd_ in SKIP_PRECHECK_STATE.get(rom, {}).get("ignore_commands", []): + skip_precheck_state = ( + cmd_ in SKIP_PRECHECK_STATE.get(rom, {}).get(i, []) + or cmd_ in SKIP_PRECHECK_STATE.get(rom, {}).get("ignore_commands", []) + or i in SKIP_PRECHECK_STATE.get(rom, {}).get(cmd_, []) + ) + + if skip_precheck_state: continue env_.set_state(state) @@ -749,6 +795,7 @@ def parse_args(): if tmp.strip(): cmd = tmp + # last_env = env.copy() last_env_objs = env.get_world_objects(clean=False) last_env_objs_cleaned = env.get_world_objects(clean=True) From 815754d9c9a5053ee235330d804e8aa716c8b373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 21 Jan 2022 10:50:41 -0500 Subject: [PATCH 52/85] Noop check: deephome --- tools/test_games.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tools/test_games.py b/tools/test_games.py index 1566a9d2..c42d4706 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -181,6 +181,18 @@ "ignore_commands": [ ], }, + "deephome.z5": { + '*': [ + 14, # Dark Spirit arrives. + 184, # scraps become a cohesive whole, melting together + 303, # The gold coin is getting ready. + ], + "wait": [ + ], + "ignore_commands": [ + "examine patch", # You find a perfect four leaf clover. + ], + }, } SKIP_CHECK_STATE = { @@ -285,12 +297,16 @@ "deephome.z5": { "wait": [13, 183], # Needed to time the actions. "noop": [ - "read letter", # Not needed to complete the game. - "read warning note", # Not needed to complete the game. - "ask man about hammer", # Not needed to complete the game. - "ask man about eranti", # Not needed to complete the game. - "read sign", # Not needed to complete the game. - "ask spirit for name", # Not needed to complete the game. + "read letter", "read warning note", + "ask man about hammer", "ask man about eranti", + "read sign", "ask spirit for name", + "examine hatch", "examine cabinet", "search table", + "x door", "x generator", "x terrock", "x pipe", "x panel", + "x box", "x chest", + "look up terrock in leshosh", "look up kebarn in leshosh", + "look up partaim in fresto", "look up indanaz in leshosh", + "look up ternalim in fresto", "look up cholok in leshosh", + "look up yetzuiz in fresto", "look up squirrel in leshosh", ] }, "detective.z5": { From da86a5b0f328c11d56d4609b3812fa2480bdd96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 21 Jan 2022 10:51:47 -0500 Subject: [PATCH 53/85] Noop check: detective --- tools/test_games.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/test_games.py b/tools/test_games.py index c42d4706..967e8be1 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -193,6 +193,14 @@ "examine patch", # You find a perfect four leaf clover. ], }, + "detective.z5": { + '*': [ + ], + "wait": [ + ], + "ignore_commands": [ + ], + }, } SKIP_CHECK_STATE = { @@ -311,8 +319,8 @@ }, "detective.z5": { "noop": [ - "read paper", # Not needed to complete the game. - "read note", # Not needed to complete the game. + "read paper", "read note", + "inventory", ] }, "dragon.z5": { From 6f66fecd09c6a6c0600062a6927acf702038ca06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 21 Jan 2022 13:06:28 -0500 Subject: [PATCH 54/85] Noop check: dragon --- frotz/src/games/dragon.c | 11 +++++------ tools/test_games.py | 21 +++++++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/frotz/src/games/dragon.c b/frotz/src/games/dragon.c index 9b47a16e..8b142158 100644 --- a/frotz/src/games/dragon.c +++ b/frotz/src/games/dragon.c @@ -105,11 +105,10 @@ int dragon_ignore_attr_clr(zword obj_num, zword attr_idx) { } void dragon_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7) & ~(1 << 6); - // Clear attr 24 & 25 - for (i=1; i<=dragon_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; + for (int i=1; i<=dragon_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 24); + clear_attr(&objs[i], 25); } + + clear_attr(&objs[240], 17); // bunch of bananas } diff --git a/tools/test_games.py b/tools/test_games.py index 967e8be1..007870c7 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -178,8 +178,6 @@ 250, 253, # boat moves with you and other objects on it. 254, 255, 256, 257, 258, 259, 260, 261, # Causes hunger. ], - "ignore_commands": [ - ], }, "deephome.z5": { '*': [ @@ -187,18 +185,23 @@ 184, # scraps become a cohesive whole, melting together 303, # The gold coin is getting ready. ], - "wait": [ - ], "ignore_commands": [ "examine patch", # You find a perfect four leaf clover. ], }, - "detective.z5": { + "detective.z5": {}, + "dragon.z5": { '*': [ - ], - "wait": [ + 54, 55, # Troll is coming in. ], "ignore_commands": [ + "examine remains", "examine barrels", # You have found a pewter mug + "examine hollow tree stump", "examine hollow", "examine stump", "examine tree", # You have found a box of matches + "examine reeds", # You have found a sack + "examine booklet", # Needed to win the game. + "examine hessian", "examine brown hessian sack", # Finds a flute. + "examine bones", "examine pile", # Finds a green glass bottle. + "examine glass", # Finds a parchment. ], }, } @@ -325,7 +328,9 @@ }, "dragon.z5": { "noop": [ - "break bottle", # Not needed to complete the game. + "break bottle", + "examine table", "examine parchment", "examine chair", + "examine carvings", "examine goblin", ] }, "enchanter.z3": { From de7c43e3b82b4857791d4f0a4c06032b5f6ca6b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 21 Jan 2022 13:30:12 -0500 Subject: [PATCH 55/85] Util function to clear a property of a zobject --- frotz/src/interface/frotz_interface.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index f51e7ea2..b293b16f 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -1364,6 +1364,15 @@ void clear_attr(zobject* obj, unsigned char attr_id) { obj->attr[attr_id / 8] &= mask; } +void clear_prop(zobject* obj, unsigned char prop_id) { + for (int i=0; i < JERICHO_NB_PROPERTIES; ++i) { + if (obj->prop_ids[i] == prop_id) { + memset(&obj->prop_data[i * JERICHO_PROPERTY_LENGTH], 0, obj->prop_lengths[i] * sizeof(zbyte)); + break; + } + } +} + //==========================// // Function Instantiations // //==========================// From fce1a8739fe6419ff2fdb1f0af6cf5f0957527ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 21 Jan 2022 14:06:31 -0500 Subject: [PATCH 56/85] Noop check: enchanter --- frotz/src/games/enchanter.c | 37 +++++++++++++++++++++++++-------- tools/test_games.py | 41 +++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/frotz/src/games/enchanter.c b/frotz/src/games/enchanter.c index f8bf3dbd..acb719df 100644 --- a/frotz/src/games/enchanter.c +++ b/frotz/src/games/enchanter.c @@ -98,11 +98,32 @@ int enchanter_ignore_attr_clr(zword obj_num, zword attr_idx) { } void enchanter_clean_world_objs(zobject* objs) { - // int i; - // char mask; - // mask = ~1; - // // Clear attr 15 - // for (i=1; i<=enchanter_get_num_world_objs(); ++i) { - // objs[i].attr[1] &= mask; - // } -} + // int i; + // char mask; + // mask = ~1; + // // Clear attr 15 + // for (i=1; i<=enchanter_get_num_world_objs(); ++i) { + // objs[i].attr[1] &= mask; + // } + clear_attr(&objs[55], 10); // cretin a.k.a. the player + clear_attr(&objs[122], 17); // Temple + clear_attr(&objs[87], 17); // Cell + clear_attr(&objs[142], 17); // Courtyard + clear_attr(&objs[66], 17); // Courtyard + clear_attr(&objs[190], 17); // Courtyard + clear_attr(&objs[116], 17); // Courtyard + clear_attr(&objs[167], 16); // Frobozz portrait + clear_attr(&objs[179], 16); // Flathead portrait + clear_attr(&objs[242], 16); // no-name object + clear_attr(&objs[27], 17); // Kitchen + clear_attr(&objs[64], 17); // North Gate + clear_attr(&objs[64], 15); // North Gate + clear_attr(&objs[43], 17); // East Hall + clear_attr(&objs[43], 15); // East Hall + clear_attr(&objs[47], 15); // Winding Stair + + // Completely ignore the 'pseudo' object. + strcpy(&objs[252].name, "pseudo"); // Its name reflects what the player's focus. + clear_prop(&objs[252], 9); + +} \ No newline at end of file diff --git a/tools/test_games.py b/tools/test_games.py index 007870c7..75f47bf7 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -204,6 +204,25 @@ "examine glass", # Finds a parchment. ], }, + "enchanter.z3": { + '*': [ + 148, # You get dragged to the Cell. + 150, # You get dragged to the Sacrificial Altar. + 176, 177, 178, 179, 180, 181, # The Adventurer moves. + 204, 205, # Lurking evil presence is around. + 262, 263, 264, # The warlock Krill kills you. + ], + "wait": [ + 67, # Hearing a voice. + 68, # group of four hunched and hairy shapes walks into your presence + 149, # You get killed in the Cell. + 175, # The Adventurer leaves the room. + ], + "ignore_commands": [ + "examine tracks", # Needed for progression. + "examine walls", # Needed for progression. + ], + }, } SKIP_CHECK_STATE = { @@ -336,21 +355,17 @@ "enchanter.z3": { 16: "read scroll", # Not actually needed for learning the spell. 202: "read map", # Not actually needed for completing the game. + 30: "examine it", # Not actually needed for completing the game. "wait": [84], # Needed to time the actions. + "look": [127], "noop": [ - "read shredded scroll", # Not needed to complete the game. - "read crumpled scroll", # Not needed to complete the game. - "read faded scroll", # Not needed to complete the game. - "read damp scroll", # Not needed to complete the game. - "read of unseen terror", # Not needed to complete the game. - "read frayed scroll", # Not needed to complete the game. - "read gold leaf scroll", # Not needed to complete the game. - "read stained scroll", # Not needed to complete the game. - "read brittle scroll", # Not needed to complete the game. - "read black scroll", # Not needed to complete the game. - "read powerful scroll", # Not needed to complete the game. - "read vellum scroll", # Not needed to complete the game. - "read ornate scroll", # Not needed to complete the game. + "read shredded scroll", "read crumpled scroll", "read faded scroll", + "read damp scroll", "read of unseen terror", "read frayed scroll", + "read gold leaf scroll", "read stained scroll", "read brittle scroll", + "read black scroll", "read powerful scroll", "read vellum scroll", + "read ornate scroll", + "examine post", + "examine dusty book", ] }, "enter.z5": { From 0b6fbab8bffc7c4ad0f61189db0b29198a34dfc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 21 Jan 2022 14:26:29 -0500 Subject: [PATCH 57/85] Noop check: enter --- frotz/src/games/enter.c | 15 ++++++++++----- jericho/game_info.py | 4 ++-- tools/test_games.py | 11 +++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/frotz/src/games/enter.c b/frotz/src/games/enter.c index c516bdb9..234b9598 100644 --- a/frotz/src/games/enter.c +++ b/frotz/src/games/enter.c @@ -24,18 +24,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // The Enterprise Incidents: http://ifdb.tads.org/viewgame?id=ld1f3t5epeagilfz -const zword enter_special_ram_addrs[7] = { +const zword enter_special_ram_addrs[5] = { 9667, // Say -120 to garrulous - 10249, // Take candygram / talk to queenie + // 10249, // Take candygram / talk to queenie 11059, // Open door and and talk with Ms. Empirious. 11607, // Put gram in basket - 11219, // Talk to Emperius / take jar + // 11219, // Talk to Emperius / take jar 10644, // Say firefly to jim 10259, // Ask Queenie to dance; Also 10264 }; zword* enter_ram_addrs(int *n) { - *n = 7; + *n = 5; return enter_special_ram_addrs; } @@ -48,7 +48,7 @@ char* enter_clean_observation(char* obs) { char* pch; pch = strchr(obs, '>'); if (pch != NULL) { - *(pch-2) = '\0'; + *(pch) = '\0'; } return obs+1; } @@ -102,4 +102,9 @@ int enter_ignore_attr_clr(zword obj_num, zword attr_idx) { } void enter_clean_world_objs(zobject* objs) { + clear_attr(&objs[78], 25); // Ms. Empirious + + clear_prop(&objs[170], 40); // North-South Hall--South End's counter. + clear_prop(&objs[140], 40); // Room 8's counter. + clear_prop(&objs[146], 40); // Hall Near Office's counter. } diff --git a/jericho/game_info.py b/jericho/game_info.py index 90da5e28..8c2752c2 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -165,8 +165,8 @@ "rom": "enter.z5", "seed" : 0, # Walkthrough obtained by issuing the command WALKTHRU. - "walkthrough": "open door/talk to alltext/3/g/3/g/1/1/talk to queenie/2/g/3/g/4/look at mural/look at queenie/4/n/take list/take envelope/read list/s/close door/w/n/e/give gram to meghan/w/s/s/e/w/s/talk to Stephanie/1/g/2/look at Stephanie/put gram in basket/3/open door/w/give gram to Danielle/say -120 to garrulous/e/n/n/n/n/wear badge/open door/knock on door/talk to empirious/1/w/take jar/give gram to ed/e/nw/talk to woman/1/w/w/e/n/talk to reunite/1/g/3/s/w/w/s/give gram to Alicia/give gram to andrea/n/e/n/say rat to Picasso/give gram to silas/s/e/n/give pass to reunite/s/se/s/s/w/1/give gram to jim/say firefly to jim/look at list/talk to alltext/2/e/give gram to queenie/talk to queenie/4/e/open door/n", - "grammar" : "about;awake/awaken/wake;awake/awaken/wake up;bother/curses/darn/drat;brief/normal;carry/hold/take inventory;damn/fuck/shit/sod;die/q/quit;dive/swim;exit/out/outside/stand;full/fullscore;full/fullscore score;get out/off/up;hear/listen;hint;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;intro;l/look;leave/go/run/walk;long/verbose;menu;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;pray;restart;restore;save;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie;sing;smell/sniff;smile;sorry;stand up;think;verify;version;wait/z;walkthru;wave;wink;y/yes;0;1;2;3;4;adjust/set OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;carry/hold/take off OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;cross/enter/go/run/walk OBJ;damn/fuck/shit/sod OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;get in/into/on/onto OBJ;get off OBJ;get/carry/hold/take OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;knock on OBJ;l/look at OBJ;l/look inside/in/into/through OBJ;l/look through OBJ;l/look under OBJ;leave OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;lock OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;put OBJ down;put down OBJ;put on OBJ;read/check/describe/examine/watch/x OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;smell/sniff OBJ;smile at OBJ;squash/squeeze OBJ;stand on OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;talk to OBJ;taste OBJ;wave OBJ;wink at OBJ;adjust/set OBJ to OBJ;answer/say/shout/speak OBJ to OBJ;ask OBJ about OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/hold/take OBJ off OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;consult OBJ about OBJ;consult OBJ on OBJ;dig OBJ with OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ to/into/on/onto OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;put OBJ in/inside/into OBJ;read OBJ in OBJ;read about OBJ in OBJ;remove/get/carry/hold/take OBJ from OBJ;tell OBJ about OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", + "walkthrough": "open door/talk to alltext/3/talk to alltext/3/talk to alltext/1/1/talk to queenie/2/talk to queenie/3/talk to queenie/4/look at mural/look at queenie/4/n/take list/take envelope/read list/s/close door/w/n/e/give gram to meghan/w/s/s/e/w/s/talk to Stephanie/1/talk to Stephanie/2/look at Stephanie/put gram in basket/3/open door/w/give gram to Danielle/say -120 to garrulous/e/n/n/n/n/wear badge/open door/knock on door/talk to empirious/1/w/take jar/give gram to ed/e/nw/talk to woman/1/w/w/e/n/talk to reunite/1/talk to reunite/3/s/w/w/s/give gram to Alicia/give gram to andrea/n/e/n/say rat to Picasso/give gram to silas/s/e/n/give pass to reunite/s/se/s/s/w/1/give gram to jim/say firefly to jim/look at list/talk to alltext/2/e/give gram to queenie/talk to queenie/4/e/open door/n", + "grammar" : "again/g;about;awake/awaken/wake;awake/awaken/wake up;bother/curses/darn/drat;brief/normal;carry/hold/take inventory;damn/fuck/shit/sod;die/q/quit;dive/swim;exit/out/outside/stand;full/fullscore;full/fullscore score;get out/off/up;hear/listen;hint;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;intro;l/look;leave/go/run/walk;long/verbose;menu;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;pray;restart;restore;save;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie;sing;smell/sniff;smile;sorry;stand up;think;verify;version;wait/z;walkthru;wave;wink;y/yes;0;1;2;3;4;adjust/set OBJ;attach/fasten/fix/tie OBJ;attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;carry/hold/take off OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;cross/enter/go/run/walk OBJ;damn/fuck/shit/sod OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;get in/into/on/onto OBJ;get off OBJ;get/carry/hold/take OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;knock on OBJ;l/look at OBJ;l/look inside/in/into/through OBJ;l/look through OBJ;l/look under OBJ;leave OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;lock OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;put OBJ down;put down OBJ;put on OBJ;read/check/describe/examine/watch/x OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;smell/sniff OBJ;smile at OBJ;squash/squeeze OBJ;stand on OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;talk to OBJ;taste OBJ;wave OBJ;wink at OBJ;adjust/set OBJ to OBJ;answer/say/shout/speak OBJ to OBJ;ask OBJ about OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/hold/take OBJ off OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;consult OBJ about OBJ;consult OBJ on OBJ;dig OBJ with OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ to/into/on/onto OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;put OBJ in/inside/into OBJ;read OBJ in OBJ;read about OBJ in OBJ;remove/get/carry/hold/take OBJ from OBJ;tell OBJ about OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index 75f47bf7..a150b02b 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -223,6 +223,13 @@ "examine walls", # Needed for progression. ], }, + "enter.z5": { + '*': [ + 5, # Mr. Alltext starts to leave the cafeteria but talks to you. + 15, # Judy arrives. + 37, # Stephanie leaves. + ], + }, } SKIP_CHECK_STATE = { @@ -372,6 +379,10 @@ 6: "1", # Could also say nothing, i.e. '0'. 20: "read list", # Not needed to complete the game. 62: "w", # Not needed to complete the game. + "noop": [ + "look at mural", + "look at list", + ], }, "gold.z5": { 146: "open washing machine", # (door is jammed) Not needed to complete the game. From c20f5ea344fb3c5c77e5b2b60cbf21061c1306d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 21 Jan 2022 15:32:17 -0500 Subject: [PATCH 58/85] Noop check: gold --- frotz/src/games/gold.c | 18 +++++++++++++++--- tools/test_games.py | 42 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/frotz/src/games/gold.c b/frotz/src/games/gold.c index 77fb2bd4..d8f4522d 100644 --- a/frotz/src/games/gold.c +++ b/frotz/src/games/gold.c @@ -24,8 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Goldilocks is a FOX!: http://ifdb.tads.org/viewgame?id=59ztsy9p01avd6wp -const zword gold_special_ram_addrs[9] = { - 1025, // Eating porridge +const zword gold_special_ram_addrs[8] = { + // 1025, // Eating porridge 20672, // Move wardrobe (Also 23313) 18314, // Oil secateurs 8251, // TV Channel @@ -37,7 +37,7 @@ const zword gold_special_ram_addrs[9] = { }; zword* gold_ram_addrs(int *n) { - *n = 9; + *n = 8; return gold_special_ram_addrs; } @@ -108,4 +108,16 @@ int gold_ignore_attr_clr(zword obj_num, zword attr_idx) { } void gold_clean_world_objs(zobject* objs) { + for (int i=1; i<=gold_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 25); + clear_attr(&objs[i], 31); + } + + clear_prop(&objs[31], 40); // (suppressor)'s counter + clear_prop(&objs[262], 40); // Wolf's eyes in forest's counter + clear_prop(&objs[259], 40); // Wolf at the door's counter + clear_prop(&objs[258], 40); // Package arrives' counter + clear_prop(&objs[261], 40); // Cave system fills with porridge's counter + + objs[252].parent = 0; // Big Bad Wolf } diff --git a/tools/test_games.py b/tools/test_games.py index a150b02b..ecb1be7f 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -228,6 +228,14 @@ 5, # Mr. Alltext starts to leave the cafeteria but talks to you. 15, # Judy arrives. 37, # Stephanie leaves. + 207, # A bell rings as the package arrives. + ], + }, + "gold.z5": { + "ignore_commands": [ + "examine ash", + "examine rotting", "examine skeleton", # Takes the blackened metal poker. + "examine sludge", # Finds a small key. ], }, } @@ -385,10 +393,30 @@ ], }, "gold.z5": { - 146: "open washing machine", # (door is jammed) Not needed to complete the game. - 178: "plug in television", # (already plugged in) Not needed to complete the game. - 179: "watch television", # (nothing on the screen) Not needed to complete the game. - 309: "ask fairy godmother about horse", # Not needed to complete the game. + 146: "open washing machine", # (door is jammed) + 178: "plug in television", # (already plugged in) + 179: "watch television", # (nothing on the screen) + 198: "watch television", # (cookery programme) + 166: "cut cable", # (too rusty) + 260: "get magic porridge pot", # (too big) + 340: "get bearskin rug", # (already have that) + "noop": [ + "inventory", "look", + "ask pedlar about suitcase", "ask fairy godmother about horse", + "ask pedlar about beans", "ask wolf about pigs", + 'ask fairy godmother about cinderella', + "examine vegetable plot", "examine packet", + "examine plant pots", "examine table", "examine fireplace", + "examine dresser", "examine washing machine", + "examine mousetrap", "examine porridge oats", + "examine wardrobe", "get dumbells", 'examine tiny metal', + 'examine fusebox', 'examine volt meter', 'examine switch a', + 'examine switch b', 'examine large chair', 'examine electrodes', + 'examine television', 'examine remote control', 'examine dining table', + 'examine toaster', 'examine toaster', 'read leaflet', + 'read instructions', 'examine bench', 'examine dynamite', + 'examine huge bed', 'examine snooker table', 'examine pockets', + ], }, "hhgg.z3": { 56: "push switch", # Not needed to complete the game. @@ -786,6 +814,7 @@ def parse_args(): if args.very_verbose: print(obs) + commands_to_ignore = [] walkthrough = env.get_walkthrough() for i, cmd in tqdm(list(enumerate(walkthrough))): cmd = cmd.lower() @@ -900,8 +929,13 @@ def parse_args(): # alt4 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) print(f"Testing walkthrough replacing '{cmd}' with 'look'...") alt5 = test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) + + if all((alt1, alt2, alt5)): + commands_to_ignore.append(cmd) + breakpoint() + print(repr(commands_to_ignore)) if not env.victory(): print(colored("FAIL", 'red')) if args.debug: From b2d277ff2126865c8a1c22360e5c08d362895370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 28 Jan 2022 17:12:46 -0500 Subject: [PATCH 59/85] Noop check: hhgg --- frotz/src/games/hhgg.c | 29 +++++++++++++++-- jericho/game_info.py | 2 +- tools/test_games.py | 74 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 4 deletions(-) diff --git a/frotz/src/games/hhgg.c b/frotz/src/games/hhgg.c index bf8ecb98..8b282ad4 100644 --- a/frotz/src/games/hhgg.c +++ b/frotz/src/games/hhgg.c @@ -30,12 +30,10 @@ const zword hhgg_special_ram_addrs[18] = { 8169, // Beer 8333, // Access Improbability Drive 8115, // Beast - 8701, // Nutrimat 8325, // Put bit in tea 8053, // Sensations 8087, // Autopilot 8091, // Steering - 8085, // Crowd 8171, // give towel to Arthur 8185, // Walk around bulldozer 8187, // Prossner lie in the mud @@ -43,6 +41,8 @@ const zword hhgg_special_ram_addrs[18] = { 8349, // Marvin, open hatch 8119, // Enjoy poetry. 8105, // Spongy gray maze + 8327, // Put small plug in plotter + 2428, // Put large plug in large receptacle }; zword* hhgg_ram_addrs(int *n) { @@ -117,4 +117,29 @@ int hhgg_ignore_attr_clr(zword obj_num, zword attr_idx) { } void hhgg_clean_world_objs(zobject* objs) { + clear_attr(&objs[31], 17); // it + clear_attr(&objs[166], 6); // bulldozer + clear_attr(&objs[135], 5); // dog + clear_attr(&objs[70], 5); // hostess + + // objs[156].parent = 0; // thing aunt gave know is + objs[215].parent = 0; // Marvin + + for (int i=1; i<=hhgg_get_num_world_objs(); ++i) { + if (i != 127) { + clear_attr(&objs[i], 25); + clear_attr(&objs[i], 27); + } + } + + // Completely ignore the 'pseudo' object. + strcpy(&objs[48].name, "pseudo"); // Its name reflects what the player's focus. + clear_prop(&objs[48], 29); + + + // Track whether the Nutrimat has been activated. + int N = 23; // Use last property slot. + objs[209].prop_ids[N-1] = 63; + objs[209].prop_lengths[N-1] = 1; + objs[209].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH] = (zmp[8339] > 0); } diff --git a/jericho/game_info.py b/jericho/game_info.py index 8c2752c2..26af283a 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -185,7 +185,7 @@ "rom": "hhgg.z3", "seed" : 4, # Walkthrough adapted from http://www.eristic.net/games/infocom/hhg.html - 'walkthrough': 'Get Up/Turn on Light/Get Gown/Wear Gown/Look in pocket/take analgesic/Get all/South/Get Mail/South/Lie Down In Front Of Bulldozer/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Follow Ford/Enter Pub/Look Shelf/Buy Sandwich/Drink Beer/Drink Beer/Drink Beer/Exit/Feed dog sandwich/Get towel/Wait/wait/wait/wait/wait/wait/wait/wait/get device/push green button/wait/wait/wait/wait/smell/examine shadow/Eat Peanuts/Take off gown/Put Gown on hook/put towel over drain/wait/get satchel/put satchel in front of panel/put mail on satchel/push dispenser button/get gown/wear gown/get all/push switch/wait/wait/wait/wait/wait/wait/wait/enjoy poetry/wait/wait/wait/wait/wait/type \"bleem\"/get plotter/wait/wait/wait/examine thumb/press green button/wait/wait/wait/wait/listen/Aft/read brochure/wait/wait/inventory/take pincer/put all into thing/d/port/touch pad/get cup/starboard/aft/aft/yes/yes/aft/no/look/look/drop thing/get rasp/get pliers/put rasp into thing/put pliers into thing/get improbability drive/fore/fore/up/drop drive/drop cup/wait/wait/drop plotter/put small plug in plotter/put bit in cup/turn on drive/wait/wait/wait/wait/smell/look at shadow/say my name/e/examine memorial/get sharp stone/put towel on your head/carve my name on the memorial/remove towel/drop stone/w/sw/get interface/z/z/z/z/z/hear the dark/aft/aft/up/d/port/open panel/take circuit/insert interface in nutrimat/close panel/touch pad/starboard/up/put large plug in large receptacle/z/turn on drive/d/port/get tea/starboard/up/drop tea/z/z/z/z/z/z/z/z/z/z/remove bit/put bit in tea/turn on drive/z/touch/touch/drink liquid/examine arthur/drop wine/get fluff/open bag/put fluff in bag/get wine/z/z/z/z/z/z/hear/aft/aft/up/open handbag/get tweezers/get fluff/put all in thing/turn on drive/z/touch/touch/touch/touch/drink liquid/get flowerpot/put it in thing/examine thumb/press red button/give thumb to robot/z/show warranty/press green button/z/z/z/z/hear/aft/aft/up/turn on drive/see/see/see/see/examine light/look under seat/unlock box with key/get glass/get wrench/push autopilot button/steer towards rocky spire/z/z/z/stand up/out/wave at crowd/z/z/z/guards, drop rifles/Trillian, shoot rifles/enter/z/z/z/z/hear/aft/aft/aft/down/get fluff/get tools/up/fore/up/turn on drive/see/examine light/n/open satchel/get fluff/get towel/give towel to Arthur/idiot/walk around bulldozer/Prosser, lie in the mud/s/w/buy beer/buy peanuts/drink beer/drink beer/e/n/give fluff to Arthur/z/z/z/z/z/z/z/hear/aft/aft/up/i/turn on drive/hear/hear/hear/z/hear/hear/hear/hear/aft/get awl/z/z/z/z/n/n/n/get particule/z/z/z/z/hear/aft/aft/up/remove bit/take tea/i/take no tea/i/plant seat fluff in flowerpot/plant satchel fluff in flowerpot/plant jacket fluff in flowerpot/plant pocket fluff in flowerpot/z/z/z/port/examine plant/get fruit/d/aft/open door/drink tea/port/get chisel/Marvin, open the hatch/starboard/d/eat fruit/drop all but pincer/take pincer/drop thing/i/starboard/z/z/give pincer to Marvin/port/d', + 'walkthrough': 'Get Up/Turn on Light/Get Gown/Wear Gown/Look in pocket/take analgesic/Get all/South/Get Mail/South/Lie Down In Front Of Bulldozer/Wait/Wait/Wait/Wait/Wait/Wait/Wait/Follow Ford/Enter Pub/Look Shelf/Buy Sandwich/Drink Beer/Drink Beer/Drink Beer/Exit/Feed dog sandwich/Get towel/Wait/wait/wait/wait/wait/wait/wait/wait/get device/push green button/wait/wait/wait/wait/smell/examine shadow/Eat Peanuts/Take off gown/Put Gown on hook/put towel over drain/wait/get satchel/put satchel in front of panel/put mail on satchel/push dispenser button/get gown/wear gown/get all/push switch/wait/wait/wait/wait/wait/wait/wait/enjoy poetry/wait/wait/wait/wait/wait/type \"bleem\"/get plotter/wait/wait/wait/examine thumb/press green button/wait/wait/wait/wait/listen/Aft/read brochure/wait/wait/inventory/take pincer/put all into thing/d/port/touch pad/get cup/starboard/aft/aft/yes/yes/aft/no/look/look/drop thing/get rasp/get pliers/put rasp into thing/put pliers into thing/get improbability drive/fore/fore/up/drop drive/drop cup/wait/wait/drop plotter/put small plug in plotter/put bit in cup/turn on drive/wait/wait/wait/wait/smell/look at shadow/say my name/e/examine memorial/get sharp stone/put towel on your head/carve my name on the memorial/remove towel/drop stone/w/sw/get interface/z/z/z/z/z/hear the dark/aft/aft/up/d/port/open panel/take circuit/insert interface in nutrimat/close panel/touch pad/starboard/up/put large plug in large receptacle/z/turn on drive/d/port/get tea/starboard/up/drop tea/z/z/z/z/z/z/z/z/z/z/remove bit/put bit in tea/turn on drive/z/touch/touch/drink liquid/examine arthur/drop wine/get fluff/open bag/put fluff in bag/get wine/z/z/z/z/z/z/hear/aft/aft/up/open handbag/get tweezers/get fluff/put all in thing/turn on drive/z/touch/touch/touch/touch/drink liquid/get flowerpot/put it in thing/examine thumb/press red button/give thumb to robot/z/show warranty/press green button/z/z/z/z/hear/aft/aft/up/turn on drive/see/see/see/see/examine light/look under seat/unlock box with key/get glass/get wrench/push autopilot button/steer towards rocky spire/z/z/z/stand up/out/z/z/z/z/guards, drop rifles/Trillian, shoot rifles/enter/z/z/z/z/hear/aft/aft/aft/down/get fluff/get tools/up/fore/up/turn on drive/see/examine light/n/open satchel/get fluff/get towel/give towel to Arthur/idiot/walk around bulldozer/Prosser, lie in the mud/s/w/buy beer/buy peanuts/drink beer/drink beer/e/n/give fluff to Arthur/z/z/z/z/z/z/z/hear/aft/aft/up/i/turn on drive/hear/hear/hear/z/hear/hear/hear/hear/aft/get awl/z/z/z/z/n/n/n/get particule/z/z/z/z/hear/aft/aft/up/remove bit/take tea/i/take no tea/i/plant seat fluff in flowerpot/plant satchel fluff in flowerpot/plant jacket fluff in flowerpot/plant pocket fluff in flowerpot/z/z/z/port/examine plant/get fruit/d/aft/open door/drink tea/port/get chisel/Marvin, open the hatch/starboard/d/eat fruit/drop all but pincer/take pincer/drop thing/i/starboard/z/z/give pincer to Marvin/port/d', "grammar" : "again/g;answer/reply;applau/cheer/clap;argue/protes;blast/fire/shoot;bleem/frippi/gashee/lyshus/misera/morpho/thou/venchi/wimbgu;brief;crawl/kneel/peek;depart/exit/withdr;diagno;disrob;dive/jump/leap;doze/nap/snooze;enter;escape/flee;footno;gaze/l/look/stare;go/procee/run/step/walk;hello/hi;help/hint/hints;hide;hitch/hitchh;hop/skip;howl/scream/shout/yell;idiot;invent/i/i'm/im;leave;no;ok/okay/sure/y/yes;panic;q/quit;relax;restar;restor;rise/stand;save;say/speak/talk;score;script;sleep;smile;stay/wait/z;super/superb;type;unscri;verbos;versio;wave;why;activa/start OBJ;addres/tell OBJ;answer/reply OBJ;answer/reply to OBJ;apprec OBJ;approa OBJ;assaul/attack/fight/hit/kill/murder/punch/slap/strike OBJ;attach/fasten/secure/tie OBJ;attach/fasten/secure/tie togeth OBJ;awake/rouse/wake OBJ;awake/rouse/wake up OBJ;bite OBJ;blast/fire/shoot OBJ;block/stop OBJ;board/embark OBJ;break/crack/damage/demoli/destro/smash/wreck OBJ;break/crack/damage/demoli/destro/smash/wreck down OBJ;brush OBJ;buy/order/purcha OBJ;call/phone OBJ;carry/catch/get/grab/hold/take OBJ;carry/catch/get/grab/hold/take dresse OBJ;carry/catch/get/grab/hold/take drunk OBJ;carry/catch/get/grab/hold/take off OBJ;carry/catch/get/grab/hold/take out OBJ;carry/catch/get/grab/hold/take undres OBJ;chase/follow/pursue OBJ;clean/tidy/wash OBJ;clean/tidy/wash up OBJ;climb/scale OBJ;climb/scale down OBJ;climb/scale over OBJ;climb/scale up OBJ;climb/scale/dive/jump/leap/go/procee/run/step/walk throug OBJ;climb/scale/rest/sit/squat/carry/catch/get/grab/hold/take in OBJ;climb/scale/rest/sit/squat/carry/catch/get/grab/hold/take on OBJ;close/shut OBJ;close/shut off OBJ;count OBJ;debark/disemb OBJ;depart/exit/withdr OBJ;descen OBJ;descri/examin/inspec/observ/scour/see/study OBJ;descri/examin/inspec/observ/scour/see/study on OBJ;descri/examin/inspec/observ/scour/see/study/gaze/l/look/stare in OBJ;descri/examin/inspec/observ/scour/see/study/gaze/l/look/stare/frisk/rummag/search for OBJ;devour/eat/gobble/ingest OBJ;dig in OBJ;dig throug OBJ;dig with OBJ;discon/unplug OBJ;dive/jump/leap across OBJ;dive/jump/leap from OBJ;dive/jump/leap off OBJ;dive/jump/leap/go/procee/run/step/walk in OBJ;dive/jump/leap/go/procee/run/step/walk out OBJ;dive/jump/leap/go/procee/run/step/walk over OBJ;doff/remove/shed OBJ;don/wear OBJ;donate/give/hand/offer/sell up OBJ;draw/open/part OBJ;draw/open/part up OBJ;drink/guzzle/imbibe/quaff/sip/swallo/swill OBJ;drink/guzzle/imbibe/quaff/sip/swallo/swill from OBJ;drop OBJ;enjoy OBJ;enter OBJ;escape/flee OBJ;escape/flee from OBJ;exting OBJ;feed OBJ;feel/pat/pet/rub/touch OBJ;fill OBJ;find/seek OBJ;fix/repair/unjam OBJ;flick/flip/switch/toggle/turn OBJ;flick/flip/switch/toggle/turn around OBJ;flick/flip/switch/toggle/turn off OBJ;flick/flip/switch/toggle/turn on OBJ;footno OBJ;free/unatta/unfast/unknot/untie OBJ;frisk/rummag/search OBJ;frisk/rummag/search in OBJ;gaze/l/look/stare OBJ;gaze/l/look/stare around OBJ;gaze/l/look/stare at OBJ;gaze/l/look/stare behind OBJ;gaze/l/look/stare down OBJ;gaze/l/look/stare on OBJ;gaze/l/look/stare out OBJ;gaze/l/look/stare throug OBJ;gaze/l/look/stare under OBJ;gaze/l/look/stare up OBJ;go/procee/run/step/walk OBJ;go/procee/run/step/walk around OBJ;go/procee/run/step/walk away OBJ;go/procee/run/step/walk behind OBJ;go/procee/run/step/walk down OBJ;go/procee/run/step/walk on OBJ;go/procee/run/step/walk to OBJ;go/procee/run/step/walk up OBJ;hear OBJ;hello/hi OBJ;hide behind OBJ;hide under OBJ;howl/scream/shout/yell at OBJ;howl/scream/shout/yell to OBJ;hurl/throw/toss OBJ;hurl/throw/toss in OBJ;i/i'm/im OBJ;insert/lay/place/put/stuff down OBJ;insert/lay/place/put/stuff on OBJ;kick OBJ;kiss OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;leave OBJ;lick/taste OBJ;lie/reclin before OBJ;lie/reclin down OBJ;lie/reclin in OBJ;lie/reclin on OBJ;lift/raise OBJ;lift/raise up OBJ;light OBJ;listen to OBJ;lock OBJ;lower OBJ;make OBJ;move/pull OBJ;move/pull togeth OBJ;pay for OBJ;pick OBJ;pick up OBJ;point/steer at OBJ;point/steer to OBJ;pour/spill/sprink OBJ;press/push on OBJ;press/push/slide OBJ;rape OBJ;read/skim OBJ;refuse OBJ;replac OBJ;rest/sit/squat down OBJ;rise/stand before OBJ;rise/stand in OBJ;rise/stand on OBJ;rise/stand/carry/catch/get/grab/hold/take up OBJ;rotate/spin/whirl OBJ;save/help/hint/hints OBJ;say/speak/talk OBJ;say/speak/talk to OBJ;shake OBJ;sleep in OBJ;sleep on OBJ;smell/sniff/whiff OBJ;smile at OBJ;stay/wait/z for OBJ;thank/thanks OBJ;type on OBJ;unlock OBJ;wave OBJ;wave at OBJ;wave to OBJ;what/what'/whats OBJ;what/what'/whats about OBJ;where/wheres OBJ;who/whos OBJ;ask/consul/query OBJ about OBJ;ask/consul/query OBJ for OBJ;ask/consul/query OBJ on OBJ;assaul/attack/fight/hit/kill/murder/punch/slap/strike OBJ with OBJ;blast/fire/shoot OBJ at OBJ;blast/fire/shoot OBJ with OBJ;block/stop OBJ with OBJ;break/crack/damage/demoli/destro/smash/wreck OBJ with OBJ;brush OBJ with OBJ;bury/plant OBJ in OBJ;call/phone OBJ on OBJ;call/phone OBJ with OBJ;carry/catch/get/grab/hold/take OBJ in OBJ;carry/catch/get/grab/hold/take OBJ off OBJ;carry/catch/get/grab/hold/take OBJ out OBJ;carve/inscri/scratc/write OBJ in OBJ;carve/inscri/scratc/write OBJ on OBJ;carve/inscri/scratc/write OBJ with OBJ;connec/plug/attach/fasten/secure/tie OBJ to OBJ;cover OBJ with OBJ;cut/slice OBJ with OBJ;cut/slice throug OBJ with OBJ;dangle/drop/hang/insert/lay/place/put/stuff OBJ in OBJ;descri/examin/inspec/observ/scour/see/study OBJ throug OBJ;doff/remove/shed/carry/catch/get/grab/hold/take OBJ from OBJ;drape/wrap OBJ in OBJ;draw/open/part OBJ with OBJ;drop OBJ down OBJ;drop/insert/lay/place/put/stuff OBJ before OBJ;drop/insert/lay/place/put/stuff/drape/wrap OBJ on OBJ;feed/donate/give/hand/offer/sell OBJ OBJ;feed/donate/give/hand/offer/sell OBJ to OBJ;feel/pat/pet/rub/touch OBJ with OBJ;flick/flip/switch/toggle/turn OBJ to OBJ;flick/flip/switch/toggle/turn OBJ with OBJ;flick/flip/switch/toggle/turn off OBJ OBJ;flick/flip/switch/toggle/turn on OBJ OBJ;gaze/l/look/stare at OBJ throug OBJ;hang OBJ from OBJ;hang OBJ on OBJ;hurl/throw/toss OBJ at OBJ;hurl/throw/toss OBJ in OBJ;hurl/throw/toss OBJ off OBJ;hurl/throw/toss OBJ over OBJ;hurl/throw/toss OBJ throug OBJ;hurl/throw/toss OBJ to OBJ;hurl/throw/toss OBJ up OBJ;insert/lay/place/put/stuff OBJ across OBJ;insert/lay/place/put/stuff OBJ at OBJ;insert/lay/place/put/stuff OBJ behind OBJ;insert/lay/place/put/stuff OBJ down OBJ;insert/lay/place/put/stuff/attach/fasten/secure/tie/drape/wrap OBJ around OBJ;insert/lay/place/put/stuff/drape/wrap OBJ over OBJ;lock OBJ with OBJ;move/pull/press/push/flick/flip/switch/toggle/turn/hurl/throw/toss OBJ OBJ;my OBJ OBJ;pick OBJ with OBJ;plug OBJ in OBJ;plug in OBJ in OBJ;plug in OBJ to OBJ;point/steer OBJ at OBJ;point/steer OBJ to OBJ;pour/spill/sprink OBJ in OBJ;pour/spill/sprink OBJ on OBJ;pour/spill/sprink OBJ over OBJ;press/push/insert/lay/place/put/stuff/slide OBJ under OBJ;read/skim OBJ throug OBJ;read/skim OBJ with OBJ;shake OBJ with OBJ;show OBJ OBJ;show OBJ to OBJ;tell OBJ OBJ;tell OBJ about OBJ;tell OBJ to OBJ;unlock OBJ with OBJ;water OBJ with OBJ;what/what'/whats OBJ OBJ;", "max_word_length" : 6 } diff --git a/tools/test_games.py b/tools/test_games.py index ecb1be7f..1794c52d 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -238,6 +238,61 @@ "examine sludge", # Finds a small key. ], }, + "hhgg.z3": { + '*': [ + 11, 12, # Bulldozer arrives. + 13, # Prefect arrives + 15, # Conversation with Prosser + 17, # Prefect leaves. + 34, # fleet VogConstructor ships arrive + 35, # electronic Sub-Etha signaling device arrives + 47, # "thing aunt gave you which you don't know it is" comes back into the inventory. + 48, # Gets to the Vogon Hold. + 58, # Brought to the Captain's Quarters. + 64, 69, 74, # Brought to the airlock. + 83, # Going to the Bridge. + 85, # Zaphod, Ford, and Trillian all head off to port. + 90, # Marvin arrives. + 96, 97, 98, 99, # Need to answer a question. + 114, # "thing aunt gave you which you don't know it is" comes back + 176, 177, 178, 179, # In the void. + 187, # Phil arrives and you end up in the Dark. + 201, 202, 203, 204, 205, 206, # In the void + 212, # Engineer robot asked a question. + 224, 225, 226, 227, 228, # In the void. + 243, # Trillian leaps out of the crowd + 262, 263, # In the void. + 269, # The game expects the word "idiot". + 280, 281, # fleet VogConstructor ships arrive + 282, # electronic Sub-Etha signaling device arrives + 283, # In the void + 294, 295, 296, 297, 298, 299, 300, 301, 302, # In the void + 307, # Transported to the Maze + 351, 352, # Marvin is opening the hatch. + ], + "look": [ + 101, # Ignore the game trying to make you not look. + ], + "examine room": [ + 101, # Ignore the game trying to make you not look. + ], + "wait": [ + 16, + 37, # Earth is destroyed. + 45, # "thing aunt gave you which you don't know it is" appears into your gown. + 46, 47, # Ford gives you the Hitchhiker's Guide to the Galaxy. + 88, 89, 93, # Marvin arrives. + 136, # Suddenly a team of Fronurbdian Beasthunters charges in + 155, # Announcement. + 182, # Arthur talks to hostess. + 331, # Plant is growing. + ], + "ignore_commands": [ + "examine shadow", # get teleported to Vogon Hold + "examine Eddie (shipboard computer)", + "examine arthur", "examine dent", # Reveals ball of fluff on Arthur's jacket. + ], + }, } SKIP_CHECK_STATE = { @@ -420,8 +475,25 @@ }, "hhgg.z3": { 56: "push switch", # Not needed to complete the game. + "wait": [ + 14, + 28, 29, 30, 31, 32, 33, 34, # waiting for fleet VogConstructor ships + 38, 39, 40, 41, # In the void. + 57, # Announcement + 59, 60, 61, 62, 63, # Waiting for Vogon to read poetry. + 65, 66, 67, 68, # Waiting for Vogon to read poetry (second verse). + 72, 73, # Waiting to be thrown into the airlock. + 77, 78, 79, 80, # In the void. + 84, # Conversation. + + ], "noop": [ - "z", "wait", # Needed to time the actions. + "look", "wait", "z", + "inventory", "i", + "look shelf", + "examine thumb", + "examine memorial", + "examine plant", ] }, "hollywood.z3": { From 5245fbadac378dce73dd6ccc815bee1623d613d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Tue, 1 Feb 2022 22:59:52 -0500 Subject: [PATCH 60/85] Noop check: hollywood --- frotz/src/games/hollywood.c | 40 +++++++++++++++++++++++++++---------- jericho/game_info.py | 2 +- tools/test_games.py | 27 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/frotz/src/games/hollywood.c b/frotz/src/games/hollywood.c index 9f997f42..4eaa2b8b 100644 --- a/frotz/src/games/hollywood.c +++ b/frotz/src/games/hollywood.c @@ -24,11 +24,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Hollywood Hijinx: http://ifdb.tads.org/viewgame?id=jnfkbgdgopwfqist -const zword hollywood_special_ram_addrs[9] = { - 8207, 8241, 8341, // Atomic Chihuahua +const zword hollywood_special_ram_addrs[8] = { + 8241, 8341, // Atomic Chihuahua 8323, // Breathing fire 8381, // Safe dial (Hallway) - 8277, // Push piano + 8345, // Push piano 8269, // Hedge Maze 8221, // Safe dial (Bomb Shelter) 8363, // throw club at herman @@ -39,12 +39,22 @@ const char *hollywood_intro[] = { "turn statue west\n", "turn statue north\n" }; zword* hollywood_ram_addrs(int *n) { - *n = 9; + *n = 8; return hollywood_special_ram_addrs; } char** hollywood_intro_actions(int *n) { *n = 3; + // Patch bug in source file. + // 8b31: GET_PROP G00,#0c -> -(SP) + // 8b35: PRINT_PADDR (SP)+ + // + // G00 is object 102 (Crawl Space, South) which doesn't have property 0x0c (i.e., 12). + // PRINT_PADDR will try to print text found at address 0 (segfault). + // Replace that PRINT_PADDR op with the nop. + zmp[0x8b35] = 180; // Nop + zmp[0x8b36] = 180; // Nop + return hollywood_intro; } @@ -110,11 +120,19 @@ int hollywood_ignore_attr_clr(zword obj_num, zword attr_idx) { } void hollywood_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 3); - // Clear attr 28 - for (i=1; i<=hollywood_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + for (int i=1; i<=hollywood_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 4); + clear_attr(&objs[i], 28); + } + + clear_attr(&objs[116], 31); // Upstairs Hall + clear_attr(&objs[158], 31); // Entrance to Hedge Maze + + clear_prop(&objs[19], 1); // Red match counter. + clear_prop(&objs[169], 1); // Green match counter. + clear_prop(&objs[181], 9); // The red wax statuette burning down counter. + + // Completely ignore the 'pseudo' object. + strcpy(&objs[237].name, "pseudo"); // Its name reflects what the player's focus. + clear_prop(&objs[237], 31); } diff --git a/jericho/game_info.py b/jericho/game_info.py index 26af283a..d6e5e99e 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -195,7 +195,7 @@ "rom": "hollywood.z3", "seed" : 0, # walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip - "walkthrough": "N/OPEN MAILBOX/GET PIECE OF PAPER AND BUSINESS CARD/OPEN DOOR/N/TURN ON FLASHLIGHT/N/EXAMINE MODEL/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS BLACK/PRESS BLACK/PRESS WHITE/PRESS WHITE/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS BLACK/PRESS BLUE/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS RED/PRESS RED/PRESS RED/GET RING/E/E/S/GET FILM AND SLIDE/EXAMINE FILM PROJECTOR/REMOVE CAP/DROP IT/TURN ON SLIDE PROJECTOR/INSERT SLIDE IN IT/FOCUS SLIDE LENS/INSERT FILM IN FILM PROJECTOR/TURN ON FILM PROJECTOR/EXAMINE SCREEN/N/GET YELLOW CARD/W/W/S/W/EXAMINE RED STATUETTE/EXAMINE WHITE STATUETTE/EXAMINE BLUE STATUETTE/E/E/LOOK BEHIND PAINTING/GET GREEN CARD/EXAMINE SAFE/TURN DIAL RIGHT 3/TURN IT LEFT 7/TURN IT RIGHT 5/OPEN SAFE/GET GRATER/E/PLAY people/PUSH PIANO NORTH/D/S/GET PILLAR/DROP IT/N/U/PUSH PIANO SOUTH/AGAIN/D/N/GET METER/S/U/OPEN PIANO/GET VIOLET CARD/W/W/DROP RING/DROP GRATER/DROP METER/N/UNLOCK DOOR/OPEN IT/N/GET ORANGE CARD/S/S/OPEN CLOSET/IN/PULL THIRD PEG/OPEN DOOR/OUT/TURN NEWEL/W/S/LOOK UNDER MAT/GET RED CARD/N/E/E/GET SACK/OPEN WINDOW/OPEN SACK/S/GET BLUE CARD/N/W/D/DROP SACK/W/IN/REMOVE BRICK/DROP IT/GET INDIGO CARD/drop all but flashlight/U/U/U/E/D/GET PENGUIN/U/W/D/D/D/take all/OUT/N/W/D/READ BUSINESS CARD/DROP IT/EXAMINE COMPUTER/TURN IT ON/INSERT RED CARD IN SLOT/INSERT ORANGE CARD IN SLOT/INSERT YELLOW CARD IN SLOT/INSERT GREEN CARD IN SLOT/INSERT BLUE CARD IN SLOT/INSERT INDIGO CARD IN SLOT/INSERT VIOLET CARD IN SLOT/EXAMINE LIGHTS/U/GET MATCHBOX/E/GET PAPER/PUT IT ON YELLOWED PAPER/S/GET RED STATUETTE/DIAL 576-3190/E/N/W/W/D/TAKE TOUPEE/U/E/E/S/U/IN/GET SKIS/PULL SECOND PEG/OPEN DOOR/OUT/N/W/W/D/U/E/E/S/DROP TOUPEE/DROP PHOTO/DROP LETTER/GET FINCH/DROP FINCH/N/N/N/NW/GET SHOVEL/NE/N/N/W/N/W/N/W/S/W/W/N/W/S/E/S/E/N/E/S/W/N/W/S/W/N/W/S/W/N/E/N/E/N/E/E/N/E/S/E/E/S/E/N/E/N/E/S/S/S/W/W/S/E/N/W/S/DIG IN GROUND/DROP SHOVEL/GET STAMP/N/E/S/W/N/E/E/N/N/N/W/S/W/S/W/N/W/W/N/W/S/W/W/S/W/S/W/S/E/N/E/S/E/N/E/S/E/N/W/S/W/N/W/N/E/S/E/E/N/E/S/E/S/E/S/S/N/E/N/GET BALL/PUT IT IN CANNON/OPEN MATCHBOX/GET MATCH/LIGHT IT/LIGHT FUSE WITH MATCH/OPEN COMPARTMENT/GET MASK/E/E/DROP FLASHLIGHT/WEAR SKIS/D/REMOVE SKIS/DROP THEM/GET MATCH/LIGHT CANDLE WITH FIRE/PUT MATCH IN WAX/S/W/DIVE/D/D/W/U/U/N/LIGHT MATCH/LIGHT CANDLE WITH MATCH/N/U/PULL CHAIN/BURN ROPE WITH CANDLE/ENTER RIGHT END OF PLANK/WAIT/DROP ALL BUT CANDLE/GET LADDER/PUT IT IN HOLE/D/GET LADDER/HANG IT ON HOOKS/EXAMINE SAFE/READ PLAQUE/TURN DIAL LEFT 4/TURN IT RIGHT 5/TURN IT LEFT 7/OPEN SAFE/GET FILM/U/GET ALL/U/E/E/GET FLASHLIGHT/W/W/S/GET BUCKET/FILL IT WITH WATER/SE/SW/S/S/S/IN/HANG BUCKET ON THIRD PEG/OUT/U/OPEN DOOR/IN/WAIT/WAIT/OPEN DOOR/OUT/OPEN PANEL/GET HYDRANT/GET PEG/READ NOTE/D/OPEN DOOR/IN/PUT PEG IN HOLE/take gun/throw gun at herman/take stick/throw stick at herman/take club/throw club at herman/turn off saw", + "walkthrough": "N/OPEN MAILBOX/GET PIECE OF PAPER AND BUSINESS CARD/OPEN DOOR/N/TURN ON FLASHLIGHT/N/EXAMINE MODEL/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS BLACK/PRESS BLACK/PRESS WHITE/PRESS WHITE/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS BLACK/PRESS BLUE/PRESS GREEN/PRESS GREEN/PRESS GREEN/PRESS RED/PRESS RED/PRESS RED/GET RING/E/E/S/GET FILM AND SLIDE/EXAMINE FILM PROJECTOR/REMOVE CAP/DROP IT/TURN ON SLIDE PROJECTOR/INSERT SLIDE IN IT/FOCUS SLIDE LENS/INSERT FILM IN FILM PROJECTOR/TURN ON FILM PROJECTOR/EXAMINE SCREEN/N/GET YELLOW CARD/W/W/S/W/EXAMINE RED STATUETTE/EXAMINE WHITE STATUETTE/EXAMINE BLUE STATUETTE/E/E/LOOK BEHIND PAINTING/GET GREEN CARD/EXAMINE SAFE/TURN DIAL RIGHT 3/TURN IT LEFT 7/TURN IT RIGHT 5/OPEN SAFE/GET GRATER/E/PLAY people/PUSH PIANO NORTH/D/S/GET PILLAR/DROP IT/N/U/PUSH PIANO SOUTH/AGAIN/D/N/GET METER/S/U/OPEN PIANO/GET VIOLET CARD/W/W/DROP RING/DROP GRATER/DROP METER/N/UNLOCK DOOR/OPEN IT/N/GET ORANGE CARD/S/S/OPEN CLOSET/IN/PULL THIRD PEG/OPEN DOOR/OUT/TURN NEWEL/W/S/LOOK UNDER MAT/GET RED CARD/N/E/E/GET SACK/OPEN WINDOW/OPEN SACK/S/GET BLUE CARD/N/W/D/DROP SACK/W/IN/REMOVE BRICK/DROP IT/GET INDIGO CARD/drop all but flashlight/U/U/U/E/D/GET PENGUIN/U/W/D/D/D/take all/OUT/N/W/D/READ BUSINESS CARD/DROP IT/TURN COMPUTER ON/INSERT RED CARD IN SLOT/INSERT ORANGE CARD IN SLOT/INSERT YELLOW CARD IN SLOT/INSERT GREEN CARD IN SLOT/INSERT BLUE CARD IN SLOT/INSERT INDIGO CARD IN SLOT/INSERT VIOLET CARD IN SLOT/EXAMINE LIGHTS/U/GET MATCHBOX/E/GET PAPER/PUT IT ON YELLOWED PAPER/S/GET RED STATUETTE/DIAL 576-3190/E/N/W/W/D/TAKE TOUPEE/U/E/E/S/U/IN/GET SKIS/PULL SECOND PEG/OPEN DOOR/OUT/N/W/W/D/U/E/E/S/DROP TOUPEE/DROP PHOTO/DROP LETTER/GET FINCH/DROP FINCH/N/N/N/NW/GET SHOVEL/NE/N/N/W/N/W/N/W/S/W/W/N/W/S/E/S/E/N/E/S/W/N/W/S/W/N/W/S/W/N/E/N/E/N/E/E/N/E/S/E/E/S/E/N/E/N/E/S/S/S/W/W/S/E/N/W/S/DIG IN GROUND/DROP SHOVEL/GET STAMP/N/E/S/W/N/E/E/N/N/N/W/S/W/S/W/N/W/W/N/W/S/W/W/S/W/S/W/S/E/N/E/S/E/N/E/S/E/N/W/S/W/N/W/N/E/S/E/E/N/E/S/E/S/E/S/S/N/E/N/GET BALL/PUT IT IN CANNON/OPEN MATCHBOX/GET MATCH/LIGHT IT/LIGHT FUSE WITH MATCH/OPEN COMPARTMENT/GET MASK/E/E/DROP FLASHLIGHT/WEAR SKIS/D/REMOVE SKIS/DROP THEM/GET MATCH/LIGHT CANDLE WITH FIRE/PUT MATCH IN WAX/S/W/DIVE/D/D/W/U/U/N/LIGHT MATCH/LIGHT CANDLE WITH MATCH/N/U/PULL CHAIN/BURN ROPE WITH CANDLE/ENTER RIGHT END OF PLANK/WAIT/DROP ALL BUT CANDLE/GET LADDER/PUT IT IN HOLE/D/GET LADDER/HANG IT ON HOOKS/EXAMINE SAFE/READ PLAQUE/TURN DIAL LEFT 4/TURN IT RIGHT 5/TURN IT LEFT 7/OPEN SAFE/GET FILM/U/GET ALL/U/E/E/GET FLASHLIGHT/W/W/S/GET BUCKET/FILL IT WITH WATER/SE/SW/S/S/S/IN/HANG BUCKET ON THIRD PEG/OUT/U/OPEN DOOR/IN/WAIT/WAIT/OPEN DOOR/OUT/OPEN PANEL/GET HYDRANT/GET PEG/READ NOTE/D/OPEN DOOR/IN/PUT PEG IN HOLE/take gun/throw gun at herman/take stick/throw stick at herman/take club/throw club at herman/turn off saw", "grammar" : "aftern/bye/farewe/goodby/greet/greeti/hello/hi/salute/affirm/aye/naw/nay/negati/no/nope/ok/okay/positi/sure/y/yes/yup;back/ski/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk;bathe/swim;brief;diagno;fly;gaze/l/look/peek/peer/stare;hint/hints/aid/help/pray;i/invent;loiter/wait/z;nap/rest/sleep/snooze;play;q/quit;restar;restor;rise/stand;save;score;script;super/superb;t/time;tten;unscri;verbos;versio;advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk off OBJ;affirm/aye/naw/nay/negati/no/nope/ok/okay/positi/sure/y/yes/yup OBJ;aftern/bye/farewe/goodby/greet/greeti/hello/hi/salute OBJ;aid/help/save OBJ;answer/reply/respon OBJ;answer/reply/respon to OBJ;ascend OBJ;ask/interr/query/questi/quiz OBJ;assaul/attack/fight/hit/hurt/injure/kill/murder/punch/slap/slay/stab/strike/whack/wound OBJ;awake/awaken/rouse/startl/surpri/wake OBJ;awake/awaken/rouse/startl/surpri/wake up OBJ;bathe/swim OBJ;bathe/swim in OBJ;bathe/swim to OBJ;bite OBJ;blow OBJ;blow in OBJ;blow out OBJ;blow throug OBJ;blow up OBJ;board/embark OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck in OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck throug OBJ;brush/clean/sweep OBJ;brush/clean/sweep off OBJ;buy OBJ;call/dial/phone OBJ;call/dial/phone up OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take off OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take out OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take up OBJ;chase/follow/pursue OBJ;check/descri/examin/inspec/observ/see/study/survey/watch OBJ;check/descri/examin/inspec/observ/see/study/survey/watch/gaze/l/look/peek/peer/stare in OBJ;check/descri/examin/inspec/observ/see/study/survey/watch/gaze/l/look/peek/peer/stare on OBJ;check/descri/examin/inspec/observ/see/study/survey/watch/gaze/l/look/peek/peer/stare/frisk/ransac/rummag/search for OBJ;chuck/fling/hurl/pitch/throw/toss OBJ;climb/scale OBJ;climb/scale over OBJ;climb/scale throug OBJ;climb/scale under OBJ;climb/scale/carry/catch/confis/get/grab/hold/seize/snatch/steal/take in OBJ;climb/scale/carry/catch/confis/get/grab/hold/seize/snatch/steal/take on OBJ;climb/scale/go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk down OBJ;climb/scale/go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk up OBJ;climb/scale/go/dive/jump/leap/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk out OBJ;close/shut/slam OBJ;concea/hide OBJ;concea/hide behind OBJ;concea/hide under OBJ;consum/devour/eat/gobble/nibble/swallo OBJ;count/tally OBJ;cross/traver OBJ;crush/squash/squeez OBJ;debark/disemb OBJ;defile/molest/rape OBJ;depart/exit/scram/withdr OBJ;descen OBJ;detach/free/unatta/undo/unfast/unhook/untie OBJ;dig/excava at OBJ;dig/excava in OBJ;dig/excava throug OBJ;dig/excava up OBJ;dig/excava with OBJ;distur/feel/pat/pet/rub/touch OBJ;dive/jump/leap OBJ;dive/jump/leap from OBJ;dive/jump/leap off OBJ;dive/jump/leap over OBJ;doff/remove/shed OBJ;don/wear OBJ;douse/exting/quench/snuff OBJ;drag/pull/shove/tug/yank OBJ;drag/pull/shove/tug/yank down OBJ;drag/pull/shove/tug/yank on OBJ;drag/pull/shove/tug/yank up OBJ;drink/guzzle/sip OBJ;drink/guzzle/sip from OBJ;drop/dump OBJ;elevat/hoist/lift/raise OBJ;elevat/hoist/lift/raise up OBJ;employ/exploi/use OBJ;empty OBJ;empty out OBJ;enter OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ;face/flip/rotate/set/spin/turn/twist/whirl off OBJ;face/flip/rotate/set/spin/turn/twist/whirl on OBJ;fill OBJ;find/seek OBJ;fire/shoot OBJ;flush OBJ;fly OBJ;fly on OBJ;fly with OBJ;focus OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge down OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge on OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge out OBJ;frisk/ransac/rummag/search OBJ;frisk/ransac/rummag/search in OBJ;gaze/l/look/peek/peer/stare OBJ;gaze/l/look/peek/peer/stare around OBJ;gaze/l/look/peek/peer/stare at OBJ;gaze/l/look/peek/peer/stare behind OBJ;gaze/l/look/peek/peer/stare down OBJ;gaze/l/look/peek/peer/stare out OBJ;gaze/l/look/peek/peer/stare throug OBJ;gaze/l/look/peek/peer/stare up OBJ;gaze/l/look/peek/peer/stare/frisk/ransac/rummag/search under OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk around OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk behind OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk over OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk throug OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk to OBJ;go/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk under OBJ;go/dive/jump/leap/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk in OBJ;grin/laugh/nod/smile/sneer/wave at OBJ;grin/laugh/nod/smile/sneer/wave to OBJ;hang OBJ;hang up OBJ;hear OBJ;howl/scream/shout/yell OBJ;howl/scream/shout/yell at OBJ;howl/scream/shout/yell to OBJ;ignite/light OBJ;jostle/rattle/shake OBJ;kick OBJ;kick down OBJ;kick in OBJ;kiss/smooch OBJ;knock/pound/rap at OBJ;knock/pound/rap down OBJ;knock/pound/rap on OBJ;leave OBJ;let go OBJ;lie/reclin down OBJ;lie/reclin in OBJ;lie/reclin on OBJ;listen OBJ;listen for OBJ;listen in OBJ;listen to OBJ;lock OBJ;loiter/wait/z for OBJ;lower OBJ;move/roll/shift OBJ;move/roll/shift up OBJ;nap/rest/sleep/snooze in OBJ;nap/rest/sleep/snooze on OBJ;nudge/press/push/ring/thrust OBJ;nudge/press/push/ring/thrust down OBJ;nudge/press/push/ring/thrust on OBJ;nudge/press/push/ring/thrust up OBJ;open/pry/unseal OBJ;open/pry/unseal up OBJ;pick OBJ;pick up OBJ;play OBJ;reach in OBJ;read/skim OBJ;releas OBJ;replac OBJ;ride OBJ;ride in OBJ;ride on OBJ;rise/stand under OBJ;rise/stand up OBJ;rise/stand/dive/jump/leap/advanc/crawl/hike/hop/procee/run/skip/step/tramp/trudge/walk on OBJ;say/speak/talk/utter OBJ;scrape off OBJ;sit/squat OBJ;sit/squat at OBJ;sit/squat down OBJ;sit/squat in OBJ;sit/squat on OBJ;ski OBJ;ski down OBJ;smell/sniff OBJ;splice OBJ;swing OBJ;swing on OBJ;taste OBJ;tell OBJ;unlock OBJ;unroll OBJ;ask/interr/query/questi/quiz OBJ about OBJ;ask/interr/query/questi/quiz OBJ for OBJ;assaul/attack/fight/hit/hurt/injure/kill/murder/punch/slap/slay/stab/strike/whack/wound OBJ with OBJ;attach/fasten/hook/secure/tie OBJ to OBJ;attach/fasten/hook/secure/tie up OBJ with OBJ;bestow/delive/donate/give/hand/offer/presen OBJ OBJ;bestow/delive/donate/give/hand/offer/presen OBJ to OBJ;blind/jab/poke OBJ with OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck OBJ off OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck OBJ with OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck down OBJ with OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck in OBJ with OBJ;break/crack/damage/demoli/destro/erase/smash/trash/wreck throug OBJ with OBJ;burn OBJ with OBJ;burn down OBJ with OBJ;buy OBJ with OBJ;call/dial/phone OBJ on OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ from OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ in OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ off OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ on OBJ;carry/catch/confis/get/grab/hold/seize/snatch/steal/take OBJ out OBJ;check/descri/examin/inspec/observ/see/study/survey/watch OBJ throug OBJ;check/descri/examin/inspec/observ/see/study/survey/watch OBJ with OBJ;chuck/fling/hurl/pitch/throw/toss OBJ at OBJ;chuck/fling/hurl/pitch/throw/toss OBJ down OBJ;chuck/fling/hurl/pitch/throw/toss OBJ in OBJ;chuck/fling/hurl/pitch/throw/toss OBJ off OBJ;chuck/fling/hurl/pitch/throw/toss OBJ on OBJ;chuck/fling/hurl/pitch/throw/toss OBJ out OBJ;chuck/fling/hurl/pitch/throw/toss OBJ over OBJ;chuck/fling/hurl/pitch/throw/toss OBJ throug OBJ;chuck/fling/hurl/pitch/throw/toss OBJ to OBJ;clip/cut/slash OBJ with OBJ;clip/cut/slash throug OBJ with OBJ;compar OBJ to OBJ;concea/hide OBJ behind OBJ;concea/hide OBJ from OBJ;concea/hide OBJ under OBJ;cover OBJ with OBJ;crush/squash/squeez OBJ on OBJ;detach/free/unatta/undo/unfast/unhook/untie OBJ from OBJ;dig/excava OBJ in OBJ;dig/excava OBJ with OBJ;dig/excava in OBJ with OBJ;distur/feel/pat/pet/rub/touch OBJ with OBJ;doff/remove/shed OBJ from OBJ;drag/pull/shove/tug/yank OBJ out OBJ;drip/pour/spill/sprink OBJ from OBJ;drip/pour/spill/sprink OBJ in OBJ;drip/pour/spill/sprink OBJ on OBJ;drip/pour/spill/sprink out OBJ in OBJ;drop/dump OBJ down OBJ;drop/dump OBJ in OBJ;drop/dump OBJ on OBJ;empty OBJ from OBJ;empty OBJ out OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ left OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ right OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ to OBJ;face/flip/rotate/set/spin/turn/twist/whirl OBJ with OBJ;feed OBJ OBJ;feed OBJ to OBJ;feed OBJ with OBJ;fill OBJ with OBJ;fire/shoot OBJ at OBJ;fire/shoot OBJ with OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ behind OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ down OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ in OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ on OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ over OBJ;force/insert/lay/load/place/put/stash/stuff/thread/wedge OBJ under OBJ;gaze/l/look/peek/peer/stare at OBJ throug OBJ;hang OBJ from OBJ;hang OBJ on OBJ;hang up OBJ from OBJ;hang up OBJ on OBJ;ignite/light OBJ with OBJ;leave OBJ in OBJ;leave OBJ on OBJ;lock OBJ with OBJ;move/roll/shift OBJ down OBJ;nudge/press/push/ring/thrust OBJ down OBJ;nudge/press/push/ring/thrust OBJ under OBJ;nudge/press/push/ring/thrust OBJ up OBJ;nudge/press/push/ring/thrust/move/roll/shift OBJ OBJ;nudge/press/push/ring/thrust/move/roll/shift OBJ to OBJ;open/pry/unseal OBJ with OBJ;pick OBJ with OBJ;play OBJ on OBJ;read/skim OBJ throug OBJ;read/skim OBJ to OBJ;scrape OBJ off OBJ;show OBJ OBJ;show OBJ to OBJ;splice OBJ with OBJ;swing OBJ at OBJ;tell OBJ about OBJ;unlock OBJ with OBJ;", "max_word_length" : 6 } diff --git a/tools/test_games.py b/tools/test_games.py index 1794c52d..70b79a37 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -293,6 +293,22 @@ "examine arthur", "examine dent", # Reveals ball of fluff on Arthur's jacket. ], }, + "hollywood.z3": { + "*": [ + 9, 10, # Tanks are moving. + 39, # strip of film falls onto the floor. + 311, # Red match goes out. + 334, # Green match goes out. + 339, # the rope it snaps + 385, # Water drains out. + 387, 388, 389, 390, 391, 392, 393, # Herman grabs and swings things at you. + ], + "wait": [ + 310, # Red match goes out. + 376, # Closet door swings shut + 383, 384, # Water drains out. + ], + }, } SKIP_CHECK_STATE = { @@ -502,6 +518,17 @@ 348: "read plaque", # Not needed for completing the game. 376: "wait", # Waiting for the closet's door to swing shut. 383: "read note", # Not needed to complete the game. + "wait": [ + 375, # waiting for the closet door to swings shut. + ], + "noop": [ + "examine model", "examine film projector", "examine safe", + "examine red statuette", "examine white statuette", "examine blue statuette", + "examine lights", + "put it on yellowed paper", # Display the maze. + "read plaque", "read note", + "read business card" + ], }, "huntdark.z5": { "noop": [ From b6a440d2706c0cf88dd8bbbe6ed8540e7da77466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 2 Feb 2022 09:53:56 -0500 Subject: [PATCH 61/85] Noop check: huntdark --- frotz/src/games/huntdark.c | 32 +++++++++++++++++++------------- tools/test_games.py | 8 ++++++++ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/frotz/src/games/huntdark.c b/frotz/src/games/huntdark.c index c4ecf100..e344e2c9 100644 --- a/frotz/src/games/huntdark.c +++ b/frotz/src/games/huntdark.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -24,17 +24,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Hunter, in Darkness: http://ifdb.tads.org/viewgame?id=mh1a6hizgwjdbeg7 -const zword huntdark_special_ram_addrs[4] = { - 8130, // Crossbow cocked - 8201, // Going left +const zword huntdark_special_ram_addrs[1] = { + // 8130, // Crossbow cocked + // 8201, // Going left 8551, // Birth - 8824, // Bats + // 8824, // Bats }; const char *huntdark_intro[] = { "\n", "\n" }; zword* huntdark_ram_addrs(int *n) { - *n = 4; + *n = 1; return huntdark_special_ram_addrs; } @@ -108,11 +108,17 @@ int huntdark_ignore_attr_clr(zword obj_num, zword attr_idx) { } void huntdark_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 6); - // Clear attr 25 - for (i=1; i<=huntdark_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + for (int i=1; i<=huntdark_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 25); + } + + clear_prop(&objs[23], 41); // bloody wound's counter + clear_prop(&objs[80], 41); // bats' counter + + objs[80].parent = 0; // bats' location + objs[117].parent = 0; // bats' location + + clear_prop(&objs[109], 1); // (BUG) object. + clear_prop(&objs[110], 1); // (BUG) object. + clear_prop(&objs[111], 1); // (BUG) object. } diff --git a/tools/test_games.py b/tools/test_games.py index 70b79a37..69dcf138 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -309,6 +309,12 @@ 383, 384, # Water drains out. ], }, + "huntdark.z5": { + "*": [ + 3, # Player arrives to Bottom of Pit. + 18, # Player arrives to (Maze). + ], + }, } SKIP_CHECK_STATE = { @@ -533,6 +539,8 @@ "huntdark.z5": { "noop": [ "wait", # Waiting for the bat to show the way out. + "x bats", + "x pool", ] }, "infidel.z3": { From 0c875586633134a8cf900962c0930e9bf20a248a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 2 Feb 2022 09:59:20 -0500 Subject: [PATCH 62/85] Noop check: infidel --- tools/test_games.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/test_games.py b/tools/test_games.py index 69dcf138..09f57374 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -315,6 +315,19 @@ 18, # Player arrives to (Maze). ], }, + "infidel.z3": { + "*": [ + 7, # large crate lands right before you + 59, # match went out. + ], + "wait": [ + 58, # match went out. + ], + "ignore_commands": [ + "examine all", + "examine jeweled", "examine jeweled ring", "examine ring", # Reveals a tiny needle. + ], + }, } SKIP_CHECK_STATE = { @@ -551,6 +564,9 @@ 159: "read hieroglyphs", # Not needed to complete the game. 173: "read hieroglyphs", # Not needed to complete the game. 184: "read scroll", # Not needed to complete the game. + "noop": { + "examine slot", + }, }, "inhumane.z5": {}, "jewel.z5": { From 4fb314fc2fa41e8bebfde0ac1cedd33badc2be50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 2 Feb 2022 10:17:29 -0500 Subject: [PATCH 63/85] Sort interactable objects. --- jericho/jericho.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jericho/jericho.py b/jericho/jericho.py index 5d67d194..85bb9d91 100644 --- a/jericho/jericho.py +++ b/jericho/jericho.py @@ -940,7 +940,7 @@ def _identify_interactive_objects(self, observation='', use_object_tree=False): desc2obj = {} # Filter out objs that aren't examinable name2desc = {} - for obj in objs: + for obj in sorted(objs): if obj[0] in name2desc: ex = name2desc[obj[0]] else: From 61c3af9c87e5560d97dd284fa20d88d6f166df62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 2 Feb 2022 10:17:42 -0500 Subject: [PATCH 64/85] Noop check: inhumane --- frotz/src/games/inhumane.c | 10 ++-------- tools/test_games.py | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/frotz/src/games/inhumane.c b/frotz/src/games/inhumane.c index 77cd714e..34707a49 100644 --- a/frotz/src/games/inhumane.c +++ b/frotz/src/games/inhumane.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -98,11 +98,5 @@ int inhumane_ignore_attr_clr(zword obj_num, zword attr_idx) { } void inhumane_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 5); - // Clear attr 26 - for (i=1; i<=inhumane_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + clear_prop(&objs[39], 25); // On the Platform's counter. } diff --git a/tools/test_games.py b/tools/test_games.py index 09f57374..b1034f89 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -328,6 +328,17 @@ "examine jeweled", "examine jeweled ring", "examine ring", # Reveals a tiny needle. ], }, + "inhumane.z5": { + "*": [ + 13, # the pit collapse, ... you end up in the desert again. + 54, # the door swings shut. + 84, # you get pushed off the swinging platform. + ], + "ignore_commands": [ + "examine toilet", "examine Roboff's toilet", # find a dark hole in the toilet. + "examine pyramid", "examine obelisk", "examine stone", # mind is numbed and full of RAHN's strange commandments + ] + }, } SKIP_CHECK_STATE = { @@ -568,7 +579,11 @@ "examine slot", }, }, - "inhumane.z5": {}, + "inhumane.z5": { + "z": [ + 59, 60, 61, 63, 64, 65, 76, 77, 78, 79, 80, 81, 83, # Timing movement with the swinging platform. + ], + }, "jewel.z5": { 22: "smell dirty floor", # Not needed to complete the game. 91: "get treasure", # Not needed to complete the game. From a5e492f927f49612935492f1d01a2768edd3442f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 2 Feb 2022 11:44:55 -0500 Subject: [PATCH 65/85] Noop check: jewel --- frotz/src/games/jewel.c | 27 ++++++++++++++++++++------- tools/test_games.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/frotz/src/games/jewel.c b/frotz/src/games/jewel.c index fb73a2f8..7bc2105e 100644 --- a/frotz/src/games/jewel.c +++ b/frotz/src/games/jewel.c @@ -102,11 +102,24 @@ int jewel_ignore_attr_clr(zword obj_num, zword attr_idx) { } void jewel_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=jewel_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + for (int i=1; i<=jewel_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 25); + } + + clear_prop(&objs[58], 41); // geyser's counter + clear_prop(&objs[60], 41); // Shaft Base's counter + clear_prop(&objs[61], 41); // Middle Shaft's counter + clear_prop(&objs[62], 41); // Top of the Shaft's counter + clear_prop(&objs[66], 41); // On the Ledge's counter + clear_prop(&objs[143], 41); // Black Dargon's Lair's counter + clear_prop(&objs[148], 41); // At the Top of the Ramp's counter + clear_prop(&objs[153], 41); // Black Dragon's Antechamber's counter + clear_prop(&objs[159], 41); // Well-Lit Passage's counter + clear_prop(&objs[162], 41); // Steep Cliff Face's counter + clear_prop(&objs[164], 41); // Red Dragon Gate's counter + clear_prop(&objs[167], 41); // Red Dragon Lair's counter + clear_prop(&objs[170], 41); // On The Divide's counter + clear_prop(&objs[174], 41); // Red Dragon's Plateau's counter + clear_prop(&objs[180], 41); // In the River's counter + clear_prop(&objs[182], 41); // Underground River's counter } diff --git a/tools/test_games.py b/tools/test_games.py index b1034f89..dccffd07 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -339,6 +339,21 @@ "examine pyramid", "examine obelisk", "examine stone", # mind is numbed and full of RAHN's strange commandments ] }, + "jewel.z5": { + "*": [ + 21, # 'x moss' triggered a clarifying question. + 60, # Geyser erupts. + 164, # Dragon attacks you. + 178, # Sit on the dragon. + 180, 182, # Dragon moves with you on top of it. + 184, # Dragon opens the lava gate. + 185, # You arrive in the Red Dragon's Lair. + 194, # eastern wall from which the river flows finally gives way + 200, # surprisingly rejuvenated dragon leaps towards you + 208, # You're bobbing up and down in a river of cold black water. + 211, # You arrive at the Pebble Beach + ], + }, } SKIP_CHECK_STATE = { @@ -591,6 +606,29 @@ 125: "ask allarah about white", # Not needed to complete the game. 127: "ask allarah about red", # Not needed to complete the game. 128: "ask allarah about jewel", # Not needed to complete the game. + 151: "ask dragon about trinket", # Not needed to complete the game. + 152: "ask dragon about white", # Not needed to complete the game. + 153: "ask dragon about black", # Not needed to complete the game. + 154: "ask dragon about red", # Not needed to complete the game. + 169: "show crossbow to dragon", + "z": [ + 58, 59, # Geyser + 160, 161, 162, 163, # Waiting for the Dragon to be annoyed. + 176, 177, 179, 181, 182, 183, # Dragon is flying around with you on it. + 187, 188, 189, 190, 191, 192, 193, # Black dragon spews acid on you. + 206, 207, 209, 210, # River pushes you. + ], + "noop": [ + "i", "look", + "read label", "read book", + "x minerals", "x gaping", "x outcrop", "x insect", "x skeleton", + "x block", "x dragon", "x fungus", "x mushroom", "x crossbow", + "x body", "x salt", "x door", "x murals", "x mirror", "x pedestal", + "x porous wall", "x bladder", "x ariana", "x boots", "x lye", "x coat", + "x chandelier", + "search refuse", "search boots", + "look under cushion", + ], }, "karn.z5": { 46: "read sign", # Not needed to complete the game. From ce3388d48448a4052e5c2b51bed9628638d4a064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 2 Feb 2022 13:08:51 -0500 Subject: [PATCH 66/85] Noop check: karn --- frotz/src/games/karn.c | 19 ++++++++++--------- tools/test_games.py | 19 ++++++++++++++++++- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/frotz/src/games/karn.c b/frotz/src/games/karn.c index f619fc76..417fdc10 100644 --- a/frotz/src/games/karn.c +++ b/frotz/src/games/karn.c @@ -24,15 +24,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Return to Karn: http://ifdb.tads.org/viewgame?id=bx8118ggp6j7nslo -const zword karn_special_ram_addrs[4] = { +const zword karn_special_ram_addrs[5] = { 14066, // Tardis flying/grounded 13050, // Color sequence 1213, // k9 following player 2194, // Pull lever and Push button + 3101, // Pull pipe }; zword* karn_ram_addrs(int *n) { - *n = 4; + *n = 5; return karn_special_ram_addrs; } @@ -103,11 +104,11 @@ int karn_ignore_attr_clr(zword obj_num, zword attr_idx) { } void karn_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=karn_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + for (int i=1; i<=karn_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 25); + clear_attr(&objs[i], 8); + } + + clear_prop(&objs[253], 25); // firework's counter + clear_prop(&objs[254], 25); // match's counter } diff --git a/tools/test_games.py b/tools/test_games.py index dccffd07..8b55333f 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -354,6 +354,18 @@ 211, # You arrive at the Pebble Beach ], }, + "karn.z5": { + "*": [ + 133, # The thrusters are moved to the Plain. + 148, # A spacecraft arrives outside the TARDIS. + 255, # Cybermen arrives. + 256, # Explosion + 308, # The firework goes off. + 309, 310, 311, # Cyberman is coming in. + 312, # Plastic Button pops back up. + 313, # Cyberman gets you. + ], + }, } SKIP_CHECK_STATE = { @@ -641,7 +653,12 @@ 239: "ask k9 about sequence", # Not actually needed for completing the game (important information). 320: "ask k9 about cybermen", # Not needed to complete the game. "noop": [ - "z" + "z", + 'x homing', 'x scanner', 'x tree', 'x k9', 'x bubble', + 'x plate', 'x left screen', 'x right screen', 'look up', + 'x control', 'x mine', 'x door', 'x device', 'x apparatus', + 'x respirator', 'x vent', 'x console', 'x slot', 'x creature', + 'x globe', ], }, "library.z5": { From 60b36fff6ea5a398da014b3220cd800b6ddd4f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 2 Feb 2022 13:12:46 -0500 Subject: [PATCH 67/85] Noop check: library --- frotz/src/games/library.c | 10 +++------- tools/test_games.py | 12 +++++++++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/frotz/src/games/library.c b/frotz/src/games/library.c index 84c035df..13c0d3ad 100644 --- a/frotz/src/games/library.c +++ b/frotz/src/games/library.c @@ -102,11 +102,7 @@ int library_ignore_attr_clr(zword obj_num, zword attr_idx) { } void library_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7) & ~(1 << 6); - // Clear attr 24 & 25 - for (i=1; i<=library_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + for (int i=1; i<=library_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 8); + } } diff --git a/tools/test_games.py b/tools/test_games.py index 8b55333f..b7d24507 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -366,6 +366,11 @@ 313, # Cyberman gets you. ], }, + "library.z5": { + "ignore_commands": [ + "examine printers", # You take the Encyclopedia Frobozzica. + ], + }, } SKIP_CHECK_STATE = { @@ -674,6 +679,11 @@ 19: "smell", # Not needed to complete the game. 41: "ask marion about encyclopedia", # Not needed to complete the game. 50: "ask technician about security gates", # Not needed to complete the game. + "noop": [ + 'i', + 'x attendant', 'x librarian', 'x stairs', 'x painting', + 'x technician', 'x shelves', 'x magazines', + ] }, "loose.z5": {}, "lostpig.z8": { @@ -1128,7 +1138,7 @@ def parse_args(): breakpoint() - print(repr(commands_to_ignore)) + print(repr(sorted(set(commands_to_ignore)))) if not env.victory(): print(colored("FAIL", 'red')) if args.debug: From b9460678d4d24a74da2dedb81bfc335dcc4f2d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 2 Feb 2022 13:25:34 -0500 Subject: [PATCH 68/85] Noop check: loose --- frotz/src/games/loose.c | 19 ++++++++++++------- tools/test_games.py | 16 +++++++++++++++- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/frotz/src/games/loose.c b/frotz/src/games/loose.c index d47bb5b9..28bd1f12 100644 --- a/frotz/src/games/loose.c +++ b/frotz/src/games/loose.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -98,11 +98,16 @@ int loose_ignore_attr_clr(zword obj_num, zword attr_idx) { } void loose_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7) & ~(1 << 6); - // Clear attr 24 & 25 - for (i=1; i<=loose_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; + for (int i=1; i<=loose_get_num_world_objs(); ++i) { + if (i != 99 && i != 101) { // Except for 'knock' and 'ladder'. + clear_attr(&objs[i], 8); } + + clear_attr(&objs[i], 25); + } + + objs[176].parent = 0; + clear_attr(&objs[176], 3); + + clear_prop(&objs[170], 41); // Mary's counter. } diff --git a/tools/test_games.py b/tools/test_games.py index b7d24507..67a3b3a8 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -371,6 +371,16 @@ "examine printers", # You take the Encyclopedia Frobozzica. ], }, + "loose.z5": { + "*" : [ + # 5, # The wolf loiters in the area, keeping an eye on you. + # 8, # The wolf loiters in the area, keeping an eye on you. + 12, # bungalow door slams open and a voice shouts + ], + "ignore_commands": [ + "examine ladder", # let you borrow the ladder + ], + }, } SKIP_CHECK_STATE = { @@ -685,7 +695,11 @@ 'x technician', 'x shelves', 'x magazines', ] }, - "loose.z5": {}, + "loose.z5": { + "noop": [ + "ask mary for ladder", + ], + }, "lostpig.z8": { 15: "follow pig", # Not needed to complete the game. 28: "wear it", # Not needed to complete the game. From 68242f0012e8805a441513a6bd381b23b3993ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 4 Feb 2022 10:38:04 -0500 Subject: [PATCH 69/85] Noop check: loose.z5 --- frotz/src/games/loose.c | 22 ++++++++++++++++++++-- tools/test_games.py | 3 +++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/frotz/src/games/loose.c b/frotz/src/games/loose.c index 28bd1f12..c20bd61b 100644 --- a/frotz/src/games/loose.c +++ b/frotz/src/games/loose.c @@ -26,13 +26,29 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. const char *loose_intro[] = { "\n" }; +const zword loose_special_ram_addrs[1] = { + 13292, // going north to go home with your mother. +}; + zword* loose_ram_addrs(int *n) { - *n = 0; - return NULL; + *n = 1; + return loose_special_ram_addrs; } char** loose_intro_actions(int *n) { *n = 1; + + // Patch bug in source file. + // Routine 14370, 0 locals + // 14371: JE G00,#88 [FALSE] 1437e + // 14375: CALL_VN 18cbc (Geb,#23) + // + // Geb refers to object 150 (hillside) where its property #23 is pointing + // to routine 14370 which ultimately creates an infinite recursive loop. + // Swapping Geb for G00, which refers to object 136 (hilltop), avoids the + // infinite loop and outputs the expected description of the hilltop. + zmp[0x14379] = 0x10; // Replacing Geb with G00 in the above CALL_VN. + return loose_intro; } @@ -110,4 +126,6 @@ void loose_clean_world_objs(zobject* objs) { clear_attr(&objs[176], 3); clear_prop(&objs[170], 41); // Mary's counter. + clear_prop(&objs[125], 41); // Clock Tower's counter. + clear_prop(&objs[174], 41); // Mother Loose's counter. } diff --git a/tools/test_games.py b/tools/test_games.py index 67a3b3a8..ec2bfcfe 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -375,10 +375,13 @@ "*" : [ # 5, # The wolf loiters in the area, keeping an eye on you. # 8, # The wolf loiters in the area, keeping an eye on you. + 11, # Need to answer to "Who's there." 12, # bungalow door slams open and a voice shouts + 48, 49, # Ending sequence. ], "ignore_commands": [ "examine ladder", # let you borrow the ladder + "examine corner", # you find a tranished brass key ], }, } From 9aa45efcc39c1dd0d07b9ea90ad5f3f002974606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 9 Feb 2022 10:45:08 -0500 Subject: [PATCH 70/85] Tweak test_games.py to detect unused special ram addresses. --- tools/test_games.py | 73 ++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/tools/test_games.py b/tools/test_games.py index ec2bfcfe..a8c673fa 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -1035,7 +1035,9 @@ def parse_args(): print(obs) commands_to_ignore = [] + triggered_ram_addrs = set() walkthrough = env.get_walkthrough() + env_ = env.copy() for i, cmd in tqdm(list(enumerate(walkthrough))): cmd = cmd.lower() last_hash = env.get_world_state_hash() @@ -1044,9 +1046,9 @@ def parse_args(): and cmd not in SKIP_PRECHECK_STATE.get(rom, {}).get(i, {}) and i not in SKIP_PRECHECK_STATE.get(rom, {}).get("*", [])) + state = env.get_state() + env_.set_state(state) if precheck_state: - env_ = env.copy() - state = env_.get_state() objs = env_._identify_interactive_objects(use_object_tree=True) cmds = ["look", "inventory", "wait", "examine me", "asd"] cmds += ["examine " + obj[0][0] for obj in objs.values()] @@ -1099,7 +1101,6 @@ def parse_args(): if tmp.strip(): cmd = tmp - # last_env = env.copy() last_env_objs = env.get_world_objects(clean=False) last_env_objs_cleaned = env.get_world_objects(clean=True) @@ -1123,39 +1124,55 @@ def parse_args(): and cmd not in SKIP_CHECK_STATE.get(rom, {}).get('noop', {})) if check_state: - if not env._world_changed(): - if True: #cmd != "look" and cmd.split(" ")[0] not in {"l", "i", "inventory"}: + if env._world_changed(): - print(colored(f'{i}. [{cmd}]: world hash hasn\'t changed.\n"""\n{obs}\n"""', 'red')) + if env.frotz_lib.get_special_ram_changed() and not env.frotz_lib.get_objects_state_changed(): + ram_addrs = env._get_ram_addrs() + ram_old = env_._get_special_ram() + ram_new = env._get_special_ram() + for ram_addr, value_old, value_new in zip(ram_addrs, ram_old, ram_new): + if value_old != value_new: + triggered_ram_addrs.add(ram_addr) - print("Objects diff:") - for o1, o2 in zip(last_env_objs, env_objs): - if o1 != o2: - display_diff(str(o1), str(o2)) + else: + print(colored(f'{i}. [{cmd}]: world hash hasn\'t changed.\n"""\n{obs}\n"""', 'red')) - print("Cleaned objects diff:") - for o1, o2 in zip(last_env_objs_cleaned, env_objs_cleaned): - if o1 != o2: - display_diff(str(o1), str(o2)) + print("Objects diff:") + for o1, o2 in zip(last_env_objs, env_objs): + if o1 != o2: + display_diff(str(o1), str(o2)) - # For debugging. - print(f"Testing walkthrough without '{cmd}'...") - alt1 = test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) - print(f"Testing walkthrough replacing '{cmd}' with 'wait'...") - alt2 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) - # print(f"Testing walkthrough replacing '{cmd}' with '0'...") - # alt3 = test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) - # print(f"Testing walkthrough replacing '{cmd}' with 'wait 1 minute'...") - # alt4 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) - print(f"Testing walkthrough replacing '{cmd}' with 'look'...") - alt5 = test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) + print("Cleaned objects diff:") + for o1, o2 in zip(last_env_objs_cleaned, env_objs_cleaned): + if o1 != o2: + display_diff(str(o1), str(o2)) - if all((alt1, alt2, alt5)): - commands_to_ignore.append(cmd) + # For debugging. + print(f"Testing walkthrough without '{cmd}'...") + alt1 = test_walkthrough(env.copy(), walkthrough[:i] + walkthrough[i+1:]) + print(f"Testing walkthrough replacing '{cmd}' with 'wait'...") + alt2 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait"] + walkthrough[i+1:]) + # print(f"Testing walkthrough replacing '{cmd}' with '0'...") + # alt3 = test_walkthrough(env.copy(), walkthrough[:i] + ["0"] + walkthrough[i+1:]) + # print(f"Testing walkthrough replacing '{cmd}' with 'wait 1 minute'...") + # alt4 = test_walkthrough(env.copy(), walkthrough[:i] + ["wait 1 minute"] + walkthrough[i+1:]) + print(f"Testing walkthrough replacing '{cmd}' with 'look'...") + alt5 = test_walkthrough(env.copy(), walkthrough[:i] + ["look"] + walkthrough[i+1:]) + if all((alt1, alt2, alt5)): + commands_to_ignore.append(cmd) + else: breakpoint() - print(repr(sorted(set(commands_to_ignore)))) + not_triggered_ram_addrs = set(env._get_ram_addrs()) - triggered_ram_addrs + if not_triggered_ram_addrs: + msg = "-> Special RAM not used: " + repr(sorted(not_triggered_ram_addrs)) + print(colored(msg, "yellow")) + + if commands_to_ignore: + msg = "-> Walkthrough commands that can be safely ignored: " + repr(sorted(set(commands_to_ignore))) + print(colored(msg, "yellow")) + if not env.victory(): print(colored("FAIL", 'red')) if args.debug: From 869a9502925b9fecd370bf5fbd424d6dbbb7fcb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 9 Feb 2022 10:45:44 -0500 Subject: [PATCH 71/85] Noop check: lostpig --- frotz/src/games/lostpig.c | 60 +++++++++++++++++++++++++++++++------ jericho/game_info.py | 2 +- tools/test_games.py | 63 +++++++++++++++++++++++++++++++++------ 3 files changed, 106 insertions(+), 19 deletions(-) diff --git a/frotz/src/games/lostpig.c b/frotz/src/games/lostpig.c index 5464fc7c..598e756c 100644 --- a/frotz/src/games/lostpig.c +++ b/frotz/src/games/lostpig.c @@ -24,18 +24,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Lost Pig: http://ifdb.tads.org/viewgame?id=mohwfk47yjzii14w -const zword lostpig_special_ram_addrs[7] = { - 13958, // Looking for pig. - 2757, // Coin in box. - 2795, // Have chair - 2921, // Acquiring book - 2575, // Fill hat with water - 2846, // Chest open - 2895, // Picking up, dropping various objects +const zword lostpig_special_ram_addrs[0] = { + // 13958, // Looking for pig. + // 2757, // Coin in box. + // 2795, // Have chair + // 2921, // Acquiring book + // 2575, // Fill hat with water + // 2846, // Chest open + // 2895, // Picking up, dropping various objects }; zword* lostpig_ram_addrs(int *n) { - *n = 7; + *n = 0; return lostpig_special_ram_addrs; } @@ -111,4 +111,46 @@ int lostpig_ignore_attr_clr(zword obj_num, zword attr_idx) { } void lostpig_clean_world_objs(zobject* objs) { + clear_attr(&objs[161], 1); // (chestPowder) + clear_attr(&objs[210], 20); // box + clear_attr(&objs[161], 15); // (chestPowder) + + for (int i=1; i<=lostpig_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 31); + if (i != 201) { // Skip ball. + clear_attr(&objs[i], 14); + } + + if (i != 183 && i != 98) { // Skip (maze) and noise. + clear_prop(&objs[i], 54); // object's counter (if any) + } + } + + clear_prop(&objs[98], 53); // noise's counter + clear_prop(&objs[210], 8); // box's description? + clear_prop(&objs[210], 1); // box's description? + clear_prop(&objs[194], 9); // (gRoom) + + objs[211].parent = 0; // trfustuff + objs[293].parent = 0; // wlfor + objs[127].parent = 0; // pig + objs[528].parent = 0; // (bH) + objs[208].parent = 0; // smoke + objs[388].parent = 0; // b (topic) + + objs[206].parent = 0; // pipe + objs[207].parent = 0; // bag + + objs[209].parent = 0; // strange helmet + objs[210].parent = 0; // box + objs[404].parent = 0; // looter + objs[385].parent = 0; // tool (topic) + objs[386].parent = 0; // strange helmet (topic) + + objs[426].parent = 0; // misspage (topic) + objs[453].parent = 0; // propaper (topic) + objs[529].parent = 0; // (pageH) (topic) + + objs[329].parent = 0; // stuff tray + objs[361].parent = 0; // pretty picture (topic) } diff --git a/jericho/game_info.py b/jericho/game_info.py index d6e5e99e..a8f49eb5 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -270,7 +270,7 @@ "rom": "lostpig.z8", "seed" : 0, # Adapted from https://jayisgames.com/review/lost-pig.php#walkthrough - "walkthrough" : "X ME/INVENTORY/X FARM/X FOREST/LOOK FOR PIG/LISTEN/NORTHEAST/X STAIRS/X METAL THING/TAKE TUBE AND TORCH/LOOK INSIDE TUBE/BLOW IN TUBE/X CRACK/EAST/X PIG/FOLLOW PIG/CATCH IT/X FOUNTAIN/X BOWL/X COIN/X CURTAIN/X MAN/NORTH/X WEST MURAL/X EAST MURAL/X STATUE/X HAT/TAKE IT/WEAR IT/SOUTH/SOUTHWEST/X BOX/PUT COIN IN SLOT/PULL LEVER/X BRICK/TAKE IT/SMELL IT/TASTE IT/EAT IT/X DENT/HIT BOX/TAKE COIN/PUT COIN IN SLOT/PULL LEVER/HIT BOX/TAKE ALL FROM BASKET/PUT COIN IN SLOT/TAKE ALL FROM BASKET/X CHAIR/TAKE IT/EAST/X SHADOW/LISTEN/SHOUT/GREET GNOME/TELL GNOME ABOUT GRUNK/ASK GNOME ABOUT STATUE/ASK WHAT GNOME LOOKING FOR/LOOK UNDER BED/TALK TO GNOME ABOUT MOGGLEV/LOOK/LOOK UNDER BED/OPEN TRUNK/X BALL/TAKE BALL/SHOW TORCH TO GNOME/ASK GNOME ABOUT FIRE/SHOW BRICK TO GNOME/ASK GNOME ABOUT MOTHER/EAST/X SHELF/X TOP SHELF/DROP CHAIR/STAND ON CHAIR/X TOP SHELF/TAKE BOOK/X IT/GET DOWN/get chair/OPEN CHEST/TAKE POLE/X IT/WEST/SHOW POLE TO GNOME/ASK GNOME ABOUT COLOR MAGNET/SHOW BOOK TO GNOME/GIVE BOOK TO GNOME/EAST/ASK GNOME ABOUT PAGE/EAST/NORTHWEST/EAST/X RIVER/X THING/TAKE THING/CROSS RIVER/TOUCH THING WITH POLE/X KEY/TAKE WATER/FILL HAT WITH WATER/WEST/SOUTHEAST/UNLOCK CHEST/OPEN IT/POUR WATER ON POWDER/LIGHT TORCH WITH FIRE/NORTHWEST/WEST/X CRACK/TAKE PAPER/TAKE PAPER WITH POLE/BURN POLE WITH TORCH/TAKE PAPER WITH POLE/drop whistle/EAST/SOUTHWEST/EAST/GIVE PAPER TO GNOME/WAIT/GO TO PIG/SHOW BRICK TO PIG/DROP ALL BRICKS/Z/Z/Z/Z/TAKE PIG/give brick to pig/Go to table room/drop chair/drop pole/drop key/go to fountain/put coin in fountain/GO TO STATUE/X HAND/PUT TORCH IN HAND/NORTH/X WINDY TUNNEL/NORTH/SOUTH/TAKE TORCH/GO TO GNOME/ASK GNOME FOR BALL/GIVE TORCH TO GNOME/THANK GNOME/GO TO WINDY CAVE/close door/NORTH/EAST/NORTHWEST/SOUTHEAST/N/E/FOLLOW GNOME/FOLLOW GNOME/FOLLOW GNOME", + "walkthrough" : "X ME/INVENTORY/X FARM/X FOREST/LOOK FOR PIG/LISTEN/NORTHEAST/X STAIRS/X METAL THING/TAKE TUBE AND TORCH/LOOK INSIDE TUBE/BLOW IN TUBE/X CRACK/EAST/X PIG/FOLLOW PIG/CATCH IT/X FOUNTAIN/X BOWL/X COIN/X CURTAIN/X MAN/NORTH/X WEST MURAL/X EAST MURAL/X STATUE/X HAT/TAKE HAT/WEAR HAT/SOUTH/SOUTHWEST/X BOX/PUT COIN IN SLOT/PULL LEVER/X BRICK/TAKE BRICK/SMELL BRICK/TASTE BRICK/EAT BRICK/X DENT/HIT BOX/TAKE COIN/PUT COIN IN SLOT/PULL LEVER/HIT BOX/TAKE ALL FROM BASKET/PUT COIN IN SLOT/TAKE ALL FROM BASKET/X CHAIR/TAKE CHAIR/EAST/X SHADOW/LISTEN/SHOUT/GREET GNOME/TELL GNOME ABOUT GRUNK/ASK GNOME ABOUT STATUE/ASK WHAT GNOME LOOKING FOR/LOOK UNDER BED/TALK TO GNOME ABOUT MOGGLEV/LOOK/LOOK UNDER BED/OPEN TRUNK/X BALL/TAKE BALL/SHOW TORCH TO GNOME/ASK GNOME ABOUT FIRE/SHOW BRICK TO GNOME/ASK GNOME ABOUT MOTHER/EAST/X SHELF/X TOP SHELF/DROP CHAIR/STAND ON CHAIR/X TOP SHELF/TAKE BOOK/X BOOK/GET DOWN/get chair/OPEN CHEST/TAKE POLE/X POLE/WEST/SHOW POLE TO GNOME/ASK GNOME ABOUT COLOR MAGNET/SHOW BOOK TO GNOME/GIVE BOOK TO GNOME/EAST/ASK GNOME ABOUT PAGE/EAST/NORTHWEST/EAST/X RIVER/X THING/TAKE THING/CROSS RIVER/TOUCH THING WITH POLE/X KEY/TAKE WATER/FILL HAT WITH WATER/WEST/SOUTHEAST/UNLOCK CHEST/OPEN IT/POUR WATER ON POWDER/LIGHT TORCH WITH FIRE/NORTHWEST/WEST/X CRACK/TAKE PAPER/TAKE PAPER WITH POLE/BURN POLE WITH TORCH/TAKE PAPER WITH POLE/drop whistle/EAST/SOUTHWEST/EAST/GIVE PAPER TO GNOME/WAIT/GO TO PIG/SHOW BRICK TO PIG/DROP ALL BRICKS/Z/Z/Z/Z/TAKE PIG/give brick to pig/Go to table room/drop chair/drop pole/drop key/go to fountain/put coin in fountain/GO TO STATUE/X HAND/PUT TORCH IN HAND/NORTH/X WINDY TUNNEL/NORTH/SOUTH/TAKE TORCH/GO TO GNOME/ASK GNOME FOR BALL/GIVE TORCH TO GNOME/THANK GNOME/GO TO WINDY CAVE/close door/NORTH/EAST/NORTHWEST/SOUTHEAST/N/E/FOLLOW GNOME/FOLLOW GNOME/FOLLOW GNOME", "grammar" : "a/t/talk piglish;about/author/clue/clues/credit/credits/help/hint/hints/info/menu/walkthrou/walkthru;arr/arrr/arrrr/growl/grr/grrr/grrrr/rar/rarr/rarrr/roar/rrr/rrrr/scream/yell/shout;awake/awaken/wake;awake/awaken/wake up;back/step/stand;back/step/stand back;back/step/stand up;bah/grumble/sigh;bathe/dive/swim;burp/fart;bye/farewell/good-bye/goodbye;consider/contempla/think;cough;crap/pee/piss/poop/wee/wizz;cry/frown/grimace/scowl/sniffle/sob;curse/dummy/idiot/stupid/damn/fuck/shit/sod;dance;declaim/deliver;declaim/deliver at wall;declaim/deliver from table top;declaim/deliver from table/tabletop;declaim/deliver monologue/monologue;declaim/deliver monologue/monologue at wall;declaim/deliver monologue/monologue from table/tabletop/top;declaim/deliver monologue/monologue to wall;declaim/deliver to wall;die/q/quit;dig;drink/sip;drool/spit;dross/bother/curses/darn/drat;dunno/shrug;exit/out/outside;exits;fly;fly away;fly up;frotz/plover/plugh/rezrov/wazzum/xyzzy/yoho/zarf/zork;full/fullscore;full/fullscore score;get down;get out/off/up;good bye;greet/hello/hi/a/t/talk/wave;grin/smile/smirk;groan/ugh/ugh!/uh/um;ha/ha!/haw/hee/laugh;ha/ha!/haw/hee/laugh ha/haw/ha!/hee;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/ha!/hee;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/hee ha/haw/ha!/hee;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/hee ha/haw/hee ha/haw/ha!/hee;have/take a bath;have/take bath;hear/listen;heat/warm up;hiccough/hiccup;hide;hooray/hurrah/hurray/woo/woohoo/wooo/woot/yay;hop/jump/skip;i dont/don't know/know!;i dunno/dunno!;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/enter;l/look;la/lalala la;la/lalala la la;la/lalala/sing;leave/go/run/walk;nah/never/nope/no;nod/ok/sure/yeah/yup/y/yes;noscript/unscript;notify;notify off;notify on;nouns/pronouns;objects;places;play;pray;recording;recording off;recording on;relax/rest/wait/z;replay;restart;restore;save;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie/long/verbose/brief/normal;smell/sniff;sneeze;snooze/nap/sleep;snort/grunt/knio/oink/squeal;sorry;stand by;stick out tongue;stick tongue out;stretch;stretch out;take inventory;thank/thanks;thank/thanks you;topic/topics;topic/topics off;topic/topics on;verify;version;whistle;win;win game;win lost pig;win story;yawn;zobleb;ztorf;a/t/talk piglish at/to OBJ;a/t/talk/answer/say/speak to OBJ;adjust/set OBJ;adjust/set/burn/light OBJ on fire;answer OBJ;apologise/apologize to OBJ;arr/arrr/arrrr/growl/grr/grrr/grrrr/rar/rarr/rarrr/roar/rrr/rrrr/scream/yell at OBJ;attach/fasten/tie OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;back/step/stand away from OBJ;bah/grumble/sigh at/to OBJ;beat/kick/poke/prod/slap/spank/attack/break/crack/destroy/fight/hit/murder/punch/smash/thump/wreck OBJ;bite/chew/lick/taste/eat OBJ;blow OBJ;blow on/at/in OBJ;bother/curses/darn/drat OBJ;buy/purchase OBJ;call OBJ;call to/for OBJ;carry/hold OBJ;chase OBJ;chase after OBJ;check/describe/examine/watch/x OBJ;chop/cut/prune/slice OBJ;climb/scale OBJ;climb/scale into/in/inside OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;complain to/at OBJ;consider/contempla OBJ;consider/contempla/think about OBJ;cook/burn/light/burn/light OBJ;count OBJ;crap/pee/piss/poop/wee/wizz on/in OBJ;cry/frown/grimace/scowl/sniffle/sob at/to OBJ;curse/damn/fuck/shit/sod OBJ;dance with OBJ;discard/drop OBJ;disrobe/doff/shed/remove OBJ;dive/swim OBJ;dive/swim in OBJ;don/wear OBJ;douse/extinguis/smother OBJ;drag/pull OBJ;draw OBJ;draw OBJ;drink/sip OBJ;drink/sip from OBJ;drool/spit at/in/on OBJ;drown/splash OBJ;dry OBJ;dry OBJ off;dry off OBJ;dummy/idiot/stupid OBJ;dust/polish/rub/scrub/shine/sweep/wipe OBJ;earn OBJ;empty OBJ out;equip/wield OBJ;feel/fondle/grope/touch in/inside OBJ;fill OBJ;flip OBJ;frotz/plover/plugh/rezrov/wazzum/xyzzy/yoho/zarf/zork OBJ;get in/into/on/onto OBJ;get off OBJ;get/catch/grab/pin/steal/swipe/trap/take OBJ;go/run/walk back to OBJ;go/run/walk to OBJ;go/run/walk/enter OBJ;goto/find/follow/seek/go/run/walk OBJ;greet/hello/hi OBJ;grin/smile/smirk at/to OBJ;groan/ugh/ugh!/uh/um OBJ;grunt/knio/oink/squeal at OBJ;ha/ha!/haw/hee/laugh OBJ;ha/ha!/haw/hee/laugh at OBJ;ha/ha!/haw/hee/laugh ha/haw/hee OBJ;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/ha!/hee OBJ;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/hee ha/haw/ha!/hee OBJ;ha/ha!/haw/hee/laugh ha/haw/hee ha/haw/hee ha/haw/hee ha/haw/hee OBJ;hear/listen OBJ;hear/listen for OBJ;hear/listen to OBJ;heat/warm OBJ;heat/warm OBJ up;heat/warm up OBJ;heat/warm up by OBJ;heat/warm up over by OBJ;heat/warm up with OBJ;hide/get/go/run/walk behind/under/in OBJ;hooray/hurrah/hurray/woo/woohoo/wooo/woot/yay OBJ;hooray/hurrah/hurray/woo/woohoo/wooo/woot/yay for OBJ;hop/jump/skip on/at OBJ;huff/puff and puff at OBJ;huff/puff at OBJ;kill OBJ;l/look at OBJ;l/look behind OBJ;l/look inside/in/into/through/on OBJ;l/look under OBJ;leave/exit/out/outside OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit at OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;lock OBJ;molest/embrace/hug/kiss OBJ;nod/ok/sure/yeah/yup at/to OBJ;nudge/straighte/clear/move/press/push/shift OBJ;open/uncover/undo/unwrap OBJ;paw OBJ;paw at OBJ;peel off OBJ;pet/scratch/feel/fondle/grope/touch OBJ;pick OBJ up;pick up OBJ;play OBJ;play with/on/in OBJ;pour/empty OBJ;pour/empty out OBJ;put OBJ down;put down OBJ;put on OBJ;put/blow OBJ out;put/blow out OBJ;reach into/in OBJ;read OBJ;remember OBJ;repair/fix OBJ;rip/tear OBJ;rock/shake OBJ;rotate/screw/turn/twist/unscrew OBJ;rotate/screw/turn/twist/unscrew/switch OBJ off;rotate/screw/turn/twist/unscrew/switch OBJ on;rotate/screw/turn/twist/unscrew/switch on OBJ;rotate/screw/turn/twist/unscrew/switch/close/cover/shut off OBJ;scare/threaten OBJ;scoop up OBJ;scoop/peel OBJ;search OBJ;search/l/look for OBJ;shout at/to OBJ;shout for OBJ;sing at/to OBJ;smoke OBJ;snort/smell/sniff OBJ;stand by OBJ;stand in OBJ;stand on OBJ;step in/into OBJ;step on/onto OBJ;step/stand near OBJ;step/stand next to OBJ;stick out tongue at OBJ;stick tongue out at OBJ;swallow OBJ;switch OBJ;take OBJ off;take off OBJ;thank/thanks OBJ;thank/thanks you OBJ;topic/topics OBJ;torture OBJ;toss/throw OBJ;unlock OBJ;vault/cross/hop/jump/skip OBJ;vault/hop/jump/skip over OBJ;wash/clean OBJ;wave at/to OBJ;wave/swing OBJ;waylay/wrestle OBJ;wrestle with OBJ;wring/squash/squeeze OBJ out;wring/squash/squeeze out OBJ;wring/squidge/squish/squash/squeeze OBJ;adjust/set OBJ to OBJ;adjust/set/burn/light OBJ on fire with/using OBJ;answer/say/speak OBJ to OBJ;attach/fasten/tie OBJ to OBJ;beat/kick/poke/prod/slap/spank OBJ at OBJ;beat/kick/poke/prod/slap/spank/attack/break/crack/destroy/fight/hit/murder/punch/smash/thump/wreck OBJ with OBJ;burn/light OBJ with/using OBJ;catch/grab/pin/steal/swipe/trap/take OBJ off OBJ;chase OBJ OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift OBJ in/into/to/toward OBJ;consult OBJ about OBJ;consult OBJ on OBJ;cook/burn/light OBJ with OBJ;dip/dunk OBJ in/inside/into OBJ;discard/drop OBJ at/against/on/onto OBJ;discard/drop OBJ in/into/down OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;display/present/show/display/present/show OBJ OBJ;display/present/show/display/present/show OBJ to OBJ;douse/extinguis/smother OBJ with/in OBJ;draw OBJ with OBJ;drown/splash OBJ on/at OBJ;drown/splash OBJ with/in OBJ;dry OBJ off on OBJ;dry OBJ off on OBJ;dry OBJ off with OBJ;dry OBJ off with OBJ;dry OBJ on OBJ;dry OBJ on OBJ;dry OBJ with OBJ;dry OBJ with OBJ;dry off OBJ with OBJ;dry off OBJ with OBJ;dust/polish/rub/scrub/shine/sweep/wipe OBJ on/over/across OBJ;empty OBJ on/onto OBJ;empty OBJ to/in/into OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feel/fondle/grope/touch OBJ to OBJ;feel/fondle/grope/touch in/inside OBJ with OBJ;fill OBJ from/with OBJ;force/jemmy/lever/prise/prize/pry OBJ apart/open with OBJ;force/jemmy/lever/prise/prize/pry apart/open OBJ with OBJ;get/catch/grab/pin/steal/swipe/trap/take/remove OBJ from OBJ;get/catch/grab/pin/steal/swipe/trap/take/remove/peel OBJ with OBJ;get/take OBJ in OBJ;give/offer/pay OBJ and OBJ;give/offer/pay over OBJ to OBJ;heat/warm OBJ up with OBJ;heat/warm OBJ up with OBJ;heat/warm OBJ with OBJ;heat/warm OBJ with OBJ;heat/warm up OBJ with OBJ;heat/warm up OBJ with OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;open/uncover/undo/unwrap OBJ with OBJ;pick OBJ up in OBJ;pick OBJ up with OBJ;pick up OBJ in OBJ;pick up OBJ with OBJ;point OBJ at OBJ;point at OBJ with OBJ;pour OBJ into/in OBJ;pour OBJ onto/on OBJ;pour out OBJ into/in OBJ;pour out OBJ onto/on OBJ;put OBJ out with/in OBJ;put out OBJ with/in OBJ;reach OBJ in/into OBJ;reach into/in OBJ with OBJ;reach/feel/fondle/grope/touch/dust/polish/rub/scrub/shine/sweep/wipe/clear/move/press/push/shift OBJ with OBJ;rip/tear/chop/cut/prune/slice OBJ with OBJ;scoop OBJ up with/into OBJ;scoop OBJ with/into OBJ;scoop up OBJ with/into OBJ;shout OBJ at/to OBJ;stick/put OBJ over/across OBJ;stick/put/discard/drop OBJ on/onto OBJ;take OBJ off of OBJ;torture/kill OBJ with OBJ;toss/throw OBJ at/against/on/onto OBJ;toss/throw/stick/put OBJ in/inside/into OBJ;transfer OBJ to OBJ;unlock/force/jemmy/lever/prise/prize/pry OBJ with OBJ;vault OBJ with OBJ;vault over OBJ with OBJ;wash/clean OBJ with/in OBJ;wring/squash/squeeze OBJ out over/into OBJ;wring/squidge/squish/squash/squeeze OBJ over/into OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index a8c673fa..3e14b9cd 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -384,6 +384,34 @@ "examine corner", # you find a tranished brass key ], }, + "lostpig.z8": { + "*": [ + 87, # Gnome examines the book with a missing page. + 118, # Gnome put the missing page back into the book. + 123, 124, 125, 126, # Pig is eating the bricks. + ], + "examine west": [ + 23, # Describes the picture on the west wall (new topics). + ], + "examine east": [ + 23, 24, # Describes the picture on the east wall (new topics). + ], + "examine south": [ + 14, 15, 16, 17, 18, 19, 20, # Maps to "examine curtain" (see below) + ], + "ignore_commands": [ + "examine stairs", "examine metal", # reveals the whistle and enables a new topic. + "examine coin", # Enables a new topic. + "examine curtain", # Reveals a way out of cave. + "examine block", "examine stone", # Reveals mark on the side of the block. + "examine hat", "examine little", # Enable topic about hat. + "examine box", "examine dent", # Reveal a lever (enable topics). + "examine gnome", # New topics: dress, clos, hair, ear, nose. + "examine chest", "examine keyhole", # New topic: key. + "examine book", # New topic: mark + "examine big", "examine paper", # New topic: piece paper + ] + }, } SKIP_CHECK_STATE = { @@ -704,15 +732,32 @@ ], }, "lostpig.z8": { - 15: "follow pig", # Not needed to complete the game. - 28: "wear it", # Not needed to complete the game. - 36: "smell it", # Not needed to complete the game. - 52: "listen", # Not needed to complete the game. - 94: "take thing", # Not needed to complete the game. - 95: "cross river", # Not needed to complete the game. - 98: "take water", # Not needed to complete the game. - 109: "take paper", # Not needed to complete the game. - 110: "take paper with pole", # Not needed to complete the game. + 15: "follow pig", + 28: "wear hat", + 36: "smell brick", + 52: "listen", + 58: "look under bed", + 61: "look under bed", + 62: "open trunk", # It's looked. + 64: "take ball", + 79: "open chest", # Grunk not have any key. + 88: "ask gnome about page", + 94: "take thing", + 95: "cross river", + 98: "take water", + 109: "take paper", + 110: "take paper with pole", + 122: "z", # Waiting for to eat the brick. + 139: "north", # It too dark, and tunnel look twisty. + 145: "thank gnome", + "noop": [ + "look", + 'inventory', + 'look inside tube', 'x brick', 'x coin', 'x crack', 'x dent', + 'x fountain', 'x hand', 'x key', 'x man', 'x pig', 'x shadow', + 'x thing', 'x chair', 'x farm', 'x forest', 'x pole', 'x windy tunnel', + 'x top shelf', 'x hat', 'x river', 'x ball', 'x shelf', + ], }, "ludicorp.z5": { 7: "smell car", # Not needed to complete the game. From 8baa78767c774644c68c479557dd2e71f8ba7ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Wed, 9 Feb 2022 11:01:25 -0500 Subject: [PATCH 72/85] Noop check: ludicorp --- frotz/src/games/ludicorp.c | 11 ++++------- tools/test_games.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/frotz/src/games/ludicorp.c b/frotz/src/games/ludicorp.c index 051d1c04..4bc8a132 100644 --- a/frotz/src/games/ludicorp.c +++ b/frotz/src/games/ludicorp.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -102,11 +102,8 @@ int ludicorp_ignore_attr_clr(zword obj_num, zword attr_idx) { } void ludicorp_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=ludicorp_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; + for (int i=1; i<=ludicorp_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 24); + clear_attr(&objs[i], 25); } } diff --git a/tools/test_games.py b/tools/test_games.py index 3e14b9cd..0bb39eae 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -412,6 +412,11 @@ "examine big", "examine paper", # New topic: piece paper ] }, + "ludicorp.z5": { + "ignore_commands": [ + "examine White Board", # Reveals Board Marker object. + ], + }, } SKIP_CHECK_STATE = { @@ -766,6 +771,18 @@ 239: "play arcade", # (you died) Not needed to complete the game. 241: "play pool", # (no ball nor cues) Not needed to complete the game. 255: "w", # (outer airlock door blocks your way) Not needed to complete the game. + "noop": [ + 'x arcade', 'x bar', 'x blank card', 'x boxes', 'x bushes', 'x button', 'x car', + 'x carpark', 'x chairs', 'x city', 'x clingfilm', 'x coffee', 'x computers', + 'x console', 'x cooler', 'x copier', 'x counter', 'x cubicles', 'x cup', + 'x cupboard', 'x desk', 'x desks', 'x dispenser', 'x door', 'x drain', 'x duct', + 'x flowers', 'x footprints', 'x fountain', 'x fuse', 'x gate', 'x generator', + 'x grill', 'x gun', 'x key', 'x keypad', 'x keys', 'x knife', 'x label', 'x ladder', + 'x light', 'x machine', 'x marker', 'x panel', 'x paper', 'x papers', 'x pass', 'x patch', + 'x pen', 'x pipe', 'x plants', 'x plaque', 'x pool', 'x pots', 'x printer', 'x robot', + 'x screen', 'x servers', 'x sheet', 'x shelves', 'x slot', 'x statue', 'x toner', + 'x tray', 'x trees', 'x water', 'x well', 'x window', 'x wire' + ], }, "lurking.z3": { "noop": ["z"] From 87ed928fd5386e136539c2a3d17fcadeb1edbabc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 11 Feb 2022 15:17:49 -0500 Subject: [PATCH 73/85] Improve debugging tools --- jericho/jericho.py | 47 +++++++++++++++++++++++++++++++++++++++ tools/find_special_ram.py | 4 ++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/jericho/jericho.py b/jericho/jericho.py index 85bb9d91..a80363bf 100644 --- a/jericho/jericho.py +++ b/jericho/jericho.py @@ -1058,3 +1058,50 @@ def _get_special_ram(self): ram = np.zeros(ram_size, dtype=np.uint8) self.frotz_lib.get_special_ram(as_ctypes(ram)) return ram + + def _get_globals(self): + """ Extract the value for all 240 global variables. """ + ram = np.zeros(self.frotz_lib.getRAMSize(), dtype=np.uint8) + self.frotz_lib.getRAM(as_ctypes(ram)) + + # The starting address for the 240 two-byte global variables (ranging from G00 to Gef) + # is found at byte 0x0c of the header. + # Ref: https://inform-fiction.org/zmachine/standards/z1point1/sect11.html + # Ref: https://inform-fiction.org/zmachine/standards/z1point1/sect06.html#two + globals_addr = ram.view(">u2")[0x0c // 2] + globals = ram[globals_addr:globals_addr + 240 * 2].view(">i2") + return globals + + def _print_memory_map(self): + ram = np.zeros(self.frotz_lib.getRAMSize(), dtype=np.uint8) + self.frotz_lib.getRAM(as_ctypes(ram)) + + high_addr = ram.view(">u2")[0x04 // 2] + dict_addr = ram.view(">u2")[0x08 // 2] + objs_addr = ram.view(">u2")[0x0a // 2] + globals_addr = ram.view(">u2")[0x0c // 2] + static_addr = ram.view(">u2")[0x0e // 2] + abbr_addr = ram.view(">u2")[0x18 // 2] + length_of_file = ram.view(">u2")[0x1a // 2] + + print(" -= {} =- ".format(self.story_file.decode())) + print("Dynamic | {:05x} | header".format(0)) + # print(" | {:05x} | abbreviation strings".format()) + print(" | {:05x} | abbreviation table".format(abbr_addr)) + print(" | {:05x} | global variables".format(globals_addr)) + # print(" | {:05x} | property defaults".format()) + print(" | {:05x} | objects".format(objs_addr)) + # print(" | {:05x} | object descriptions and properties".format()) + # print(" | {:05x} | arrays".format()) + print("Static | {:05x} | grammar table".format(static_addr)) + # print(" | {:05x} | actions table".format()) + # print(" | {:05x} | preactions table".format()) + # print(" | {:05x} | adjectives table".format()) + print(" | {:05x} | dictionary".format(dict_addr)) + print("High | {:05x} | Z-code".format(high_addr)) + # print(" | {:05x} | static strings".format()) + print(" | {:05x} | end of file".format(length_of_file)) + + + + diff --git a/tools/find_special_ram.py b/tools/find_special_ram.py index be41b1f3..1c0d074d 100644 --- a/tools/find_special_ram.py +++ b/tools/find_special_ram.py @@ -30,7 +30,7 @@ def get_zmp(env): #start = zmp.view(">u2")[6] # ref: https://inform-fiction.org/zmachine/standards/z1point1/sect06.html#two #length = 240 * 2 # 240 2-byte global variables. #globals = zmp[start:start + length].view(">i2") - return zmp + return zmp.view(">u2") def display_indices(indices): @@ -189,7 +189,7 @@ def display_unique_changes(idx, history, changes_history): # if matches[idx][0][0] == 0: # continue - print(f"{idx:6d}: {count:3d} : " + ", ".join(f"{i}.{cmd}({value})" for i, cmd, value in matches[idx][:20])) + print(f"{idx*2}-{idx*2+1}: {count:3d} : " + ", ".join(f"{i}.{cmd}({value:x})" for i, cmd, value in matches[idx][:20])) def main(): From 87eb5fce1c748f54aeaa444a3267bafb08d2a550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 11 Feb 2022 15:17:58 -0500 Subject: [PATCH 74/85] Noop check: lurking --- frotz/src/games/lurking.c | 55 ++++++++++++++++++++++++++++----------- jericho/game_info.py | 2 +- tools/test_games.py | 46 +++++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 17 deletions(-) diff --git a/frotz/src/games/lurking.c b/frotz/src/games/lurking.c index 5ebb0ec4..7d166fc0 100644 --- a/frotz/src/games/lurking.c +++ b/frotz/src/games/lurking.c @@ -26,18 +26,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // The Lurking Horror: http://ifdb.tads.org/viewgame?id=jhbd0kja1t57uop const zword lurking_special_ram_addrs[11] = { - 883, // Cut line with axe - 756, // knock on door - 859, // Read page, click on more - 813, // Throw axe at cord + // 4889, // Drinking coke + // 756, // knock on door 1047, // Lower ladder (alt. 1163, 1333) - 11251, // Microwave timer + 1067, // Move lab bench. 11235, // press up/down button - 961, // Microwave setting + 11251, // Microwave timer 1145, // Cleaning up junk - 4889, // Drinking coke - 935, // Position of valve + 813, // Throw axe at cord + 859, // Read page, click on more, again and again. + 883, // Cut line with axe 883, // Cutting line + 935, // Position of valve + 961, // Microwave setting + // 1132, 1133, // Microwave timer }; const char *lurking_intro[] = { "sit on chair\n", @@ -113,11 +115,34 @@ int lurking_ignore_attr_clr(zword obj_num, zword attr_idx) { } void lurking_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 1); - // Clear attr 6 - for (i=1; i<=lurking_get_num_world_objs(); ++i) { - objs[i].attr[0] &= mask; - } + for (int i=1; i<=lurking_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 6); + clear_attr(&objs[i], 10); + } + + clear_attr(&objs[183], 11); // sign-up sheet + + clear_prop(&objs[90], 3); // Chinese food. + clear_prop(&objs[206], 16); // Infinite Corridor. + + // Completely ignore the 'pseudo' object. + strcpy(&objs[247].name, "pseudo"); // Its name reflects what the player's focus. + + objs[100].parent = 0; // urchin + objs[235].parent = 0; // waxer + objs[20].parent = 0; // man + + if (objs[56].parent != objs[122].parent) { // If player is not in the same room as the doors. + clear_attr(&objs[122], 13); // doors + clear_attr(&objs[225], 13); // doors + } + + objs[143].parent = 0; // tangle machinery + objs[153].parent = 0; // tangle machinery + + // // Track whether player has knocked on the Alchemy door. + int N = 23; // Use last property slot. + objs[108].prop_ids[N-1] = 63; + objs[108].prop_lengths[N-1] = 1; + objs[108].prop_data[(N-1) * JERICHO_PROPERTY_LENGTH] = (zmp[9306] == 140 && zmp[9307] == 121); } diff --git a/jericho/game_info.py b/jericho/game_info.py index a8f49eb5..6dcc9dd8 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -289,7 +289,7 @@ "rom": "lurking.z3", "seed" : 0, # Walkthrough adapted from http://mirror.ifarchive.org/if-archive/solutions/jgunness.zip and http://www.eristic.net/games/infocom/lurking.html - "walkthrough": "STAND/S/W/OPEN FRIDGE/GET COKE AND CARTON/OPEN CARTON/OPEN OVEN/PUT CARTON IN OVEN/CLOSE OVEN/PRESS 4/PRESS 0/PRESS 5/PRESS MED/PRESS START/Z/Z/Z/Z/OPEN OVEN/GET CARTON/E/N/GIVE CARTON TO HACKER/ASK HACKER ABOUT KEYS/ASK HACKER FOR MASTER KEY/SIT DOWN/CLICK ON EDIT/CLICK ON PAPER/READ PAGE/CLICK ON MORE/AGAIN/AGAIN/AGAIN/D/Z/GET STONE/Z/Z/STAND UP/Z/Z/Z/S/PRESS DOWN BUTTON/Z/Z/S/OPEN PANEL/GET FLASHLIGHT/OPEN DOOR/N/D/D/E/GET GLOVES AND CROWBAR/WEAR GLOVES/U/LIGHT FLASHLIGHT/GET FLASK/D/TURN OFF FLASHLIGHT/W/W/W/U/S/GET CONTAINER/E/Z/Z/Z/E/U/CLIMB ROPE/LOWER LADDER/OPEN DOOR/OUT/U/REMOVE PLUG/DROP PLUG/GET PAPER/D/IN/D/D/E/SMASH CABINET/GET AXE/W/THROW AXE AT CORD/OPEN CONTAINER/POUR WAX ON FLOOR/DROP CONTAINER AND ASSIGNMENT/E/E/N/D/SE/GET BOOTS/WEAR THEM/U/U/UNLOCK DOOR WITH KEY/OPEN DOOR/OUT/U/D/THROW STONE AT CREATURE/U/EXAMINE TREE/DIG IN TUB/GET HAND/D/IN/D/S/GET STONE/N/D/NW/U/S/W/W/W/W/N/D/E/GET IN FORKLIFT/START IT/E/E/E/LIGHT FLASHLIGHT/REMOVE JUNK WITH FORKLIFT/AGAIN/AGAIN/AGAIN/E/GET OUT OF FORKLIFT/OPEN MANHOLE WITH CROWBAR/D/N/D/GET KNIFE/U/S/U/W/W/TURN OFF FLASHLIGHT/W/W/W/U/S/E/E/E/E/S/KNOCK ON DOOR/Z/GIVE PAPER TO PROFESSOR/S/Z/Z/CUT LINE WITH KNIFE/GET OUT OF PENTAGRAM/MOVE BENCH/OPEN TRAPDOOR/D/OPEN TRAPDOOR/LIGHT FLASHLIGHT/U/PUT HAND IN LIQUID/Z/Z/GET HAND/GET HYRAX/PUT IT ON HAND/DRINK COKE/N/OPEN DOOR/N/TURN OFF FLASHLIGHT/N/W/W/W/W/N/S/E/E/E/E/W/W/W/W/N/D/SHOW HAND TO URCHIN/GET CUTTER/D/DROP CUTTER, FLASK AND AXE/NW/UNLOCK PADLOCK WITH KEY/GET PADLOCK/OPEN HATCH/LIGHT FLASHLIGHT/D/E/TURN VALVE WITH CROWBAR/Z/Z/Z/TURN VALVE/CLOSE VALVE/E/E/REMOVE BRICK WITH CROWBAR/REMOVE NEW BRICK WITH CROWBAR/W/W/W/U/TURN OFF FLASHLIGHT/DROP KNIFE AND CROWBAR/SE/GET ALL/U/E/E/U/PRESS DOWN/D/Z/Z/WEDGE DOORS WITH AXE/D/GET CHAIN/TIE CHAIN TO ROD/LOCK IT WITH PADLOCK/U/PUT CHAIN ON HOOK/GET AXE/U/U/PRESS UP BUTTON/D/D/Z/Z/Z/WEDGE DOORS WITH AXE/D/GET AXE/LIGHT FLASHLIGHT/N/W/W/W/W/W/D/D/CUT GROWTH WITH CUTTER/D/N/D/S/S/D/OPEN FLASK/LOOK IN IT/POUR LIQUID ON SLIME/UNLOCK DOOR WITH KEY/OPEN DOOR/S/REACH INTO POOL/PULL LINE/CUT LINE WITH AXE/AGAIN/AGAIN/GET LINE/OPEN METAL COVER/UNPLUG COAXIAL CABLE/PUT LINE IN SOCKET/Z/THROW STONE AT THING/GET STONE", + "walkthrough": "STAND/S/W/OPEN FRIDGE/GET COKE AND CARTON/OPEN CARTON/OPEN OVEN/PUT CARTON IN OVEN/CLOSE OVEN/PRESS 4/PRESS 0/PRESS 5/PRESS MED/PRESS START/Z/Z/Z/Z/OPEN OVEN/GET CARTON/E/N/GIVE CARTON TO HACKER/ASK HACKER ABOUT KEYS/ASK HACKER FOR MASTER KEY/SIT DOWN/CLICK ON EDIT/CLICK ON PAPER/READ PAGE/CLICK ON MORE/AGAIN/AGAIN/AGAIN/D/Z/GET STONE/Z/STAND UP/Z/Z/Z/S/PRESS DOWN BUTTON/Z/Z/S/OPEN PANEL/GET FLASHLIGHT/OPEN DOOR/N/D/D/E/GET GLOVES AND CROWBAR/WEAR GLOVES/U/LIGHT FLASHLIGHT/GET FLASK/D/TURN OFF FLASHLIGHT/W/W/W/U/S/GET CONTAINER/E/Z/Z/Z/E/U/CLIMB ROPE/LOWER LADDER/OPEN DOOR/OUT/U/REMOVE PLUG/DROP PLUG/GET PAPER/D/IN/D/D/E/SMASH CABINET/GET AXE/W/THROW AXE AT CORD/OPEN CONTAINER/POUR WAX ON FLOOR/DROP CONTAINER AND ASSIGNMENT/E/E/N/D/SE/GET BOOTS/WEAR THEM/U/U/UNLOCK DOOR WITH KEY/OPEN DOOR/OUT/U/D/THROW STONE AT CREATURE/U/EXAMINE TREE/DIG IN TUB/GET HAND/D/IN/D/S/GET STONE/N/D/NW/U/S/W/W/W/W/N/D/E/GET IN FORKLIFT/START IT/E/E/E/LIGHT FLASHLIGHT/REMOVE JUNK WITH FORKLIFT/AGAIN/AGAIN/AGAIN/E/GET OUT OF FORKLIFT/OPEN MANHOLE WITH CROWBAR/D/N/D/GET KNIFE/U/S/U/W/W/TURN OFF FLASHLIGHT/W/W/W/U/S/E/E/E/E/S/KNOCK ON DOOR/Z/GIVE PAPER TO PROFESSOR/S/Z/Z/CUT LINE WITH KNIFE/GET OUT OF PENTAGRAM/MOVE BENCH/OPEN TRAPDOOR/D/OPEN TRAPDOOR/LIGHT FLASHLIGHT/U/PUT HAND IN LIQUID/Z/Z/GET HAND/GET HYRAX/PUT IT ON HAND/DRINK COKE/N/OPEN DOOR/N/TURN OFF FLASHLIGHT/N/W/W/W/W/N/S/E/E/E/E/W/W/W/W/N/D/SHOW HAND TO URCHIN/GET CUTTER/D/DROP CUTTER, FLASK AND AXE/NW/UNLOCK PADLOCK WITH KEY/GET PADLOCK/OPEN HATCH/LIGHT FLASHLIGHT/D/E/TURN VALVE WITH CROWBAR/Z/Z/Z/TURN VALVE/CLOSE VALVE/E/E/REMOVE BRICK WITH CROWBAR/REMOVE NEW BRICK WITH CROWBAR/W/W/W/U/TURN OFF FLASHLIGHT/DROP KNIFE AND CROWBAR/SE/GET ALL/U/E/E/U/PRESS DOWN/D/WEDGE DOORS WITH AXE/D/GET CHAIN/TIE CHAIN TO ROD/LOCK IT WITH PADLOCK/U/PUT CHAIN ON HOOK/GET AXE/U/U/PRESS UP BUTTON/D/D/Z/WEDGE DOORS WITH AXE/D/GET AXE/LIGHT FLASHLIGHT/N/W/W/W/W/W/D/D/CUT GROWTH WITH CUTTER/D/N/D/S/S/D/OPEN FLASK/LOOK IN IT/POUR LIQUID ON SLIME/UNLOCK DOOR WITH KEY/OPEN DOOR/S/REACH INTO POOL/PULL LINE/CUT LINE WITH AXE/AGAIN/AGAIN/GET LINE/OPEN METAL COVER/UNPLUG COAXIAL CABLE/PUT LINE IN SOCKET/Z/THROW STONE AT THING/GET STONE", "grammar" : "answer/reply/respon;brief;call/say/talk;chase/follow;clear/move/shift/drive/go/procee/run/steer/step/walk;concea/hide;damn/fuck/shit;depart/exit/withdr;diagno;die;disemb;dive/jump/leap;enter;gaze/l/look/stare;greeti/hello/hi;hack;help/hint;hop/skip;i/invent;leave;listen;nap/sleep;no/nope;okay/y/yes;pray;q/quit;restar;restor;rise/stand;save;score;scream/shout/yell;script;smell/sniff;super/superb;swim/wade;t/time;thank/thanks;unscri;verbos;versio;wait/z;where;who;yawn;admire/compli OBJ;answer/reply/respon OBJ;approa OBJ;ask/quiz about OBJ;ask/quiz for OBJ;attack/fight/hit/strike OBJ;awake/wake OBJ;awake/wake up OBJ;bargai with OBJ;beckon/wave OBJ;beckon/wave to OBJ;beckon/wave/scream/shout/yell at OBJ;bite OBJ;blow out OBJ;board/ride OBJ;break/crack/destro/scrape/scratc/smash/wreck OBJ;bury OBJ;call/say/talk OBJ;call/say/talk to OBJ;carry/catch/get/grab/hold/snatch/take OBJ;carry/catch/get/grab/hold/snatch/take off OBJ;carry/catch/get/grab/hold/snatch/take out OBJ;carry/catch/get/grab/hold/snatch/take/drag/pull/tug down OBJ;chase/follow OBJ;check/descri/examin/watch/x OBJ;check/descri/examin/watch/x/gaze/l/look/stare in OBJ;check/descri/examin/watch/x/gaze/l/look/stare on OBJ;check/descri/examin/watch/x/gaze/l/look/stare/rummag/search for OBJ;choose/click/select OBJ;choose/click/select on OBJ;clear/move/shift/drag/pull/tug OBJ;climb/scale OBJ;climb/scale down OBJ;climb/scale off OBJ;climb/scale out OBJ;climb/scale over OBJ;climb/scale up OBJ;climb/scale/carry/catch/get/grab/hold/snatch/take on OBJ;climb/scale/rest/sit/carry/catch/get/grab/hold/snatch/take in OBJ;close/shut OBJ;compar OBJ;concea/hide OBJ;concea/hide behind OBJ;concea/hide from OBJ;concea/hide under OBJ;concea/hide/rise/stand in OBJ;consum/eat/gobble OBJ;cook/heat/warm OBJ;count OBJ;cross OBJ;curdle/scare/startl/surpri OBJ;depart/exit/withdr OBJ;descen OBJ;detach/discon/free/unatta/unfast/unhook/untie/unwrap OBJ;dig in OBJ;dig throug OBJ;dig with OBJ;disemb OBJ;dive/jump/leap across OBJ;dive/jump/leap down OBJ;dive/jump/leap from OBJ;dive/jump/leap in OBJ;dive/jump/leap off OBJ;dive/jump/leap on OBJ;dive/jump/leap to OBJ;dive/jump/leap/drive/go/procee/run/steer/step/walk over OBJ;drag/pull/tug on OBJ;drink/sip/swallo OBJ;drink/sip/swallo from OBJ;drive/go/procee/run/steer/step/walk OBJ;drive/go/procee/run/steer/step/walk around OBJ;drive/go/procee/run/steer/step/walk away OBJ;drive/go/procee/run/steer/step/walk down OBJ;drive/go/procee/run/steer/step/walk in OBJ;drive/go/procee/run/steer/step/walk on OBJ;drive/go/procee/run/steer/step/walk throug OBJ;drive/go/procee/run/steer/step/walk to OBJ;drive/go/procee/run/steer/step/walk under OBJ;drive/go/procee/run/steer/step/walk up OBJ;drop/dump OBJ;drop/dump from OBJ;edit OBJ;empty/pour/spill OBJ;enter OBJ;erase OBJ;erect/lift/raise OBJ;erect/lift/raise/insert/lay/place/put up OBJ;exting OBJ;feel/pat/pet/rub/squeez/touch OBJ;fill OBJ;find OBJ;fix/patch/repair OBJ;flip/power/set/turn OBJ;flip/power/set/turn around OBJ;flip/power/set/turn off OBJ;flip/power/set/turn on OBJ;flip/power/set/turn over OBJ;gaze/l/look/stare OBJ;gaze/l/look/stare around OBJ;gaze/l/look/stare at OBJ;gaze/l/look/stare behind OBJ;gaze/l/look/stare down OBJ;gaze/l/look/stare throug OBJ;gaze/l/look/stare under OBJ;gaze/l/look/stare up OBJ;gestur/point at OBJ;gestur/point to OBJ;greeti/hello/hi OBJ;hack OBJ;hang from OBJ;help/hint OBJ;hurl/pitch/throw/toss OBJ;hurl/pitch/throw/toss away OBJ;input/type OBJ;input/type login OBJ;input/type passwo OBJ;insert/lay/place/put down OBJ;insert/lay/place/put on OBJ;kick OBJ;kill/murder/slay/stab OBJ;kiss OBJ;knock/rap at OBJ;knock/rap down OBJ;knock/rap on OBJ;lean on OBJ;leave OBJ;let go OBJ;lie down OBJ;lie on OBJ;light OBJ;light up OBJ;listen for OBJ;listen to OBJ;login OBJ;login as OBJ;login on OBJ;lower OBJ;nap/sleep in OBJ;nap/sleep on OBJ;open OBJ;open up OBJ;passwo OBJ;pick OBJ;pick up OBJ;plug/screw in OBJ;press/push/shove OBJ;press/push/shove down OBJ;press/push/shove on OBJ;press/push/shove up OBJ;rattle/shake OBJ;reach in OBJ;reach under OBJ;read OBJ;releas OBJ;remove/shed OBJ;rest/sit at OBJ;rest/sit down OBJ;rest/sit on OBJ;rise/stand on OBJ;rise/stand/carry/catch/get/grab/hold/snatch/take up OBJ;roll up OBJ;rummag/search OBJ;rummag/search in OBJ;sample/taste OBJ;shoot OBJ;slide OBJ;slide on OBJ;smell/sniff OBJ;start OBJ;start/flip/power/set/turn up OBJ;stop OBJ;swim/wade in OBJ;swing/thrust OBJ;tell OBJ;tell about OBJ;thank/thanks OBJ;tortur OBJ;trade OBJ;unplug/unscre OBJ;wait/z OBJ;wait/z for OBJ;wear OBJ;what OBJ;what/read about OBJ;where OBJ;who OBJ;apply OBJ to OBJ;ask/quiz OBJ about OBJ;ask/quiz OBJ for OBJ;attach/connec/fasten/hook/loop/tie/wrap OBJ around OBJ;attach/connec/fasten/hook/loop/tie/wrap OBJ on OBJ;attach/connec/fasten/hook/loop/tie/wrap OBJ to OBJ;attach/connec/fasten/hook/loop/tie/wrap up OBJ with OBJ;attack/fight/hit/strike OBJ with OBJ;beckon/wave OBJ at OBJ;break/crack/destro/scrape/scratc/smash/wreck OBJ with OBJ;break/crack/destro/scrape/scratc/smash/wreck down OBJ with OBJ;burn/ignite OBJ with OBJ;burn/ignite down OBJ with OBJ;bury OBJ in OBJ;buy/purcha OBJ from OBJ;buy/purcha OBJ with OBJ;carry/catch/get/grab/hold/snatch/take OBJ from OBJ;carry/catch/get/grab/hold/snatch/take OBJ in OBJ;carry/catch/get/grab/hold/snatch/take OBJ off OBJ;carry/catch/get/grab/hold/snatch/take OBJ out OBJ;carry/catch/get/grab/hold/snatch/take OBJ with OBJ;choose/click/select OBJ with OBJ;choose/click/select on OBJ with OBJ;chop/cut/prune/slash/slice/split OBJ with OBJ;chop/cut/prune/slash/slice/split throug OBJ with OBJ;clear/move/shift OBJ with OBJ;close/shut OBJ with OBJ;compar OBJ to OBJ;compar OBJ with OBJ;concea/hide OBJ from OBJ;count OBJ in OBJ;cover OBJ with OBJ;curdle/scare/startl/surpri OBJ with OBJ;detach/discon/free/unatta/unfast/unhook/untie/unwrap OBJ from OBJ;dig OBJ with OBJ;dig in OBJ with OBJ;drive/go/procee/run/steer/step/walk OBJ OBJ;drive/go/procee/run/steer/step/walk OBJ on OBJ;drive/go/procee/run/steer/step/walk OBJ over OBJ;drop/dump OBJ on OBJ;drop/dump/insert/lay/place/put OBJ down OBJ;drop/dump/insert/lay/place/put OBJ in OBJ;empty/pour/spill OBJ from OBJ;empty/pour/spill OBJ in OBJ;empty/pour/spill OBJ on OBJ;empty/pour/spill OBJ over OBJ;empty/pour/spill OBJ throug OBJ;erect/lift/raise up OBJ with OBJ;feed/give/offer OBJ OBJ;feed/give/offer OBJ to OBJ;feed/give/offer OBJ with OBJ;feel/pat/pet/rub/squeez/touch OBJ to OBJ;feel/pat/pet/rub/squeez/touch OBJ with OBJ;fill OBJ at OBJ;fill OBJ with OBJ;fix/patch/repair OBJ with OBJ;flip/power/set/turn OBJ to OBJ;flip/power/set/turn OBJ with OBJ;gaze/l/look/stare at OBJ throug OBJ;gaze/l/look/stare up OBJ in OBJ;hang OBJ from OBJ;hang OBJ on OBJ;hone/sharpe OBJ on OBJ;hone/sharpe OBJ with OBJ;hurl/pitch/throw/toss OBJ at OBJ;hurl/pitch/throw/toss OBJ away OBJ;hurl/pitch/throw/toss OBJ down OBJ;hurl/pitch/throw/toss OBJ in OBJ;hurl/pitch/throw/toss OBJ off OBJ;hurl/pitch/throw/toss OBJ on OBJ;hurl/pitch/throw/toss OBJ over OBJ;hurl/pitch/throw/toss OBJ throug OBJ;hurl/pitch/throw/toss OBJ to OBJ;insert/lay/place/put OBJ across OBJ;insert/lay/place/put OBJ around OBJ;insert/lay/place/put OBJ behind OBJ;insert/lay/place/put OBJ betwee OBJ;insert/lay/place/put OBJ on OBJ;insert/lay/place/put OBJ over OBJ;insert/lay/place/put OBJ under OBJ;kill/murder/slay/stab OBJ with OBJ;lean OBJ on OBJ;lean/rise/stand OBJ agains OBJ;lever/pry out OBJ with OBJ;lock OBJ to OBJ;lock OBJ with OBJ;lower OBJ down OBJ;lower OBJ in OBJ;melt/thaw OBJ with OBJ;open OBJ with OBJ;pick OBJ with OBJ;plug/screw OBJ in OBJ;plug/screw OBJ with OBJ;press/push/shove OBJ OBJ;press/push/shove/clear/move/shift OBJ on OBJ;press/push/shove/clear/move/shift OBJ to OBJ;prop/wedge OBJ betwee OBJ;prop/wedge OBJ in OBJ;prop/wedge OBJ with OBJ;rattle/shake OBJ at OBJ;reach in OBJ with OBJ;read OBJ to OBJ;remove/shed OBJ from OBJ;remove/shed/unplug/unscre/lever/pry/erect/lift/raise OBJ with OBJ;sell OBJ OBJ;sell OBJ to OBJ;show OBJ OBJ;show OBJ to OBJ;slide/press/push/shove OBJ under OBJ;swing/thrust OBJ at OBJ;tell OBJ OBJ;tell OBJ about OBJ;trade OBJ with OBJ;trade/feed/give/offer OBJ for OBJ;unlock OBJ with OBJ;unplug/unscre OBJ from OBJ;", "max_word_length" : 6 } diff --git a/tools/test_games.py b/tools/test_games.py index 0bb39eae..12ffae49 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -417,6 +417,38 @@ "examine White Board", # Reveals Board Marker object. ], }, + "lurking.z3": { + "*": [ + 29, 30, 31, 32, # Forced to click on "MORE". + 34, # Arriving to the Platform. + 37, # Arriving to Terminal Room + 38, # Hacker takes your chair. + 41, # Hack returns to his hacking. + 43, 44, 45, 46, 49, # Elevator is moving, its doors open and close. + 106, # The dark shape drops next to you. + 168, # Thick black mist begins to form in the room. + 171, # The mist gets you. + 177, # The hand is trying to crawl out of the vat. + 216, 217, # You hear the rats coming. + 236, # Elevator doors. + 249, 250, 251, # You go up in the elevator + elevator doors. + 257, # greasy chain is revealed. + 274, # The mist dissipates. + 277, 278, # The Hacker is at the door and arrives. + 281, # Hacker does something. + 282, # Powerline is revealed. + 285, # Hacker pulls himself out of the side of the mass. + 287, # The creature eats you. + ], + "wait": [ + 162, # Enter the Department of Alchemy, + 237, # Elevator doors. + ], + "ignore_commands": [ + "examine paper", # Makes you click on "MORE". + "examine objects", # Read the piece of paper. + ], + }, } SKIP_CHECK_STATE = { @@ -785,7 +817,19 @@ ], }, "lurking.z3": { - "noop": ["z"] + "z": [ + 14, 15, 16, 17, # Waiting for the microwave to finish. + 36, # Wait for darkness creature to appear. + 39, 40, # Hacker is typing on the computer. + 67, 68, 69, # Wait for the floor waxer to wax away. + 165, 166, # Wait for the professor to let you in. + 176, # The hand is trying to crawl out of the vat. + 215, # Wait for the rats to arrive. + 286, # Wait for the smooth stone to flow before throwing it at the thing. + ], + "noop": [ + "examine tree", "look in it", + ] }, "moonlit.z5": {}, "murdac.z5": {}, From bd99c9e5edf0d3cc2c83193177e6a2c610cffeb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 11 Feb 2022 21:56:52 -0500 Subject: [PATCH 75/85] Noop check: moonlit --- frotz/src/games/moonlit.c | 20 ++++++++++---------- tools/test_games.py | 18 ++++++++++++++++-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/frotz/src/games/moonlit.c b/frotz/src/games/moonlit.c index 5da51e06..77a7be6f 100644 --- a/frotz/src/games/moonlit.c +++ b/frotz/src/games/moonlit.c @@ -24,12 +24,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // The Moonlit Tower - http://ifdb.tads.org/viewgame?id=10387w68qlwehbyq -const zword moonlit_special_ram_addrs[3] = { - 7517, // Activated by setting constellation to horse, Also 7516 +const zword moonlit_special_ram_addrs[2] = { + // 7517, // Activated by setting constellation to horse, Also 7516 + 10424, // look up + 10458, // go south -> your face aches unbearably }; zword* moonlit_ram_addrs(int *n) { - *n = 1; + *n = 2; return moonlit_special_ram_addrs; } @@ -103,11 +105,9 @@ int moonlit_ignore_attr_clr(zword obj_num, zword attr_idx) { } void moonlit_clean_world_objs(zobject* objs) { - // int i; - // char mask; - // mask = ~(1 << 7) & ~1; - // // Clear attr 24 & 31 - // for (i=1; i<=moonlit_get_num_world_objs(); ++i) { - // objs[i].attr[3] &= mask; - // } + for (int i=1; i<=moonlit_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 31); + } + + clear_prop(&objs[20], 35); // (self object) } diff --git a/tools/test_games.py b/tools/test_games.py index 12ffae49..0a0115e9 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -419,7 +419,7 @@ }, "lurking.z3": { "*": [ - 29, 30, 31, 32, # Forced to click on "MORE". + 29, 30, 31, 32, # Forced to click on "MORE". 34, # Arriving to the Platform. 37, # Arriving to Terminal Room 38, # Hacker takes your chair. @@ -449,6 +449,11 @@ "examine objects", # Read the piece of paper. ], }, + "moonlit.z5": { + "ignore_commands": [ + "examine sky", + ] + }, } SKIP_CHECK_STATE = { @@ -831,7 +836,16 @@ "examine tree", "look in it", ] }, - "moonlit.z5": {}, + "moonlit.z5": { + 47: "d", # You emerge back where you started. + "noop": [ + "i", "l", "look", + "x arrangement", "x comb", "x fan",'x bones', 'x compass', + 'x crane', 'x feather', 'x flower', 'x hawk', 'x hawks', + 'x horse', 'x kite', 'x leaf', 'x light', 'x self', + 'x shadow', 'x storm', 'x swallow', 'x trees', 'x mask', + ] + }, "murdac.z5": {}, "night.z5": { 37: "get printer", # Not needed to complete the game. From e4e4ce8e50924bc1ce01df3cbf588c30f9d36759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 18 Feb 2022 23:07:08 -0500 Subject: [PATCH 76/85] Halt emulator on z_quit --- frotz/src/common/process.c | 1 + frotz/src/interface/frotz_interface.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/frotz/src/common/process.c b/frotz/src/common/process.c index 48471e18..2bfd894f 100644 --- a/frotz/src/common/process.c +++ b/frotz/src/common/process.c @@ -890,6 +890,7 @@ void z_nop (void) void z_quit (void) { finished = 9999; + emulator_halted = 2; }/* z_quit */ diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index b293b16f..e3f738c7 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -1597,9 +1597,12 @@ char* setup(char *story_file, int seed, void *rom, size_t rom_size) { } char* jericho_step(char *next_action) { - if (emulator_halted > 0) + if (emulator_halted == 1) return halted_message; + if (emulator_halted == 2) + return "Emulator has stopped."; + // Swap prev_objs_state and curr_objs_state. zobject* tmp_objs_state; tmp_objs_state = prev_objs_state; From 25fbed5caf1f4a7e8c14b6a747ddde084571d749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Fri, 18 Feb 2022 23:11:32 -0500 Subject: [PATCH 77/85] FIX: do not assume RAM size is even. --- jericho/jericho.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/jericho/jericho.py b/jericho/jericho.py index a80363bf..ed1400a8 100644 --- a/jericho/jericho.py +++ b/jericho/jericho.py @@ -1068,7 +1068,7 @@ def _get_globals(self): # is found at byte 0x0c of the header. # Ref: https://inform-fiction.org/zmachine/standards/z1point1/sect11.html # Ref: https://inform-fiction.org/zmachine/standards/z1point1/sect06.html#two - globals_addr = ram.view(">u2")[0x0c // 2] + globals_addr = ram[0x0c:0x0c+2].view(">u2")[0] # Extract a word data. globals = ram[globals_addr:globals_addr + 240 * 2].view(">i2") return globals @@ -1076,13 +1076,16 @@ def _print_memory_map(self): ram = np.zeros(self.frotz_lib.getRAMSize(), dtype=np.uint8) self.frotz_lib.getRAM(as_ctypes(ram)) - high_addr = ram.view(">u2")[0x04 // 2] - dict_addr = ram.view(">u2")[0x08 // 2] - objs_addr = ram.view(">u2")[0x0a // 2] - globals_addr = ram.view(">u2")[0x0c // 2] - static_addr = ram.view(">u2")[0x0e // 2] - abbr_addr = ram.view(">u2")[0x18 // 2] - length_of_file = ram.view(">u2")[0x1a // 2] + def _get_word(pos): + return ram[pos:pos+2].view(">u2")[0] + + high_addr = _get_word(0x04) + dict_addr = _get_word(0x08) + objs_addr = _get_word(0x0a) + globals_addr = _get_word(0x0c) + static_addr = _get_word(0x0e) + abbr_addr = _get_word(0x18) + length_of_file = _get_word(0x1a) print(" -= {} =- ".format(self.story_file.decode())) print("Dynamic | {:05x} | header".format(0)) From dfbf697fa9c75bd9f7043a7f35dbcfa07aca4dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 21 Feb 2022 13:26:04 -0500 Subject: [PATCH 78/85] Noop check: murdac --- frotz/src/games/murdac.c | 42 ++++++++++++++++++++++------------------ tools/test_games.py | 17 +++++++++++++++- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/frotz/src/games/murdac.c b/frotz/src/games/murdac.c index 569c17bd..04c6a437 100644 --- a/frotz/src/games/murdac.c +++ b/frotz/src/games/murdac.c @@ -24,21 +24,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Monsters of Murdac: http://ifdb.tads.org/viewgame?id=q36lh5np0q9nak28 -const zword murdac_special_ram_addrs[10] = { - 3909, // Blow shawm; Also 525 - 3587, // Tracks state of door. Also 3626 - 4659, // Tracks throwing plank, rod. - 637, // Scare centaur with blow shawm - 2934, // Eat toadstone - 5838, // Wave scroll, dig; - 3042, // Tracks lion health - 2548, // Fill bowl, look - 3365, // Prick dummy, exodus +const zword murdac_special_ram_addrs[1] = { + // 3909, // Blow shawm; Also 525 + // 3587, // Tracks state of door. Also 3626 + // 4659, // Tracks throwing plank, rod. + // 637, // Scare centaur with blow shawm + // 2934, // Eat toadstone + // 5838, // Wave scroll, dig; + // 3042, // Tracks lion health + // 2548, // Fill bowl, look + // 3365, // Prick dummy, exodus 6387, // Running away from the poltergeist. }; zword* murdac_ram_addrs(int *n) { - *n = 10; + *n = 1; return murdac_special_ram_addrs; } @@ -51,7 +51,7 @@ char* murdac_clean_observation(char* obs) { char* pch; pch = strchr(obs, '>'); if (pch != NULL) { - *(pch-2) = '\0'; + *(pch) = '\0'; } return obs+1; } @@ -81,6 +81,11 @@ int murdac_get_moves() { } short murdac_get_score() { + // Reaching victory is actually worth 1 point but the game + // terminates before increasing the score. So, we do it manually. + if (murdac_victory()) + return 250; + return zmp[6357]; } @@ -109,11 +114,10 @@ int murdac_ignore_attr_clr(zword obj_num, zword attr_idx) { } void murdac_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 6); - // Clear attr 1 - for (i=1; i<=murdac_get_num_world_objs(); ++i) { - objs[i].attr[0] &= mask; - } + clear_attr(&objs[15], 5); // (MONSTER) + clear_prop(&objs[10], 4); // (OGRE) + clear_prop(&objs[62], 4); // (WALL1) + clear_prop(&objs[104], 4); // (MONKROOM) + clear_prop(&objs[90], 4); // (BEACH3) + clear_prop(&objs[119], 4); // (ISLE1) } diff --git a/tools/test_games.py b/tools/test_games.py index 0a0115e9..ceeda502 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -454,6 +454,17 @@ "examine sky", ] }, + "murdac.z5": { + "*": [ + 43, 44, # Monster gets you. + *range(64, 71+1), # Poltergeist gets you. + 170, # Geyser strikes you and you leave the room. + 242, # Cannibals get you. + ], + "look": [ + *range(179, 189+1), # Water in the bowls boil away (strange vision). + ] + }, } SKIP_CHECK_STATE = { @@ -846,7 +857,11 @@ 'x shadow', 'x storm', 'x swallow', 'x trees', 'x mask', ] }, - "murdac.z5": {}, + "murdac.z5": { + "noop": [ + "look" + ] + }, "night.z5": { 37: "get printer", # Not needed to complete the game. 38: "ask gnome about printer", # Not needed to complete the game. From 39b6f8d606deb9733f7556ce36f533f338906825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 21 Feb 2022 14:28:04 -0500 Subject: [PATCH 79/85] Noop check: night --- frotz/src/games/night.c | 10 +++------- tools/test_games.py | 11 ++++++++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/frotz/src/games/night.c b/frotz/src/games/night.c index b593a82b..6ab2956e 100644 --- a/frotz/src/games/night.c +++ b/frotz/src/games/night.c @@ -100,11 +100,7 @@ int night_ignore_attr_clr(zword obj_num, zword attr_idx) { } void night_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=night_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + objs[108].parent = 0; // Mouse + objs[112].parent = 0; // Message + clear_prop(&objs[108], 24); } diff --git a/tools/test_games.py b/tools/test_games.py index ceeda502..5542e5f1 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -465,6 +465,9 @@ *range(179, 189+1), # Water in the bowls boil away (strange vision). ] }, + "night.z5": { + + }, } SKIP_CHECK_STATE = { @@ -865,7 +868,13 @@ "night.z5": { 37: "get printer", # Not needed to complete the game. 38: "ask gnome about printer", # Not needed to complete the game. - "noop": ["z"] + "z": [ + 30, 31, # Waiting for the mouse. + 64, 65, 66, 67, 68, # Waiting for the mouse. + ], + "noop": [ + "x sign", + ] }, "omniquest.z5": {}, "partyfoul.z8": { From 93cff3f0b12ba8d73eb9980faeacac55d3d25631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 21 Feb 2022 14:35:24 -0500 Subject: [PATCH 80/85] Noop check: omniquest --- frotz/src/games/omniquest.c | 20 +++++++++----------- tools/test_games.py | 17 +++++++++++++---- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/frotz/src/games/omniquest.c b/frotz/src/games/omniquest.c index f471c061..883597fb 100644 --- a/frotz/src/games/omniquest.c +++ b/frotz/src/games/omniquest.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -24,12 +24,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Omniquest: http://ifdb.tads.org/viewgame?id=mygqz9tzxqvryead -const zword omniquest_special_ram_addrs[1] = { - 2123 // Keep track of whether you've given sushi to samurai; Also 2135. +const zword omniquest_special_ram_addrs[0] = { + // 2123 // Keep track of whether you've given sushi to samurai; Also 2135. }; zword* omniquest_ram_addrs(int *n) { - *n = 1; + *n = 0; return omniquest_special_ram_addrs; } @@ -100,11 +100,9 @@ int omniquest_ignore_attr_clr(zword obj_num, zword attr_idx) { } void omniquest_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=omniquest_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + for (int i=1; i<=omniquest_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 24); + clear_attr(&objs[i], 25); + } + clear_prop(&objs[138], 40); // (long_time) } diff --git a/tools/test_games.py b/tools/test_games.py index 5542e5f1..72b03f30 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -465,9 +465,13 @@ *range(179, 189+1), # Water in the bowls boil away (strange vision). ] }, - "night.z5": { - - }, + "night.z5": {}, + "omniquest.z5": { + "ignore_commands": [ + "examine tree", # snorkel hanging from the tree. You take it. + "examine boot", # boot further reveals a crystal, which you take. + ] + } } SKIP_CHECK_STATE = { @@ -876,7 +880,12 @@ "x sign", ] }, - "omniquest.z5": {}, + "omniquest.z5": { + "noop": [ + "read scroll", + "x cage", + ] + }, "partyfoul.z8": { "z": [53, 54], # Ending sequence. }, From 9c4f9fabc7e7f6cd42a8cd8dc092619a2eb70fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 21 Feb 2022 16:46:50 -0500 Subject: [PATCH 81/85] Noop check: partyfoul + add option to skip z_read_char --- frotz/src/games/partyfoul.c | 29 ++++++++++++++++++++------- frotz/src/interface/frotz_interface.c | 3 ++- frotz/src/interface/frotz_interface.h | 2 ++ jericho/game_info.py | 2 +- tools/test_games.py | 14 ++++++++++++- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/frotz/src/games/partyfoul.c b/frotz/src/games/partyfoul.c index 61200bfe..695b696d 100644 --- a/frotz/src/games/partyfoul.c +++ b/frotz/src/games/partyfoul.c @@ -24,30 +24,31 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Party Foul - http://ifdb.tads.org/viewgame?id=cqwq699i9qiqdju -const zword partyfoul_special_ram_addrs[3] = { +const zword partyfoul_special_ram_addrs[4] = { 17509, // Spread peanut butter on frank (alt. 17755, 19428, 21423, 47829) 1923, // plug the toaster + 2259, // plug the hair dryer 28036, // Waiting for your husband to be prepared to leave the party (alt. 28037, 32186) }; -const char *partyfoul_intro[] = { "\n", - "no\n" }; +const char *partyfoul_intro[] = { "\n", "no\n", "\n" }; zword* partyfoul_ram_addrs(int *n) { - *n = 3; + *n = 4; return partyfoul_special_ram_addrs; } char** partyfoul_intro_actions(int *n) { - *n = 2; + *n = 3; + skip_z_read_char = TRUE; return partyfoul_intro; } char* partyfoul_clean_observation(char* obs) { char* pch; - pch = strstr(obs, "> "); + pch = strstr(obs, "> "); if (pch != NULL) { - *(pch-2) = '\0'; + *(pch-1) = '\0'; } return obs + strspn(obs, "\n "); // Skip leading newlines and whitespaces. } @@ -108,4 +109,18 @@ int partyfoul_ignore_attr_clr(zword obj_num, zword attr_idx) { } void partyfoul_clean_world_objs(zobject* objs) { + for (int i=1; i<=partyfoul_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 29); + clear_attr(&objs[i], 30); + } + + clear_attr(&objs[124], 21); + + objs[49].parent = 0; + objs[67].parent = 0; + objs[84].parent = 0; + objs[85].parent = 0; + objs[86].parent = 0; + objs[95].parent = 0; + objs[100].parent = 0; } diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index e3f738c7..7cafd371 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -73,6 +73,7 @@ extern int getRngCounter(); extern void setRng(long, int, int); zbyte next_opcode; +bool skip_z_read_char = FALSE; int last_ret_pc = -1; int desired_seed = 0; int ROM_IDX = 0; @@ -103,7 +104,7 @@ void zstep() { // Run the Z-Machine until it requires user input void run_free() { // Opcode 228 (z_read) and 246 (z_read_char) indicate need for user input - while (next_opcode != 228 && next_opcode != 246 && emulator_halted <= 0) { + while (next_opcode != 228 && (next_opcode != 246 || skip_z_read_char) && emulator_halted <= 0) { zstep(); } } diff --git a/frotz/src/interface/frotz_interface.h b/frotz/src/interface/frotz_interface.h index 50a914bc..3feca526 100644 --- a/frotz/src/interface/frotz_interface.h +++ b/frotz/src/interface/frotz_interface.h @@ -53,6 +53,8 @@ extern void getRAM(unsigned char *ram); int filter_candidate_actions(char *candidate_actions, char *valid_actions, char *hashes); +extern bool skip_z_read_char; + extern char world[256 + 8192]; // Upper + lower screens. extern int tw_max_score; diff --git a/jericho/game_info.py b/jericho/game_info.py index 6dcc9dd8..7e5a18fe 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -334,7 +334,7 @@ "name": "partyfoul", "rom": "partyfoul.z8", "seed" : 0, - "walkthrough" : "l/give drink to frank/look at frank/look at ron/w/z/take purse/e/n/take jar/put jar in purse/w/l/take knife/put knife in purse/e/l/take peanut butter/s/w/take knife/spread peanut butter on frank/e/n/open door/l/open closet/take hair dryer/plug hair dryer into wall/turn on hair dryer/turn on space heater/drop hair dryer/e/nw/plug toaster into wall/turn on toaster/e/z/z/l/take napkin/s/order drink/take celery/wipe celery with napkin/put celery in purse/n/take peanut butter/w/take knife/put peanut butter on celery/put raisins on celery/give celery to barb/z/z/z", + "walkthrough" : "give drink to frank/look at frank/look at ron/w/take purse/e/n/take jar/w/take knife/put knife in purse/e/take peanut butter/s/w/take knife/spread peanut butter on frank/put jar into purse/e/n/open door/open closet/take hair dryer/plug hair dryer into wall/turn on hair dryer/turn on space heater/drop hair dryer/e/nw/plug toaster into wall/z/z/turn on toaster/e/z/z/take napkin/s/order drink/take celery/wipe celery with napkin/put celery in purse/n/w/take knife/put peanut butter on celery/put raisins on celery/give celery to barb", "grammar" : "awake/awaken/wake;awake/awaken/wake up;blow my nose;blow nose;blow your nose;bother/curses/darn/drat;carry/hold/take inventory;chuckle/laugh;cringe/swear/pout/sigh;damn/fuck/shit;exit/leave/out/stand;get out/off/up;go/run/walk;hocus pocus;hop/jump/skip;i/inv/inventory;info/about/hints/hint/help;l/look;listen;long/verbose;magic word;magic words;magic/pocus/hocus/abracadab/plough/frotz/plover/sneeze/xyzzy;nap/sleep;no;normal/brief;notify;notify off;notify on;pray;pronouns/nouns;q/quit;remember;restart;restore;save;score;short/superbrie;sing;smell/sniff;sorry;stand up;stomp/yell/scream/answer/say/shout/speak;think;think harder;transcrip/script;transcrip/script off;transcrip/script on;tutorial mode;tutorial mode off;tutorial mode on;tutorial off;tutorial on;verify;version;wait/z;wave;y/yes;yawn;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;burn/light OBJ;buy/purchase OBJ;carry/hold/take off OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;climb/scale OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;converse with OBJ;create/make OBJ;create/make a OBJ;create/make the OBJ;cross/enter/go/run/walk OBJ;discard/drop/throw OBJ;disconnec/unplug OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;dry OBJ;eat OBJ;embrace/hug/kiss OBJ;feel/touch OBJ;flirt with OBJ;get in/into/on/onto OBJ;get off OBJ;get/carry/hold/take OBJ;go/run/walk into/in/inside/through OBJ;hear OBJ;kick/throttle/smother/attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;knock over OBJ;l/look at OBJ;l/look inside/in/into/through OBJ;l/look under OBJ;listen to OBJ;mess up OBJ;mess/tilt/disturb OBJ;open/uncover/unwrap OBJ;order/buy/purchase OBJ;order/buy/purchase a OBJ;pick OBJ up;pick up OBJ;play OBJ;pour/spill OBJ;put OBJ down;put down OBJ;put on OBJ;read/check/describe/examine/watch/x OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;shoving/clear/move/press/push/shift OBJ;sit on OBJ;sit on top of OBJ;sit on/in/inside OBJ;smell/sniff OBJ;squash/squeeze OBJ;stand on OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;talk OBJ;talk to OBJ;taste OBJ;un plug OBJ;wave OBJ;wink at OBJ;adjust/set OBJ to OBJ;aim/point OBJ at OBJ;aim/point OBJ towards OBJ;answer/say/shout/speak OBJ to OBJ;apply OBJ to OBJ;apply/paint/spread/smear OBJ onto OBJ;ask OBJ about OBJ;ask OBJ for OBJ;attach/fasten/fix/tie OBJ to OBJ;carry/hold/take OBJ off OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ with OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe down OBJ with OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe up OBJ with OBJ;connect OBJ to OBJ;connect/plug OBJ into OBJ;consult OBJ on/about OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;draw on OBJ with OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;paint/spread/smear OBJ on OBJ;plug in OBJ OBJ;plug in OBJ into OBJ;plug in OBJ to OBJ;plug/plug OBJ in OBJ;put OBJ in/inside/into OBJ;read OBJ in OBJ;read about OBJ in OBJ;remove/get/carry/hold/take OBJ from OBJ;tell OBJ about OBJ;unlock/open/uncover/unwrap OBJ with OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index 72b03f30..6da2f440 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -471,6 +471,14 @@ "examine tree", # snorkel hanging from the tree. You take it. "examine boot", # boot further reveals a crystal, which you take. ] + }, + "partyfoul.z8": { + "*": [ + 34, 35, # Lights turn off and back on. + 39, # It seems as if someone has just turned something off in another room (the hair dryer). + 41, # You get caugth with celery in your hands. + 47, # Abbey take the knife from your hands. + ], } } @@ -887,7 +895,11 @@ ] }, "partyfoul.z8": { - "z": [53, 54], # Ending sequence. + 1: "look at frank", + 2: "look at ron", + 7: "take jar", # Abbey stops you. + 30: "z", # Waiting for Abbey to leave the room. + 31: "z", # Waiting for Abbey to leave the room. }, "pentari.z5": {}, "planetfall.z3": { From 88f15eb4cc8d19f7e0e29f034e5d3377bbaf598c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Tue, 22 Feb 2022 13:33:06 -0500 Subject: [PATCH 82/85] Noop check: pentari --- frotz/src/games/pentari.c | 18 +++++++++--------- jericho/game_info.py | 2 +- tools/test_games.py | 12 ++++++++++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/frotz/src/games/pentari.c b/frotz/src/games/pentari.c index cc4a1e62..9bf91769 100644 --- a/frotz/src/games/pentari.c +++ b/frotz/src/games/pentari.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2018 Microsoft Corporation This program is free software; you can redistribute it and/or @@ -38,7 +38,7 @@ char* pentari_clean_observation(char* obs) { char* pch; pch = strchr(obs, '>'); if (pch != NULL) { - *(pch-2) = '\0'; + *(pch) = '\0'; } return obs+1; } @@ -98,11 +98,11 @@ int pentari_ignore_attr_clr(zword obj_num, zword attr_idx) { } void pentari_clean_world_objs(zobject* objs) { - int i; - char mask; - mask = ~(1 << 7); - // Clear attr 24 - for (i=1; i<=pentari_get_num_world_objs(); ++i) { - objs[i].attr[3] &= mask; - } + for (int i=1; i<=pentari_get_num_world_objs(); ++i) { + clear_attr(&objs[i], 25); + } + + objs[103].parent = 0; + clear_prop(&objs[103], 51); + clear_prop(&objs[103], 52); } diff --git a/jericho/game_info.py b/jericho/game_info.py index 7e5a18fe..d45511ec 100644 --- a/jericho/game_info.py +++ b/jericho/game_info.py @@ -343,7 +343,7 @@ "name": "pentari", "rom": "pentari.z5", "seed" : 0, - "walkthrough" : "north/north/in/city/east/covert/south/smash seal/north/north/north/south/east/get in floor/up/north/open towel/north/south/south/west/west/put sword down/take dagger/north/take chest/south/east/put all down/south/south/north/north/take chest/put all down/north/enter/take scroll/get up/south/fwoosh/take emerald/put dagger in chest/west/take sword/hit elf/take emerald/put all on box/l", + "walkthrough" : "north/north/in/city/east/covert/south/smash seal/north/north/north/south/east/get in floor/up/north/open towel/north/south/south/west/west/put sword down/take dagger/north/take chest/south/east/put all down/south/south/north/north/take chest/put all down/north/enter/take scroll/get up/south/fwoosh/take emerald/z/west/take sword/hit elf/take emerald/put all on box/l", "grammar" : "awake/awaken/wake;awake/awaken/wake up;bother/curses/darn/drat;brief/normal;carry/hold/take inventory;city;covert;damn/fuck/shit/sod;defiant;die/q/quit;dive/swim;exit/out/outside/stand;full/fullscore;full/fullscore score;fwoosh;get out/off/up;hear/listen;help;hop/jump/skip;i/inv/inventory;i/inv/inventory tall;i/inv/inventory wide;in/inside/cross/enter;info;l/look;leave/go/run/walk;long/verbose;luminus;nap/sleep;no;noscript/unscript;notify off;notify on;nouns/pronouns;objects;places;pray;restart;restore;save;score;script/transcrip;script/transcrip off;script/transcrip on;short/superbrie;sing;smell/sniff;sorry;stand up;think;verify;version;wait/z;wave;y/yes;adjust/set OBJ;attach/fasten/fix/tie OBJ;awake/awaken/wake OBJ;awake/awaken/wake OBJ up;awake/awaken/wake up OBJ;blow OBJ;bother/curses/darn/drat OBJ;burn/light OBJ;buy/purchase OBJ;carry/hold/take off OBJ;chase/follow/pursue/trail OBJ;chase/follow/pursue/trail after OBJ;chop/cut/prune/slice OBJ;clean/dust/polish/rub/scrub/shine/sweep/wipe OBJ;clear/move/press/push/shift OBJ;climb/scale OBJ;climb/scale up/over OBJ;close/cover/shut OBJ;close/cover/shut up OBJ;cross/enter/go/run/walk OBJ;damn/fuck/shit/sod OBJ;dig OBJ;discard/drop/throw OBJ;disrobe/doff/shed/remove OBJ;don/wear OBJ;drag/pull OBJ;drink/sip/swallow OBJ;eat OBJ;embrace/hug/kiss OBJ;empty OBJ;empty OBJ out;empty out OBJ;feel/fondle/grope/touch OBJ;fill OBJ;fold OBJ;get in/into/on/onto OBJ;get off OBJ;get/carry/hold/take OBJ;hear/listen OBJ;hear/listen to OBJ;hop/jump/skip over OBJ;l/look at OBJ;l/look inside/in/into/through OBJ;l/look under OBJ;leave OBJ;leave/go/run/walk into/in/inside/through OBJ;lie/sit on top of OBJ;lie/sit on/in/inside OBJ;open/uncover/undo/unwrap OBJ;peel OBJ;peel off OBJ;pick OBJ up;pick up OBJ;put OBJ down;put down OBJ;put on OBJ;read/check/describe/examine/watch/x OBJ;rotate/screw/turn/twist/unscrew OBJ;search OBJ;shatter/attack/break/crack/destroy/fight/hit/kill/murder/punch/smash/thump/torture/wreck OBJ;smell/sniff OBJ;squash/squeeze OBJ;stand on OBJ;swing OBJ;swing on OBJ;switch OBJ;switch/rotate/screw/turn/twist/unscrew OBJ off;switch/rotate/screw/turn/twist/unscrew OBJ on;switch/rotate/screw/turn/twist/unscrew on OBJ;switch/rotate/screw/turn/twist/unscrew/close/cover/shut off OBJ;taste OBJ;unfold OBJ;wave OBJ;adjust/set OBJ to OBJ;attach/fasten/fix/tie OBJ to OBJ;burn/light OBJ with OBJ;carry/hold/take OBJ off OBJ;clear/move/press/push/shift OBJ OBJ;clear/move/press/push/shift/transfer OBJ to OBJ;consult OBJ about OBJ;consult OBJ on OBJ;dig OBJ with OBJ;discard/drop/throw OBJ at/against/on/onto OBJ;discard/drop/throw OBJ in/into/down OBJ;discard/drop/throw/put OBJ on/onto OBJ;display/present/show OBJ OBJ;display/present/show OBJ to OBJ;empty OBJ to/into/on/onto OBJ;feed/give/offer/pay OBJ OBJ;feed/give/offer/pay OBJ to OBJ;feed/give/offer/pay over OBJ to OBJ;insert OBJ in/into OBJ;l/look up OBJ in OBJ;lock OBJ with OBJ;put OBJ in/inside/into OBJ;read OBJ in OBJ;read about OBJ in OBJ;remove/get/carry/hold/take OBJ from OBJ;unlock/open/uncover/undo/unwrap OBJ with OBJ;", "max_word_length" : 9 } diff --git a/tools/test_games.py b/tools/test_games.py index 6da2f440..1e5f2b1f 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -479,7 +479,13 @@ 41, # You get caugth with celery in your hands. 47, # Abbey take the knife from your hands. ], - } + }, + "pentari.z5": { + "*": [ + 44, # Dark Elf gets you. + 48, # Victory. + ] + }, } SKIP_CHECK_STATE = { @@ -901,7 +907,9 @@ 30: "z", # Waiting for Abbey to leave the room. 31: "z", # Waiting for Abbey to leave the room. }, - "pentari.z5": {}, + "pentari.z5": { + "z": [42], + }, "planetfall.z3": { 216: "eat brown goo", # Not needed to complete the game. }, From 9348e2d85ae0e5ae0fd5fb4ea6d539676b87f2fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 6 Jan 2025 18:00:05 -0500 Subject: [PATCH 83/85] Fix md5 import --- frotz/src/interface/frotz_interface.c | 2 +- frotz/src/interface/md5.c | 140 +++++++++++++------------- frotz/src/interface/md5.h | 4 +- 3 files changed, 73 insertions(+), 73 deletions(-) diff --git a/frotz/src/interface/frotz_interface.c b/frotz/src/interface/frotz_interface.c index 7cafd371..cff4291a 100644 --- a/frotz/src/interface/frotz_interface.c +++ b/frotz/src/interface/frotz_interface.c @@ -197,7 +197,7 @@ enum SUPPORTED { // Set ROM_IDX according to the story_file. void load_rom_bindings(char *story_file) { - char md5_hash[32]; + char md5_hash[64]; char *start; FILE * f = fopen (story_file, "r"); diff --git a/frotz/src/interface/md5.c b/frotz/src/interface/md5.c index 97f7f010..ad2c4914 100644 --- a/frotz/src/interface/md5.c +++ b/frotz/src/interface/md5.c @@ -4,6 +4,8 @@ extern int enc64(char*,byte*,int); +MD5state *nil_state; + /* * rfc1321 requires that I include this. The code is new. The constants * all come from the rfc (hence the copyright). We trade a table for the @@ -67,76 +69,76 @@ typedef struct Table Table tab[] = { /* round 1 */ - { 0xd76aa478, 0, S11}, - { 0xe8c7b756, 1, S12}, - { 0x242070db, 2, S13}, - { 0xc1bdceee, 3, S14}, - { 0xf57c0faf, 4, S11}, - { 0x4787c62a, 5, S12}, - { 0xa8304613, 6, S13}, - { 0xfd469501, 7, S14}, - { 0x698098d8, 8, S11}, - { 0x8b44f7af, 9, S12}, - { 0xffff5bb1, 10, S13}, - { 0x895cd7be, 11, S14}, - { 0x6b901122, 12, S11}, - { 0xfd987193, 13, S12}, - { 0xa679438e, 14, S13}, + { 0xd76aa478, 0, S11}, + { 0xe8c7b756, 1, S12}, + { 0x242070db, 2, S13}, + { 0xc1bdceee, 3, S14}, + { 0xf57c0faf, 4, S11}, + { 0x4787c62a, 5, S12}, + { 0xa8304613, 6, S13}, + { 0xfd469501, 7, S14}, + { 0x698098d8, 8, S11}, + { 0x8b44f7af, 9, S12}, + { 0xffff5bb1, 10, S13}, + { 0x895cd7be, 11, S14}, + { 0x6b901122, 12, S11}, + { 0xfd987193, 13, S12}, + { 0xa679438e, 14, S13}, { 0x49b40821, 15, S14}, /* round 2 */ - { 0xf61e2562, 1, S21}, - { 0xc040b340, 6, S22}, - { 0x265e5a51, 11, S23}, - { 0xe9b6c7aa, 0, S24}, - { 0xd62f105d, 5, S21}, - { 0x2441453, 10, S22}, - { 0xd8a1e681, 15, S23}, - { 0xe7d3fbc8, 4, S24}, - { 0x21e1cde6, 9, S21}, - { 0xc33707d6, 14, S22}, - { 0xf4d50d87, 3, S23}, - { 0x455a14ed, 8, S24}, - { 0xa9e3e905, 13, S21}, - { 0xfcefa3f8, 2, S22}, - { 0x676f02d9, 7, S23}, + { 0xf61e2562, 1, S21}, + { 0xc040b340, 6, S22}, + { 0x265e5a51, 11, S23}, + { 0xe9b6c7aa, 0, S24}, + { 0xd62f105d, 5, S21}, + { 0x2441453, 10, S22}, + { 0xd8a1e681, 15, S23}, + { 0xe7d3fbc8, 4, S24}, + { 0x21e1cde6, 9, S21}, + { 0xc33707d6, 14, S22}, + { 0xf4d50d87, 3, S23}, + { 0x455a14ed, 8, S24}, + { 0xa9e3e905, 13, S21}, + { 0xfcefa3f8, 2, S22}, + { 0x676f02d9, 7, S23}, { 0x8d2a4c8a, 12, S24}, /* round 3 */ - { 0xfffa3942, 5, S31}, - { 0x8771f681, 8, S32}, - { 0x6d9d6122, 11, S33}, - { 0xfde5380c, 14, S34}, - { 0xa4beea44, 1, S31}, - { 0x4bdecfa9, 4, S32}, - { 0xf6bb4b60, 7, S33}, - { 0xbebfbc70, 10, S34}, - { 0x289b7ec6, 13, S31}, - { 0xeaa127fa, 0, S32}, - { 0xd4ef3085, 3, S33}, - { 0x4881d05, 6, S34}, - { 0xd9d4d039, 9, S31}, - { 0xe6db99e5, 12, S32}, - { 0x1fa27cf8, 15, S33}, - { 0xc4ac5665, 2, S34}, + { 0xfffa3942, 5, S31}, + { 0x8771f681, 8, S32}, + { 0x6d9d6122, 11, S33}, + { 0xfde5380c, 14, S34}, + { 0xa4beea44, 1, S31}, + { 0x4bdecfa9, 4, S32}, + { 0xf6bb4b60, 7, S33}, + { 0xbebfbc70, 10, S34}, + { 0x289b7ec6, 13, S31}, + { 0xeaa127fa, 0, S32}, + { 0xd4ef3085, 3, S33}, + { 0x4881d05, 6, S34}, + { 0xd9d4d039, 9, S31}, + { 0xe6db99e5, 12, S32}, + { 0x1fa27cf8, 15, S33}, + { 0xc4ac5665, 2, S34}, /* round 4 */ - { 0xf4292244, 0, S41}, - { 0x432aff97, 7, S42}, - { 0xab9423a7, 14, S43}, - { 0xfc93a039, 5, S44}, - { 0x655b59c3, 12, S41}, - { 0x8f0ccc92, 3, S42}, - { 0xffeff47d, 10, S43}, - { 0x85845dd1, 1, S44}, - { 0x6fa87e4f, 8, S41}, - { 0xfe2ce6e0, 15, S42}, - { 0xa3014314, 6, S43}, - { 0x4e0811a1, 13, S44}, - { 0xf7537e82, 4, S41}, - { 0xbd3af235, 11, S42}, - { 0x2ad7d2bb, 2, S43}, - { 0xeb86d391, 9, S44}, + { 0xf4292244, 0, S41}, + { 0x432aff97, 7, S42}, + { 0xab9423a7, 14, S43}, + { 0xfc93a039, 5, S44}, + { 0x655b59c3, 12, S41}, + { 0x8f0ccc92, 3, S42}, + { 0xffeff47d, 10, S43}, + { 0x85845dd1, 1, S44}, + { 0x6fa87e4f, 8, S41}, + { 0xfe2ce6e0, 15, S42}, + { 0xa3014314, 6, S43}, + { 0x4e0811a1, 13, S44}, + { 0xf7537e82, 4, S41}, + { 0xbd3af235, 11, S42}, + { 0x2ad7d2bb, 2, S43}, + { 0xeb86d391, 9, S44}, }; int debug; @@ -154,7 +156,7 @@ sum(FILE *fd, char *hash) int i, n; MD5state *s; - s = nil; + s = nil_state; n = 0; buf = calloc(256,64); for(;;){ @@ -187,10 +189,10 @@ md5(byte *p, uint len, byte *digest, MD5state *s) byte *end; uint x[16]; - if(s == nil){ + if(s == nil_state){ s = calloc(sizeof(*s),1); - if(s == nil) - return nil; + if(s == nil_state) + return nil_state; /* seed the state, these constants would look nicer big-endian */ s->state[0] = 0x67452301; @@ -229,7 +231,7 @@ md5(byte *p, uint len, byte *digest, MD5state *s) d = s->state[3]; decode(x, p, 64); - + for(i = 0; i < 64; i++){ t = tab + i; switch(i>>4){ @@ -249,7 +251,7 @@ md5(byte *p, uint len, byte *digest, MD5state *s) a += x[t->x] + t->sin; a = (a << t->rot) | (a >> (32 - t->rot)); a += b; - + /* rotate variables */ tmp = d; d = c; @@ -268,7 +270,7 @@ md5(byte *p, uint len, byte *digest, MD5state *s) if(done){ encode(digest, s->state, 16); free(s); - return nil; + return nil_state; } return s; } diff --git a/frotz/src/interface/md5.h b/frotz/src/interface/md5.h index 4fe8e852..ac993bee 100644 --- a/frotz/src/interface/md5.h +++ b/frotz/src/interface/md5.h @@ -12,9 +12,7 @@ typedef struct MD5state uint state[4]; } MD5state; -MD5state *nil; - MD5state* md5(byte*, uint, byte*, MD5state*); void sum(FILE*, char*); -#endif MD5_H \ No newline at end of file +#endif From 8bea90c1c0285328cd1d69a00ecbe2e39eaffd44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 6 Jan 2025 18:00:35 -0500 Subject: [PATCH 84/85] Improve find_special_ram printing --- tools/find_special_ram.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/find_special_ram.py b/tools/find_special_ram.py index 1c0d074d..813448bd 100644 --- a/tools/find_special_ram.py +++ b/tools/find_special_ram.py @@ -30,6 +30,8 @@ def get_zmp(env): #start = zmp.view(">u2")[6] # ref: https://inform-fiction.org/zmachine/standards/z1point1/sect06.html#two #length = 240 * 2 # 240 2-byte global variables. #globals = zmp[start:start + length].view(">i2") + # Round up zmp to the nearest multiple of 16. + zmp = zmp[:len(zmp) - len(zmp) % 16] return zmp.view(">u2") From 26347722fede826f6285c5afecc5999ea16afaec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Alexandre=20C=C3=B4t=C3=A9?= Date: Mon, 6 Jan 2025 18:01:11 -0500 Subject: [PATCH 85/85] Improve checks for anchor.c --- frotz/src/games/anchor.c | 4 +++- tools/test_games.py | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/frotz/src/games/anchor.c b/frotz/src/games/anchor.c index 5a586c73..534e7352 100644 --- a/frotz/src/games/anchor.c +++ b/frotz/src/games/anchor.c @@ -29,12 +29,13 @@ const char *anchor_intro[] = { "\n", "\n", "\n" }; const zword anchor_special_ram_addrs[3] = { // 21922, // Combination lock 40660, // Bathe + 40674, // Look in telescope // 38470, // Transitions between days // 37992, // Sleep 8810, // Talking to Micheal // 18081, // Asking Bum about brother // 24928, // Turn c, w, h and e. - 18839, // Being chased by a monster around the Old Stone Well. + // 18839, // Being chased by a monster around the Old Stone Well. // 31625, // Breaking door leading to Hallway. // 17267, // Ritual sequence in town square // 27970, // Opening the hatch and waiting for the sound. @@ -91,6 +92,7 @@ short anchor_get_score() { int anchor_max_score() { return 100; + // return 99; } int anchor_get_num_world_objs() { diff --git a/tools/test_games.py b/tools/test_games.py index 1e5f2b1f..42ad9dc1 100644 --- a/tools/test_games.py +++ b/tools/test_games.py @@ -513,19 +513,21 @@ "anchor.z8": { "noop": [ "read newspaper",# "read news in newspaper", "read sports in newspaper", "read features in newspaper", - "Look up Wilhelm in album", #"Look up Eustacia in album", "Look up Croseus in album", + "Look up Wilhelm in album", "Look up Eustacia in album", "Look up Croseus in album", "read slip of paper", "read wall", "read blueprint", "ask bum about himself", "ask bum about anna", "ask bum about crypt", "tell bum about skull", - "put mirror 1 in caliper" + "put mirror 1 in caliper", + 'examine coffin', 'examine safe', 'look at bookshelf', 'look at controls', 'look at device', 'look at fireplace', 'look at furnace', 'look at ring', 'look at screen', 'look at window pane', 'look in displaycase', 'look in hole', 'look in overalls', 'look in safe', 'look in tear', 'look up croseus in album', 'look up edward in record', 'look up elijah inrecord', 'look up eustacia in album', 'look up heinrich in record', 'look up mordecai in record', 'look up wilhelm in album', 'look up wilhelm in record', ], "wait": [ 400, # Waiting to hear something from within the hatch. 471, 474, # Waiting for the old man to meet his faith. 494, # Waiting for Michael to ask for the mirror. 498, 499, 500, 501, 502, 503, # Summoning sequence. - ] + ], + 496: "look", # Waiting for Michael to take up a torch from one of the crowd. }, "awaken.z5": { 4: "n", # Dog blocks your path.