Add: 增加处理光墙(海域格子间的分隔)

- 优化寻路初始化
- 修复海图log显示单字符显示'E'
This commit is contained in:
LmeSzinc 2020-05-23 17:22:51 +08:00
parent aa0e38a28c
commit 7b97d3243c
5 changed files with 119 additions and 17 deletions

View File

@ -0,0 +1,41 @@
from module.campaign.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from campaign.event_20200521_cn.d1 import Config as ConfigBase
MAP = CampaignMap()
MAP.map_data = """
-- -- -- -- ++ -- -- -- -- ++ ++
-- -- -- -- -- -- ++ ++ -- -- --
++ -- -- -- -- -- ++ ++ -- -- --
-- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- --
++ ++ -- -- -- -- ++ ++ -- -- --
++ -- -- -- -- -- -- -- -- -- --
"""
MAP.wall_data = """
· · | · · · · · · · · · ,
+ ,
· · · · · · · · · · | · ,
+ + + + + ,
· · | · · | · | · · · · | · · ,
+---+---+ | | + ,
· · · | · · | · · · · | · | · ,
+---+ +---+ +---+ +-- ,
· · · · · · · · · · · ,
,
· · · · · · · · · · · ,
,
· · · · · · · · · · · ,
"""
class Config(ConfigBase):
MAP_HAS_WALL = True
MAP_SIREN_TEMPLATE = ['Algerie', 'LaGalissonniere']
class Campaign(CampaignBase):
MAP = MAP

View File

@ -202,6 +202,7 @@ class AzurLaneConfig:
MAP_HAS_SIREN = False MAP_HAS_SIREN = False
MAP_HAS_DYNAMIC_RED_BORDER = False MAP_HAS_DYNAMIC_RED_BORDER = False
MAP_HAS_MAP_STORY = False # event_20200521_cn(穹顶下的圣咏曲) adds after-combat story. MAP_HAS_MAP_STORY = False # event_20200521_cn(穹顶下的圣咏曲) adds after-combat story.
MAP_HAS_WALL = False # event_20200521_cn(穹顶下的圣咏曲) adds wall between grids.
MAP_SIREN_MOVE_WAIT = 1.5 # The enemy moving takes about 1.2 ~ 1.5s. MAP_SIREN_MOVE_WAIT = 1.5 # The enemy moving takes about 1.2 ~ 1.5s.
MAP_SIREN_TEMPLATE = ['1', '2', '3'] MAP_SIREN_TEMPLATE = ['1', '2', '3']
MAP_SIREN_COUNT = 0 MAP_SIREN_COUNT = 0

View File

@ -327,6 +327,7 @@ class Fleet(Camera, MapOperation, AmbushHandler):
self.map.reset() self.map.reset()
self.handle_map_green_config_cover() self.handle_map_green_config_cover()
self.map.poor_map_data = self.config.POOR_MAP_DATA self.map.poor_map_data = self.config.POOR_MAP_DATA
self.map.grid_connection_initial(wall=self.config.MAP_HAS_WALL and self.is_map_green)
self.hp_init() self.hp_init()
self.handle_strategy(index=self.fleet_current_index) self.handle_strategy(index=self.fleet_current_index)
self.ensure_edge_insight(preset=self.map.in_map_swipe_preset_data) self.ensure_edge_insight(preset=self.map.in_map_swipe_preset_data)

View File

@ -86,7 +86,8 @@ class GridInfo:
return ''.join([text[0] for text in self.enemy_genre.split('_')]).upper() if self.enemy_genre else 'SU' return ''.join([text[0] for text in self.enemy_genre.split('_')]).upper() if self.enemy_genre else 'SU'
if self.is_enemy: if self.is_enemy:
return '%s%s' % (self.enemy_scale, self.enemy_genre[0].upper()) if self.enemy_genre else '0E' return '%s%s' % (self.enemy_scale, self.enemy_genre[0].upper()) \
if self.enemy_genre and self.enemy_scale else '0E'
dic = { dic = {
'FL': 'is_current_fleet', 'FL': 'is_current_fleet',
@ -105,6 +106,11 @@ class GridInfo:
def __str__(self): def __str__(self):
return location2node(self.location) return location2node(self.location)
__repr__ = __str__
def __hash__(self):
return hash(self.location)
@property @property
def str(self): def str(self):
return self.encode() return self.encode()

View File

@ -40,6 +40,7 @@ class CampaignMap:
self._shape = (0, 0) self._shape = (0, 0)
self._map_data = '' self._map_data = ''
self._weight_data = '' self._weight_data = ''
self._wall_data = ''
self._block_data = [] self._block_data = []
self._spawn_data = [] self._spawn_data = []
self._spawn_data_backup = [] self._spawn_data_backup = []
@ -47,6 +48,7 @@ class CampaignMap:
self.in_map_swipe_preset_data = None self.in_map_swipe_preset_data = None
self.poor_map_data = False self.poor_map_data = False
self.camera_sight = (-3, -1, 3, 2) self.camera_sight = (-3, -1, 3, 2)
self.grid_connection = {}
def __iter__(self): def __iter__(self):
return iter(self.grids.values()) return iter(self.grids.values())
@ -87,10 +89,11 @@ class CampaignMap:
# camera_data can be generate automatically, but it's better to set it manually. # camera_data can be generate automatically, but it's better to set it manually.
self.camera_data = [location2node(loca) for loca in camera_2d(self._shape, sight=self.camera_sight)] self.camera_data = [location2node(loca) for loca in camera_2d(self._shape, sight=self.camera_sight)]
# weight_data set to 10. # weight_data set to 10.
for grid in self: for grid in self:
grid.weight = 10. grid.weight = 10.
# Initialize grid connection.
self.grid_connection_initial()
@property @property
def map_data(self): def map_data(self):
@ -106,6 +109,57 @@ class CampaignMap:
for loca, data in self._parse_text(text): for loca, data in self._parse_text(text):
self.grids[loca].decode(data) self.grids[loca].decode(data)
@property
def wall_data(self):
return self._wall_data
@wall_data.setter
def wall_data(self, text):
self._wall_data = text
def grid_connection_initial(self, wall=False):
"""
Args:
wall (bool): If use wall_data
Returns:
bool: If used wall data.
"""
# Generate grid connection.
total = set([grid for grid in self.grids.keys()])
for grid in self:
connection = set()
for arr in np.array([(0, -1), (0, 1), (-1, 0), (1, 0)]):
arr = tuple(arr + grid.location)
if arr in total:
connection.add(self[arr])
self.grid_connection[grid] = connection
if not wall or not self._wall_data:
return False
# Use wall_data to delete connection.
wall = []
for y, line in enumerate([l for l in self._wall_data.split('\n') if l]):
for x, letter in enumerate(line[4:-2]):
if letter != ' ':
wall.append((x, y))
wall = np.array(wall)
vert = wall[np.all([wall[:, 0] % 4 == 2, wall[:, 1] % 2 == 0], axis=0)]
hori = wall[np.all([wall[:, 0] % 4 == 0, wall[:, 1] % 2 == 1], axis=0)]
disconnect = []
for loca in (vert - (2, 0)) // (4, 2):
disconnect.append([loca, loca + (1, 0)])
for loca in (hori - (0, 1)) // (4, 2):
disconnect.append([loca, loca + (0, 1)])
for g1, g2 in disconnect:
g1 = self[g1]
g2 = self[g2]
self.grid_connection[g1].remove(g2)
self.grid_connection[g2].remove(g1)
return True
def show(self): def show(self):
# logger.info('Showing grids:') # logger.info('Showing grids:')
logger.info(' ' + ' '.join([' ' + chr(x + 64 + 1) for x in range(self.shape[0] + 1)])) logger.info(' ' + ' '.join([' ' + chr(x + 64 + 1) for x in range(self.shape[0] + 1)]))
@ -210,28 +264,27 @@ class CampaignMap:
for grid in self: for grid in self:
grid.cost = 9999 grid.cost = 9999
grid.connection = None grid.connection = None
self[location].cost = 0 start = self[location]
total = set([grid for grid in self.grids.keys()]) start.cost = 0
visited = [location] visited = [start]
visited = set(visited) visited = set(visited)
while 1: while 1:
new = visited.copy() new = visited.copy()
for grid in visited: for grid in visited:
for arr in np.array([(0, -1), (0, 1), (-1, 0), (1, 0)]): for arr in self.grid_connection[grid]:
arr = tuple(arr + grid) if arr.is_land:
if arr not in total or self[arr].is_land:
continue continue
cost = 1 if self[arr].is_ambush_save else ambush_cost cost = 1 if arr.is_ambush_save else ambush_cost
cost += self[grid].cost cost += grid.cost
if cost < self[arr].cost: if cost < arr.cost:
self[arr].cost = cost arr.cost = cost
self[arr].connection = grid arr.connection = grid
elif cost == self[arr].cost: elif cost == arr.cost:
if abs(arr[0] - grid[0]) == 1: if abs(arr.location[0] - grid.location[0]) == 1:
self[arr].connection = grid arr.connection = grid
if self[arr].is_sea: if arr.is_sea:
new.add(arr) new.add(arr)
if len(new) == len(visited): if len(new) == len(visited):
break break