Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
import gradio as gr
|
2 |
import pandas as pd
|
3 |
-
from xgboost import Booster, DMatrix
|
4 |
import numpy as np
|
|
|
5 |
|
6 |
-
#
|
7 |
card_numbers = {
|
8 |
"Archers": 1, "Archer Queen": 2, "Baby Dragon": 3, "Balloon": 4, "Bandit": 5, "Barbarians": 6,
|
9 |
"Bats": 7, "Battle Healer": 8, "Battle Ram": 9, "Bomber": 10, "Bowler": 11, "Bush Goblins": 12,
|
@@ -23,29 +23,36 @@ card_numbers = {
|
|
23 |
"Royal Giant": 78, "Royal Hogs": 79, "Royal Recruits": 80, "Skeleton Army": 81,
|
24 |
"Skeleton Barrel": 82, "Skeleton Dragons": 83, "Skeleton King": 84, "Skeletons": 85, "Sparky": 86,
|
25 |
"Spear Goblins": 87, "Suspicious Bush": 88, "Three Musketeers": 89, "Valkyrie": 90,
|
26 |
-
"Wall Breakers": 91, "Witch": 92, "Wizard": 93, "Zappies": 94,"Bomb Tower": 95, "Cannon": 96,
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
"Skeletons/Evolution": 176, "Tesla/Evolution": 177, "Valkyrie/Evolution": 178,
|
44 |
-
"Wall Breakers/Evolution": 179, "Wizard/Evolution": 180, "Zap/Evolution": 181
|
45 |
|
|
|
|
|
|
|
46 |
}
|
47 |
|
48 |
-
MODEL_PATH = "model.json"
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
def deck_to_ids(deck, mapping):
|
51 |
"""Convert card names to IDs based on the mapping."""
|
@@ -53,68 +60,43 @@ def deck_to_ids(deck, mapping):
|
|
53 |
|
54 |
def preprocess_deck(deck):
|
55 |
"""Prepare the selected deck for the model."""
|
56 |
-
# Convert cards to IDs
|
57 |
deck_ids = deck_to_ids(deck, card_numbers)
|
58 |
-
|
59 |
-
# Perform one-hot encoding
|
60 |
-
num_choices = 181 # Total number of cards
|
61 |
one_hot = np.zeros(num_choices, dtype=int)
|
62 |
-
one_hot[np.array(deck_ids)] = 1
|
63 |
-
|
64 |
-
# Add additional features (placeholder for now)
|
65 |
-
trophy_difference = 0 # Placeholder for trophy difference
|
66 |
-
elixir_leaked = 0 # Placeholder for leaked elixir
|
67 |
-
|
68 |
-
# Combine features
|
69 |
-
features = np.concatenate(([trophy_difference, elixir_leaked], one_hot))
|
70 |
return pd.DataFrame([features])
|
71 |
|
72 |
-
def load_model(model_path):
|
73 |
-
"""Load the saved XGBoost model."""
|
74 |
-
model = Booster()
|
75 |
-
model.load_model(model_path)
|
76 |
-
return model
|
77 |
-
|
78 |
-
# Load the model at startup
|
79 |
-
model = load_model(MODEL_PATH)
|
80 |
-
|
81 |
def predict_outcome(opponent_deck):
|
82 |
"""Make a prediction based on the opponent's deck."""
|
83 |
-
# Prepare the opponent deck data
|
84 |
deck_data = preprocess_deck(opponent_deck)
|
85 |
-
|
86 |
-
# Make the prediction
|
87 |
-
dmatrix = DMatrix(deck_data) # Convert data to DMatrix format
|
88 |
prediction = model.predict(dmatrix)
|
|
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
return result
|
93 |
-
|
94 |
-
# List of cards for selection
|
95 |
-
card_list = list(card_numbers.keys())
|
96 |
|
97 |
-
# Create
|
98 |
with gr.Blocks() as interface:
|
99 |
gr.Markdown("## Clash Royale Prediction")
|
100 |
-
gr.Markdown("Select
|
101 |
|
102 |
opponent_deck = gr.CheckboxGroup(
|
103 |
-
choices=
|
104 |
-
label="
|
105 |
-
info="Select exactly 8 cards."
|
|
|
106 |
)
|
107 |
|
108 |
result = gr.Textbox(label="Prediction Result:", interactive=False)
|
109 |
|
110 |
def validate_and_predict(deck):
|
111 |
-
"""Validate the number of selected cards and make a prediction."""
|
112 |
if len(deck) != 8:
|
113 |
return "Error: Select exactly 8 cards."
|
114 |
return predict_outcome(deck)
|
115 |
-
|
116 |
predict_button = gr.Button("Make Prediction")
|
117 |
predict_button.click(validate_and_predict, inputs=[opponent_deck], outputs=[result])
|
118 |
|
119 |
-
# Launch the interface
|
120 |
interface.launch()
|
|
|
1 |
import gradio as gr
|
2 |
import pandas as pd
|
|
|
3 |
import numpy as np
|
4 |
+
from xgboost import Booster, DMatrix
|
5 |
|
6 |
+
# Generating the complete `card_images` dictionary
|
7 |
card_numbers = {
|
8 |
"Archers": 1, "Archer Queen": 2, "Baby Dragon": 3, "Balloon": 4, "Bandit": 5, "Barbarians": 6,
|
9 |
"Bats": 7, "Battle Healer": 8, "Battle Ram": 9, "Bomber": 10, "Bowler": 11, "Bush Goblins": 12,
|
|
|
23 |
"Royal Giant": 78, "Royal Hogs": 79, "Royal Recruits": 80, "Skeleton Army": 81,
|
24 |
"Skeleton Barrel": 82, "Skeleton Dragons": 83, "Skeleton King": 84, "Skeletons": 85, "Sparky": 86,
|
25 |
"Spear Goblins": 87, "Suspicious Bush": 88, "Three Musketeers": 89, "Valkyrie": 90,
|
26 |
+
"Wall Breakers": 91, "Witch": 92, "Wizard": 93, "Zappies": 94, "Bomb Tower": 95, "Cannon": 96,
|
27 |
+
"Cannon Cart (broken)": 97, "Inferno Tower": 98, "Mortar": 99, "Tesla": 100, "X-Bow": 101,
|
28 |
+
"Barbarian Hut": 102, "Elixir Collector": 103, "Furnace": 104, "Goblin Cage": 105,
|
29 |
+
"Goblin Drill": 106, "Goblin Hut": 107, "Phoenix Egg": 108, "Tombstone": 109, "Arrows": 110,
|
30 |
+
"Barbarian Barrel": 111, "Earthquake": 112, "Fireball": 113, "Freeze": 114, "Giant Snowball": 115,
|
31 |
+
"Goblin Curse": 116, "Lightning": 117, "Poison": 118, "Rage": 119, "Rocket": 120,
|
32 |
+
"Royal Delivery": 121, "The Log": 122, "Tornado": 123, "Void": 124, "Zap": 125,
|
33 |
+
"Archers/Evolution": 155, "Barbarians/Evolution": 156, "Battle Ram/Evolution": 157,
|
34 |
+
"Bats/Evolution": 158, "Bomber/Evolution": 159, "Cannon/Evolution": 160,
|
35 |
+
"Electro Dragon/Evolution": 161, "Firecracker/Evolution": 162, "Giant Snowball/Evolution": 163,
|
36 |
+
"Goblin Barrel/Evolution": 164, "Goblin Cage/Evolution": 165, "Goblin Drill/Evolution": 166,
|
37 |
+
"Goblin Giant/Evolution": 167, "Ice Spirit/Evolution": 168, "Knight/Evolution": 169,
|
38 |
+
"Mega Knight/Evolution": 170, "Mortar/Evolution": 171, "Musketeer/Evolution": 172,
|
39 |
+
"P.E.K.K.A/Evolution": 173, "Royal Giant/Evolution": 174, "Royal Recruits/Evolution": 175,
|
40 |
+
"Skeletons/Evolution": 176, "Tesla/Evolution": 177, "Valkyrie/Evolution": 178,
|
41 |
+
"Wall Breakers/Evolution": 179, "Wizard/Evolution": 180, "Zap/Evolution": 181
|
42 |
+
}
|
|
|
|
|
43 |
|
44 |
+
card_images = {
|
45 |
+
card_name: f"https://clashroyale.fandom.com/wiki/Arenas?file={card_name.replace(' ', '').replace('/', '')}Card.png"
|
46 |
+
for card_name in card_numbers.keys()
|
47 |
}
|
48 |
|
49 |
+
MODEL_PATH = "model.json"
|
50 |
+
|
51 |
+
def load_model(model_path):
|
52 |
+
"""Load the saved XGBoost model."""
|
53 |
+
model = Booster()
|
54 |
+
model.load_model(model_path)
|
55 |
+
return model
|
56 |
|
57 |
def deck_to_ids(deck, mapping):
|
58 |
"""Convert card names to IDs based on the mapping."""
|
|
|
60 |
|
61 |
def preprocess_deck(deck):
|
62 |
"""Prepare the selected deck for the model."""
|
|
|
63 |
deck_ids = deck_to_ids(deck, card_numbers)
|
64 |
+
num_choices = len(card_numbers)
|
|
|
|
|
65 |
one_hot = np.zeros(num_choices, dtype=int)
|
66 |
+
one_hot[np.array(deck_ids)] = 1
|
67 |
+
features = np.concatenate(([0, 0], one_hot))
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
return pd.DataFrame([features])
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
def predict_outcome(opponent_deck):
|
71 |
"""Make a prediction based on the opponent's deck."""
|
|
|
72 |
deck_data = preprocess_deck(opponent_deck)
|
73 |
+
dmatrix = DMatrix(deck_data)
|
|
|
|
|
74 |
prediction = model.predict(dmatrix)
|
75 |
+
return f"Probability of Winning: {prediction[0] * 100:.2f}%"
|
76 |
|
77 |
+
# Load the model
|
78 |
+
model = load_model(MODEL_PATH)
|
|
|
|
|
|
|
|
|
79 |
|
80 |
+
# Create Gradio Interface
|
81 |
with gr.Blocks() as interface:
|
82 |
gr.Markdown("## Clash Royale Prediction")
|
83 |
+
gr.Markdown("Select 8 cards from the opponent's deck to predict the probability of winning!")
|
84 |
|
85 |
opponent_deck = gr.CheckboxGroup(
|
86 |
+
choices=list(card_images.keys()),
|
87 |
+
label="Opponent's Deck",
|
88 |
+
info="Select exactly 8 cards.",
|
89 |
+
item_text=lambda name: f'<img src="{card_images[name]}" alt="{name}" width="50" height="50" /> {name}'
|
90 |
)
|
91 |
|
92 |
result = gr.Textbox(label="Prediction Result:", interactive=False)
|
93 |
|
94 |
def validate_and_predict(deck):
|
|
|
95 |
if len(deck) != 8:
|
96 |
return "Error: Select exactly 8 cards."
|
97 |
return predict_outcome(deck)
|
98 |
+
|
99 |
predict_button = gr.Button("Make Prediction")
|
100 |
predict_button.click(validate_and_predict, inputs=[opponent_deck], outputs=[result])
|
101 |
|
|
|
102 |
interface.launch()
|