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
if(cards[0]%13 == cards[1]%13) {
return ((cards[0]%13)*1000 + (cards[0]%13)*10);
if(holeCards[0]%13 == holeCards[1]%13) {
return ((holeCards[0]%13)*1000 + (holeCards[0]%13)*10);
} else {
if(cards[0]%13 < cards[1]%13) {
if(cards[0]/13 == cards[1]/13) {
return ((cards[0]%13)*1000 + (cards[1]%13)*10 + 1);
if(holeCards[0]%13 < holeCards[1]%13) {
if(holeCards[0]/13 == holeCards[1]/13) {
return ((holeCards[0]%13)*1000 + (holeCards[1]%13)*10 + 1);
} else {
return ((cards[0]%13)*1000 + (cards[1]%13)*10);
return ((holeCards[0]%13)*1000 + (holeCards[1]%13)*10);
}
} else {
if(cards[0]/13 == cards[1]/13) {
return ((cards[1]%13)*1000 + (cards[0]%13)*10 + 1);
if(holeCards[0]/13 == holeCards[1]/13) {
return ((holeCards[1]%13)*1000 + (holeCards[0]%13)*10 + 1);
} 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
int* CardsValue::intCodeToHoleCards(int code)
static const int straight[10] = { 7936, 3968, 1984, 992, 496, 248, 124, 62, 31, 4111 };
int CardsValue::cardsValue(int cards[4], int bestHand[4])
{
int color_1_idx;
int card_idx;
KickerValue kickerValue1;
// one possibility !!!
int* cards = new int[2];
cards[0] = code/1000;
cards[1] = (code-cards[0]*1000)/10;
if(cards[0]==cards[1]) {
cards[1] +=13;
} else {
if(code%10 == 0) cards[1] +=13;
// Royal Flush, Straight Flush, Flush
for(color_1_idx=0; color_1_idx<4; color_1_idx++) { // check all colors
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
if(bestHand) bestHand[color_1_idx] = straight[0];
return 900000000; // Royal Flush
} else {
for(card_idx=1; card_idx<10; card_idx++) {
if((cards[color_1_idx] & straight[card_idx]) == straight[card_idx]) { // check for Straight Flush
if(bestHand) bestHand[color_1_idx] = straight[card_idx];
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];
@@ -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;
@@ -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]) {
cards[5] = i;
cards[6] = j;
(chance[0][cardsValue(cards,0)/100000000])++;
(chance[0][cardsValueOld(cards,0)/100000000])++;
sum++;
}
}
@@ -699,7 +863,7 @@ std::vector< std::vector<int> > CardsValue::calcCardsChance(GameState beRoID, in
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]) {
cards[6] = i;
(chance[0][cardsValue(cards,0)/100000000])++;
(chance[0][cardsValueOld(cards,0)/100000000])++;
sum++;
}
}
@@ -711,8 +875,8 @@ std::vector< std::vector<int> > CardsValue::calcCardsChance(GameState beRoID, in
}
break;
case GAME_STATE_RIVER: {
chance[0][cardsValue(cards,0)/100000000] = 100;
chance[1][cardsValue(cards,0)/100000000] = 1;
chance[0][cardsValueOld(cards,0)/100000000] = 100;
chance[1][cardsValueOld(cards,0)/100000000] = 1;
}
break;
default: {
+11 -4
View File
@@ -38,18 +38,25 @@
#include <iostream>
#include <vector>
struct KickerValue {
int factorValue;
int select;
int remain;
};
class CardsValue
{
public:
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::list<std::string> translateCardsValueCode(int cardsValueCode);
static int holeCardsToIntCode(int*);
static int* intCodeToHoleCards(int);
static int holeCardsToIntCode(int[2]);
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);
};
+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];
(*it)->setMyCards(tempPlayerArray);
(*it)->setMyCardsValueInt(CardsValue::cardsValue(tempPlayerAndBoardArray, bestHandPos));
(*it)->setMyCardsValueInt(CardsValue::cardsValueOld(tempPlayerAndBoardArray, bestHandPos));
(*it)->setMyBestHandPosition(bestHandPos);
(*it)->setMyRoundStartCash((*it)->getMyCash());
+10 -24
View File
@@ -905,18 +905,10 @@ LocalPlayer::LocalPlayer(ConfigFile *c, int id, unsigned uniqueId, PlayerType ty
}
LocalPlayer::~LocalPlayer()
{
}
void LocalPlayer::setHand(HandInterface* br)
{
currentHand = br;
}
void LocalPlayer::action()
{
@@ -1269,7 +1261,6 @@ void LocalPlayer::preflopEngine()
evaluation(bet, raise);
}
void LocalPlayer::flopEngine()
{
@@ -1532,7 +1523,6 @@ void LocalPlayer::flopEngine()
}
void LocalPlayer::turnEngine()
{
@@ -1807,7 +1797,6 @@ void LocalPlayer::turnEngine()
}
void LocalPlayer::riverEngine()
{
@@ -2068,7 +2057,6 @@ void LocalPlayer::riverEngine()
}
void LocalPlayer::evaluation(int bet, int raise)
{
@@ -2193,7 +2181,6 @@ void LocalPlayer::evaluation(int bet, int raise)
}
int LocalPlayer::flopCardsValue(int* cards)
{
@@ -2827,7 +2814,6 @@ int LocalPlayer::flopCardsValue(int* cards)
}
void LocalPlayer::calcMyOdds()
{
@@ -2941,8 +2927,8 @@ void LocalPlayer::calcMyOdds()
tempOpponentCardsArray[1] = j;
tempOpponentCardsArray[6] = k;
tempMyCardsArray[6] = k;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0);
tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
}
@@ -2995,8 +2981,8 @@ void LocalPlayer::calcMyOdds()
tempOpponentCardsArray[0] = i;
tempOpponentCardsArray[1] = j;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0);
tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
}
@@ -3490,8 +3476,8 @@ void LocalPlayer::flopEngine3()
tempOpponentCardsArray[6] = l;
tempMyCardsArray[5] = k;
tempMyCardsArray[6] = l;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0);
tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
@@ -3659,8 +3645,8 @@ void LocalPlayer::turnEngine3()
tempOpponentCardsArray[1] = j;
tempOpponentCardsArray[6] = k;
tempMyCardsArray[6] = k;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0);
tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
}
@@ -3823,8 +3809,8 @@ void LocalPlayer::riverEngine3()
tempOpponentCardsArray[0] = i;
tempOpponentCardsArray[1] = j;
tempMyCardsValue = CardsValue::cardsValue(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValue(tempOpponentCardsArray,0);
tempMyCardsValue = CardsValue::cardsValueOld(tempMyCardsArray,0);
tempOpponentCardsValue = CardsValue::cardsValueOld(tempOpponentCardsArray,0);
if(tempMyCardsValue>=tempOpponentCardsValue) countMy++;
}
+3 -2
View File
@@ -48,8 +48,9 @@ public:
~LocalPlayer();
void setHand(HandInterface *);
void setHand(HandInterface *theValue) {
currentHand = theValue;
}
int getMyID() const {
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 GetRand(int minValue, int maxValue, unsigned count, int *out);
static int bitcount(int in);
};