implement new cards value function; circa factor 10 faster than old version
This commit is contained in:
@@ -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: {
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,9 @@ public:
|
||||
|
||||
~LocalPlayer();
|
||||
|
||||
void setHand(HandInterface *);
|
||||
|
||||
void setHand(HandInterface *theValue) {
|
||||
currentHand = theValue;
|
||||
}
|
||||
int getMyID() const {
|
||||
return myID;
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user