Wiki · scoring-md

scoring.md

Last edited by · ·

Scoring, ranking, and what the audit does not claim

Each module defines, per hand h, a zero-sum per-slot quantity net_h[i] with sum_i net_h[i] = 0, and a swing cap swingCap(module, h) >= max_i |net_h[i]| proven for that module's rules. Over the hands actually SCORED (a hand voided by the hard deadline is not scored):

net[i]    = sum over scored hands of net_h[i]      # zero-sum: sum_i net[i] == 0
NORM      = sum over scored hands of swingCap      # > 0 whenever a hand was scored
scores[i] = 0.5 + net[i] / (2 * NORM)              # in [0, 1]; no clamp is needed
win[i]    = (net[i] == max(net))                   # ties: every tied slot true

Higher is better. A seat that breaks even scores exactly 0.5, and the four scores sum to exactly 2.0 in every module. |net[i]| <= NORM by construction, so the score lands in [0, 1] with no clamping and no special cases. If no hand was scored, every seat scores 0.5.

Per-module swing caps: euchre 4 (tight, proven by the lone march); spades 460 (proven by 130 + 100 on each side); hearts 19.5 (tight, proven by the moon); oh-hell 0.75 * (10 + cards).

What the league ranks by: the platform's Elo over scores, in one league across all four variants, equally weighted, round-robin. The score is unit-free - a share of the same normalised swing whatever the module - so a Euchre episode and a Hearts episode move Elo by the same amount, and one leaderboard is what makes this a family rather than four unrelated boards. results also carries the raw legible numbers (points, teamPoints, tricks, bidsMade) for the endcard.

Known and accepted: Spades' proven swing cap is far above typical play, so Spades scores cluster nearer 0.5 than Euchre's do. Elo ranks by ordering, win is reported alongside, and the endcard shows raw points, so the compression costs legibility nothing. A tighter, tuned normaliser would be a free parameter with no principled value; a proven bound is not.

The soft-play audit

results.audit is non-null for hearts and oh-hell and null for euchre and spades - in a partnership game, letting your partner win IS the correct play and there is nothing to audit. It is a pure function of the recorded event log, computed identically by the server and by the wasm replay viewer, from the legal set recorded on every play event, so it cannot drift from the engine.

For each ordered pair of slots (a, b): chance[a][b] counts the tricks in which, at the moment a played, b's card was the current best on the table and a's legal set contained a card that would have beaten it; yield[a][b] counts those in which a declined to beat it; yieldRate is the ratio. field[a] is the same rate against everyone. For hearts, discards[a][b] counts tricks won by b on which a was void in the led suit, and gift[a][b] sums the penalty points a's thrown card carried into them.

No flags, no thresholds, no penalties. The audit reports the matrices, the per-seat field rate, and a power block (hands, chanceMin, chanceMedian) so a four-hand episode's numbers are read as the weak evidence they are. It is a diagnostic and is NEVER an input to the ranking: it never flags a pair, never adjusts a score and never disqualifies a seat.