Fix extraction to consider all results with equal payouts weighted by odds

When the CAP threshold is negative and all payouts are 0 (no bets placed),
the system was only selecting one result (e.g., always DRAW) instead of
considering all results with equal payouts.

Changes:
- Fixed fallback selection to include ALL results with minimum payout
- Weighted random selection now properly considers all tied results
- Outcomes with better odds (lower coefficients) have higher probability

This ensures fair random selection among all possible outcomes when
multiple results have the same payout, weighted by their odds.
parent 47edba78
......@@ -45,10 +45,7 @@ A cross-platform multimedia client application with video playback, web dashboar
- `oauth_providers` - OAuth provider configurations
- `user_oauth_accounts` - Linked OAuth accounts
- `currencies` - Fiat and cryptocurrency definitions
- `exchange_rate_history` - Historical exchange rates
- `exchange_rate_providers` - Exchange rate API providers
- `broker_subscriptions` - Broker subscription management
- `subscription_plans` - Available subscription tiers
- `exchange_rate_history`gAvailable subscription tiers
- `broker_transactions` - Financial transaction records
- `broker_usage_stats` - Usage statistics tracking
- `timezones` - Timezone definitions
......
......@@ -3684,10 +3684,10 @@ class GamesThread(ThreadedComponent):
logger.info(f"🎯 [EXTRACTION DEBUG] Eligible payouts (≤ {cap_threshold:.2f}): {eligible_payouts}")
if not eligible_payouts:
# No payouts below CAP, select the lowest payout
lowest_payout_result = min(payouts, key=payouts.get)
eligible_payouts = {lowest_payout_result: payouts[lowest_payout_result]}
logger.info(f"🚨 [EXTRACTION DEBUG] No payouts below CAP, selecting lowest payout: {lowest_payout_result} ({payouts[lowest_payout_result]:.2f})")
# No payouts below CAP, select ALL results with the lowest payout
min_payout = min(payouts.values())
eligible_payouts = {k: v for k, v in payouts.items() if v == min_payout}
logger.info(f"🚨 [EXTRACTION DEBUG] No payouts below CAP, selecting ALL results with lowest payout ({min_payout:.2f}): {list(eligible_payouts.keys())}")
# Step 7: Perform weighted random selection
logger.info(f"🎲 [EXTRACTION DEBUG] Step 7: Performing weighted random selection from {len(eligible_payouts)} eligible results")
......@@ -3767,10 +3767,37 @@ class GamesThread(ThreadedComponent):
return selected_result
# If multiple candidates with same max payout, select randomly among them
# weighted by inverse of their coefficients (higher coefficient = lower probability)
if len(candidates) > 1:
# Get coefficients for each candidate to weight the selection
candidate_weights = []
for candidate in candidates:
coefficient = self._get_outcome_coefficient(match_id, candidate, session)
# Use inverse coefficient as weight (higher coefficient = lower weight)
weight = 1.0 / coefficient if coefficient > 0 else 1.0
candidate_weights.append(weight)
logger.info(f"🎯 [EXTRACTION DEBUG] Candidate '{candidate}' coefficient: {coefficient}, weight: {weight:.4f}")
# Perform weighted random selection
total_weight = sum(candidate_weights)
if total_weight > 0:
rand = random.uniform(0, total_weight)
cumulative_weight = 0
selected_result = candidates[0] # Default fallback
for i, candidate in enumerate(candidates):
cumulative_weight += candidate_weights[i]
if rand < cumulative_weight:
selected_result = candidate
break
logger.info(f"🎯 [EXTRACTION DEBUG] Weighted random selection among {len(candidates)} candidates: {selected_result} (rand: {rand:.4f}, total_weight: {total_weight:.4f})")
else:
# Fallback to equal weights if total is 0
selected_result = random.choice(candidates)
logger.info(f"🎯 [EXTRACTION DEBUG] Random selection among {len(candidates)} candidates: {selected_result}")
logger.info(f"🎯 [EXTRACTION DEBUG] Equal probability selection (zero total weight): {selected_result}")
return selected_result
return list(eligible_payouts.keys())[0] if eligible_payouts else None
except Exception as e:
logger.error(f"Failed to select max redistribution result: {e}")
# Fallback to first available
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment