Spaces:
Sleeping
Sleeping
π Add MULTIPLAYER BATTLE MODE with voice narration
Browse files- Live global leaderboard with country flags
- Real-time competition between players (simulated)
- Your position highlighted and pulsing
- Multiplayer events in the log
- Epic voice narration using Web Speech API
- Dramatic announcements for achievements and milestones
- Alert when other players take the lead
- Challenge button (coming soon)
- Join/Leave global battle toggle
- Leaderboard updates every second
app.py
CHANGED
|
@@ -21,9 +21,22 @@ state = {
|
|
| 21 |
"variants_evaluated": 0,
|
| 22 |
"start_time": None,
|
| 23 |
"achievements": [],
|
| 24 |
-
"high_score": 0.9333
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
}
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
# Achievement definitions
|
| 28 |
ACHIEVEMENTS = {
|
| 29 |
"first_evolution": {"name": "π― First Evolution!", "desc": "Started your first evolution", "threshold": 1},
|
|
@@ -362,6 +375,82 @@ def create_fitness_chart():
|
|
| 362 |
|
| 363 |
return fig
|
| 364 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
def simulate_evolution():
|
| 366 |
"""Simulate one evolution step."""
|
| 367 |
if not state["running"]:
|
|
@@ -369,6 +458,10 @@ def simulate_evolution():
|
|
| 369 |
|
| 370 |
state["iteration"] += 1
|
| 371 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
# Simulate evaluating multiple variants (Modal parallel execution)
|
| 373 |
variants_this_gen = random.randint(4, 8) # Simulating parallel evaluation
|
| 374 |
state["variants_evaluated"] += variants_this_gen
|
|
@@ -555,6 +648,10 @@ def format_events():
|
|
| 555 |
color = "#FFD700"
|
| 556 |
icon = "π"
|
| 557 |
style = "font-size: 16px; font-weight: bold; background: linear-gradient(45deg, #7B3FF2, #00AAFF); padding: 10px; border-radius: 5px; margin: 5px 0;"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 558 |
elif event["type"] == "improvement":
|
| 559 |
color = "#00FF88"
|
| 560 |
icon = "β¨"
|
|
@@ -702,10 +799,62 @@ with gr.Blocks(
|
|
| 702 |
</script>
|
| 703 |
''')
|
| 704 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 705 |
with gr.Row():
|
| 706 |
with gr.Column(scale=1):
|
| 707 |
toggle_btn = gr.Button("π Start Evolution", variant="primary", size="lg")
|
| 708 |
|
|
|
|
|
|
|
|
|
|
| 709 |
gr.Markdown("### π Statistics")
|
| 710 |
with gr.Row():
|
| 711 |
fitness_display = gr.Number(
|
|
@@ -733,9 +882,16 @@ with gr.Blocks(
|
|
| 733 |
gr.Markdown("### π Fitness Evolution")
|
| 734 |
fitness_chart = gr.Plot(value=create_fitness_chart())
|
| 735 |
|
| 736 |
-
#
|
| 737 |
-
gr.
|
| 738 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 739 |
|
| 740 |
# Achievements Display
|
| 741 |
gr.Markdown("### π Achievements & Leaderboard")
|
|
@@ -764,11 +920,16 @@ with gr.Blocks(
|
|
| 764 |
|
| 765 |
# Toggle state
|
| 766 |
running_state = gr.State(False)
|
|
|
|
| 767 |
|
| 768 |
def on_toggle(running):
|
| 769 |
new_state = not running
|
| 770 |
return new_state, toggle_evolution(new_state)
|
| 771 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 772 |
def on_share():
|
| 773 |
return gr.update(visible=True, value=get_share_text())
|
| 774 |
|
|
@@ -778,6 +939,12 @@ with gr.Blocks(
|
|
| 778 |
outputs=[running_state, toggle_btn]
|
| 779 |
)
|
| 780 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 781 |
share_btn.click(
|
| 782 |
fn=on_share,
|
| 783 |
outputs=[share_text]
|
|
@@ -801,6 +968,7 @@ with gr.Blocks(
|
|
| 801 |
speed_display: speed,
|
| 802 |
fitness_chart: create_fitness_chart(),
|
| 803 |
landscape_3d: create_3d_landscape(),
|
|
|
|
| 804 |
code_display: format_code_display(),
|
| 805 |
achievements_display: format_achievements(),
|
| 806 |
event_log: format_events()
|
|
@@ -808,7 +976,7 @@ with gr.Blocks(
|
|
| 808 |
|
| 809 |
timer.tick(
|
| 810 |
fn=update_all,
|
| 811 |
-
outputs=[fitness_display, generation_display, variants_display, speed_display, fitness_chart, landscape_3d, code_display, achievements_display, event_log]
|
| 812 |
)
|
| 813 |
|
| 814 |
# Challenge Mode
|
|
|
|
| 21 |
"variants_evaluated": 0,
|
| 22 |
"start_time": None,
|
| 23 |
"achievements": [],
|
| 24 |
+
"high_score": 0.9333,
|
| 25 |
+
"player_name": f"Player_{random.randint(1000, 9999)}",
|
| 26 |
+
"multiplayer_active": False,
|
| 27 |
+
"other_players": {},
|
| 28 |
+
"global_best": 0.9333
|
| 29 |
}
|
| 30 |
|
| 31 |
+
# Simulated multiplayer data
|
| 32 |
+
FAKE_PLAYERS = [
|
| 33 |
+
{"name": "NeuralNinja_JP", "country": "π―π΅", "fitness": 0.9455, "status": "evolving"},
|
| 34 |
+
{"name": "CodeEvolver_US", "country": "πΊπΈ", "fitness": 0.9523, "status": "evolving"},
|
| 35 |
+
{"name": "AIWizard_UK", "country": "π¬π§", "fitness": 0.9812, "status": "leading"},
|
| 36 |
+
{"name": "QuantumCoder_DE", "country": "π©πͺ", "fitness": 0.9234, "status": "struggling"},
|
| 37 |
+
{"name": "MatrixMaster_FR", "country": "π«π·", "fitness": 0.9667, "status": "evolving"}
|
| 38 |
+
]
|
| 39 |
+
|
| 40 |
# Achievement definitions
|
| 41 |
ACHIEVEMENTS = {
|
| 42 |
"first_evolution": {"name": "π― First Evolution!", "desc": "Started your first evolution", "threshold": 1},
|
|
|
|
| 375 |
|
| 376 |
return fig
|
| 377 |
|
| 378 |
+
def update_multiplayer():
|
| 379 |
+
"""Update multiplayer state with other players' progress."""
|
| 380 |
+
if not state["multiplayer_active"]:
|
| 381 |
+
return
|
| 382 |
+
|
| 383 |
+
# Simulate other players making progress
|
| 384 |
+
for player in FAKE_PLAYERS:
|
| 385 |
+
if random.random() < 0.3: # 30% chance of improvement
|
| 386 |
+
improvement = random.uniform(0.001, 0.01)
|
| 387 |
+
player["fitness"] = min(player["fitness"] + improvement, 0.9999)
|
| 388 |
+
|
| 389 |
+
# Check if someone beat us
|
| 390 |
+
current_fitness = state["fitness_history"][-1] if state["fitness_history"] else 0.9333
|
| 391 |
+
if player["fitness"] > current_fitness and player["fitness"] > state["global_best"]:
|
| 392 |
+
state["global_best"] = player["fitness"]
|
| 393 |
+
state["events"].append({
|
| 394 |
+
"time": datetime.now().strftime("%H:%M:%S"),
|
| 395 |
+
"type": "multiplayer",
|
| 396 |
+
"message": f"β‘ {player['name']} {player['country']} TOOK THE LEAD! ({player['fitness']:.4f})"
|
| 397 |
+
})
|
| 398 |
+
|
| 399 |
+
def format_multiplayer_leaderboard():
|
| 400 |
+
"""Format live multiplayer leaderboard."""
|
| 401 |
+
current_fitness = state["fitness_history"][-1] if state["fitness_history"] else 0.9333
|
| 402 |
+
|
| 403 |
+
# Combine all players
|
| 404 |
+
all_players = [{"name": state["player_name"], "country": "π΄", "fitness": current_fitness, "status": "you"}]
|
| 405 |
+
all_players.extend(FAKE_PLAYERS)
|
| 406 |
+
|
| 407 |
+
# Sort by fitness
|
| 408 |
+
all_players.sort(key=lambda x: x["fitness"], reverse=True)
|
| 409 |
+
|
| 410 |
+
html = '''
|
| 411 |
+
<div style="background: linear-gradient(135deg, #1a1a3a, #0a0a2a); padding: 20px; border-radius: 10px; border: 2px solid #7B3FF2;">
|
| 412 |
+
<h3 style="color: #FFD700; margin-top: 0; text-align: center;">π LIVE GLOBAL LEADERBOARD</h3>
|
| 413 |
+
<div style="max-height: 400px; overflow-y: auto;">
|
| 414 |
+
'''
|
| 415 |
+
|
| 416 |
+
for i, player in enumerate(all_players):
|
| 417 |
+
rank = i + 1
|
| 418 |
+
medal = "π₯" if rank == 1 else "π₯" if rank == 2 else "π₯" if rank == 3 else f"#{rank}"
|
| 419 |
+
|
| 420 |
+
is_you = player["status"] == "you"
|
| 421 |
+
bg_color = "linear-gradient(45deg, #FFD700, #FFA500)" if is_you else "rgba(123, 63, 242, 0.2)"
|
| 422 |
+
border = "2px solid #FFD700" if rank == 1 else "1px solid rgba(255, 255, 255, 0.1)"
|
| 423 |
+
|
| 424 |
+
html += f'''
|
| 425 |
+
<div style="background: {bg_color}; margin: 10px 0; padding: 15px; border-radius: 8px; border: {border};
|
| 426 |
+
{'animation: pulse 2s infinite;' if is_you else ''} transition: all 0.3s;">
|
| 427 |
+
<div style="display: flex; justify-content: space-between; align-items: center;">
|
| 428 |
+
<div style="font-size: 20px; color: {'#000' if is_you else '#FFF'};">
|
| 429 |
+
{medal} {player['country']} <strong>{player['name']}</strong>
|
| 430 |
+
{' (YOU)' if is_you else ''}
|
| 431 |
+
</div>
|
| 432 |
+
<div style="font-size: 24px; color: {'#000' if is_you else '#00FF88'}; font-weight: bold;">
|
| 433 |
+
{player['fitness']:.4f}
|
| 434 |
+
</div>
|
| 435 |
+
</div>
|
| 436 |
+
{'<div style="color: #FFD700; font-size: 14px; margin-top: 5px;">π₯ YOUR POSITION</div>' if is_you else ''}
|
| 437 |
+
</div>
|
| 438 |
+
'''
|
| 439 |
+
|
| 440 |
+
html += '''
|
| 441 |
+
</div>
|
| 442 |
+
<div style="text-align: center; margin-top: 20px;">
|
| 443 |
+
<button style="background: linear-gradient(45deg, #FF6B6B, #4ECDC4); color: white; border: none;
|
| 444 |
+
padding: 10px 30px; border-radius: 25px; font-size: 18px; cursor: pointer;"
|
| 445 |
+
onclick="alert('Multiplayer Battle Mode: Coming Soon!')">
|
| 446 |
+
βοΈ CHALLENGE TOP PLAYER
|
| 447 |
+
</button>
|
| 448 |
+
</div>
|
| 449 |
+
</div>
|
| 450 |
+
'''
|
| 451 |
+
|
| 452 |
+
return html
|
| 453 |
+
|
| 454 |
def simulate_evolution():
|
| 455 |
"""Simulate one evolution step."""
|
| 456 |
if not state["running"]:
|
|
|
|
| 458 |
|
| 459 |
state["iteration"] += 1
|
| 460 |
|
| 461 |
+
# Update multiplayer if active
|
| 462 |
+
if state["multiplayer_active"]:
|
| 463 |
+
update_multiplayer()
|
| 464 |
+
|
| 465 |
# Simulate evaluating multiple variants (Modal parallel execution)
|
| 466 |
variants_this_gen = random.randint(4, 8) # Simulating parallel evaluation
|
| 467 |
state["variants_evaluated"] += variants_this_gen
|
|
|
|
| 648 |
color = "#FFD700"
|
| 649 |
icon = "π"
|
| 650 |
style = "font-size: 16px; font-weight: bold; background: linear-gradient(45deg, #7B3FF2, #00AAFF); padding: 10px; border-radius: 5px; margin: 5px 0;"
|
| 651 |
+
elif event["type"] == "multiplayer":
|
| 652 |
+
color = "#FF6B6B"
|
| 653 |
+
icon = "βοΈ"
|
| 654 |
+
style = "font-size: 14px; font-weight: bold; background: rgba(255, 107, 107, 0.2); padding: 8px; border-radius: 5px; margin: 5px 0; border: 1px solid #FF6B6B;"
|
| 655 |
elif event["type"] == "improvement":
|
| 656 |
color = "#00FF88"
|
| 657 |
icon = "β¨"
|
|
|
|
| 799 |
</script>
|
| 800 |
''')
|
| 801 |
|
| 802 |
+
# Epic Voice Narration System
|
| 803 |
+
gr.HTML('''
|
| 804 |
+
<script>
|
| 805 |
+
// Text-to-speech narration
|
| 806 |
+
const speak = (text, rate = 1, pitch = 1) => {
|
| 807 |
+
if (!window.speechSynthesis) return;
|
| 808 |
+
|
| 809 |
+
const utterance = new SpeechSynthesisUtterance(text);
|
| 810 |
+
utterance.rate = rate;
|
| 811 |
+
utterance.pitch = pitch;
|
| 812 |
+
utterance.volume = 0.8;
|
| 813 |
+
|
| 814 |
+
// Try to use a dramatic voice
|
| 815 |
+
const voices = speechSynthesis.getVoices();
|
| 816 |
+
const dramaticVoice = voices.find(v => v.name.includes('Daniel') || v.name.includes('Alex')) || voices[0];
|
| 817 |
+
if (dramaticVoice) utterance.voice = dramaticVoice;
|
| 818 |
+
|
| 819 |
+
speechSynthesis.speak(utterance);
|
| 820 |
+
};
|
| 821 |
+
|
| 822 |
+
// Epic intro narration
|
| 823 |
+
setTimeout(() => {
|
| 824 |
+
speak("Welcome to Evolution Aurora. Where artificial intelligence learns to code before your very eyes.", 0.9, 0.8);
|
| 825 |
+
}, 1000);
|
| 826 |
+
|
| 827 |
+
// Watch for achievements and milestones
|
| 828 |
+
const narrateProgress = new MutationObserver((mutations) => {
|
| 829 |
+
mutations.forEach((mutation) => {
|
| 830 |
+
const text = mutation.target.textContent || '';
|
| 831 |
+
|
| 832 |
+
if (text.includes('ACHIEVEMENT UNLOCKED')) {
|
| 833 |
+
speak("Achievement unlocked!", 1.2, 1.2);
|
| 834 |
+
} else if (text.includes('0.95') && text.includes('Fitness')) {
|
| 835 |
+
speak("Incredible! 95 percent fitness achieved. The AI is learning fast.", 1, 0.9);
|
| 836 |
+
} else if (text.includes('0.99') && text.includes('Fitness')) {
|
| 837 |
+
speak("Approaching perfection! 99 percent fitness. This is extraordinary!", 1.1, 1.1);
|
| 838 |
+
} else if (text.includes('TOOK THE LEAD')) {
|
| 839 |
+
speak("Alert! Another player has taken the lead! You must evolve faster!", 1.2, 1);
|
| 840 |
+
}
|
| 841 |
+
});
|
| 842 |
+
});
|
| 843 |
+
|
| 844 |
+
setTimeout(() => {
|
| 845 |
+
const containers = document.querySelectorAll('[id*="display"], [id*="event_log"]');
|
| 846 |
+
containers.forEach(c => narrateProgress.observe(c, { childList: true, subtree: true }));
|
| 847 |
+
}, 2000);
|
| 848 |
+
</script>
|
| 849 |
+
''')
|
| 850 |
+
|
| 851 |
with gr.Row():
|
| 852 |
with gr.Column(scale=1):
|
| 853 |
toggle_btn = gr.Button("π Start Evolution", variant="primary", size="lg")
|
| 854 |
|
| 855 |
+
# Multiplayer toggle
|
| 856 |
+
multiplayer_btn = gr.Button("π Join Global Battle", variant="secondary", size="lg")
|
| 857 |
+
|
| 858 |
gr.Markdown("### π Statistics")
|
| 859 |
with gr.Row():
|
| 860 |
fitness_display = gr.Number(
|
|
|
|
| 882 |
gr.Markdown("### π Fitness Evolution")
|
| 883 |
fitness_chart = gr.Plot(value=create_fitness_chart())
|
| 884 |
|
| 885 |
+
# Multiplayer Leaderboard
|
| 886 |
+
with gr.Row():
|
| 887 |
+
with gr.Column(scale=1):
|
| 888 |
+
gr.Markdown("### π Global Competition")
|
| 889 |
+
multiplayer_display = gr.HTML(value=format_multiplayer_leaderboard())
|
| 890 |
+
|
| 891 |
+
with gr.Column(scale=2):
|
| 892 |
+
# Code Evolution Display
|
| 893 |
+
gr.Markdown("### 𧬠Live Code Evolution")
|
| 894 |
+
code_display = gr.HTML(value=format_code_display())
|
| 895 |
|
| 896 |
# Achievements Display
|
| 897 |
gr.Markdown("### π Achievements & Leaderboard")
|
|
|
|
| 920 |
|
| 921 |
# Toggle state
|
| 922 |
running_state = gr.State(False)
|
| 923 |
+
multiplayer_state = gr.State(False)
|
| 924 |
|
| 925 |
def on_toggle(running):
|
| 926 |
new_state = not running
|
| 927 |
return new_state, toggle_evolution(new_state)
|
| 928 |
|
| 929 |
+
def on_multiplayer(active):
|
| 930 |
+
state["multiplayer_active"] = not active
|
| 931 |
+
return not active, "π« Leave Battle" if not active else "π Join Global Battle"
|
| 932 |
+
|
| 933 |
def on_share():
|
| 934 |
return gr.update(visible=True, value=get_share_text())
|
| 935 |
|
|
|
|
| 939 |
outputs=[running_state, toggle_btn]
|
| 940 |
)
|
| 941 |
|
| 942 |
+
multiplayer_btn.click(
|
| 943 |
+
fn=on_multiplayer,
|
| 944 |
+
inputs=[multiplayer_state],
|
| 945 |
+
outputs=[multiplayer_state, multiplayer_btn]
|
| 946 |
+
)
|
| 947 |
+
|
| 948 |
share_btn.click(
|
| 949 |
fn=on_share,
|
| 950 |
outputs=[share_text]
|
|
|
|
| 968 |
speed_display: speed,
|
| 969 |
fitness_chart: create_fitness_chart(),
|
| 970 |
landscape_3d: create_3d_landscape(),
|
| 971 |
+
multiplayer_display: format_multiplayer_leaderboard(),
|
| 972 |
code_display: format_code_display(),
|
| 973 |
achievements_display: format_achievements(),
|
| 974 |
event_log: format_events()
|
|
|
|
| 976 |
|
| 977 |
timer.tick(
|
| 978 |
fn=update_all,
|
| 979 |
+
outputs=[fitness_display, generation_display, variants_display, speed_display, fitness_chart, landscape_3d, multiplayer_display, code_display, achievements_display, event_log]
|
| 980 |
)
|
| 981 |
|
| 982 |
# Challenge Mode
|