policesquadquest/play.sh
type-two 3b20f7accc Case Eight, a case picker, and a linter for the authoring traps
Case Eight — The Smell of Fear (1991). Act II, full colour. Five rooms, 100
points, verified at 100/100 with two verified deaths.

The puzzle is identification: Meinheimer has an eidetic memory, so the double
cannot be caught out on a fact — he can be caught out on a manner. Ask him two
questions and he answers "about four hundred", "roughly", "give or take", and a
man who remembers everything never says roughly. The catch is gated on having
heard the approximations, so the player has to earn it. Accusing him without
that is a death. Also in: the Blue Note, the SWAT tank through the wall into the
zoo (which arms the lion that kills Hapsburg two rooms later), the mariachi
infiltration, and a nuclear device disarmed by tripping over its power cable.

tools/lint.py: three of the four bugs that cost real time here were the same
class, and I walked into sets_flag-on-a-takeable twice — once in Case Ten, then
again in Case Eight after documenting it. So the rules are a linter now, not a
paragraph. It caught two live instances of that trap (case-08 blueprint,
case-10 wig) and a scoring mismatch on the first run. All five cases lint clean
and all five still win.

play.sh is now a case picker: bare invocation lists the cases and asks, or pass
a number.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 22:55:40 +10:00

39 lines
1.1 KiB
Bash
Executable File

#!/bin/sh
# Play a case: ./play.sh list them and pick
# ./play.sh 07 by number
# ./play.sh cases/case-07-from-the-files
# ponytail: MRPGI lives next door; no vendoring, no submodule.
set -e
ENGINE="${MRPGI:-$HOME/Documents/MRPGI}"
cd "$(dirname "$0")"
# Menu goes to stderr so the caller only captures the reply.
pick() {
{
echo "POLICE SQUAD QUEST — cases:"
echo
for d in cases/*/; do
n=$(basename "$d" | sed 's/^case-//; s/-.*//')
t=$(sed -n 's/.*"name"[^"]*"\([^"]*\)".*/\1/p' "$d/game.json" 2>/dev/null | head -1)
printf ' %s %s\n' "$n" "${t:-$(basename "$d")}"
done
echo
printf 'case number: '
} >&2
read -r reply
echo "$reply"
}
arg="$1"
[ -n "$arg" ] || arg=$(pick)
# A bare number selects by case prefix; anything else is treated as a path.
case "$arg" in
[0-9]*) CASE=$(ls -d cases/case-"$arg"-*/ 2>/dev/null | head -1) ;;
*) CASE="$arg" ;;
esac
[ -n "$CASE" ] && [ -f "$CASE/game.json" ] || { echo "no such case: $arg"; exit 1; }
exec cargo run --release -p mrpgi --manifest-path "$ENGINE/Cargo.toml" -- \
--game "$(cd "$CASE" && pwd)"