Skip to content

Instantly share code, notes, and snippets.

@dizzi
Created December 12, 2011 10:45
Show Gist options
  • Save dizzi/1466530 to your computer and use it in GitHub Desktop.
Save dizzi/1466530 to your computer and use it in GitHub Desktop.
Cards
/*
* cards.cpp
*
* Created on: 26.11.2011
* Author: dizzi
*/
#include <iostream>
#include <string>
#include <cards.h>
#include "gtest/gtest.h"
//#define debug;
using namespace std;
string scolor[] = { "s", "h", "c", "d" };
string lcolor[] = { "spades", "hearts", "clubs", "diamonds" };
string svalue[] = { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A" };
short int getColor(short int card) {
return (card & 0x30) >> 4;
}
short int getValue(short int card) {
return (card & 0x0F) - 1;
}
void card2text(short int card) {
int value = getValue(card);
int color = getColor(card);
cout << svalue[value];
cout << scolor[color] << endl;
}
int score(short int cards[7]) {
short int colors[4] = { 0 };
short int values[LENGTH] = { 0 };
short int cardarray[4][LENGTH] = { 0 };
short int localhighCard = -1;
// short int color = -1;
short int flushColor = -1;
// init basic data - color, values, highCard
for (int card = 0; card < 7; card++) {
int color = getColor(cards[card]);
int value = getValue(cards[card]);
colors[color]++;
if (colors[color] >= 5)
flushColor = color;
values[value%LENGTH]++;
cardarray[color][value%LENGTH]++;
localhighCard = value > localhighCard ? value : localhighCard;
}
unsigned int score = 0;
score = isStraightFlush(flushColor, cardarray);
if (score != 0)
return score;
score = isQuads(values);
if (score != 0)
return score;
score = isFullhouse(values);
if (score != 0)
return score;
if(flushColor!=-1)
score = isFlush(&cardarray[flushColor][0]);
if (score != 0)
return score;
score = isStraight(values);
if (score != 0)
return score;
score = isSet(values);
if (score != 0)
return score;
score = isPair(values);
if (score != 0)
return score;
score = isHighCard(values);
return score;
}
unsigned int isHighCard(short int values[LENGTH]) {
unsigned int score = 0;
int toFive = 0;
for (int i = LENGTH; i >= 1; i--) {
if (values[i % LENGTH] != 0) {
score |= 1 << i;
toFive++;
if (toFive == 5) {
#ifdef debug
cout << "HighCard: " << score << endl;
#endif
return score;
}
}
}
return score;
}
unsigned int isPair(short int values[LENGTH]) {
bool set2ndPair = false;
bool setKickers = false;
unsigned int score = 0;
int kickers[3] = { -1 };
int kickerIndex = 0;
for (int i = LENGTH; i >= 1; i--) {
if (values[i % LENGTH] == 2 && !setKickers) {
if (!set2ndPair) { // find higher pair
score |= PAIR | (i << TO_HIGHER);
set2ndPair = true;
} else { // find lower pair
score |= (i << TO_LOWER);
set2ndPair = false;
setKickers = true;
}
} else if (values[i % LENGTH] != 0 && kickerIndex<3) { // note 3 highest kickers
kickers[kickerIndex] = i;
kickerIndex++;
}
}
// if two pairs found use only first kicker, otherwise all three
if (score >= PAIR) {
for (int i = 0; i < 3; i++) {
score |= (1 << kickers[i]);
if (!set2ndPair && i == 0)
break;
}
#ifdef debug
cout << "Pair(s): " << score << endl;
#endif
} else
score = 0;
return score;
}
unsigned int isSet(short int values[LENGTH]) {
unsigned int score = 0;
int kickerIndex = 0;
for (int i = LENGTH; i >= 1; i--) {
if (values[i % LENGTH] == 3) {
score |= SET | i << TO_HIGHER;
} else if (values[i % LENGTH] != 0 && kickerIndex < 2) { // note 2 highest kickers
score |= (1 << i);
kickerIndex++;
}
}
if (score >= SET) {
#ifdef debug
cout << "Set: " << score << endl;
#endif
} else
score = 0;
return score;
}
unsigned int isStraight(short int values[LENGTH]) {
int highCard = -1;
unsigned int score = 0;
int inrow = 0;
for (int i = LENGTH; i >= 0; i--) {
if (values[i % LENGTH] != 0) {
inrow++;
highCard = highCard == -1 ? i : highCard;
} else {
inrow = 0;
highCard = -1;
}
if (inrow >= 5) {
score = STRAIGHT | (highCard << TO_HIGHER);
#ifdef debug
cout << "Straight: " << score << endl;
#endif
return score;
}
}
return score;
}
unsigned int isFlush(short int values[LENGTH]) {
unsigned int score = 0;
int toFive = 0;
for (int i = LENGTH; i >= 1; i--) {
// cout << "Index: " << i % LENGTH << "-" << values[i % LENGTH] << ", ";
if (values[i % LENGTH] != 0) {
toFive++;
score |= 1 << i;
}
if (toFive == 5) { // count only highest 5 cards
score |= FLUSH;
#ifdef debug
cout << "Flush: " << score << endl;
#endif
return score;
}
}
// remove kicker pieces if complete flush was not collected
score = score >= FLUSH ? score : 0;
return score;
}
unsigned int isFullhouse(short int values[LENGTH]) {
unsigned int score = 0;
unsigned int set = isSet(values);
unsigned int pair = isPair(values);
if (set != 0 and pair != 0) {
set = (set >> TO_HIGHER) & 0x0F; // filter values of set/pair and agregate it
pair = (pair >> TO_HIGHER) & 0x0F;
score = FULLHOUSE | (set << TO_HIGHER) | (pair << TO_LOWER);
#ifdef debug
cout << "Fullhouse: " << score << endl;
#endif
return score;
}
return score;
}
unsigned int isQuads(short int values[LENGTH]) {
short int kicker = -1;
unsigned int score = 0;
for (int i = LENGTH; i >= 1; i--) {
if (values[i % LENGTH] == 4) {
score = QUADS | (i << TO_HIGHER);
} else if (values[i % LENGTH] != 0 && kicker == -1) {
kicker = i;
}
}
if (score >= QUADS) {
score |= 1 << kicker;
#ifdef debug
cout << "Quads: " << score << endl;
#endif
return score;
}
return score;
}
unsigned int isStraightFlush(short int flushColor, short int values[4][LENGTH]) {
// short int color = -1;
unsigned int score = 0;
if (flushColor != -1) {
score = isStraight(&values[flushColor][0]);
if (score != 0) {
score = (score & ~STRAIGHT) | STRAIGHTFLUSH;
#ifdef debug
cout << "Straight flush: " << score << endl;
#endif
}
}
return score;
}
void scoreToText(unsigned int score) {
switch (score & (0x0FF << 24)) {
case PAIR:
cout << "Pair, ";
break;
case SET:
cout << "Set, ";
break;
case STRAIGHT:
cout << "Straight, ";
break;
case FLUSH:
cout << "Flush, ";
break;
case FULLHOUSE:
cout << "Fullhouse, ";
break;
case QUADS:
cout << "Quads, ";
break;
case STRAIGHTFLUSH:
cout << "Straightflush, ";
break;
default:
cout << "HighCard, ";
}
cout << svalue[((score >> TO_HIGHER) & 0x0F)] << ", ";
cout << svalue[((score >> TO_LOWER) & 0x0F)] << " Kickers: ";
for (int i = LENGTH; i >= 0; i--)
if ((((score & 0x0FFFF) >> i) & 1) != 0)
cout << svalue[i] << ",";
cout << endl;
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
return 0;
}
/*
* cards.h
*
* Created on: 10.12.2011
* Author: dizzi
*/
#ifndef CARDS_H_
#define CARDS_H_
const short int LENGTH = 13;
//const int HIGHCARD = 1<<23;
const unsigned int PAIR = 1 << 24;
const unsigned int TWOPAIRS = 1 << 25;
const unsigned int SET = 1 << 26;
const unsigned int STRAIGHT = 1 << 27;
const unsigned int FLUSH = 1 << 28;
const unsigned int FULLHOUSE = 1 << 29;
const unsigned int QUADS = 1 << 30;
const unsigned int STRAIGHTFLUSH = 1 << 31;
const int TO_HIGHER = 20;
const int TO_LOWER = 16;
unsigned int isHighCard(short int[LENGTH]);
unsigned int isPair(short int[LENGTH]);
unsigned int isSet(short int[LENGTH]);
unsigned int isStraight(short int[LENGTH]);
unsigned int isFlush(short int[LENGTH]);
unsigned int isFullhouse(short int[LENGTH]);
unsigned int isQuads(short int[LENGTH]);
unsigned int isStraightFlush(short int, short int[4][LENGTH]);
void scoreToText(unsigned int);
int score(short int[7]);
#endif /* CARDS_H_ */
/*
* cards_test.cpp
*
* Created on: 10.12.2011
* Author: dizzi
*/
#include <limits.h>
#include "cards.h"
#include "gtest/gtest.h"
TEST(FlushTest, DISABLED_Core) {
short int data1[LENGTH] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
EXPECT_EQ(isFlush(data1), 0);
short int data2[LENGTH] = { 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1};
EXPECT_EQ(isFlush(data2), FLUSH | (1 << 13) | (1 << 12) | (1 << 9) | (1 << 6) | (1 << 2));
short int data3[LENGTH] = { 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0};
EXPECT_EQ(isFlush(data3), FLUSH | (1 << 13) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 6));
short int data4[LENGTH] = { 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1};
EXPECT_EQ(isFlush(data4), FLUSH | (1 << 12) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 6));
}
TEST(StraightTest, DISABLED_Core) {
short int data1[LENGTH] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
EXPECT_EQ(isStraight(data1), 0);
short int data2[LENGTH] = { 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1};
EXPECT_EQ(isStraight(data2), STRAIGHT | (4 << TO_HIGHER));
short int data3[LENGTH] = { 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 1, 1, 1};
EXPECT_EQ(isStraight(data3), 0);
short int data4[LENGTH] = { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1};
EXPECT_EQ(isStraight(data4), STRAIGHT | (13 << TO_HIGHER));
short int data5[LENGTH] = { 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
EXPECT_EQ(isStraight(data5), STRAIGHT | (12 << TO_HIGHER));
short int data6[LENGTH] = { 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1};
EXPECT_EQ(isStraight(data6), 0);
}
TEST(PairTest, Core) {
short int data1[LENGTH] = { 0, 1, 0, 0, 3, 0, 1, 0, 0, 1, 0, 1, 0};
EXPECT_EQ(isPair(data1), 0);
short int data2[LENGTH] = { 2, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1};
EXPECT_EQ(isPair(data2), PAIR | (13 << TO_HIGHER) | (1 << 12) | (1 << 11) | (1 << 9));
short int data3[LENGTH] = { 2, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 2};
EXPECT_EQ(isPair(data3), PAIR | (13 << TO_HIGHER) | (12 << TO_LOWER) | (1 << 11));
short int data4[LENGTH] = { 0, 1, 1, 0, 0, 2, 1, 1, 0, 0, 1, 0, 0};
EXPECT_EQ(isPair(data4), PAIR | (5 << TO_HIGHER) | (1 << 10) | (1 << 7) | (1 << 6));
short int data5[LENGTH] = { 1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, 2};
EXPECT_EQ(isPair(data5), PAIR | (12 << TO_HIGHER) | (9 << TO_LOWER) | (1 << 13));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment