143 lines
5.1 KiB
Python
143 lines
5.1 KiB
Python
import json
|
||
import csv
|
||
import os
|
||
from datetime import datetime
|
||
from config import DEFAULT_MAZE_FILE
|
||
|
||
class GameSaveManager:
|
||
"""游戏存档管理器"""
|
||
|
||
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_game_state(self, maze_instance, save_name=None):
|
||
"""
|
||
保存游戏状态,包括迷宫和路径信息
|
||
|
||
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}"
|
||
|
||
# 创建存档数据结构
|
||
save_data = {
|
||
"metadata": {
|
||
"save_name": save_name,
|
||
"save_time": datetime.now().isoformat(),
|
||
"maze_size": maze_instance.size,
|
||
"wall_size": maze_instance.wall_size,
|
||
"maze_display_size": maze_instance.maze_size
|
||
},
|
||
"maze_data": {
|
||
"grid": maze_instance.generater.maze if maze_instance.generater.maze else [],
|
||
"generator_name": maze_instance.generater.name if hasattr(maze_instance.generater, 'name') else "Unknown"
|
||
},
|
||
"path_data": {
|
||
"full_path": maze_instance.full_path,
|
||
"current_step": maze_instance.path_step,
|
||
"is_path_complete": maze_instance.is_path_complete
|
||
}
|
||
}
|
||
|
||
# 保存为JSON文件
|
||
save_file = os.path.join(self.save_directory, f"{save_name}.json")
|
||
try:
|
||
with open(save_file, 'w', encoding='utf-8') as f:
|
||
json.dump(save_data, f, indent=2, ensure_ascii=False)
|
||
|
||
# 同时保存CSV格式的迷宫数据(兼容性)
|
||
csv_file = os.path.join(self.save_directory, f"{save_name}_maze.csv")
|
||
self.save_maze_csv(maze_instance.generater.maze, csv_file)
|
||
|
||
print(f"游戏状态已保存至: {os.path.abspath(save_file)}")
|
||
return save_file
|
||
|
||
except Exception as e:
|
||
print(f"保存失败: {str(e)}")
|
||
return None
|
||
|
||
def load_game_state(self, save_file):
|
||
"""
|
||
加载游戏状态
|
||
|
||
Args:
|
||
save_file: 存档文件路径
|
||
|
||
Returns:
|
||
dict: 包含游戏状态的字典,如果加载失败返回None
|
||
"""
|
||
try:
|
||
with open(save_file, 'r', encoding='utf-8') as f:
|
||
save_data = json.load(f)
|
||
|
||
print(f"成功加载存档: {save_data['metadata']['save_name']}")
|
||
print(f"保存时间: {save_data['metadata']['save_time']}")
|
||
return save_data
|
||
|
||
except Exception as e:
|
||
print(f"加载失败: {str(e)}")
|
||
return None
|
||
|
||
def save_maze_csv(self, maze_grid, filename):
|
||
"""保存迷宫网格为CSV格式"""
|
||
try:
|
||
with open(filename, 'w', newline='', encoding='utf-8') as f:
|
||
writer = csv.writer(f)
|
||
for row in maze_grid:
|
||
writer.writerow(row)
|
||
return True
|
||
except Exception as e:
|
||
print(f"CSV保存失败: {str(e)}")
|
||
return False
|
||
|
||
def get_save_list(self):
|
||
"""获取所有存档文件列表"""
|
||
saves = []
|
||
if os.path.exists(self.save_directory):
|
||
for filename in os.listdir(self.save_directory):
|
||
if filename.endswith('.json'):
|
||
save_path = os.path.join(self.save_directory, filename)
|
||
try:
|
||
with open(save_path, 'r', encoding='utf-8') as f:
|
||
save_data = json.load(f)
|
||
saves.append({
|
||
'filename': filename,
|
||
'path': save_path,
|
||
'name': save_data['metadata']['save_name'],
|
||
'save_time': save_data['metadata']['save_time'],
|
||
'maze_size': save_data['metadata']['maze_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)
|
||
# 同时删除对应的CSV文件
|
||
csv_file = save_file.replace('.json', '_maze.csv')
|
||
if os.path.exists(csv_file):
|
||
os.remove(csv_file)
|
||
print(f"存档已删除: {save_file}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"删除失败: {str(e)}")
|
||
return False
|
||
|
||
# 全局存档管理器实例
|
||
save_manager = GameSaveManager()
|