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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -233
app.py CHANGED
@@ -1,252 +1,48 @@
1
  import gradio as gr
2
 
3
  # ========================================================
4
- # DATABASE HERO META & SKEMA COMBO TOURNAMENT
5
  # ========================================================
6
- HERO_DATA = {
7
  "Ling": {
8
- "role": "Jungler", "tier": "S+", "type": "Dash/Burst", "meta": "Dive",
9
- "img": "https://m.mobilelegends.com/static/images/heroid/84.jpg",
10
- "counters": {"Minsitthar": "Grounded mematikan gerak Ling.", "Khufra": "Bouncing Ball menghentikan dash.", "Saber": "Targeting instan di tembok."}
11
  },
12
  "Fanny": {
13
- "role": "Jungler", "tier": "S+", "type": "High Mobility", "meta": "Dive",
14
- "img": "https://m.mobilelegends.com/static/images/heroid/17.jpg",
15
- "counters": {"Khufra": "Menghentikan kabel Fanny.", "Eudora": "Stun instan & burst.", "Kaja": "Suppress mutlak."}
 
 
 
 
 
 
 
16
  },
17
  "Hylos": {
18
- "role": "Tank", "tier": "S", "type": "High HP/Regen", "meta": "Ube/Regen",
19
- "img": "https://m.mobilelegends.com/static/images/heroid/49.jpg",
20
- "counters": {"Karrie": "True damage %HP.", "Valir": "Slow & knockback menjauh.", "Lunox": "Penetrasi tinggi."}
21
  },
22
  "Zhuxin": {
23
- "role": "Mage", "tier": "S", "type": "CC/Zone", "meta": "Teamfight Control",
24
- "img": "https://m.mobilelegends.com/static/images/heroid/125.jpg",
25
- "counters": {"Helcurt": "Silence memutus channeling.", "Natalia": "Ciduk cepat.", "Harley": "Burst instan."}
26
- },
27
- "Harith": {
28
- "role": "Gold Lane", "tier": "S", "type": "Dash/Magic", "meta": "Poke/Sustained",
29
- "img": "https://m.mobilelegends.com/static/images/heroid/71.jpg",
30
- "counters": {"Minsitthar": "Grounded.", "Phoveus": "Counter dash.", "Baxia": "Anti-heal."}
31
  },
32
  "Tigreal": {
33
- "role": "Roamer", "tier": "S", "type": "CC/Initiator", "meta": "Wombo Combo",
34
- "img": "https://m.mobilelegends.com/static/images/heroid/6.jpg",
35
- "counters": {"Diggie": "Anti-CC masal.", "Akai": "Membatalkan ulti Tigreal.", "Valir": "Knockback."}
36
- },
37
- "Nolan": {
38
- "role": "Jungler", "tier": "S", "type": "Dash/Fast Clear", "meta": "Dive",
39
- "img": "https://m.mobilelegends.com/static/images/heroid/121.jpg",
40
- "counters": {"Khufra": "Counter dash.", "Minsitthar": "Grounded.", "Kaja": "Suppress."}
41
  },
42
  "Mathilda": {
43
- "role": "Roamer", "tier": "S", "type": "Support/Poke", "meta": "Ube/Regen",
44
- "img": "https://m.mobilelegends.com/static/images/heroid/100.jpg",
45
- "counters": {"Saber": "Lock saat terbang.", "Chou": "Tendang menjauh.", "Wanwan": "Trigger weakness."}
46
  },
47
- "Valentina": {
48
- "role": "Mid", "tier": "A", "type": "Copy/Burst", "meta": "Flex Pick",
49
- "img": "https://m.mobilelegends.com/static/images/heroid/111.jpg",
50
- "counters": {"Helcurt": "Silence.", "Gusion": "Burst cepat.", "Hayabusa": "Skill sulit ditiru."}
51
  },
52
  "Roger": {
53
- "role": "Jungler/Gold", "tier": "S", "type": "Physical/Burst", "meta": "Poke/Sustained",
54
- "img": "https://m.mobilelegends.com/static/images/heroid/40.jpg",
55
- "counters": {"Grock": "Immune CC.", "Vexana": "CC/Terror.", "Terizla": "Sustain lebih kuat."}
56
- },
57
- "Angela": {
58
- "role": "Roamer", "tier": "S", "type": "Healer/Buff", "meta": "Ube/Regen",
59
- "img": "https://m.mobilelegends.com/static/images/heroid/58.jpg",
60
- "counters": {"Baxia": "Anti-regen.", "Helcurt": "Silence target."}
61
  },
62
- "Vexana": {
63
- "role": "Mid", "tier": "S", "type": "Burst/CC", "meta": "Wombo Combo",
64
- "img": "https://m.mobilelegends.com/static/images/heroid/38.jpg",
65
- "counters": {"Kagura": "Bisa lepas CC.", "Lancelot": "Immune burst."}
66
- }
67
- }
68
-
69
- ALL_HEROES = sorted(list(HERO_DATA.keys()))
70
- BLANK_IMG = "https://via.placeholder.com/65x65/0f172a/64748b?text=%3F"
71
-
72
- # Render HTML murni bypass firewall Hugging Face
73
- def update_hero_html(hero_name):
74
- if hero_name in HERO_DATA:
75
- url = HERO_DATA[hero_name]["img"]
76
- 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>'
77
- 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>'
78
-
79
- 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):
80
- blue_team = [h for h in [b1, b2, b3, b4, b5] if h]
81
- red_team = [h for h in [r1, r2, r3, r4, r5] if h]
82
- all_bans = [h for h in [ban1, ban2, ban3, ban4, ban5, ban6, ban7, ban8, ban9, ban10] if h]
83
-
84
- # 1. ANALISIS COUNTER HERO MUSUH
85
- counter_html = "<div style='background-color: #0f172a; padding: 15px; border-radius: 10px; border: 1px solid #334155;'>"
86
- if not red_team:
87
- counter_html += "<p style='color: #94a3b8; margin:0;'>Menunggu pick musuh...</p>"
88
- else:
89
- for hero in red_team:
90
- if hero in HERO_DATA:
91
- data = HERO_DATA[hero]
92
- counter_html += f"""
93
- <div style='margin-bottom: 12px; border-left: 4px solid #ef4444; padding-left: 12px;'>
94
- <b style='color: #f87171;'>⚠️ ANCAMAN TOURNAMENT: {hero}</b> <span style='font-size:11px; color:#cbd5e1; background:#991b1b; padding:2px 6px; border-radius:4px;'>{data['type']}</span>
95
- <ul style='color: #94a3b8; font-size: 13px; margin: 4px 0 0 15px; padding:0;'>
96
- """
97
- for c_hero, reason in data["counters"].items():
98
- if c_hero not in blue_team and c_hero not in red_team and c_hero not in all_bans:
99
- counter_html += f"<li><span style='color: #60a5fa; font-weight:bold;'>{c_hero}</span>: {reason}</li>"
100
- counter_html += "</ul></div>"
101
- counter_html += "</div>"
102
-
103
- # 2. METALOGI & REKOMENDASI COMBO TIM
104
- meta_counts = {}
105
- for h in blue_team:
106
- if h in HERO_DATA:
107
- m_type = HERO_DATA[h]["meta"]
108
- meta_counts[m_type] = meta_counts.get(m_type, 0) + 1
109
-
110
- meta_html = "<div style='background-color: #0f172a; padding: 15px; border-radius: 10px; border: 1px solid #334155;'>"
111
- if not blue_team:
112
- meta_html += "<p style='color: #94a3b8; margin:0;'>Rancang draf timmu untuk melihat arah sinergi META...</p>"
113
- else:
114
- dominant_meta = max(meta_counts, key=meta_counts.get) if meta_counts else "General Meta"
115
- if dominant_meta == "Wombo Combo":
116
- 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;'>Cocok disinergikan dengan hero area eksekusi tinggi seperti <i>Claude</i> atau <i>Terizla</i>.</p>"
117
- elif dominant_meta == "Ube/Regen":
118
- 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;'>Disarankan mengamankan Jungler tebal (Tank/Fighter) seperti <i>Hylos</i> atau <i>Baxia</i>.</p>"
119
- elif dominant_meta == "Dive":
120
- 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;'>Pastikan Midlaner mengamankan tipe mage burst jarak jauh atau backup cepat seperti <i>Mathilda</i>.</p>"
121
- else:
122
- meta_html += f"<b style='color: #cbd5e1; font-size:14px;'>🛡️ STRATEGI BERIMBANG ({dominant_meta})</b>"
123
- meta_html += "</div>"
124
-
125
- # 3. KELENGKAPAN LINI LANE
126
- roles = [HERO_DATA[h]["role"] for h in blue_team if h in HERO_DATA]
127
- all_roles = ["Jungler", "Roamer", "Midlaner", "EXP Laner", "Gold Laner"]
128
- missing = [r for r in all_roles if r not in roles]
129
-
130
- comp_html = "<div style='background-color: #0f172a; padding: 15px; border-radius: 10px; border: 1px solid #334155;'>"
131
- if missing:
132
- comp_html += f"<p style='color: #fb7185; margin:0;'>⚠️ <b>Role Kurang:</b> {', '.join(missing)}</p>"
133
- else:
134
- comp_html += "<p style='color: #4ade80; margin:0;'>✅ <b>Lini Formasi Lengkap!</b> Semua lane terisi.</p>"
135
- comp_html += "</div>"
136
-
137
- return counter_html, meta_html, comp_html
138
-
139
- # ========================================================
140
- # INTERFACE DESIGN
141
- # ========================================================
142
- custom_css = """
143
- body { background-color: #020617; }
144
- .gradio-container { background-color: #020617 !important; color: white !important; }
145
- .blue-side { border: 2px solid #3b82f6; padding: 15px; border-radius: 12px; background: rgba(59, 130, 246, 0.03); }
146
- .red-side { border: 2px solid #ef4444; padding: 15px; border-radius: 12px; background: rgba(239, 68, 68, 0.03); }
147
- .ban-panel { border: 1px dashed #475569; padding: 12px; border-radius: 10px; background: rgba(15, 23, 42, 0.6); margin-bottom: 15px; }
148
- """
149
-
150
- with gr.Blocks() as demo:
151
- gr.HTML("""
152
- <div style='text-align: center; padding: 10px 0;'>
153
- <h1 style='color: #3b82f6; font-size: 28px; margin:0;'>🏆 MLBB VISUAL TOURNAMENT ANALYZER</h1>
154
- <p style='color: #64748b; margin: 5px 0;'>Sistem Analisis Strategi Draf MPL 10-Ban Rule • Patch v2026</p>
155
- </div>
156
- """)
157
-
158
- # BAN SECTIONS
159
- with gr.Group(elem_classes="ban-panel"):
160
- gr.HTML("<b style='color: #94a3b8; display:block; text-align:center; margin-bottom:5px;'>🚫 TOURNAMENT BAN POOL</b>")
161
- with gr.Row():
162
- b_ban1 = gr.Dropdown([None] + ALL_HEROES, label="B-Ban 1")
163
- b_ban2 = gr.Dropdown([None] + ALL_HEROES, label="B-Ban 2")
164
- b_ban3 = gr.Dropdown([None] + ALL_HEROES, label="B-Ban 3")
165
- b_ban4 = gr.Dropdown([None] + ALL_HEROES, label="B-Ban 4")
166
- b_ban5 = gr.Dropdown([None] + ALL_HEROES, label="B-Ban 5")
167
- with gr.Row():
168
- r_ban1 = gr.Dropdown([None] + ALL_HEROES, label="R-Ban 1")
169
- r_ban2 = gr.Dropdown([None] + ALL_HEROES, label="R-Ban 2")
170
- r_ban3 = gr.Dropdown([None] + ALL_HEROES, label="R-Ban 3")
171
- r_ban4 = gr.Dropdown([None] + ALL_HEROES, label="R-Ban 4")
172
- r_ban5 = gr.Dropdown([None] + ALL_HEROES, label="R-Ban 5")
173
-
174
- with gr.Row():
175
- # BLUE TEAM PICKS
176
- with gr.Column(elem_classes="blue-side", scale=1):
177
- gr.HTML("<h3 style='color: #60a5fa; margin-top:0; text-align:center;'>🔵 BLUE TEAM PICKS</h3>")
178
- rank_pick = gr.Dropdown(["Pro-Tournament", "Ranked Match"], value="Pro-Tournament", label="Format")
179
-
180
- b1 = gr.Dropdown([None] + ALL_HEROES, label="Pick 1")
181
- img_b1 = gr.HTML(update_hero_html(None))
182
-
183
- b2 = gr.Dropdown([None] + ALL_HEROES, label="Pick 2")
184
- img_b2 = gr.HTML(update_hero_html(None))
185
-
186
- b3 = gr.Dropdown([None] + ALL_HEROES, label="Pick 3")
187
- img_b3 = gr.HTML(update_hero_html(None))
188
-
189
- b4 = gr.Dropdown([None] + ALL_HEROES, label="Pick 4")
190
- img_b4 = gr.HTML(update_hero_html(None))
191
-
192
- b5 = gr.Dropdown([None] + ALL_HEROES, label="Pick 5")
193
- img_b5 = gr.HTML(update_hero_html(None))
194
-
195
- # CENTER OPERATIONS PANEL
196
- with gr.Column(scale=1):
197
- btn_analyze = gr.Button("⚔️ EVALUASI STRATEGI TURNAMEN", variant="primary", size="lg")
198
-
199
- gr.HTML("<h3 style='color: #fbbf24; margin-top:15px;'>🔮 METALOGI & COMBO TIM</h3>")
200
- meta_out = gr.HTML("<p style='color: #64748b;'>Menunggu draf...</p>")
201
-
202
- gr.HTML("<h3 style='color: #4ade80; margin-top:15px;'>📊 CHECKPOINT LANE BALANCE</h3>")
203
- comp_out = gr.HTML("<p style='color: #64748b;'>Memonitor lane...</p>")
204
-
205
- # RED TEAM PICKS
206
- with gr.Column(elem_classes="red-side", scale=1):
207
- gr.HTML("<h3 style='color: #f87171; margin-top:0; text-align:center;'>🔴 RED TEAM PICKS</h3>")
208
-
209
- r1 = gr.Dropdown([None] + ALL_HEROES, label="Enemy 1")
210
- img_r1 = gr.HTML(update_hero_html(None))
211
-
212
- r2 = gr.Dropdown([None] + ALL_HEROES, label="Enemy 2")
213
- img_r2 = gr.HTML(update_hero_html(None))
214
-
215
- r3 = gr.Dropdown([None] + ALL_HEROES, label="Enemy 3")
216
- img_r3 = gr.HTML(update_hero_html(None))
217
-
218
- r4 = gr.Dropdown([None] + ALL_HEROES, label="Enemy 4")
219
- img_r4 = gr.HTML(update_hero_html(None))
220
-
221
- r5 = gr.Dropdown([None] + ALL_HEROES, label="Enemy 5")
222
- img_r5 = gr.HTML(update_hero_html(None))
223
-
224
- gr.HTML("<h2 style='color: #ef4444; border-bottom: 2px solid #ef4444; padding-bottom: 5px; margin-top:20px;'>🕵️ DEEP COUNTER-PICK STRATEGY REPORT</h2>")
225
- counter_out = gr.HTML("<p style='color: #64748b;'>Kalkulasi taktis...</p>")
226
-
227
- # BINDING IMAGE CHANGES VIA HTML INJECTION (Bersih dari pemicu lama)
228
- b1.change(fn=update_hero_html, inputs=b1, outputs=img_b1)
229
- b2.change(fn=update_hero_html, inputs=b2, outputs=img_b2)
230
- b3.change(fn=update_hero_html, inputs=b3, outputs=img_b3)
231
- b4.change(fn=update_hero_html, inputs=b4, outputs=img_b4)
232
- b5.change(fn=update_hero_html, inputs=b5, outputs=img_b5)
233
-
234
- r1.change(fn=update_hero_html, inputs=r1, outputs=img_r1)
235
- r2.change(fn=update_hero_html, inputs=r2, outputs=img_r2)
236
- r3.change(fn=update_hero_html, inputs=r3, outputs=img_r3)
237
- r4.change(fn=update_hero_html, inputs=r4, outputs=img_r4)
238
- r5.change(fn=update_hero_html, inputs=r5, outputs=img_r5)
239
-
240
- # ACTION BUTTON BINDING
241
- btn_analyze.click(
242
- fn=analyze_tournament_draft,
243
- 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],
244
- outputs=[counter_out, meta_out, comp_out]
245
- )
246
-
247
- if __name__ == "__main__":
248
- demo.launch(
249
- css=custom_css,
250
- theme=gr.themes.Default(),
251
- show_error=True
252
- )
 
1
  import gradio as gr
2
 
3
  # ========================================================
4
+ # 1. DATABASE HERO META PRIORITAS (ANALYSIS CORE)
5
  # ========================================================
6
+ META_HEROES = {
7
  "Ling": {
8
+ "role": "Jungler", "type": "Dash/Burst", "meta": "Dive",
9
+ "counters": {"Minsitthar": "Grounded mematikan gerak Ling.", "Khufra": "Bouncing Ball menghentikan dash.", "Saber": "Targeting instan di tembok.", "Kaja": "Suppress mutlak."}
 
10
  },
11
  "Fanny": {
12
+ "role": "Jungler", "type": "High Mobility", "meta": "Dive",
13
+ "counters": {"Khufra": "Menghentikan kabel Fanny.", "Eudora": "Stun instan & burst.", "Kaja": "Suppress mutlak.", "Akai": "Heavy Spin menjepit di dinding."}
14
+ },
15
+ "Nolan": {
16
+ "role": "Jungler", "type": "Dash/Fast Clear", "meta": "Dive",
17
+ "counters": {"Khufra": "Counter dash.", "Minsitthar": "Grounded.", "Kaja": "Suppress.", "Martis": "Immune CC."}
18
+ },
19
+ "Hayabusa": {
20
+ "role": "Jungler", "type": "Burst/Blink", "meta": "Dive",
21
+ "counters": {"Khufra": "Bouncing ball menggagalkan bayangan.", "Saber": "Lock langsung sebelum ulti.", "Phoveus": "Trigger saat ganti bayangan."}
22
  },
23
  "Hylos": {
24
+ "role": "Tank", "type": "High HP/Regen", "meta": "Ube/Regen",
25
+ "counters": {"Karrie": "True damage %HP.", "Valir": "Slow & knockback menjauh.", "Lunox": "Penetrasi tinggi.", "Baxia": "Mengurangi regen HP."}
 
26
  },
27
  "Zhuxin": {
28
+ "role": "Midlaner", "type": "Cc/Zone", "meta": "Teamfight Control",
29
+ "counters": {"Helcurt": "Silence memutus channeling.", "Natalia": "Ciduk senyap.", "Harley": "Burst instan.", "Kadita": "Immune CC."}
 
 
 
 
 
 
30
  },
31
  "Tigreal": {
32
+ "role": "Roamer", "type": "Cc/Initiator", "meta": "Wombo Combo",
33
+ "counters": {"Diggie": "Anti-CC masal mematikan implosion.", "Akai": "Membatalkan ulti Tigreal.", "Valir": "Knockback dorongan jauh."}
 
 
 
 
 
 
34
  },
35
  "Mathilda": {
36
+ "role": "Roamer", "type": "Support/Poke", "meta": "Ube/Regen",
37
+ "counters": {"Saber": "Lock saat terbang.", "Chou": "Tendang menjauh.", "Minsitthar": "Grounded mematikan terbang bebas."}
 
38
  },
39
+ "Harith": {
40
+ "role": "Gold Laner", "type": "Dash/Magic", "meta": "Poke/Sustained",
41
+ "counters": {"Minsitthar": "Grounded mematikan total tariannya.", "Phoveus": "Trigger lompatan pasif.", "Khufra": "Bouncing ball penahan dash."}
 
42
  },
43
  "Roger": {
44
+ "role": "Gold Laner/Jungler", "type": "Physical/Burst", "meta": "Poke/Sustained",
45
+ "counters": {"Grock": "Immune CC.", "Vexana": "Teror bayangan lord.", "Terizla": "Adu gebuk menang sustain."}
 
 
 
 
 
 
46
  },
47
+ "Terizla": {
48
+ "role": "EXP Laner", "type": "Sustain/Initi