Sunday, May 25, 2008

Blackjack

Been a while since an update, been busy, blah blah blah...

Now with that out of the way, Blackjack!

I decided to write a Blackjack game tonight. I've been thinking about it for a while. The real reason for the game is to create an AI for Blackjack which counts cards (tactic used to take advantage of the game). I wanted to see how much I could get done in a single night, starting from scratch.

In just 90 minutes, I have the following classes:

Player
Card
Deck

Player and Card are trivial. Player currently only keeps track of the money they have to bet as well as the running total of their current hand. Card has an enum for the Suit of the card. It contains a function to print out the name of the Suit (instead of just the 0,1,2,3), as well as a number holding the face value. Note that I don't care about the rules of Blackjack within the Card class which pertain to the value of each card, I follow the standard of 4 suits that hold cards valued 1-13. 4x13 = 52.

Deck is where the fun happens! A Deck object has an array of 52 Cards. Basically, a Deck is an array of 52 Cards, but you get the point. The Deck of Cards gets populated by the default CTOR using a nested for-loop. It's pretty straightforward beings that enums are treated as integers, so increasing the Suit is as simple as incrementing a counter, and the same of course goes for the face value of each card.

The fun stuff comes in when you realize you need to shuffle the deck. For the sake of brevity and getting something "quick and dirty" working, I implemented a really terrible swap mechanism. It's so terrible. Wow, is it bad. Well, O.K, it's not that bad... Here's how it currently works:

1. I maintain a list of available positions. Initially the values 0-51 appear in this list.
2. I loop over the Deck of Cards and I first save the current element in a temporary Card object.
3. Inside a do-while structure I generate a random number between 0-51 and then call a search function I wrote which iterates through my list of available positions.
4. If the number is found in the list, that means it's available for swapping. The return value is set and that number is removed from the list. If it isn't found, the do-while generates another value and tries again.
5. With the available position in hand, we swap the current Card with that in the position of the random number we generated.
6. Now, we place our temp Card object into the position of the element we just swapped (the one in the random number position of the Deck array)
7. All done, we've "swapped" one Card, now we do it again for the next card.

See, isn't that awful? Oh well, it works, and it will get better. So, basically I've got all of the basic mechanics for a card game working, whether it be Blackjack or anything else. Now I can focus on (fixing the above "problems" and...) implementing the Blackjack logic.

This just goes to show how much work you can get done in a very short period of time if you sit down and really focus. Of course, I had been thinking about the basics of how to develop this type of system, and I think that's a big reason I was able to flesh this out so quickly, but it was more about focusing on a task and just "doing it". That's the reason why I wasn't too concerned with how terrible of a Shuffle mechanism I was implementing. I knew it would work, albeit contrived and inefficient, but that's the key: Get it working, and then get it better.

I'll try to update this more now that Summer is here, but I will be busy with Google Summer of Code, so don't hold me to that. Cheers.