A group assignment I directed during my 2nd year, we developed an atmospheric survival horror game about the mythical Windigo.
In addition to directing responsibilities, I was in charge of pipeline (we used a Perforce setup with a remote server to version assets) and engine level C++ programming (primarily core gameplay features and supporting the AI developer with whatever engine features they required).
if( Serial.available() >= 4 ) { //Protocol >= 4 bytes (header + info + footer + Npayload)
Header = Serial.read();
PacketInfo = Serial.read();
unsigned int payloadLength = (PakInfo & 0x0F);
Byte payload[payloadLength];
Byte result = -1;
for(int i = 0; i < payloadLength; i++)
{
Byte result = Serial.read();
/* Premature packet footer */
if(result == FOOTER_ID)
break;
payload[i] = result;
}
/* Less data than expected */
if(result == FOOTER_ID)
{
return PACKET_ERR_INVALID;
}
Footer = Serial.read();
Byte chksum = CalculateChecksum(...); // Generate checksum somehow
Serial.write(chksum); // Send back to dealer for verification
}
Dealer side
Playing card
Data structure
Credit to my lecturer Ian Stephenson for the main idea behind this, his example implementation used macros to define the constants. I decided to use enums placed inside namespaces so they don’t pollute the global namespace while giving a readability benefit. I find Suit::Spade clearer than just SPADE.
A possible alternative would be to use bitfields, but in the higher level parts of the library these simple constants/macros are abstracted away with C++ classes and functions anyway.
Suit
namespace Suit
{
/* Suit is stored in the left nibble of a byte */
enum Value
{
Diamond = (1<<4), // 0001 0000
Heart = (1<<5), // 0010 0000
Club = (1<<6), // 0100 0000
Spade = (1<<7) // 1000 0000
};
}
Rank
namespace Rank
{
/* Rank is stored in the right nibble of a byte */
enum Value
{
Joker = (0x00), // This isn't used in poker, but is added for completeness
Two = (0x01),
Three = (0x02),
Four = (0x03),
Five = (0x04),
Six = (0x05),
Seven = (0x06),
Eight = (0x07),
Nine = (0x08),
Ten = (0x09),
Jack = (0x0A),
Queen = (0x0B),
King = (0x0C),
Ace = (0x0D),
/* Unused= (0x0E), */
/* Unused= (0x0F) */
};
}