In the grammar in figure 1, italicized names are non-terminals, text starting with a semi-colon is a comment about the grammar (i.e., not part of the grammar), and other non-italicized text is literal. Ellipses indicate zero or more repetitions of the preceding non-terminal. Extra whitespace may appear between any parenthesis, non-terminal, and other literal sequence (but not in the middle of a literal sequence that contains no parentheses).
Each player program runs as a process that receives notifications from its stdin and sometimes writes plays to its stdout. Each player is either in wait or move mode, starting out in wait mode:
When a player receives a (move state) message, then it shifts to move mode and replies with a play; if the play is (clean) or (clean card), then the player shifts to wait mode; otherwise, the player receives another (move state) message and continues its turn in move mode.
When a player receives a (moved name play) message, then it stays in the wait mode without sending a reply.
For the most part, the constraints on plays should be clear based on the game rules. To clarify, here are some specific constraints:
(act mine treasure treasure) —
The state must have a actions value of 1 or more, the first treasure must be in the hand part of state, the second treasure must be in the supply, and the second treasure must have a cost no more than the first treasure’s value plus three.
(add treasure) —
The treasure card must be in the hand part of state, and its value is added to the number of available coins that can be used for a later buy in the same turn. No actions are allowed after this play; that is, the next (move state) message will include an actions value of zero.
(buy card) —
The state must have a buys value of 1 or more, and the cost of card must be no more than the coins values in state. No actions are allowed after this play.
(clean card) —
Ends a turn by moving all played cards and all hand cards to the discard pile. The Dominion rules specify that a player does not have to show hand cards as they are moved to the discard pile, except that one of the cards will be visible, and card is the card that is visible to other players. If the current state includes an empty hand, then end a turn with (clean), instead.
Ends a turn in the case that the current state includes an empty hand.
Whenever a player reports a legal play message, it is broadcast to all other players through a (moved name play) notification, where name indicates the player who moved. In principle, many parts of state report information that players could track on their own via notifications, but state provides a basically complete snapshot of the game to support simpler player programs. More to the point, state reflects the information that a game controller needs to drive the game (but the controller needs a separate instance of the player-specific information in state for each player).
For now, the following elements of Dominion have been omitted from the player protocol: curse cards and all kingdom cards except mine. Expect future versions of the protocol to add additional kingdom cards and other player states (to respond to player actions, such as militia).
((players name ...) ; in order, current first (supply card ...) (trash card ...) ; in order, top to bottom (actions number) ; actions remaining in turn (buys number) ; buys remaining in turn (coins number) ; coins available for buys (deck card ...) ; not in draw order (hand card ...) (plays card ...) (discards card ...)) card = treasure | victory | action treasure = copper | gold | silver victory = estate | duchy | province action = mine play = (act mine treasure treasure) | (add treasure) ; adds coins | (buy card) | (clean) ; ending a turn with an empty hand | (clean card) ; card in hand is exposed notification = (move state) | (moved name play) name = a sequence of letters number = a sequence of decimal digits