e893d0164b17d3a75518736b29961266f1d8b7df
33
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e893d0164b |
The bots could not win, and the reason was worse than being weak
The board froze. By 1908 no centre changed hands again, and a game left running to 1960 finished on the distribution it had reached in 1939. A game that cannot be won is not a hard game, it is a broken one. Thirty seeded games now play themselves out in solo.test.ts. The leader used to finish on a mean of 7.8 centres and never once reached eighteen; it now averages 13.7 and solos in six games out of thirty, won by three different powers -- about the rate a table of decent players manages. Five faults, and every one of them is a rule somebody could have told you over a board. A threat is two units of one power, not two neighbours. Support comes from your own units or from a deal, so two enemies who have agreed nothing cannot combine. Counting any two neighbours put half of every army on garrison duty in a crowded position, drawn from exactly the units that would otherwise have attacked: France sat with three units beside Kiel for five years and never took it, all three defending against a threat that did not exist. Take what you can carry before what you merely want. The most valuable target is usually the one you cannot have, and sorting by worth and spending as you go lets it eat the units that could have taken the second. March toward the guns. Everything else asks what a unit can take this turn, and a board settles the moment the answer everywhere is nothing. A unit with nothing else to do walks toward the best thing this power wants and cannot yet have, discounted for every year of walking so it does not set out across Europe for something nearer hands will take first. Gather. Units choosing objectives one at a time never gather anywhere: each picks the best thing it can see and sets off alone, and a defended centre needs two. A goal somebody is already walking toward is worth more to the next unit than it was to the first. And the one that mattered most: supporting somebody does not cost you the province. Support was priced at the target's full value, which made every request refusable and every one of them refused -- a centre is worth a hundred, a working relationship at most eighty, and the arithmetic could not come out any other way. Two hundred and twenty-four approaches in one game, ninety-five of them asking for support, not one accepted; the entire press reduced to agreeing where not to go. You give up the province only if you could have taken it yourself, and usually you could not, which is precisely why they are asking. Powers now lean: a seed decides which way each goes when two things are worth the same, so seven identical minds stop playing seven identical games. Not randomness -- the same power asked twice in one game answers the same, and a seed replays a game exactly. Callers that pass no seed get the plain alphabetical tie-break they always had. The game is called at the end of 1920 rather than 1912, set by measurement: solos land between 1915 and 1920, and 1912 cut a fifth of them off mid-conquest, turning a game somebody was winning into a draw. One test fixture moved. The promise cases put a French army in Burgundy, which made Belgium contested -- so the bot now quite correctly goes and takes an uncontested Holland instead, and the promise was never tested at all. Silesia and Tyrolia lean on Munich just as well and cannot reach Belgium, so the only thing between the Ruhr and it is the promise. |
||
|
|
2db55fd47f |
The last one: an answer has to agree with itself
6.F.29 and every other published movement case now passes -- 137 of the 137 that can be run, and 176 of 176 across all four sections. The resolver guesses, and a guess is only ever tested against the guesses in force beside it. Where several cycles are knotted together that is not enough: two readings can each be locally consistent, and the search lands on whichever one the order it happened to start from leads to. 6.F.28 and 6.F.29 are the same ring of six convoy paradoxes with one support between them, and the document keeps the pair to show that the answer swings on it. The document is explicit that there is no straightforward way to fix this inside the recursion. So it is fixed outside it. The resolution is run again, starting each order from the answer the last run gave it rather than from a fresh guess of false. A reading that is genuinely settled reproduces itself and we stop; one that was an artefact of where the search began does not, and the next run starts from somewhere better. Four passes, and a position still arguing with itself after that is oscillating rather than converging, so the first answer stands. Two other corrections came from the document's own text on the way here. Its published resolver replaces "did the dependency list grow" with a guess_based flag saved and restored around every frame, and counts recursion_hits to decide which order a cycle hangs from -- both because the simpler tests stop meaning what they say once more than one cycle exists. And section 5.D's hack: a convoy asks the units attacking it by adjudicating them directly rather than through the resolver, which keeps the dependency graph a set of clean single cycles. Pandin's paradox is the small example -- routed through resolve, the English Channel comes to depend on Wales and Belgium, neither of which is a decision the paradox turns on. The document's test for the head of a cycle still needed one addition: an order named in the cycle that is still on the stack is one of its callers, and while a caller is waiting the answer is that caller's to settle. settle.test.ts checks the property directly rather than through the published cases. An adjudicator that cannot reproduce its own answer is not finished, whatever it scores. |
||
|
|
4fe188cadd |
6.F.28: six paradoxes in a ring, and none of them seen
The fix for 6.F.22 asked whether a cycle had come back round to this order before letting it take the two guesses. Necessary but not sufficient: it looked only at the dependencies added since that order started. 6.F.28 is six convoy paradoxes arranged in a ring, each a tidy four-order cycle in its own right. Every one of them satisfied that test, settled itself locally against a caller's provisional answer, and wrote the result down as final. The ring they were links in was never seen at all -- no backup rule, no Szykman, and an answer that was locally consistent six times over and globally wrong. An order may now only settle a cycle when nothing anywhere in the dependency list is still waiting further down the stack. If one of its own callers is entangled, the answer is that caller's to settle, because their value is the one everything here was computed against. 6.G.19 in the previous commit and this leaves one deviation of the hundred and thirty-nine. 6.F.29 is 6.F.28 plus a single support that unwinds the whole ring, which is what the document keeps the pair for. The half of the ring furthest from that support comes out right and the half nearest it does not: the resolver settles the first order it reaches while a second free value elsewhere in the ring reads the same under both of its guesses, and declares a determinacy it has not earned. Both halves are consistent on their own. Together they are not. |
||
|
|
9dc28e0d7a |
A convoy order from a fleet with nothing to do
6.G.19. The document's rule, from issue 4.E.1: for a convoy order the fleet must be part of at least one route for which the fleets are available, and it must not be superfluous -- there has to be a route, ordered or not, for which that fleet is necessary. The path finder implements it by considering only proper routes, where the chain never jumps to a province an earlier fleet already reached. Tunis - Ionian - Adriatic - Albania is not proper, because the Ionian touches Albania and the Adriatic is doing nothing. In graph terms the chain has no chords. It matters more than a tidy-up. In 6.G.19 France orders a convoy from the Western Mediterranean for Marseilles to Spain when the Gulf of Lyon already touches both. If that order counts, France has expressed an intent to go by sea and the two units swap places; if it does not, they walk into each other and bounce. The document's own advice is that an interactive system should never have offered the order. Properness is asked only when a particular fleet is being judged, which is the only question the document uses it for. Asking it of the plain question -- could water get an army there at all -- is a different and wrong claim, and doing so broke five cases where a convoy legitimately runs the long way round because the short way has no fleet in it. The rewrite from breadth-first over seas to depth-first over chains needed the first step back: a two-coasted province has no bare entry in the fleet graph, so an army boarding in Bulgaria found no water to start from until both coasts' seas were offered to it. |
||
|
|
35b52f3453 |
Half a convoy looked exactly like a whole one
Multi-fleet convoys work and always did -- London to Spain across the Channel and the Mid-Atlantic with both fleets carrying, which is what the fifty DATC convoy cases are about. What did not work was finding that out from inside the game. A convoy takes as many orders as there are seas to cross, and the rules give two different answers to writing fewer. With no fleet ordered at all the move is illegal -- legality is decided on the board alone -- and the panel reddens it. With one fleet of a two-fleet chain the move is perfectly legal and simply fails, silently, a turn later, with nothing on screen to tell it apart from having been blocked. From the chair where the orders are written those are one complaint: nobody is carrying this. And it is worse than it looks, because the board deliberately offers crossings that run through other powers' fleets, which cannot be ordered at all, only asked for -- so a player can write a crossing that no order of theirs could ever complete. The panel now asks the question that matters rather than the one the rules happen to answer: given everything on the table, is there a chain that gets this army there? When there is not it says which kind of not, in amber rather than the red an illegal order gets, because a legal order that will fail is a different thing to tell somebody. |
||
|
|
5b402f2ce9 |
A page before the map, and two ways to stop playing
Diplomacy has a reputation and about half of it is wrong, so the landing page states the rules completely -- they are short enough -- and says the strange part out loud: there is no luck in this game, every unit is exactly as strong as every other, and nothing happens on the board that somebody did not agree to help with. It is also the honest place for the licence and for where the map came from. A page that says nothing about that is a page quietly hoping nobody asks. The dice on starting are the only joke in here. There are none in this game; that is the sound of every other board game you have played, and the last one you hear before finding out that none of this is luck. Giving up is two different things and concede.ts keeps them apart. Resigning is unilateral, because nobody is entitled to your attention. But the power does not leave the board -- it goes into civil disorder, holds everything, waives its builds and is paid off as it loses centres, which is what the rules already say happens to an absent player. That matters to everyone else: a resigned Austria is still eleven centres somebody has to go and take, and letting them evaporate would hand the game to whoever happened to be next door. Verified by playing four years past a resignation: Austria sits on its three while France reaches six. A draw is not unilateral, and that is what keeps it Diplomacy rather than a menu. Every surviving power votes, one refusal is enough, and each refusal comes back with its reason so it can be argued with next year. A power refuses while it leads or is within two of leading. Asked in Spring 1901 all six refuse -- the right answer, since a game that could be drawn on the first turn would not be worth playing. Conceding is harder to get than a draw and should be: it carries only when the solo was coming anyway. Otherwise refusing costs nothing but time, and time is all the losing side has. The resign button asks twice, in the page rather than in a browser dialog. It is the one control here that cannot be taken back. |
||
|
|
8c31ecb35c |
Three of the six DATC deviations were bugs
The illegal/invalid line (6.A.5, 6.D.8). The document separates an order that is impossible in this position from one this position allows that merely did not come off. The first is ignored and its unit is holding like any other; the second means the unit tried to leave and cannot be propped up where it stands. An army sent across water with a fleet on the route and no convoy ordered is the second; the identical order with nobody in the sea at all is the first. Guessing at this once cost four passing cases to buy one. Reading the document cost nothing -- it says so outright, in the note under 6.D.8 and again under 6.D.32. A support that only looked like a hold (6.A.5). "Supports A Yorkshire" and "Supports A Yorkshire - Yorkshire" are the same shape once parsed, and the case turns on the difference: the first holds a unit down, the second supports a move nobody can legally make. The extractor was throwing that away; it now keeps it, and the fixture is regenerated. The head of a cycle (6.F.22). Kruijswijk's resolver guesses that an order fails, sees what follows, then guesses the other way. Only the outermost order in a cycle may do that, because its answer is the one everything else was computed against. This engine let any order that reached the dependency list first declare the cycle its own -- and an inner one takes both guesses with its callers' provisional answers held fixed, gets the same result twice for that reason, and writes it down as settled. The cycle then becomes invisible: the backup rule never runs and Szykman's rule never fires, and the position resolves to whichever of its two consistent readings the search happened to walk into first. It had been doing this on every paradox and getting away with it, because on a first-order paradox both readings agree. Also carried across from the reference algorithm: an order that resolved itself while a nested call was away must not have the guess written over it. Three remain. 6.F.28 and 6.F.29 are sixth-order paradoxes -- the same twenty-six orders with one support between them, and the point of the pair is that the answer swings on it, where this resolver gives both the same answer. 6.G.19 the document itself gives three answers to, calls a little bit pedantic, and advises adjudicators not to offer at all. |
||
|
|
ce276836cc |
Convoys were in the rules and not on the board
Fifty of the DATC cases are about convoys, paradoxes included, and the adjudicator passes them. But the army's half of a convoy could not be ordered: the board offered a unit the provinces it could walk to, and a crossing is by definition not one of those. The fleet's half could be ordered, which made it worse -- the verb was there and did nothing anybody could reach. An army on a coast is now also offered the coasts a chain of crewed seas can reach, in blue with long dashes, so a crossing does not look like a march. A sea counts if a fleet is standing in it, whoever owns it; a fleet that has not been ordered to convoy still counts, because it is a thing that could be arranged and that is what the talking is for. This is deliberately not the question the rules ask when they judge a convoy order, which is whether water could ever get there. That one says yes to most of Europe: offering thirty provinces because a chain of fleets is conceivable is worse than offering none. Clicking a blue coast writes the move viaConvoy. Not a formality -- the rules let a unit be convoyed to a province it could have walked to, and the two orders resolve differently. The fleet's own offering was too loose in the other direction and is now on the same chain: the North Sea listed eleven armies it could never carry, one of them in Ankara, and wrote orders the adjudicator discarded without saying why. What needed nothing added: the order list already flags A Yorkshire → Norway in red while it stands alone, and clears it when F North Sea convoys Yorkshire → Norway joins it. The validator knew all along. |
||
|
|
73f33ec408 |
Support was asking the wrong question
The rule is that the supporting unit must be able to reach the province the supported unit is going *to*, not the province it is standing in. The board offered the other set -- units standing next door -- so Vienna could not support Venice into Tyrolia, which is an ordinary order: Vienna and Tyrolia touch, Vienna and Venice do not. There was no way to write it at all. It was wrong in the other direction too. Support to hold was offered for units the supporter could not have reached, the order was written, and the adjudicator turned it into a hold after submission without saying so. This was a rules question living in a component, so it moves to the rules: src/game/targets.ts, and eight tests instead of a closure. The rest of the stiffness was that a stray click threw away a half-written order. You picked Support, picked the unit to help, missed the destination by a province, and the whole thing silently became a fresh move somewhere else. A two-part order now stands its ground and sounds a refusal; clicking the unit giving the order backs out of it, and any other unit of yours still switches straight over, which is what makes writing a page of orders quick. And the unit picked to support -- or to carry -- is marked on the board, in a different colour from the unit giving the order. Without it the second half of every support is written blind: you click a unit, every highlight on the map changes, and nothing says which one you chose. |
||
|
|
9c6efb3d85 |
The war, out loud
Music, battle sounds and the four endings. The score is original and says so at length in score.ts: there is a great deal of music from and about that war, some of it still in copyright somewhere, and it would be a strange sort of care to license the map properly and then lift eight bars of somebody's march. What is borrowed is the idiom, which belongs to nobody -- a minor key, dotted rhythms, low brass a bar at a time, and a side drum that never stops. Three pieces, and which one is playing tells you something. THE_FRONT in spring, when the armies move and nothing is decided. THE_PUSH in autumn, at a hundred and thirty-two, when centres change hands and the year is counted. ARMISTICE when it is over, whoever won. The sounds are chosen in the rules rather than fired from the interface, for the same reason the orders are validated there: what a turn sounded like is a question with a right answer, and a right answer can be tested. src/game/ sound.ts turns orders and an outcome into cues and nothing in it touches an AudioContext. The interesting cases are the quiet ones -- a turn where everybody walks into empty country makes no sound at all, and getting that wrong would be the same as having no guns, because guns on every turn are just weather. Each kind plays once however many battles there were. Four land battles are not four times as loud as one, they are mud, and the player learns nothing from mud. A landing is ground and two fleets over a coast are naval, which is the sort of distinction that is only worth making because the rules already know enough to make it. An escort sounds only for a convoy that actually carried somebody: a held order succeeds, so asking whether the army's order worked is the wrong question -- ask whether it was ordered to make the crossing and whether it arrived. Four endings rather than two, because losing has more than one shape. Being eliminated in 1904 and watching Russia take an eighteenth centre in 1911 are both defeats and they do not feel remotely alike. The buses open at whatever the toggle already says rather than at full: a one-shot opens the context itself, so a game started with the sound off would otherwise have made exactly one noise, the first one, before anything got round to muting it. |
||
|
|
0208a10da6 |
Retreats and the winter, given back to the player
Both were being taken for the player, the same way a computer power's are, which quietly removed half the consequence of the turn they had just played. A beaten unit that finds somewhere to stand is a nuisance for years and one that does not is gone; the winter is where a good spring turns into a bigger army, or does not. Offered as places rather than as a notation, for the same reason the orders are: the rules already know what is allowed, so the interface only ever offers what is. A beaten unit lists the provinces it may fall back to and nothing else, with Disband beside them. The winter lists the home centres that are yours and empty, and offers a fleet only where a fleet could sit -- so St Petersburg offers two coasts and Moscow offers none. The game steps past anything with no decision in it. A retreat phase where nothing of yours was thrown out, or a winter where your centres and units are level, is not a choice, it is a screen asking you to press Done. |
||
|
|
69adcc8f89 |
The press, in front of the player
The board is the game being played now rather than a picture of the opening: the loop runs, powers approach you before every set of orders, and what you agree is judged when the orders come in. Approaches arrive as sentences with Agree and Refuse under them, because a proposal is a thing somebody said and should not look like a row in a form. Asking is done from an order already written -- I am going there, help me -- which is the only shape this request has ever taken, and the answer comes back immediately in the power's own words. Those words are now written for a person. A power that turns you down saying 'austria is worth more to me than boh' is telling the truth in a voice nobody uses; it says Austria, and Bohemia, and puts a full stop on the end. The turn log too. Nothing in the panel enforces anything. Agreeing writes no order and stops no order being written, and the gap between what was agreed and what was ordered is the whole game -- which is why the panel also shows, per power, how many promises you have kept and broken and how far each of them now believes you. Retreats and builds are still taken for the player automatically, the same way a computer power's are. Choosing them is the next piece. |
||
|
|
e0852c50aa |
Warships, not sailing boats
A fleet in 1901 is a pre-dreadnought: coal-fired, armoured, and part of a naval race. A sail was wrong by fifty years. The tell is not the hull, which is a wedge like any other -- it is the pair of raked funnels over a hull that is long and low, with a turret at the bow because a warship points at things. At map scale the funnels are what a player actually sees. |
||
|
|
4c1ebbab4a |
Bots that attack, units that look like units
The planner worked one unit at a time, picking each one's best destination independently. That is why nothing was ever taken: a defended province is attacked by a single unit, bounces, and is attacked again next year for ever. It now works the other way round -- list what is worth having, work out how many units it takes, and commit that many or none. A province you cannot take is not worth one unit. Three things came out of that. A single unit still walks at an *empty* province, since the worst case is a bounce and it might be free, but never at a garrison. Garrisoning now needs two neighbours rather than one, because one unit cannot dislodge another -- with one counting as a threat, almost every centre on a crowded board was threatened, almost every unit stood still, and nothing happened for two centuries. And an attack is priced at two units unless the defender has two friends near enough to prop it up; assuming one was enough meant almost every attack was priced at three, which nobody can afford. Asking for help now works from what a power wanted and could not have. It used to read the moves already planned, which was exactly backwards once the planner learned not to attack what it cannot take: the target is no longer in the plan, so the bot stopped asking precisely when it needed to. The game is now called at the end of 1912. This game has no clock of its own and seven cautious powers will hold a standoff for ever -- a run to 2198 had the board still alive and nobody near eighteen. Eighteen wins outright and otherwise the survivors draw, which is a proper ending here and the commonest way real games finish. Units are a soldier and a ship rather than two wedges. A helmet and square shoulders read as troops at any size; a triangle above a curved hull is a boat before anybody has decided to look. Both in the power's colour with one flat highlight, and a shadow so they sit on the ground instead of floating over a border. |
||
|
|
75104e2614 |
The turn loop, and two bugs it found
Spring orders, retreats, autumn orders, retreats, then the winter -- the only phase that changes who owns anything. Everybody talks before the orders: computer powers approach each other, answer on the merits, and what they agree binds that turn and is judged at the end of it on the orders that were given rather than on how the turn came out. The loop has no interface attached on purpose. A whole game can be played out in a test, which is the only way to ask the question that matters about the bots -- not whether an order looks sensible but whether seven powers left alone get anywhere. Asking it found two things nothing else would have. Every bot was submitting orders for all twenty-two units on the board rather than its own three. The validator fills in a hold for every unit, which is right for adjudication and wrong as an answer to what one power does this turn; it only showed up when seven powers were asked at once. And fifteen of nineteen units held in Spring 1901, when in this game every unit moves. An empty province was priced by asking what the unit standing in it could reach -- and there is no unit standing in it -- so every empty non-centre scored zero and every move to one was skipped as worthless. It is sixteen of nineteen now. What the loop still does not do is finish. Played to 2149 the board is alive and nobody has soloed: the powers take the neutrals and then hold each other off. Taking a defended centre needs two units on it and the bots do not reliably arrange that. That is the next piece of work and the test says so rather than pretending otherwise. |
||
|
|
f88482f8cc |
Order entry
Clicks on the board, because that is where the question is. Select a unit, pick a verb, and the provinces the next click will accept light up. Nobody writes a move the rules were never going to allow, and nobody has to learn a notation to find that out. What is offered comes from the rules rather than from the map, which is the same split the map is built on: a fleet on the north coast of Spain is drawn identically to one on the south coast and can go to entirely different places. A support is only offered where both units could have gone, since you cannot support a move you could not have made yourself, and a fleet is only asked which coast it means when more than one is reachable. Orders are drawn where they are given -- an arrow to the destination, a dashed line to what a support is holding up, a ring round a unit staying put -- and written out beside the board in the rules' own words, because an arrow cannot tell you that the support you meant for Vienna is going to Budapest. The written list runs through the validator on every keystroke, so an order the rules will not take is struck through while it is being written rather than after the turn. |
||
|
|
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. |
||
|
|
fd05217f90 |
Territories, not circles
The board is regions again. Voronoi cells divide it with no gaps and no overlaps and look like a board, which is what this was always supposed to be. What they cannot do is reproduce every adjacency in the rules, because provinces interleave -- the Adriatic borders Venice with Trieste between their centres. The lesson I drew from that was to abandon regions and draw the adjacency graph, which is unimpeachable and is not a map. It is circles joined by lines. The right answer is to stop asking the picture to carry the rules. Clicking a province lights up exactly where its unit may legally go, taken from the graph rather than from which shapes happen to share an edge. Vienna lights Bohemia, Galicia, Budapest, Trieste and Tyrolia; a fleet on the north coast of Spain does not light the Gulf of Lyon. The picture is a picture and the rules answer for themselves when asked. |
||
|
|
ad6e384956 |
The board, drawn
Coordinates placed by hand, roughly where each province falls in Europe, and everything else drawn from those and from the adjacency rules. Nothing here is a picture of anybody's board. It draws the graph rather than regions, and that was not the first idea. The first idea was Voronoi cells -- every point belonging to the nearest province -- which makes a handsome cut-paper board and is wrong. Sixty-five pairs that border each other in the rules came out with regions that did not touch, and no amount of moving coordinates fixes it: provinces here interleave. The Adriatic borders Venice with Trieste between their centres; the Atlantic borders North Africa around the outside of Spain. Convex cells cannot say that. A map that shows two regions meeting when the rules say otherwise is worse than an ugly map -- it is a map that loses you the game. The tests found three provinces drawn on top of each other and a distance check of mine that was measuring Europe rather than checking my typing: it failed fifteen honest placings because oceans are large and Moscow borders five things. The exact check is that a line exists for every border in the rules and for no others. The viewBox is fitted to what is actually drawn. Europe is not rectangular, and the box the coordinates were typed into left a third of the frame as empty ocean -- which wastes the one thing this game was given more of than the others. |
||
|
|
efbecf6425 |
Bots that open the conversation
A bot that only answers is not negotiating, it is a form to fill in. propose() works from the plan the power has already made: what it wants this turn, where that will not work alone, and who could make it work. Help taking something defended first, then a quiet border over ground neither of them owns, then peace when a neighbour is over your centres and your ambitions are elsewhere. Three a turn at most, or six powers talking at once is a mailstorm. Each overture carries what the power says, so it reaches a human as a message rather than as a form. A power will offer a quiet border to somebody it is attacking somewhere else, and that is on purpose. Marching on French Belgium while suggesting both sides leave Burgundy alone is not a lie and not incoherent -- a promise about Burgundy is a promise about Burgundy, and it will be kept to the letter by somebody robbing you at the same moment. A test asserted the opposite and the test was wrong: refusing that offer would be playing a politer game than this one. Asking the power you are attacking to help you, or offering it peace while your orders say otherwise, are different things and are both refused. Nothing here promises any of it will be kept. Whether the power still wants the deal when orders are due is settled in settleUp, and the answer is sometimes no. |
||
|
|
16d047ea81 |
The bots
A position is worth its centres, and almost nothing else: units are how you get them and are worth nothing in themselves. Every other term is a small correction on that one fact. Orders are a greedy plan taken in order of what is worth most, with a second unit put behind the first when the prize is worth two units -- a bot that never doubles up is not playing this game. Agreements are applied after the plan rather than as a constraint on it, on purpose: the plan has to know what it is giving up before it can decide whether the promise is worth keeping. Three things the tests taught it. It garrisons a threatened centre it is already standing on, because scoring only moves had it defending Berlin by marching the Munich garrison there. It never shoves at its own countryman, which has no strength and wastes two units. And the price of breaking a promise is how far it trusts the partner, not how far the partner trusts it -- the other way round gives a power that has been lied to four times a high cost of retaliating, because it has been scrupulous and is still well thought of, which is exactly backwards. Every decision comes back as a sentence. When a power turns on you it says what the province was worth and what it thought you were worth, because being betrayed should be infuriating rather than mysterious. |
||
|
|
9c09750d1e |
The press
Three things a power can offer, because these are the three that change a turn: support for a named move on a named turn, a demilitarised province, and peace. All concrete, all about a particular turn, all checkable by arithmetic against the orders actually submitted. A game where the machine decides by feel whether you kept your word is a game where being betrayed feels arbitrary rather than infuriating. Deals are judged on the orders given, never on how they turned out. A support that was ordered and cut was still given; a move that bounced was still attempted. Blaming a power for a bounce would make every alliance a lottery and every honest ally look like a liar. Contradictory promises are the mechanic rather than something to prevent. Promising a province to one power and supporting another into it is a double deal, and conflicts() exists so that a power can be shown it has promised two things it cannot both do -- at the moment of agreeing, deliberately. Peace covers the centres a power owns as well as the provinces it occupies. Walking into an undefended centre and calling it peace because nobody was home is the first thing anybody tries. A test asserted the wrong thing here and the comment above the code was promising more than the code did; the code now does what it said. Trust is directional and fades. A stranger starts above halfway, because a game where every stranger is a proven liar never gets started, and an old betrayal loses weight without leaving the ledger, so a broken alliance can re-form out of need. |
||
|
|
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. |
||
|
|
9a12b46bd1 |
Write down the six that do not pass
A known deviation nobody has written down is a bug waiting to be rediscovered, and a red mark nobody can explain is worse than a red mark with a reason next to it. |
||
|
|
44f75ebb5a |
133 of 136 movement cases
Four more rules, each one found by a case rather than by reasoning: A support may name a coast, and if it names one it has to be the right one. A fleet cannot convoy and support at the same time, so a support for a move that can only go by water is impossible when every route runs through the supporting fleet -- 6.D.31 calls that an impossibility for complex reasons and it is a fair description. A move over water is only an order if fleets have actually been ordered to carry it: Yorkshire to Holland with nobody in the North Sea is impossible in this position however possible it is in another. And moving to the province you are already in is not a move, with or without a convoy under it. The intent rule also settled something I had assumed the other way. Ordering your own fleet to convoy is how a power says it is going by sea, and that is the same signal that lets two units swap places instead of bouncing -- so it commits the army. Sinking the escort strands it rather than sending it walking overland. One of my own cases asserted the opposite and was wrong. Three cases are excluded rather than failed: 6.A.6, 6.B.10 and 6.B.11 state their setup in prose -- 'Germany has a fleet in London' -- and the fixture is built from order lines, so it cannot carry a unit nobody ordered. Six remain, and they are listed in the README rather than left to be rediscovered. |
||
|
|
6c388f5bc4 |
Convoy intent, coasts in support, and what a disrupted convoy is
122 of 139 movement cases now. Intent, which decides whether two units swapping bounce or sail past each other: an army goes by convoy if it was ordered to, or if its own power gave a legal convoy order for that move. Somebody else's fleets offering a route is not intent however good the route, and your own fleet offering from a sea it could never do it from is not intent either, because that was not an order. Once intent exists any ordered route may carry it, foreign or not. A convoy order is only an order if water could actually carry that army past that fleet, which is a question about the map and is now asked. Support is given to a province, not to a coast of one: a fleet in Marseilles may support an attack on the north coast of Spain although it could never sail there. And a support is only as legal as the move underneath it. Two bugs of my own. Convoy routing could not start from or arrive at a province with two coasts, because the fleet graph has no bare entry for one -- there is no 'bul', only 'bul/ec' and 'bul/sc' -- so an army boarding in Bulgaria found no sea and stayed home. And I had read 'disrupted' as the escort being sunk when it means the army not arriving; in Pandin's Paradox the fleet survives and the army still does not get there. |
||
|
|
c27e4cad81 |
Fix five hand-written cases built on an impossible order
Paris does not border Munich, so it can never support an attack on it. Five of my own cases were built on that support and the new validation pass refused it -- and three of them had been passing for the wrong reason, which is worse than failing. Every one of them now uses a supporter that could actually have made the move it is supporting. The Portugal case takes its support off the Mid-Atlantic, since Spain is the only land province that touches Portugal at all -- which is also why a unit dislodged there has nowhere to go. |
||
|
|
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. |
||
|
|
601b961c88 |
Retreats and the winter
Movement is the part everybody thinks about and it is not the part that decides the game. A beaten unit that finds somewhere to stand is a nuisance for years; one that does not is gone. And the winter is where a good spring turns into a bigger army, or does not. Four things are closed to a retreat: anywhere unreachable, anywhere occupied, the province the attacker came from, and any province two units bounced out of -- that last is the one people forget, since a bounce leaves a province empty and closed rather than empty and open. The exception is an attacker who arrived by convoy: it never marched through the ground between, so there is nothing to stop the loser falling back that way. Two units retreating to the same province destroy each other, there being no support in this phase and nothing to break the tie with. Ownership changes only in the autumn and only by standing on a centre. A centre you walked through in the spring is not yours; one you walked away from stays yours until somebody else stands on it, which is why a power with no units can still hold centres. Civil disorder removes what is furthest from home, fleets first, then alphabetically -- arbitrary in the last step on purpose, so that two adjudicators never disagree about a game nobody is playing. |
||
|
|
ec3b5143c7 |
The adjudicator
Kruijswijk's resolver: work each order out from the others, and when that turns out to be circular -- which it genuinely can be, this game has real paradoxes in it -- guess, check whether both guesses agree, and fall back to a stated rule when they do not. A ring of units all moving into each other all move. A convoy paradox is settled by Szykman's rule, which is a convention rather than a deduction and is written down as one. Four strengths do the work: attack, hold, defend and prevent. A move has to beat the right one of them strictly, so an unsupported attack never takes a supported province and a tie is always a bounce. Worth noting what falls out rather than being written down. A unit cannot drive out a countryman, so a move against one has attack strength zero, so it cuts no support -- which is why a power cannot cut its own support. That is a consequence of Calhamer's rule, not a separate one, and the comment says so where the zero is returned. Twenty-one cases, all written out in full so a reader can check them by hand. |
||
|
|
f4d60235ea |
Four endings, not two
A game of this ends in a solo, an elimination, a draw, or somebody else's solo, and none of those is a win or a loss in the shape the other games on this site use. The draw is the one that matters: it is the usual outcome and it is neither, so it cannot borrow either tune. |
||
|
|
f92330b552 |
Units, orders, and finding the water under an army
Convoy routing is breadth-first over the fleets actually ordered to convoy this army, so it returns the shortest chain and answers null rather than guessing. It takes a set of fleets to treat as already gone, which is what the adjudicator will need to ask whether a convoy survives being attacked. The tests found a wrong assumption of mine rather than a wrong line of code: taking the Channel out of a London to Brest convoy leaves no route at all. The North Sea does not touch the Mid-Atlantic on this board -- the long way round is over the top through the Norwegian Sea -- so the Channel is the whole western sea route. |
||
|
|
c5cd0a6351 |
The board, and what this game is going to be
Seventy-five provinces as two graphs, because an army and a fleet do not move on the same one, and three provinces whose two coasts do not connect. The topology is a fact about a published game and free to use; the artwork is not, and there is none here -- the map will be generated from this data the way the cave game's dodecahedron is. The name is a working one for the same reason the starship game is not called what you expect. The tests check the board against itself, and symmetry is the one that pays: it found the Skagerrak wired to the Baltic, which would have opened a back door into the Baltic and made Denmark worth nothing. |