Work the Shell - Calling All Functions, and Some Math Too!

Shuffle off to the next step in creating a shell script Blackjack game.

If you've been keeping track of my column, you'll know that we're building a
Blackjack game as a shell script. Why? Because most shell scripts are far
too boring to study without nodding off, so considering all the nuances of
shell script programming within the context of a game just sounds more fun!

My last column talked about how to shuffle a deck of cards, as portrayed in
a program with a simple array of 52 values, 1-52. There are
some interesting nuances to the shuffle problem. Let's start there.
Then we'll look at how to turn an arbitrary 1-52
value into a familiar rank and suite from a deck of cards.

The Shuffle Function

If you've been writing shell scripts since the
dawn of UNIX, you might not
have realized that modern shells now support functions and procedures, just
like a “real” programming language. For any block of code that you plan on
executing more than once, it's the way to go.

This builds an array called newdeck, which is actually the shuffled deck
(in the last column we showed deck, which was an array of cards in linear
order), and it uses some basic shell math with the $(( )) notation to
save spawning a subshell to invoke expr for each increment of the count
variable.

I said that shell scripts are robust programming environments and that might
be a tiny bit of hyperbole, really. Eagle-eyed readers will notice that the
pickCard function returns its value by setting a global variable,
picked, which isn't really optimal programming strategy. But it works, and
pragmatism is an important part of any good approach to software
development, isn't it?

Displaying cards as a numeric value from 1-52 is not the most friendly,
so let's turn our attention to the display of the card values in the
familiar rank and suite of a traditional deck of playing cards.

Math Games to Identify Rank and Suite

A deck of cards is composed of 52 cards, split evenly into four suites of
13 cards. The order of the suites doesn't matter (in
Blackjack, at least),
but the rank does. Indeed, the goal of the game is have a summary rank
value of 21 points without going any higher.

The rank of a card is the remainder of the numeric card value divided
by 13. In math terms, this is called the modulus and can be computed
thusly:

rank = cardvalue % 13

To put this into proper shell notation, we'll again use the $(( ))
shortcuts and end up with:

rank=$(( $card % 13 ))

Getting the suite should be simple too; it's the other half of the
division. In other words, if the card value is 17, then 17/13 = 1,
meaning it's suite #1, and 17%13 = 4. Since we'd like to have our suites
in the range of 1-4, rather than 0-3, however, we'll need to add one
to the equation. Further, the 13th of each card is the same suite as
the earlier 12, so we'll also have to subtract one before we do the
division (card #13 would be suite #1 if we just calculated 13/13, but
if we calculate 12/13 for that, we'll correctly identify it as part of
suite #0).

This is very confusing, so here's the equation instead:

suite="$(( ( ( $card - 1) / 13 ) + 1))"

Much clearer, right? Seriously, you can experimentally verify that
this works correctly. The important edge cases are value=1, value=12,
value=13 and value=14. If you can get those right, you're good for all
values in the deck.

Once we've identified the rank and suite of a card, we just have to do
a bit of fancy footwork to turn numbers into words:

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.

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.

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.