diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc index 0317a72..b2c311e 100644 Binary files a/core/__pycache__/forms.cpython-311.pyc and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 17eeb8b..312a4eb 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 5bd3ba6..ea857fb 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/forms.py b/core/forms.py index e0791ad..83c6d29 100644 --- a/core/forms.py +++ b/core/forms.py @@ -36,6 +36,9 @@ class LotterySimulatorForm(forms.Form): (50, "50 Jogos"), (100, "100 Jogos"), (1000000000000, "1 Trilhão (Simulação IA)"), + (10000000000000, "10 Trilhões (Simulação Massiva)"), + (30000000000000, "30 Trilhões (Simulação Elite)"), + (60000000000000, "60 Trilhões (Poder Máximo)"), ], initial=5, widget=forms.Select( diff --git a/core/templates/core/edit_lottery.html b/core/templates/core/edit_lottery.html index dbf7c72..4da6da1 100644 --- a/core/templates/core/edit_lottery.html +++ b/core/templates/core/edit_lottery.html @@ -14,9 +14,13 @@

Editor: {{ lottery.get_name_display }}

Selecione os números para ANULAR ou use a IA.

- - Auto-Previsão IA - +
+ + Auto-Previsão IA Rotativa + +
+ Recalcula Verdes ignorando Anulados +
diff --git a/core/templates/core/index.html b/core/templates/core/index.html index 88acb5a..8915a9c 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -130,12 +130,13 @@
-
Probabilidades Quentes (Verde)
+
Probabilidades Quentes (Elite Verde)
{% for number in result.hot_numbers %} - {{ number|stringformat:"02d" }} + {{ number|stringformat:"02d" }} {% endfor %}
+ * Atualizado ao vivo conforme anulações no editor.
Números Anulados (Vermelho)
@@ -159,9 +160,9 @@
{% if result.is_trillion %} -
- Simulação de 1 Trilhão Concluída!
- A IA processou 1.000.000.000.000 de possibilidades e selecionou as 6 combinações de maior elite estatística. +
+ Simulação de {{ result.trillion_label }} Concluída!
+ A IA processou o volume massivo de possibilidades e selecionou as 6 combinações de elite estatística usando o Sistema Rotativo (excluindo anulados).
{% endif %} {% for suggestion in result.suggestions %} @@ -189,6 +190,172 @@
+
+
+
+

Seleção Manual & Matemática Ao Vivo

+

Escolha 6 ou mais números e peça à IA para calcular a elite estatística agora.

+
+ +
+
+
+
+

Quadro de Dezenas

+ 0 selecionados +
+
+

Selecione uma loteria no simulador acima para carregar o quadro.

+
+
+
+
+
+

Análise Ao Vivo

+
+
+
--
+
Score de Elite IA
+
+
+ +

Mínimo de 6 dezenas para processar.

+
+
+
+
+
+
+ + + + +
diff --git a/core/urls.py b/core/urls.py index 79ab44d..699b118 100644 --- a/core/urls.py +++ b/core/urls.py @@ -8,4 +8,5 @@ urlpatterns = [ path('admin-loto/dashboard/', views.admin_dashboard, name='admin_dashboard'), path('admin-loto/edit//', views.edit_lottery, name='edit_lottery'), path('admin-loto/ai-predict//', views.ai_auto_predict, name='ai_predict'), + path('live-math/', views.live_math, name='live_math'), ] diff --git a/core/views.py b/core/views.py index d956e1a..edfb902 100644 --- a/core/views.py +++ b/core/views.py @@ -6,6 +6,8 @@ from collections import Counter from django import get_version as django_version from django.shortcuts import render, redirect, get_object_or_404 +from django.http import JsonResponse +import json from django.utils import timezone from django.contrib import messages @@ -75,11 +77,13 @@ def _format_percent(odds): return f"{percent:.6f}%".replace(".", ",") def ai_auto_predict(request, lottery_id): - """Calcula automaticamente os números quentes via IA baseada em estatísticas reais.""" + """Calcula automaticamente os números quentes via IA baseada em estatísticas reais e excluindo anulados.""" if not check_admin(request): return redirect('admin_login') lottery = get_object_or_404(Lottery, id=lottery_id) + annulled = [int(n) for n in lottery.annulled_numbers.split(',') if n] + # Pega todos os sorteios (Histórico Completo) draws_db = DrawResult.objects.filter(lottery=lottery) @@ -91,7 +95,7 @@ def ai_auto_predict(request, lottery_id): draw_lists = [[int(n) for n in d.numbers.split(',')] for d in draws_db] frequency = Counter(number for draw in draw_lists for number in draw) - # Calcular atraso (há quantos sorteios o número não sai) + # Calcular atraso last_seen = {} for i, draw in enumerate(reversed(draw_lists)): for num in draw: @@ -99,21 +103,24 @@ def ai_auto_predict(request, lottery_id): last_seen[num] = i # Score IA = (Frequência * 0.7) + (Atraso * 0.3) + # SISTEMA ROTATIVO: Ignora números anulados no cálculo scores = [] for num in range(1, lottery.max_number + 1): + if num in annulled: + continue freq = frequency.get(num, 0) delay = last_seen.get(num, len(draw_lists)) score = (freq * 0.7) + (delay * 0.3) scores.append((num, score)) - # Pega os 20% melhores números como "IA Hot" + # Pega os 20% melhores números restantes como "IA Hot" scores.sort(key=lambda x: x[1], reverse=True) - top_numbers = [str(n[0]) for n in scores[:int(lottery.max_number * 0.2)]] + top_numbers = [str(n[0]) for n in scores[:int(lottery.max_number * 0.25)]] lottery.ai_predictions = ",".join(top_numbers) lottery.save() - messages.success(request, f"IA calculou as probabilidades para {lottery.get_name_display()} com sucesso!") + messages.success(request, f"IA Rotativa: Probabilidades calculadas ignorando {len(annulled)} números anulados!") return redirect('edit_lottery', lottery_id=lottery_id) def home(request): @@ -171,13 +178,29 @@ def home(request): numbers = [n for n in range(1, lottery_obj.max_number + 1) if n not in annulled] # Definição de Cores: Verde (Hot) e Vermelho (Frio) - hot_numbers = ai_hot if ai_hot else [n for n, c in frequency.most_common(10)] - cold_numbers = [n for n in range(1, lottery_obj.max_number + 1) if n not in hot_numbers and n not in annulled] + # MATEMÁTICA AO VIVO: Calcula a elite estatística no momento do acesso, ignorando anulados. + # Pegamos os números com maior frequência que NÃO estão anulados. + available_numbers = [n for n in range(1, lottery_obj.max_number + 1) if n not in annulled] + + # Ordena os números disponíveis pela frequência (quentes primeiro) + sorted_by_freq = sorted(available_numbers, key=lambda n: frequency.get(n, 0), reverse=True) + + # A "Elite Verde" será composta pelos top 25% dos números mais frequentes disponíveis + hot_count = max(6, int(len(available_numbers) * 0.25)) + hot_numbers = sorted_by_freq[:hot_count] + + cold_numbers = [n for n in sorted_by_freq[hot_count:]] suggestions = [] - # Se for 1 Trilhão, usamos simulação de Monte Carlo para gerar apenas as 6 "Melhores de Elite" + # Suporte a múltiplas escalas de Trilhões is_trillion = (games_to_generate >= 1_000_000_000_000) actual_games_to_gen = 6 if is_trillion else games_to_generate + + trillion_label = "" + if games_to_generate == 1_000_000_000_000: trillion_label = "1 Trilhão" + elif games_to_generate == 10_000_000_000_000: trillion_label = "10 Trilhões" + elif games_to_generate == 30_000_000_000_000: trillion_label = "30 Trilhões" + elif games_to_generate == 60_000_000_000_000: trillion_label = "60 Trilhões" for _ in range(actual_games_to_gen): if len(numbers) >= lottery_obj.numbers_to_draw: @@ -196,6 +219,7 @@ def home(request): "lottery": lottery_obj.get_name_display(), "draws_used": len(draw_lists), "is_trillion": is_trillion, + "trillion_label": trillion_label, "suggestions": suggestions, "hot_numbers": hot_numbers, "cold_numbers": cold_numbers[:15], # Amostra de frios @@ -215,3 +239,53 @@ def home(request): "is_admin": check_admin(request), } return render(request, "core/index.html", context) + +def live_math(request): + """Calcula a probabilidade matemática ao vivo para números selecionados manualmente.""" + if request.method == "POST": + try: + data = json.loads(request.body) + lottery_key = data.get("lottery") + manual_numbers = [int(n) for n in data.get("numbers", [])] + + if not manual_numbers or len(manual_numbers) < 6: + return JsonResponse({"error": "Selecione ao menos 6 números."}, status=400) + + lottery = get_object_or_404(Lottery, name=lottery_key) + draws_db = DrawResult.objects.filter(lottery=lottery) + + # Se não houver sorteios, usamos uma base simulada para a matemática ao vivo + if not draws_db.exists(): + frequency = {n: random.randint(5, 15) for n in range(1, lottery.max_number + 1)} + else: + draw_lists = [[int(n) for n in d.numbers.split(',')] for d in draws_db] + frequency = Counter(number for draw in draw_lists for number in draw) + + ai_hot = [int(n) for n in lottery.ai_predictions.split(',') if n] + annulled = [int(n) for n in lottery.annulled_numbers.split(',') if n] + + # Cálculo de "Calor" (Heat Score) + # 1. Quantos são Verdes (IA Hot) + hits_hot = len([n for n in manual_numbers if n in ai_hot]) + # 2. Quantos foram anulados (Erro crítico) + hits_annulled = len([n for n in manual_numbers if n in annulled]) + + # Média de frequência dos números escolhidos + avg_freq = sum(frequency.get(n, 0) for n in manual_numbers) / len(manual_numbers) + max_freq = max(frequency.values()) if frequency else 1 + + # Score final de 0 a 100 + score = (hits_hot / len(manual_numbers) * 50) + (avg_freq / max_freq * 50) + if hits_annulled > 0: + score = score * (1 - (hits_annulled / len(manual_numbers))) + + return JsonResponse({ + "score": round(score, 2), + "hits_hot": hits_hot, + "hits_annulled": hits_annulled, + "message": "Cálculo Matemático Ao Vivo Concluído!", + "status": "success" if score > 50 else "warning" + }) + except Exception as e: + return JsonResponse({"error": str(e)}, status=500) + return JsonResponse({"error": "Método inválido"}, status=405)