221 lines
7.9 KiB
Python
221 lines
7.9 KiB
Python
import csv
|
||
import os
|
||
from datetime import datetime
|
||
from config import DEFAULT_MAZE_FILE
|
||
|
||
class SimpleSaveManager:
|
||
"""简化的存档管理器 - 只保存CSV格式的迷宫文件"""
|
||
|
||
def __init__(self):
|
||
self.save_directory = "saves"
|
||
self.ensure_save_directory()
|
||
|
||
def ensure_save_directory(self):
|
||
"""确保存档目录存在"""
|
||
if not os.path.exists(self.save_directory):
|
||
os.makedirs(self.save_directory)
|
||
|
||
def save_maze_with_path(self, maze_instance, save_name=None):
|
||
"""
|
||
保存包含路径信息的迷宫到CSV文件
|
||
|
||
Args:
|
||
maze_instance: Maze类的实例
|
||
save_name: 存档名称,如果为None则使用时间戳
|
||
|
||
Returns:
|
||
str: 保存的文件路径
|
||
"""
|
||
if save_name is None:
|
||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||
save_name = f"maze_save_{timestamp}"
|
||
|
||
# 确保文件名以.csv结尾
|
||
if not save_name.endswith('.csv'):
|
||
save_name += '.csv'
|
||
|
||
save_file = os.path.join(self.save_directory, save_name)
|
||
|
||
try:
|
||
# 生成包含路径信息的网格
|
||
path_grid = self.create_path_grid(maze_instance)
|
||
|
||
# 保存到CSV文件
|
||
with open(save_file, 'w', newline='', encoding='utf-8') as f:
|
||
writer = csv.writer(f)
|
||
for row in path_grid:
|
||
writer.writerow(row)
|
||
|
||
print(f"迷宫已保存至: {os.path.abspath(save_file)}")
|
||
return save_file
|
||
|
||
except Exception as e:
|
||
print(f"保存失败: {str(e)}")
|
||
return None
|
||
|
||
def create_path_grid(self, maze_instance):
|
||
"""
|
||
创建包含路径信息的网格
|
||
|
||
Args:
|
||
maze_instance: Maze类的实例
|
||
|
||
Returns:
|
||
list: 包含路径信息的二维网格
|
||
"""
|
||
if not maze_instance.generater.maze or not maze_instance.full_path:
|
||
return maze_instance.generater.maze if maze_instance.generater.maze else []
|
||
|
||
# 从原始迷宫开始
|
||
path_grid = [row[:] for row in maze_instance.generater.maze] # 深拷贝
|
||
|
||
# 将完整路径信息添加到网格中
|
||
for idx, (y, x) in enumerate(maze_instance.full_path):
|
||
current_cell = path_grid[y][x]
|
||
path_info = f"p{idx + 1}" # 路径编号从1开始
|
||
|
||
if current_cell.startswith('s'):
|
||
# 起点:保留起点标记,但也添加路径信息
|
||
path_grid[y][x] = f"s{path_info}"
|
||
elif current_cell.startswith('e'):
|
||
# 终点:保留终点标记,但也添加路径信息
|
||
path_grid[y][x] = f"e{path_info}"
|
||
elif current_cell.startswith('g'):
|
||
# 金币:g10p31 格式
|
||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||
elif current_cell.startswith('t'):
|
||
# 陷阱:t19p31 格式
|
||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||
elif current_cell.startswith('l'):
|
||
# 机关:l24p31 格式
|
||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||
elif current_cell.startswith('b'):
|
||
# boss:b92p31 格式
|
||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||
elif current_cell == '0':
|
||
# 空地:直接是p31
|
||
path_grid[y][x] = path_info
|
||
else:
|
||
# 其他情况也添加路径信息
|
||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||
|
||
return path_grid
|
||
|
||
def load_maze_from_csv(self, csv_file):
|
||
"""
|
||
从CSV文件加载迷宫,解析路径信息
|
||
|
||
Args:
|
||
csv_file: CSV文件路径
|
||
|
||
Returns:
|
||
dict: 包含迷宫数据和路径信息的字典
|
||
"""
|
||
try:
|
||
with open(csv_file, 'r', newline='', encoding='utf-8') as f:
|
||
reader = csv.reader(f)
|
||
grid = [list(row) for row in reader]
|
||
|
||
# 解析路径信息
|
||
path_data = self.extract_path_from_grid(grid)
|
||
|
||
# 创建原始迷宫(移除路径信息)
|
||
original_grid = self.create_original_grid(grid)
|
||
|
||
result = {
|
||
'original_grid': original_grid,
|
||
'path_grid': grid,
|
||
'path_sequence': path_data['path_sequence'],
|
||
'path_positions': path_data['path_positions']
|
||
}
|
||
|
||
print(f"成功从 {os.path.abspath(csv_file)} 加载迷宫")
|
||
print(f"路径长度: {len(path_data['path_sequence'])}")
|
||
return result
|
||
|
||
except Exception as e:
|
||
print(f"加载失败: {str(e)}")
|
||
return None
|
||
|
||
def extract_path_from_grid(self, grid):
|
||
"""从网格中提取路径信息"""
|
||
path_positions = {} # {step_number: (y, x)}
|
||
|
||
for y in range(len(grid)):
|
||
for x in range(len(grid[y])):
|
||
cell = grid[y][x]
|
||
|
||
# 查找所有路径信息 p数字
|
||
import re
|
||
# 使用正则表达式找到所有p后跟数字的模式
|
||
path_matches = re.findall(r'p(\d+)', cell)
|
||
|
||
for path_match in path_matches:
|
||
try:
|
||
step_number = int(path_match)
|
||
path_positions[step_number] = (y, x)
|
||
except ValueError:
|
||
continue
|
||
|
||
# 按步数排序创建路径序列
|
||
path_sequence = []
|
||
for step in sorted(path_positions.keys()):
|
||
path_sequence.append(path_positions[step])
|
||
|
||
return {
|
||
'path_sequence': path_sequence,
|
||
'path_positions': path_positions
|
||
}
|
||
|
||
def create_original_grid(self, path_grid):
|
||
"""从包含路径的网格创建原始迷宫网格"""
|
||
original_grid = []
|
||
|
||
for row in path_grid:
|
||
original_row = []
|
||
for cell in row:
|
||
# 移除路径信息,恢复原始状态
|
||
if 'p' in cell:
|
||
p_index = cell.find('p')
|
||
original_cell = cell[:p_index] if p_index > 0 else '0'
|
||
else:
|
||
original_cell = cell
|
||
original_row.append(original_cell)
|
||
original_grid.append(original_row)
|
||
|
||
return original_grid
|
||
|
||
def get_save_list(self):
|
||
"""获取所有CSV存档文件列表"""
|
||
saves = []
|
||
if os.path.exists(self.save_directory):
|
||
for filename in os.listdir(self.save_directory):
|
||
if filename.endswith('.csv'):
|
||
file_path = os.path.join(self.save_directory, filename)
|
||
try:
|
||
stat = os.stat(file_path)
|
||
saves.append({
|
||
'filename': filename,
|
||
'path': file_path,
|
||
'name': filename.replace('.csv', ''),
|
||
'save_time': datetime.fromtimestamp(stat.st_mtime).isoformat(),
|
||
'size': stat.st_size
|
||
})
|
||
except:
|
||
continue
|
||
return sorted(saves, key=lambda x: x['save_time'], reverse=True)
|
||
|
||
def delete_save(self, save_file):
|
||
"""删除存档文件"""
|
||
try:
|
||
if os.path.exists(save_file):
|
||
os.remove(save_file)
|
||
print(f"存档已删除: {save_file}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"删除失败: {str(e)}")
|
||
return False
|
||
|
||
# 全局简化存档管理器实例
|
||
simple_save_manager = SimpleSaveManager()
|