Blackjack Game
This is a Blackjack game. It uses the uLCD screen, an SD card reader to play sounds to a speaker, and The Adafruit Bluefruit LE module for player input. This program uses the waveplayer library to play the game sounds.
In the game the player starts with $300. The player can place a bet by using the Adafruit Bluefruit app to connect to the Bluetooth module in the controller option. Once the controller option is selected the player will need to got to the control pad option. Once the player has connected the mbed will need to be reset. The game will print the instructions to the uLCD. The game can go on until the player runs out of money or decides to quit.
Wiring
SparkFun MicroSD Breakout Board
| MicroSD Breakout | mbed |
|---|---|
| CS | p8 |
| DI | p5 |
| VCC | VOUT |
| SCK | p7 |
| GND | GND |
| DO | p6 |
| CD | nc |
Adafruit Bluefruit LE UART Friend
| Bluefruit | mbed |
|---|---|
| TXO | p10 |
| RXI | p9 |
| VCC | VU |
| GND | GND |
| CTS | GND |
| RTS | nc |
uLCD-144-G2 128 by 128 Smart Color LCD
| mbed | using the uLCD Header | using the uLCD Cable |
|---|---|---|
| VU | 5V | 5v |
| GND | GND | GND |
| p30 | Reset | Reset |
| p28 | RX | TX |
| p27 | TX | RX |
The speaker needs to be setup with a Drive Transitor.
The resistor connects to p18 on the mbed.
Demo Video
The main program code is listed below:
Blackjack Game
#include "mbed.h"
#include <string>
#include "SDFileSystem.h"
#include "wave_player.h"
#include "uLCD_4DGL.h"
uLCD_4DGL LCD(p28, p27, p30);
SDFileSystem sd(p5, p6, p7, p8, "sd");
AnalogOut DACout(p18);
Serial blue(p9,p10);
wave_player waver(&DACout);
//////////////////
/////LCD Clear////
////& Setup///////
///for Prints/////
void lcdSetup()
{
LCD.cls();
LCD.locate(0,0);
}
///////////////////
///Sound Effects///
///////////////////
void playIntro()
{
FILE *wave_file;
//wave_file=fopen("/sd/wavfiles/pacman_intro.wav","r");
wave_file=fopen("/sd/wavfiles/crash_x.wav","r");
waver.play(wave_file);
fclose(wave_file);
}
void playWin()
{
FILE *wave_file;
wave_file=fopen("/sd/wavfiles/cash_register_x.wav","r");
waver.play(wave_file);
fclose(wave_file);
}
void playLose()
{
FILE *wave_file;
wave_file=fopen("/sd/wavfiles/whah_whah.wav","r");
//wave_file=fopen("/sd/wavfiles/crash_x.wav","r");
waver.play(wave_file);
fclose(wave_file);
}
void playBet()
{
FILE *wave_file;
wave_file=fopen("/sd/wavfiles/drum_roll_y.wav","r");
waver.play(wave_file);
fclose(wave_file);
}
void playGameover()
{
FILE *wave_file;
wave_file=fopen("/sd/wavfiles/pacman_dies_y.wav","r");
waver.play(wave_file);
fclose(wave_file);
}
////////////////////////
/////Card Drawing///////
/////////Code///////////
////////////////////////
////Draws parts of a ///
//seven segment dispaly/
//Has special segments//
//for the high cards////
////////////////////////
////////////////////////
void segmentZero(int x1, int y1, int color)
{
LCD.filled_rectangle(x1+4, y1+3, x1+10, y1+3, color);
}
void segmentOne(int x1, int y1, int color)
{
LCD.filled_rectangle(x1+4, y1+10, x1+10, y1+10, color);
}
void segmentTwo(int x1, int y1, int color)
{
LCD.filled_rectangle(x1+4, y1+17, x1+10, y1+17, color);
}
///////
void segmentThree(int x1, int y1, int color)
{
LCD.filled_rectangle(x1+3, y1+4, x1+3, y1+9, color);
}
void segmentFour(int x1, int y1, int color)
{
LCD.filled_rectangle( x1+3, y1+11, x1+3, y1+16, color);
}
////
void segmentFive(int x1, int y1, int color)
{
LCD.filled_rectangle(x1+11, y1+4, x1+11, y1+9, color);
}
void segmentSix(int x1, int y1, int color)
{
LCD.filled_rectangle(x1+11, y1+11, x1+11, y1+16, color);
}
void segmentQueen(int x1, int y1, int color)
{
LCD.filled_rectangle(x1+8, y1+14, x1+8, y1+14, color);
LCD.filled_rectangle(x1+9, y1+15, x1+9, y1+15, color);
LCD.filled_rectangle(x1+10, y1+16, x1+10, y1+16, color);
LCD.filled_rectangle(x1+11, y1+17, x1+11, y1+17, color);
LCD.filled_rectangle(x1+12, y1+18, x1+12, y1+18, color);
}
void segmentKing(int x1, int y1, int color)
{
LCD.filled_rectangle(x1+3, y1+10, x1+3, y1+10, color);
LCD.filled_rectangle(x1+4, y1+9, x1+4, y1+9, color);
LCD.filled_rectangle(x1+4, y1+11, x1+4, y1+11, color);
LCD.filled_rectangle(x1+5, y1+8, x1+5, y1+8, color);
LCD.filled_rectangle(x1+5, y1+12, x1+5, y1+12, color);
LCD.filled_rectangle(x1+6, y1+7, x1+6, y1+7, color);
LCD.filled_rectangle(x1+6, y1+13, x1+6, y1+13, color);
LCD.filled_rectangle(x1+7, y1+6, x1+7, y1+6, color);
LCD.filled_rectangle(x1+7, y1+14, x1+7, y1+14, color);
LCD.filled_rectangle(x1+8, y1+5, x1+8, y1+5, color);
LCD.filled_rectangle(x1+8, y1+15, x1+8, y1+15, color);
LCD.filled_rectangle(x1+9, y1+4, x1+9, y1+4, color);
LCD.filled_rectangle(x1+9, y1+16, x1+9, y1+16, color);
}
//////////////////////////
///Functions that call////
///the segement drawing///
///there is a fucntion////
/////for each card////////
//////////////////////////
void drawTwo(int x1, int y1, int color)
{
segmentZero(x1, y1, color);
segmentOne(x1, y1, color);
segmentTwo(x1, y1, color);
segmentFour(x1, y1, color);
segmentFive(x1, y1, color);
}
void drawThree(int x1, int y1, int color)
{
segmentZero(x1, y1, color);
segmentOne(x1, y1, color);
segmentTwo(x1, y1, color);
segmentFive(x1, y1, color);
segmentSix(x1, y1, color);
}
void drawFour(int x1, int y1, int color)
{
segmentOne(x1, y1, color);
segmentThree(x1, y1, color);
segmentFive(x1, y1, color);
segmentSix(x1, y1, color);
}
void drawFive(int x1, int y1, int color)
{
segmentZero(x1, y1, color);
segmentOne(x1, y1, color);
segmentTwo(x1, y1, color);
segmentThree(x1, y1, color);
segmentSix(x1, y1, color);
}
void drawSix(int x1, int y1, int color)
{
segmentOne(x1, y1, color);
segmentTwo(x1, y1, color);
segmentThree(x1, y1, color);
segmentFour(x1, y1, color);
segmentSix(x1, y1, color);
}
void drawSeven(int x1, int y1, int color)
{
segmentZero(x1, y1, color);
segmentFive(x1, y1, color);
segmentSix(x1, y1, color);
}
void drawEight(int x1, int y1, int color)
{
segmentZero(x1, y1, color);
segmentOne(x1, y1, color);
segmentTwo(x1, y1, color);
segmentThree(x1, y1, color);
segmentFour(x1, y1, color);
segmentFive(x1, y1, color);
segmentSix(x1, y1, color);
}
void drawNine(int x1, int y1, int color)
{
segmentZero(x1, y1, color);
segmentOne(x1, y1, color);
segmentThree(x1, y1, color);
segmentFive(x1, y1, color);
segmentSix(x1, y1, color);
}
void drawTen(int x1, int y1, int color)
{
segmentThree(x1, y1, color);
segmentFour(x1, y1, color);
LCD.line(x1+8, y1+4, x1+10, y1+4, color);
LCD.line(x1+8, y1+16, x1+10, y1+16, color);
LCD.line(x1+7, y1+5, x1+7, y1+15, color);
LCD.line(x1+11, y1+5, x1+11, y1+15, color);
}
void drawJack(int x1, int y1, int color)
{
segmentTwo(x1, y1, color);
segmentFour(x1, y1, color);
segmentFive(x1, y1, color);
segmentSix(x1, y1, color);
}
void drawQueen(int x1, int y1, int color)
{
segmentZero(x1, y1, color);
segmentTwo(x1, y1, color);
segmentThree(x1, y1, color);
segmentFour(x1, y1, color);
segmentFive(x1, y1, color);
segmentSix(x1, y1, color);
segmentQueen(x1, y1, color);
}
void drawKing(int x1, int y1, int color)
{
segmentThree(x1, y1, color);
segmentFour(x1, y1, color);
segmentKing(x1, y1, color);
}
void drawAce(int x1, int y1, int color)
{
LCD.line(x1+7, y1+3, x1+3, y1+17, color);
LCD.line(x1+7, y1+3, x1+11, y1+17, color);
LCD.line(x1+5, y1+10, x1+9, y1+10, color);
}
////////////////////
/////Card Checker///
////////////////////
//Takes in card/////
/////Properties &///
//Screen positions//
//to draw a card////
void drawCard(int x1, int x2, int y1, int y2, char cardValue, char cardSuit)
{
int color;
//if statement that gets the color the card number needs to be drawn in
if((cardSuit == 'C') || (cardSuit == 'S')) {
color = 0x000000;
} else if((cardSuit == 'H') || (cardSuit == 'D')) {
color = 0xFF0000;
}
//Draws the card background and border
int backColor = 0xFFFFFF;
LCD.filled_rectangle(x1, y1, x2, y2, backColor);
LCD.rectangle(x1, y1, x2, y2, RED);
//Decides which card is being drawn
if(cardValue == 'A') {
drawAce(x1, y1, color);
} else if(cardValue == '2') {
drawTwo(x1, y1, color);
} else if(cardValue == '3') {
drawThree(x1, y1, color);
} else if(cardValue == '4') {
drawFour(x1, y1, color);
} else if(cardValue == '5') {
drawFive(x1, y1, color);
} else if(cardValue == '6') {
drawSix(x1, y1, color);
} else if(cardValue == '7') {
drawSeven(x1, y1, color);
} else if(cardValue == '8') {
drawEight(x1, y1, color);
} else if(cardValue == '9') {
drawNine(x1, y1, color);
} else if(cardValue == '0') {
drawTen(x1, y1, color);
} else if(cardValue == 'J') {
drawJack(x1, y1, color);
} else if(cardValue == 'Q') {
drawQueen(x1, y1, color);
} else if(cardValue == 'K') {
drawKing(x1, y1, color);
}
}
//global print wait function to give player time to read the screen
void printWait()
{
wait(4);
}
//////////////////////
//////Card Class//////
//////////////////////
//////////////////////
class Card
{
private:
// Data members of class Card
string typeString;
char typeChar;
int initial_value;
string suit;
char typeSuit;
public:
Card();
string getType() const;
int getValue() const;
string getSuit() const;
char getCharType() const;
char getCharSuit() const;
};
////////////////
///Hand Class///
////////////////
class Hand
{
private:
int value;
int number_of_aces;
int number_of_cards;
Card * cards[11];
std::string hand_holder;
void updateValue();
public:
explicit Hand(std::string);
~Hand();
Hand & operator++();
bool operator>(const Hand & rhs) const;
bool operator>(int rhs) const;
bool operator<(const Hand & rhs) const;
bool operator<(int rhs) const;
bool operator==(const Hand & rhs) const;
bool operator==(int rhs) const;
void printHand();
void printFirstCard();
};
//enum for Blackjack Class
enum Hit_or_Stand { HIT, STAND };
///////////////////
//Blackjack class//
///////////////////
class Blackjack
{
private:
double playerMoney, playerBet;
Hand playerHand, dealerHand;
Hit_or_Stand playerChoice;
Hit_or_Stand queryPlayer();
public:
Blackjack(double money)
:playerMoney(money), playerHand("Player"), dealerHand("Dealer")
{ }
void printPlayerMoney(double money);
void printPush();
void printPlayerWins();
void printPlayerBlackjack();
void printDealerWins();
void printDealerBlackjack();
void printPlayerBust();
void printDealerBust();
double play(double bet);
};
/////////////////////////////////////////////////////
//////Function Implementations for the classes///////
/////////////////////////////////////////////////////
Card::Card()
{
int x = (rand() % 13) + 1;
switch(x) {
case(1):
typeString = "Ace";
initial_value = 11;
typeChar = 'A';
break;
case(2):
typeString = "Two";
initial_value = 2;
typeChar = '2';
break;
case(3):
typeString = "Three";
initial_value = 3;
typeChar = '3';
break;
case(4):
typeString = "Four";
initial_value = 4;
typeChar = '4';
break;
case(5):
typeString = "Five";
initial_value = 5;
typeChar = '5';
break;
case(6):
typeString = "Six";
initial_value = 6;
typeChar = '6';
break;
case(7):
typeString = "Seven";
initial_value = 7;
typeChar = '7';
break;
case(8):
typeString = "Eight";
initial_value = 8;
typeChar = '8';
break;
case(9):
typeString = "Nine";
initial_value = 9;
typeChar = '9';
break;
case(10):
typeString = "Ten";
initial_value = 10;
typeChar = '0';
break;
case(11):
typeString = "Jack";
initial_value = 10;
typeChar = 'J';
break;
case(12):
typeString = "Queen";
initial_value = 10;
typeChar = 'Q';
break;
case(13):
typeString = "King";
initial_value = 10;
typeChar = 'K';
}
int y = (rand() % 4) + 1;
switch(y) {
case(1):
suit = "Club";
typeSuit = 'C';
break;
case(2):
suit = "Spade";
typeSuit = 'S';
break;
case(3):
suit = "Heart";
typeSuit = 'H';
break;
case(4):
suit = "Diamond";
typeSuit = 'D';
break;
}
}
/////Functions to get information about the cards
string Card::getType() const
{
return typeString;
}
int Card::getValue() const
{
return initial_value;
}
string Card::getSuit() const
{
return suit;
}
char Card::getCharType() const
{
return typeChar;
}
char Card::getCharSuit() const
{
return typeSuit;
}
Hand::Hand(std::string Who)
{
hand_holder = Who;
number_of_aces = 0;
number_of_cards = 0;
value = 0;
}
Hand::~Hand()
{
for(int i = 0; i < number_of_cards; i++) {
delete cards[i];
}
}
////////////////////////
///Updates Hand Value///
////////////////////////
void Hand::updateValue()
{
value = 0;
int aceCount = number_of_aces;
for(int i=0; i<number_of_cards; i++) {
value = value + cards[i]->getValue();
}
for(int i = 0; i < number_of_cards; i++) {
if(value > 21 && aceCount > 0) {
value = value - 10;
aceCount--;
}
}
}
///Operator overloads the add up the vaule of the hand and to compare
///the value of the hands
Hand & Hand::operator++()
{
Card * card_ptr = new Card();
if(card_ptr->getType() == "Ace")
number_of_aces++;
cards[number_of_cards] = card_ptr;
number_of_cards++;
updateValue();
return *this;
}
bool Hand::operator>(const Hand & rhs) const
{
bool result(value > rhs.value);
return result;
}
bool Hand::operator>(int rhs) const
{
bool result(value > rhs);
return result;
}
bool Hand::operator<(const Hand & rhs) const
{
bool result(value > rhs.value);
return result;
}
bool Hand::operator<(int rhs) const
{
bool result(value < rhs);
return result;
}
bool Hand::operator==(const Hand & rhs) const
{
bool result(value == rhs.value);
return result;
}
bool Hand::operator==(int rhs) const
{
bool result(value == rhs);
return result;
}
///////////
///Prints the hand value and calls the card checker funtion to decide what cards to draw
void Hand::printHand()
{
int x1 = 1;
int x2 = 15;
int y1 = 46;
int y2 = 66;
LCD.cls();
LCD.locate(0,0);
LCD.printf("%s's hand is: \n\r", hand_holder);
for(int i = 0; i < number_of_cards; i++) {
drawCard(x1, x2, y1, y2, cards[i]->getCharType(), cards[i]->getCharSuit());
x1 = x1 + 16;
x2 = x2 + 16;
//LCD.printf("%s \n\r", cards[i]->getType());
}
LCD.printf("\n\r");
LCD.printf("Hand value is: ");
LCD.printf("%d\n\r", value);
wait(4);
}
/////////////////////
//Prints first Card//
/////////////////////
void Hand::printFirstCard()
{
int x1 = 1;
int x2 = 15;
int y1 = 46;
int y2 = 66;
LCD.cls();
LCD.locate(0,0);
LCD.printf("%s's first\n\rcard is: \n\r\n\r", hand_holder);
drawCard(x1, x2, y1, y2, cards[0]->getCharType(), cards[0]->getCharSuit());
wait(4);
}
//////////////////////////////
//////////////////////////////
//////////////////////////////
///////BlackJack Class////////
//////////////////////////////
//////////////////////////////
//////////////////////////////
////Bluetooth module is used for the input
Hit_or_Stand Blackjack::queryPlayer()
{
Hit_or_Stand Move;
std::string choice;
LCD.printf("Press 3 to Hit\n\rPress 4 to Stand\n\r");
char bnum=0;
char bhit=0;
while(1) {
if (blue.getc()=='!') {
if (blue.getc()=='B') { //button data
bnum = blue.getc();
bhit = blue.getc();
if((bnum=='3') && (bhit=='0')) {
lcdSetup();
LCD.printf("HIT");
Move = HIT;
wait(.5);
return Move;
} else if ((bnum=='4') && (bhit=='0')) {
lcdSetup();
LCD.printf("STAND");
Move = STAND;
wait(.5);
return Move;
}
}
}
}
}
////Result Print statemets
///Tells the player how much money they have
void Blackjack::printPush()
{
lcdSetup();
LCD.printf("Push \n\rPlayer has\n\r$%5.2lf", playerMoney);
printWait();
}
void Blackjack::printPlayerWins()
{
lcdSetup();
LCD.printf("Player Wins!\n\rPlayer has\n\r$%5.2lf", playerMoney);
playWin();
printWait();
}
void Blackjack::printPlayerBlackjack()
{
lcdSetup();
LCD.printf("Player has\n\rBlackjack.\n\rPlayer Wins\n\rPlayer has\n\r$%5.2lf", playerMoney);
playWin();
printWait();
}
void Blackjack::printDealerWins()
{
lcdSetup();
LCD.printf("Dealer Wins\n\rPlayer has\n\r$%5.2lf", playerMoney);
playLose();
printWait();
}
void Blackjack::printDealerBlackjack()
{
lcdSetup();
LCD.printf("Dealer has\n\rBlackjack.\n\rDealer Wins\n\rPlayer has\n\r$%5.2lf", playerMoney);
playLose();
printWait();
}
void Blackjack::printPlayerBust()
{
lcdSetup();
LCD.printf("Player's hand\n\ris bust\n\rDealer Wins\n\rPlayer has\n\r$%5.2lf", playerMoney);
playLose();
printWait();
}
void Blackjack::printDealerBust()
{
lcdSetup();
LCD.printf("Dealer's hand\n\ris bust.\n\rPlayer Wins!\n\rPlayer has\n\r$%5.2lf", playerMoney);
playWin();
printWait();
}
/////////////////
//Prints player money and bet
void Blackjack::printPlayerMoney(double money)
{
LCD.locate(0,11);
LCD.printf("Bet: $%5.2lf\n\r", money);
LCD.printf("Player: $%5.2lf\n\r",playerMoney);
}
////Balckjack game
double Blackjack::play(double bet)
{
int dealer_num_cards = 0;
int player_num_cards = 0;
++playerHand;
player_num_cards++;
++dealerHand;
dealer_num_cards++;
++playerHand;
player_num_cards++;
++dealerHand;
dealer_num_cards++;
dealerHand.printFirstCard();
playerHand.printHand();
printPlayerMoney(bet);
while (playerHand < 21) {
playerChoice = queryPlayer();
if(playerChoice == HIT) {
++playerHand;
player_num_cards++;
playerHand.printHand();
printPlayerMoney(bet);
} else if(playerChoice == STAND) {
dealerHand.printHand();
break;
}
}
if(playerHand == 21) {
dealerHand.printHand();
if(dealerHand == 21 && dealer_num_cards == 2 && player_num_cards > 2) {
playerMoney = playerMoney - bet;
printDealerBlackjack();
} else if(dealerHand == 21 && dealer_num_cards == 2 && player_num_cards ==2) {
printPush();
} else if(player_num_cards == 2) {
playerMoney = playerMoney + bet*1.5;
printPlayerBlackjack();
} else {
while(dealerHand < 17) {
++dealerHand;
dealer_num_cards++;
dealerHand.printHand();
}
if(dealerHand == 21 && dealer_num_cards > 2 && player_num_cards > 2) {
printPush();
} else if(dealerHand == 21 && dealer_num_cards > 2 && player_num_cards == 2) {
playerMoney = playerMoney + bet*1.5;
printPlayerBlackjack();
} else if(player_num_cards == 2) {
playerMoney = playerMoney + bet*1.5;
printPlayerBlackjack();
} else {
playerMoney = playerMoney + bet;
printPlayerWins();
}
}
} else if(playerHand > 21) {
dealerHand.printHand();
playerMoney = playerMoney - bet;
printPlayerBust();
} else if(playerHand < 21) {
if(dealerHand < 17) {
while(dealerHand < 17) {
++dealerHand;
dealer_num_cards++;
dealerHand.printHand();
}
}
if(playerHand > dealerHand && playerHand < 21) {
playerMoney = playerMoney + bet;
printPlayerWins();
} else if(dealerHand > playerHand && dealerHand < 21) {
playerMoney = playerMoney - bet;
printDealerWins();
} else if(dealerHand > 21) {
playerMoney = playerMoney + bet;
printDealerBust();
} else if(dealerHand == 21) {
playerMoney = playerMoney - bet;
printDealerWins();
} else if(playerHand == dealerHand) {
printPush();
}
}
return playerMoney;
}
////Takes bet using bluettoth module for input
double takeBet(const double & playerMoney)
{
double bet = 0;
char bnum =0;
char bhit =0;
lcdSetup();
LCD.printf("Press the Up and\n\rDown Arrows to\n\radjust the bet\n\rammount, press 1\n\rto submit a bet\n\rIf a bet isn't\n\rsumbitted the gameis over\n\r");
playBet();
while(1) {
if (blue.getc()=='!') {
if (blue.getc()=='B') { //button data
bnum = blue.getc(); //button number
bhit = blue.getc();
if((bet < playerMoney) && (bnum=='5') && (bhit=='1')) {
bet = bet + 10;
lcdSetup();
LCD.printf("Bet increased to\n\r$%5.2lf\n\r", bet);
wait(.5);
}
if((bet > 0) && (bnum=='6') && (bhit=='1')) {
bet = bet - 10;
lcdSetup();
LCD.printf("Bet decreased to\n\r$%5.2lf\n\r", bet);
wait(.5);
}
if((bnum=='1') && (bhit=='1')) {
lcdSetup();
LCD.printf("Player Bet:\n\r$%5.2lf\n\r", bet);
wait(1);
return bet;
}
}
}
}
}
int main()
{
///Increased the baudrate for max drawing speed
LCD.baudrate(3000000);
//seed to make random number generate different numbers each time
srand( static_cast<unsigned int>(time(0)));
double playerMoney = 300.0, playerBet;
int roundNum =1;
//Intro Music
playIntro();
lcdSetup();
LCD.printf("Player starts with\n\r$%5.2lf\n\rRound %d\n\r", playerMoney, roundNum);
wait(3);
//Takes bet
playerBet = takeBet(playerMoney);
//Blackjack game continues until the player is out of money or quits
while ((playerBet > 0.0) && (playerMoney > 0.0)) {
Blackjack myBlackjack(playerMoney);
playerMoney = myBlackjack.play(playerBet);
if (playerMoney > 0.0) {
lcdSetup();
LCD.locate(6,8);
LCD.printf("Round %d", ++roundNum);
wait(3);
playerBet = takeBet(playerMoney);
}
}
lcdSetup();
LCD.printf("Player has quit");
playLose();
}
The import of the program is listed below. All the libraries are already included as well.
Import programBlackjackGame
This is a Blackjack game. It uses the uLCD screen, an SD card reader to play sounds to a speaker, and The Adafruit Bluefruit LE module for player input
Please log in to post comments.
