Work the Shell - <emphasis>Baccarat Punto Banco</emphasis>, Part II

Remember that Baccarat hands can't go to 11 or even 10 for that matter.

Last month, we visited the rarefied climes of the expensive private player rooms at Monte Carlo to learn about the elite gambling game Baccarat. The game is straightforward, but it's governed by a fairly complicated set of rules.

At its most rudimentary though, Baccarat has two players: a Banker and a Player, and each is dealt two cards, the rank of which are summed up to calculate the winning hand.

Any hand worth 10 or more is divided by 10, so a 9 + 6 isn't 15, but 5, and a hand of 3 + 4 = 7 would indeed beat it.

It gets complicated in the case of whether the Banker should draw a third card. The Player can draw one card only on any two-card point value of less than six, but the Banker can draw based only on the Player's initial hand, the card the Player drew and the Banker's hand value. It works like this:

  1. If the Player didn't draw a card, the Banker draws a card on 0–5 and stands otherwise.

  2. If the Player drew a 2 or 3 and the Banker has a total of 0–4, the Banker draws a card.

  3. If the Player drew a 4 or 5 and the Banker has a total of 0–5, the Banker draws a card.

  4. If the Player drew a 6 or 7 and the Banker has a total of 0–6, the Banker draws a card.

  5. If the Player drew an 8 and the Banker has a total of 0–2, the Banker draws a card.

  6. If the Player drew a 9, 10, face card or ace and the Banker has a total of 0–3, the Banker draws a card.

In all situations not detailed above, the Banker cannot draw a card, and the Baccarat hand will end either with the Player winning, the Banker wining or an égalité, or tie.

As you can see, it's a set of rules that apparently could be loved only by a computer programmer, so it looks perfect for us to expand the game in this direction.

On to the Script

Last month's Baccarat game took everything into account up to, but not including, the Banker picking a third card, with all the complicated rules detailed above.

Running it as is, here's a typical sequence:

$ sh 

Welcome to Baccarat. You can choose to either 
stake the player or dealer to win this game. 
Remember, face cards are worthless and all point values
are modulo 10, with '9' the best possible hand value. 
We're using Punto Banco rules with this simulation, 
if you're already an expert...

** Player was dealt: 3 of Hearts, 10 of Clubs (hand value = 3)
** Dealer was dealt: 4 of Clubs, 10 of Spades (hand value = 4)

Player takes a card: 6 of Hearts (hand value = 12)

** Banker play rules yet to ends inconclusively.

As you can see, instead of capturing the rules, I just have a “coming soon” stub. Think of it as, um, early alpha so far.

In fact, it's sufficiently in alpha that there's a bug displayed in the above sequence. Can you see it? How can the Player have a hand value of 12?

Fortunately, it's straightforward to see the problem:

playerhandvalue=$(( $playerhandvalue + 
    $handvalue ))

This is just plain wrong. Because the line above hands all three Player cards to the handValue function, all this needs to be is the simpler:


Phew. Easily fixed. Now, where were we?

One thing that we need to ascertain easily is whether the Player took a card. This can be done by actually testing the number of cards in the Player hand, but instead I simply create a new variable, playerDrewCard, setting it to zero on initial deal and flipping it to one if the Player takes another card.

Now, the first rule can be captured like this:

if [ $playerDrewCard -eq 0 ] ; then
  if [ $bankerhandvalue -lt 6 ] ; then
    # Banker draws a card

    handValue ${banker[1]} ${banker[2]}

    echo -n "Banker takes a card: "
    showCard ${banker[$nextbankercard]}
    echo "$cardname (hand value = 

Notice here that if the Player drew a card and the Banker's hand is worth six or more, there is no else clause, and correctly, there is no additional action before the end-game winner is determined.

The else at the bottom, however, is our gateway to the situation where neither the Banker nor Player has an 8 or 9 (which is already captured in the game) and where the Player took another card. Now, it's just a set of conditionals.

To make things easy though, let's have the Player's drawn card's rank handy:

pdcRank=$(( ${player[3]} % 13 ))

Unfortunately, although the man page for test indicates that you can group complicated tests logically with parentheses, pragmatic reality demonstrates that it's far less portable than we might desire, so instead of a nice (A or B) and C statement, we'll break each rule into two if statements, like this:

if [ $pdcRank -eq 2 -o $pdcRank -eq 3 ] ; then
  if [ $bankerhandvalue -lt 5 ]; then

In this case, we're testing the card the Player took (card #3) and testing that the Banker's hand is below a certain value. If both are true, we have condition #2, above.

Now, it's just a matter of having a sequence of these tests in a row to build all the rules necessary for Punto Banco Baccarat.

In all its crazy-nested-if-statement glory:

if [ $pdcRank -eq 2 -o $pdcRank -eq 3 ] ; then
    if [ $bankerhandvalue -lt 5 ]; then
  elif [ $pdcRank -eq 4 -o $pdcRank -eq 5 ] ; then
    if [ $bankerhandvalue -lt 6 ] ; then
  elif [ $pdcRank -eq 6 -o $pdcRank -eq 7 ] ; then
    if [ $bankerhandvalue -lt 7 ] ; then
  elif [ $pdcRank -eq 8 -a $bankerhandvalue -lt 3 ]
  elif [ $pdcRank -eq 9 -o $pdcRank -eq 0 ] ; then
    if [ $bankerhandvalue -lt 4 ] ; then

Finally, we can play Baccarat on our handy Linux box:

> sh 

Welcome to Baccarat. You can choose to either stake 
the player or banker to win this game. Remember, face 
cards are worthless and all point values are modulo 10, 
with '9' the best possible hand value. We're using Punto
Banco rules with this simulation, if you're already an expert...

** Player was dealt: 6 of Clubs, 8 of Hearts (hand value = 4)
** Banker was dealt: King of Spades, Ace of Hearts (hand value = 1)

Player takes a card: 9 of Hearts (hand value = 3)
Banker takes a card: 5 of Clubs (hand value = 6)

Play is complete. Banker wins

Of course, now you can run this a few million times and calculate the odds of the Banker winning versus the Player winning versus the tie situation and be a cool, calculated gambler next time you're in the south of France. Helpful, eh?


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

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState