Skip to content

Instantly share code, notes, and snippets.

@TheBuzzSaw
Last active October 29, 2016 18:37
Show Gist options
  • Select an option

  • Save TheBuzzSaw/6c51f4c857b2090018a23ef035cd9ff1 to your computer and use it in GitHub Desktop.

Select an option

Save TheBuzzSaw/6c51f4c857b2090018a23ef035cd9ff1 to your computer and use it in GitHub Desktop.
Full deck of 52 cards in 39 bytes (40 bytes if you include the count)
#include <iostream>
#include <cstring>
#include <string>
#include "Pile.hpp"
using namespace std;
int main(int argc, char** argv)
{
cout << Pile<52>::ByteCount << endl;
Pile<52> pile;
cout << "size: " << sizeof(pile) << endl;
for (int suit : Suits)
{
for (int value : Values)
{
pile.AddCard(suit, value);
}
}
for (int i = 0; i < pile.cardCount; ++i)
{
int card = pile.GetCard(i);
cout << GetValueName(GetValue(card))
<< " of "
<< GetSuitName(GetSuit(card)) << endl;
}
{
string junk;
getline(cin, junk);
}
return 0;
}
#include "Pile.hpp"
const char* GetValueName(int value)
{
switch (value)
{
case 2: return "Two";
case 3: return "Three";
case 4: return "Four";
case 5: return "Five";
case 6: return "Six";
case 7: return "Seven";
case 8: return "Eight";
case 9: return "Nine";
case 10: return "Ten";
case Jack: return "Jack";
case Queen: return "Queen";
case King: return "King";
case Ace: return "Ace";
default: return "(invalid value)";
}
}
const char* GetSuitName(int suit)
{
switch (suit)
{
case Clubs: return "Clubs";
case Diamonds: return "Diamonds";
case Spades: return "Spades";
case Hearts: return "Hearts";
default: return "(invalid suit)";
}
}
#ifndef PileHpp
#define PileHpp
#include <cstdint>
constexpr int Clubs = 0;
constexpr int Diamonds = 1;
constexpr int Spades = 2;
constexpr int Hearts = 3;
constexpr int Suits[] = { Clubs, Diamonds, Spades, Hearts };
constexpr int Jack = 11;
constexpr int Queen = 12;
constexpr int King = 13;
constexpr int Ace = 14;
constexpr int Values[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace };
const char* GetValueName(int value);
const char* GetSuitName(int suit);
constexpr int GetValue(int card)
{
return card & 0xf;
}
constexpr int GetSuit(int card)
{
return (card >> 4) & 0x3;
}
template<int Capacity> struct Pile
{
static constexpr int ByteCount = (Capacity * 6 + 7) / 8;
static constexpr int TrueCapacity = (ByteCount * 8) / 6;
uint8_t cardCount = 0;
uint8_t cardBits[ByteCount] = {};
int GetBitPair(int bitIndex) const
{
int byteIndex = bitIndex / 8;
int bitOffset = bitIndex - byteIndex * 8;
return (cardBits[byteIndex] >> (6 - bitOffset)) & 0x3;
}
void SetBitPair(int bitIndex, int value)
{
int byteIndex = bitIndex / 8;
int bitOffset = bitIndex - byteIndex * 8;
int shift = 6 - bitOffset;
int mask = ~(0x3 << shift);
cardBits[byteIndex] &= mask;
int newPair = (value & 0x3) << shift;
cardBits[byteIndex] |= newPair;
}
int GetCard(int cardIndex) const
{
int bitIndex = cardIndex * 6;
return
GetBitPair(bitIndex + 0) << 4 |
GetBitPair(bitIndex + 2) << 2 |
GetBitPair(bitIndex + 4) << 0;
}
int GetSuit(int cardIndex) const
{
return GetBitPair(cardIndex * 6);
}
int GetValue(int cardIndex) const
{
int bitIndex = cardIndex * 6;
int pair1 = GetBitPair(bitIndex + 2);
int pair2 = GetBitPair(bitIndex + 4);
return (pair1 << 2) | pair2;
}
void SetCard(int cardIndex, int card)
{
int bitIndex = cardIndex * 6;
SetBitPair(bitIndex + 0, card >> 4);
SetBitPair(bitIndex + 2, card >> 2);
SetBitPair(bitIndex + 4, card >> 0);
}
void SetSuit(int cardIndex, int suit)
{
SetBitPair(cardIndex * 6, suit);
}
void SetValue(int cardIndex, int value)
{
int bitIndex = cardIndex * 6;
SetBitPair(bitIndex + 2, value >> 2);
SetBitPair(bitIndex + 4, value);
}
void AddCard(int suit, int value)
{
SetSuit(cardCount, suit);
SetValue(cardCount++, value);
}
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment