贪心算法3
This commit is contained in:
parent
90b1d60079
commit
78bade385e
@ -1,380 +0,0 @@
|
||||
"""
|
||||
3x3视野贪心资源收集算法
|
||||
|
||||
该模块实现了一个基于3x3视野的贪心算法,用于在迷宫中收集资源。
|
||||
算法特点:
|
||||
1. 每次移动时只考虑当前位置周围3x3范围内的资源
|
||||
2. 优先选择正价值资源(金币),如果没有则选择损失最小的负价值资源(陷阱)
|
||||
3. 只能进行上下左右四个方向的移动
|
||||
4. 当视野内没有资源时,会进行探索性移动
|
||||
5. 避免无限循环,当连续多步无法找到新资源时会自动停止
|
||||
|
||||
使用方法:
|
||||
```python
|
||||
from greedy_3x3_algorithm import Greedy3x3Algorithm
|
||||
|
||||
# 创建迷宫(二维数组,[y][x]格式)
|
||||
maze = [
|
||||
['s', '0', 'g5', '1', 't3'],
|
||||
['0', '1', '0', '0', 'g2'],
|
||||
['g3', '0', '1', 't2', '0'],
|
||||
['0', 't1', '0', '0', 'g4'],
|
||||
['1', '0', 'g1', '0', 'e']
|
||||
]
|
||||
|
||||
# 创建算法实例并运行
|
||||
algorithm = Greedy3x3Algorithm(maze)
|
||||
result = algorithm.run()
|
||||
|
||||
# 获取结果
|
||||
print(f"总价值: {result['total_value']}")
|
||||
print(f"路径: {result['path']}")
|
||||
```
|
||||
"""
|
||||
|
||||
import copy
|
||||
from collections import deque
|
||||
|
||||
|
||||
class Greedy3x3Algorithm:
|
||||
"""
|
||||
3x3视野贪心资源收集算法
|
||||
|
||||
该算法在每个位置只考虑周围3x3范围内的资源,选择价值最高的资源进行收集。
|
||||
如果视野内没有资源,则进行探索性移动。
|
||||
"""
|
||||
|
||||
def __init__(self, maze, start_pos=None, end_pos=None, debug=False):
|
||||
"""
|
||||
初始化算法
|
||||
|
||||
Args:
|
||||
maze: 二维列表,表示迷宫地图 ([y][x]格式)
|
||||
start_pos: 起始位置 (x, y),默认自动寻找's'
|
||||
end_pos: 目标位置 (x, y),默认自动寻找'e'
|
||||
debug: 是否输出调试信息
|
||||
"""
|
||||
self.original_maze = copy.deepcopy(maze)
|
||||
self.maze = copy.deepcopy(maze)
|
||||
self.rows = len(maze)
|
||||
self.cols = len(maze[0]) if self.rows > 0 else 0
|
||||
self.debug = debug
|
||||
|
||||
# 寻找起始位置和目标位置
|
||||
self.start_pos = start_pos or self._find_position('s')
|
||||
self.end_pos = end_pos or self._find_position('e')
|
||||
|
||||
if not self.start_pos:
|
||||
raise ValueError("无法找到起始位置 's'")
|
||||
if not self.end_pos:
|
||||
raise ValueError("无法找到目标位置 'e'")
|
||||
|
||||
# 初始化状态
|
||||
self.current_pos = self.start_pos
|
||||
self.path = [self.start_pos]
|
||||
self.collected_resources = []
|
||||
self.total_value = 0
|
||||
self.visited_resources = set()
|
||||
self.explored_positions = set([self.start_pos])
|
||||
|
||||
if self.debug:
|
||||
print(f"3x3视野贪心算法初始化")
|
||||
print(f"迷宫大小: {self.rows}x{self.cols}")
|
||||
print(f"起始位置: {self.start_pos}")
|
||||
print(f"目标位置: {self.end_pos}")
|
||||
|
||||
def _find_position(self, target):
|
||||
"""寻找地图中指定字符的位置,返回(x, y)格式"""
|
||||
for y in range(self.rows):
|
||||
for x in range(self.cols):
|
||||
if self.maze[y][x].lower() == target.lower():
|
||||
return (x, y)
|
||||
return None
|
||||
|
||||
def get_3x3_vision(self, pos):
|
||||
"""
|
||||
获取以pos为中心的3x3视野范围内的所有单元格
|
||||
|
||||
Args:
|
||||
pos: 当前位置 (x, y)
|
||||
|
||||
Returns:
|
||||
dict: {(x, y): cell_value} 形式的字典
|
||||
"""
|
||||
x, y = pos
|
||||
vision = {}
|
||||
|
||||
# 遍历3x3范围
|
||||
for dx in range(-1, 2):
|
||||
for dy in range(-1, 2):
|
||||
new_x, new_y = x + dx, y + dy
|
||||
|
||||
# 检查边界
|
||||
if 0 <= new_x < self.cols and 0 <= new_y < self.rows:
|
||||
vision[(new_x, new_y)] = self.maze[new_y][new_x]
|
||||
|
||||
return vision
|
||||
|
||||
def get_adjacent_positions(self, pos):
|
||||
"""
|
||||
获取当前位置的上下左右四个相邻位置
|
||||
|
||||
Args:
|
||||
pos: 当前位置 (x, y)
|
||||
|
||||
Returns:
|
||||
list: 可移动的相邻位置列表
|
||||
"""
|
||||
x, y = pos
|
||||
adjacent = []
|
||||
|
||||
# 上下左右四个方向
|
||||
directions = [(0, -1), (0, 1), (-1, 0), (1, 0)] # 上、下、左、右
|
||||
|
||||
for dx, dy in directions:
|
||||
new_x, new_y = x + dx, y + dy
|
||||
|
||||
# 检查边界和可移动性
|
||||
if (0 <= new_x < self.cols and
|
||||
0 <= new_y < self.rows and
|
||||
self._can_move_to((new_x, new_y))):
|
||||
adjacent.append((new_x, new_y))
|
||||
|
||||
return adjacent
|
||||
|
||||
def _can_move_to(self, pos):
|
||||
"""检查是否可以移动到指定位置"""
|
||||
x, y = pos
|
||||
cell = self.maze[y][x]
|
||||
return cell != '1' # 不能移动到墙壁
|
||||
|
||||
def _evaluate_resource_value(self, cell):
|
||||
"""评估资源的价值"""
|
||||
if cell.startswith('g'):
|
||||
try:
|
||||
return int(cell[1:])
|
||||
except ValueError:
|
||||
return 0
|
||||
elif cell.startswith('t'):
|
||||
try:
|
||||
return -int(cell[1:])
|
||||
except ValueError:
|
||||
return 0
|
||||
else:
|
||||
return 0
|
||||
|
||||
def _find_best_resource_in_vision(self):
|
||||
"""
|
||||
在3x3视野范围内找到价值最高的可到达资源
|
||||
|
||||
Returns:
|
||||
tuple: (最佳资源位置, 资源价值) 或 (None, 0)
|
||||
"""
|
||||
vision = self.get_3x3_vision(self.current_pos)
|
||||
adjacent_positions = self.get_adjacent_positions(self.current_pos)
|
||||
|
||||
best_pos = None
|
||||
best_value = float('-inf')
|
||||
|
||||
# 只考虑相邻且在视野内的位置
|
||||
for pos in adjacent_positions:
|
||||
if pos in vision and pos not in self.visited_resources:
|
||||
cell = vision[pos]
|
||||
value = self._evaluate_resource_value(cell)
|
||||
|
||||
if value != 0 and value > best_value:
|
||||
best_value = value
|
||||
best_pos = pos
|
||||
|
||||
return best_pos, best_value if best_pos else 0
|
||||
|
||||
def _find_exploration_target(self):
|
||||
"""当视野内没有资源时,寻找探索目标"""
|
||||
adjacent = self.get_adjacent_positions(self.current_pos)
|
||||
|
||||
# 优先选择未探索的位置
|
||||
unexplored = [pos for pos in adjacent if pos not in self.explored_positions]
|
||||
if unexplored:
|
||||
return unexplored[0]
|
||||
|
||||
# 如果所有相邻位置都探索过,选择任意一个
|
||||
if adjacent:
|
||||
return adjacent[0]
|
||||
|
||||
return None
|
||||
|
||||
def _collect_resource(self, pos):
|
||||
"""收集指定位置的资源"""
|
||||
x, y = pos
|
||||
cell = self.maze[y][x]
|
||||
value = self._evaluate_resource_value(cell)
|
||||
|
||||
if value != 0:
|
||||
self.collected_resources.append({
|
||||
'position': pos,
|
||||
'type': cell,
|
||||
'value': value
|
||||
})
|
||||
self.total_value += value
|
||||
self.visited_resources.add(pos)
|
||||
|
||||
if self.debug:
|
||||
print(f"收集资源: 位置{pos}, 类型{cell}, 价值{value}, 总价值{self.total_value}")
|
||||
|
||||
def run(self, max_moves=1000, max_stuck=20):
|
||||
"""
|
||||
运行3x3视野贪心资源收集算法
|
||||
|
||||
Args:
|
||||
max_moves: 最大移动步数,防止无限循环
|
||||
max_stuck: 连续无资源的最大步数
|
||||
|
||||
Returns:
|
||||
dict: 包含路径、收集的资源等信息的结果字典
|
||||
"""
|
||||
if self.debug:
|
||||
print("\\n开始3x3视野贪心资源收集...")
|
||||
|
||||
moves = 0
|
||||
stuck_count = 0
|
||||
|
||||
while moves < max_moves and stuck_count < max_stuck:
|
||||
moves += 1
|
||||
|
||||
# 在3x3视野内寻找最佳资源
|
||||
best_resource_pos, best_value = self._find_best_resource_in_vision()
|
||||
|
||||
if best_resource_pos is not None:
|
||||
if self.debug:
|
||||
print(f"第{moves}步: 发现视野内资源 位置{best_resource_pos}, 价值{best_value}")
|
||||
|
||||
# 移动到资源位置并收集
|
||||
self.current_pos = best_resource_pos
|
||||
self.path.append(best_resource_pos)
|
||||
self.explored_positions.add(best_resource_pos)
|
||||
self._collect_resource(best_resource_pos)
|
||||
|
||||
stuck_count = 0 # 重置无资源计数
|
||||
else:
|
||||
# 视野内没有资源,进行探索性移动
|
||||
exploration_target = self._find_exploration_target()
|
||||
|
||||
if exploration_target:
|
||||
if self.debug:
|
||||
print(f"第{moves}步: 视野内无资源,探索移动到 {exploration_target}")
|
||||
self.current_pos = exploration_target
|
||||
self.path.append(exploration_target)
|
||||
self.explored_positions.add(exploration_target)
|
||||
stuck_count += 1
|
||||
else:
|
||||
if self.debug:
|
||||
print(f"第{moves}步: 无法进行任何移动,结束收集")
|
||||
break
|
||||
|
||||
if self.debug:
|
||||
if moves >= max_moves:
|
||||
print(f"达到最大移动步数 {max_moves},结束收集")
|
||||
elif stuck_count >= max_stuck:
|
||||
print(f"连续 {max_stuck} 步未找到资源,结束收集")
|
||||
print("3x3视野资源收集完成!")
|
||||
|
||||
return self._get_result()
|
||||
|
||||
def _get_result(self):
|
||||
"""获取算法执行结果"""
|
||||
return {
|
||||
'path': self.path.copy(),
|
||||
'path_yx_format': [(y, x) for (x, y) in self.path], # 兼容现有代码的(y,x)格式
|
||||
'collected_resources': self.collected_resources.copy(),
|
||||
'total_value': self.total_value,
|
||||
'total_moves': len(self.path) - 1,
|
||||
'resources_count': len(self.collected_resources),
|
||||
'start_pos': self.start_pos,
|
||||
'end_pos': self.end_pos,
|
||||
'final_pos': self.current_pos,
|
||||
'explored_positions_count': len(self.explored_positions),
|
||||
'algorithm_name': '3x3视野贪心算法'
|
||||
}
|
||||
|
||||
def get_marked_maze(self):
|
||||
"""
|
||||
获取标记了路径的迷宫
|
||||
|
||||
Returns:
|
||||
list: 标记后的迷宫,S=起点, E=终点, *=已收集资源, .=路径
|
||||
"""
|
||||
marked_maze = copy.deepcopy(self.original_maze)
|
||||
|
||||
# 标记路径点
|
||||
for i, (x, y) in enumerate(self.path):
|
||||
if (x, y) == self.start_pos:
|
||||
marked_maze[y][x] = 'S' # 起点
|
||||
elif (x, y) == self.end_pos:
|
||||
marked_maze[y][x] = 'E' # 终点
|
||||
elif (x, y) in [r['position'] for r in self.collected_resources]:
|
||||
marked_maze[y][x] = '*' # 已收集资源
|
||||
else:
|
||||
marked_maze[y][x] = '.' # 路径点
|
||||
|
||||
return marked_maze
|
||||
|
||||
def print_result(self):
|
||||
"""打印算法执行结果"""
|
||||
result = self._get_result()
|
||||
|
||||
print("\\n=== 3x3视野贪心算法执行结果 ===")
|
||||
print(f"起始位置: {result['start_pos']}")
|
||||
print(f"最终位置: {result['final_pos']}")
|
||||
print(f"总移动步数: {result['total_moves']}")
|
||||
print(f"探索位置数: {result['explored_positions_count']}")
|
||||
print(f"收集资源数量: {result['resources_count']}")
|
||||
print(f"资源总价值: {result['total_value']}")
|
||||
|
||||
if result['collected_resources']:
|
||||
print("\\n收集的资源详情:")
|
||||
for i, resource in enumerate(result['collected_resources'], 1):
|
||||
print(f" {i}. 位置{resource['position']}: {resource['type']} (价值: {resource['value']})")
|
||||
else:
|
||||
print("\\n未收集到任何资源")
|
||||
|
||||
# 显示标记后的迷宫
|
||||
marked_maze = self.get_marked_maze()
|
||||
print("\\n标记路径后的迷宫:")
|
||||
print("S: 起点, E: 终点, *: 已收集资源, .: 路径")
|
||||
for row in marked_maze:
|
||||
print(' '.join(f"{cell:>2}" for cell in row))
|
||||
|
||||
|
||||
def demo():
|
||||
"""演示函数"""
|
||||
# 创建示例迷宫
|
||||
demo_maze = [
|
||||
['s', '0', 'g5', '1', 't3'],
|
||||
['0', '1', '0', '0', 'g2'],
|
||||
['g3', '0', '1', 't2', '0'],
|
||||
['0', 't1', '0', '0', 'g4'],
|
||||
['1', '0', 'g1', '0', 'e']
|
||||
]
|
||||
|
||||
print("=== 3x3视野贪心算法演示 ===")
|
||||
print("迷宫说明:")
|
||||
print(" s: 起点, e: 终点")
|
||||
print(" g数字: 金币资源 (正收益)")
|
||||
print(" t数字: 陷阱资源 (负收益)")
|
||||
print(" 0: 可通行路径, 1: 墙壁")
|
||||
print("\\n原始迷宫:")
|
||||
for row in demo_maze:
|
||||
print(' '.join(f"{cell:>2}" for cell in row))
|
||||
|
||||
# 运行算法
|
||||
algorithm = Greedy3x3Algorithm(demo_maze, debug=True)
|
||||
result = algorithm.run()
|
||||
|
||||
# 打印结果
|
||||
algorithm.print_result()
|
||||
|
||||
return algorithm, result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo()
|
@ -1,448 +0,0 @@
|
||||
import copy
|
||||
from collections import deque
|
||||
|
||||
class GreedyResourceCollector:
|
||||
"""
|
||||
基于贪心算法的资源收集器
|
||||
每次移动时选择3x3视野范围内最高价值的资源
|
||||
只能进行上下左右移动
|
||||
"""
|
||||
|
||||
def __init__(self, maze, start_pos=None, end_pos=None):
|
||||
"""
|
||||
初始化贪心资源收集器
|
||||
|
||||
Args:
|
||||
maze: 迷宫地图,2D列表
|
||||
start_pos: 起始位置 (row, col),如果为None则自动寻找
|
||||
end_pos: 目标位置 (row, col),如果为None则自动寻找
|
||||
"""
|
||||
self.original_maze = copy.deepcopy(maze)
|
||||
self.maze = copy.deepcopy(maze)
|
||||
self.rows = len(maze)
|
||||
self.cols = len(maze[0]) if self.rows > 0 else 0
|
||||
|
||||
# 寻找起始位置和目标位置
|
||||
self.start_pos = start_pos or self._find_position('s')
|
||||
self.end_pos = end_pos or self._find_position('e')
|
||||
|
||||
if not self.start_pos:
|
||||
raise ValueError("无法找到起始位置 's'")
|
||||
if not self.end_pos:
|
||||
raise ValueError("无法找到目标位置 'e'")
|
||||
|
||||
self.current_pos = self.start_pos
|
||||
self.path = [self.start_pos]
|
||||
self.collected_resources = []
|
||||
self.total_value = 0
|
||||
self.visited_resources = set()
|
||||
|
||||
print(f"起始位置: {self.start_pos}")
|
||||
print(f"目标位置: {self.end_pos}")
|
||||
|
||||
def _find_position(self, target):
|
||||
"""寻找地图中指定字符的位置"""
|
||||
for i in range(self.rows):
|
||||
for j in range(self.cols):
|
||||
if self.maze[i][j].lower() == target.lower():
|
||||
return (i, j)
|
||||
return None
|
||||
|
||||
def get_3x3_vision(self, pos):
|
||||
"""
|
||||
获取以pos为中心的3x3视野范围内的所有单元格
|
||||
|
||||
Args:
|
||||
pos: 当前位置 (row, col)
|
||||
|
||||
Returns:
|
||||
dict: {(row, col): cell_value} 形式的字典
|
||||
"""
|
||||
row, col = pos
|
||||
vision = {}
|
||||
|
||||
# 遍历3x3范围
|
||||
for dr in range(-1, 2):
|
||||
for dc in range(-1, 2):
|
||||
new_row, new_col = row + dr, col + dc
|
||||
|
||||
# 检查边界
|
||||
if 0 <= new_row < self.rows and 0 <= new_col < self.cols:
|
||||
vision[(new_row, new_col)] = self.maze[new_row][new_col]
|
||||
|
||||
return vision
|
||||
|
||||
def get_adjacent_cells(self, pos):
|
||||
"""
|
||||
获取当前位置的上下左右四个相邻位置
|
||||
|
||||
Args:
|
||||
pos: 当前位置 (row, col)
|
||||
|
||||
Returns:
|
||||
list: 可移动的相邻位置列表
|
||||
"""
|
||||
row, col = pos
|
||||
adjacent = []
|
||||
|
||||
# 上下左右四个方向
|
||||
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
|
||||
|
||||
for dr, dc in directions:
|
||||
new_row, new_col = row + dr, col + dc
|
||||
|
||||
# 检查边界和可移动性
|
||||
if (0 <= new_row < self.rows and
|
||||
0 <= new_col < self.cols and
|
||||
self.can_move_to((new_row, new_col))):
|
||||
adjacent.append((new_row, new_col))
|
||||
|
||||
return adjacent
|
||||
|
||||
def can_move_to(self, pos):
|
||||
"""
|
||||
检查是否可以移动到指定位置
|
||||
|
||||
Args:
|
||||
pos: 目标位置 (row, col)
|
||||
|
||||
Returns:
|
||||
bool: 是否可以移动
|
||||
"""
|
||||
row, col = pos
|
||||
cell = self.maze[row][col]
|
||||
|
||||
# 不能移动到墙壁
|
||||
if cell == '1':
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def evaluate_resource_value(self, cell):
|
||||
"""
|
||||
评估资源的价值
|
||||
|
||||
Args:
|
||||
cell: 单元格内容
|
||||
|
||||
Returns:
|
||||
int: 资源价值,正数表示收益,负数表示损失
|
||||
"""
|
||||
if cell.startswith('g'):
|
||||
# 金币资源,提取数值
|
||||
try:
|
||||
return int(cell[1:])
|
||||
except ValueError:
|
||||
return 0
|
||||
elif cell.startswith('t'):
|
||||
# 陷阱资源,提取数值并取负
|
||||
try:
|
||||
return -int(cell[1:])
|
||||
except ValueError:
|
||||
return 0
|
||||
else:
|
||||
# 其他类型单元格没有资源价值
|
||||
return 0
|
||||
|
||||
def find_best_resource_in_vision(self):
|
||||
"""
|
||||
在3x3视野范围内找到价值最高的可到达资源
|
||||
如果视野内没有正价值资源,则考虑移动到更有利的位置
|
||||
|
||||
Returns:
|
||||
tuple: (最佳资源位置, 资源价值) 或 (None, 0)
|
||||
"""
|
||||
vision = self.get_3x3_vision(self.current_pos)
|
||||
|
||||
best_pos = None
|
||||
best_value = float('-inf')
|
||||
|
||||
# 首先只考虑正价值资源
|
||||
for pos, cell in vision.items():
|
||||
# 跳过已访问的资源
|
||||
if pos in self.visited_resources:
|
||||
continue
|
||||
|
||||
# 跳过当前位置
|
||||
if pos == self.current_pos:
|
||||
continue
|
||||
|
||||
# 跳过不可移动的位置
|
||||
if not self.can_move_to(pos):
|
||||
continue
|
||||
|
||||
# 检查是否为资源
|
||||
value = self.evaluate_resource_value(cell)
|
||||
if value > 0 and value > best_value: # 只考虑正价值资源
|
||||
# 确保可以到达这个位置
|
||||
path_to_resource = self.find_path_to_target(pos)
|
||||
if path_to_resource: # 可以到达
|
||||
best_value = value
|
||||
best_pos = pos
|
||||
|
||||
# 如果视野内没有正价值资源,考虑负价值资源(陷阱)
|
||||
if best_pos is None:
|
||||
for pos, cell in vision.items():
|
||||
if pos in self.visited_resources or pos == self.current_pos:
|
||||
continue
|
||||
if not self.can_move_to(pos):
|
||||
continue
|
||||
|
||||
value = self.evaluate_resource_value(cell)
|
||||
if value < 0 and value > best_value: # 选择损失最小的陷阱
|
||||
path_to_resource = self.find_path_to_target(pos)
|
||||
if path_to_resource:
|
||||
best_value = value
|
||||
best_pos = pos
|
||||
|
||||
# 如果视野内完全没有资源,寻找最近的正价值资源
|
||||
if best_pos is None:
|
||||
best_pos, best_value = self.find_nearest_valuable_resource()
|
||||
|
||||
return best_pos, best_value if best_pos else 0
|
||||
|
||||
def find_nearest_valuable_resource(self):
|
||||
"""
|
||||
在整个地图上寻找最近的高价值正资源
|
||||
|
||||
Returns:
|
||||
tuple: (最佳资源位置, 资源价值) 或 (None, 0)
|
||||
"""
|
||||
best_pos = None
|
||||
best_score = float('-inf')
|
||||
|
||||
for i in range(self.rows):
|
||||
for j in range(self.cols):
|
||||
pos = (i, j)
|
||||
cell = self.maze[i][j]
|
||||
|
||||
# 跳过已访问的资源
|
||||
if pos in self.visited_resources:
|
||||
continue
|
||||
|
||||
# 跳过当前位置
|
||||
if pos == self.current_pos:
|
||||
continue
|
||||
|
||||
# 检查是否为正价值资源
|
||||
value = self.evaluate_resource_value(cell)
|
||||
if value > 0: # 只考虑正价值资源
|
||||
# 计算到达该资源的路径
|
||||
path_to_resource = self.find_path_to_target(pos)
|
||||
if path_to_resource:
|
||||
# 计算性价比:价值/距离
|
||||
distance = len(path_to_resource)
|
||||
score = value / distance
|
||||
|
||||
if score > best_score:
|
||||
best_score = score
|
||||
best_pos = pos
|
||||
|
||||
if best_pos:
|
||||
value = self.evaluate_resource_value(self.maze[best_pos[0]][best_pos[1]])
|
||||
return best_pos, value
|
||||
|
||||
return None, 0
|
||||
|
||||
def find_path_to_target(self, target_pos):
|
||||
"""
|
||||
使用BFS找到到目标位置的最短路径
|
||||
|
||||
Args:
|
||||
target_pos: 目标位置 (row, col)
|
||||
|
||||
Returns:
|
||||
list: 从当前位置到目标位置的路径(不包含当前位置)
|
||||
"""
|
||||
if self.current_pos == target_pos:
|
||||
return []
|
||||
|
||||
queue = deque([(self.current_pos, [])])
|
||||
visited = {self.current_pos}
|
||||
|
||||
while queue:
|
||||
pos, path = queue.popleft()
|
||||
|
||||
# 获取相邻位置
|
||||
for next_pos in self.get_adjacent_cells(pos):
|
||||
if next_pos in visited:
|
||||
continue
|
||||
|
||||
new_path = path + [next_pos]
|
||||
|
||||
# 找到目标
|
||||
if next_pos == target_pos:
|
||||
return new_path
|
||||
|
||||
visited.add(next_pos)
|
||||
queue.append((next_pos, new_path))
|
||||
|
||||
return [] # 无法到达
|
||||
|
||||
def collect_resource(self, pos):
|
||||
"""
|
||||
收集指定位置的资源
|
||||
|
||||
Args:
|
||||
pos: 资源位置 (row, col)
|
||||
"""
|
||||
row, col = pos
|
||||
cell = self.maze[row][col]
|
||||
value = self.evaluate_resource_value(cell)
|
||||
|
||||
if value != 0:
|
||||
self.collected_resources.append({
|
||||
'position': pos,
|
||||
'type': cell,
|
||||
'value': value
|
||||
})
|
||||
self.total_value += value
|
||||
self.visited_resources.add(pos)
|
||||
|
||||
print(f"收集资源: 位置{pos}, 类型{cell}, 价值{value}, 总价值{self.total_value}")
|
||||
|
||||
def run_greedy_collection(self):
|
||||
"""
|
||||
运行贪心资源收集算法
|
||||
|
||||
Returns:
|
||||
dict: 包含路径、收集的资源等信息
|
||||
"""
|
||||
print("开始贪心资源收集...")
|
||||
|
||||
while True:
|
||||
# 在3x3视野内寻找最佳资源
|
||||
best_resource_pos, best_value = self.find_best_resource_in_vision()
|
||||
|
||||
if best_resource_pos is None:
|
||||
print("视野内没有更多资源可收集")
|
||||
break
|
||||
|
||||
print(f"发现最佳资源: 位置{best_resource_pos}, 价值{best_value}")
|
||||
|
||||
# 计算到最佳资源的路径
|
||||
path_to_resource = self.find_path_to_target(best_resource_pos)
|
||||
|
||||
if not path_to_resource:
|
||||
print(f"无法到达资源位置{best_resource_pos}")
|
||||
self.visited_resources.add(best_resource_pos) # 标记为无法到达
|
||||
continue
|
||||
|
||||
# 移动到资源位置
|
||||
for next_pos in path_to_resource:
|
||||
self.current_pos = next_pos
|
||||
self.path.append(next_pos)
|
||||
print(f"移动到: {next_pos}")
|
||||
|
||||
# 收集资源
|
||||
self.collect_resource(best_resource_pos)
|
||||
|
||||
print("资源收集完成!")
|
||||
return self.get_collection_result()
|
||||
|
||||
def get_collection_result(self):
|
||||
"""
|
||||
获取收集结果
|
||||
|
||||
Returns:
|
||||
dict: 包含路径、资源、统计信息的字典
|
||||
"""
|
||||
return {
|
||||
'path': self.path.copy(),
|
||||
'collected_resources': self.collected_resources.copy(),
|
||||
'total_value': self.total_value,
|
||||
'total_moves': len(self.path) - 1,
|
||||
'resources_count': len(self.collected_resources),
|
||||
'start_pos': self.start_pos,
|
||||
'end_pos': self.end_pos,
|
||||
'final_pos': self.current_pos
|
||||
}
|
||||
|
||||
def print_result_summary(self):
|
||||
"""打印收集结果摘要"""
|
||||
result = self.get_collection_result()
|
||||
|
||||
print("\n=== 贪心资源收集结果摘要 ===")
|
||||
print(f"起始位置: {result['start_pos']}")
|
||||
print(f"最终位置: {result['final_pos']}")
|
||||
print(f"总移动步数: {result['total_moves']}")
|
||||
print(f"收集资源数量: {result['resources_count']}")
|
||||
print(f"资源总价值: {result['total_value']}")
|
||||
|
||||
print("\n收集的资源详情:")
|
||||
for i, resource in enumerate(result['collected_resources'], 1):
|
||||
print(f" {i}. 位置{resource['position']}: {resource['type']} (价值: {resource['value']})")
|
||||
|
||||
print(f"\n完整移动路径: {' -> '.join(map(str, result['path']))}")
|
||||
|
||||
def visualize_path_on_maze(self):
|
||||
"""
|
||||
在迷宫上可视化移动路径
|
||||
|
||||
Returns:
|
||||
list: 标记了路径的迷宫副本
|
||||
"""
|
||||
visual_maze = copy.deepcopy(self.original_maze)
|
||||
|
||||
# 标记路径
|
||||
for i, pos in enumerate(self.path):
|
||||
row, col = pos
|
||||
if pos == self.start_pos:
|
||||
visual_maze[row][col] = 'S' # 起点
|
||||
elif pos == self.end_pos:
|
||||
visual_maze[row][col] = 'E' # 终点
|
||||
elif pos in [r['position'] for r in self.collected_resources]:
|
||||
# 已收集的资源位置
|
||||
visual_maze[row][col] = '*'
|
||||
else:
|
||||
# 路径点
|
||||
visual_maze[row][col] = str(i % 10)
|
||||
|
||||
return visual_maze
|
||||
|
||||
def print_visual_maze(self):
|
||||
"""打印可视化的迷宫"""
|
||||
visual_maze = self.visualize_path_on_maze()
|
||||
|
||||
print("\n=== 路径可视化迷宫 ===")
|
||||
print("S: 起点, E: 终点, *: 已收集资源, 数字: 路径步骤")
|
||||
for row in visual_maze:
|
||||
print(' '.join(f"{cell:>2}" for cell in row))
|
||||
|
||||
|
||||
def demo_greedy_resource_collection():
|
||||
"""演示贪心资源收集算法"""
|
||||
|
||||
# 创建一个示例迷宫
|
||||
demo_maze = [
|
||||
['s', '0', 'g5', '1', 't3'],
|
||||
['0', '1', '0', '0', 'g2'],
|
||||
['g3', '0', '1', 't2', '0'],
|
||||
['0', 't1', '0', '0', 'g4'],
|
||||
['1', '0', 'g1', '0', 'e']
|
||||
]
|
||||
|
||||
print("=== 贪心资源收集算法演示 ===")
|
||||
print("迷宫说明:")
|
||||
print(" s: 起点, e: 终点")
|
||||
print(" g数字: 金币资源 (正收益)")
|
||||
print(" t数字: 陷阱资源 (负收益)")
|
||||
print(" 0: 可通行路径, 1: 墙壁")
|
||||
print("\n原始迷宫:")
|
||||
for row in demo_maze:
|
||||
print(' '.join(f"{cell:>2}" for cell in row))
|
||||
|
||||
# 创建贪心收集器并运行
|
||||
collector = GreedyResourceCollector(demo_maze)
|
||||
result = collector.run_greedy_collection()
|
||||
|
||||
# 打印结果
|
||||
collector.print_result_summary()
|
||||
collector.print_visual_maze()
|
||||
|
||||
return collector, result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 运行演示
|
||||
collector, result = demo_greedy_resource_collection()
|
1
main.py
1
main.py
@ -7,7 +7,6 @@ from draw import Button, Toast
|
||||
from save_ui import SaveLoadUI
|
||||
from boss_fight_ui import BossFightUI
|
||||
from mechanism_ui import MechanismUI
|
||||
from greedy_3x3_algorithm import Greedy3x3Algorithm
|
||||
from config import *
|
||||
import sys
|
||||
import os
|
||||
|
1
maze.py
1
maze.py
@ -3,7 +3,6 @@ from maze_generator import MazeGenerator
|
||||
from SourceCollector import SourceCollector
|
||||
from tanxin import *
|
||||
from simple_save_manager import simple_save_manager
|
||||
from greedy_3x3_algorithm import Greedy3x3Algorithm
|
||||
from config import UI_WIDTH
|
||||
import time
|
||||
import random
|
||||
|
389
tanxin.py
389
tanxin.py
@ -50,6 +50,9 @@ class Greedy3x3ResourceCollector:
|
||||
self.oscillation_detection = [] # 用于检测来回走动的历史
|
||||
self.max_oscillation_length = 6 # 检测来回走动的最大长度
|
||||
|
||||
# 预处理每个点到终点的距离
|
||||
self.distance_to_end = self._calculate_distance_to_end()
|
||||
|
||||
print(f"3x3视野贪心算法初始化")
|
||||
print(f"起始位置: {self.start}")
|
||||
print(f"目标位置: {self.end}")
|
||||
@ -58,7 +61,8 @@ class Greedy3x3ResourceCollector:
|
||||
"""寻找地图中指定字符的位置,返回(x, y)格式"""
|
||||
for y in range(self.rows):
|
||||
for x in range(self.cols):
|
||||
if self.map_data[y][x].lower() == target.lower():
|
||||
cell_value = str(self.map_data[y][x]).lower()
|
||||
if cell_value.startswith(target.lower()):
|
||||
return (x, y)
|
||||
return None
|
||||
|
||||
@ -160,14 +164,16 @@ class Greedy3x3ResourceCollector:
|
||||
|
||||
def find_best_resource_in_3x3_vision(self):
|
||||
"""
|
||||
在3x3视野内寻找最佳资源
|
||||
优先级:金币 > 未走过 > 走过的路(优先很久之前走过的路) > 墙/陷阱
|
||||
在3x3视野内寻找最佳资源,新的优先级顺序:
|
||||
1. 金币(优先直接相邻,也考虑对角线上可通过两步到达的)
|
||||
2. 空地(优先离终点更近的)
|
||||
3. boss或机关
|
||||
4. 陷阱(尽可能减少损失)
|
||||
5. 墙壁不考虑
|
||||
|
||||
加入死胡同检测和回溯机制
|
||||
"""
|
||||
x, y = self.current_pos
|
||||
best_pos = None
|
||||
best_value = float('-inf')
|
||||
best_visited_time = float('inf')
|
||||
|
||||
# 更新当前位置的访问次数
|
||||
self.position_visit_count[self.current_pos] = self.position_visit_count.get(self.current_pos, 0) + 1
|
||||
@ -233,19 +239,19 @@ class Greedy3x3ResourceCollector:
|
||||
if least_visited:
|
||||
return least_visited, 0 # 访问次数最少的位置,价值为0
|
||||
|
||||
# 在3x3视野内寻找最佳位置
|
||||
# 按照新的优先级在3x3视野内寻找最佳位置
|
||||
# 1. 收集相邻和对角线上的所有单元格
|
||||
adjacent_cells = [] # 相邻的单元格 [(pos, cell_type, value)]
|
||||
diagonal_cells = [] # 对角线上的单元格 [(pos, cell_type, value, can_reach)]
|
||||
|
||||
for i in range(-1, 2):
|
||||
for j in range(-1, 2):
|
||||
# 跳过自身和对角线位置
|
||||
if (i == 0 and j == 0) or (i != 0 and j != 0):
|
||||
continue
|
||||
|
||||
nx, ny = x + i, y + j
|
||||
|
||||
# 检查位置是否在地图范围内
|
||||
if 0 <= nx < self.cols and 0 <= ny < self.rows:
|
||||
cell = self.map_data[ny][nx]
|
||||
pos = (nx, ny)
|
||||
cell = self.map_data[ny][nx]
|
||||
|
||||
# 检查是否是墙,不能走
|
||||
if cell == '1':
|
||||
@ -253,47 +259,115 @@ class Greedy3x3ResourceCollector:
|
||||
|
||||
# 计算资源价值
|
||||
value = self.evaluate_resource_value(cell)
|
||||
cell_type = self._get_cell_type(cell)
|
||||
|
||||
# 检查是否已经走过这个位置
|
||||
is_visited = pos in self.explored_positions
|
||||
visited_time = self.position_visit_count.get(pos, 0)
|
||||
# 相邻位置(上下左右)
|
||||
if i == 0 or j == 0:
|
||||
if i != 0 or j != 0: # 排除自身位置
|
||||
adjacent_cells.append((pos, cell_type, value))
|
||||
# 对角线位置
|
||||
else:
|
||||
# 判断是否可以两步到达
|
||||
can_reach = self._can_reach_diagonal_coin(self.current_pos, pos)
|
||||
diagonal_cells.append((pos, cell_type, value, can_reach))
|
||||
|
||||
# 计算探索潜力
|
||||
exploration_potential = self.calculate_exploration_potential(pos)
|
||||
# 2. 优先级1:查找相邻的金币
|
||||
adjacent_coins = [(pos, value) for pos, cell_type, value in adjacent_cells
|
||||
if cell_type == 'gold' and value > 0]
|
||||
|
||||
# 优先级计算逻辑
|
||||
# 1. 金币优先
|
||||
if value > 0:
|
||||
if (value > best_value or
|
||||
(value == best_value and
|
||||
((not is_visited and best_visited_time > 0) or
|
||||
(is_visited and visited_time < best_visited_time)))):
|
||||
best_value = value
|
||||
best_pos = pos
|
||||
best_visited_time = visited_time if is_visited else 0
|
||||
# 2. 没有金币,选择未走过的路
|
||||
elif not is_visited:
|
||||
if best_value <= 0 and (best_visited_time > 0 or exploration_potential > best_value):
|
||||
best_value = exploration_potential
|
||||
best_pos = pos
|
||||
best_visited_time = 0
|
||||
# 3. 如果都走过了,选择走过次数最少的路
|
||||
elif is_visited and visited_time < best_visited_time:
|
||||
if best_value <= 0:
|
||||
best_value = -visited_time # 负值,访问次数越少越好
|
||||
best_pos = pos
|
||||
best_visited_time = visited_time
|
||||
if adjacent_coins:
|
||||
# 如果有多个金币,选择价值最高的
|
||||
best_coin = max(adjacent_coins, key=lambda x: x[1])
|
||||
return best_coin
|
||||
|
||||
# 3. 优先级2:查找可达的对角线上的金币
|
||||
diagonal_coins = [(pos, value) for pos, cell_type, value, can_reach in diagonal_cells
|
||||
if cell_type == 'gold' and value > 0 and can_reach]
|
||||
|
||||
if diagonal_coins:
|
||||
# 如果有多个可达的对角线金币,选择价值最高的
|
||||
best_diag_coin = max(diagonal_coins, key=lambda x: x[1])
|
||||
# 计算到达这个对角线金币的两步路径中的第一步
|
||||
dx, dy = best_diag_coin[0]
|
||||
step_x = 1 if dx > x else -1
|
||||
step_y = 1 if dy > y else -1
|
||||
|
||||
# 检查两种可能路径的第一步
|
||||
path1_pos = (x + step_x, y)
|
||||
path2_pos = (x, y + step_y)
|
||||
|
||||
# 选择离终点更近的路径
|
||||
dist1 = self.distance_to_end.get(path1_pos, float('inf'))
|
||||
dist2 = self.distance_to_end.get(path2_pos, float('inf'))
|
||||
|
||||
if dist1 <= dist2 and self.can_move_to(path1_pos):
|
||||
return path1_pos, 0
|
||||
elif self.can_move_to(path2_pos):
|
||||
return path2_pos, 0
|
||||
|
||||
# 4. 优先级3:查找空地,优先选择离终点更近的
|
||||
empty_spaces = [(pos, self.distance_to_end.get(pos, float('inf')))
|
||||
for pos, cell_type, _ in adjacent_cells
|
||||
if cell_type == 'empty']
|
||||
|
||||
if empty_spaces:
|
||||
# 选择离终点最近的空地
|
||||
best_empty = min(empty_spaces, key=lambda x: x[1])
|
||||
return best_empty[0], 0
|
||||
|
||||
# 5. 优先级4:boss或机关
|
||||
mechanism_positions = [(pos, value) for pos, cell_type, value in adjacent_cells
|
||||
if cell_type in ['boss', 'mechanism']]
|
||||
|
||||
if mechanism_positions:
|
||||
# 选择任意一个boss或机关位置
|
||||
return mechanism_positions[0][0], mechanism_positions[0][1]
|
||||
|
||||
# 6. 优先级5:陷阱,尽可能减少损失
|
||||
trap_positions = [(pos, value) for pos, cell_type, value in adjacent_cells
|
||||
if cell_type == 'trap']
|
||||
|
||||
if trap_positions:
|
||||
# 选择损失最小的陷阱(value是负数,所以用max)
|
||||
best_trap = max(trap_positions, key=lambda x: x[1])
|
||||
return best_trap
|
||||
|
||||
# 如果找不到合适的位置,就选择任意一个可行的相邻位置
|
||||
if best_pos is None:
|
||||
for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
|
||||
nx, ny = x + dx, y + dy
|
||||
if (0 <= nx < self.cols and 0 <= ny < self.rows and
|
||||
self.map_data[ny][nx] != '1'): # 使用'1'表示墙壁
|
||||
best_pos = (nx, ny)
|
||||
break
|
||||
for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
|
||||
nx, ny = x + dx, y + dy
|
||||
if (0 <= nx < self.cols and 0 <= ny < self.rows and
|
||||
self.map_data[ny][nx] != '1'): # 使用'1'表示墙壁
|
||||
return (nx, ny), 0
|
||||
|
||||
return best_pos, best_value if best_value > float('-inf') else 0
|
||||
# 如果实在没有可行位置,返回None
|
||||
return None, 0
|
||||
|
||||
def _get_cell_type(self, cell):
|
||||
"""
|
||||
获取单元格类型
|
||||
|
||||
Args:
|
||||
cell: 单元格内容
|
||||
|
||||
Returns:
|
||||
str: 'gold', 'trap', 'boss', 'mechanism', 'empty', 'wall', 'start', 'end'
|
||||
"""
|
||||
if cell.startswith('g'):
|
||||
return 'gold'
|
||||
elif cell.startswith('t'):
|
||||
return 'trap'
|
||||
elif cell.startswith('b'):
|
||||
return 'boss'
|
||||
elif cell.startswith('l'):
|
||||
return 'mechanism'
|
||||
elif cell == 's':
|
||||
return 'start'
|
||||
elif cell == 'e':
|
||||
return 'end'
|
||||
elif cell == '1':
|
||||
return 'wall'
|
||||
else:
|
||||
return 'empty' # 包括 '0' 和其他可通行的单元格
|
||||
|
||||
def find_exploration_target(self):
|
||||
"""
|
||||
@ -623,6 +697,227 @@ class Greedy3x3ResourceCollector:
|
||||
|
||||
return potential
|
||||
|
||||
def _calculate_distance_to_end(self):
|
||||
"""
|
||||
使用BFS预处理计算每个点到终点的距离
|
||||
返回字典 {(x, y): distance}
|
||||
"""
|
||||
distances = {}
|
||||
queue = deque([(self.end, 0)]) # (位置, 距离)
|
||||
visited = {self.end}
|
||||
|
||||
# 方向:上、下、左、右
|
||||
directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
|
||||
|
||||
while queue:
|
||||
(x, y), dist = queue.popleft()
|
||||
distances[(x, y)] = dist
|
||||
|
||||
# 检查四个方向
|
||||
for dx, dy in directions:
|
||||
nx, ny = x + dx, y + dy
|
||||
|
||||
# 检查边界和可行性
|
||||
if (0 <= nx < self.cols and
|
||||
0 <= ny < self.rows and
|
||||
self.map_data[ny][nx] != '1' and # 不是墙
|
||||
(nx, ny) not in visited):
|
||||
|
||||
visited.add((nx, ny))
|
||||
queue.append(((nx, ny), dist + 1))
|
||||
|
||||
print(f"已预处理完成从终点的距离计算,可达点数量: {len(distances)}")
|
||||
return distances
|
||||
|
||||
def _can_reach_diagonal_coin(self, current_pos, diagonal_pos):
|
||||
"""
|
||||
检查对角线上的金币是否可通过两步到达
|
||||
|
||||
Args:
|
||||
current_pos: 当前位置 (x, y)
|
||||
diagonal_pos: 对角线上的金币位置 (x, y)
|
||||
|
||||
Returns:
|
||||
bool: 是否可以通过两步到达
|
||||
"""
|
||||
cx, cy = current_pos
|
||||
dx, dy = diagonal_pos
|
||||
|
||||
# 计算方向
|
||||
step_x = 1 if dx > cx else -1
|
||||
step_y = 1 if dy > cy else -1
|
||||
|
||||
# 检查两种可能的两步路径
|
||||
path1 = [(cx + step_x, cy), diagonal_pos] # 先横后纵
|
||||
path2 = [(cx, cy + step_y), diagonal_pos] # 先纵后横
|
||||
|
||||
# 检查路径1是否可行
|
||||
path1_valid = True
|
||||
for x, y in path1:
|
||||
if not (0 <= x < self.cols and 0 <= y < self.rows and self.map_data[y][x] != '1'):
|
||||
path1_valid = False
|
||||
break
|
||||
|
||||
# 检查路径2是否可行
|
||||
path2_valid = True
|
||||
for x, y in path2:
|
||||
if not (0 <= x < self.cols and 0 <= y < self.rows and self.map_data[y][x] != '1'):
|
||||
path2_valid = False
|
||||
break
|
||||
|
||||
return path1_valid or path2_valid
|
||||
|
||||
def add_path_to_map(self):
|
||||
"""
|
||||
将路径标记到地图上
|
||||
|
||||
Returns:
|
||||
list: 标记了路径的地图
|
||||
"""
|
||||
marked_map = copy.deepcopy(self.original_map)
|
||||
|
||||
# 标记起点和终点
|
||||
sx, sy = self.start
|
||||
ex, ey = self.end
|
||||
marked_map[sy][sx] = 'S'
|
||||
marked_map[ey][ex] = 'E'
|
||||
|
||||
# 标记路径
|
||||
for i, (x, y) in enumerate(self.path):
|
||||
# 跳过起点和终点
|
||||
if (x, y) == self.start or (x, y) == self.end:
|
||||
continue
|
||||
|
||||
# 检查是否是资源位置
|
||||
cell = self.original_map[y][x]
|
||||
if (x, y) in self.visited_resources:
|
||||
marked_map[y][x] = '*' # 已收集资源
|
||||
else:
|
||||
# 只有不是特殊位置才标记为路径
|
||||
if not (cell.startswith('g') or cell.startswith('t') or
|
||||
cell.startswith('b') or cell.startswith('l')):
|
||||
marked_map[y][x] = '.' # 路径
|
||||
|
||||
return marked_map
|
||||
|
||||
|
||||
"""
|
||||
传统的贪心路径寻找算法
|
||||
"""
|
||||
|
||||
class GreedyPlayer:
|
||||
"""
|
||||
传统贪心路径寻找算法
|
||||
"""
|
||||
|
||||
def __init__(self, map_data):
|
||||
"""
|
||||
初始化贪心玩家
|
||||
|
||||
Args:
|
||||
map_data: 迷宫地图,2D列表 (注意:这里是[y][x]格式)
|
||||
"""
|
||||
self.map_data = copy.deepcopy(map_data)
|
||||
self.rows = len(map_data)
|
||||
self.cols = len(map_data[0]) if self.rows > 0 else 0
|
||||
|
||||
# 寻找起点和终点
|
||||
self.start = None
|
||||
self.end = None
|
||||
for y in range(self.rows):
|
||||
for x in range(self.cols):
|
||||
cell_value = str(self.map_data[y][x]).lower()
|
||||
if cell_value.startswith('s'):
|
||||
self.start = (x, y)
|
||||
elif cell_value.startswith('e'):
|
||||
self.end = (x, y)
|
||||
|
||||
if not self.start or not self.end:
|
||||
raise ValueError("无法找到起点或终点")
|
||||
|
||||
self.path = []
|
||||
self.marked_map = copy.deepcopy(map_data)
|
||||
self.total_reward = 0
|
||||
|
||||
def find_path(self):
|
||||
"""
|
||||
使用传统贪心算法寻找路径
|
||||
"""
|
||||
current = self.start
|
||||
self.path = [current]
|
||||
visited = set([current])
|
||||
|
||||
while current != self.end:
|
||||
x, y = current
|
||||
best_move = None
|
||||
best_value = float('-inf')
|
||||
|
||||
# 检查四个方向
|
||||
for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
|
||||
nx, ny = x + dx, y + dy
|
||||
|
||||
if (0 <= nx < self.cols and 0 <= ny < self.rows and
|
||||
str(self.map_data[ny][nx]) != '1' and
|
||||
(nx, ny) not in visited):
|
||||
|
||||
# 计算移动价值
|
||||
cell = str(self.map_data[ny][nx])
|
||||
value = 0
|
||||
|
||||
# 终点最高价值
|
||||
if cell.lower().startswith('e'):
|
||||
value = float('inf')
|
||||
# 金币为正价值
|
||||
elif cell.lower().startswith('g'):
|
||||
try:
|
||||
value = int(cell[1:])
|
||||
except ValueError:
|
||||
value = 1
|
||||
# 陷阱为负价值
|
||||
elif cell.lower().startswith('t'):
|
||||
try:
|
||||
value = -int(cell[1:])
|
||||
except ValueError:
|
||||
value = -1
|
||||
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_move = (nx, ny)
|
||||
|
||||
if best_move:
|
||||
# 更新当前位置
|
||||
current = best_move
|
||||
self.path.append(current)
|
||||
visited.add(current)
|
||||
|
||||
# 收集资源
|
||||
x, y = current
|
||||
cell = str(self.map_data[y][x])
|
||||
if cell.lower().startswith('g'):
|
||||
try:
|
||||
self.total_reward += int(cell[1:])
|
||||
except ValueError:
|
||||
self.total_reward += 1
|
||||
elif cell.lower().startswith('t'):
|
||||
try:
|
||||
self.total_reward -= int(cell[1:])
|
||||
except ValueError:
|
||||
self.total_reward -= 1
|
||||
|
||||
# 标记路径
|
||||
if not cell.lower().startswith('e'):
|
||||
self.marked_map[y][x] = '.'
|
||||
else:
|
||||
# 无法继续移动
|
||||
break
|
||||
|
||||
return self.path
|
||||
|
||||
def get_total_reward(self):
|
||||
"""
|
||||
获取收集到的总奖励
|
||||
"""
|
||||
return self.total_reward
|
||||
|
||||
# 使用示例
|
||||
def main():
|
||||
|
Loading…
Reference in New Issue
Block a user