Counting is the hard part
People assume the hard part of a card game is the cards. It is not. Shuffling a deck and dealing six of them took an afternoon. Scoring a cribbage hand the way a human being expects it to be scored took considerably longer, and it is the piece I have rewritten the most.
Here is the whole of it. Four cards in your hand, one starter card turned up, and every scoring combination is counted across all five — not four, and not each in isolation:
- Fifteens. Every subset that sums to fifteen is worth two. Every subset. Face cards count ten, so a hand full of tens and fives scores in ways that look like a bug.
- Pairs. Two points each, counted pairwise — which is why three of a kind is six and four of a kind is twelve, and why nobody should ever hard-code those two numbers.
- Runs. Three or more in sequence, one point per card, and every duplicate multiplies the whole run rather than adding to it.
- Flush. Four in hand is four; the starter only joins if it matches. The crib is stricter and needs all five.
- His nobs. One point for the jack matching the starter's suit, sitting on its own outside every other rule, because of course it does.
Where it goes wrong
Every one of those rules is simple. The trouble is that they interact, and the natural way to write each one — walk the cards, find the thing, add the points — produces a scorer that is right about ninety-five percent of hands and confidently wrong about the rest. The wrong five percent are the memorable ones. A player who has counted cribbage hands at a kitchen table for forty years will not file a bug report saying the run multiplier is off. They will say the game cheated them, and they will be right.
The runs are the usual culprit. A hand of 4-5-5-6 is not one run and a pair sitting next to each other; it is two runs of three, plus the pair, and the two runs are counted in full. Get that wrong and you are four points light on a hand that comes up constantly. Fifteens are the other one: it is tempting to stop at the first subset that works, and the whole point is that you must not.
What finally worked was refusing to be clever. Five cards is thirty-one non-empty subsets. That is a number a computer does not notice. So the scorer enumerates all of them, asks each subset the small dumb questions — do you sum to fifteen, are you a run, are you a pair — and adds up the answers. No special cases, no multipliers, no clever early exit. It is the slowest thing in the game and it is still faster than the animation of a peg moving one hole.
Proving it
The reason this is worth writing down is what it bought. Once scoring is a pure function from five cards to a number, you can test it against every hand that exists. Not a sample — all of them. The full space of five-card combinations from a fifty-two card deck is small enough to walk through end to end, so the test suite does exactly that and checks the total against the known distribution of cribbage hand scores. If a rule is wrong anywhere, it is wrong somewhere in that sweep, and the sweep runs in seconds.
That is the whole trick, and it is not really about cribbage. The rules were never the difficult part. Arranging them so I could prove they were right was.