101 lines
3.5 KiB
Python
101 lines
3.5 KiB
Python
from typing import TYPE_CHECKING, Optional
|
|
|
|
from src.classes.tile import Tile, TileType
|
|
|
|
if TYPE_CHECKING:
|
|
from src.classes.region import Region
|
|
|
|
|
|
class Map():
|
|
"""
|
|
通过dict记录position 到 tile。
|
|
"""
|
|
def __init__(self, width: int, height: int):
|
|
self.tiles = {}
|
|
self.width = width
|
|
self.height = height
|
|
|
|
# 加载所有region数据到Map中
|
|
self._load_regions()
|
|
|
|
def _load_regions(self):
|
|
"""从配置文件加载所有区域数据到Map实例中"""
|
|
# 延迟导入避免循环导入
|
|
from src.classes.region import regions_by_id, regions_by_name
|
|
from src.classes.region import normal_regions_by_id, normal_regions_by_name
|
|
from src.classes.region import cultivate_regions_by_id, cultivate_regions_by_name
|
|
from src.classes.region import city_regions_by_id, city_regions_by_name
|
|
|
|
self.regions = regions_by_id
|
|
self.region_names = regions_by_name
|
|
self.normal_regions = normal_regions_by_id
|
|
self.normal_region_names = normal_regions_by_name
|
|
self.cultivate_regions = cultivate_regions_by_id
|
|
self.cultivate_region_names = cultivate_regions_by_name
|
|
self.city_regions = city_regions_by_id
|
|
self.city_region_names = city_regions_by_name
|
|
|
|
def is_in_bounds(self, x: int, y: int) -> bool:
|
|
"""
|
|
判断坐标是否在地图边界内。
|
|
"""
|
|
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=None)
|
|
|
|
def get_tile(self, x: int, y: int) -> Tile:
|
|
return self.tiles[(x, y)]
|
|
|
|
def get_center_locs(self, locs: list[tuple[int, int]]) -> tuple[int, int]:
|
|
"""
|
|
获取locs的中心位置。
|
|
如果几何中心恰好在位置列表中,返回几何中心;
|
|
否则返回距离几何中心最近的实际位置。
|
|
"""
|
|
if not locs:
|
|
return (0, 0)
|
|
|
|
# 分别计算x和y坐标的平均值
|
|
avg_x = sum(loc[0] for loc in locs) // len(locs)
|
|
avg_y = sum(loc[1] for loc in locs) // len(locs)
|
|
center = (avg_x, avg_y)
|
|
|
|
# 如果几何中心恰好在位置列表中,直接返回
|
|
if center in locs:
|
|
return center
|
|
|
|
# 否则找到距离几何中心最近的实际位置
|
|
def distance_squared(loc: tuple[int, int]) -> int:
|
|
"""计算到中心点的距离平方(避免开方运算)"""
|
|
return (loc[0] - avg_x) ** 2 + (loc[1] - avg_y) ** 2
|
|
|
|
return min(locs, key=distance_squared)
|
|
|
|
def get_region(self, x: int, y: int) -> Optional['Region']:
|
|
"""
|
|
获取一个region。
|
|
"""
|
|
return self.tiles[(x, y)].region
|
|
|
|
def get_info(self) -> str:
|
|
"""返回地图的简要信息,按类型分组罗列区域并说明用途。"""
|
|
parts: list[str] = []
|
|
|
|
# 修炼区域
|
|
parts.append("修炼区域(可以修炼以增进修为):")
|
|
parts.extend([f"- {str(region)}" for region in self.cultivate_regions.values()])
|
|
parts.append("")
|
|
|
|
# 普通区域
|
|
parts.append("普通区域(可以狩猎或采集):")
|
|
parts.extend([f"- {str(region)}" for region in self.normal_regions.values()])
|
|
parts.append("")
|
|
|
|
# 城市区域
|
|
parts.append("城市区域(可以交易):")
|
|
parts.extend([f"- {str(region)}" for region in self.city_regions.values()])
|
|
return "\n".join(parts)
|
|
|
|
|