cuxlip commited on
Commit
e4eb517
·
verified ·
1 Parent(s): 22c664e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +200 -1
app.py CHANGED
@@ -45,4 +45,203 @@ META_HEROES = {
45
  "counters": {"Grock": "Immune CC.", "Vexana": "Teror bayangan lord.", "Terizla": "Adu gebuk menang sustain."}
46
  },
47
  "Terizla": {
48
- "role": "EXP Laner", "type": "Sustain/Initi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  "counters": {"Grock": "Immune CC.", "Vexana": "Teror bayangan lord.", "Terizla": "Adu gebuk menang sustain."}
46
  },
47
  "Terizla": {
48
+ "role": "EXP Laner", "type": "Sustain/Initiator", "meta": "Wombo Combo",
49
+ "counters": {"Valir": "Zonasi dorongan menjauh.", "Karrie": "Dicairkan dengan true damage.", "Diggie": "Bebas dari rantai ulti."}
50
+ },
51
+ "Ruby": {
52
+ "role": "EXP Laner", "type": "Spellvamp/Cc", "meta": "Sustained",
53
+ "counters": {"Baxia": "Memotong lifesteal.", "Phoveus": "Ayunan skill pemicu lompatan.", "Minsitthar": "Mencegah pasif lompat kecil."}
54
+ }
55
+ # Tambahkan counter hero META lainnya di sini jika diperlukan
56
+ }
57
+
58
+ # ========================================================
59
+ # 2. DAFTAR UTUH SEMUA HERO MLBB (TOTAL LIST)
60
+ # ========================================================
61
+ ALL_MLBB_HEROES = sorted([
62
+ # META PRIORITAS (Ditampilkan di atas dengan tanda khusus)
63
+ "⭐ Ling", "⭐ Fanny", "⭐ Nolan", "⭐ Hayabusa", "⭐ Hylos", "⭐ Zhuxin",
64
+ "⭐ Tigreal", "⭐ Mathilda", "⭐ Harith", "⭐ Roger", "⭐ Terizla", "⭐ Ruby",
65
+ # ALL HEROES SYSTEM
66
+ "Aamon", "Akai", "Aldous", "Alice", "Alpha", "Alucard", "Angela", "Argus", "Arlott", "Atlas", "Aulus", "Aurora",
67
+ "Badang", "Balmond", "Bane", "Barats", "Baxia", "Beatrix", "Belerick", "Benedetta", "Brody", "Bruno",
68
+ "Carmilla", "Cecilion", "Chang'e", "Chou", "Cici", "Claude", "Clint", "Cyclops",
69
+ "Diggie", "Dyrroth", "Esmeralda", "Estes", "Eudora", "Faramis", "Floryn", "Fredrinn", "Freya",
70
+ "Gatotkaca", "Gloo", "Gord", "Grock", "Guinevere", "Gusion", "Hanabi", "Hanzo", "Harley", "Helcurt",
71
+ "Irithel", "Ixia", "Jawhead", "Johnson", "Kadita", "Kagura", "Kaja", "Karina", "Karrie", "Khaleed", "Khufra", "Kimmy",
72
+ "Lancelot", "Layla", "Leomord", "Lesley", "Lolita", "Lunox", "Luo Yi", "Lyria", "Martis", "Masha", "Melissa", "Minotaur", "Minsitthar", "Miya", "Moskov",
73
+ "Nana", "Natalia", "Natan", "Novaria", "Odette", "Paquito", "Pharsa", "Phoveus", "Popol and Kupa",
74
+ "Rafaela", "Saber", "Selena", "Silvanna", "Sun", "Terizla", "Thamuz", "Uranus", "Vale", "Valentina", "Valir", "Vexana",
75
+ "Wanwan", "X.Borg", "Xavier", "Yi Sun-shin", "Yin", "Yu Zhong", "Yve", "Zilong"
76
+ ])
77
+
78
+ BLANK_IMG = "https://via.placeholder.com/65x65/0f172a/64748b?text=%3F"
79
+
80
+ # Helper pembersih bintang untuk pencarian database & gambar
81
+ def clean_name(name):
82
+ if not name: return ""
83
+ return name.replace("⭐ ", "").strip()
84
+
85
+ # Render HTML Image otomatis menggunakan placeholder terstandar jika tidak terdaftar link manual
86
+ def update_hero_html(hero_name):
87
+ if not hero_name:
88
+ return f'<div style="display:flex; justify-content:center; margin: 4px 0;"><img src="{BLANK_IMG}" style="width:65px; height:65px; border-radius:8px; border:2px solid #334155;" /></div>'
89
+
90
+ pure_name = clean_name(hero_name)
91
+ # Fallback gambar text generator jika link statis tidak dipanggil langsung
92
+ url = f"https://via.placeholder.com/65x65/1e293b/f8fafc?text={pure_name[:4]}"
93
+
94
+ return f'<div style="display:flex; justify-content:center; margin: 4px 0;"><img src="{url}" style="width:65px; height:65px; border-radius:8px; border:2px solid #475569; object-fit:cover;" /></div>'
95
+
96
+ def analyze_tournament_draft(rank, b1, b2, b3, b4, b5, r1, r2, r3, r4, r5, ban1, ban2, ban3, ban4, ban5, ban6, ban7, ban8, ban9, ban10):
97
+ blue_team = [clean_name(h) for h in [b1, b2, b3, b4, b5] if h]
98
+ red_team = [clean_name(h) for h in [r1, r2, r3, r4, r5] if h]
99
+ all_bans = [clean_name(h) for h in [ban1, ban2, ban3, ban4, ban5, ban6, ban7, ban8, ban9, ban10] if h]
100
+
101
+ # 1. ANALISIS COUNTER HERO MUSUH (BERBASIS META CORE)
102
+ counter_html = "<div style='background-color: #0f172a; padding: 15px; border-radius: 10px; border: 1px solid #334155;'>"
103
+ if not red_team:
104
+ counter_html += "<p style='color: #94a3b8; margin:0;'>Menunggu pick musuh...</p>"
105
+ else:
106
+ has_meta_analysis = False
107
+ for hero in red_team:
108
+ if hero in META_HEROES:
109
+ has_meta_analysis = True
110
+ data = META_HEROES[hero]
111
+ counter_html += f"""
112
+ <div style='margin-bottom: 12px; border-left: 4px solid #ef4444; padding-left: 12px;'>
113
+ <b style='color: #f87171;'>⚠️ ANCAMAN META: {hero}</b> <span style='font-size:11px; color:#cbd5e1; background:#991b1b; padding:2px 6px; border-radius:4px;'>{data['meta']}</span>
114
+ <ul style='color: #94a3b8; font-size: 13px; margin: 4px 0 0 15px; padding:0;'>
115
+ """
116
+ for c_hero, reason in data["counters"].items():
117
+ if c_hero not in blue_team and c_hero not in red_team and c_hero not in all_bans:
118
+ counter_html += f"<li><span style='color: #60a5fa; font-weight:bold;'>{c_hero}</span>: {reason}</li>"
119
+ counter_html += "</ul></div>"
120
+ if not has_meta_analysis:
121
+ counter_html += "<p style='color: #34d399; margin:0;'>✅ Musuh pick hero non-prioritas turnamen. Tekanan draf tergolong aman.</p>"
122
+ counter_html += "</div>"
123
+
124
+ # 2. METALOGI & REKOMENDASI COMBO TIM
125
+ meta_counts = {}
126
+ for h in blue_team:
127
+ if h in META_HEROES:
128
+ m_type = META_HEROES[h]["meta"]
129
+ meta_counts[m_type] = meta_counts.get(m_type, 0) + 1
130
+
131
+ meta_html = "<div style='background-color: #0f172a; padding: 15px; border-radius: 10px; border: 1px solid #334155;'>"
132
+ if not blue_team:
133
+ meta_html += "<p style='color: #94a3b8; margin:0;'>Rancang draf timmu untuk melihat arah sinergi META...</p>"
134
+ else:
135
+ dominant_meta = max(meta_counts, key=meta_counts.get) if meta_counts else "Sustain/Balanced"
136
+ if dominant_meta == "Wombo Combo":
137
+ meta_html += "<b style='color: #fbbf24; font-size:16px;'>🔥 DETEKSI STRATEGI: META WOMBO COMBO</b><p style='color: #cbd5e1; font-size:13px; margin:5px 0;'>Sinergikan dengan hero area CC masal.</p>"
138
+ elif dominant_meta == "Ube/Regen":
139
+ meta_html += "<b style='color: #34d399; font-size:16px;'>🛡️ DETEKSI STRATEGI: META UBE (REGEN)</b><p style='color: #cbd5e1; font-size:13px; margin:5px 0;'>Pertahankan formasi menempel dan amankan healer/tank tebal.</p>"
140
+ elif dominant_meta == "Dive":
141
+ meta_html += "<b style='color: #60a5fa; font-size:16px;'>🚀 DETEKSI STRATEGI: META DIVE (TABRAK)</b><p style='color: #cbd5e1; font-size:13px; margin:5px 0;'>Amankan hero penabrak lini belakang musuh.</p>"
142
+ else:
143
+ meta_html += f"<b style='color: #cbd5e1; font-size:14px;'>🛡️ STRATEGI BERIMBANG ATAU COMFORT PICK ({dominant_meta})</b>"
144
+ meta_html += "</div>"
145
+
146
+ return counter_html, meta_html, "<div style='background-color: #0f172a; padding: 15px; border-radius: 10px; border: 1px solid #334155; color:#4ade80;'>✅ Draft Monitoring Aktif</div>"
147
+
148
+ # ========================================================
149
+ # INTERFACE DESIGN
150
+ # ========================================================
151
+ custom_css = """
152
+ body { background-color: #020617; }
153
+ .gradio-container { background-color: #020617 !important; color: white !important; }
154
+ .blue-side { border: 2px solid #3b82f6; padding: 15px; border-radius: 12px; background: rgba(59, 130, 246, 0.03); }
155
+ .red-side { border: 2px solid #ef4444; padding: 15px; border-radius: 12px; background: rgba(239, 68, 68, 0.03); }
156
+ .ban-panel { border: 1px dashed #475569; padding: 12px; border-radius: 10px; background: rgba(15, 23, 42, 0.6); margin-bottom: 15px; }
157
+ """
158
+
159
+ with gr.Blocks() as demo:
160
+ gr.HTML("""
161
+ <div style='text-align: center; padding: 10px 0;'>
162
+ <h1 style='color: #3b82f6; font-size: 28px; margin:0;'>🏆 MLBB COMPLETE TOURNAMENT ANALYZER</h1>
163
+ <p style='color: #64748b; margin: 5px 0;'>Sistem Analisis Strategi Draf MPL 10-Ban Rule • Patch v2026</p>
164
+ </div>
165
+ """)
166
+
167
+ # BAN SECTIONS
168
+ with gr.Group(elem_classes="ban-panel"):
169
+ gr.HTML("<b style='color: #94a3b8; display:block; text-align:center; margin-bottom:5px;'>🚫 TOURNAMENT BAN POOL</b>")
170
+ with gr.Row():
171
+ b_ban1 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="B-Ban 1")
172
+ b_ban2 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="B-Ban 2")
173
+ b_ban3 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="B-Ban 3")
174
+ b_ban4 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="B-Ban 4")
175
+ b_ban5 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="B-Ban 5")
176
+ with gr.Row():
177
+ r_ban1 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="R-Ban 1")
178
+ r_ban2 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="R-Ban 2")
179
+ r_ban3 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="R-Ban 3")
180
+ r_ban4 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="R-Ban 4")
181
+ r_ban5 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="R-Ban 5")
182
+
183
+ with gr.Row():
184
+ # BLUE TEAM PICKS
185
+ with gr.Column(elem_classes="blue-side", scale=1):
186
+ gr.HTML("<h3 style='color: #60a5fa; margin-top:0; text-align:center;'>🔵 BLUE TEAM PICKS</h3>")
187
+ rank_pick = gr.Dropdown(["Pro-Tournament", "Ranked Match"], value="Pro-Tournament", label="Format")
188
+
189
+ b1 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Pick 1")
190
+ img_b1 = gr.HTML(update_hero_html(None))
191
+ b2 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Pick 2")
192
+ img_b2 = gr.HTML(update_hero_html(None))
193
+ b3 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Pick 3")
194
+ img_b3 = gr.HTML(update_hero_html(None))
195
+ b4 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Pick 4")
196
+ img_b4 = gr.HTML(update_hero_html(None))
197
+ b5 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Pick 5")
198
+ img_b5 = gr.HTML(update_hero_html(None))
199
+
200
+ # CENTER OPERATIONS PANEL
201
+ with gr.Column(scale=1):
202
+ btn_analyze = gr.Button("⚔️ EVALUASI STRATEGI TURNAMEN", variant="primary", size="lg")
203
+ gr.HTML("<h3 style='color: #fbbf24; margin-top:15px;'>🔮 METALOGI & COMBO TIM</h3>")
204
+ meta_out = gr.HTML("<p style='color: #64748b;'>Menunggu draf...</p>")
205
+ gr.HTML("<h3 style='color: #4ade80; margin-top:15px;'>📊 STATUS ENGINE</h3>")
206
+ comp_out = gr.HTML("<p style='color: #64748b;'>Ready.</p>")
207
+
208
+ # RED TEAM PICKS
209
+ with gr.Column(elem_classes="red-side", scale=1):
210
+ gr.HTML("<h3 style='color: #f87171; margin-top:0; text-align:center;'>🔴 RED TEAM PICKS</h3>")
211
+
212
+ r1 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Enemy 1")
213
+ img_r1 = gr.HTML(update_hero_html(None))
214
+ r2 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Enemy 2")
215
+ img_r2 = gr.HTML(update_hero_html(None))
216
+ r3 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Enemy 3")
217
+ img_r3 = gr.HTML(update_hero_html(None))
218
+ r4 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Enemy 4")
219
+ img_r4 = gr.HTML(update_hero_html(None))
220
+ r5 = gr.Dropdown([None] + ALL_MLBB_HEROES, label="Enemy 5")
221
+ img_r5 = gr.HTML(update_hero_html(None))
222
+
223
+ gr.HTML("<h2 style='color: #ef4444; border-bottom: 2px solid #ef4444; padding-bottom: 5px; margin-top:20px;'>🕵️ DEEP COUNTER-PICK STRATEGY REPORT</h2>")
224
+ counter_out = gr.HTML("<p style='color: #64748b;'>Kalkulasi taktis...</p>")
225
+
226
+ # BINDING IMAGE CHANGES VIA HTML INJECTION
227
+ b1.change(fn=update_hero_html, inputs=b1, outputs=img_b1)
228
+ b2.change(fn=update_hero_html, inputs=b2, outputs=img_b2)
229
+ b3.change(fn=update_hero_html, inputs=b3, outputs=img_b3)
230
+ b4.change(fn=update_hero_html, inputs=b4, outputs=img_b4)
231
+ b5.change(fn=update_hero_html, inputs=b5, outputs=img_b5)
232
+
233
+ r1.change(fn=update_hero_html, inputs=r1, outputs=img_r1)
234
+ r2.change(fn=update_hero_html, inputs=r2, outputs=img_r2)
235
+ r3.change(fn=update_hero_html, inputs=r3, outputs=img_r3)
236
+ r4.change(fn=update_hero_html, inputs=r4, outputs=img_r4)
237
+ r5.change(fn=update_hero_html, inputs=r5, outputs=img_r5)
238
+
239
+ # ACTION BUTTON BINDING
240
+ btn_analyze.click(
241
+ fn=analyze_tournament_draft,
242
+ inputs=[rank_pick, b1, b2, b3, b4, b5, r1, r2, r3, r4, r5, b_ban1, b_ban2, b_ban3, b_ban4, b_ban5, r_ban1, r_ban2, r_ban3, r_ban4, r_ban5],
243
+ outputs=[counter_out, meta_out, comp_out]
244
+ )
245
+
246
+ if __name__ == "__main__":
247
+ demo.launch(show_error=True)