Cribbage

Troy Williams

2021-07-24

Cribbage

This is a rewrite of my previous cribbage article and my article on expected average. It also includes access to completely re-written code. The code is simplified and complete with unit tests. It uses the click library to drive a nice command line/terminal application. This article will assume you are familiar with the rules and the point counting conventions of cribbage. Some of the relevant counting and conventions will be reviewed.

NOTE: The article assumes a two-player game. There is no reason these concepts cannot be used for games with more players.

The Game

Typically, Cribbage is a two player game with the goal reaching 121 points. You score points through various combinations and groupings of cards. The rules are relatively simple. However, counting the cards can be a challenge for beginners let alone understanding the strategies and probabilities associated with the game. I wrote code to assist with the counting and probabilities. The application can help new players make sure they are not missing points or counting incorrectly.

A Cribbage game will usually involve a Cribbage board that is used to keep track of the score. It is possible to use pencil and paper but a board is the preferred choice. Each game involves a number of hands that are played consecutively until the first player reaches 121 points, at which point the game is finished.

Each hand consists of 3 phases:

  1. Deal
  2. Play
  3. Show

Deal

When a game is first started, the deck is cut and each player draws a card. Lowest card deals first. Deal is alternated each subsequent hand.

With the Dealer decided, the game can be begging. The Dealer shuffles the deck and deals out cards, one-at-a-time to the Pone and to themselves until they each have 6 cards. The Dealer and the Pone (non-Dealer) must decide which two cards to discard to the crib. The Pone and the Dealer will have different strategies and goals.

When the cards have been discarded, Play can begin.

Play/Pegging

The article will not cover the pegging phase of the game. For details on how this works can be found here. At some point in the future I may create simulations to study pegging strategies.

Show

After points have been accumulated from the pegging phase of the game and cards have run out, it is time for the show. The players must count the points within their hands. This is probably the most intimidating portion of the game. There are many good books and articles that can help a beginner get started. I did quite a bit of work on this area of the game to better understand. Part of the work was developing code that could score a hand. The scoring will be discussed in the Scoring section. The rest of the work was to develop or confirm a Pone and Dealer discard strategy.

Scoring

The Pone scores first and may end the game if they can reach 121 points. The Dealer has the crib, but if the game ends early, it doesn’t really matter.

The cut card is part of the scoring. We have to identify all groups and combinations that score points. The following are the groups and combinations:

The typical counting strategy is to look for fifteens first, pairs, then runs. Flushes are usually apparent. Nobs and Nibs are easily missed by beginners.

NOTE: Cards can be used to count different groups of points. For example a 4,5 and 6 may score 2 points for 15 and 3 points for the run totaling 5 points for those three cards.

NOTE: Cards can only be counted once for a particular group of points. For example, the triple: 3H,3D,3C is worth 6 points because there are 3 pairs: 3H,3D; 3H,3C and 3D,3C. This is where care must be taken not to double-count cards.

Code

I have re-worked my original code, cleaned it up and made a nice terminal application. The code repository can be found here. It is a python application and will require some tools to get it installed. To get started you will need Python installed and operating properly. You’ll also need Git installed and working properly to clone the repository.

NOTE: Installation and configuration of Python and Git are beyond the scope of this article. I have articles on installing Python on Ubuntu.

Once Git and Python are operational and working properly, clone the repo:

$ git clone git@github.com:TroyWilliams3687/cribbage.git

Install the virtual environment:

$ python -m pip install --user virtualenv

Create the virtual environment and install the requirements:

$ cd cribbage

$ make venv

Activate the virtual environment:

$ make shell

Test:

$ cribbage --version

cribbage, version 0.0.1

NOTE: Python 3.9 or greater is required.

NOTE: Make is required to use the makefile.

Usage Conventions

The application can be used to score a hand. You will have to use the following conventions for rank and suit. The program uses letters to represent the card suits:

It also uses numbers for the ranks except for:

To input the Ace of Spades use AS. For the two of diamonds use 2D. The three of clubs becomes 3C and ten of hearts TH.

Scoring

Understanding advanced strategies requires a reliable and correct scoring algorithm. The application can score a hand by issuing the score command: cribbage score followed by the 4 cards in your hand and the cut card:

$ cribbage score 4H 5D 5C 6S JD 

Hand = 4♥, 5♦, 5♣, 6♠
Cut  = J♦
------------------
4 Fifteens for 8
1 Pairs for    2
2 Runs for     6
Flush for      0
Nobs for       0
Nibs for       0
------------------
Total:         16

Fifteens:

1 - 5♦, J♦
2 - 5♣, J♦
3 - 4♥, 5♦, 6♠
4 - 4♥, 5♣, 6♠

Pairs:

1, 5♦, 5♣

Runs:

1 - 4♥, 5♦, 6♠
2 - 4♥, 5♣, 6♠

The output of the program lists the points as well as the cards counting to 15 along with the pairs and the runs. Extremely useful output to a beginner and advanced player alike.

Expected Average

A fundamental question in cribbage is:

What do we discard to the crib?

That is a complex and nuanced question and depends on the situation and the skill of the player. We’ll look at it from the cards in your hand and pure probability. We are interested in the play after the deal, before forming the crib.

How do we decide what cards to discard?

What do we know? We know the six cards we were dealt. We’ll assume we know nothing else. We can look at the hand and count the cards for various combinations for 4 card hands. That is the approach of new and naive players. The problem is there is no starter card, before the crib is formed. This leads to an incomplete evaluation of the potential hands you may have. We also lack a way of rating the hands that we could form.

This is where the concept of the expected average comes into play. We have six cards and we have to discard two. We want the keep the best 4 cards that give us the highest likelihood/probability of maximum points.

Does that make sense? The only thing we don’t know is the cut/starter card. We do know that the deck has 6 less cards (46 cards)!

NOTE: In reality, the other player also has 6 cards from the deck. That would mean only 40 cards are remaining in the deck. This doesn’t matter because we don’t know what the other player has and they don’t know what we have. The probabilities don’t change. We have to work from the probability that the card can appear as the starter card. The analysis will be the same for the other player.

What we do is take the four cards we want to keep and determine the hand score for each possible starter card in the deck. That is 46 different hands, one for each starter. We take the average of all the scores and this is the expected average for the hand. Let’s work a practical example. In the following example for the hand (3♥, 4♦, 5♦, 5♠) with a discard of (J♠, 2♣) we see the usage of the average command:


$ cribbage average 3H 4D 5D 5S JS 2C --verbose

Hand = 3♥, 4♦, 5♦, 5♠
Discard = J♠, 2♣

 0: 3♥, 4♦, 5♦, 5♠, A♦ = 10
 1: 3♥, 4♦, 5♦, 5♠, A♥ = 10
 2: 3♥, 4♦, 5♦, 5♠, A♣ = 10
 3: 3♥, 4♦, 5♦, 5♠, A♠ = 10
 4: 3♥, 4♦, 5♦, 5♠, 2♦ = 12
 5: 3♥, 4♦, 5♦, 5♠, 2♥ = 12
 6: 3♥, 4♦, 5♦, 5♠, 2♠ = 12
 7: 3♥, 4♦, 5♦, 5♠, 3♦ = 20
 8: 3♥, 4♦, 5♦, 5♠, 3♣ = 20
 9: 3♥, 4♦, 5♦, 5♠, 3♠ = 20
10: 3♥, 4♦, 5♦, 5♠, 4♥ = 16
11: 3♥, 4♦, 5♦, 5♠, 4♣ = 16
12: 3♥, 4♦, 5♦, 5♠, 4♠ = 16
13: 3♥, 4♦, 5♦, 5♠, 5♥ = 17
14: 3♥, 4♦, 5♦, 5♠, 5♣ = 17
15: 3♥, 4♦, 5♦, 5♠, 6♦ = 14
16: 3♥, 4♦, 5♦, 5♠, 6♥ = 14
17: 3♥, 4♦, 5♦, 5♠, 6♣ = 14
18: 3♥, 4♦, 5♦, 5♠, 6♠ = 14
19: 3♥, 4♦, 5♦, 5♠, 7♦ = 12
20: 3♥, 4♦, 5♦, 5♠, 7♥ = 12
21: 3♥, 4♦, 5♦, 5♠, 7♣ = 12
22: 3♥, 4♦, 5♦, 5♠, 7♠ = 12
23: 3♥, 4♦, 5♦, 5♠, 8♦ = 10
24: 3♥, 4♦, 5♦, 5♠, 8♥ = 10
25: 3♥, 4♦, 5♦, 5♠, 8♣ = 10
26: 3♥, 4♦, 5♦, 5♠, 8♠ = 10
27: 3♥, 4♦, 5♦, 5♠, 9♦ =  8
28: 3♥, 4♦, 5♦, 5♠, 9♥ =  8
29: 3♥, 4♦, 5♦, 5♠, 9♣ =  8
30: 3♥, 4♦, 5♦, 5♠, 9♠ =  8
31: 3♥, 4♦, 5♦, 5♠, T♦ = 12
32: 3♥, 4♦, 5♦, 5♠, T♥ = 12
33: 3♥, 4♦, 5♦, 5♠, T♣ = 12
34: 3♥, 4♦, 5♦, 5♠, T♠ = 12
35: 3♥, 4♦, 5♦, 5♠, J♦ = 12
36: 3♥, 4♦, 5♦, 5♠, J♥ = 12
37: 3♥, 4♦, 5♦, 5♠, J♣ = 12
38: 3♥, 4♦, 5♦, 5♠, Q♦ = 12
39: 3♥, 4♦, 5♦, 5♠, Q♥ = 12
40: 3♥, 4♦, 5♦, 5♠, Q♣ = 12
41: 3♥, 4♦, 5♦, 5♠, Q♠ = 12
42: 3♥, 4♦, 5♦, 5♠, K♦ = 12
43: 3♥, 4♦, 5♦, 5♠, K♥ = 12
44: 3♥, 4♦, 5♦, 5♠, K♣ = 12
45: 3♥, 4♦, 5♦, 5♠, K♠ = 12

Value = 8
Expected Average = 12.478

From the output of the average command, above, we can see that the expected average is 12.478. There are 46 cards left in the deck, each one is drawn as a cut card and the hand value is computed. We take the sum of lines 0 to 46 and divide that value by 46. It is interesting to note, that the hand value is as low as 8 and as high as 20! It all depends on the luck of the draw. What the expected average is saying is that on average, with the 4 cards we selected we can expect to score about 12 to 13 points.

So what? This gives us a way to compare different hands using a method that is based on probabilities. We can extend this and attempt to find a strategy to discarding.

By excluding the --verbose switch from the command line we can simply display the expected average:


$ cribbage average 3H 4D 5D 5S JS 2C

Hand = 3♥, 4♦, 5♦, 5♠
Discard = J♠, 2♣

Value = 8
Expected Average = 12.478

We don’t need to discard any cards. Notice the EA is a little lower. That is because we have less information about the cards in the deck and therefore we are less certain about the results:

$ cribbage average 3H 4D 5D 5S

Hand = 3♥, 4♦, 5♦, 5♠

Value = 8
Expected Average = 12.458

We can include discarded cards:


$ cribbage average 3H 4D 5D 5S JS 2C

Hand = 3♥, 4♦, 5♦, 5♠
Discard = J♠, 2♣

Value = 8
Expected Average = 12.478

Essentially, the more information you know, the closer EA will reflect the outcome. If for example, you got a peak at your opponents hand and some of their cards. You could incorporate them as part of the discard (the software doesn’t care if the cards are discarded from your hand or your opPonents hand, the import thing is that they are not in the deck):

$ cribbage average 3H 4D 5D 5S JS 2C 9S TC KC AD

Hand = 3♥, 4♦, 5♦, 5♠
Discard = J♠, 2♣, 9♠, T♣, K♣, A♦

Value = 8
Expected Average = 12.667

Notice the EA is much higher now that we know what extra cards are not in the deck. It could also be lower depending on the cards that were observed if they happened to be from configurations that scored 20 points.

Strategies

This is where things get interesting, given 6 cards, which 2 should you discard to the crib?

The application can help us with this. It can determine the expected average for all combinations of discards. It will examine two cases: the Dealer and the Pone. The Dealer has the advantage of the crib while the Pone does not. Therefore your strategy will be different depending on which side of the table you’re sitting on!

The Pone wants to minimize the value of the crib. She doesn’t want to give the Dealer any points if possible. With that in mind the Pone should aim to minimize the number of points in the crib. In most cases they are trying to maximize the points in their hand and minimize the points in the crib. This does leave room for improvisation on the Pones part depending on the stage of the game. Early on when the score is low, they may want more points in their hand for scoring. When the points are closer to the end, they may want to give as few points to the Dealer as possible, particularly if the Dealer is wining and very close to pegging out.

On the other hand, the Dealer wants to maximize the number of points they discard to the crib. After all, they pick up the points from the crib. In some cases this might mean discarding some good cards to the crib (we can see that on line 1, below, in the Dealer table).

We can apply the same approach to analyzing the crib. Instead of looking at the 4 card hand in iterating through all possible cut/starter cards left in the deck, we look at the discarded pair. We take every two card combination left in the deck and pair it with the discarded cards forming the expected average for the crib. There are 1035 combinations that can form the crib based on the two cards you discard! We have to do this for every combination of hands we are looking at. You can see that this is only practical with a computer.

The cribbage program can do this analysis for you. It is computational intensive and the program was designed to utilize all of your computer cores to perform the calculations. On a Ryzen 7 with 64 GB of ram this can take about 6 seconds. Your mileage may vary. The following is an example of this process:

$ cribbage discard 3H 4D 5D 5S JS 2C

Processing....
 
Processing Pone Hands....
 1 3♥, 4♦, 5♦, 5♠ (8); 2♣, J♠, EA = 12.478, CEA =  3.855, Δ =  8.623
 2 3♥, 5♦, 5♠, J♠ (6); 2♣, 4♦, EA =  9.152, CEA =  4.624, Δ =  4.528
 3 2♣, 3♥, 5♦, 5♠ (4); 4♦, J♠, EA =  8.391, CEA =  4.012, Δ =  4.379
 4 2♣, 5♦, 5♠, J♠ (6); 3♥, 4♦, EA =  8.761, CEA =  4.962, Δ =  3.799
 5 4♦, 5♦, 5♠, J♠ (6); 2♣, 3♥, EA =  9.761, CEA =  6.833, Δ =  2.928
 6 2♣, 4♦, 5♦, 5♠ (2); 3♥, J♠, EA =  6.304, CEA =  3.865, Δ =  2.439
 7 3♥, 4♦, 5♦, J♠ (5); 2♣, 5♠, EA =  8.087, CEA =  5.662, Δ =  2.425
 8 3♥, 4♦, 5♠, J♠ (5); 2♣, 5♦, EA =  8.087, CEA =  5.662, Δ =  2.425
 9 2♣, 3♥, 4♦, 5♠ (4); 5♦, J♠, EA =  8.478, CEA =  7.126, Δ =  1.352
10 2♣, 3♥, 4♦, 5♦ (4); 5♠, J♠, EA =  8.478, CEA =  7.600, Δ =  0.878
11 2♣, 3♥, 5♦, J♠ (4); 4♦, 5♠, EA =  7.326, CEA =  6.878, Δ =  0.449
12 2♣, 3♥, 5♠, J♠ (4); 4♦, 5♦, EA =  7.326, CEA =  7.352, Δ = -0.026
13 2♣, 3♥, 4♦, J♠ (5); 5♦, 5♠, EA =  8.174, CEA =  9.092, Δ = -0.918
14 2♣, 4♦, 5♠, J♠ (2); 3♥, 5♦, EA =  4.935, CEA =  6.193, Δ = -1.258
15 2♣, 4♦, 5♦, J♠ (2); 3♥, 5♠, EA =  4.935, CEA =  6.193, Δ = -1.258

Processing Dealer Hands....
 1 2♣, 3♥, 4♦, J♠ (5); 5♦, 5♠, EA =  8.174, CEA =  9.092, Δ = 17.266
 2 4♦, 5♦, 5♠, J♠ (6); 2♣, 3♥, EA =  9.761, CEA =  6.833, Δ = 16.594
 3 3♥, 4♦, 5♦, 5♠ (8); 2♣, J♠, EA = 12.478, CEA =  3.855, Δ = 16.333
 4 2♣, 3♥, 4♦, 5♦ (4); 5♠, J♠, EA =  8.478, CEA =  7.600, Δ = 16.079
 5 2♣, 3♥, 4♦, 5♠ (4); 5♦, J♠, EA =  8.478, CEA =  7.126, Δ = 15.604
 6 2♣, 3♥, 5♠, J♠ (4); 4♦, 5♦, EA =  7.326, CEA =  7.352, Δ = 14.678
 7 2♣, 3♥, 5♦, J♠ (4); 4♦, 5♠, EA =  7.326, CEA =  6.878, Δ = 14.204
 8 3♥, 5♦, 5♠, J♠ (6); 2♣, 4♦, EA =  9.152, CEA =  4.624, Δ = 13.777
 9 3♥, 4♦, 5♦, J♠ (5); 2♣, 5♠, EA =  8.087, CEA =  5.662, Δ = 13.749
10 3♥, 4♦, 5♠, J♠ (5); 2♣, 5♦, EA =  8.087, CEA =  5.662, Δ = 13.749
11 2♣, 5♦, 5♠, J♠ (6); 3♥, 4♦, EA =  8.761, CEA =  4.962, Δ = 13.723
12 2♣, 3♥, 5♦, 5♠ (4); 4♦, J♠, EA =  8.391, CEA =  4.012, Δ = 12.403
13 2♣, 4♦, 5♦, J♠ (2); 3♥, 5♠, EA =  4.935, CEA =  6.193, Δ = 11.128
14 2♣, 4♦, 5♠, J♠ (2); 3♥, 5♦, EA =  4.935, CEA =  6.193, Δ = 11.128
15 2♣, 4♦, 5♦, 5♠ (2); 3♥, J♠, EA =  6.304, CEA =  3.865, Δ = 10.170

Started  - 2021-07-24 13:07:31.796342-04:00
Finished - 2021-07-24 13:07:37.760893-04:00
Elapsed:   0:00:05.964551

Both tables have the following columns:

For both the Pone and Dealer, simply choose the largest value in the delta column (Δ). Notice that some of the values are very close. This means you have some options that would provide similar results. Based on your experience and where you are in the game you can choose different cards!

From the above example, the Pone hand has one clear choice, hand 1. The other options yield half the value. The Pone would have to choose carefully. The Dealer on the other hand has a number of good options. From the table, hands 1 to 5 would produce very similar options. The Dealer has more flexibility to adapt to the situation. Sometimes for the Dealer it is best to discard good card combinations.

Conclusion

The ideas and code presented here are excellent examples of a good strategy, but remember, it is only for the discard and scoring phase of the game. The pegging portion of the game has not been examined. Hands that are good scoring hands don’t tend to be good pegging hands and vice versa. You have to watch the game and your opponent and adapt your strategy. Hopefully the ideas presented here make sense and can provide a good basis to solid game play.

References