v0.4.5 - fix bug with not being able to drop cars

This commit is contained in:
Jesse
2026-08-14 23:22:00 -04:00
parent 6655e20ea8
commit 98f93e6691
5 changed files with 191 additions and 9 deletions
+50
View File
@@ -21,6 +21,56 @@ page as `v0.1.0 · <sha> · <date>`, so what is deployed can always be identifie
## Unreleased
## 0.4.5 — 2026-08-14
### A train can back out of a curve again
**Reported one commit after 0.4.4 shipped:** "seems like I can't drop a car at all. I'm trying to
switch to get an empty car to an industry, but I can't drop any cars on the siding first."
Setting out a cut needs no Move and is refused almost nowhere — but you may only set out where the
train **is**, and the Office square is barred outright (§A.4). So "I cannot drop" is nearly always
"I cannot get there", and getting there means leaving the Running Track through a turnout and a
curve. 0.4.4 fixed the forward half of exactly that and left the reverse half wrong:
- **Forward** exits by `facing` — fixed in 0.4.4 to read the card's far end rather than assuming
`opposite(entry)`.
- **Reverse** still exited by `opposite(facing)`, which is the other end of a **straight** and of
nothing else. A crew facing north on a north-west curve backs out through **west**; `opposite('n')`
is a south port the card does not have, and `exploreMoves` returns nothing at all from a port the
card lacks.
So 0.4.4 moved the problem rather than solving it. Before it, a crew that rounded a curve could only
back out; after it, a crew could only carry on. Either way a siding entered one way could not be left
the other, and a siding that had to be *backed* into could not be entered at all.
`reversePort` now asks the card for its other end, the same way `farPort` does going forward. A train
always stands on a two-port card — §A.1 forbids finishing a Move on a turnout — so there is exactly
one other end to find.
**How much of the board this was hiding.** Over 25 bot games, at 1,937 points where a crew could have
been switching, comparing what the board highlights now against what it highlighted before:
| | |
| --- | --- |
| squares offered, before → now | 7,461 → 10,040 (**+35%**) |
| positions hiding at least one legal square | 694 (**35.8%**) |
| positions with **no legal move at all** | 300 (**15.5%**) |
Both figures understate it: the "before" reckoning was run with occupancy ignored, so it was allowed
squares that another train was actually sitting on. A crew counted as stuck was stuck even on the
generous reading.
**Tests.** The failing case is pinned three ways — backing off a curve, carrying on round one, and
the whole errand from the report: take a cut off the Running Track into a siding, set it out, and
come back for the industry. That last one fails on 0.4.4 with *"the crew is stranded on the siding —
it cannot return to the Running Track"*, which is the report in one line.
`sim.test.ts` needed a wider sample rather than a lower bar: crews now have real switching to do, so
the bot lays fewer track pieces per game and five seeds no longer produced the 40 placements the
dead-end **rate** is measured over. Eight seeds now, same stride; the rate itself came out at 0.147
against a bar of 0.25.
## 0.4.4 — 2026-08-14
Out of a play session: engines that pointed north, a card whose name collided with five other things,