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

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed wave_player

main.cpp

Committer:
xmanwms95
Date:
2017-03-17
Revision:
0:c9085cb4a4af

File content as of revision 0:c9085cb4a4af:

#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();
}