refactor regions
This commit is contained in:
@@ -7,7 +7,7 @@ import inspect
|
||||
|
||||
from src.classes.essence import Essence, EssenceType
|
||||
from src.classes.root import Root, corres_essence_type
|
||||
from src.classes.tile import Region
|
||||
from src.classes.region import Region
|
||||
from src.classes.event import Event, NULL_EVENT
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -172,7 +172,8 @@ class MoveToRegion(DefineAction, ActualActionMixin):
|
||||
移动到某个region
|
||||
"""
|
||||
if isinstance(region, str):
|
||||
region = self.world.map.region_names[region]
|
||||
from src.classes.region import regions_by_name
|
||||
region = regions_by_name[region]
|
||||
cur_loc = (self.avatar.pos_x, self.avatar.pos_y)
|
||||
region_center_loc = region.center_loc
|
||||
delta_x = region_center_loc[0] - cur_loc[0]
|
||||
@@ -187,7 +188,8 @@ class MoveToRegion(DefineAction, ActualActionMixin):
|
||||
判断动作是否完成
|
||||
"""
|
||||
if isinstance(region, str):
|
||||
region = self.world.map.region_names[region]
|
||||
from src.classes.region import regions_by_name
|
||||
region = regions_by_name[region]
|
||||
return self.avatar.is_in_region(region)
|
||||
|
||||
def get_event(self, region: Region|str) -> Event:
|
||||
@@ -196,8 +198,9 @@ class MoveToRegion(DefineAction, ActualActionMixin):
|
||||
"""
|
||||
if isinstance(region, str):
|
||||
region_name = region
|
||||
if region in self.world.map.region_names:
|
||||
region_name = self.world.map.region_names[region].name
|
||||
from src.classes.region import regions_by_name
|
||||
if region in regions_by_name:
|
||||
region_name = regions_by_name[region].name
|
||||
elif hasattr(region, 'name'):
|
||||
region_name = region.name
|
||||
else:
|
||||
@@ -249,8 +252,9 @@ class Cultivate(DefineAction, ActualActionMixin):
|
||||
"""
|
||||
判断修炼动作是否可以执行
|
||||
"""
|
||||
return self.avatar.cultivation_progress.can_cultivate()
|
||||
|
||||
root = self.avatar.root
|
||||
_corres_essence_type = corres_essence_type[root]
|
||||
return self.avatar.cultivation_progress.can_cultivate() and self.avatar.tile.region.essence.get_density(_corres_essence_type) > 0
|
||||
|
||||
# 突破境界class
|
||||
@long_action(step_month=1)
|
||||
|
||||
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING
|
||||
import random
|
||||
|
||||
from src.classes.world import World
|
||||
from src.classes.tile import Region
|
||||
from src.classes.region import Region
|
||||
from src.classes.root import corres_essence_type
|
||||
from src.classes.event import Event, NULL_EVENT
|
||||
from src.utils.llm import get_ai_prompt_and_call_llm_async
|
||||
|
||||
@@ -7,7 +7,8 @@ import json
|
||||
from src.classes.calendar import MonthStamp
|
||||
from src.classes.action import Action, ALL_ACTUAL_ACTION_CLASSES, ALL_ACTION_CLASSES, ALL_ACTUAL_ACTION_NAMES
|
||||
from src.classes.world import World
|
||||
from src.classes.tile import Tile, Region
|
||||
from src.classes.tile import Tile
|
||||
from src.classes.region import Region
|
||||
from src.classes.cultivation import CultivationProgress
|
||||
from src.classes.root import Root
|
||||
from src.classes.age import Age
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from enum import Enum
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class EssenceType(Enum):
|
||||
@@ -14,6 +15,32 @@ class EssenceType(Enum):
|
||||
def __str__(self) -> str:
|
||||
"""返回灵气类型的中文名称"""
|
||||
return essence_names.get(self, self.value)
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, essence_str: str) -> 'EssenceType':
|
||||
"""
|
||||
从字符串创建EssenceType实例
|
||||
|
||||
Args:
|
||||
essence_str: 灵气的字符串表示,如 "金", "木", "水", "火", "土"
|
||||
|
||||
Returns:
|
||||
对应的EssenceType枚举值
|
||||
|
||||
Raises:
|
||||
ValueError: 如果字符串不匹配任何已知的灵气类型
|
||||
"""
|
||||
# 首先尝试匹配中文名称
|
||||
for essence_type, chinese_name in essence_names.items():
|
||||
if chinese_name == essence_str:
|
||||
return essence_type
|
||||
|
||||
# 然后尝试匹配英文值
|
||||
for essence_type in cls:
|
||||
if essence_type.value == essence_str:
|
||||
return essence_type
|
||||
|
||||
raise ValueError(f"Unknown essence type: {essence_str}")
|
||||
|
||||
essence_names = {
|
||||
EssenceType.GOLD: "金",
|
||||
@@ -31,7 +58,9 @@ class Essence():
|
||||
浓度从0~10。
|
||||
"""
|
||||
def __init__(self, density: dict[EssenceType, int]):
|
||||
self.density = density
|
||||
self.density = defaultdict(int)
|
||||
for essence_type, density in density.items():
|
||||
self.density[essence_type] = density
|
||||
|
||||
def get_density(self, essence_type: EssenceType) -> int:
|
||||
return self.density[essence_type]
|
||||
|
||||
@@ -12,6 +12,9 @@ class Item:
|
||||
desc: str
|
||||
grade: int
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.id)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
|
||||
307
src/classes/region.py
Normal file
307
src/classes/region.py
Normal file
@@ -0,0 +1,307 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Union, TypeVar, Type
|
||||
from enum import Enum
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from src.utils.df import game_configs
|
||||
from src.classes.essence import EssenceType, Essence
|
||||
|
||||
|
||||
def get_tiles_from_shape(shape: 'Shape', north_west_cor: str, south_east_cor: str) -> list[tuple[int, int]]:
|
||||
"""
|
||||
根据形状和两个角点坐标,计算出对应的所有坐标点
|
||||
|
||||
Args:
|
||||
shape: 区域形状
|
||||
north_west_cor: 西北角坐标,格式: "x,y"
|
||||
south_east_cor: 东南角坐标,格式: "x,y"
|
||||
|
||||
Returns:
|
||||
所有坐标点的列表
|
||||
"""
|
||||
nw_coords = tuple(map(int, north_west_cor.split(',')))
|
||||
se_coords = tuple(map(int, south_east_cor.split(',')))
|
||||
|
||||
min_x, min_y = nw_coords
|
||||
max_x, max_y = se_coords
|
||||
|
||||
coordinates = []
|
||||
|
||||
if shape == Shape.SQUARE or shape == Shape.RECTANGLE:
|
||||
# 正方形和长方形:填充整个矩形区域
|
||||
for x in range(min_x, max_x + 1):
|
||||
for y in range(min_y, max_y + 1):
|
||||
coordinates.append((x, y))
|
||||
|
||||
elif shape == Shape.MEANDERING:
|
||||
# 蜿蜒形状(如河流):创建一条从西北到东南的蜿蜒路径
|
||||
# 计算河流的宽度(根据距离动态调整)
|
||||
distance_x = max_x - min_x
|
||||
distance_y = max_y - min_y
|
||||
total_distance = max(distance_x, distance_y)
|
||||
|
||||
# 河流宽度:距离越长,河流越宽
|
||||
if total_distance < 10:
|
||||
width = 1
|
||||
elif total_distance < 30:
|
||||
width = 2
|
||||
else:
|
||||
width = 3
|
||||
|
||||
# 生成中心路径点
|
||||
path_points = []
|
||||
if distance_x >= distance_y:
|
||||
# 主要沿X轴方向流动
|
||||
for x in range(min_x, max_x + 1):
|
||||
# 计算对应的y坐标,添加一些蜿蜒效果
|
||||
progress = (x - min_x) / max(distance_x, 1)
|
||||
base_y = min_y + int(progress * distance_y)
|
||||
|
||||
# 添加蜿蜒效果:使用简单的正弦波
|
||||
import math
|
||||
wave_amplitude = min(3, distance_y // 4) if distance_y > 0 else 0
|
||||
wave_y = int(wave_amplitude * math.sin(progress * math.pi * 2))
|
||||
y = max(min_y, min(max_y, base_y + wave_y))
|
||||
|
||||
path_points.append((x, y))
|
||||
else:
|
||||
# 主要沿Y轴方向流动
|
||||
for y in range(min_y, max_y + 1):
|
||||
progress = (y - min_y) / max(distance_y, 1)
|
||||
base_x = min_x + int(progress * distance_x)
|
||||
|
||||
# 添加蜿蜒效果
|
||||
import math
|
||||
wave_amplitude = min(3, distance_x // 4) if distance_x > 0 else 0
|
||||
wave_x = int(wave_amplitude * math.sin(progress * math.pi * 2))
|
||||
x = max(min_x, min(max_x, base_x + wave_x))
|
||||
|
||||
path_points.append((x, y))
|
||||
|
||||
# 为每个路径点添加宽度
|
||||
for px, py in path_points:
|
||||
for dx in range(-width//2, width//2 + 1):
|
||||
for dy in range(-width//2, width//2 + 1):
|
||||
nx, ny = px + dx, py + dy
|
||||
# 确保在边界内
|
||||
if min_x <= nx <= max_x and min_y <= ny <= max_y:
|
||||
coordinates.append((nx, ny))
|
||||
|
||||
# 去重并排序
|
||||
return sorted(list(set(coordinates)))
|
||||
|
||||
|
||||
@dataclass
|
||||
class Region(ABC):
|
||||
"""
|
||||
区域抽象基类
|
||||
理想中,一些地块应当在一起组成一个区域。
|
||||
比如,某山;某湖、江、海;某森林;某平原;某城市;
|
||||
一些分布,比如物产,按照Region来分布。
|
||||
再比如,灵气,应当也是按照region分布的。
|
||||
默认,一个region内部的属性,是共通的。
|
||||
同时,NPC应当对Region有观测和认知。
|
||||
"""
|
||||
id: int
|
||||
name: str
|
||||
desc: str
|
||||
shape: 'Shape'
|
||||
north_west_cor: str # 西北角坐标,格式: "x,y"
|
||||
south_east_cor: str # 东南角坐标,格式: "x,y"
|
||||
|
||||
# 这些字段将在__post_init__中设置
|
||||
cors: list[tuple[int, int]] = field(init=False) # 存储所有坐标点
|
||||
center_loc: tuple[int, int] = field(init=False)
|
||||
area: int = field(init=False)
|
||||
|
||||
def __post_init__(self):
|
||||
"""初始化计算字段"""
|
||||
# 先计算所有坐标点
|
||||
self.cors = get_tiles_from_shape(self.shape, self.north_west_cor, self.south_east_cor)
|
||||
|
||||
# 基于坐标点计算面积
|
||||
self.area = len(self.cors)
|
||||
|
||||
# 计算中心位置(基于实际坐标点的平均值)
|
||||
if self.cors:
|
||||
avg_x = sum(coord[0] for coord in self.cors) // len(self.cors)
|
||||
avg_y = sum(coord[1] for coord in self.cors) // len(self.cors)
|
||||
self.center_loc = (avg_x, avg_y)
|
||||
else:
|
||||
# 如果没有坐标点,使用边界框中心作为fallback
|
||||
nw_coords = tuple(map(int, self.north_west_cor.split(',')))
|
||||
se_coords = tuple(map(int, self.south_east_cor.split(',')))
|
||||
self.center_loc = (
|
||||
(nw_coords[0] + se_coords[0]) // 2,
|
||||
(nw_coords[1] + se_coords[1]) // 2
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.id)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, Region):
|
||||
return False
|
||||
return self.id == other.id
|
||||
|
||||
@abstractmethod
|
||||
def get_region_type(self) -> str:
|
||||
"""返回区域类型的字符串表示"""
|
||||
pass
|
||||
|
||||
|
||||
class Shape(Enum):
|
||||
"""
|
||||
区域形状类型
|
||||
"""
|
||||
SQUARE = "square" # 正方形
|
||||
RECTANGLE = "rectangle" # 长方形
|
||||
MEANDERING = "meandering" # 蜿蜒的(如河流)
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, shape_str: str) -> 'Shape':
|
||||
"""
|
||||
从字符串创建Shape实例
|
||||
|
||||
Args:
|
||||
shape_str: 形状的字符串表示,如 "square", "rectangle", "meandering"
|
||||
|
||||
Returns:
|
||||
对应的Shape枚举值
|
||||
|
||||
Raises:
|
||||
ValueError: 如果字符串不匹配任何已知的形状类型
|
||||
"""
|
||||
for shape in cls:
|
||||
if shape.value == shape_str:
|
||||
return shape
|
||||
raise ValueError(f"Unknown shape type: {shape_str}")
|
||||
|
||||
|
||||
@dataclass
|
||||
class NormalRegion(Region):
|
||||
"""
|
||||
普通区域 - 平原、大河之类的,没有灵气或灵气很低
|
||||
"""
|
||||
|
||||
def get_region_type(self) -> str:
|
||||
return "normal"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"普通区域:{self.name} - {self.desc}"
|
||||
|
||||
|
||||
@dataclass
|
||||
class CultivateRegion(Region):
|
||||
"""
|
||||
修炼区域 - 有灵气的区域,可以修炼
|
||||
"""
|
||||
essence_type: EssenceType # 最高灵气类型
|
||||
essence_density: int # 最高灵气密度
|
||||
essence: Essence = field(init=False) # 灵气对象,根据 essence_type 和 essence_density 生成
|
||||
|
||||
def __post_init__(self):
|
||||
# 先调用父类的 __post_init__
|
||||
super().__post_init__()
|
||||
|
||||
# 创建灵气对象,主要灵气类型设置为指定密度,其他类型设置为0
|
||||
essence_density_dict = {essence_type: 0 for essence_type in EssenceType}
|
||||
essence_density_dict[self.essence_type] = self.essence_density
|
||||
self.essence = Essence(essence_density_dict)
|
||||
|
||||
def get_region_type(self) -> str:
|
||||
return "cultivate"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"修炼区域:{self.name}({self.essence_type}行灵气:{self.essence_density})- {self.desc}"
|
||||
|
||||
|
||||
@dataclass
|
||||
class CityRegion(Region):
|
||||
"""
|
||||
城市区域 - 不能修炼,但会有特殊操作
|
||||
"""
|
||||
|
||||
def get_region_type(self) -> str:
|
||||
return "city"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"城市区域:{self.name} - {self.desc}"
|
||||
|
||||
|
||||
T = TypeVar('T', NormalRegion, CultivateRegion, CityRegion)
|
||||
|
||||
def _load_regions(region_type: Type[T], config_name: str) -> tuple[dict[int, T], dict[str, T]]:
|
||||
"""
|
||||
通用的区域加载函数
|
||||
|
||||
Args:
|
||||
region_type: 区域类型 (NormalRegion, CultivateRegion, CityRegion)
|
||||
config_name: 配置文件名 ("normal_region", "cultivate_region", "city_region")
|
||||
|
||||
Returns:
|
||||
(按ID索引的字典, 按名称索引的字典)
|
||||
"""
|
||||
regions_by_id: dict[int, T] = {}
|
||||
regions_by_name: dict[str, T] = {}
|
||||
|
||||
region_df = game_configs[config_name]
|
||||
for _, row in region_df.iterrows():
|
||||
# 构建基础参数
|
||||
base_params = {
|
||||
"id": int(row["id"]),
|
||||
"name": str(row["name"]),
|
||||
"desc": str(row["desc"]),
|
||||
"shape": Shape.from_str(str(row["shape"])),
|
||||
"north_west_cor": str(row["north-west-cor"]),
|
||||
"south_east_cor": str(row["south-east-cor"])
|
||||
}
|
||||
|
||||
# 如果是修炼区域,添加额外参数
|
||||
if region_type == CultivateRegion:
|
||||
base_params["essence_type"] = EssenceType.from_str(str(row["root_type"]))
|
||||
base_params["essence_density"] = int(row["root_density"])
|
||||
|
||||
region = region_type(**base_params)
|
||||
regions_by_id[region.id] = region
|
||||
regions_by_name[region.name] = region
|
||||
|
||||
return regions_by_id, regions_by_name
|
||||
|
||||
|
||||
def load_all_regions() -> tuple[
|
||||
dict[int, Union[NormalRegion, CultivateRegion, CityRegion]],
|
||||
dict[str, Union[NormalRegion, CultivateRegion, CityRegion]]
|
||||
]:
|
||||
"""
|
||||
统一加载所有类型的区域数据
|
||||
返回: (按ID索引的字典, 按名称索引的字典)
|
||||
"""
|
||||
all_regions_by_id: dict[int, Union[NormalRegion, CultivateRegion, CityRegion]] = {}
|
||||
all_regions_by_name: dict[str, Union[NormalRegion, CultivateRegion, CityRegion]] = {}
|
||||
|
||||
# 加载普通区域
|
||||
normal_by_id, normal_by_name = _load_regions(NormalRegion, "normal_region")
|
||||
all_regions_by_id.update(normal_by_id)
|
||||
all_regions_by_name.update(normal_by_name)
|
||||
|
||||
# 加载修炼区域
|
||||
cultivate_by_id, cultivate_by_name = _load_regions(CultivateRegion, "cultivate_region")
|
||||
all_regions_by_id.update(cultivate_by_id)
|
||||
all_regions_by_name.update(cultivate_by_name)
|
||||
|
||||
# 加载城市区域
|
||||
city_by_id, city_by_name = _load_regions(CityRegion, "city_region")
|
||||
all_regions_by_id.update(city_by_id)
|
||||
all_regions_by_name.update(city_by_name)
|
||||
|
||||
return all_regions_by_id, all_regions_by_name
|
||||
|
||||
|
||||
# 从配表加载所有区域数据
|
||||
regions_by_id, regions_by_name = load_all_regions()
|
||||
|
||||
# 分别加载各类型区域数据
|
||||
normal_regions_by_id, normal_regions_by_name = _load_regions(NormalRegion, "normal_region")
|
||||
cultivate_regions_by_id, cultivate_regions_by_name = _load_regions(CultivateRegion, "cultivate_region")
|
||||
city_regions_by_id, city_regions_by_name = _load_regions(CityRegion, "city_region")
|
||||
@@ -18,6 +18,25 @@ class Root(Enum):
|
||||
WATER = "水"
|
||||
FIRE = "火"
|
||||
EARTH = "土"
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, root_str: str) -> 'Root':
|
||||
"""
|
||||
从字符串创建Root实例
|
||||
|
||||
Args:
|
||||
root_str: 灵根的字符串表示,如 "金", "木", "水", "火", "土"
|
||||
|
||||
Returns:
|
||||
对应的Root枚举值
|
||||
|
||||
Raises:
|
||||
ValueError: 如果字符串不匹配任何已知的灵根类型
|
||||
"""
|
||||
for root in cls:
|
||||
if root.value == root_str:
|
||||
return root
|
||||
raise ValueError(f"Unknown root type: {root_str}")
|
||||
|
||||
corres_essence_type = {
|
||||
Root.GOLD: EssenceType.GOLD,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import itertools
|
||||
from enum import Enum
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from src.classes.essence import Essence, EssenceType
|
||||
if TYPE_CHECKING:
|
||||
from src.classes.region import Region
|
||||
|
||||
class TileType(Enum):
|
||||
PLAIN = "plain" # 平原
|
||||
@@ -22,52 +23,6 @@ class TileType(Enum):
|
||||
RUINS = "ruins" # 遗迹
|
||||
FARM = "farm" # 农田
|
||||
|
||||
region_id_counter = itertools.count(1)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Region():
|
||||
"""
|
||||
理想中,一些地块应当在一起组成一个区域。
|
||||
比如,某山;某湖、江、海;某森林;某平原;某城市;
|
||||
一些分布,比如物产,按照Region来分布。
|
||||
再比如,灵气,应当也是按照region分布的。
|
||||
默认,一个region内部的属性,是共通的。
|
||||
同时,NPC应当对Region有观测和认知。
|
||||
"""
|
||||
name: str
|
||||
description: str
|
||||
essence: Essence
|
||||
id: int = field(init=False)
|
||||
center_loc: tuple[int, int] = field(init=False)
|
||||
area: int = field(init=False)
|
||||
|
||||
def __post_init__(self):
|
||||
self.id = next(region_id_counter)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"区域。名字:{self.name},描述:{self.description},最浓的灵气:{self.get_most_dense_essence()}, 灵气值:{self.get_most_dense_essence_value()}"
|
||||
|
||||
def get_most_dense_essence(self) -> EssenceType:
|
||||
return max(self.essence.density.items(), key=lambda x: x[1])[0]
|
||||
|
||||
def get_most_dense_essence_value(self) -> int:
|
||||
most_dense_essence = self.get_most_dense_essence()
|
||||
return self.essence.density[most_dense_essence]
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.id)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, Region):
|
||||
return False
|
||||
return self.id == other.id
|
||||
# 物产
|
||||
# 灵气
|
||||
# 其他
|
||||
|
||||
default_region = Region(name="平原", description="最普通的平原,没有什么可说的", essence=Essence(density={EssenceType.GOLD: 1, EssenceType.WOOD: 1, EssenceType.WATER: 1, EssenceType.FIRE: 1, EssenceType.EARTH: 1}))
|
||||
default_region.area = 1 # 默认区域面积为1
|
||||
|
||||
@dataclass
|
||||
class Tile():
|
||||
@@ -75,7 +30,7 @@ class Tile():
|
||||
type: TileType
|
||||
x: int
|
||||
y: int
|
||||
region: Region # 可以是一个region的一部分,也可以不属于任何region
|
||||
region: 'Region' = None # 可以是一个region的一部分,也可以不属于任何region
|
||||
|
||||
class Map():
|
||||
"""
|
||||
@@ -83,10 +38,18 @@ class Map():
|
||||
"""
|
||||
def __init__(self, width: int, height: int):
|
||||
self.tiles = {}
|
||||
self.regions = {} # region_id -> region
|
||||
self.region_names = {} # region_name -> region
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
# 加载所有region数据到Map中
|
||||
self._load_regions()
|
||||
|
||||
def _load_regions(self):
|
||||
"""从配置文件加载所有区域数据到Map实例中"""
|
||||
# 延迟导入避免循环导入
|
||||
from src.classes.region import load_all_regions
|
||||
|
||||
self.regions, self.region_names = load_all_regions()
|
||||
|
||||
def is_in_bounds(self, x: int, y: int) -> bool:
|
||||
"""
|
||||
@@ -95,25 +58,11 @@ class Map():
|
||||
return 0 <= x < self.width and 0 <= y < self.height
|
||||
|
||||
def create_tile(self, x: int, y: int, tile_type: TileType):
|
||||
self.tiles[(x, y)] = Tile(tile_type, x, y, region=default_region)
|
||||
self.tiles[(x, y)] = Tile(tile_type, x, y, region=None)
|
||||
|
||||
def get_tile(self, x: int, y: int) -> Tile:
|
||||
return self.tiles[(x, y)]
|
||||
|
||||
def create_region(self, name: str, description: str, essence: Essence, locs: list[tuple[int, int]]):
|
||||
"""
|
||||
创建一个region。
|
||||
"""
|
||||
region = Region(name=name, description=description, essence=essence)
|
||||
center_loc = self.get_center_locs(locs)
|
||||
for loc in locs:
|
||||
self.tiles[loc].region = region
|
||||
region.center_loc = center_loc
|
||||
region.area = len(locs)
|
||||
self.regions[region.id] = region
|
||||
self.region_names[name] = region
|
||||
return region
|
||||
|
||||
def get_center_locs(self, locs: list[tuple[int, int]]) -> tuple[int, int]:
|
||||
"""
|
||||
获取locs的中心位置。
|
||||
@@ -139,7 +88,7 @@ class Map():
|
||||
|
||||
return min(locs, key=distance_squared)
|
||||
|
||||
def get_region(self, x: int, y: int) -> Region | None:
|
||||
def get_region(self, x: int, y: int) -> 'Region | None':
|
||||
"""
|
||||
获取一个region。
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user