implement new cards value function; circa factor 10 faster than old version

This commit is contained in:
floty
2014-05-24 15:13:49 +02:00
parent ac85136ac2
commit 0f59c0ad57
7 changed files with 231 additions and 62 deletions
+195 -31
View File
@@ -221,52 +221,216 @@ int CardsValue::holeCardsClass(int one, int two)
} }
int CardsValue::holeCardsToIntCode(int* cards) int CardsValue::holeCardsToIntCode(int holeCards[2])
{ {
// Code der HoleCards ermitteln // Code der HoleCards ermitteln
if(cards[0]%13 == cards[1]%13) { if(holeCards[0]%13 == holeCards[1]%13) {
return ((cards[0]%13)*1000 + (cards[0]%13)*10); return ((holeCards[0]%13)*1000 + (holeCards[0]%13)*10);
} else { } else {
if(cards[0]%13 < cards[1]%13) { if(holeCards[0]%13 < holeCards[1]%13) {
if(cards[0]/13 == cards[1]/13) { if(holeCards[0]/13 == holeCards[1]/13) {
return ((cards[0]%13)*1000 + (cards[1]%13)*10 + 1); return ((holeCards[0]%13)*1000 + (holeCards[1]%13)*10 + 1);
} else { } else {
return ((cards[0]%13)*1000 + (cards[1]%13)*10); return ((holeCards[0]%13)*1000 + (holeCards[1]%13)*10);
} }
} else { } else {
if(cards[0]/13 == cards[1]/13) { if(holeCards[0]/13 == holeCards[1]/13) {
return ((cards[1]%13)*1000 + (cards[0]%13)*10 + 1); return ((holeCards[1]%13)*1000 + (holeCards[0]%13)*10 + 1);
} else { } else {
return ((cards[1]%13)*1000 + (cards[0]%13)*10); return ((holeCards[1]%13)*1000 + (holeCards[0]%13)*10);
} }
} }
} }
} }
/* DO NOT USE, THIS MAY LEAK MEMORY static const int straight[10] = { 7936, 3968, 1984, 992, 496, 248, 124, 62, 31, 4111 };
int* CardsValue::intCodeToHoleCards(int code)
int CardsValue::cardsValue(int cards[4], int bestHand[4])
{ {
int color_1_idx;
int card_idx;
KickerValue kickerValue1;
// one possibility !!! // Royal Flush, Straight Flush, Flush
for(color_1_idx=0; color_1_idx<4; color_1_idx++) { // check all colors
int* cards = new int[2]; if(Tools::bitcount(cards[color_1_idx])>=5) { // check if at least 5 cards of one color
if((cards[color_1_idx] & straight[0]) == straight[0]) { // check for Royal Flush
cards[0] = code/1000; if(bestHand) bestHand[color_1_idx] = straight[0];
cards[1] = (code-cards[0]*1000)/10; return 900000000; // Royal Flush
} else {
if(cards[0]==cards[1]) { for(card_idx=1; card_idx<10; card_idx++) {
cards[1] +=13; if((cards[color_1_idx] & straight[card_idx]) == straight[card_idx]) { // check for Straight Flush
} else { if(bestHand) bestHand[color_1_idx] = straight[card_idx];
if(code%10 == 0) cards[1] +=13; return (800000000+(12-card_idx)*1000000); // Straight Flush
}
}
}
// Flush
kickerValue1 = determineKickerValue(cards[color_1_idx],0,4);
if(bestHand) bestHand[color_1_idx] = kickerValue1.select;
return 500000000 + kickerValue1.factorValue;
}
} }
return cards; int AND = cards[0] & cards[1] & cards[2] & cards[3];
int OR = cards[0] | cards[1] | cards[2] | cards[3];
int temp1;
KickerValue kickerValue2;
}*/ // Four of a Kind
if(AND) {
kickerValue1 = determineKickerValue(AND,0,0);
kickerValue2 = determineKickerValue(OR & ~AND,1,1);
if(bestHand) {
temp1 = kickerValue2.select;
for(color_1_idx=3; color_1_idx>=0; color_1_idx--) {
bestHand[color_1_idx] = (cards[color_1_idx] & (kickerValue1.select | temp1));
if(bestHand[color_1_idx] & temp1) temp1 = 0;
}
}
return 700000000 + kickerValue1.factorValue + kickerValue2.factorValue;
}
int CardsValue::cardsValue(int* cards, int* position) // Straight
for(card_idx=0; card_idx<10; card_idx++) {
if((OR & straight[card_idx]) == straight[card_idx]) {
if(bestHand) {
temp1 = straight[card_idx];
for(color_1_idx=3; color_1_idx>=0; color_1_idx--) {
bestHand[color_1_idx] += (temp1 & cards[color_1_idx]);
temp1 &= ~bestHand[color_1_idx];
}
}
return 400000000 + (12-card_idx)*1000000;
}
}
int color_2_idx, color_3_idx;
int temp2;
// Full House, Three of a Kind
temp1 = 0;
for(color_1_idx=0; color_1_idx<2; color_1_idx++) {
for(color_2_idx=color_1_idx+1; color_2_idx<3; color_2_idx++) {
for(color_3_idx=color_2_idx+1; color_3_idx<4; color_3_idx++) {
temp1 |= cards[color_1_idx] & cards[color_2_idx] & cards[color_3_idx];
}
}
}
if(temp1) {
if(Tools::bitcount(temp1) == 2) {
// two times Three of a Kind
if(bestHand) {
kickerValue1 = determineKickerValue(temp1,0,0);
kickerValue2 = determineKickerValue(kickerValue1.remain,1,1);
temp2 = 0;
for(color_1_idx=3; color_1_idx>=0; color_1_idx--) {
if(temp2<2) bestHand[color_1_idx] += (cards[color_1_idx] & (kickerValue1.select | kickerValue2.select));
else bestHand[color_1_idx] += (cards[color_1_idx] & kickerValue1.select);
if(cards[color_1_idx] & kickerValue2.select) temp2++;
}
}
return 600000000 + determineKickerValue(temp1,0,1).factorValue;
} else {
// one times Three of a Kind
temp2 = temp1;
temp1 = 0;
// check for additional pair
for(color_1_idx=0; color_1_idx<3; color_1_idx++) {
for(color_2_idx=color_1_idx+1; color_2_idx<4; color_2_idx++) {
temp1 |= cards[color_1_idx] & cards[color_2_idx];
}
}
temp1 &= ~temp2; // remove Three of a Kind from found pairs
if(temp1) {
// with additional pair
kickerValue1 = determineKickerValue(temp2,0,0);
kickerValue2 = determineKickerValue(temp1,1,1);
if(bestHand) {
for(color_1_idx=3; color_1_idx>=0; color_1_idx--) bestHand[color_1_idx] = (cards[color_1_idx] & (kickerValue1.select | kickerValue2.select));
}
return 600000000 + kickerValue1.factorValue + kickerValue2.factorValue; // Full House
} else {
// without addition pair
kickerValue1 = determineKickerValue(temp2,0,0);
kickerValue2 = determineKickerValue(OR & ~temp2,1,2);
if(bestHand) {
for(color_1_idx=3; color_1_idx>=0; color_1_idx--) bestHand[color_1_idx] = (cards[color_1_idx] & (kickerValue1.select | kickerValue2.select));
}
return 300000000 + kickerValue1.factorValue + kickerValue2.factorValue; // Three of a Kind
}
}
}
// Two Pairs, Two of a Kind
temp1 = 0;
for(color_1_idx=0; color_1_idx<3; color_1_idx++) {
for(color_2_idx=color_1_idx+1; color_2_idx<4; color_2_idx++) {
temp1 |= (cards[color_1_idx] & cards[color_2_idx]);
}
}
if(temp1) {
if(Tools::bitcount(temp1) >= 2) { // at least two times Two of a Kind
kickerValue1 = determineKickerValue(temp1,0,1);
kickerValue2 = determineKickerValue(OR & ~kickerValue1.select,2,2);
if(bestHand) {
temp1 = (kickerValue1.select | kickerValue2.select);
for(color_1_idx=3; color_1_idx>=0; color_1_idx--) {
bestHand[color_1_idx] += (cards[color_1_idx] & temp1);
if(bestHand[color_1_idx] & kickerValue2.select) temp1 &= ~kickerValue2.select;
}
}
return 200000000 + kickerValue1.factorValue + kickerValue2.factorValue; // Two Pairs
} else {
kickerValue1 = determineKickerValue(temp1,0,0);
kickerValue2 = determineKickerValue(OR & ~temp1,1,3);
if(bestHand) {
for(color_1_idx=3; color_1_idx>=0; color_1_idx--) {
bestHand[color_1_idx] += (cards[color_1_idx] & (kickerValue1.select | kickerValue2.select));
}
}
return 100000000 + kickerValue1.factorValue + kickerValue2.factorValue; // Two of a Kind
}
}
// High Card
kickerValue1 = determineKickerValue(OR,0,4);
if(bestHand) {
for(color_1_idx=3; color_1_idx>=0; color_1_idx--) {
bestHand[color_1_idx] += (cards[color_1_idx] & kickerValue1.select);
}
}
return kickerValue1.factorValue;
}
static const int factor_kicker_short[4] = {1000000,10000,100,1};
static const int factor_kicker_long[5] = {1000000,10000,100,10,1};
KickerValue CardsValue::determineKickerValue(int testValue, int factorPointerStart, int factorPointerEnd)
{
KickerValue kickerValue;
kickerValue.factorValue = 0;
kickerValue.remain = testValue;
kickerValue.select = 0;
int compareValue = 4096;
int factorPointer = factorPointerStart;
for(int card_idx=0; (factorPointer<=factorPointerEnd) & (card_idx<13); card_idx++) {
if(kickerValue.remain >= compareValue) {
if(factorPointerEnd - factorPointerStart==4) kickerValue.factorValue += (12-card_idx)*factor_kicker_long[factorPointer];
else kickerValue.factorValue += (12-card_idx)*factor_kicker_short[factorPointer];
kickerValue.remain &= ~compareValue;
factorPointer++;
}
compareValue >>= 1;
}
kickerValue.select = testValue & ~kickerValue.remain;
return kickerValue;
}
int CardsValue::cardsValueOld(int cards[7], int position[5])
{ {
int array[7][3]; int array[7][3];
@@ -645,7 +809,7 @@ int CardsValue::cardsValue(int* cards, int* position)
} }
std::vector< std::vector<int> > CardsValue::calcCardsChance(GameState beRoID, int* playerCards, int* boardCards) std::vector< std::vector<int> > CardsValue::calcCardsChance(GameState beRoID, int playerCards[2], int boardCards[5])
{ {
int i,j; int i,j;
@@ -681,7 +845,7 @@ std::vector< std::vector<int> > CardsValue::calcCardsChance(GameState beRoID, in
if(j!=cards[0] && j!=cards[1] && j!=cards[2] && j!=cards[3] && j!=cards[4]) { if(j!=cards[0] && j!=cards[1] && j!=cards[2] && j!=cards[3] && j!=cards[4]) {
cards[5] = i; cards[5] = i;
cards[6] = j; cards[6] = j;
(chance[0][cardsValue(cards,0)/100000000])++; (chance[0][cardsValueOld(cards,0)/100000000])++;
sum++; sum++;
} }
} }
@@ -699,7 +863,7 @@ std::vector< std::vector<int> > CardsValue::calcCardsChance(GameState beRoID, in
for(i=0; i<52; i++) { for(i=0; i<52; i++) {
if(i!=cards[0] && i!=cards[1] && i!=cards[2] && i!=cards[3] && i!=cards[4] && i!=cards[5]) { if(i!=cards[0] && i!=cards[1] && i!=cards[2] && i!=cards[3] && i!=cards[4] && i!=cards[5]) {
cards[6] = i; cards[6] = i;
(chance[0][cardsValue(cards,0)/100000000])++; (chance[0][cardsValueOld(cards,0)/100000000])++;
sum++; sum++;
} }
} }
@@ -711,8 +875,8 @@ std::vector< std::vector<int> > CardsValue::calcCardsChance(GameState beRoID, in
} }
break; break;
case GAME_STATE_RIVER: { case GAME_STATE_RIVER: {
chance[0][cardsValue(cards,0)/100000000] = 100; chance[0][cardsValueOld(cards,0)/100000000] = 100;
chance[1][cardsValue(cards,0)/100000000] = 1; chance[1][cardsValueOld(cards,0)/100000000] = 1;
} }
break; break;
default: { default: {
+11 -4
View File
@@ -38,18 +38,25 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
struct KickerValue {
int factorValue;
int select;
int remain;
};
class CardsValue class CardsValue
{ {
public: public:
static int holeCardsClass(int, int); static int holeCardsClass(int, int);
static int cardsValue(int*, int*); static int cardsValue(int[4], int[4]);
static KickerValue determineKickerValue(int, int, int);
static int cardsValueOld(int[7], int[5]);
static std::string determineHandName(int myCardsValueInt, PlayerList activePlayerList); static std::string determineHandName(int myCardsValueInt, PlayerList activePlayerList);
static std::list<std::string> translateCardsValueCode(int cardsValueCode); static std::list<std::string> translateCardsValueCode(int cardsValueCode);
static int holeCardsToIntCode(int*); static int holeCardsToIntCode(int[2]);
static int* intCodeToHoleCards(int);
static std::vector< std::vector<int> > calcCardsChance(GameState, int*, int*); static std::vector< std::vector<int> > calcCardsChance(GameState, int[2], int[5]);
//static int** showdown(GameState, int**, int); //static int** showdown(GameState, int**, int);
}; };
+1 -1
View File
@@ -98,7 +98,7 @@ LocalHand::LocalHand(boost::shared_ptr<EngineFactory> f, GuiInterface *g, boost:
for(j=0; j<2; j++) tempPlayerAndBoardArray[j] = tempPlayerArray[j]; for(j=0; j<2; j++) tempPlayerAndBoardArray[j] = tempPlayerArray[j];
(*it)->setMyCards(tempPlayerArray); (*it)->setMyCards(tempPlayerArray);
(*it)->setMyCardsValueInt(CardsValue::cardsValue(tempPlayerAndBoardArray, bestHandPos)); (*it)->setMyCardsValueInt(CardsValue::cardsValueOld(tempPlayerAndBoardArray, bestHandPos));
(*it)->setMyBestHandPosition(bestHandPos); (*it)->setMyBestHandPosition(bestHandPos);
(*it)->setMyRoundStartCash((*it)->getMyCash()); (*it)->setMyRoundStartCash((*it)->getMyCash());
+10 -24
View File
@@ -905,18 +905,10 @@ LocalPlayer::LocalPlayer(ConfigFile *c, int id, unsigned uniqueId, PlayerType ty
} }
LocalPlayer::~LocalPlayer() LocalPlayer::~LocalPlayer()
{ {
} }
void LocalPlayer::setHand(HandInterface* br)
{
currentHand = br;
}
void LocalPlayer::action() void LocalPlayer::action()
{ {
@@ -1269,7 +1261,6 @@ void LocalPlayer::preflopEngine()
evaluation(bet, raise); evaluation(bet, raise);
} }
void LocalPlayer::flopEngine() void LocalPlayer::flopEngine()
{ {
@@ -1532,7 +1523,6 @@ void LocalPlayer::flopEngine()
} }
void LocalPlayer::turnEngine() void LocalPlayer::turnEngine()
{ {
@@ -1807,7 +1797,6 @@ void LocalPlayer::turnEngine()
} }
void LocalPlayer::riverEngine() void LocalPlayer::riverEngine()
{ {
@@ -2068,7 +2057,6 @@ void LocalPlayer::riverEngine()
} }
void LocalPlayer::evaluation(int bet, int raise) void LocalPlayer::evaluation(int bet, int raise)
{ {
@@ -2193,7 +2181,6 @@ void LocalPlayer::evaluation(int bet, int raise)
} }
int LocalPlayer::flopCardsValue(int* cards) int LocalPlayer::flopCardsValue(int* cards)
{ {
@@ -2827,7 +2814,6 @@ int LocalPlayer::flopCardsValue(int* cards)
} }
void LocalPlayer::calcMyOdds() void LocalPlayer::calcMyOdds()
{ {
@@ -2941,8 +2927,8 @@ void LocalPlayer::calcMyOdds()
tempOpponentCardsArray[1] = j; tempOpponentCardsArray[1] = j;
tempOpponentCardsArray[6] = k; tempOpponentCardsArray[6] = k;
tempMyCardsArray[6] = k; tempMyCardsArray[6] = k;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0); tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0); tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++; if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
} }
@@ -2995,8 +2981,8 @@ void LocalPlayer::calcMyOdds()
tempOpponentCardsArray[0] = i; tempOpponentCardsArray[0] = i;
tempOpponentCardsArray[1] = j; tempOpponentCardsArray[1] = j;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0); tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0); tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++; if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
} }
@@ -3490,8 +3476,8 @@ void LocalPlayer::flopEngine3()
tempOpponentCardsArray[6] = l; tempOpponentCardsArray[6] = l;
tempMyCardsArray[5] = k; tempMyCardsArray[5] = k;
tempMyCardsArray[6] = l; tempMyCardsArray[6] = l;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0); tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0); tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++; if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
@@ -3659,8 +3645,8 @@ void LocalPlayer::turnEngine3()
tempOpponentCardsArray[1] = j; tempOpponentCardsArray[1] = j;
tempOpponentCardsArray[6] = k; tempOpponentCardsArray[6] = k;
tempMyCardsArray[6] = k; tempMyCardsArray[6] = k;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0); tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0); tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++; if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
} }
@@ -3823,8 +3809,8 @@ void LocalPlayer::riverEngine3()
tempOpponentCardsArray[0] = i; tempOpponentCardsArray[0] = i;
tempOpponentCardsArray[1] = j; tempOpponentCardsArray[1] = j;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0); tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0); tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++; if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
} }
+3 -2
View File
@@ -48,8 +48,9 @@ public:
~LocalPlayer(); ~LocalPlayer();
void setHand(HandInterface *); void setHand(HandInterface *theValue) {
currentHand = theValue;
}
int getMyID() const { int getMyID() const {
return myID; return myID;
} }
+10
View File
@@ -83,3 +83,13 @@ void Tools::GetRand(int minValue, int maxValue, unsigned count, int *out)
} }
} }
int Tools::bitcount(int in)
{
int count=0 ;
while (in) {
count++ ;
in &= (in - 1) ;
}
return count ;
}
+1
View File
@@ -38,6 +38,7 @@ public:
static void ShuffleArrayNonDeterministic(int *inout, unsigned count); static void ShuffleArrayNonDeterministic(int *inout, unsigned count);
static void GetRand(int minValue, int maxValue, unsigned count, int *out); static void GetRand(int minValue, int maxValue, unsigned count, int *out);
static int bitcount(int in);
}; };