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;
}