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.