void CIteratorThread::StandardDealingAlgorithmForUpTo13Opponents(int nopponents) { unsigned int card = 0; write_log(Preferences()->debug_prwin(), "[PrWinThread] Using random algorithm, as f$prwin_number_of_opponents <= 13\n"); // random replacement algorithm // opponent cards if (nopponents < 1) { write_log(Preferences()->debug_prwin(), "[PrWinThread] No opponents. Auto-adapting to 1.\n"); nopponents = 1; } for (int i=0; i<nopponents*NumberOfCardsPerPlayer(); i+=NumberOfCardsPerPlayer()) { temp_usedCards=usedCards; do { usedCards = temp_usedCards; //reset the card mask to clear settings from failed card assignments for (int j=0; j<NumberOfCardsPerPlayer(); j++) { card = GetRandomCard(); CardMask_SET(usedCards, card); ocard[i+j] = card; } if (!_willplay) { write_log(Preferences()->debug_prwin(), "[PrWinThread] Weighting disabled. Willplay is 0.\n"); break; //0 disables weighting } //put break for i=0 and opponent unraised BB case (cannot assume anything about his cards) //In round 1 we should really do an analysis of chairs to find out how many have still to //place a bet. Not implemented since accuracy of prwin pre-flop is less critical. // // bblimp and special handling for checking players removed in OH 9.2.8 // as it was broken and we consider it useless / even harmful. // http://www.maxinmontreal.com/forums/viewtopic.php?f=156&t=19064 } while (!IsHandInWeightedRange(ocard[i], ocard[i+1], _willplay, _wontplay, _topclip, _mustplay)); } // additional common cards CardMask_RESET(addlcomCards); for (int i=0; i<(kNumberOfCommunityCards - _ncomCards); i++) { card = GetRandomCard(); CardMask_SET(usedCards, card); CardMask_SET(addlcomCards, card); } }
static void parseArgs(int argc, char **argv) { int i, c; for (i = 1; i < argc; ++i) { if (!strcmp(argv[i], "-low")) gLow = 1; else if (!strcmp(argv[i], "-hl")) gHighLow = 1; else { if (Deck_stringToCard(argv[i], &c) == 0) goto error; if (!CardMask_CARD_IS_SET(gCards, c)) { CardMask_SET(gCards, c); ++gNCards; }; }; } return; error: fprintf(stderr, "Usage: eval [ -low ] [ -hl ] cards \n"); exit(0); }
void CIteratorThread::InitIteratorLoop() { write_log(preferences.debug_prwin(), "[PrWinThread] Initializing iterator loop\n"); // Set starting status and parameters InitNumberOfIterations(); // player cards CardMask_RESET(_plCards); CardMask_RESET(_comCards); _nplCards = _ncomCards = 0; // Counters _win = _tie = _los = 0; int userchair = p_symbol_engine_userchair->userchair(); if (userchair == k_undefined) return; // setup masks AssertRange(userchair, 0, k_max_chair_number); for (int i=0; i<k_number_of_cards_per_player; i++) { Card card = p_table_state->User()->_hole_cards[i]; if (card.IsKnownCard()) { CardMask_SET(_plCards, card.GetValue()); _nplCards++; } } for (int i=0; i<k_number_of_community_cards; i++) { Card card = p_table_state->_common_cards[i]; if (card.IsKnownCard()) { CardMask_SET(_comCards, card.GetValue()); _ncomCards++; } } //Weighted prwin only for nopponents <=13 _willplay = p_function_collection->Evaluate("f$prwin_willplay"); _wontplay = p_function_collection->Evaluate("f$prwin_wontplay"); _mustplay = p_function_collection->Evaluate("f$prwin_mustplay"); _topclip = p_function_collection->Evaluate("f$prwin_topclip"); // Call prw1326 callback if needed if (_prw1326.useme==1326 && _prw1326.usecallback==1326 && (p_betround_calculator->betround()!= k_betround_preflop || _prw1326.preflop==1326) ){ _prw1326.prw_callback(); //Matrix 2008-05-09 } }
// Evaluate the best 7 card hand given our hole cards and 5 common_cards // TODO: Change this to evalute best 5+ card hand // TODO: Change this to store common cards (so we can print it out later) unsigned int Hand::Evaluate(const CommonCards& common_cards) { CardMask eval_cards; // char buf[256]; // Debug::log(LDEBUG) << "Hand: " << (*this) << std::endl; // Debug::log(LDEBUG) << "Common cards: " << common_cards << std::endl; // Set a poker-eval card mask with the values of all the cards CardMask_RESET(eval_cards); CardMask_SET(eval_cards, pokereval_cards[0]); CardMask_SET(eval_cards, pokereval_cards[1]); CardMask_SET(eval_cards, ConvertCardToPokerEvalCard(common_cards.flop1)); CardMask_SET(eval_cards, ConvertCardToPokerEvalCard(common_cards.flop2)); CardMask_SET(eval_cards, ConvertCardToPokerEvalCard(common_cards.flop3)); CardMask_SET(eval_cards, ConvertCardToPokerEvalCard(common_cards.turn)); CardMask_SET(eval_cards, ConvertCardToPokerEvalCard(common_cards.river)); // StdDeck_maskToString(eval_cards, buf); // Debug::log(LDEBUG) << "Mask: " << buf << std::endl; // Get my handval/pokerval hand_value = Hand_EVAL_N(eval_cards, 7); // StdRules_HandVal_toString(hand_value, buf); // Debug::log(LDEBUG) << "Hand_EVAL_N: " << buf << std::endl << std::endl; return hand_value; }
static int PyList2CardMask(PyObject* object, CardMask* cardsp) { CardMask cards; int cards_size = 0; int valid_cards_size = 0; if(!PyList_Check(object)) { PyErr_SetString(PyExc_TypeError, "expected a list of cards"); return -1; } valid_cards_size = cards_size = PyList_Size(object); CardMask_RESET(cards); int card; int i; for(i = 0; i < cards_size; i++) { card = -1; PyObject* pycard = PyList_GetItem(object, i); if(PyErr_Occurred()) return -1; if(PyString_Check(pycard)) { char* card_string = PyString_AsString(pycard); if(!strcmp(card_string, "__")) { card = 255; } else { if(Deck_stringToCard(card_string, &card) == 0) { PyErr_Format(PyExc_RuntimeError, "card %s is not a valid card name", card_string); return -1; } } } else if(PyInt_Check(pycard)) { card = PyInt_AsLong(pycard); if(card != NOCARD && (card < 0 || card > StdDeck_N_CARDS)) { PyErr_Format(PyExc_TypeError, "card value (%d) must be in the range [0-%d]", card, StdDeck_N_CARDS); return -1; } } else { PyErr_SetString(PyExc_TypeError, "card must be a string or an int"); return -1; } if(card == NOCARD) valid_cards_size--; else CardMask_SET(cards, card); } *cardsp = cards; return valid_cards_size; }
void CIteratorThread::SwapDealingAlgorithmForMoreThan13Opponents(int nopponents) { write_log(preferences.debug_prwin(), "[PrWinThread] Useing swap-algorithm, as f$prwin_number_of_opponents > 13\n"); // swap alogorithm // weighted prwin not implemented for this case int numberOfCards = k_number_of_cards_per_deck; for (int i=0; i<numberOfCards; i++) { deck[i] = i; } while (numberOfCards >= 1) { int selected_card = rand() % numberOfCards; numberOfCards--; if (selected_card != numberOfCards) { SwapInts(&deck[selected_card], &deck[numberOfCards]); } } // opponent cards int x = 0; for (int i=0; i<nopponents*k_number_of_cards_per_player; i++) { while (CardMask_CARD_IS_SET(usedCards, deck[x]) && (x < k_number_of_cards_per_deck)) { x++; } ocard[i] = deck[x++]; } // additional common cards CardMask_RESET(addlcomCards); for (int i=0; i<(k_number_of_community_cards - _ncomCards); i++) { while (CardMask_CARD_IS_SET(usedCards, deck[x]) && (x < k_number_of_cards_per_deck)) { x++; } CardMask_SET(addlcomCards, deck[x++]); } }
static int rbList2CardMask(VALUE object, CardMask* cardsp) { CardMask cards; int cards_size = 0; int valid_cards_size = 0; if (TYPE(object) != T_ARRAY) { rb_fatal("expected a list of cards"); } valid_cards_size = cards_size = RARRAY_LENINT(object); CardMask_RESET(cards); int card; int i; for(i = 0; i < cards_size; i++) { card = -1; char* card_string = RSTRING_PTR(rb_ary_entry(object, i)); if(!strcmp(card_string, "__")) card = 255; else if(Deck_stringToCard(card_string, &card) == 0) rb_fatal("card %s is not a valid card name", card_string); if(card == NOCARD) valid_cards_size--; else CardMask_SET(cards, card); } *cardsp = cards; return valid_cards_size; }
UINT CIteratorThread::IteratorThreadFunction(LPVOID pParam) { CIteratorThread *pParent = static_cast<CIteratorThread*>(pParam); // Loop-variables j, k get used inside and outside loops. // It is a bit messy, nearly impossible to fix it. // At least the outer loops ("f$prwin_number_of_iterations" and "i") could be improved. unsigned int pl_pokval = 0, opp_pokval = 0, opp_pokvalmax = 0; HandVal pl_hv = 0, opp_hv = 0; int dummy = 0; int sym_nopponents = p_symbol_engine_prwin->nopponents_for_prwin(); bool hand_lost; ResetGlobalVariables(); // Seed the RNG srand((unsigned)GetTickCount()); // // Main iterator loop // write_log(preferences.debug_prwin(), "[PrWinThread] Start of main loop.\n"); // "f$prwin_number_of_iterations" has to be declared outside of the loop, // as we check afterwards, if the loop terminated successfully. AdjustPrwinVariablesIfNecessary(pParent); unsigned int nit; for (nit=0; nit < iter_vars.nit(); nit++) { // Check event for thread stop signal if(::WaitForSingleObject(pParent->_m_stop_thread, 0) == WAIT_OBJECT_0) { // Set event ::SetEvent(pParent->_m_wait_thread); AfxEndThread(0); } CardMask_OR(usedCards, pParent->_plCards, pParent->_comCards); if (UseEnhancedPrWin()) { EnhancedDealingAlgorithm(); } else { StandardDealingAlgorithm(sym_nopponents); } // Get my handval/pokerval CardMask_OR(evalCards, pParent->_plCards, pParent->_comCards); CardMask_OR(evalCards, evalCards, addlcomCards); pl_hv = Hand_EVAL_N(evalCards, 7); pl_pokval = p_symbol_engine_pokerval->CalculatePokerval(pl_hv, 7, &dummy, CARD_NOCARD, CARD_NOCARD); // Scan through opponents' handvals/pokervals // - if we find one better than ours, then we are done, increment los // - for win/tie, we need to wait until we scan them all opp_pokvalmax = 0; hand_lost = false; for (int i=0; i<sym_nopponents; i++) { CardMask_RESET(opp_evalCards); CardMask_OR(opp_evalCards, pParent->_comCards, addlcomCards); CardMask_SET(opp_evalCards, ocard[i*2]); CardMask_SET(opp_evalCards, ocard[(i*2)+1]); opp_hv = Hand_EVAL_N(opp_evalCards, 7); opp_pokval = p_symbol_engine_pokerval->CalculatePokerval(opp_hv, 7, &dummy, CARD_NOCARD, CARD_NOCARD); if (opp_pokval>pl_pokval) { _los++; hand_lost = true; break; } else { if (opp_pokval > opp_pokvalmax) { opp_pokvalmax = opp_pokval; } } } if (!hand_lost) { if (pl_pokval > opp_pokvalmax) { _win++; } else { _tie++; } } UpdateIteratorVarsForDisplay(nit); } write_log(preferences.debug_prwin(), "[PrWinThread] End of main loop.\n"); if (SimulationFinished(nit)) { iter_vars.set_iterator_thread_running(false); iter_vars.set_iterator_thread_complete(true); UpdateIteratorVarsForDisplay(nit); } else { iter_vars.set_iterator_thread_running(false); iter_vars.set_iterator_thread_complete(false); iter_vars.set_iterator_thread_progress(0); //??? iter_vars.set_nit(0); for (int i=0; i<k_number_of_cards_per_player; i++) iter_vars.set_pcard(i, CARD_NOCARD); for (int i=0; i<k_number_of_community_cards; i++) { iter_vars.set_ccard(i, CARD_NOCARD); } ResetIteratorVars(); } ::SetEvent(pParent->_m_wait_thread); StopIteratorThread(); return 0; }
UINT CIteratorThread::IteratorThreadFunction(LPVOID pParam) { CIteratorThread *pParent = static_cast<CIteratorThread*>(pParam); // Loop-variables j, k get used inside and outside loops. // It is a bit messy, nearly impossible to fix it. // At least the outer loops ("f$prwin_number_of_iterations" and "i") could be improved. unsigned int pl_pokval = 0, opp_pokval = 0, opp_pokvalmax = 0; HandVal pl_hv = 0, opp_hv = 0; int dummy = 0; bool hand_lost; ResetGlobalVariables(); // Seed the RNG srand((unsigned)GetTickCount()); while (true) { // Check event for thread stop signal once per main iterator loop // (and additionally once every 1000 iterations later) if(::WaitForSingleObject(pParent->_m_stop_thread, 0) == WAIT_OBJECT_0) { // Set event ::SetEvent(pParent->_m_wait_thread); AfxEndThread(0); } Sleep(500); if (!p_symbol_engine_autoplayer->ismyturn()) { // Not my turn; // Nothing to simulate continue; } if (IteratorThreadComplete()) { // No longer anything to do continue; } // // Main iterator loop // write_log(preferences.debug_prwin(), "[PrWinThread] Start of main loop.\n"); // "f$prwin_number_of_iterations" has to be declared outside of the loop, // as we check afterwards, if the loop terminated successfully. _nopponents = p_symbol_engine_prwin->nopponents_for_prwin(); AdjustPrwinVariablesIfNecessary(); for (_iterations_calculated=0; _iterations_calculated < _iterations_required; ++_iterations_calculated) { // Check event for thread stop signal once every 1000 iterations if ((_iterations_calculated % 1000 == 0) && (_iterations_calculated > 0) && (::WaitForSingleObject(pParent->_m_stop_thread, 0) == WAIT_OBJECT_0)) { // Set event ::SetEvent(pParent->_m_wait_thread); AfxEndThread(0); } CardMask_OR(usedCards, pParent->_plCards, pParent->_comCards); if (UseEnhancedPrWin()) { EnhancedDealingAlgorithm(); } else { StandardDealingAlgorithm(_nopponents); } // Get my handval/pokerval CardMask_OR(evalCards, pParent->_plCards, pParent->_comCards); CardMask_OR(evalCards, evalCards, addlcomCards); pl_hv = Hand_EVAL_N(evalCards, 7); pl_pokval = p_symbol_engine_pokerval->CalculatePokerval(pl_hv, 7, &dummy, CARD_NOCARD, CARD_NOCARD);//?? // Scan through opponents' handvals/pokervals // - if we find one better than ours, then we are done, increment los // - for win/tie, we need to wait until we scan them all opp_pokvalmax = 0; hand_lost = false; for (int i=0; i<_nopponents; i++) { CardMask_RESET(opp_evalCards); CardMask_OR(opp_evalCards, pParent->_comCards, addlcomCards); CardMask_SET(opp_evalCards, ocard[i*2]); CardMask_SET(opp_evalCards, ocard[(i*2)+1]); opp_hv = Hand_EVAL_N(opp_evalCards, 7); opp_pokval = p_symbol_engine_pokerval->CalculatePokerval(opp_hv, 7, &dummy, CARD_NOCARD, CARD_NOCARD); write_log(preferences.debug_prwin(), "[PrWinThread] PlayerPV: %i OppPV: %i\n", pl_pokval, opp_pokval); if (opp_pokval > pl_pokval) { write_log(preferences.debug_prwin(), "[PrWinThread] Lost\n"); _los++; hand_lost = true; break; } else { if (opp_pokval > opp_pokvalmax) { opp_pokvalmax = opp_pokval; } } } if (!hand_lost) { if (pl_pokval > opp_pokvalmax) { write_log(preferences.debug_prwin(), "[PrWinThread] Won\n"); _win++; } else { write_log(preferences.debug_prwin(), "[PrWinThread] Tie\n"); _tie++; } } UpdateIteratorVarsForDisplay(); } write_log(preferences.debug_prwin(), "[PrWinThread] End of main loop.\n"); if (!IteratorThreadComplete()) { // Computation stopped with some kind of error. // Reset vars to avoid bogus data ResetIteratorVars(); } UpdateIteratorVarsForDisplay(); ::SetEvent(pParent->_m_wait_thread); } return 0; }
void write_logautoplay(const char * action) { char nowtime[26]; CString pcards, comcards, temp, rank, pokerhand, bestaction, fcra_seen; char *card; CardMask Cards; int nCards; CString fcra_formula_status; int sym_userchair = (int) p_symbol_engine_userchair->userchair(); int betround = (int) p_betround_calculator->betround(); if (!prefs.trace_enabled()) return; if (log_fp != NULL) { CSLock lock(log_critsec); // log$ writing if (prefs.log_symbol_enabled()) { int max_log = p_symbols->logsymbols_collection()->GetCount(); if (max_log > 0) { if (max_log > prefs.log_symbol_max_log()) { max_log = prefs.log_symbol_max_log(); } write_log(k_always_log_basic_information, "*** log$ (Total: %d | Showing: %d)\n", p_symbols->logsymbols_collection()->GetCount(), max_log); for (int i=0; i<max_log; i++) { write_log(k_always_log_basic_information, "*** %s\n", p_symbols->logsymbols_collection()->GetAt(i)); } } } CardMask_RESET(Cards); nCards=0; // player cards if (p_symbol_engine_userchair->userchair_confirmed()) { for (int i=0; i<=1; i++) { card = StdDeck_cardString(p_scraper->card_player(sym_userchair, i)); temp.Format("%s", card); pcards.Append(temp); CardMask_SET(Cards, p_scraper->card_player(sym_userchair, i)); nCards++; } } else { pcards = "...."; } // common cards comcards = ""; if (betround >= k_betround_flop) { for (int i=0; i<=2; i++) { if (p_scraper->card_common(i) != CARD_BACK && p_scraper->card_common(i) != CARD_NOCARD) { card = StdDeck_cardString(p_scraper->card_common(i)); temp.Format("%s", card); comcards.Append(temp); CardMask_SET(Cards, p_scraper->card_common(i)); nCards++; } } } if (betround >= k_betround_turn) { card = StdDeck_cardString(p_scraper->card_common(3)); temp.Format("%s", card); comcards.Append(temp); CardMask_SET(Cards, p_scraper->card_common(3)); nCards++; } if (betround >= k_betround_river) { card = StdDeck_cardString(p_scraper->card_common(4)); temp.Format("%s", card); comcards.Append(temp); CardMask_SET(Cards, p_scraper->card_common(4)); nCards++; } comcards.Append(".........."); comcards = comcards.Left(10); // Always use handrank169 here rank.Format("%.0f", p_symbol_engine_handrank->handrank169()); // poker hand pokerhand = p_symbol_engine_pokerval->HandType(); // best action if (strcmp(action, "SWAG")==0) { bestaction.Format("$%.2f", p_autoplayer_functions->f$betsize()); } else { if (p_autoplayer_functions->f$alli()) bestaction = "Allin"; else if (p_autoplayer_functions->f$betsize()) bestaction = "SWAG"; else if (p_autoplayer_functions->f$rais()) bestaction = "Bet/Raise"; else if (p_autoplayer_functions->f$call()) bestaction = "Call/Check"; else if (p_autoplayer_functions->f$prefold()) bestaction = "Pre-fold"; else bestaction = "Fold/Check"; } // fcra_seen int sym_myturnbits = p_symbol_engine_autoplayer->myturnbits(); fcra_seen.Format("%s%s%s%s%s", sym_myturnbits&0x01 ? "F" : ".", sym_myturnbits&0x02 ? "C" : ".", // Check button out of order to stay consistent // with button order in manual mode. sym_myturnbits&0x10 ? "K" : ".", sym_myturnbits&0x04 ? "R" : ".", sym_myturnbits&0x08 ? "A" : "."); // fcra formula status fcra_formula_status.Format("%s%s%s%s", !p_autoplayer_functions->f$alli() && !p_autoplayer_functions->f$rais() && !p_autoplayer_functions->f$call() && !p_autoplayer_functions->f$betsize() ? "F" : ".", p_autoplayer_functions->f$call() ? "C" : ".", p_autoplayer_functions->f$rais() ? "R" : ".", p_autoplayer_functions->f$alli() ? "A" : "."); fprintf(log_fp, "%s - %1d ", get_time(nowtime), p_tablemap->nchairs()); fprintf(log_fp, "%4s %10s %4s %5s ", pcards.GetString(), comcards.GetString(), rank.GetString(), pokerhand.GetString()); fprintf(log_fp, "%4d %4d %4d ", (iter_vars.prwin() * 1000), (iter_vars.prlos() * 1000), (iter_vars.prtie() * 1000)); fprintf(log_fp, "%2d %8d %-10s - ", p_symbol_engine_prwin->nopponents_for_prwin(), iter_vars.nit(), bestaction.GetString()); fprintf(log_fp, "%-5s %9.2f %9.2f %9.2f ", action, p_symbol_engine_chip_amounts->call(), p_tablelimits->bet(), p_symbol_engine_chip_amounts->pot()); int userchair = p_symbol_engine_userchair->userchair(); fprintf(log_fp, "%9.2f - %s %s %.2f\n", p_symbol_engine_chip_amounts->balance(userchair), fcra_seen.GetString(), fcra_formula_status.GetString(), p_autoplayer_functions->f$betsize() ); if (prefs.trace_enabled() && p_symbols->symboltrace_collection()->GetSize() > 0) { write_log_nostamp(1, "***** Autoplayer Trace ****\n"); for (int i=0; i<p_symbols->symboltrace_collection()->GetSize(); i++) { write_log_nostamp(1, "%s\n", p_symbols->symboltrace_collection()->GetAt(i)); } write_log_nostamp(1, "***********************\n"); } fflush(log_fp); } }
bool CVersus::GetCounts(void) { if (_versus_fh == k_undefined) return false; int i = 0, j = 0; CardMask plCards, oppCards, deadCards, comCardsScrape, comCardsEnum, comCardsAll, usedCards; unsigned int wintemp = 0, tietemp = 0, lostemp = 0, offset = 0; unsigned int nhiwin = 0, nhitie = 0, nhilos = 0, ntiwin = 0, ntitie = 0, ntilos = 0, nlowin = 0, nlotie = 0, nlolos = 0; unsigned int nhinowwin = 0, nhinowtie = 0, nhinowlos = 0, ntinowwin = 0, ntinowtie = 0, ntinowlos = 0, nlonowwin = 0, nlonowtie = 0, nlonowlos = 0; unsigned int c0rank = 0, c1rank = 0, temprank = 0; BYTE byte[8] = {0}; long pos = 0; int listnum = 0; int card0_offset[52] = { 0, 62475, 123725, 183750, 242550, 300125, 356475, 411600, 465500, 518175, 569625, 619850, 668850, 716625, 763175, 808500, 852600, 895475, 937125, 977550, 1016750, 1054725, 1091475, 1127000, 1161300, 1194375, 1226225, 1256850, 1286250, 1314425, 1341375, 1367100, 1391600, 1414875, 1436925, 1457750, 1477350, 1495725, 1512875, 1528800, 1543500, 1556975, 1569225, 1580250, 1590050, 1598625, 1605975, 1612100, 1617000, 1620675, 1623125, 1624350 }; int betround = p_betround_calculator->betround(); int sym_userchair = (int) p_symbol_engine_userchair->userchair(); unsigned int pcard[2] = {0}; for (i=0; i<=1; i++) pcard[i] = CARD_NOCARD; unsigned int card_player[2] = {0}, card_common[5] = {0}; for (i=0; i<=1; i++) card_player[i] = p_scraper->card_player(sym_userchair, i); for (i=0; i<=4; i++) card_common[i] = p_scraper->card_common(i); // Get the lock CSLock lock(m_critsec); if (!p_symbol_engine_userchair->userchair_confirmed()) return false; if (card_player[0] == CARD_NOCARD || card_player[0] == CARD_BACK || card_player[1] == CARD_NOCARD || card_player[1] == CARD_BACK) { return false; } _nwin = _ntie = _nlos = _nhands = 0; _nhandshi = _nhandsti = _nhandslo = 0; _nhandshinow = _nhandstinow = _nhandslonow = 0; _vsprwinhi = _vsprtiehi = _vsprloshi = 0; _vsprwinti = _vsprtieti = _vsprlosti = 0; _vsprwinlo = _vsprtielo = _vsprloslo = 0; _vsprwinhinow = _vsprtiehinow = _vsprloshinow = 0; _vsprwintinow = _vsprtietinow = _vsprlostinow = 0; _vsprwinlonow = _vsprtielonow = _vsprloslonow = 0; nhiwin = nhitie = nhilos = ntiwin = ntitie = ntilos = nlowin = nlotie = nlolos = 0; // Clear counters for (listnum=0; listnum<MAX_HAND_LISTS; listnum++) _nlistwin[listnum] = _nlisttie[listnum] = _nlistlos[listnum] = 0; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PREFLOP if (betround == k_betround_preflop) { // order cards properly if (card_player[0] < card_player[1]) { pcard[0] = card_player[0]; pcard[1] = card_player[1]; } else { pcard[0] = card_player[1]; pcard[1] = card_player[0]; } // figure out offset into file offset = 0; //for (i=1; i<pcard[0]; i++) offset += (52-i)*1225; offset += card0_offset[pcard[0]]; offset += (pcard[1]-pcard[0]-1)*1225; offset *= sizeof(byte); // seek to right position in file if ((pos = _lseek(_versus_fh, offset, SEEK_SET)) == long(k_undefined)) { return false; } wintemp = lostemp = 0; for (i=0; i<(k_number_of_cards_per_deck - 1); i++) { for (j=i+1; j<k_number_of_cards_per_deck; j++) { if (i!=pcard[0] && i!=pcard[1] && j!=pcard[0] && j!=pcard[1]) { _read(_versus_fh, &byte, sizeof(byte)); memcpy(&wintemp, &byte[0], sizeof(unsigned int)); memcpy(&lostemp, &byte[4], sizeof(unsigned int)); _nwin += wintemp; _ntie += 1712304 - wintemp - lostemp; _nlos += lostemp; _nhands = _nhands + 1; if (wintemp<lostemp) { _nhandshi = _nhandshi + 1; nhiwin += wintemp; nhitie += 1712304 - wintemp - lostemp; nhilos += lostemp; } else if (wintemp>lostemp) { _nhandslo = _nhandslo + 1; nlowin += wintemp; nlotie += 1712304 - wintemp - lostemp; nlolos += lostemp; } else { _nhandsti = _nhandsti + 1; ntiwin += wintemp; ntitie += 1712304 - wintemp - lostemp; ntilos += lostemp; } // Calculations for vs$xx$prwin, vs$xx$prtie, vs$xx$prlos c0rank = StdDeck_RANK(i); c1rank = StdDeck_RANK(j); if (c0rank < c1rank) { temprank = c0rank; c0rank = c1rank; c1rank = temprank; } for (listnum=0; listnum<MAX_HAND_LISTS; listnum++) { if ((StdDeck_SUIT(i)==StdDeck_SUIT(j) && p_formula->formula()->inlist[listnum][c0rank][c1rank]) || (StdDeck_SUIT(i)!=StdDeck_SUIT(j) && p_formula->formula()->inlist[listnum][c1rank][c0rank])) { _nlistwin[listnum] += wintemp; _nlisttie[listnum] += 1712304 - wintemp - lostemp; _nlistlos[listnum] += lostemp; } } } } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FLOP, TURN, RIVER else if (betround >= k_betround_flop) { CardMask playerEvalCardsNow, oppEvalCardsNow; HandVal player_hv_now = 0, opp_hv_now = 0; // Common cards CardMask_RESET(comCardsScrape); if (betround >= k_betround_flop) CardMask_SET(comCardsScrape, card_common[0]); if (betround >= k_betround_flop) CardMask_SET(comCardsScrape, card_common[1]); if (betround >= k_betround_flop) CardMask_SET(comCardsScrape, card_common[2]); if (betround >= k_betround_turn) CardMask_SET(comCardsScrape, card_common[3]); if (betround >= k_betround_river) CardMask_SET(comCardsScrape, card_common[4]); // player cards CardMask_RESET(plCards); CardMask_SET(plCards, card_player[0]); CardMask_SET(plCards, card_player[1]); // all used cards CardMask_OR(usedCards, comCardsScrape, plCards); // eval player hand now CardMask_OR(playerEvalCardsNow, plCards, comCardsScrape); player_hv_now = Hand_EVAL_N(playerEvalCardsNow, betround+3); // Enumerate through all possible opponent hands (excludes already used cards) for (i=0; i<=50; i++) { for (j=i+1; j<=51; j++) { if (!CardMask_CARD_IS_SET(usedCards, i) && !CardMask_CARD_IS_SET(usedCards, j)) { CardMask_RESET(oppCards); CardMask_SET(oppCards, i); CardMask_SET(oppCards, j); // Enumerate through all possible river situations (exclude player cards and opponent cards) CardMask_OR(deadCards, usedCards, oppCards); wintemp = tietemp = lostemp = 0; if (betround==k_betround_flop || betround==k_betround_turn) { ENUMERATE_N_CARDS_D(comCardsEnum, betround==k_betround_flop ? 2 : betround==k_betround_turn ? 1 : 0, deadCards, { CardMask_OR(comCardsAll, comCardsScrape, comCardsEnum); DoCalc(plCards, oppCards, comCardsAll, &wintemp, &tietemp, &lostemp); }); }
void COpenHoldemStatusbar::ComputeCurrentStatus() { CardMask Cards; CString temp; int userchair = p_symbol_engine_userchair->userchair(); // Player cards CardMask_RESET(Cards); int nCards = 0; _status_plcards = ""; if (p_table_state->User()->HasKnownCards()) { for (int i=0; i<k_number_of_cards_per_player; i++) { // This condition got already checked: "playing" Card card = p_table_state->User()->_hole_cards[i]; // Assertion removeed, because the scraper runs in a different thread. // assert(card.IsKnownCard()); _status_plcards.Append(card.ToString()); CardMask_SET(Cards, card.GetValue()); nCards++; } _status_nopp.Format("%d", p_symbol_engine_prwin->nopponents_for_prwin()); } else { for (int i=0; i<k_number_of_cards_per_player; i++) { if (p_table_state->User()->HasKnownCards()) { Card card = p_table_state->User()->_hole_cards[i]; _status_plcards.Append(card.ToString()); CardMask_SET(Cards, card.GetValue()); nCards++; } } // Not playing, therefore no opponents to be considered for prwin. _status_nopp = ""; } // Common cards _status_comcards = ""; for (int i=0; i<k_number_of_community_cards; i++) { Card card = p_table_state->_common_cards[i]; if (card.IsKnownCard()) { _status_comcards.Append(card.ToString()); CardMask_SET(Cards, card.GetValue()); nCards++; } } // poker hand HandVal hv = Hand_EVAL_N(Cards, nCards); char hvstring[100] = {0}; HandVal_toString(hv, hvstring); _status_pokerhand = hvstring; _status_pokerhand = _status_pokerhand.Mid(0, _status_pokerhand.Find(" ")); // Always use handrank169 here _status_handrank.Format("%.0f/169", p_symbol_engine_handrank->handrank169()); // Always update prwin/nit if (p_symbol_engine_userchair->userchair_confirmed() && p_table_state->User()->HasKnownCards()) { _status_prwin.Format("%d/%d/%d", (int) (p_iterator_thread->prwin()*1000), (int) (p_iterator_thread->prtie()*1000), (int) (p_iterator_thread->prlos()*1000)); double iterations; p_engine_container->EvaluateSymbol("f$prwin_number_of_iterations", &iterations); _status_nit.Format("%d/%s", p_iterator_thread->IteratorThreadProgress(), Number2CString(iterations)); } else { _status_prwin = "0/0/0"; // No iteratrions without userchair or cards _status_nit.Format("0"); } }
void CIteratorThread::EnhancedDealingAlgorithm() { // Dealing algorithm for enhanced prwin // (user-defined weighting at DLL-level). write_log(preferences.debug_prwin(), "[PrWinThread] Using Matrix's enhanced prwin.\n"); //prw1326 active Matrix 2008-05-08 int k = 0; //k is used as an index into ocard[] unsigned int card = 0; int userchair = p_symbol_engine_userchair->userchair(); int playersplayingbits = p_symbol_engine_active_dealt_playing->playersplayingbits(); //we have to use actual opponents for prw1326 calculations int nopponents = bitcount(playersplayingbits & ~(1 << userchair)); int betround = p_betround_calculator->betround(); int bblindbits = p_symbol_engine_blinds->bblindbits(); // loop through active opponents for(int i=0; i<k_max_number_of_players; i++) { if (i == userchair) continue; //skip our own chair! if (!(playersplayingbits & (1<<i))) continue; //skip inactive chairs // first deal with the special non-weighted cases // player who is marked 'ignore' or one who is BB and has not VPIP'd if (_prw1326.chair[i].ignore || (_prw1326.bblimp && p_symbol_engine_history->nbetsround(betround)<1.1 && (bblindbits&(1<<i))) ) { card = GetRandomCard(); CardMask_SET(usedCards, card); ocard[k++] = card; card = GetRandomCard(); CardMask_SET(usedCards, card); ocard[k++] = card; continue; } // end of special non-weighted cases int randfix=(RAND_MAX/_prw1326.chair[i].limit) * _prw1326.chair[i].limit; int j; while (true) { //find a possible hand for this chair NOTE: may want to put in loop limits to prevent hanging do { j=rand(); } while (j>=randfix); j = j % _prw1326.chair[i].limit; //j is now any one of the allowed hands if(CardMask_CARD_IS_SET(usedCards, _prw1326.chair[i].rankhi[j] )) continue; //hand contains dead card if(CardMask_CARD_IS_SET(usedCards, _prw1326.chair[i].ranklo[j] )) continue; //hand contains dead card // if(symbols.prw1326.chair[i].ignore)break; //chair marked as not to be weighted if(_prw1326.chair[i].level <= _prw1326.chair[i].weight[j]) break; //hand marked as always uae //check if we want a player who is BB and has not VPIP'd to be analysed further // if(symbols.prw1326.bblimp) // { // if ((symbols.sym.nbetsround[0]<1.1) && ((int)symbols.sym.bblindbits&(1<<i)))break; // } //we should really do a 'randfix' here for the case where RAND_MAX is not an integral //multiple of .level, but the bias introduced is trivial compared to other uncertainties. if(rand() % _prw1326.chair[i].level < _prw1326.chair[i].weight[j]) break; //allowable //if we reach here we will loop again to find a suitable hand } //end of possible hand find ocard[k++] = _prw1326.chair[i].rankhi[j]; ocard[k++] = _prw1326.chair[i].ranklo[j]; CardMask_SET(usedCards, ocard[k-2]); CardMask_SET(usedCards, ocard[k-1]); } //end of active opponent loop // additional common cards CardMask_RESET(addlcomCards); for (int i=0; i<(k_number_of_community_cards - _ncomCards); i++) { card = GetRandomCard(); CardMask_SET(usedCards, card); CardMask_SET(addlcomCards, card); } } //end of prw1326 code
int CIteratorThread::EnhancedDealingAlgorithm() { write_log(preferences.debug_prwin(), "[PrWinThread] Using ZeeZooLaa's enhanced prwin.\n"); unsigned int card = 0, deadHandsCounter = 0; int k = 0; //k is used as an index into ocard[] int userchair = p_symbol_engine_userchair->userchair(); int playersplayingbits = p_symbol_engine_active_dealt_playing->playersplayingbits(); int chairWeight; bool deadHands[k_number_of_pocketcard_combinations_without_order]; for(int eachChair=0; eachChair < kMaxNumberOfPlayers; eachChair++) { // loop through playing opponents if (eachChair == userchair) continue; //skip our own chair! if (!(playersplayingbits & (1<<eachChair))) continue; //skip inactive chairs chairWeight = _total_weight[eachChair]; if (_prw1326.chair[eachChair].ignore || chairWeight <= 0 ) { card = GetRandomCard(); CardMask_SET(usedCards, card); ocard[k++] = card; card = GetRandomCard(); CardMask_SET(usedCards, card); ocard[k++] = card; continue; } // end of special non-weighted cases memset(deadHands,false,sizeof(deadHands)); deadHandsCounter = 0; bool random_weighted_hand_was_found = false; while(!random_weighted_hand_was_found) { int random_weight = RNG::Instance()->under(chairWeight); //find random_weight which is between [0..chairWeight) for (int eachPossibleHand=0; eachPossibleHand < _prw1326.chair[eachChair].limit; eachPossibleHand++) { //find random weighted hand if (!deadHands[eachPossibleHand] && random_weight < _prw1326.chair[eachChair].weight[eachPossibleHand]) { //random hand found. if(CardMask_CARD_IS_SET(usedCards, _prw1326.chair[eachChair].rankhi[eachPossibleHand] ) || CardMask_CARD_IS_SET(usedCards, _prw1326.chair[eachChair].ranklo[eachPossibleHand] )) { //hand contains dead card deadHands[eachPossibleHand] = true; deadHandsCounter++; chairWeight -= _prw1326.chair[eachChair].weight[eachPossibleHand]; if(deadHandsCounter == _prw1326.chair[eachChair].limit || chairWeight <= 0) { //all range consists only of dead cards //failed to satisfy the specified range, user possibly needs to expand the range of corresponding chair if(eachChair == 0) return -10; return 0-eachChair; } break; //generate new random_weight } //hand not dead, use it ocard[k++] = _prw1326.chair[eachChair].rankhi[eachPossibleHand]; ocard[k++] = _prw1326.chair[eachChair].ranklo[eachPossibleHand]; CardMask_SET(usedCards, ocard[k-2]); CardMask_SET(usedCards, ocard[k-1]); random_weighted_hand_was_found = true; break; } //keep decreasing the random_weight until it becomes less then _prw1326.chair[eachPlayer].weight if(!deadHands[eachPossibleHand]) { random_weight -= _prw1326.chair[eachChair].weight[eachPossibleHand]; } }//end of eachPossibleHand }//end of random_weighted_hand_was_found } //end of eachPlayer // additional common cards CardMask_RESET(addlcomCards); for (int i=0; i<(kNumberOfCommunityCards - _ncomCards); i++) { card = GetRandomCard(); CardMask_SET(usedCards, card); CardMask_SET(addlcomCards, card); } return 0; //success }
UINT CIteratorThread::IteratorThreadFunction(LPVOID pParam) { CIteratorThread *pParent = static_cast<CIteratorThread*>(pParam); // Loop-variables j, k get used inside and outside loops. // It is a bit messy, nearly impossible to fix it. // At least the outer loops ("f$prwin_number_of_iterations" and "i") could be improved. unsigned int pl_pokval = 0, opp_pokval = 0, opp_pokvalmax = 0; HandVal pl_hv = 0, opp_hv = 0; int dummy = 0, enhanced_dealing_return=0; bool hand_lost; ResetGlobalVariables(); // Seed the RNG srand((unsigned)GetTickCount()); while (true) { // Check event for thread stop signal once per main iterator loop // (and additionally once every 1000 iterations later) if(::WaitForSingleObject(pParent->_m_stop_thread, 0) == WAIT_OBJECT_0) { // Set event ::SetEvent(pParent->_m_wait_thread); AfxEndThread(0); } Sleep(500); if (!p_symbol_engine_autoplayer->ismyturn()) { // Not my turn; // Nothing to simulate continue; } if (IteratorThreadComplete()) { // No longer anything to do continue; } write_log(preferences.debug_prwin(), "[PrWinThread] Start of main loop.\n"); // "f$prwin_number_of_iterations" has to be declared outside of the loop, // as we check afterwards, if the loop terminated successfully. _nopponents = p_symbol_engine_prwin->nopponents_for_prwin(); AdjustPrwinVariablesIfNecessary(); LARGE_INTEGER frequency; // ticks per second LARGE_INTEGER t1, t2; // ticks double elapsedTime = 0; QueryPerformanceFrequency(&frequency); // get ticks per second CalculateTotalWeights(); // // Main iterator loop // for (_iterations_calculated=0; _iterations_calculated < _iterations_required; ++_iterations_calculated) { // Check event for thread stop signal once every 1000 iterations if ((_iterations_calculated % 1000 == 0) && (_iterations_calculated > 0) && (::WaitForSingleObject(pParent->_m_stop_thread, 0) == WAIT_OBJECT_0)) { // Set event ::SetEvent(pParent->_m_wait_thread); AfxEndThread(0); } CardMask_OR(usedCards, pParent->_plCards, pParent->_comCards); if (UseEnhancedPrWin()) { QueryPerformanceCounter(&t1); // start timer enhanced_dealing_return = EnhancedDealingAlgorithm(); if (enhanced_dealing_return < 0) { _prwin = enhanced_dealing_return; _prtie = enhanced_dealing_return; _prlos = enhanced_dealing_return; _iterations_calculated = _iterations_required; write_log(preferences.debug_prwin(), "[PrWinThread] Chair's %i range consists of dead cards only.\n",enhanced_dealing_return); break; } QueryPerformanceCounter(&t2); // stop timer elapsedTime = elapsedTime + (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart; // compute the elapsed time in millisec } else { QueryPerformanceCounter(&t1); // start timer StandardDealingAlgorithm(_nopponents); QueryPerformanceCounter(&t2); // stop timer elapsedTime = elapsedTime + (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart; // compute the elapsed time in millisec } // Get my handval/pokerval CardMask_OR(evalCards, pParent->_plCards, pParent->_comCards); CardMask_OR(evalCards, evalCards, addlcomCards); pl_hv = Hand_EVAL_N(evalCards, 7); pl_pokval = p_symbol_engine_pokerval->CalculatePokerval(pl_hv, 7, &dummy, CARD_NOCARD, CARD_NOCARD);//?? // Scan through opponents' handvals/pokervals // - if we find one better than ours, then we are done, increment los // - for win/tie, we need to wait until we scan them all opp_pokvalmax = 0; hand_lost = false; for (int i=0; i<_nopponents; i++) { CardMask_RESET(opp_evalCards); CardMask_OR(opp_evalCards, pParent->_comCards, addlcomCards); CardMask_SET(opp_evalCards, ocard[i*2]); CardMask_SET(opp_evalCards, ocard[(i*2)+1]); opp_hv = Hand_EVAL_N(opp_evalCards, 7); opp_pokval = p_symbol_engine_pokerval->CalculatePokerval(opp_hv, 7, &dummy, CARD_NOCARD, CARD_NOCARD); write_log(preferences.debug_prwin(), "[PrWinThread] PlayerPV: %i OppPV: %i\n", pl_pokval, opp_pokval); if (opp_pokval > pl_pokval) { write_log(preferences.debug_prwin(), "[PrWinThread] Lost\n"); _los++; hand_lost = true; break; } else { if (opp_pokval > opp_pokvalmax) { opp_pokvalmax = opp_pokval; } } } if (!hand_lost) { if (pl_pokval > opp_pokvalmax) { write_log(preferences.debug_prwin(), "[PrWinThread] Won\n"); _win++; } else { write_log(preferences.debug_prwin(), "[PrWinThread] Tie\n"); _tie++; } } UpdateIteratorVarsForDisplay(); } write_log(preferences.debug_prwin(), "[PrWinThread] End of main loop.\n"); if (!IteratorThreadComplete()) { // Computation stopped with some kind of error. // Reset vars to avoid bogus data ResetIteratorVars(); } if(enhanced_dealing_return == 0) { UpdateIteratorVarsForDisplay(); //calculates _prwin, _prtie, _prlos } if(UseEnhancedPrWin()) { write_log(preferences.debug_prwin(), "EnhancedDealingAlgorithm elapsed time in millisec: %.3f Iterations: %d prwin: %.3f prtie: %.3f prlos: %.3f vanilla.limit: %i \n", elapsedTime,_iterations_calculated, _prwin, _prtie, _prlos, _prw1326.vanilla_chair.limit ); } else { write_log(preferences.debug_prwin(), "StandardDealingAlgorithm elapsed time in millisec: %.3f Iterations: %d prwin: %.3f prtie: %.3f prlos: %.3f\n", elapsedTime,_iterations_calculated, _prwin, _prtie, _prlos); } ::SetEvent(pParent->_m_wait_thread); } return 0; }
UINT CIteratorThread::IteratorThreadFunction(LPVOID pParam) { CIteratorThread *pParent = static_cast<CIteratorThread*>(pParam); // Loop-variables j, k get used inside and outside loops. // It is a bit messy, nearly impossible to fix it. // At least the outer loops ("f$prwin_number_of_iterations" and "i") could be improved. int j = 0, k = 0; int randfix = 0; CardMask addlcomCards = {0}, evalCards = {0}, opp_evalCards = {0}, usedCards = {0}, temp_usedCards = {0}; unsigned int ocard[MAX_OPPONENTS*2] = {0}, card = 0, pl_pokval = 0, opp_pokval = 0, opp_pokvalmax = 0; HandVal pl_hv = 0, opp_hv = 0; int dummy = 0; int deck[k_number_of_cards_per_deck] = {0}, x = 0; int numberOfCards = 0; int betround = p_betround_calculator->betround(); int sym_playersplayingbits = p_symbol_engine_active_dealt_playing->playersplayingbits(); double sym_nbetsround = p_symbol_engine_history->nbetsround(betround); int sym_bblindbits = p_symbol_engine_blinds->bblindbits(); bool sym_didcall = p_symbol_engine_history->didcall(betround); int sym_nopponents = p_symbol_engine_prwin->nopponents_for_prwin(); int nopp = sym_nopponents <= MAX_OPPONENTS ? sym_nopponents : MAX_OPPONENTS; bool hand_lost; // Seed the RNG srand((unsigned)GetTickCount()); // // Main iterator loop // write_log(prefs.debug_prwin(), "[PrWinThread] Start of main loop.\n"); // "f$prwin_number_of_iterations" has to be declared outside of the loop, // as we check afterwards, if the loop terminated successfully. unsigned int nit; for (nit=0; nit < iter_vars.nit(); nit++) { // Check event for thread stop signal if(::WaitForSingleObject(pParent->_m_stop_thread, 0) == WAIT_OBJECT_0) { // Set event ::SetEvent(pParent->_m_wait_thread); AfxEndThread(0); } CardMask_OR(usedCards, pParent->_plCards, pParent->_comCards); //Correct the protection aganst low f$willplay/f$wontplay - Matrix 2008-12-22 if (pParent->_willplay && (pParent->_willplay<nopp*2+1) ) { write_log(prefs.debug_prwin(), "[PrWinThread] Adjusting willplay (too low)\n"); pParent->_willplay=nopp*2+1; //too low a value can give lockup } if (pParent->_wontplay<pParent->_willplay) { write_log(prefs.debug_prwin(), "[PrWinThread] Adjusting wontplay (too low)\n"); pParent->_wontplay=pParent->_willplay; //wontplay cannot safely be less than willplay } if (_prw1326.useme==1326 && (betround>=k_betround_flop || _prw1326.preflop==1326)) { write_log(prefs.debug_prwin(), "[PrWinThread] Using Matrix's enhanced prwin.\n"); //prw1326 active Matrix 2008-05-08 k = nopp = 0; //k is used as an index into ocard[] // loop through active opponents for(int i=0; i<k_max_number_of_players; i++) { if (i==(int) p_symbol_engine_userchair->userchair()) continue; //skip our own chair! if (!((sym_playersplayingbits) & (1<<i))) continue; //skip inactive chairs nopp++; //we have to use actual opponents for prw1326 calculations // first deal with the special non-weighted cases // player who is marked 'ignore' or one who is BB and has not VPIP'd if (_prw1326.chair[i].ignore || (_prw1326.bblimp && sym_nbetsround<1.1 && (sym_bblindbits&(1<<i))) ) { do { card = rand() & 63; } while (card>51 || CardMask_CARD_IS_SET(usedCards, card)); CardMask_SET(usedCards, card); ocard[k++] = card; do { card = rand() & 63; } while (card>51 || CardMask_CARD_IS_SET(usedCards, card)); CardMask_SET(usedCards, card); ocard[k++] = card; continue; } // end of special non-weighted cases randfix=(RAND_MAX/_prw1326.chair[i].limit) * _prw1326.chair[i].limit; while (true) { //find a possible hand for this chair NOTE: may want to put in loop limits to prevent hanging do { j=rand(); } while (j>=randfix); j = j % _prw1326.chair[i].limit; //j is now any one of the allowed hands if(CardMask_CARD_IS_SET(usedCards, _prw1326.chair[i].rankhi[j] )) continue; //hand contains dead card if(CardMask_CARD_IS_SET(usedCards, _prw1326.chair[i].ranklo[j] )) continue; //hand contains dead card // if(symbols.prw1326.chair[i].ignore)break; //chair marked as not to be weighted if(_prw1326.chair[i].level <= _prw1326.chair[i].weight[j]) break; //hand marked as always uae //check if we want a player who is BB and has not VPIP'd to be analysed further // if(symbols.prw1326.bblimp) // { // if ((symbols.sym.nbetsround[0]<1.1) && ((int)symbols.sym.bblindbits&(1<<i)))break; // } //we should really do a 'randfix' here for the case where RAND_MAX is not an integral //multiple of .level, but the bias introduced is trivial compared to other uncertainties. if(rand() % _prw1326.chair[i].level < _prw1326.chair[i].weight[j]) break; //allowable //if we reach here we will loop again to find a suitable hand } //end of possible hand find ocard[k++] = _prw1326.chair[i].rankhi[j]; ocard[k++] = _prw1326.chair[i].ranklo[j]; CardMask_SET(usedCards, ocard[k-2]); CardMask_SET(usedCards, ocard[k-1]); } //end of active opponent loop // additional common cards CardMask_RESET(addlcomCards); for (int i=0; i<(k_number_of_community_cards - pParent->_ncomCards); i++) { do { card = rand() & 63; } while (card>51 ||CardMask_CARD_IS_SET(usedCards, card)); CardMask_SET(usedCards, card); CardMask_SET(addlcomCards, card); } } //end of prw1326 code else { // normal prwin opponent card selection write_log(prefs.debug_prwin(), "[PrWinThread] Using standard prwin.\n"); // if f$prwin_number_of_opponents<=13 then deal with random replacement algorithm, otherwise deal with swap algorithm if (nopp <= 13) { write_log(prefs.debug_prwin(), "[PrWinThread] Using random algorithm, as f$prwin_number_of_opponents <= 13\n"); // random replacement algorithm // opponent cards if (nopp < 1) { write_log(prefs.debug_prwin(), "[PrWinThread] No opponents.\n"); } for (int i=0; i<nopp*2; i+=2) { temp_usedCards=usedCards; do { usedCards=temp_usedCards; //reset the card mask to clear settings from failed card assignments do { card = rand() & 63; } while (card>51 || CardMask_CARD_IS_SET(usedCards, card)); CardMask_SET(usedCards, card); ocard[i] = card; do { card = rand() & 63; } while (card>51 || CardMask_CARD_IS_SET(usedCards, card)); CardMask_SET(usedCards, card); ocard[i+1] = card; if (!pParent->_willplay) { write_log(prefs.debug_prwin(), "[PrWinThread] Weighting disabled. Willplay is 0.\n"); break; //0 disables weighting } //put break for i=0 and opponent unraised BB case (cannot assume anything about his cards) //In round 1 we should really do an analysis of chairs to find out how many have still to //place a bet. Not implemented since accuracy of prwin pre-flop is less critical. if (!i) { //if we called then we are not BB, BB limped to flop, //BB still playing, so do not weight his cards if (sym_nbetsround<1.1 && sym_didcall && (sym_playersplayingbits&sym_bblindbits) ) { break; } } } while (!pParent->InRange(ocard[i], ocard[i+1], pParent->_willplay, pParent->_wontplay, pParent->_topclip, pParent->_mustplay)); } // additional common cards CardMask_RESET(addlcomCards); for (int i=0; i<(k_number_of_community_cards - pParent->_ncomCards); i++) { do { card = rand() & 63; } while (card>51 ||CardMask_CARD_IS_SET(usedCards, card)); CardMask_SET(usedCards, card); CardMask_SET(addlcomCards, card); } } else { write_log(prefs.debug_prwin(), "[PrWinThread] Useing swap-algorithm, as f$prwin_number_of_opponents > 13\n"); // swap alogorithm //weighted prwin not implemented for this case numberOfCards=52; for (int i=0; i<numberOfCards; i++) deck[i] = i; while (numberOfCards>=1) { x = rand() % numberOfCards; numberOfCards--; if (x != numberOfCards) { SwapInts(&deck[x], &deck[numberOfCards]); } } // opponent cards x = 0; for (int i=0; i<nopp*2; i++) { while (CardMask_CARD_IS_SET(usedCards, deck[x]) && x<=51) { x++; } ocard[i] = deck[x++]; } // additional common cards CardMask_RESET(addlcomCards); for (int i=0; i<(k_number_of_community_cards - pParent->_ncomCards); i++) { while (CardMask_CARD_IS_SET(usedCards, deck[x]) && x<=51) { x++; } CardMask_SET(addlcomCards, deck[x++]); } } } // Get my handval/pokerval CardMask_OR(evalCards, pParent->_plCards, pParent->_comCards); CardMask_OR(evalCards, evalCards, addlcomCards); pl_hv = Hand_EVAL_N(evalCards, 7); pl_pokval = p_symbol_engine_pokerval->CalculatePokerval(pl_hv, 7, &dummy, CARD_NOCARD, CARD_NOCARD); // Scan through opponents' handvals/pokervals // - if we find one better than ours, then we are done, increment los // - for win/tie, we need to wait until we scan them all opp_pokvalmax = 0; hand_lost = false; for (int i=0; i<nopp; i++) { CardMask_RESET(opp_evalCards); CardMask_OR(opp_evalCards, pParent->_comCards, addlcomCards); CardMask_SET(opp_evalCards, ocard[i*2]); CardMask_SET(opp_evalCards, ocard[(i*2)+1]); opp_hv = Hand_EVAL_N(opp_evalCards, 7); opp_pokval = p_symbol_engine_pokerval->CalculatePokerval(opp_hv, 7, &dummy, CARD_NOCARD, CARD_NOCARD); if (opp_pokval>pl_pokval) { pParent->_los++; hand_lost = true; break; } else { if (opp_pokval > opp_pokvalmax) opp_pokvalmax = opp_pokval; } } if (!hand_lost) { if (pl_pokval > opp_pokvalmax) pParent->_win++; else pParent->_tie++; } // Update display once every 1000 iterations if ((nit % 1000 == 0) && nit >= 1000) { write_log(prefs.debug_prwin(), "[PrWinThread] Progress: %d %.3f %.3f %.3f\n", nit, pParent->_win / (double) nit, pParent->_tie / (double) nit, pParent->_los / (double) nit); iter_vars.set_iterator_thread_progress(nit); iter_vars.set_prwin(pParent->_win / (double) nit); iter_vars.set_prtie(pParent->_tie / (double) nit); iter_vars.set_prlos(pParent->_los / (double) nit); } } write_log(prefs.debug_prwin(), "[PrWinThread] End of main loop.\n"); if (nit >= iter_vars.nit()) { iter_vars.set_iterator_thread_running(false); iter_vars.set_iterator_thread_complete(true); iter_vars.set_iterator_thread_progress(nit); iter_vars.set_prwin(pParent->_win / (double) iter_vars.nit()); iter_vars.set_prtie(pParent->_tie / (double) iter_vars.nit()); iter_vars.set_prlos(pParent->_los / (double) iter_vars.nit()); } else { iter_vars.set_iterator_thread_running(false); iter_vars.set_iterator_thread_complete(false); iter_vars.set_iterator_thread_progress(0); iter_vars.set_nit(0); iter_vars.set_f$p(0); iter_vars.set_br(0); for (int i=0; i<k_number_of_cards_per_player; i++) iter_vars.set_pcard(i, CARD_NOCARD); for (int i=0; i<k_number_of_community_cards; i++) iter_vars.set_ccard(i, CARD_NOCARD); iter_vars.set_prwin(0); iter_vars.set_prtie(0); iter_vars.set_prlos(0); } ::SetEvent(pParent->_m_wait_thread); delete p_iterator_thread; p_iterator_thread = NULL; return 0; }
void write_logautoplay(int level, const char * action) { char nowtime[26]; CString pcards, comcards, temp, rank, pokerhand, bestaction, fcra_seen; char *card; CardMask Cards; int i, nCards; HandVal hv; CString fcra_formula_status; int sym_userchair = (int) p_symbols->sym()->userchair; int sym_br = (int) p_symbols->sym()->br; if (level>prefs.log_level()) return; if (log_fp != NULL) { CSLock lock(log_critsec); // log$ writing if (prefs.log_symbol_enabled()) { int max_log = p_symbols->logsymbols_collection()->GetCount(); if (max_log > 0) { if (max_log > prefs.log_symbol_max_log()) { max_log = prefs.log_symbol_max_log(); } write_log(1, "*** log$ (Total: %d | Showing: %d)\n", p_symbols->logsymbols_collection()->GetCount(), max_log); for (int i=0; i<max_log; i++) { write_log(1, "*** %s\n", p_symbols->logsymbols_collection()->GetAt(i)); } } } CardMask_RESET(Cards); nCards=0; // player cards if (p_symbols->user_chair_confirmed()) { for (i=0; i<=1; i++) { card = StdDeck_cardString(p_scraper->card_player(sym_userchair, i)); temp.Format("%s", card); pcards.Append(temp); CardMask_SET(Cards, p_scraper->card_player(sym_userchair, i)); nCards++; } } else { pcards = "...."; } // common cards comcards = ""; if (sym_br >= 2) { for (i=0; i<=2; i++) { if (p_scraper->card_common(i) != CARD_BACK && p_scraper->card_common(i) != CARD_NOCARD) { card = StdDeck_cardString(p_scraper->card_common(i)); temp.Format("%s", card); comcards.Append(temp); CardMask_SET(Cards, p_scraper->card_common(i)); nCards++; } } } if (sym_br >= 3) { card = StdDeck_cardString(p_scraper->card_common(3)); temp.Format("%s", card); comcards.Append(temp); CardMask_SET(Cards, p_scraper->card_common(3)); nCards++; } if (sym_br >= 4) { card = StdDeck_cardString(p_scraper->card_common(4)); temp.Format("%s", card); comcards.Append(temp); CardMask_SET(Cards, p_scraper->card_common(4)); nCards++; } comcards.Append(".........."); comcards = comcards.Left(10); // handrank if (prefs.sym_handrank_value() == "169") rank.Format("%.0f", p_symbols->sym()->handrank169); else if (prefs.sym_handrank_value() == "1000") rank.Format("%.0f", p_symbols->sym()->handrank1000); else if (prefs.sym_handrank_value() == "1326") rank.Format("%.0f", p_symbols->sym()->handrank1326); else if (prefs.sym_handrank_value() == "2652") rank.Format("%.0f", p_symbols->sym()->handrank2652); else if (prefs.sym_handrank_value() == "p") rank.Format("%.2f", p_symbols->sym()->handrankp); // poker hand hv = Hand_EVAL_N(Cards, nCards); if (HandVal_HANDTYPE(hv)==HandType_STFLUSH && StdDeck_RANK(HandVal_TOP_CARD(hv))==Rank_ACE) pokerhand="royfl"; else if (HandVal_HANDTYPE(hv)==HandType_STFLUSH) pokerhand="strfl"; else if (HandVal_HANDTYPE(hv)==HandType_QUADS) pokerhand="4kind"; else if (HandVal_HANDTYPE(hv)==HandType_FULLHOUSE) pokerhand="fullh"; else if (HandVal_HANDTYPE(hv)==HandType_FLUSH) pokerhand="flush"; else if (HandVal_HANDTYPE(hv)==HandType_STRAIGHT) pokerhand="strai"; else if (HandVal_HANDTYPE(hv)==HandType_TRIPS) pokerhand="3kind"; else if (HandVal_HANDTYPE(hv)==HandType_TWOPAIR) pokerhand="2pair"; else if (HandVal_HANDTYPE(hv)==HandType_ONEPAIR) pokerhand="1pair"; else if (HandVal_HANDTYPE(hv)==HandType_NOPAIR) pokerhand="hcard"; // best action if (strcmp(action, "SWAG")==0) { bestaction.Format("$%.2f", p_symbols->f$betsize()); } else { if (p_symbols->f$alli()) bestaction = "Allin"; else if (p_symbols->f$betsize()) bestaction = "SWAG"; else if (p_symbols->f$rais()) bestaction = "Bet/Raise"; else if (p_symbols->f$call()) bestaction = "Call/Check"; else if (p_symbols->f$prefold()) bestaction = "Pre-fold"; else bestaction = "Fold/Check"; } // fcra_seen int sym_myturnbits = (int) p_symbols->sym()->myturnbits; fcra_seen.Format("%s%s%s%s%s", sym_myturnbits&0x01 ? "F" : ".", sym_myturnbits&0x02 ? "C" : ".", // Check button out of order to stay consistent // with button order in manual mode. sym_myturnbits&0x10 ? "K" : ".", sym_myturnbits&0x04 ? "R" : ".", sym_myturnbits&0x08 ? "A" : "."); // fcra formula status fcra_formula_status.Format("%s%s%s%s", !p_symbols->f$alli() && !p_symbols->f$rais() && !p_symbols->f$call() && !p_symbols->f$betsize() ? "F" : ".", p_symbols->f$call() ? "C" : ".", p_symbols->f$rais() ? "R" : ".", p_symbols->f$alli() ? "A" : "."); fprintf(log_fp, "%s - %1d ", get_time(nowtime), p_tablemap->nchairs()); fprintf(log_fp, "%4s %10s %4s %5s ", pcards.GetString(), comcards.GetString(), rank.GetString(), pokerhand.GetString()); fprintf(log_fp, "%4d %4d %4d ", (int) (p_symbols->sym()->prwin*1000), (int) (p_symbols->sym()->prlos*1000), (int) (p_symbols->sym()->prtie*1000)); fprintf(log_fp, "%2d %8d %-10s - ", (int) p_symbols->sym()->nopponents, (int) p_symbols->sym()->nit, bestaction.GetString()); fprintf(log_fp, "%-5s %9.2f %9.2f %9.2f ", action, p_symbols->sym()->call, p_tablelimits->bet(), p_symbols->sym()->pot); fprintf(log_fp, "%9.2f - %s %s %.2f\n", p_symbols->sym()->balance[10], fcra_seen.GetString(), fcra_formula_status.GetString(), p_symbols->f$betsize() ); if (prefs.trace_enabled() && p_symbols->symboltrace_collection()->GetSize() > 0) { write_log_nostamp(1, "***** Autoplayer Trace ****\n"); for (int i=0; i<p_symbols->symboltrace_collection()->GetSize(); i++) { write_log_nostamp(1, "%s\n", p_symbols->symboltrace_collection()->GetAt(i)); } write_log_nostamp(1, "***********************\n"); } fflush(log_fp); } }
void CIteratorThread::StandardDealingAlgorithmForUpTo13Opponents(int nopponents) { unsigned int card = 0; write_log(preferences.debug_prwin(), "[PrWinThread] Using random algorithm, as f$prwin_number_of_opponents <= 13\n"); // random replacement algorithm // opponent cards if (nopponents < 1) { write_log(preferences.debug_prwin(), "[PrWinThread] No opponents. Auto-adapting to 1.\n"); nopponents = 1; } for (int i=0; i<nopponents*k_number_of_cards_per_player; i+=k_number_of_cards_per_player) { temp_usedCards=usedCards; do { usedCards = temp_usedCards; //reset the card mask to clear settings from failed card assignments for (int j=0; j<k_number_of_cards_per_player; j++) { card = GetRandomCard(); CardMask_SET(usedCards, card); ocard[i+j] = card; } if (!_willplay) { write_log(preferences.debug_prwin(), "[PrWinThread] Weighting disabled. Willplay is 0.\n"); break; //0 disables weighting } //put break for i=0 and opponent unraised BB case (cannot assume anything about his cards) //In round 1 we should really do an analysis of chairs to find out how many have still to //place a bet. Not implemented since accuracy of prwin pre-flop is less critical. if (!i) { //if we called then we are not BB, BB limped to flop, //BB still playing, so do not weight his cards int betround = p_betround_calculator->betround(); if (p_symbol_engine_history->nbetsround(betround) < 1.1 && p_symbol_engine_history->didcall(betround) && (p_symbol_engine_active_dealt_playing->playersplayingbits() & p_symbol_engine_blinds->bblindbits())) { break; } } } while (!IsHandInWeightedRange(ocard[i], ocard[i+1], _willplay, _wontplay, _topclip, _mustplay)); } // additional common cards CardMask_RESET(addlcomCards); for (int i=0; i<(k_number_of_community_cards - _ncomCards); i++) { card = GetRandomCard(); CardMask_SET(usedCards, card); CardMask_SET(addlcomCards, card); } }
void CIteratorThread::InitIteratorLoop() { int e = SUCCESS; CGrammar gram; write_log(preferences.debug_prwin(), "[PrWinThread] Initializing iterator loop\n"); // Set starting status and parameters iter_vars.set_iterator_thread_running(true); iter_vars.set_iterator_thread_complete(false); iter_vars.set_iterator_thread_progress(0); iter_vars.set_nit(10000); //!! f$prwin_number_of_iterations") // Users cards for (int i=0; i<k_number_of_cards_per_player; i++) { iter_vars.set_pcard(i, p_scraper->card_player(p_symbol_engine_userchair->userchair(), i)); } // Community cards for (int i=0; i<k_number_of_community_cards; i++) { iter_vars.set_ccard(i, p_scraper->card_common(i)); } iter_vars.set_prwin(0); iter_vars.set_prtie(0); iter_vars.set_prlos(0); // player cards CardMask_RESET(_plCards); CardMask_RESET(_comCards); _nplCards = _ncomCards = 0; // Counters _win = _tie = _los = 0; // setup masks for (int i=0; i<k_number_of_cards_per_player; i++) { if (iter_vars.pcard(i) != CARD_BACK && iter_vars.pcard(i) != CARD_NOCARD) { CardMask_SET(_plCards, iter_vars.pcard(i)); _nplCards++; } } for (int i=0; i<k_number_of_community_cards; i++) { if (iter_vars.ccard(i) != CARD_BACK && iter_vars.ccard(i) != CARD_NOCARD) { CardMask_SET(_comCards, iter_vars.ccard(i)); _ncomCards++; } } //Weighted prwin only for nopponents <=13 e = SUCCESS; _willplay = (int) gram.CalcF$symbol(p_formula, "f$prwin_willplay", &e); e = SUCCESS; _wontplay = (int) gram.CalcF$symbol(p_formula, "f$prwin_wontplay", &e); e = SUCCESS; _mustplay = (int) gram.CalcF$symbol(p_formula, "f$prwin_mustplay", &e); e = SUCCESS; _topclip = (int) gram.CalcF$symbol(p_formula, "f$prwin_topclip", &e); // Call prw1326 callback if needed if (_prw1326.useme==1326 && _prw1326.usecallback==1326 && (p_betround_calculator->betround()!= k_betround_preflop || _prw1326.preflop==1326) ) { _prw1326.prw_callback(); //Matrix 2008-05-09 } }
void CSymbolEnginePrwin::CalculateNhands() { CardMask plCards = {0}, comCards = {0}, oppCards = {0}, playerEvalCards = {0}, opponentEvalCards = {0}; HandVal hv_player = 0, hv_opponent = 0; unsigned int pl_pokval = 0, opp_pokval = 0; int dummy = 0; int nplCards, ncomCards; _nhandshi = 0; _nhandsti = 0; _nhandslo = 0; // player cards CardMask_RESET(plCards); nplCards = 0; for (int i=0; i<kNumberOfCardsPerPlayer; i++) { Card card = p_table_state->User()->_hole_cards[i]; if (card.IsKnownCard()) { CardMask_SET(plCards, card.GetValue()); nplCards++; } } // common cards CardMask_RESET(comCards); ncomCards = 0; for (int i=0; i<kNumberOfCommunityCards; i++) { Card card = p_table_state->_common_cards[i]; if (card.IsKnownCard()) { CardMask_SET(comCards, card.GetValue()); ncomCards++; } } // player/common cards and pokerval CardMask_OR(playerEvalCards, plCards, comCards); hv_player = Hand_EVAL_N(playerEvalCards, nplCards+ncomCards); pl_pokval = p_symbol_engine_pokerval->CalculatePokerval(hv_player, nplCards+ncomCards, &dummy, CARD_NOCARD, CARD_NOCARD); for (int i=0; i<(kNumberOfCardsPerDeck-1); i++) { for (int j=(i+1); j<kNumberOfCardsPerDeck; j++) { if (!CardMask_CARD_IS_SET(plCards, i) && !CardMask_CARD_IS_SET(plCards, j) && !CardMask_CARD_IS_SET(comCards, i) && !CardMask_CARD_IS_SET(comCards, j)) { // opponent cards CardMask_RESET(oppCards); CardMask_SET(oppCards, i); CardMask_SET(oppCards, j); CardMask_OR(opponentEvalCards, oppCards, comCards); hv_opponent = Hand_EVAL_N(opponentEvalCards, 2+ncomCards); opp_pokval = p_symbol_engine_pokerval->CalculatePokerval(hv_opponent, (kNumberOfCardsPerPlayer + ncomCards), &dummy, CARD_NOCARD, CARD_NOCARD); if (pl_pokval > opp_pokval) { _nhandslo++; } else if (pl_pokval < opp_pokval) { _nhandshi++; } else { _nhandsti++; } } } } AssertRange(_nhandshi, 0, nhands()); AssertRange(_nhandsti, 0, nhands()); AssertRange(_nhandslo, 0, nhands()); assert((_nhandshi + _nhandsti + _nhandslo) == nhands()); _prwinnow = pow(((double)_nhandslo/nhands()), _nopponents_for_prwin); _prlosnow = 1 - pow((((double)_nhandslo + _nhandsti)/nhands()), _nopponents_for_prwin); AssertRange(_prwinnow, 0, 1); AssertRange(_prlosnow, 0, 1); }
void CSymbolEnginePrwin::CalculateNhands() { CardMask plCards = {0}, comCards = {0}, oppCards = {0}, playerEvalCards = {0}, opponentEvalCards = {0}; HandVal hv_player = 0, hv_opponent = 0; unsigned int pl_pokval = 0, opp_pokval = 0; int dummy = 0; int nplCards, ncomCards; _nhandshi = 0; _nhandsti = 0; _nhandslo = 0; // player cards CardMask_RESET(plCards); nplCards = 0; for (int i=0; i<k_number_of_cards_per_player; i++) { if (p_scraper_access->IsKnownCard(p_scraper->card_player(USER_CHAIR, i))) { CardMask_SET(plCards, p_scraper->card_player(USER_CHAIR, i)); nplCards++; } } // common cards CardMask_RESET(comCards); ncomCards = 0; for (int i=0; i<k_number_of_community_cards; i++) { if (p_scraper_access->IsKnownCard(p_scraper->card_common(i))) { CardMask_SET(comCards, p_scraper->card_common(i)); ncomCards++; } } // player/common cards and pokerval CardMask_OR(playerEvalCards, plCards, comCards); hv_player = Hand_EVAL_N(playerEvalCards, nplCards+ncomCards); pl_pokval = p_symbol_engine_pokerval->CalculatePokerval(hv_player, nplCards+ncomCards, &dummy, CARD_NOCARD, CARD_NOCARD); for (int i=0; i<(k_number_of_cards_per_deck-1); i++) { for (int j=(i+1); j<k_number_of_cards_per_deck; j++) { if (!CardMask_CARD_IS_SET(plCards, i) && !CardMask_CARD_IS_SET(plCards, j) && !CardMask_CARD_IS_SET(comCards, i) && !CardMask_CARD_IS_SET(comCards, j)) { // opponent cards CardMask_RESET(oppCards); CardMask_SET(oppCards, i); CardMask_SET(oppCards, j); CardMask_OR(opponentEvalCards, oppCards, comCards); hv_opponent = Hand_EVAL_N(opponentEvalCards, 2+ncomCards); opp_pokval = p_symbol_engine_pokerval->CalculatePokerval(hv_opponent, (k_number_of_cards_per_player + ncomCards), &dummy, CARD_NOCARD, CARD_NOCARD); if (pl_pokval > opp_pokval) { _nhandslo++; } else if (pl_pokval < opp_pokval) { _nhandshi++; } else { _nhandsti++; } } } } AssertRange(_nhandshi, 0, nhands()); AssertRange(_nhandsti, 0, nhands()); AssertRange(_nhandslo, 0, nhands()); assert((_nhandshi + _nhandsti + _nhandslo) == nhands()); _prwinnow = pow(((double)_nhandslo/nhands()), _nopponents_for_prwin); _prlosnow = 1 - pow((((double)_nhandslo + _nhandsti)/nhands()), _nopponents_for_prwin); AssertRange(_prwinnow, 0, 1); AssertRange(_prlosnow, 0, 1); }