Похоже, вы пытаетесь создать калькулятор капитала. Я тоже так делал, но не для Омахи (вместо этого Техасский Холдем). С учетом того, что игроки могли оценить, у меня есть ~ 200K рук в секунду, что дает достаточно точный результат в кратчайшие сроки. Если там только два игрока
оценивать, я могу получить до 4 миллионов оценок в секунду.
Я использовал битовые маски для рук. Одно 64-разрядное целое число для представления карты, руки или всей доски. Вам нужно всего лишь 52 из этого, очевидно. Используя побитовые операторы, дела идут довольно быстро. Вот быстрый пример из моего проекта (на C ++, хотя). Это использует 2 + 2 оценщика
для быстрого поиска:
while (trial < trials) {
/** I use here a linked list over the hand-distributions (players).
* This is kind of natural as well, as circle is the basic
* shape of poker.
*/
pDist = pFirstDist;
unsigned __int64 usedCards = _deadCards;
bool collision;
/** Here, we choose random distributions for the comparison.
* There is a chance, that two separate distributions has
* the same card being picked-up. In that case, we have a collision,
* so do the choosing again.
*/
do {
pDist->Choose(usedCards, collision);
/** If there is only one hand in the distribution (unary),
* there is no need to check over collision, since it's been
* already done in the phase building them (distributions).
*/
if (pDist->_isUnary)
collision = false;
pDist = pDist->_pNext;
} while (pDist != pFirstDist && !collision);
if (collision) {
/** Oops! Collision occurred! Take the next player (hand-
* distribution and do this all over again.
*
*/
pFirstDist = pDist->_pNext;
continue;
}
unsigned __int64 board = 0;
/** Pick a board from the hashed ones, until it's unique compared to
* the distributions.
*
*/
do {
if (count == 1) {
board = boards[0];
collision = false;
} else {
board = boards[Random()];
collision = (board & usedCards) != 0;
}
} while (collision);
board |= _boardCards;
int best = 0, s = 1;
do {
pDist->_currentHand |= board;
unsigned long i, l = static_cast<unsigned long>(pDist->_currentHand >> 32);
int p;
bool f = false;
/** My solution to find out the set bits.
* Since I'm working on a 32-bit environment, the "64-bit"
* variable needs to be split in to parts.
*/
if (_BitScanForward(&i, l)) {
p = _evaluator->_handRanks[53 + i + 32]; // Initial entry to the 2 + 2 evaluator hash.
l &= ~(static_cast<unsigned long>(1) << i);
f = true;
}
if (f)
while (_BitScanForward(&i, l)) {
l &= ~(static_cast<unsigned long>(1) << i);
p = _evaluator->_handRanks[p + i + 32];
}
l = static_cast<unsigned long>(pDist->_currentHand & 0xffffffff);
if (!f) {
_BitScanForward(&i, l);
p = _evaluator->_handRanks[53 + i];
l &= ~(static_cast<unsigned long>(1) << i);
}
while (_BitScanForward(&i, l)) {
l &= ~(static_cast<unsigned long>(1) <<_handRanks[p + i];
}
pDist->_rank = p;
/** Keep the statistics up. Please do remember, that
* equity consist of ties as well, so it's not a percentual
* chance of winning.
*/
if (p > best) {
pWinner = pDist;
s = 1;
best = p;
} else if (p == best)
++s;
pDist = pDist->_pNext;
} while (pDist != pFirstDist);
if (s > 1) {
for (unsigned int i = 0; i _rank == best) {
_handDistributions[i]->_ties += 1.0f / s;
_handDistributions[i]->_equity += 1.0f / s;
}
} else {
++pWinner->_wins;
++pWinner->_equity;
}
++trial;
pFirstDist = pDist->_pNext;
}
Пожалуйста, обратитесь к оценщику 2 + 2, который довольно легко адаптировать к вашим собственным потребностям.