Spaces:
Sleeping
Sleeping
File size: 3,690 Bytes
8bdaafd | 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 | 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),
}
|