Spaces:
Sleeping
Sleeping
File size: 6,545 Bytes
7418c14 075b4b2 abb2690 dc0fd01 73bfbed a3768e0 73bfbed 7418c14 075b4b2 10d6aa1 2c80a62 bc61848 2c80a62 10d6aa1 2c80a62 bc61848 10d6aa1 2c80a62 10d6aa1 2c80a62 bc61848 10d6aa1 7418c14 075b4b2 94172b1 10d6aa1 cab2759 2c80a62 10d6aa1 6afba73 bc61848 2c80a62 bc61848 2c80a62 c216029 10d6aa1 2c80a62 10d6aa1 2c80a62 10d6aa1 c216029 2c80a62 cab2759 2c80a62 abb2690 10d6aa1 2c80a62 10d6aa1 210d467 cab2759 f941683 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
import gradio as gr
import pandas as pd
import numpy as np
from xgboost import Booster, DMatrix
import requests
# Generate card_numbers
card_numbers = {
"Archers": 1, "Archer Queen": 2, "Baby Dragon": 3, "Balloon": 4, "Bandit": 5, "Barbarians": 6,
"Bats": 7, "Battle Healer": 8, "Battle Ram": 9, "Bomber": 10, "Bowler": 11, "Bush Goblins": 12,
"Cannon Cart": 13, "Cursed Hog": 14, "Dark Prince": 15, "Dart Goblin": 16, "Electro Dragon": 17,
"Electro Giant": 18, "Electro Spirit": 19, "Electro Wizard": 20, "Elite Barbarians": 21,
"Elixir Blob": 22, "Elixir Golem": 23, "Elixir Golemite": 24, "Executioner": 25, "Firecracker": 26,
"Fire Spirit": 27, "Fisherman": 28, "Flying Machine": 29, "Giant": 30, "Giant Skeleton": 31,
"Goblin Brawler": 32, "Goblin Gang": 33, "Goblin Demolisher": 34, "Goblin Giant": 35,
"Goblin Machine": 36, "Goblins": 37, "Goblinstein": 38, "Golden Knight": 39, "Golem": 40,
"Golemite": 41, "Guardienne": 42, "Guards": 43, "Hog Rider": 44, "Hunter": 45, "Heal Spirit": 46,
"Ice Golem": 47, "Ice Spirit": 48, "Ice Wizard": 49, "Inferno Dragon": 50, "Knight": 51,
"Lava Hound": 52, "Lava Pup": 53, "Little Prince": 54, "Lumberjack": 55, "Magic Archer": 56,
"Mega Knight": 57, "Mega Minion": 58, "Mighty Miner": 59, "Miner": 60, "Mini P.E.K.K.A.": 61,
"Minion Horde": 62, "Minions": 63, "Monk": 64, "Mother Witch": 65, "Monster": 66, "Musketeer": 67,
"Night Witch": 68, "P.E.K.K.A.": 69, "Phoenix": 70, "Reborn Phoenix": 71, "Prince": 72,
"Princess": 73, "Ram Rider": 74, "Rascal Boy": 75, "Rascal Girl": 76, "Royal Ghost": 77,
"Royal Giant": 78, "Royal Hogs": 79, "Royal Recruits": 80, "Skeleton Army": 81,
"Skeleton Barrel": 82, "Skeleton Dragons": 83, "Skeleton King": 84, "Skeletons": 85, "Sparky": 86,
"Spear Goblins": 87, "Suspicious Bush": 88, "Three Musketeers": 89, "Valkyrie": 90,
"Wall Breakers": 91, "Witch": 92, "Wizard": 93, "Zappies": 94, "Bomb Tower": 95, "Cannon": 96,
"Inferno Tower": 98, "Mortar": 99, "Tesla": 100, "X-Bow": 101, "Barbarian Hut": 102,
"Elixir Collector": 103, "Furnace": 104, "Goblin Cage": 105, "Goblin Drill": 106,
"Goblin Hut": 107, "Phoenix Egg": 108, "Tombstone": 109, "Arrows": 110, "Barbarian Barrel": 111,
"Earthquake": 112, "Fireball": 113, "Freeze": 114, "Giant Snowball": 115, "Lightning": 117,
"Poison": 118, "Rage": 119, "Rocket": 120, "Royal Delivery": 121, "The Log": 122, "Tornado": 123,
"Zap": 125, "Goblin Barrel": 132, "Graveyard": 139
}
# Generate card_images with normalized filenames
base_url = "https://raw.githubusercontent.com/RoyaleAPI/cr-api-assets/master/cards/"
card_images = {
card_name: f"{base_url}{card_name.lower().replace(' ', '-').replace('/', '-').replace('.', '')}.png"
for card_name in card_numbers.keys()
}
# Validate URLs
valid_card_images = {}
for card, url in card_images.items():
response = requests.head(url)
if response.status_code == 200:
valid_card_images[card] = url
# Define model-related functions
MODEL_PATH = "model.json"
def load_model(model_path):
"""Load the saved XGBoost model."""
model = Booster()
model.load_model(model_path)
return model
def deck_to_ids(deck, mapping):
"""Convert card names to IDs based on the mapping."""
return [mapping.get(card, 0) - 1 for card in deck]
def preprocess_deck(deck):
"""Prepare the selected deck for the model."""
deck_ids = deck_to_ids(deck, card_numbers)
num_choices = len(card_numbers)
one_hot = np.zeros(num_choices, dtype=int)
one_hot[np.array(deck_ids)] = 1
features = np.concatenate(([0, 0], one_hot))
return pd.DataFrame([features])
def predict_outcome(opponent_deck):
"""Make a prediction based on the opponent's deck."""
deck_data = preprocess_deck(opponent_deck)
dmatrix = DMatrix(deck_data)
prediction = model.predict(dmatrix)
return f"Probability of Winning: {prediction[0] * 100:.2f}%"
# Load the model
model = load_model(MODEL_PATH)
# Create Gradio Interface
with gr.Blocks(css="""
.card-container img {
width: 80px !important;
height: 80px !important;
object-fit: contain;
margin: 5px auto;
}
.card-container {
text-align: center;
padding: 5px;
border: 1px solid #ddd;
border-radius: 8px;
margin: 5px;
}
.checkbox-container {
margin-top: 5px;
}
""") as interface:
gr.Markdown("## Clash Royale Prediction")
gr.Markdown("Select 8 cards from the opponent's deck to predict the probability of winning!")
# State for tracking selected cards
selected_cards_display = gr.Markdown("Selected cards: 0/8")
def update_selection(*checkbox_values):
selected_count = sum(checkbox_values)
return f"Selected cards: {selected_count}/8"
# Create card grid using rows and columns
cards_per_row = 8
cards_list = list(valid_card_images.items())
all_checkboxes = []
for i in range(0, len(cards_list), cards_per_row):
with gr.Row():
for card, url in cards_list[i:i + cards_per_row]:
with gr.Column(elem_classes="card-container"):
gr.Image(value=url, show_label=False)
checkbox = gr.Checkbox(label=card, elem_classes="checkbox-container")
all_checkboxes.append(checkbox)
with gr.Row():
result = gr.Textbox(label="Prediction Result:", interactive=False)
clear_btn = gr.Button("Clear Selection")
predict_btn = gr.Button("Make Prediction", variant="primary")
def clear_selection():
return [False] * len(all_checkboxes) + ["Selected cards: 0/8", ""]
clear_btn.click(
clear_selection,
outputs=all_checkboxes + [selected_cards_display, result]
)
def validate_and_predict(*checkbox_values):
selected_cards = [
card for card, checked in zip(valid_card_images.keys(), checkbox_values)
if checked
]
if len(selected_cards) != 8:
return f"Error: Please select exactly 8 cards. You selected {len(selected_cards)}."
return predict_outcome(selected_cards)
predict_btn.click(
validate_and_predict,
inputs=all_checkboxes,
outputs=result
)
# Update the card count display
for checkbox in all_checkboxes:
checkbox.change(
update_selection,
inputs=all_checkboxes,
outputs=selected_cards_display
)
interface.launch() |