miaoda-game-spades-rules
v0.3.1
Published
Verified four-player partnership Spades rules with bidding, nil, legal play, bags, scoring, player views, and deterministic JSON state.
Maintainers
Readme
miaoda-game-spades-rules
Immutable, engine-neutral rules for four-player partnership Spades profile pagat-partnership-4p:
public bidding, legal trick play, Nil, contracts, bags, repeated hands, and target 500.
pnpm add miaoda-game-spades-rulesRun a game
import { applySpadesAction, createSpadesGame, createSpadesPlayerView } from 'miaoda-game-spades-rules';
let state = createSpadesGame({ playerIds: ['north', 'east', 'south', 'west'], seed: 2026 });
const playerId = state.activePlayerId;
const view = createSpadesPlayerView(state, playerId);
const tricks = view.legalActions.bidValues[3];
if (tricks !== undefined) {
const result = applySpadesAction(state, { type: 'bid', playerId, tricks });
if (result.ok) state = result.state;
}Opposite seats form teams 0 and 1. Bid 0 means Nil. Submit only listed bid values and play card ids;
UI and bots should not duplicate follow-suit, trump, contract, or bag calculations.
Public events
import { projectSpadesEvents } from 'miaoda-game-spades-rules';
if (result.ok) broadcast(projectSpadesEvents(result.events));The projector rebuilds and detaches bidding, play, trick, scoring, new-hand, and winner events. Nested team and Nil results are copied field by field. Unknown runtime event types throw.
Restore a snapshot
import { restoreSpadesState } from 'miaoda-game-spades-rules';
state = restoreSpadesState(JSON.parse(savedJson));Restore validates and detaches the authoritative snapshot. Use validateSpadesState for a
non-throwing result. Keep authoritative state on a trusted host and send clients only their
createSpadesPlayerView result plus projected public events; opponent hands remain private.
