void CSymbolEngineOpenPPLHandAndBoardExpression::ResetOnHeartbeat() { _prime_coded_hole_cards = PrimeCodedRanks( p_table_state->User()->_hole_cards[0].GetOpenHoldemRank(), p_table_state->User()->_hole_cards[1].GetOpenHoldemRank()); _prime_coded_board_cards = PrimeCodedRanks( p_table_state->_common_cards[0].GetOpenHoldemRank(), p_table_state->_common_cards[1].GetOpenHoldemRank(), p_table_state->_common_cards[2].GetOpenHoldemRank(), p_table_state->_common_cards[3].GetOpenHoldemRank(), p_table_state->_common_cards[4].GetOpenHoldemRank()); write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] _prime_coded_hole_cards = %i\n", _prime_coded_hole_cards); write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] _prime_coded_board_cards = %i\n", _prime_coded_board_cards); }
void CSymbolEngineOpenPPLHandAndBoardExpression::ResetOnHeartbeat() { _prime_coded_hole_cards = PrimeCodedRanks( p_table_state->User()->hole_cards(0)->GetOpenHoldemRank(), p_table_state->User()->hole_cards(1)->GetOpenHoldemRank()); _prime_coded_board_cards = PrimeCodedRanks( p_table_state->CommonCards(0)->GetOpenHoldemRank(), p_table_state->CommonCards(1)->GetOpenHoldemRank(), p_table_state->CommonCards(2)->GetOpenHoldemRank(), p_table_state->TurnCard()->GetOpenHoldemRank(), p_table_state->RiverCard()->GetOpenHoldemRank()); write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] _prime_coded_hole_cards = %i\n", _prime_coded_hole_cards); write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] _prime_coded_board_cards = %i\n", _prime_coded_board_cards); }
bool CSymbolEngineOpenPPLHandAndBoardExpression::EvaluateSymbol(const char *name, double *result, bool log /* = false */) { // First check, if hand$ or board$ and/or Suited // At the same time remove the unnecessary parts of the expression if (memcmp(name, "hand$", 5) == 0) { is_hand_expression = true; is_board_expression = false; hand_or_board_expression = name; write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] Evaluating %s\n", hand_or_board_expression); hand_or_board_expression = CStringRemoveLeft(hand_or_board_expression, 5); prime_coded_available_ranks = _prime_coded_hole_cards; } else if (memcmp(name, "board$", 6) == 0) { is_hand_expression = false; is_board_expression = true; hand_or_board_expression = name; write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] Evaluating %s\n", hand_or_board_expression); hand_or_board_expression = CStringRemoveLeft(hand_or_board_expression, 6); prime_coded_available_ranks = _prime_coded_board_cards; } else { // Quick exit on other symbols return false; } write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] Encoded available ranks> %i\n", prime_coded_available_ranks); bool is_suited_expression = false; assert(is_hand_expression || is_board_expression); if (hand_or_board_expression.Right(6).MakeLower() == "suited") { write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] Suited expression\n"); is_suited_expression = true; hand_or_board_expression = CStringRemoveRight( hand_or_board_expression, 6); } // Checking ranks with potential multiplicity > 1, not caring about suits. // We do this at the very beginning, as this is a very quick test // and most real-world-use-cases will be false, so we get a fast exit. int prime_coded_search_expression = PrimeCodedRanks(hand_or_board_expression); write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] Encoded searched ranks> %i\n", prime_coded_available_ranks); if ((prime_coded_available_ranks % prime_coded_search_expression) != 0) { // Division without reminder not possible. // Therefore different primes in the search-expression // Therefore ranks that do not fit available ranks. write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] No match, because ranks do not fit\n"); *result = false; return true; } // This was super-elegant, but unfortunatelly there can be // SUITED expressions, which we can only solve with srankbits. // Ranks in the expression (to be searched) if (is_suited_expression) { int rankbits_to_be_searched = CardStringToRankbits(((char*)hand_or_board_expression.GetString())); write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] rank bits for %s = %i\n", hand_or_board_expression.GetString(), rankbits_to_be_searched); if (is_hand_expression) { // Suited hand-expression // Ranks already checked, there are only 2, this simplifies things if (!p_symbol_engine_cards->issuited()) { write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] No match, because off-suited hole-cards\n"); // No suited ranks available *result = false; return true; } } else { // Suited board-expression int rankbits_available = p_symbol_engine_pokerval->srankbitscommon(); // Check ranks in expression against available ranks if ((rankbits_to_be_searched & rankbits_available) != rankbits_to_be_searched) { write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] No match, because suited rankbits do not fit\n"); *result = false; return true; } } } // Third case: cards with individual suits int length = hand_or_board_expression.GetLength(); for (int i=0; i<(length-1); i++) { if (IsCardRankCharacter(hand_or_board_expression[i]) && IsCardSuitCharacter(hand_or_board_expression[i+1])) { CString card_with_specific_suit = CString(hand_or_board_expression[i]) + CString(hand_or_board_expression[i+1]); int icard_with_specific_suit = CardStringToCardNumber( ((char*)card_with_specific_suit.GetString())); // Check if card is on the board or in the hand if (is_hand_expression) { if (!IsCardInCollection(icard_with_specific_suit, p_table_state->User()->_hole_cards[0].GetValue(), p_table_state->User()->_hole_cards[1].GetValue())) { write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] No match, concrete hole cards do not fit\n"); *result = false; return true; } } else { if (!IsCardInCollection(icard_with_specific_suit, p_table_state->_common_cards[0].GetValue(), p_table_state->_common_cards[1].GetValue(), p_table_state->_common_cards[2].GetValue(), p_table_state->_common_cards[3].GetValue(), p_table_state->_common_cards[4].GetValue())) { write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] No match, concrete board cards do not fit\n"); *result = false; return true; } } } } write_log(preferences.debug_hand_and_baord_expressions(), "[CSymbolEngineOpenPPLHandAndBoardExpression] successful match\n"); *result = true; return true; }