import math from maze import * import math import math class GreedyPlayer: def __init__(self, map_data, start=None, end=None): """初始化GreedyPlayer对象""" self.map_data = map_data self.rows = len(map_data) self.cols = len(map_data[0]) if self.rows > 0 else 0 self.start = start self.end = end self.path = [] self.total_reward = 0 self.visited = set() self.marked_map = [] # 如果未指定起点和终点,自动查找 if not self.start or not self.end: self._find_start_end() def _find_start_end(self): """自动查找地图中的起点(s)和终点(e)""" for y in range(self.rows): for x in range(self.cols): if self.map_data[y][x] == 's' or self.map_data[y][x] == 'S': self.start = (x, y) elif self.map_data[y][x] == 'e' or self.map_data[y][x] == 'E': self.end = (x, y) print(f"起点: {self.start}, 终点: {self.end}") def get_visible_cells(self, x, y, visibility=1): """获取以(x,y)为中心的上下左右四个方向的单元格信息""" visible = {} # 只考虑上下左右四个方向(dx或dy为±1,另一个为0) directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] for dx, dy in directions: nx, ny = x + dx, y + dy if 0 <= nx < self.cols and 0 <= ny < self.rows: cell = self.map_data[ny][nx] distance = 1 # 上下左右移动距离为1 visible[(nx, ny)] = (cell, distance) return visible def evaluate_cell(self, cell, distance): """评估单元格的价值,返回奖励/路径的比值""" if cell == 's' or cell == 'e': return 0 # 起点和终点不参与资源评估 if cell.startswith('t'): try: value = -int(cell[1:]) # t表示损失,转为负值 return value / distance except ValueError: return 0 elif cell.startswith('g'): try: value = int(cell[1:]) # g表示收益,转为正值 return value / distance except ValueError: return 0 return 0 # 0、l、b等不产生资源价值 def find_path(self): """基于贪心策略的路径规划(只能上下左右移动)""" if not self.start or not self.end: raise ValueError("地图中未找到起点或终点") current = self.start self.path = [current] self.visited = {current} self.total_reward = 0 while current != self.end: x, y = current visible = self.get_visible_cells(x, y) best_cell = None best_value = -float('inf') for (nx, ny), (cell, distance) in visible.items(): # 跳过已访问的位置 if (nx, ny) in self.visited: continue # 只允许在0、t、g、l、b上行走 if cell not in ['0'] and not cell.startswith(('t', 'g', 'l', 'b')): continue # 评估单元格价值 value = self.evaluate_cell(cell, distance) # 终点具有最高优先级 if cell == 'e': value = float('inf') # 选择贪心值最大的单元格 if value > best_value: best_value = value best_cell = (nx, ny) # 无法找到可行路径 if best_cell is None: print("无法找到通往终点的路径!") break # 更新当前位置和路径 current = best_cell self.path.append(current) self.visited.add(current) # 更新总收益(跳过起点和终点) if len(self.path) > 1 and len(self.path) < len(self.path) + 1: cell = self.map_data[current[1]][current[0]] if cell.startswith('t'): self.total_reward -= int(cell[1:]) elif cell.startswith('g'): self.total_reward += int(cell[1:]) self.add_path_to_map() return self.path def add_path_to_map(self): """在地图上标记路径,上下移动用|,左右移动用-""" if not self.path: print("没有路径可标记") return # 创建地图副本,避免修改原始地图 marked_map = [row.copy() for row in self.map_data] # 标记路径点 for i, (x, y) in enumerate(self.path): if marked_map[y][x] == 's': marked_map[y][x] = 'S' # 标记起点 elif marked_map[y][x] == 'e': marked_map[y][x] = 'E' # 标记终点 else: marked_map[y][x] = '*' # 标记路径点 # 标记路径线(上下左右) for i in range(len(self.path) - 1): x1, y1 = self.path[i] x2, y2 = self.path[i + 1] # 左右移动 if x1 != x2 and y1 == y2: start, end = (x1, x2) if x1 < x2 else (x2, x1) for x in range(start, end + 1): if marked_map[y1][x] not in ['S', 'E']: marked_map[y1][x] = '-' # 上下移动 elif y1 != y2 and x1 == x2: start, end = (y1, y2) if y1 < y2 else (y2, y1) for y in range(start, end + 1): if marked_map[y][x1] not in ['S', 'E']: marked_map[y][x1] = '|' # 保存标记后的地图 self.marked_map = marked_map return marked_map def get_path(self): """返回找到的路径""" return self.path def get_total_reward(self): """返回总收益""" return self.total_reward # 使用示例 def main(): obj = MazeGenerator(20,'demo.csv',name="龙脊峡谷迷宫") obj.generate( seed=123, boss_count=2, traps_range=(5, 10), mechanisms_range=(3, 7), skill_traps=8 ) obj.export_to_csv() map_data = obj.read_csv() see = MazeGenerator(1,filename ='demo.csv') see.read_from_csv() see.print_maze() player = GreedyPlayer(map_data) player.find_path() see.maze = player.marked_map see.print_maze() if __name__ == "__main__": main()