add real-time game data, prediction history, and fix winning cards chart
- WebSocket connection shows live game state (round #, phase, bets per chair, pot) in a persistent bar at the top of predictions page - Prediction cards now display current bet amounts per chair - Round results flash HIT/MISS against the Bayesian prediction - New "Last 20 Predictions vs Actual" table with per-game probabilities, predicted vs actual winner, and running accuracy - Predictions auto-refresh after each round ends - Fix winning cards chart: use taller container (480px) and dedicated scales config for horizontal bar rendering - Add _last_n_predictions() helper to db.py for detailed per-game prediction history with game numbers
This commit is contained in:
39
app/db.py
39
app/db.py
@@ -1217,14 +1217,39 @@ def _backtest_theories(winners):
|
||||
}
|
||||
|
||||
|
||||
def _last_n_predictions(winners, n=20):
|
||||
"""Get detailed prediction vs actual for the last N games."""
|
||||
warmup = 30
|
||||
if len(winners) <= warmup:
|
||||
return []
|
||||
start = max(warmup, len(winners) - n)
|
||||
results = []
|
||||
for i in range(start, len(winners)):
|
||||
history = winners[:i]
|
||||
actual = winners[i]
|
||||
m1, _ = _markov_matrix_1(history)
|
||||
m2, _ = _markov_matrix_2(history)
|
||||
pred, _ = _bayesian_prediction(history, m1, m2)
|
||||
predicted = max(CHAIR_LABELS, key=lambda c: pred[c])
|
||||
results.append({
|
||||
"index": i,
|
||||
"predicted": predicted,
|
||||
"actual": actual,
|
||||
"correct": predicted == actual,
|
||||
"probs": {c: round(pred[c], 4) for c in CHAIR_LABELS},
|
||||
})
|
||||
return results
|
||||
|
||||
|
||||
@_with_lock
|
||||
def get_prediction_analysis() -> dict:
|
||||
"""Run all prediction/game-theory analysis and return results."""
|
||||
client = get_client()
|
||||
|
||||
# Query 1: Full winner sequence
|
||||
result = client.query("SELECT winner FROM games ORDER BY game_no ASC")
|
||||
winners = [config.CHAIRS.get(r[0], "?") for r in result.result_rows]
|
||||
# Query 1: Full winner sequence with game numbers
|
||||
result = client.query("SELECT game_no, winner FROM games ORDER BY game_no ASC")
|
||||
game_nos = [r[0] for r in result.result_rows if config.CHAIRS.get(r[1], "?") in CHAIR_LABELS]
|
||||
winners = [config.CHAIRS.get(r[1], "?") for r in result.result_rows]
|
||||
winners = [w for w in winners if w in CHAIR_LABELS] # filter unknowns
|
||||
|
||||
# Query 2: Card data for last 500 games
|
||||
@@ -1252,6 +1277,13 @@ def get_prediction_analysis() -> dict:
|
||||
# Backtesting
|
||||
backtest = _backtest_theories(winners)
|
||||
|
||||
# Last 20 prediction vs actual
|
||||
last_20_raw = _last_n_predictions(winners, 20)
|
||||
# Attach game_nos to last_20
|
||||
for entry in last_20_raw:
|
||||
idx = entry["index"]
|
||||
entry["game_no"] = game_nos[idx] if idx < len(game_nos) else 0
|
||||
|
||||
# Card analysis
|
||||
card_values = _card_value_distribution(cards_data)
|
||||
face_cards = _face_card_frequency(cards_data)
|
||||
@@ -1261,6 +1293,7 @@ def get_prediction_analysis() -> dict:
|
||||
return {
|
||||
"total_games": len(winners),
|
||||
"last_winners": winners[-10:] if len(winners) >= 10 else winners,
|
||||
"last_20_predictions": last_20_raw,
|
||||
"prediction": prediction,
|
||||
"signals": signals,
|
||||
"markov1": {"matrix": markov1, "counts": {k: dict(v) for k, v in markov1_counts.items()}},
|
||||
|
||||
Reference in New Issue
Block a user