Cribbage: Calculating Hand Value

The last few months, we've been building a complex shell script to play elements of the game of Cribbage, demonstrating a variety of concepts and techniques as we proceed. That's all good, and last month, the script expanded to include a "shuffle" capability and the ability to deal out six cards, a typical two-player starting hand.

Cribbage tip: in a three-player game, each player gets five cards, and the extra is dealt directly into the "crib"—the extra hand counted after play by the dealer.

The challenge we're going to tackle this month is figuring out the best four cards to keep of those initial six, based on potential point values of the different hands. Ultimately, a fifth, "cut card", is turned up that everyone shares (somewhat akin to the shared cards in Texas Hold 'em), but smart Cribbage players seek to maximize the four they hold and celebrate when the fifth adds to the point value of the hand, rather than count on that cut card to make the hand.

So what's valuable in a Cribbage hand? Sequential runs of three or more cards, pairs or better of the same rank, having all the cards in your hand match suit (and possibly the cut card), combinations of card ranks that add up to 15, and having the jack of the same suit as is on the cut card.

Cards of the same rank—pairs or better—are tricky to count because the game works on combinations. So 5H, 5D is worth two points "for the pair", but 5H, 5D, 5S is worth six points, because it combines to three pairs: 5H+5D, 5H+5S and 5D+5S. Four of a kind? A sweet 12 points and a very rare combination indeed.

Critical to know: aces always are worth 1 when counting up fifteens, and all face cards are worth 10 points. So A+4+K is a fifteen, just as 9+6 is, though for pairs, it's the same rank, not just pairs of face cards. In other words, J+K is not a pair.

Where counting gets tricky is those combinations of fifteens. A great hand, for example, is 6S, 7H, 8D, 8S, which offers two points for 7H+8D, two points for 7H+8S, three points for 6S+7H+8D, another three points for 6S+7H+8S and a final two points for the pair 8D+8S—very nice. If the cut card is another 7 or, even better, another 8, you can see where there are a lot of points in that potential hand!

The challenge, of course, is doing all of this programmatically. When we left off the program last month, it could deal six cards to us and sort them in increasing rank order, which is helpful, particularly in recognizing runs.

Calculating All Four-Card Combinations

The first problem we have is actually earlier than anything to do with card values. It's to calculate all possible four-card combinations out of a six-card hand. It's combinatorics—something I really enjoyed back when I took that class in college for my CS degree.

What we're looking at is actually factorial math. So "six choose four" is really 6! minus 2!, which is generally written as shown in Figure 1, where n is the total number of cards, and m is the subset we want to choose. In this case, it's 6! / 4!(6! - 4!).

Figure 1. Equation for "Six Choose Four"

A factorial number is calculated as the multiple of all decreasing numbers, so 4! = 4 x 3 x 2 x 1, and 6! = 6 x 5 x 4 x 3 x 2 x 1. Of course, the "x 1" part is pointless, so we can skip it. 4! = 24 and 6! = 720, which means that we have 15 card combinations to check for points. (If we had only five cards dealt because it was a three- or four-person Cribbage game, we'd have only five combinations to evaluate instead.)

The question is, how do we figure out all 15 of those combinations easily? I mean, I could hard-code all 15 of them—it's only four digits per subset, after all—but that seems less interesting than trying to solve the more-general mathematical equation. And yes, I can see myself getting sidetracked as I proceed, but that's part of the fun of programming when you're not on a deadline, right?

Um, never mind. Let's just take as a given that for six-choose-four, there are these specific combinations and no more: {1,2,3,4}, {1,2,3,5}, {1,2,3,6}, {1,2,4,5}, {1,2,4,6}, {1,2,5,6}, {1,3,4,5}, {1,3,4,6}, {1,3,5,6}, {1,4,5,6}, {2,3,4,5}, {2,3,4,6}, {2,3,5,6}, {2,4,5,6} and {3,4,5,6}.

If we're working with five-choose-four, the combinations are {a,b,c,d}, {a,b,c,e}, {a,b,d,e}, {a,c,d,e} and {b,c,d,e}.

The easy way to code this is as an array of arrays. Let's do it this way:


# six choose four
sixfour[0]="0 1 2 3";  sixfour[1]="0 1 2 4"
sixfour[2]="0 1 2 5";  sixfour[3]="0 1 3 4"
sixfour[4]="0 1 3 5";  sixfour[5]="0 1 4 5"
sixfour[6]="0 2 3 4";  sixfour[7]="0 2 3 5"
sixfour[8]="0 2 4 5";  sixfour[9]="0 3 4 5"
sixfour[10]="1 2 3 4"; sixfour[11]="1 2 3 5"
sixfour[12]="1 2 4 5"; sixfour[13]="1 3 4 5"
sixfour[14]="2 3 4 5"

If you're paying close attention to the script we've been creating, you know that our hand is indexed starting at 0, so the card values are 0–5 instead. That's easily fixed by shifting every value down one in the predefined arrays.

Now it's just a matter of interpreting the different sixfour array values as a set of four cards to select, and here's how I do it:


for subhand in {0..14}
do
  /bin/echo -n "Subhand ${subhand}:"
  for thecard in ${sixfour[$subhand]}
  do
    showcard ${hand[$thecard]}
    /bin/echo -n "  $showcardvalue"
  done
  echo ""
done

The echo statements (remember -n prevents a carriage return being appended to the output) aren't important to the final code, but for this interim solution, you'll see how it works by me just tucking it into the end of the program, just after the code that deals, sorts and shows the full six-card hand:


Hand: AS, 5C, 7H, 8H, 9D, JS.
Subhand 0:  AS  5C  7H  8H
Subhand 1:  AS  5C  7H  9D
Subhand 2:  AS  5C  7H  JS
Subhand 3:  AS  5C  8H  9D
Subhand 4:  AS  5C  8H  JS
Subhand 5:  AS  5C  9D  JS
Subhand 6:  AS  7H  8H  9D
Subhand 7:  AS  7H  8H  JS
Subhand 8:  AS  7H  9D  JS
Subhand 9:  AS  8H  9D  JS
Subhand 10:  5C  7H  8H  9D
Subhand 11:  5C  7H  8H  JS
Subhand 12:  5C  7H  9D  JS
Subhand 13:  5C  8H  9D  JS
Subhand 14:  7H  8H  9D  JS

That's a lot of four-card hands, but at least we've got them. Next month, we'll actually start writing the code to evaluate hand values. Stay tuned!

______________________

Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

There is something exotic

sollen's picture

There is something exotic about the traffic lights that "know" you are there -- the instant you pull up, they change 60W 12V LED SUV driving Light How do they detect your presence?

++++

cnbestmall's picture

++++ http://www.cnbestmall.com ++++

Accept Paypal and Credit Card, FREE SHIPPING

Nike AIr max, Shox, Rift, dunk, blazer, air force 1 shoes: 48 USD

Nike free running shoes: 42 USD

D&G, LV, Gucci, parda DC, polo, puma, supra shoes: 42 USD.

Timberland boot: 50 USD

T-shirts (polo, ed hardy, lacoste,gucci, lv, etc) $28

Jeans (AF, armani, bape, BBC, CA, coogi, D&G, Diesel, Evisu, Levis, gucci, true religion, versace) 45 USD

Down Coat jacket parka vests (moncler, canada goose, barbour, parajumpers, woolrich) 168 USD-268 USD

++++ http://www.cnbestmall.com ++++

Cribage

Carling's picture

I can't wait to give your gribbage a run, It's the only card game that I miss so much, M$ used to have Cribage, I played that for years until they droped it for no good reason, I look forwards to playing it again, thank you

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix