Welcome to 476 Introduction High Level Design Program/Hardware Design Results Do Differently
 post update

Introduction Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @11:12PM
from the dept.
To some, BlackJack is merely a game. But, to Jeffrey Hantson and Benjamin Hysell, BlackJack is an obsession. As 18-year-old Cornell freshman they were among the first to discover the pure enjoyment and money-making potential of this basic card game at Turning Stone Resort and Casino. However, their innate ability to count cards led to their permanent removal from this Oneida Nation facility.

Unable to bring themselves to the game of BlackJack, Ben and Jeff were now forced to bring the game of BlackJack to them. They set up an underground BlackJack ring, which became a popular destination of Cornell students looking for a rush. This venture brought Ben and Jeff countless riches, but soon also brought them problems with the law. In a late night raid by campus police, 68 students were arrested and quickly turned on the two individuals who had brought them so much enjoyment.

In order to avoid jail time, Jeff Hantson and Benjamin Hysell agreed to forever stay away from the game of BlackJack. This lasted for a short eight months, until, when presented with the opportunity to design a system using a microcontroller, they quickly decided upon a BlackJack player. While they continue to hide this project from their parole officer, Ben and Jeff's brilliant design cannot be kept quiet for long, as it will be unleashed upon the world on April 29th, 2002.

The working project is a single-deck, single-player BlackJack game. The player has the ability to enter a bankroll at the start of game play, and can bet a variable amount of money on each hand. Throughout game play, the cards of both the player and the house are displayed to an LCD along with point totals.

The player has the option to hit, double down, and stand, and makes these choices through a keypad, while the house plays with standard Las Vegas style rules. At the conclusion of each hand, a winner is declared and the player's bankroll is updated accordingly.

High Level Design: The Statemachine
High Level Design Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @11:10PM
from the dept.
Our BlackJack player was implemented through a large state machine. The particular states are described below:

- bank_state - The user is given the ability to enter his/her bankroll for game play. This bankroll can be anywhere between $0 and $9999. The bankroll is stored in a signed, 16-bit variable, therefore, it has an upper bound of $32767. In order to prevent the user from entering a bankroll greater than this, it was limited to four digits, and thus an upper bound of $9999. Once a bankroll has been entered, the state machine moves to bet_state.

- bet_state - The user is given the ability to enter his/her bet for the individual hand. This bet can be anywhere between $0 and $9999. The bet is stored in a signed, 16-bit variable, therefore it has an upper bound of $32767. In order to prevent the user from entering a bet greater than this, it was limited to four digits, and thus an upper bound of $9999. Once a bet amount has been entered, the state machine moves to user_play_state.

- user_play_state - If there are less than 10 free cards remaining, the deck is reshuffled. Otherwise, four cards are dealt, two to each the user and the house. Both of the user's cards are displayed, along with his/her point total. One of the house's cards are displayed, along with this card's point value. Each hand is then checked to see whether a BlackJack has occurred. If a BlackJack has occurred, winner_state is entered. Otherwise, user_hit_state is entered.

- user_hit_state - The user is given the option to hit, stand, or double-down. If the user chooses to double-down, he/she is given one more card, his/her bet is doubled, and house_play_state is entered. If the user chooses to hit, he/she is given one card for each time he/she chooses to hit which is displayed and his/her point total is updated. If this point total surpasses 21, winner_state is entered. Otherwise, the state machine remains in user_hit_state until stand is chosen. If the player chooses to stand, house_play_state is entered.

- house_play_state - Upon entering this state, the house's other card is displayed and the point total is updated. Because Las Vegas-style rules are used, the house must hit on 16 and stand on 17. Therefore, cards are added to the house's hand until the total is greater than or equal to 17. If at any time the point total surpasses 21, winner_state is entered. Once the house is through hitting, winner_state is entered.

- winner_state - In this state, the user is told whether he/she won or lost. In the special cases of win/loss by bust or BlackJack, The user is informed at this time. The user's bankroll is updated accordingly. In order to prevent the bankroll from overflowing its range (-$32767 to +$32767)it is checked to see if it falls between +/-$25000. If it is outside this range, state game_over is entered and the game must be reset. If it is within this range, bet_state is entered and the next hand is begun.


Hardware Design: Atmels, Keypads, and LCDs oh My
Program/Hardware Design Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @11:09PM
from the dept.
The following parts were used in our design:

- Atmel AT90S8515 Microcontroller
- Varitronix MDLS16264-LV-Silver LCD
- 4x4 Keypad

The keypad and LCD were connected to the microcontroller via ports A and B, respectively. The wiring details can be seen in the schematic.


Program Design: Deck->Structure, Creation, Movement, Shuffling
Program/Hardware Design Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @11:06PM
from the dept.
Deck Structure
The 8515 and the STK500 development platform does not provide programmers with vast amounts of program memory. One needs to be mindful of these memory limitations while in the design phase of any project, and we took special note of our memory limitations before writing any code.

Each card is delimited by two characters, one to denote suit and the other for the face value. These two variables are grouped into a structure to denote one card. This allowed us to easily manipulate the card later in the program, the suit and face value would be found contained within one variable of struct Card.

To create the deck we created another structure named Deck containing an array of 52 card structures and an integer value named position. The array holds each of the 52 cards in a standard deck and position acts like a marker telling us where in the deck we currently are. By keeping track of our position in the deck we could deal cards in two easy steps:

1. Use position to reference into the card array (card[position]) and obtain the next card to deal.

2. Next increment position to know where in the array the next card is coming from, thus moving from position 0 to 52 dealing out cards.

Position provided us with excellent flexibility with our programming. Once cards were used they did not need to be removed from the deck structure to another ?discard? structure to be re-shuffled. Once position moved past a card in the array we would never run into that card again. Position also allowed us to tell how many cards were left in the deck, allowing us to set a limit on how many cards were played until the deck is re-shuffled.

Had we more memory to play with would would have been able to easily extend our program to more decks by changing two program parameters. We would need to change the number of cards held in the card array from 52 to how many decks we would need and change at what point we would need to re-shuffle. Currently once position reaches greater than 42 the deck is re-shuffled, we would only need to extend this to how many extra decks we would want.

Moving the Deck Around
The 8515 has very little stack space to pass variables between functions. We designed two functions to create and shuffle our deck, each taking in a Deck as described above. We could have created the deck as a global variable and automatically save stack space by not passing it between functions. However we anticipated creating multiple decks later on in our program and did not want to have our card creation and shuffling routines hard-coded to use just one global deck.

Thus, being limited by stack space our deck is passed between routines by just passing pointers to our deck. This would allow us to grow the number of decks in the program in two possible ways. One, we could create more Deck variables and pass them in one at a time to be created. Or two we could extend our deck by just increasing the number of cards the card array would hold to hold all of our cards and change a few loop parameters to accommodate the larger deck we planned for the future.

Creating the Deck
Deck creation is a rather easy affair with the structures we have designed. We use a for loop to loop through all 52 possible positions in our card array assigning the face and suit value to each card with the help of two helper arrays, face to hold the 2 through Ace and suit holding the four possible suits. For each card we index into the suit array with the current loop count and divide by 13, and similarly assign face by indexing into the face array and using the mod operator with 13. Although we use two rather expensive operations, mod and division, we only create the deck once in the beginning of the program and thus the time needed to complete this operation is transparent to the user as it is all done before the user begins to interact with the system.

Shuffling the cards became an interesting problem for us to overcome in the beginning of our design. We desired to keep all of the cards within one structure at all times and keep the movement of data to a minimum. Thus we needed a way to shuffle our cards in place of the deck and not use an extra structure. Our shuffle method iterates through the deck, stopping at each place of the deck, randomly selecting another position in the deck and swapping those two cards. The most difficult part of this routine is creating a random number. We were able to find the rand() function within the C manual and during development we were able to have a shuffled deck. Although rand() produces the same random variable every time it is called this allowed for easier debugging as we could expect the same cards to appear every time we played and could debug other issues in the system. Once the system was fully operational our last task was to make the system truly random. This was accomplished by seeding the rand() function, using srand(). The difficulty then became what to use as a seed to srand(). Our solution was to use TCNT1 from timer 1. We were able to turn on timer 1 and allow it to continuously count up and reset. Therefore by accessing TCNT1 we were provided with a different value every time we started the program. TCNT1 is accessed at a different time every time the program is run as the cards are not shuffled until the user enters how large their bankroll is and we run out of cards.

Program Design: Bankroll and Bet
Program/Hardware Design Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @11:04PM
from the dept.
The user was given the ability to enter a bankroll upon entering the BlackJack player, and enter a bet amount at the beginning of each hand. This interaction was provided by way of a 4x4 keypad. In order to decode the keypad, port A of the AT90S8515 microcontroller was connected to the keypad with pin 0 connected to pin 1 of the keypad, pin 1 connected to pin 2 of the keypad, and so on.

Then using an interrupt driven by timer 0, the keypad was scanned every 50 msec using the following scheme consisting of two separate tests. First, pins 0-3 of port A are set as low outputs, pins 4-7 of port A are set as inputs with their pull-up resistors turned on, and pins 4-7 are read. Therefore, the pin connected to the row of the button pushed will read a low value. Second, pins 4-7 of port A are set as low outputs, pins 0-3 of port A are set as inputs with their pull-up resistors turned on, and pins 0-3 are read. Therefore, the pin connected to the column of the button pushed will read a low value. The values are then or-ed together and a look-up table is used to determine which key was pressed.

As each key is pushed, it must be debounced. A state machine is used in which the button must be at a pressed voltage level for 2 scans (100 msec) in order to be registered, and must be released before it is registered again. Buttons 0 through 9 and, and A and C are valid buttons. Buttons 0 through 9 are used to enter a value for the bankroll or bet amount. As each button is registered, a variable called digitsEntered is incremented. When digitsEntered reaches 4, a full value has been entered and this value will remain unless cleared. As each value is entered, it is written back to the LCD, so that the user can see what they have entered. Button A is used by the user to verify the value they have entered. The state machine will not move to the next state and the value entered will not be stored until button A has been pressed. Button C allows the user to clear the value they have entered.


Program Design: LCD Display
Program/Hardware Design Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @11:02PM
from the dept.
Depending on what state the BlackJack player is in, the LCD will display different things. What is displayed in each state is summarized below.


The LCD appears with no value in the bank until one is entered by the user. As the user enters digits on the keypad, they are displayed on the LCD.


The bankroll is displayed, so the user can choose how much to bet. If the user just came from bank_state, the value he/she entered will appear (or 0 if nothing was entered). If the user just came from winner_state, his/her updated bankroll will appear. As the user enters his/her bet amount it will be displayed on the LCD.


User Cards User Total
House Card Preliminary House Total

The user's two cards are displayed along with his/her total number of points. The house's first card is displayed along with this card's point value.


User Cards User Total
House Card Preliminary House Total

Those cards and values displayed in user_play_state are updated with each additional card requested by the user. If at any point the user's total surpasses 21, the house's card is replaced with "BUSTED".


House Cards House Total
User Cards User Total

The user line and house line are swapped with all house cards and the actual house total displayed. If at any point the house's total surpasses 21, the user's cards are replaced with "BUSTED".

In the case of a BlackJack, the loser's hand is replaced by "Blackjack", and the winner's hand and point total are displayed. If no BlackJack occurs, the top line informs the user of whether or not he/she has won. If the user wins, the top line displays "YOU WIN!!!". If the user loses, the top line displays "YOU LOSE!!!".


Game Over
Press Reset

In the event that the user's bankroll falls outside of the bounds (-$25000 to +$25000), the user is informed that the game is over and that he/she must press reset.

Results Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @10:59PM
from the dept.
In the end, we were very happy with the operation of our BlackJack player. We allowed the player to enter his own bankroll and bet amount, without causing an error in our system. We were able to produce a random deck of cards at the beginning of each game and when the amount of free cards reached a significantly low level.

The house operates just as it would in Las Vegas, hitting on 16 and standing on 17, while the player is presented with the majority of options he would have available there (hit, stand, double down).

The LCD worked properly, displaying the correct cards and point totals at the correct time, as well as informing the player of who won, and why in the case of blackjack and bust.

Overall, we think that any individual who experimented with our game would find it very enjoyable.

Next Time: What We Would do Differently
Do Differently Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @10:57PM
from the dept.
While we were satisfied overall with the operation of our BlackJack player, there are some features that we wish we could have added.

Our first regret is the basicness of our display. We did look into a more advanced display, which could have graphically shown the cards in play. However, the available displays appeared either too expensive or complex.

We tried to use to basic LCD to display actual hearts, diamonds, clubs, and spades. Unfortunately, we couldn't seem to write to the character generator RAM, which is necessary to create our own characters. Finally, we simply settled for letter representation of card suits.

Our second regret is our inability to increase the deck size. We had initially hoped to use eight decks in game play, much like is done in Las Vegas casinos. However, when attempting to increase deck size to even two, we ran out of memory. If we had more time, we would have either added more memory, or switched to the Mega163 microcontroller, which has more memory. Because we ran out of time, we remainded at our initial 52 card size.

Our final regret is our inability to implement the option to split and the ability to have multiple players. These regrets are grouped together, because they both deal with a variable number of hands, something that we were unable to master.

Appendix: Program Listings
Appendix: Program Listings Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @10:51PM
from the dept.
All the wonders of blackjack.c lie within...click through to download.

Click here to dl...

Appendix: Schematics
Appendix: Schematics Posted by Ben and Jeff the Blackjack Duo on Sunday April 28, @10:50PM
from the dept.
Get your schematics here! Get them while they are hot hot hot!

click here to dl...

Older Stuff

There are no previous articles.

Quick Links

476 Homepage

They Love Him in Germany

Developers! Developers!

Update: 04/21 13:34 by ben:

Powered by Zope  Squishdot Powered
  Designate one sucker in your group as master hacker and have her do all the work. That way she will burn out 3/4 of the way through the course and no one else will be able to finish the project since only she understands it. ~CS 412 Compilers
All trademarks and copyrights on this page are owned by their respective companies. Comments are owned by the Poster.
[ home | post update | search ]