#!/usr/bin/env bash # A/B the card-reward skip policy. # # ./ab_card_skip.sh # # Runs N sessions with --card-skip-policy jev, then N with --card-skip-policy # combined, and prints a comparison of deck size and progress. # # Everything else is identical between the arms, so any difference is the # policy. (The earlier before/after comparison was confounded: several bug # fixes landed at the same time as the policy change.) set -u # Fail fast if the bot cannot start a run (e.g. a pending Timeline epoch). if ! python3 run.py --steps 1 >/tmp/preflight.log 2>&1; then cat /tmp/preflight.log exit 2 fi N="${1:-5}" STEPS="${2:-600}" run_arm() { local policy="$1" tag="$2" for i in $(seq 1 "$N"); do echo "--- $tag $i/$N ---" python3 run.py --steps "$STEPS" --pause 0.3 \ --card-skip-policy "$policy" > "/tmp/ab_${tag}_${i}.log" 2>&1 echo " exit=$? takes=$(grep -c 'select_card_reward' "/tmp/ab_${tag}_${i}.log") skips=$(grep -c 'skip_card_reward' "/tmp/ab_${tag}_${i}.log")" done } echo "### ARM A: jev decides skip" run_arm jev jev echo echo "### ARM B: combined (jev + a floor)" run_arm combined combined echo python3 - <<'PY' import json, glob, os, statistics as st H = os.path.expanduser( "~/Library/Application Support/SlayTheSpire2/steam/" "76561198141226155/modded/profile1/saves/history" ) rows = [] for f in glob.glob(H + "/*.run"): d = json.load(open(f)) pl = (d.get("players") or [{}])[0] mph = d.get("map_point_history") or [] rows.append({ "t": d.get("start_time", 0), "killed": d.get("killed_by_encounter", "?").replace("ENCOUNTER.", ""), "deck": len(pl.get("deck") or []), "pts": sum(len(a) for a in mph if isinstance(a, list)), }) rows.sort(key=lambda r: r["t"]) # The last 2N runs are this experiment's. total = 2 * int(os.environ.get("AB_N", "5")) tail = rows[-total:] if total <= len(rows) else rows armA, armB = tail[:len(tail)//2], tail[len(tail)//2:] print(f"{'arm':<12} {'n':>2} {'deck avg':>9} {'pts avg':>8} {'reached act 2':>14}") for name, grp in (("jev", armA), ("combined", armB)): if not grp: continue decks = [r["deck"] for r in grp] pts = [r["pts"] for r in grp] act2 = sum(1 for r in grp if r["pts"] > 17) print(f"{name:<12} {len(grp):>2} {st.mean(decks):>9.1f} {st.mean(pts):>8.1f} " f"{act2}/{len(grp):>12}") PY