Commit Graph
3 Commits
Author SHA1 Message Date
jcoffey-dev dbf4b9dea4 Use the published board instead of drawing a worse one
Three attempts at drawing this map came to nothing worth looking at. Dividing
the plane by nearest province gives a tidy board that looks nothing like
Europe. Drawing the adjacency graph gives something unimpeachable about the
rules and not a map at all -- circles joined by lines. Fifty-six polygons
placed by eye gives fifty-six islands.

The standard map published with the diplomacy engine is AGPL-3.0, the same
licence as this project, so it can be carried across whole with attribution
rather than approximated badly. tools/map.py extracts the outlines, the unit
coordinates and the layer transform into board.json and can be re-run against
a newer copy. NOTICE.md says where it came from and what is still ours, which
is every colour and every mark drawn on top.

Drawing Europe accurately is real work, somebody did it properly, and they
published it under a licence that invites exactly this. Three days of my
approximating it would have produced something worse than the thing that
already existed.

Clicking still answers with the rules rather than the picture: a shape cannot
say that a fleet on Spain's north coast may not enter the Gulf of Lyon while
one on the south coast may, because both coasts are the same shape.
2026-09-09 08:10:30 -07:00
jcoffey-dev 38f69e9aa6 Harnesses for retreating and the winter
All 176 published cases now parse and run. Retreating passes 18 of 18,
building 7 of 7, civil disorder 13 of 13; movement is unchanged at 133 of
139.

The retreat and winter engine code was written before these cases and mostly
held up, but civil disorder was wrong in a way playing would never have shown.

It measured distance to a power's *home* centres. The rule is distance to the
centres it owns -- a Russia driven out of Moscow and holding Sweden measures
from Sweden -- so every power that had lost a home centre was disbanding the
wrong unit.

And it measured over the graph each unit moves on, which is wrong in both
directions. An army counts sea provinces it would have to be convoyed across,
so Albania is two steps from Naples rather than unreachable. A fleet counts
inland provinces it could never enter, so the Baltic is two from Warsaw. That
reads as nonsense until you notice what is being measured: not how the unit
would get home, but how far out of the way it is. A fleet in the Baltic is
still in the middle of Russia's business; one in the North Atlantic is not.

Civil disorder also only applies to the shortfall. A power that disbanded one
of the two it owed has half answered, and the automatic rule picks from what
is left rather than from what it started with.
2026-09-09 06:41:28 -07:00
jcoffey-dev b41cf1c210 Run the published test cases, and fix what they found
tools/datc.py turns the Diplomacy Adjudicator Test Cases into a fixture: the
orders and their annotated outcomes, not the document's prose. 139 movement
cases run; 107 pass.

Three real faults so far, none of which the hand-written cases had caught:

Orders were never validated. An illegal order has to be refused and the unit
left holding -- still standing there, still in everybody's way -- and a fleet
told to go to Spain has to be told which coast when both are reachable.
There is now a validation pass, and ordering another country's unit is
refused without disturbing the order its owner actually gave.

The paradox rule did not terminate. Settling only what was already in the
dependency cycle resolves nothing in a real paradox, so the resolver asked
the same question forever -- Pandin's Paradox was a stack overflow rather
than an answer. It now restarts the whole resolution with the convoyed army
held still, which is inelegant and provably finite: each restart forces one
more army to stand, and there are only so many armies.

A held army kept its path. Szykman's rule stops the army; it has to stop the
army's weight too, or the paradox re-forms on the next pass and the restart
never converges.
2026-09-09 00:36:39 -07:00