double CParseTreeOperatorNode::Evaluate(bool log /* = false */) { write_log(preferences.debug_formula(), "[CParseTreeOperatorNode] Evaluating node type %i %s\n", _node_type, TokenString(_node_type)); p_autoplayer_trace->SetLastEvaluatedRelativeLineNumber(_relative_line_number); // Actions first, which are "unary". // We have to encode all possible outcomes in a single floating-point, // therefore: // * positive values mean: raise size (by big-blinds, raise-to-semantics) // * negative values mean: elementary actions if (_node_type == kTokenActionRaiseToBigBlinds) { // RaiseTo N Force return EvaluateSibbling(_first_sibbling, log); } else if (_node_type == kTokenActionRaiseByBigBlinds) { // RaiseBy N Force double raise_by_amount_in_bblinds = EvaluateSibbling(_first_sibbling, log); double final_betsize_in_bblinds = p_symbol_engine_chip_amounts->ncallbets() + raise_by_amount_in_bblinds; write_log(preferences.debug_formula(), "[CParseTreeOperatorNode] raiseby = %.2f ncallbets = %.2f final = %.2f\n", raise_by_amount_in_bblinds, p_symbol_engine_chip_amounts->ncallbets(), final_betsize_in_bblinds); return final_betsize_in_bblinds; } else if (_node_type == kTokenActionRaiseByPercentagedPotsize) { // RaiseBy X% Force double raise_by_percentage = EvaluateSibbling(_first_sibbling, log); assert(p_symbol_engine_tablelimits->bet() > 0); double pot_size_after_call_in_big_blinds = (p_symbol_engine_chip_amounts->pot() / p_symbol_engine_tablelimits->bet()) + p_symbol_engine_chip_amounts->nbetstocall(); assert(pot_size_after_call_in_big_blinds >= 0); double raise_by_amount_in_bblinds = 0.01 * raise_by_percentage * pot_size_after_call_in_big_blinds; double final_betsize_in_bblinds = p_symbol_engine_chip_amounts->ncallbets() + raise_by_amount_in_bblinds; write_log(preferences.debug_formula(), "[CParseTreeOperatorNode] raiseby percentage = %.2f pot after call = %.2f raiseby = %.2f final = %.2f\n", raise_by_percentage, pot_size_after_call_in_big_blinds, raise_by_amount_in_bblinds, final_betsize_in_bblinds); return final_betsize_in_bblinds; } else if (TokenIsElementaryAction(_node_type)) { return (0 - _node_type); } // Finally operators else if (TokenIsUnary(_node_type)) { return EvaluateUnaryExpression(log); } else if (TokenIsBinary(_node_type)) { return EvaluateBinaryExpression(log); } else if (TokenIsTernary(_node_type)) { return EvaluateTernaryExpression(log); } assert(false); return kUndefined; }
double CParseTreeNode::Evaluate(bool log /* = false */){ write_log(preferences.debug_formula(), "[CParseTreeNode] Evaluating node type %i %s\n", _node_type, TokenString(_node_type)); p_autoplayer_trace->SetLastEvaluatedRelativeLineNumber(_relative_line_number); // Most common types first: numbers and identifiers if (_node_type == kTokenNumber) { write_log(preferences.debug_formula(), "[CParseTreeNode] Number evaluates to %6.3f\n", _constant_value); return _constant_value; } else if (_node_type == kTokenIdentifier) { assert(_first_sibbling == NULL); assert(_second_sibbling == NULL); assert(_third_sibbling == NULL); assert(_terminal_name != ""); double value = EvaluateIdentifier(_terminal_name, log); write_log(preferences.debug_formula(), "[CParseTreeNode] Identifier evaluates to %6.3f\n", value); // In case of f$-functions the line changed inbetween, // so we have to set it to the current location (again) // for the next log. p_autoplayer_trace->SetLastEvaluatedRelativeLineNumber(_relative_line_number); return value; } // Actions second, which are also "unary". // We have to encode all possible outcomes in a single floating-point, // therefore: // * positive values mean: raise size (by big-blinds, raise-to-semantics) // * negative values mean: elementary actions else if (_node_type == kTokenActionRaiseToBigBlinds) { // RaiseTo N Force return EvaluateSibbling(_first_sibbling, log); } else if (_node_type == kTokenActionRaiseByBigBlinds) { // RaiseBy N Force double raise_by_amount_in_bblinds = EvaluateSibbling(_first_sibbling, log); double final_betsize_in_bblinds = p_symbol_engine_chip_amounts->ncallbets() + raise_by_amount_in_bblinds; write_log(preferences.debug_formula(), "[CParseTreeNode] raiseby = %.2f ncallbets = %.2f final = %.2f\n", raise_by_amount_in_bblinds, p_symbol_engine_chip_amounts->ncallbets(), final_betsize_in_bblinds); return final_betsize_in_bblinds; } else if (_node_type == kTokenActionRaiseByPercentagedPotsize) { // RaiseBy X% Force double raise_by_percentage = EvaluateSibbling(_first_sibbling, log); assert(p_symbol_engine_tablelimits->bet() > 0); double pot_size_after_call_in_big_blinds = (p_symbol_engine_chip_amounts->pot() / p_symbol_engine_tablelimits->bet()) + p_symbol_engine_chip_amounts->nbetstocall(); assert(pot_size_after_call_in_big_blinds >= 0); double raise_by_amount_in_bblinds = 0.01 * raise_by_percentage * pot_size_after_call_in_big_blinds; double final_betsize_in_bblinds = p_symbol_engine_chip_amounts->ncallbets() + raise_by_amount_in_bblinds; write_log(preferences.debug_formula(), "[CParseTreeNode] raiseby percentage = %.2f pot after call = %.2f raiseby = %.2f final = %.2f\n", raise_by_percentage, pot_size_after_call_in_big_blinds, raise_by_amount_in_bblinds, final_betsize_in_bblinds); return final_betsize_in_bblinds; } else if (_node_type == kTokenActionUserVariableToBeSet) { // User-variables are a special case of elementary actions // Therefore need to be handled first. SetUserVariable(_terminal_name); return kUndefinedZero; } else if (TokenIsElementaryAction(_node_type)) { return (0 - _node_type); } // Finally operators else if (TokenIsUnary(_node_type)) { return EvaluateUnaryExpression(log); } else if (TokenIsBinary(_node_type)) { return EvaluateBinaryExpression(log); } else if (TokenIsTernary(_node_type)) { return EvaluateTernaryExpression(log); } assert(false); return kUndefined; }