Spaces:
Runtime error
Runtime error
| import random | |
| import json | |
| from datetime import datetime | |
| from models import Box | |
| def initialize_game_state(user_id): | |
| """Initialize game state for a new user""" | |
| return { | |
| "user_id": user_id, | |
| "box": None, | |
| "coins": 0, | |
| "wins": 0, | |
| "losses": 0, | |
| "inventory": [], | |
| "created_at": datetime.now().isoformat(), | |
| "last_login": datetime.now().isoformat() | |
| } | |
| def create_box(name): | |
| """Create a new box with random stats""" | |
| box = Box(name=name) | |
| # Random base stats | |
| box.attack = random.randint(8, 15) | |
| box.defense = random.randint(6, 12) | |
| box.health = random.randint(40, 60) | |
| box.max_health = box.health | |
| box.speed = random.randint(3, 8) | |
| # Random ability | |
| abilities = [ | |
| {"name": "Power Strike", "damage_bonus": 5, "description": "Extra damage on attacks"}, | |
| {"name": "Iron Shield", "defense_bonus": 3, "description": "Better defense"}, | |
| {"name": "Quick Attack", "speed_bonus": 2, "description": "Faster attacks"}, | |
| {"name": "Regeneration", "heal_bonus": 2, "description": "Heals over time"}, | |
| {"name": "Critical Hit", "crit_chance": 0.2, "description": "Chance for double damage"} | |
| ] | |
| box.ability = random.choice(abilities) | |
| return box | |
| def calculate_battle_result(attacker, defender): | |
| """Calculate battle result between two boxes""" | |
| battle_log = [] | |
| rounds = 0 | |
| max_rounds = 20 | |
| attacker_health = attacker.health | |
| defender_health = defender.health | |
| # Determine who goes first | |
| attacker_first = attacker.speed >= defender.speed | |
| while attacker_health > 0 and defender_health > 0 and rounds < max_rounds: | |
| rounds += 1 | |
| battle_log.append(f"\n--- Round {rounds} ---") | |
| if attacker_first: | |
| # Attacker's turn | |
| damage = max(1, attacker.attack - defender.defense + random.randint(-2, 3)) | |
| # Apply ability bonus | |
| if "damage_bonus" in attacker.ability: | |
| damage += attacker.ability["damage_bonus"] | |
| battle_log.append(f"{attacker.name} uses {attacker.ability['name']}!") | |
| # Critical hit chance | |
| if "crit_chance" in attacker.ability and random.random() < attacker.ability["crit_chance"]: | |
| damage *= 2 | |
| battle_log.append(f"💥 CRITICAL HIT!") | |
| defender_health -= damage | |
| battle_log.append(f"{attacker.name} deals {damage} damage to {defender.name}") | |
| battle_log.append(f"{defender.name} health: {max(0, defender_health)}/{defender.max_health}") | |
| if defender_health <= 0: | |
| break | |
| # Defender's turn | |
| damage = max(1, defender.attack - attacker.defense + random.randint(-2, 3)) | |
| # Apply ability bonus | |
| if "damage_bonus" in defender.ability: | |
| damage += defender.ability["damage_bonus"] | |
| battle_log.append(f"{defender.name} uses {defender.ability['name']}!") | |
| # Critical hit chance | |
| if "crit_chance" in defender.ability and random.random() < defender.ability["crit_chance"]: | |
| damage *= 2 | |
| battle_log.append(f"💥 CRITICAL HIT!") | |
| attacker_health -= damage | |
| battle_log.append(f"{defender.name} deals {damage} damage to {attacker.name}") | |
| battle_log.append(f"{attacker.name} health: {max(0, attacker_health)}/{attacker.max_health}") | |
| else: | |
| # Defender goes first (same logic as above but reversed) | |
| damage = max(1, defender.attack - attacker.defense + random.randint(-2, 3)) | |
| if "damage_bonus" in defender.ability: | |
| damage += defender.ability["damage_bonus"] | |
| battle_log.append(f"{defender.name} uses {defender.ability['name']}!") | |
| if "crit_chance" in defender.ability and random.random() < defender.ability["crit_chance"]: | |
| damage *= 2 | |
| battle_log.append(f"💥 CRITICAL HIT!") | |
| attacker_health -= damage | |
| battle_log.append(f"{defender.name} deals {damage} damage to {attacker.name}") | |
| battle_log.append(f"{attacker.name} health: {max(0, attacker_health)}/{attacker.max_health}") | |
| if attacker_health <= 0: | |
| break | |
| damage = max(1, attacker.attack - defender.defense + random.randint(-2, 3)) | |
| if "damage_bonus" in attacker.ability: | |
| damage += attacker.ability["damage_bonus"] | |
| battle_log.append(f"{attacker.name} uses {attacker.ability['name']}!") | |
| if "crit_chance" in attacker.ability and random.random() < attacker.ability["crit_chance"]: | |
| damage *= 2 | |
| battle_log.append(f"💥 CRITICAL HIT!") | |
| defender_health -= damage | |
| battle_log.append(f"{attacker.name} deals {damage} damage to {defender.name}") | |
| battle_log.append(f"{defender.name} health: {max(0, defender_health)}/{defender.max_health}") | |
| # Determine winner | |
| if attacker_health > 0 and defender_health <= 0: | |
| winner = "attacker" | |
| battle_log.append(f"\n🎉 {attacker.name} WINS!") | |
| elif defender_health > 0 and attacker_health <= 0: | |
| winner = "defender" | |
| battle_log.append(f"\n💀 {defender.name} WINS!") | |
| else: | |
| # Draw or max rounds reached | |
| winner = "draw" | |
| if attacker_health > defender_health: | |
| winner = "attacker" | |
| battle_log.append(f"\n⏰ Time's up! {attacker.name} wins by health!") | |
| elif defender_health > attacker_health: | |
| winner = "defender" | |
| battle_log.append(f"\n⏰ Time's up! {defender.name} wins by health!") | |
| else: | |
| battle_log.append(f"\n🤝 It's a DRAW!") | |
| return { | |
| "winner": "user" if winner == "attacker" else "opponent" if winner == "defender" else "draw", | |
| "log": "\n".join(battle_log), | |
| "rounds": rounds | |
| } | |
| def get_shop_items(): | |
| """Get available shop items""" | |
| return [ | |
| { | |
| "name": "Power Boost", | |
| "cost": 50, | |
| "description": "Increase attack by 3", | |
| "effect": "attack +3", | |
| "type": "attack" | |
| }, | |
| { | |
| "name": "Defense Shield", | |
| "cost": 40, | |
| "description": "Increase defense by 3", | |
| "effect": "defense +3", | |
| "type": "defense" | |
| }, | |
| { | |
| "name": "Health Potion", | |
| "cost": 30, | |
| "description": "Restore 20 health", | |
| "effect": "health +20", | |
| "type": "health" | |
| }, | |
| { | |
| "name": "Speed Boots", | |
| "cost": 60, | |
| "description": "Increase speed by 2", | |
| "effect": "speed +2", | |
| "type": "speed" | |
| }, | |
| { | |
| "name": "Mystery Box", | |
| "cost": 100, | |
| "description": "Random stat boost", | |
| "effect": "random +5", | |
| "type": "mystery" | |
| }, | |
| { | |
| "name": "XP Boost", | |
| "cost": 80, | |
| "description": "Gain 50 XP instantly", | |
| "effect": "xp +50", | |
| "type": "xp" | |
| }, | |
| { | |
| "name": "Coin Pouch", | |
| "cost": 20, | |
| "description": "Get 30 coins", | |
| "effect": "coins +30", | |
| "type": "coins" | |
| }, | |
| { | |
| "name": "Ability Upgrade", | |
| "cost": 150, | |
| "description": "Upgrade your ability", | |
| "effect": "ability ++", | |
| "type": "ability" | |
| }, | |
| { | |
| "name": "Max Health Boost", | |
| "cost": 70, | |
| "description": "Increase max health by 15", | |
| "effect": "max_health +15", | |
| "type": "max_health" | |
| }, | |
| { | |
| "name": "Lucky Charm", | |
| "cost": 90, | |
| "description": "Increase critical hit chance", | |
| "effect": "crit +10%", | |
| "type": "crit" | |
| } | |
| ] | |
| def purchase_item(user_data, item): | |
| """Purchase an item from the shop""" | |
| if user_data["coins"] < item["cost"]: | |
| return {"success": False, "message": "Not enough coins!"} | |
| box = user_data.get("box") | |
| if not box: | |
| return {"success": False, "message": "Create a box first!"} | |
| user_data["coins"] -= item["cost"] | |
| # Apply item effect | |
| if item["type"] == "attack": | |
| box.attack += 3 | |
| message = f"Attack increased to {box.attack}!" | |
| elif item["type"] == "defense": | |
| box.defense += 3 | |
| message = f"Defense increased to {box.defense}!" | |
| elif item["type"] == "health": | |
| box.health = min(box.max_health, box.health + 20) | |
| message = f"Health restored to {box.health}!" | |
| elif item["type"] == "speed": | |
| box.speed += 2 | |
| message = f"Speed increased to {box.speed}!" | |
| elif item["type"] == "mystery": | |
| stat = random.choice(["attack", "defense", "speed"]) | |
| if stat == "attack": | |
| box.attack += 5 | |
| message = f"Mystery box gave +5 attack!" | |
| elif stat == "defense": | |
| box.defense += 5 | |
| message = f"Mystery box gave +5 defense!" | |
| else: | |
| box.speed += 5 | |
| message = f"Mystery box gave +5 speed!" | |
| elif item["type"] == "xp": | |
| box.gain_xp(50) | |
| message = f"Gained 50 XP! Current level: {box.level}" | |
| elif item["type"] == "coins": | |
| user_data["coins"] += 30 | |
| message = f"Received 30 coins! Total: {user_data['coins']}" | |
| elif item["type"] == "ability": | |
| box.ability["level"] = box.ability.get("level", 1) + 1 | |
| message = f"Ability upgraded to level {box.ability['level']}!" | |
| elif item["type"] == "max_health": | |
| box.max_health += 15 | |
| box.health += 15 | |
| message = f"Max health increased to {box.max_health}!" | |
| elif item["type"] == "crit": | |
| if "crit_chance" not in box.ability: | |
| box.ability["crit_chance"] = 0.1 | |
| else: | |
| box.ability["crit_chance"] = min(0.5, box.ability["crit_chance"] + 0.1) | |
| message = f"Critical hit chance increased to {box.ability['crit_chance']*100:.0f}%!" | |
| user_data["inventory"].append(item["name"]) | |
| return {"success": True, "message": message} | |
| def get_leaderboard(game_state): | |
| """Get the global leaderboard""" | |
| players = [] | |
| for user_id, data in game_state.items(): | |
| if data.get("box"): | |
| players.append({ | |
| "name": user_id, | |
| "box_name": data["box"].name, | |
| "level": data["box"].level, | |
| "wins": data.get("wins", 0), | |
| "losses": data.get("losses", 0), | |
| "total_battles": data.get("wins", 0) + data.get("losses", 0) | |
| }) | |
| # Sort by wins, then by win rate | |
| players.sort(key=lambda x: (x["wins"], x["wins"]/(x["losses"]+1) if x["losses"] > 0 else x["wins"]), reverse=True) | |
| return players | |
| def save_game_state(game_state, filename="game_state.json"): | |
| """Save game state to file""" | |
| try: | |
| with open(filename, 'w') as f: | |
| json.dump(game_state, f, default=str) | |
| return True | |
| except: | |
| return False | |
| def load_game_state(filename="game_state.json"): | |
| """Load game state from file""" | |
| try: | |
| with open(filename, 'r') as f: | |
| return json.load(f) | |
| except: | |
| return {} |