Playing cards library

Hi.
I am working on a small project which is about playing cards.
To my surprise I can not find any library for Arduino that provides playing cards :smiley:

I would rather not have to write it myself.
Does someone know of any library that has the basic functionality that playing cards require?

A deck of 52 cards which can be shuffled and cards can be drawn from, then reset.

Cheers!

simmisj:
Hi.
I am working on a small project which is about playing cards.
To my surprise I can not find any library for Arduino that provides playing cards :smiley:

I would rather not have to write it myself.
Does someone know of any library that has the basic functionality that playing cards require?

A deck of 52 cards which can be shuffled and cards can be drawn from, then reset.

Cheers!

How are you going to display them?
I suggest you have a 4 X 13 array and use the random function to pick the cards.
Once a card has been picked, replace it in the array with a zero so that it cannot be picked again.

Why replace with a zero?

Simply maintain an index into the array that points to the top, next available storage.

This would allow for a form of placing items on, and remove items from a stack of cards!

simmisj:
I am working on a small project which is about playing cards.
To my surprise I can not find any library for Arduino that provides playing cards :smiley:

There is a lot of different card games. What’s “playing cards” for you?
Poker? Blackjack? Patience? Rummy? Canasta? Bridge?
Or what else?

simmisj:
I would rather not have to write it myself.
Does someone know of any library that has the basic functionality that playing cards require?

A deck of 52 cards which can be shuffled and cards can be drawn from, then reset.

Doesn’t sound too complicated.
I’ve made a very small class and a programming example:

const char* suits[]= { "Spades", "Hearts", "Diamonds", "Clubs" };
const uint8_t SUITS=sizeof(suits)/sizeof(suits[0]);

const char* ranks[]= { "ACE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING"};
const uint8_t RANKS=sizeof(ranks)/sizeof(ranks[0]);


class cardDeck
{
  public:
  cardDeck() // create card deck
  {
    for( byte c=0; c<SUITS*RANKS;c++)
    {
        cards[c]=c;
    }
  };
 
  
  void shuffle(){};
  uint8_t drawWithoutRemoving(){return cards[random(52)];};
  
  void printCardValue(uint8_t v, Print* device)
  {
    byte suit= v/RANKS;
    byte rank= v%RANKS;
    device->print(ranks[rank]);device->print(" of ");device->print(suits[suit]);device->println();
  };
  private:
  uint8_t cards[SUITS*RANKS];
};  


cardDeck deck;

void setup() 
{
  Serial.begin(9600);
  Serial.println("Deck of playing cards");
  deck.shuffle();
}

void loop() 
{
   for (byte b=0;b<SUITS*RANKS; b++)
  {
     byte card=b;
//     card= deck.drawWithoutRemoving();
     deck.printCardValue(card, &Serial);
     delay(1000);
  }
  delay(5000);
  Serial.println();
}

The code is creating a 52 cards card deck and shows the cards in their initial order on Serial over and over
Shuffling is not yet implemented.

Just one variation is possible: Drawing a random card without removing it from the deck. To create that modification, just remove the comment slashs from the line

//     card= deck.drawWithoutRemoving();

If you like I could easily extend that a little bit, perhaps with shuffling cards on some command input. Or with "draw card and remove it from the deck.

This is like asking why there is not a "library for numbers".

What would this library do? Print out the image of a playing card? To what hardware?

Allow you to have an array of playing cards? Most people would represent a playing card as a byte. You can do this by having suit = b/4, value = b %4. Or you can do it the other way, which means suit is in the lower two bits. Or you can do something tricky so that the value of the byte reflects the value of the card in your game.

Incidentally - many obvious algorithms to shuffle an array are actually not as random as they seem.

Henry_Best: I am using 20x4 LCD display to display the cards.

jurs: Nice. That looks promising. If you have the time and will to extend on it then by all means, please do. Shuffling, drawing with removing, and resetting the deck would be sufficient for a basic implementation.
Poker is the game I want to represent.

PaulMurrayCbr: What? No, this is not like asking why there is not a "library for numbers".
This is like asking if anyone has come across a library that gives the functionality of a deck of 52 playing cards. Yes, they will most likely be represented by numbers.
This library would give the functionality of having a deck of playing cards. On an Arduino. Displayed on an LCD screen in my case.

There are some “messy” things to deal with, like removal from the deck, and “hands”. I would seriously consider a class for this. The deck itself is easy, arrays or structs. It’s when you get into operations that things become painful.

simmisj:
This library would give the functionality of having a deck of playing cards. On an Arduino. Displayed on an LCD screen in my case.

Hmm. So you have one "deck" object and potentially many "hand" objects. Actually, considering that you have a discard pile in some games, you just need many "deck" objects. Some deck objects are special in that they sort the cards, other are special in that they implement a stack or queue. Decks have a maximum size - you don't need the decks that act as hands of cards to cope with more than 5 cards at a time.

You need functions to "choose N random cards from this deck and add them to this other deck", or "take this particular card from this deck and put it on the top of this other deck", or "check to see if this particular card is in this deck". You might also want to implement higher-order things like iterators, so that you could write a function that works out the value of a hand/deck. Naah - not on the arduino: you'd just subclass it.

Where ordering is not important. the obvious way to go would be to use a bitfield.

A heavyweight way to go would be to have a "Deck" object and several "hand" objects. The deck object holds, for each card, the 'hand' that it currently belongs to. That's a lot of pointers - but they're only two bytes each. 104 bytes of memory is not excessive. However, it means that you have to iterate through things to work out what cards are in a hand. Alternatively, if there are no more than 256 or 16 places a card can be at any time, you could pack the "where is this card now?" info into a smaller space.

Or you could do everything all at once: the deck stores for each card what hand it's in and the index in that hand, and each hand also stores what cards are in it as a bitfield. The deck holds an array of pointers to all hands, and identifies hands by an index into that array. The code has to keep everything synchonised. Expensive, but it makes everything you might want to do easier.

Plenty of ways to skin this particular cat.

simmisj:
Henry_Best: I am using 20x4 LCD display to display the cards.

So posssibly you want to create “user defined characters” for your text display to show, clubs, diamonds, hearts and clubs. Perhaps something like:

simmisj:
jurs: Nice. That looks promising. If you have the time and will to extend on it then by all means, please do. Shuffling, drawing with removing, and resetting the deck would be sufficient for a basic implementation.
Poker is the game I want to represent.

PaulMurrayCbr: What? No, this is not like asking why there is not a “library for numbers”.
This is like asking if anyone has come across a library that gives the functionality of a deck of 52 playing cards. Yes, they will most likely be represented by numbers.
This library would give the functionality of having a deck of playing cards. On an Arduino. Displayed on an LCD screen in my case.

I’ve slightly modified the class and example program, so that now also functions can be used for:
deck.reset();
deck.shuffle(); // actually working now
deck.drawAndRemove(); // draw a card from the deck and virtually ‘remove’ it

Actually the drawAndRemove() function easily avoids what aarg has written about:

aarg:
There are some “messy” things to deal with, like removal from the deck, and “hands”. I would seriously consider a class for this. The deck itself is easy, arrays or structs. It’s when you get into operations that things become painful.

Actually drawAndRemove() is working like that:

  • the counter variable ‘cardsInDeck’ is decreased by one
  • then cards[cardsInDeck] is returned to caller
    When starting with a deck of 52 cards consecutive calls of drawAndRemove() will return cards[51], cards[50], cards[49] and so on. No special error handling, so if you try to drawAndRemove() more than 52 cards from a deck of 52 cards, you always draw ‘cards[0]’ after 52 or more cards have beeen drawn from the deck.

This is the modified class and example code:

const char* suits[]= { "Spades", "Hearts", "Diamonds", "Clubs" };
const uint8_t SUITS=sizeof(suits)/sizeof(suits[0]);

const char* ranks[]= { "ACE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING"};
const uint8_t RANKS=sizeof(ranks)/sizeof(ranks[0]);

const uint8_t CARDS= SUITS*RANKS;


class cardDeck
{
  public:
  cardDeck() {reset();}; // constructor creates a sorted card deck
 
  void reset() // reset card deck to sorted state
  {
   for( byte c=0;c<CARDS;c++) cards[c]=c;
   cardsInDeck=CARDS;
  };
  
  void shuffle() // shuffle the cards array into random order
  {
    // Start from the last element and swap one by one. We don't
    // need to run for the first element that's why i > 0
    for (int i = CARDS-1; i > 0; i--)
    {
        // Pick a random index from 0 to i
        int j = random(i+1);
 
        // Swap cards[i] with the element at random index
        byte temp=cards[i];
        cards[i]=cards[j];
        cards[j]=temp;
    }    
  };
  uint8_t drawWithoutRemoving(){return cards[random(52)];};
  uint8_t drawAndRemove()
  {
    if (cardsInDeck>0)cardsInDeck--;
    return cards[cardsInDeck];
  };
  
  void printCardValue(uint8_t v, Print* device)
  {
    byte suit= v/RANKS;
    byte rank= v%RANKS;
    device->print(ranks[rank]);device->print(" of ");device->print(suits[suit]);device->print('\t');
    device->print( cardsInDeck);device->println(" cards left in deck");
  };
  
  uint8_t cardByIndex(uint8_t index) {return cards[index];};
  
  private:
  uint8_t cardsInDeck;
  uint8_t cards[CARDS];
};  


cardDeck deck;

void setup() 
{
  Serial.begin(9600);
  Serial.println("Deck of playing cards");
  Serial.println("Shuffling cards");
  deck.shuffle();
}

void loop() 
{
   for (byte b=0;b<CARDS; b++)
  {
    byte card;
     // card=b;
     // card=deck.cardByIndex(b);
     // card= deck.drawWithoutRemoving();
     card= deck.drawAndRemove();
     deck.printCardValue(card, &Serial);
     delay(1000);
  }
  // All cards have beeen shown; reset und shuffle the deck.
  Serial.println("Resetting and shuffling cards.");
  deck.reset();
  deck.shuffle();
  delay(5000);
  Serial.println();
}

So your sketch better counts how many cards are drawn between resetting the deck and never tries to drawAndRemove()more than 52 cards from a resetted and shuffled deck.

On the other hand there is no limit for drawWithoutRemoving(); cards.

The example sketch provides four demo modes, displaying on Serial:
// card=b; // use the card number as the drawn card
// card=deck.cardByIndex(b); // use a card by index from the deck
// card= deck.drawWithoutRemoving(); // draw random card whithout removing it from the deck
// card= deck.drawAndRemove(); // draw the last card from a shuffled deck and decrease number of cards left
Just remove the comment slashs from one of these for line to run one of the demo modes

No functions for managing different “player hands” available yet.

When talking about “Poker is the game”, what do you actually want?

There are different types of Poker games, as far as I know.
So you want the card deck for “7 Card Stud Poker”, or something similar like that?

And the Arduino and LCD display is just to replace the ‘dealer’ the ‘deck’ and the ‘table’ in the game?
Shuffling and dealing cards and displaying them on LCD for a game "Human against human?
You do not want to create a “computerized Poker player”, do you?

Some starting points, ideas, snippets:

#define CARD(suit,rank) (((suit)<<4) | (rank))
#define SUIT(card)  ((card)>>4)
#define RANK(card) ((card) & 15)

char * suitnames[] = {"spades","diamonds","clubs","hearts"} ;  // numbered 0..3
char * ranknames[] = {0, "ace", "two", ..... "king" } ; // number rank from 1 to 13 note

byte pack[52] ;

void init_pack ()
{
  byte index = 0 ;
  for (byte suit = 0 ; suit < 4 ; suit++)
    for (byte rank = 1 ; rank <= 13 ; rank++)
      pack [index++] = CARD (suit, rank) ;
  shuffle_pack () ;
}

void print_pack ()
{
  for (byte i = 0 ; i < 52 ; i++)
    print_card (pack [i]) ;
}

void print_card (byte card)
{
  char * suitname = suitnames [SUIT (card)] ;
  char * rankname = ranknames [RANK (card)] ;
  Serial.print (rankname) ; Serial.print (" of ") ; 
  Serial.println (suitname) ;
}

void shuffle_pack ()
{
  ...
}

For correct shuffling you need a good RNG and this algorithm:

But really this level of stuff is fun to code, why would you not want to?

MarkT:
For correct shuffling you need a good RNG and this algorithm:

The Arduino core library provides a "Pseudo Random Number Generator" (PRNG) which should be good enough for gaming, as long as you initialize the number generation with a true random value.

In games you typically use the time of the first players action as a true random initializing value.

Typical a game starts with a question or request like:

How many players?

or

Please press any key to start game!

And then you can easily use the value of the micros() function at the time the user enters a number or presses a key to initialize the PRNG to a hardly unrepeatable value:

randomSeed(micros());

After that the random() function provides nearly unique sequences of random numbers.

But of course you also could use different initialization. A common method for PC games is initializing a RNG with the "unixtime" (seconds sind 1/1/1970 0:00 UTC). You can also use that with Arduino as long as the Arduino is equipped with an RTC module: Each game starting in a different second will then create a different random sequence after initialized with something like:

randomSeed(rtc.now());

Using "TRUE RANDOM NUMBER GENERATOR" (TRNG) for initializing a PRNG with a unique starting value is a bit more complicated. Arduino DUE provides a TRNG on the ciip that could be used.

But I think using "micros()" for initialization when the user does his first action in play, should be enough for a card game randomizsation.

But I think using "micros()" for initialization when the user does his first action in play, should be enough for a card game randomizsation.

That depends on the stakes. Rather vulnerable to a forced-reset attack.

played around with this as well…

So in a game like 21 or Poker, containerizing discarded hands isn’t all that necessary, so it should be easy (i.e. 21) to come up with an additional ‘Hand’ object for the cards as they are dealt. In 21, the most cards a player can have in a single deck game is 12 including the Bust card. So, create two objects of size 12 for each players hand… you can even have splits.

I came up with a quick game of “War” (unofficial rules :frowning: ) and had some fun creating a Card class and a Deck class.

This is a cool idea to work on. If I can get the time, it will be fun to include it in an animated clock that I have as one of the little sequences it displays.

Take a look (compiled and tested):

#define NUMBER_OF_CARDS 52

enum Suit {SPADES, HEARTS, CLUBS, DIAMONDS};
enum Face {ACE, DUECE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING};
const char* suitName[] = {"Spades", "Hearts", "Clubs", "Diamonds"};
const char* faceName[] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};

class Card
{
  public:
    Card() {};
    Card(Face cardFace, Suit cardSuit);
    void printCard();
    Face face;
    Suit suit;
  private:
};

class Deck
{
  public:
    Deck();
    void printDeck();
    void shuffle();
    Card dealCard();
    bool newDeck();
  private:
    Card* theDeckPtr;
    int currentCard;
};

Card::Card(Face cardFace, Suit cardSuit)
{
  face = cardFace;
  suit = cardSuit;
}

void Card::printCard()
{
  Serial.print(faceName[face]);
  Serial.print(F(" of "));
  Serial.println(suitName[suit]);
}

Deck::Deck()
{
  Face faces[] = {ACE, DUECE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING};
  Suit suits[] = {SPADES, HEARTS, CLUBS, DIAMONDS};
  theDeckPtr = new Card[NUMBER_OF_CARDS];
  for (int i = 0; i < NUMBER_OF_CARDS; i++) // fill the array of Card objects with faces and suits
  {
    theDeckPtr[i] = Card(faces[i % 13], suits[i / 13]);  
  }
  currentCard = 0;
}

void Deck::shuffle()
{
  Serial.println(F("Shuffling the deck..........")); //<<<<<<<<<<<<<<<<  EDIT OUT
  randomSeed(millis());
  currentCard = 0;
  for (int i = 0; i < NUMBER_OF_CARDS; i++)
  {
    int index = random(i, NUMBER_OF_CARDS);
    Card temp = theDeckPtr[i];
    theDeckPtr[i] = theDeckPtr[index];
    theDeckPtr[index] = temp;
  }
}

void Deck::printDeck()
{
  for (int i = 0; i < NUMBER_OF_CARDS; i++)
  {
    theDeckPtr[i].printCard();
  }
}

Card Deck::dealCard()
{
  if (currentCard >= NUMBER_OF_CARDS)
  {
    shuffle();
  }
  if (currentCard < NUMBER_OF_CARDS)
  {
    return theDeckPtr[currentCard++];
  }
  return (theDeckPtr[0]);
}

bool Deck::newDeck()
{
  return currentCard ? false : true;;
}

//<<<<<<<<<<<<< PROGRAM START <<<<<<<<<<<<<<<<<<<<<<<<

int dealerScore = 0;
int playerScore = 0;
Deck myDeck;

void setup()
{
  Serial.begin(9600);
  Serial.println(F("enter 'x' to draw a hand"));
  while(!Serial.available()){};
  myDeck.shuffle();
}

void loop()
{
  if (Serial.available())
  {
    if (myDeck.newDeck())
    {
      Serial.println(F("*****Cards Randomized*****"));
    }
    if (Serial.read() == 'x')
    {
      Card myCard = myDeck.dealCard();
      Serial.print(F("You drew the "));
      myCard.printCard();
      delay(500);
      Card dealerCard = myDeck.dealCard();
      Serial.print(F("Dealer drew the "));
      dealerCard.printCard();
      delay(500);
      if ((myCard.face == 0 ? 13 : myCard.face)  > (dealerCard.face == 0 ? 13 : dealerCard.face))
      {
        Serial.println(F("you win the hand"));
        playerScore++;
      }
      else if ((myCard.face == 0 ? 13 : myCard.face)  < (dealerCard.face == 0 ? 13 : dealerCard.face))
      {
        Serial.println(F("Dealer wins the hand"));
        dealerScore++;
      }
      else
      {
        Serial.println(F("You both tie the hand"));
      }
      printScore();
    }
  }
}

void printScore()
{
  Serial.println();
  Serial.print(F("   You:"));
  Serial.println(playerScore);
  Serial.print(F("Dealer:"));
  Serial.println(dealerScore);
  Serial.println();
}

I haven’t created the header/implementation files, obviously, just working out the classes.

how about some 21? (pretty darn close, I think)

#define NUMBER_OF_CARDS 52

enum Suit {SPADES, HEARTS, CLUBS, DIAMONDS};
enum Face {ACE = 0, DUECE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING};
const char* suitName[] = {"Spades", "Hearts", "Clubs", "Diamonds"};
const char* faceName[] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};

class Card
{
  public:
    Card() {};
    Card(Face cardFace, Suit cardSuit, byte cardValue);
    void printCard();
    byte getValue();
    Face face;
    Suit suit;
    
  private: 
    byte value;
};

class Hand
{
  public:
    Hand();
    void printHand();
    void getCard(Card newCard);
    byte handTotal();
    void empty();

  private:
    byte aceCount = 0;
    byte total;
    Card* cards;
    byte cardCount = 0;
};

class Deck
{
  public:
    Deck();
    void printDeck();
    void shuffle();
    Card dealCard();
    bool newDeck();
    bool lowDeck();
    
  private:
    Card* theDeckPtr;
    byte currentCard;
};

Card::Card(Face cardFace, Suit cardSuit, byte cardValue)
{
  face = cardFace;
  suit = cardSuit;
  value = cardValue;
}

byte Card::getValue()
{
  return value;
}

void Card::printCard()
{
  Serial.print(faceName[face]);
  Serial.print(F(" of "));
  Serial.println(suitName[suit]);  //Serial.print(suitName[suit]);
  //Serial.print(F(" and value of "));
  //Serial.println(value);
}

Deck::Deck()
{
  Face faces[] = {ACE, DUECE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING};
  Suit suits[] = {SPADES, HEARTS, CLUBS, DIAMONDS};
  theDeckPtr = new Card[NUMBER_OF_CARDS];
  for (byte i = 0; i < NUMBER_OF_CARDS; i++) // fill the array of Card objects with faces, suits and values
  {
    theDeckPtr[i] = Card(faces[i % 13], suits[i / 13], ((i % 13) + 1 < 10 ? (i % 13) + 1 : 10));
  }
  currentCard = 0;
}
bool Deck::lowDeck()
{
  return currentCard > NUMBER_OF_CARDS >> 1;
}
void Deck::shuffle()
{
  Serial.println(F("Shuffling the deck..........")); //<<<<<<<<<<<<<<<<  EDIT OUT
  randomSeed(millis());
  currentCard = 0;
  for (byte i = 0; i < NUMBER_OF_CARDS; i++)
  {
    byte index = random(i, NUMBER_OF_CARDS);
    Card temp = theDeckPtr[i];
    theDeckPtr[i] = theDeckPtr[index];
    theDeckPtr[index] = temp;
  }
}

void Deck::printDeck()
{
  for (byte i = 0; i < NUMBER_OF_CARDS; i++)
  {
    theDeckPtr[i].printCard();
  }
}

Card Deck::dealCard()
{
  if (currentCard >= NUMBER_OF_CARDS)
  {
    shuffle();
  }
  if (currentCard < NUMBER_OF_CARDS)
  {
    return theDeckPtr[currentCard++];
  }
  return (theDeckPtr[0]);
}

bool Deck::newDeck()
{
  return currentCard ? false : true;;
}

Hand::Hand()
{
  cards = new Card[12]; // 4*ACE + 4*DEUCE + 3*THREE = 21 pts in 11 cards
}

void Hand::getCard(Card newCard)
{
  cards[cardCount++] = newCard;
  if (newCard.face == ACE)
  {
    total += 11;
    aceCount++;
  }
  else
  {
    total += newCard.getValue();
  }
  if(total > 21 && aceCount > 0)
  {
    total -= 10;
    aceCount--;
  }
}

void Hand::printHand()
{
  for (byte i = 0; i < cardCount; i++)
  {
    cards[i].printCard();
  }
  Serial.print(F("Hand Total = "));
  Serial.println(total);
  Serial.println();
}

byte Hand::handTotal()
{
  return total;
}

void Hand::empty()
{
  for(byte i = 0; i < cardCount; i++)
  {
    Card* nullCard = &cards[i];
    nullCard = NULL;
  }
  cardCount = 0;
  total = 0;
  aceCount = 0;
}

//<<<<<<<<<<<<< PROGRAM START <<<<<<<<<<<<<<<<<<<<<<<<

enum GameState {
  DEAL_CARDS,
  PLAYER_DRAW,
  DEALER_DRAW,
  SCORE
};

char* gameStateText[] = {"Dealing Cards...", "Select 'h' to hit or 's' to stay", "Dealer playing...", "select 'x' for a new hand"};

GameState gameState = DEAL_CARDS;
GameState lastGameState = DEAL_CARDS;

int dealerScore = 0;
int playerScore = 0;
Deck myDeck;
Hand myHand;
Hand dealerHand;

void setup()
{
  Serial.begin(9600);
  Serial.println(F("Enter 'x' to draw a hand"));
  while (!Serial.available()) {};
  myDeck.shuffle();
}

void loop()
{
  char playerCommand = 0;
  if (Serial.available())
  {
    playerCommand = Serial.read();
    Serial.println(playerCommand);
  }
  if (gameState == DEAL_CARDS)
  {
    myHand.getCard(myDeck.dealCard());
    dealerHand.getCard(myDeck.dealCard());
    myHand.getCard(myDeck.dealCard());
    dealerHand.getCard(myDeck.dealCard());
    Serial.println(F("My Hand: "));
    myHand.printHand();
    Serial.println(F("Dealer Hand: "));
    dealerHand.printHand();
    evaluateScores();
    if(gameState == DEAL_CARDS)
    {
      gameState = PLAYER_DRAW;
    }
  }
  if (gameState == PLAYER_DRAW)
  {
    if (playerCommand == 'h')
    {
      myHand.getCard(myDeck.dealCard());
      Serial.println(F("My Hand: "));
      myHand.printHand();
      Serial.println(F("Dealer Hand: "));
      dealerHand.printHand();
      evaluateScores();
    }
    else if (playerCommand == 's')
    {
      Serial.println(F("Player Stays"));
      Serial.println(F("My Hand: "));
      myHand.printHand();
      Serial.println(F("Dealer Hand: "));
      dealerHand.printHand();
      evaluateScores();
      gameState = DEALER_DRAW;
    }
  }
  else if (gameState == DEALER_DRAW)
  {
    if (dealerHand.handTotal() <= myHand.handTotal())
    {
      dealerHand.getCard(myDeck.dealCard());
      Serial.println(F("My Hand: "));
      myHand.printHand();
      Serial.println(F("Dealer Hand: "));
      dealerHand.printHand();
      evaluateScores();
    }
  }
  else if(gameState == SCORE)
  {
    if(playerCommand == 'x')
    {
      myHand.empty();
      dealerHand.empty();
      if(myDeck.lowDeck())
      {
        myDeck.shuffle();
      }
      gameState = DEAL_CARDS;
    }
  }
  
  if(lastGameState != gameState)
  {
    Serial.println(gameStateText[gameState]);
  }
  lastGameState = gameState;
}

void evaluateScores()
{
  if(gameState == PLAYER_DRAW || gameState == DEAL_CARDS)
  {
    if(myHand.handTotal() == 21 && dealerHand.handTotal() == 21)
    {
      Serial.println(F("It's a Draw"));
      gameState = SCORE;
    }
    else if (myHand.handTotal() == 21)
    {
      Serial.println(F("Player has Twenty One!"));
      gameState = SCORE;
    }
    else if (dealerHand.handTotal() == 21)
    {
      Serial.println(F("Dealer has 21!"));
      gameState = SCORE;
    }
    else if (myHand.handTotal() > 21)
    {
      Serial.println(F("Player Busted!"));
      gameState = SCORE;
    }
    else if (dealerHand.handTotal() > 21)
    {
      Serial.println(F("Dealer Busts!"));
      gameState = SCORE;
    }
    else if(dealerHand.handTotal() > 16 && dealerHand.handTotal() == myHand.handTotal())
    {
      Serial.println(F("It's a PUSH..."));
      gameState = SCORE;
    }
  }
  else if (gameState == DEALER_DRAW)
  {
    if(dealerHand.handTotal() > 21)
    {
      Serial.println(F("Dealer Busts!"));
      gameState = SCORE;
    }
    else if(dealerHand.handTotal() > 16 && dealerHand.handTotal() == myHand.handTotal())
    {
      Serial.println(F("It's a PUSH..."));
      gameState = SCORE;
    }
    else if(dealerHand.handTotal() > myHand.handTotal())
    {
      Serial.println(F("Dealer Wins!"));
      gameState = SCORE;
    }
  }
}

no splits, yet :wink:

GameOfBlackJack.ino (6.92 KB)

Why not just read a floating analog in for random numners? The usual algorithm: read pairs of numbers off the pin. If the low bit goes from 0 to 1, its a 1. If from 1 to 0 , a zero. If a pair of readings has the same low bit, discard it.

uint_16 getSeed() {
  uint_16 seed = 0;
  uint_16 bit = 1;

  while(bit) {
    byte a = analogRead(0);
    delay(1);
    byte b = analogRead(0);
    delay(1);

    if((a & 1) != (b & 1)) {
      if(a&1) seed |= bit;
      bit <<= 1;
    }
  }

  return seed;
}

Wow guys. Overwhelming support. Thanks everyone.

I just want to clarify one thing first. I never expected or intended for anyone to actually write code for me. I was simply curious if someone had done this before and if so, then I could use that solution. This is a rather trivial thing to make and fun, like some pointed out, and I could have done it myself. I was just trying to save some time. The fun part seems to be taking over since 3 versions have been submitted already. Which is great :slight_smile:

Now on to addressing everyone individually:

PaulMurrayCbr: Correct me if I am wrong but that seems like a way to create the solution in a minimalist way. That is not at all required. But valid instructions towards a solution non the less.

jurs: Just tested your second version and it works well. This can be my base for what I am doing. Thanks a lot.

jurs:
So posssibly you want to create "user defined characters" for your text display to show, clubs, diamonds, hearts and clubs. Perhaps something like:

http://forum.arduino.cc/index.php?topic=179608.0

That seems interesting and would be very nice to implement. I will take a look at that after I have made my first working version. For now I simply use h for hearts and so on.

jurs:
When talking about "Poker is the game", what do you actually want?

There are different types of Poker games, as far as I know.
So you want the card deck for "7 Card Stud Poker", or something similar like that?

And the Arduino and LCD display is just to replace the 'dealer' the 'deck' and the 'table' in the game?
Shuffling and dealing cards and displaying them on LCD for a game "Human against human?
You do not want to create a "computerized Poker player", do you?

I am specifically interested in Texas hold em no limit. 2 cards for each player and up to 5 community cards. There is an LCD for each player. Currently only two. On each LCD the cards for the player is displayed along with any community cards that have been dealt.
Currently only two players, human vs human. Computer player could be cool though.
I use three push buttons to advance the game. One button for each player to indicate whatever. Currently the cards are not shown on the screen unless the button is pressed to simulate looking at the cards.
Then there is a third "dealer" button which is used to advance the game one step forward whatever that may involve at the given time.

MarkT, jurs, and PaulMurrayCbr: About the random generator seed. I think using the macros() when a game starts or reading the analog pin is sufficient for now. But it definitely has vulnerability if used online for example. Guys beat an online poker casino by syncing up to the servers clocks

BulldogLowell: I will take a look at your code when I have time. For now jurs' code is sufficient for a first version. Thanks.

Thanks again everyone. Feel free to add anything to this thread. I am sure others will find this information very useful when they think they might want to do some game with a deck of cards on their little Arduinos :slight_smile: