Lucas Young
Original: 18 May 2023
I’ve been playing a lot of cribbage lately, and I lose more often than I would like. This left me with some questions:
What is the optimal way to play cribbage?
How often should I expect to lose if I’m playing optimally?
How often should I expect to get skunked if I’m playing optimally?
How often should I expect to get double-skunked if I’m playing optimally?
How do these numbers change if I’m not playing optimally?
To answer these questions, I wrote around 7,000 lines of code.
I first built a cribbage discard optimizer. If you’re interested, here’s a link:
https://lucasyoung.shinyapps.io/Cribbage-Discard-Optimizer/
To get the discard optimizer to run in a reasonable time frame, I analyzed all 6,175 numeric cribbage hands (ignoring suit) and stored the results in a look up table. Here are some overview numbers for all the numeric hands:
To visualize the loss of points for non-optimal discards, I simulated 10,000 hands and analyzed the expected point values for each potential discard of those hands. After being dealt 6 cards at the beginning of a hand, there are 15 ways to discard 2 of those cards. Each of those 15 discard sets can be ranked based on the expected points from the resulting hand and crib. For the purposes of this analysis, the most optimal discard set is ranked “1” and the least optimal discard set is ranked “15”. Here are the results:
Next, I taught my computer to play cribbage and simulated 270,000 games. To simplify the problem, I only considered hand and crib points, ignoring pegging all together. Based on some brief research, players get somewhere around 20 pegging points per game, so I had my simulated games play until a player broke 100 points rather than the usual 120.
For each set of simulated games, I assigned each player a skill level between 1 and 15. A player with skill level 1 always chooses the most optimal discard set. A player with skill level 15 always chooses the least optimal discard set. Matchups are denoted with the two skill levels separated by an underscore; “1_5” means player 1 is choosing the most optimal discard sets, and player 2 is choosing the 5th most optimal discard sets. I simulated 10,000 games for each matchup.
Thanks to the help of multi-threading, I could run a 10,000 game simulation in about 6 hours. The 270,000 games I simulated for this project took a total of around 162 hours… and yes, there were some perfect hands (29 points) in there.