Created
December 12, 2011 10:45
-
-
Save dizzi/1466530 to your computer and use it in GitHub Desktop.
Cards
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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