Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import random | |
| from typing import Any | |
| MONSTER_DB: dict[str, dict[str, int]] = { | |
| "哥布林": {"hp": 20, "attack": 5, "defense": 2, "difficulty": 1}, | |
| "森林狼": {"hp": 40, "attack": 15, "defense": 5, "difficulty": 2}, | |
| "远古巨龙": {"hp": 500, "attack": 100, "defense": 80, "difficulty": 10}, | |
| "default": {"hp": 30, "attack": 10, "defense": 5, "difficulty": 1}, | |
| } | |
| def _difficulty_scale(game_state: Any | None) -> float: | |
| if game_state is None: | |
| return 1.0 | |
| diff_name = str(getattr(game_state, "difficulty", "normal")).lower() | |
| return {"easy": 0.9, "normal": 1.0, "hard": 1.2}.get(diff_name, 1.0) | |
| def _current_location_danger(game_state: Any | None) -> int: | |
| if game_state is None: | |
| return 1 | |
| player = getattr(game_state, "player", None) | |
| world = getattr(game_state, "world", None) | |
| if player is None or world is None: | |
| return 1 | |
| location_name = str(getattr(player, "location", "")) | |
| location = getattr(world, "locations", {}).get(location_name) | |
| if location is None: | |
| return 1 | |
| try: | |
| return max(1, int(getattr(location, "danger_level", 1))) | |
| except Exception: | |
| return 1 | |
| def get_monster_profile(monster_name: str, game_state: Any | None = None) -> dict[str, int]: | |
| normalized_name = str(monster_name or "").strip() | |
| profile = MONSTER_DB.get(normalized_name) | |
| if profile is not None: | |
| return dict(profile) | |
| base = dict(MONSTER_DB["default"]) | |
| location_danger = _current_location_danger(game_state) | |
| diff_scale = _difficulty_scale(game_state) | |
| generated_difficulty = max(1, int(round(base["difficulty"] + (location_danger - 1) * 0.6))) | |
| generated_attack = max(1, int(round(base["attack"] * diff_scale + location_danger * 2))) | |
| generated_defense = max(1, int(round(base["defense"] * diff_scale + location_danger))) | |
| generated_hp = max(1, int(round(base["hp"] * diff_scale + location_danger * 10))) | |
| return { | |
| "hp": generated_hp, | |
| "attack": generated_attack, | |
| "defense": generated_defense, | |
| "difficulty": generated_difficulty, | |
| } | |
| def resolve_combat( | |
| player_state: Any, | |
| monster_name: str, | |
| *, | |
| game_state: Any | None = None, | |
| rng: random.Random | None = None, | |
| ) -> dict[str, Any]: | |
| active_rng = rng or random | |
| monster = get_monster_profile(monster_name, game_state=game_state) | |
| player_level = max(1, int(getattr(player_state, "level", 1))) | |
| player_attack = max(1, int(getattr(player_state, "attack_power", getattr(player_state, "attack", 1)))) | |
| player_defense = max(0, int(getattr(player_state, "defense_power", getattr(player_state, "defense", 0)))) | |
| player_power = player_attack + player_level * 2 | |
| monster_power = int(monster["defense"]) + int(monster["difficulty"]) * 3 | |
| outcome = "win" if player_power >= monster_power else "lose" | |
| random_float = float(active_rng.uniform(0.0, 3.0)) | |
| base_hp_loss = max(1, int(round(int(monster["attack"]) - player_defense - random_float))) | |
| if outcome == "lose": | |
| base_hp_loss = max(base_hp_loss + int(monster["difficulty"]) * 2, int(round(base_hp_loss * 1.4))) | |
| if outcome == "win": | |
| message = f"你击败了{monster_name},但仍受了些伤。" | |
| else: | |
| message = f"你不敌{monster_name},被迫败退。" | |
| return { | |
| "outcome": outcome, | |
| "player_hp_loss": int(base_hp_loss), | |
| "monster_name": str(monster_name), | |
| "message": message, | |
| "player_power": int(player_power), | |
| "monster_power": int(monster_power), | |
| } | |