v0.8.0.8 — a played train does not come back; a discarded one does

Jesse's ruling on the question v0.8.0.7 filed: once a regularly scheduled train has
been played its number is on the timetable, so putting it back into a reshuffled
deck to be played again makes no sense. The same card sitting in a discard pile was
never played and its slot is still open, so it should come back. An Extra is a
single run rather than a standing slot, so a played one is free to run again.

The test is therefore WHERE the card is, not only what it is — which is worth
writing down, because it is exactly the rule a later tidy-up would simplify into
filtering by kind everywhere.

And the duplicate that started it: trainScheduled was pushing a synthetic
train-<number> into the Salvage Yard beside the real card cardPlayed had already
put there — four scheduled trains left eight entries in a pile holding four cards.
Nothing read it, it inflated the depth, it displayed as "a card", and it would have
been swept into the draw deck to be drawn as an id with nothing behind it. Removed,
which retires the phantom-id class rather than papering over it, so v0.8.0.7's
cardName resolver for it goes too.

Games in progress resume: no predicate changed its answer, and a draw is a draw
whatever is on top. What differs is the Yard's depth, which was double-counting,
and what a reshuffle recovers — and reshuffles are effectively unreachable, with
zero seen across eight games driven to 4000 moves.

Closes #23.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X6cF1iYvJ1kNmzYBzu4QX6
This commit is contained in:
Jesse.Markowitz
2026-09-10 07:19:47 -04:00
co-authored by Claude Opus 5
parent d0e5091824
commit 072029b1f7
6 changed files with 140 additions and 50 deletions
+43
View File
@@ -19,6 +19,49 @@ page as `v0.1.0 · <sha> · <date>`, so what is deployed can always be identifie
---
## 0.8.0.8 — 2026-09-10
**A played train does not come back. Gitea#23, ruled and closed.**
Jesse, on the question v0.8.0.7 filed rather than answered: *"Once you've played a regularly
scheduled train and it's in the salvage deck, that train is already on the timetable. It does not
make sense to put that back into a reshuffled home deck to get played again. By contrast, a regularly
scheduled train that's in a discard pile could potentially get reused later, and so should have that
capability. Extras run one time and then they're done — if they are in the Salvage deck, they should
get shuffled back in so that they could get run again."*
**The test is WHERE the card is, not only what it is** — which is the part worth writing down, because
it is exactly the rule a later tidy-up would "simplify" into filtering by card kind everywhere. The
same train card is spent in the Salvage Yard and still runnable in a Department:
| card | where | on a reshuffle |
| --- | --- | --- |
| timetabled train | Salvage Yard — it was **played**, its number is on the timetable | stays out |
| timetabled train | a Department — **discarded**, never played, slot still open | comes back |
| Extra | anywhere | comes back; an Extra is one run, not a standing slot |
| everything else | anywhere | comes back, as before |
### And the duplicate that started it
`trainScheduled` was pushing a synthetic `train-<number>` into the Salvage Yard **beside the real
card `cardPlayed` had already put there** — measured: four scheduled trains left eight entries in a
pile holding four cards. Nothing read that id. It inflated the pile's depth, displayed as "a card"
because no such card exists, and would have been swept into the draw deck to be drawn as an id with
nothing behind it. Removed, which retires the whole phantom-id class rather than papering over it —
so v0.8.0.7's `cardName()` resolver for `train-<n>` is gone too, along with its test. Dead code kept
for an id that can no longer exist is worse than no code.
### Games in progress
**Resume.** No predicate changed its answer — nothing that was legal became illegal, and a draw is a
draw whatever is on top of the deck. What differs is the Salvage Yard's depth, which was
double-counting, and what a reshuffle would recover. Reshuffles are effectively unreachable in
ordinary play: eight games driven to 4000 moves across eight seeds produced zero.
Closes #23.
---
## 0.8.0.7 — 2026-09-10
### The Salvage Yard was face up and had nothing to say