void CIteratorThread::UpdateIteratorVarsForDisplay() { // Update display once every 1000 iterations if (IteratorThreadComplete() || ((_iterations_calculated % 1000 == 0) && (_iterations_calculated >= 1000))) { _prwin = _win / (double) _iterations_calculated; _prtie = _tie / (double) _iterations_calculated; _prlos = _los / (double) _iterations_calculated; write_log(preferences.debug_prwin(), "[PrWinThread] Progress: %d %.3f %.3f %.3f\n", _iterations_calculated, _prwin, _prtie, _prlos); } }
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; }
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; }