支持json存档,并且动态调整UI
This commit is contained in:
parent
67d8e66e57
commit
257c275d73
25
config.py
25
config.py
@ -44,18 +44,19 @@ COLOR_GREEN = (100, 255, 100)
|
||||
COLOR_GOLD = (255, 215, 0)
|
||||
|
||||
# 布局配置
|
||||
def get_button_positions():
|
||||
"""返回按钮位置配置"""
|
||||
control_panel_x = MAZE_SIZE + ((UI_WIDTH - MAZE_SIZE) / 2 - 100)
|
||||
def get_button_positions(maze_display_size=MAZE_SIZE):
|
||||
"""返回按钮位置配置,根据实际迷宫显示尺寸调整"""
|
||||
control_panel_x = maze_display_size + 50
|
||||
|
||||
return {
|
||||
'start_button': (MAZE_SIZE + 50, 0),
|
||||
'save_button': (MAZE_SIZE + 50, 110),
|
||||
'load_button': (MAZE_SIZE + 150, 110),
|
||||
'next_step_button': (MAZE_SIZE + 50, 200),
|
||||
'reset_path_button': (MAZE_SIZE + 200, 200),
|
||||
'auto_play_button': (MAZE_SIZE + 350, 200),
|
||||
'progress_text': (MAZE_SIZE + 50, 270),
|
||||
'hint_text': (MAZE_SIZE + 50, 300),
|
||||
'save_list_area': (MAZE_SIZE + 50, 350, 400, 200) # x, y, width, height
|
||||
'start_button': (control_panel_x, 0),
|
||||
'save_button': (control_panel_x, 110),
|
||||
'load_button': (control_panel_x + 100, 110),
|
||||
'next_step_button': (control_panel_x, 200),
|
||||
'reset_path_button': (control_panel_x + 120, 200),
|
||||
'auto_play_button': (control_panel_x + 250, 200),
|
||||
'progress_text': (control_panel_x, 270),
|
||||
'hint_text': (control_panel_x, 300),
|
||||
'shortcut_text': (control_panel_x, 330),
|
||||
'save_list_area': (control_panel_x, 350, 400, 200) # x, y, width, height
|
||||
}
|
||||
|
170
main.py
170
main.py
@ -27,40 +27,51 @@ def pygameInit(title: str = "pygame"):
|
||||
pygame.font.init()
|
||||
textFont = pygame.font.Font(FONT_FILE, FONT_SIZE)
|
||||
|
||||
def create_buttons(button_positions):
|
||||
"""根据按钮位置创建所有按钮"""
|
||||
# 创建按钮纹理(只需要一次)
|
||||
button_start_texture = pygame.image.load(START_BUTTON_IMAGE).convert_alpha()
|
||||
button_start_texture = pygame.transform.scale(button_start_texture, BUTTON_START_SIZE)
|
||||
|
||||
button_save_texture = pygame.image.load(SAVE_BUTTON_IMAGE).convert_alpha()
|
||||
button_save_texture = pygame.transform.scale(button_save_texture, BUTTON_SAVE_SIZE)
|
||||
|
||||
button_load_texture = pygame.image.load(LOAD_BUTTON_IMAGE).convert_alpha()
|
||||
button_load_texture = pygame.transform.scale(button_load_texture, BUTTON_SAVE_SIZE)
|
||||
|
||||
# 创建按钮对象
|
||||
button_start = Button(pygame.rect.Rect(*button_positions['start_button'], *BUTTON_START_SIZE), button_start_texture)
|
||||
button_save = Button(pygame.rect.Rect(*button_positions['save_button'], *BUTTON_SAVE_SIZE), button_save_texture)
|
||||
button_load = Button(pygame.rect.Rect(*button_positions['load_button'], *BUTTON_SAVE_SIZE), button_load_texture)
|
||||
button_next_step = Button(pygame.rect.Rect(*button_positions['next_step_button'], *BUTTON_CONTROL_SIZE), None)
|
||||
button_reset_path = Button(pygame.rect.Rect(*button_positions['reset_path_button'], *BUTTON_CONTROL_SIZE), None)
|
||||
button_auto_play = Button(pygame.rect.Rect(*button_positions['auto_play_button'], *BUTTON_CONTROL_SIZE), None)
|
||||
|
||||
return {
|
||||
'start': button_start,
|
||||
'save': button_save,
|
||||
'load': button_load,
|
||||
'next_step': button_next_step,
|
||||
'reset_path': button_reset_path,
|
||||
'auto_play': button_auto_play
|
||||
}
|
||||
|
||||
def update_save_ui_positions(save_ui, button_positions):
|
||||
"""更新存档界面的位置"""
|
||||
save_ui.list_area = pygame.Rect(*button_positions['save_list_area'])
|
||||
|
||||
if __name__ == "__main__":
|
||||
pygameInit("maze")
|
||||
maze = Maze(wall_size=WALL_SIZE, maze_size=MAZE_SIZE, file_name=DEFAULT_MAZE_FILE)
|
||||
|
||||
# 加载图片资源
|
||||
# 加载图片资源(将根据需要动态缩放)
|
||||
image_wall = pygame.image.load(WALL_IMAGE).convert_alpha()
|
||||
image_wall = pygame.transform.scale(image_wall, (WALL_SIZE, WALL_SIZE))
|
||||
|
||||
image_coin = pygame.image.load(COIN_IMAGE).convert_alpha()
|
||||
image_coin = pygame.transform.scale(image_coin, (WALL_SIZE, WALL_SIZE))
|
||||
|
||||
image_trap = pygame.image.load(TRAP_IMAGE).convert_alpha()
|
||||
image_trap = pygame.transform.scale(image_trap, (WALL_SIZE, WALL_SIZE))
|
||||
|
||||
# 获取按钮位置配置
|
||||
# 初始按钮位置和按钮
|
||||
button_positions = get_button_positions()
|
||||
|
||||
# 创建按钮
|
||||
button_start_texture = pygame.image.load(START_BUTTON_IMAGE).convert_alpha()
|
||||
button_start_texture = pygame.transform.scale(button_start_texture, BUTTON_START_SIZE)
|
||||
button_start = Button(pygame.rect.Rect(*button_positions['start_button'], *BUTTON_START_SIZE), button_start_texture)
|
||||
|
||||
button_save_texture = pygame.image.load(SAVE_BUTTON_IMAGE).convert_alpha()
|
||||
button_save_texture = pygame.transform.scale(button_save_texture, BUTTON_SAVE_SIZE)
|
||||
button_save = Button(pygame.rect.Rect(*button_positions['save_button'], *BUTTON_SAVE_SIZE), button_save_texture)
|
||||
|
||||
button_load_texture = pygame.image.load(LOAD_BUTTON_IMAGE).convert_alpha()
|
||||
button_load_texture = pygame.transform.scale(button_load_texture, BUTTON_SAVE_SIZE)
|
||||
button_load = Button(pygame.rect.Rect(*button_positions['load_button'], *BUTTON_SAVE_SIZE), button_load_texture)
|
||||
|
||||
# 添加路径控制按钮
|
||||
button_next_step = Button(pygame.rect.Rect(*button_positions['next_step_button'], *BUTTON_CONTROL_SIZE), None)
|
||||
button_reset_path = Button(pygame.rect.Rect(*button_positions['reset_path_button'], *BUTTON_CONTROL_SIZE), None)
|
||||
button_auto_play = Button(pygame.rect.Rect(*button_positions['auto_play_button'], *BUTTON_CONTROL_SIZE), None)
|
||||
buttons = create_buttons(button_positions)
|
||||
|
||||
# 提示信息
|
||||
mes1 = Toast("没有生成迷宫,无法保存", UI_WIDTH, UI_HEIGHT, font=textFont)
|
||||
@ -71,17 +82,29 @@ if __name__ == "__main__":
|
||||
|
||||
# 创建存档界面
|
||||
save_ui = SaveLoadUI(textFont)
|
||||
update_save_ui_positions(save_ui, button_positions)
|
||||
|
||||
# 路径控制变量
|
||||
auto_play = False
|
||||
auto_play_timer = 0
|
||||
auto_play_interval = AUTO_PLAY_INTERVAL
|
||||
|
||||
# 当前显示尺寸跟踪
|
||||
current_display_size = MAZE_SIZE
|
||||
|
||||
running = True
|
||||
while running:
|
||||
clock.tick(FPS) # 限制帧数
|
||||
screen.fill(COLOR_WHITE) # 铺底
|
||||
|
||||
# 检查迷宫显示尺寸是否发生变化,如果变化则更新按钮位置
|
||||
if maze.get_actual_display_size() != current_display_size:
|
||||
current_display_size = maze.get_actual_display_size()
|
||||
button_positions = get_button_positions(current_display_size)
|
||||
buttons = create_buttons(button_positions)
|
||||
update_save_ui_positions(save_ui, button_positions)
|
||||
print(f"UI布局已更新,迷宫显示尺寸: {current_display_size}")
|
||||
|
||||
# 自动播放逻辑
|
||||
if auto_play and len(maze.full_path) > 0:
|
||||
auto_play_timer += 1
|
||||
@ -103,38 +126,67 @@ if __name__ == "__main__":
|
||||
|
||||
# 如果存档界面正在显示,不处理其他按钮事件
|
||||
if not save_ui.show_save_list:
|
||||
button_start.handle_event(event=event)
|
||||
button_save.handle_event(event=event)
|
||||
button_load.handle_event(event=event)
|
||||
button_next_step.handle_event(event=event)
|
||||
button_reset_path.handle_event(event=event)
|
||||
button_auto_play.handle_event(event=event)
|
||||
buttons['start'].handle_event(event=event)
|
||||
buttons['save'].handle_event(event=event)
|
||||
buttons['load'].handle_event(event=event)
|
||||
buttons['next_step'].handle_event(event=event)
|
||||
buttons['reset_path'].handle_event(event=event)
|
||||
buttons['auto_play'].handle_event(event=event)
|
||||
|
||||
if button_start.pressed == True:
|
||||
if buttons['start'].pressed == True:
|
||||
maze.generate()
|
||||
auto_play = False # 生成新迷宫时停止自动播放
|
||||
|
||||
if button_save.pressed == True:
|
||||
if buttons['save'].pressed == True:
|
||||
if len(maze.grid) == 0:
|
||||
mes1.show()
|
||||
else:
|
||||
maze.export_to_csv(DEFAULT_MAZE_FILE)
|
||||
mes2.text = f"迷宫已保存至{DEFAULT_MAZE_FILE}"
|
||||
mes2.show()
|
||||
# 自动保存为JSON格式
|
||||
result = maze.save_game(format_type="json")
|
||||
if result:
|
||||
mes2.text = "迷宫已保存为JSON格式"
|
||||
mes2.show()
|
||||
else:
|
||||
mes5.text = "保存失败"
|
||||
mes5.show()
|
||||
|
||||
if button_load.pressed == True:
|
||||
save_ui.update_save_list(maze)
|
||||
save_ui.toggle_save_list()
|
||||
if buttons['load'].pressed == True:
|
||||
# 直接读取样例JSON文件并生成路径
|
||||
sample_file = "saves/sample.json"
|
||||
if os.path.exists(sample_file):
|
||||
if maze.load_game(sample_file):
|
||||
# 加载成功后重新生成路径
|
||||
if maze.generater.maze:
|
||||
from SourceCollector import SourceCollector
|
||||
maze.source_collector = SourceCollector(maze=maze.generater.maze)
|
||||
maze.source_collector.run()
|
||||
maze.full_path = maze.source_collector.get_path()
|
||||
maze.path_step = 0
|
||||
maze.is_path_complete = False
|
||||
maze.grid = maze.generater.maze # 重置显示网格
|
||||
mes4.text = f"已加载 {sample_file} 并生成路径"
|
||||
mes4.show()
|
||||
auto_play = False
|
||||
else:
|
||||
mes5.text = "加载的迷宫数据无效"
|
||||
mes5.show()
|
||||
else:
|
||||
mes5.text = f"无法加载 {sample_file}"
|
||||
mes5.show()
|
||||
else:
|
||||
# 如果sample.json不存在,则打开存档选择界面
|
||||
save_ui.update_save_list(maze)
|
||||
save_ui.toggle_save_list()
|
||||
|
||||
# 路径控制
|
||||
if button_next_step.pressed == True and len(maze.full_path) > 0:
|
||||
if buttons['next_step'].pressed == True and len(maze.full_path) > 0:
|
||||
maze.next_path_step()
|
||||
|
||||
if button_reset_path.pressed == True and len(maze.full_path) > 0:
|
||||
if buttons['reset_path'].pressed == True and len(maze.full_path) > 0:
|
||||
maze.reset_path()
|
||||
auto_play = False
|
||||
|
||||
if button_auto_play.pressed == True and len(maze.full_path) > 0:
|
||||
if buttons['auto_play'].pressed == True and len(maze.full_path) > 0:
|
||||
auto_play = not auto_play
|
||||
auto_play_timer = 0
|
||||
|
||||
@ -149,10 +201,18 @@ if __name__ == "__main__":
|
||||
auto_play = not auto_play
|
||||
auto_play_timer = 0
|
||||
elif event.key == pygame.K_s and pygame.key.get_pressed()[pygame.K_LCTRL]:
|
||||
# Ctrl+S 保存包含路径的CSV
|
||||
# Ctrl+S 保存包含路径的JSON
|
||||
if len(maze.grid) > 0:
|
||||
result = maze.save_game()
|
||||
result = maze.save_game(format_type="json")
|
||||
if result:
|
||||
mes3.text = "JSON格式存档已保存"
|
||||
mes3.show()
|
||||
elif event.key == pygame.K_s and pygame.key.get_pressed()[pygame.K_LSHIFT]:
|
||||
# Shift+S 保存为CSV格式(兼容旧版本)
|
||||
if len(maze.grid) > 0:
|
||||
result = maze.save_game(format_type="csv")
|
||||
if result:
|
||||
mes3.text = "CSV格式存档已保存"
|
||||
mes3.show()
|
||||
elif event.key == pygame.K_l and pygame.key.get_pressed()[pygame.K_LCTRL]:
|
||||
# Ctrl+L 打开读档界面
|
||||
@ -164,25 +224,25 @@ if __name__ == "__main__":
|
||||
|
||||
|
||||
maze.draw(screen=screen, wall_texture=image_wall, coin_texture=image_coin, trap_texture=image_trap)
|
||||
button_start.draw(screen=screen)
|
||||
button_save.draw(screen=screen)
|
||||
button_load.draw(screen=screen)
|
||||
buttons['start'].draw(screen=screen)
|
||||
buttons['save'].draw(screen=screen)
|
||||
buttons['load'].draw(screen=screen)
|
||||
|
||||
# 绘制路径控制按钮
|
||||
if len(maze.full_path) > 0:
|
||||
# 绘制按钮背景
|
||||
pygame.draw.rect(screen, COLOR_GRAY, button_next_step.rect)
|
||||
pygame.draw.rect(screen, COLOR_GRAY, button_reset_path.rect)
|
||||
pygame.draw.rect(screen, COLOR_GREEN if auto_play else COLOR_GRAY, button_auto_play.rect)
|
||||
pygame.draw.rect(screen, COLOR_GRAY, buttons['next_step'].rect)
|
||||
pygame.draw.rect(screen, COLOR_GRAY, buttons['reset_path'].rect)
|
||||
pygame.draw.rect(screen, COLOR_GREEN if auto_play else COLOR_GRAY, buttons['auto_play'].rect)
|
||||
|
||||
# 绘制按钮文字
|
||||
next_text = textFont.render("下一步", True, COLOR_BLACK)
|
||||
reset_text = textFont.render("重置", True, COLOR_BLACK)
|
||||
auto_text = textFont.render("自动播放" if not auto_play else "停止", True, COLOR_BLACK)
|
||||
|
||||
screen.blit(next_text, (button_next_step.rect.x + 10, button_next_step.rect.y + 15))
|
||||
screen.blit(reset_text, (button_reset_path.rect.x + 25, button_reset_path.rect.y + 15))
|
||||
screen.blit(auto_text, (button_auto_play.rect.x + 5, button_auto_play.rect.y + 15))
|
||||
screen.blit(next_text, (buttons['next_step'].rect.x + 10, buttons['next_step'].rect.y + 15))
|
||||
screen.blit(reset_text, (buttons['reset_path'].rect.x + 25, buttons['reset_path'].rect.y + 15))
|
||||
screen.blit(auto_text, (buttons['auto_play'].rect.x + 5, buttons['auto_play'].rect.y + 15))
|
||||
|
||||
# 显示当前步数信息
|
||||
progress_text = textFont.render(f"路径进度: {maze.path_step}/{len(maze.full_path)}", True, COLOR_BLACK)
|
||||
@ -194,8 +254,8 @@ if __name__ == "__main__":
|
||||
screen.blit(hint_text, button_positions['hint_text'])
|
||||
|
||||
# 显示快捷键提示
|
||||
shortcut_text = textFont.render("Ctrl+S: 保存包含路径的CSV | Ctrl+L: 读档", True, COLOR_LIGHT_GRAY)
|
||||
screen.blit(shortcut_text, (MAZE_SIZE + 50, 330))
|
||||
shortcut_text = textFont.render("Ctrl+S: 保存JSON | Shift+S: 保存CSV | Ctrl+L: 读档", True, COLOR_LIGHT_GRAY)
|
||||
screen.blit(shortcut_text, button_positions['shortcut_text'])
|
||||
|
||||
mes1.draw(screen=screen)
|
||||
mes2.draw(screen=screen)
|
||||
|
31
maze.csv
31
maze.csv
@ -1,16 +1,15 @@
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
||||
1,t15,1,0,1,0,1,l16,0,0,0,t8,0,0,0,1
|
||||
1,0,1,0,1,0,1,1,1,0,1,1,1,1,0,1
|
||||
1,0,1,0,1,0,1,0,0,0,1,0,l15,0,0,1
|
||||
1,0,1,0,1,t18,1,0,1,0,1,1,1,0,1,1
|
||||
1,0,1,0,1,t15,0,0,1,0,1,0,l26,0,1,1
|
||||
1,g11,1,0,1,0,1,t19,1,0,1,0,1,0,1,1
|
||||
1,0,1,0,1,0,1,0,1,0,1,0,1,l11,0,1
|
||||
1,0,1,0,1,0,1,1,1,0,1,1,1,1,1,1
|
||||
1,0,g30,0,1,0,1,0,l19,0,0,0,0,0,0,1
|
||||
1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1
|
||||
1,0,0,0,1,s,0,0,0,0,0,0,0,0,b70,1
|
||||
1,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1
|
||||
1,0,1,0,1,0,0,0,0,e,0,t8,g13,t5,1,1
|
||||
1,0,1,0,1,1,1,1,1,1,1,0,1,0,0,1
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
||||
1,s,1,0,1,0,1,0,1,0,0,0,0,0,1
|
||||
1,0,1,0,1,0,1,0,1,1,1,0,1,1,1
|
||||
1,0,1,0,0,0,1,0,1,0,0,0,1,0,1
|
||||
1,0,1,0,1,1,1,0,1,0,1,1,1,0,1
|
||||
1,0,0,0,1,0,0,0,0,0,0,0,1,0,1
|
||||
1,1,1,0,1,0,1,1,1,0,1,1,1,0,1
|
||||
1,0,0,t15,g10,0,0,0,1,0,l20,0,0,0,1
|
||||
1,0,1,1,1,1,1,1,1,0,1,0,1,0,1
|
||||
1,0,0,0,1,0,1,0,1,0,1,0,1,0,1
|
||||
1,1,1,1,1,0,1,0,1,1,1,1,1,0,1
|
||||
1,0,0,g10,0,g10,0,0,1,0,0,0,0,0,1
|
||||
1,0,1,1,1,0,1,0,1,1,1,0,1,1,1
|
||||
1,g10,0,0,1,0,1,0,0,g10,0,b50,0,e,1
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
||||
|
|
58
maze.py
58
maze.py
@ -3,6 +3,7 @@ from maze_generator import MazeGenerator
|
||||
from SourceCollector import SourceCollector
|
||||
from tanxin import *
|
||||
from simple_save_manager import simple_save_manager
|
||||
from config import UI_WIDTH
|
||||
import time
|
||||
|
||||
class Maze:
|
||||
@ -12,6 +13,9 @@ class Maze:
|
||||
self.size = int(maze_size / wall_size)
|
||||
self.file_name = file_name
|
||||
|
||||
# 动态显示尺寸(会根据实际地图大小调整)
|
||||
self.actual_display_size = maze_size
|
||||
self.actual_wall_size = wall_size
|
||||
|
||||
self.grid = []
|
||||
self.generater = MazeGenerator(self.size, self.file_name)
|
||||
@ -19,6 +23,26 @@ class Maze:
|
||||
self.path_step = 0 # 当前显示到路径的第几步
|
||||
self.full_path = [] # 完整路径
|
||||
self.is_path_complete = False # 路径是否完全显示
|
||||
|
||||
def update_display_size(self):
|
||||
"""根据当前迷宫大小更新显示尺寸"""
|
||||
if len(self.grid) > 0:
|
||||
self.size = len(self.grid)
|
||||
# 计算合适的墙壁大小,确保迷宫不会太大或太小
|
||||
max_display_size = min(800, UI_WIDTH - 400) # 留出400像素给控制面板
|
||||
min_wall_size = 20
|
||||
max_wall_size = 60
|
||||
|
||||
# 根据迷宫大小计算墙壁尺寸
|
||||
ideal_wall_size = max_display_size // self.size
|
||||
self.actual_wall_size = max(min_wall_size, min(max_wall_size, ideal_wall_size))
|
||||
self.actual_display_size = self.size * self.actual_wall_size
|
||||
|
||||
print(f"迷宫大小: {self.size}x{self.size}, 墙壁尺寸: {self.actual_wall_size}, 显示尺寸: {self.actual_display_size}")
|
||||
|
||||
def get_actual_display_size(self):
|
||||
"""获取当前实际显示尺寸"""
|
||||
return self.actual_display_size
|
||||
|
||||
|
||||
def generate(self):
|
||||
@ -30,6 +54,7 @@ class Maze:
|
||||
self.path_step = 0
|
||||
self.is_path_complete = False
|
||||
self.grid = self.generater.maze # 使用原始迷宫数据
|
||||
self.update_display_size() # 更新显示尺寸
|
||||
print(f"路径长度: {len(self.full_path)}")
|
||||
|
||||
def next_path_step(self):
|
||||
@ -74,17 +99,17 @@ class Maze:
|
||||
"""导出迷宫到CSV文件(兼容旧版本)"""
|
||||
self.generater.export_to_csv(filename=filename)
|
||||
|
||||
def save_game(self, save_name=None):
|
||||
"""保存包含路径信息的迷宫到CSV文件"""
|
||||
def save_game(self, save_name=None, format_type="json"):
|
||||
"""保存包含路径信息的迷宫到文件"""
|
||||
if len(self.grid) == 0:
|
||||
print("没有生成迷宫,无法保存")
|
||||
return None
|
||||
|
||||
return simple_save_manager.save_maze_with_path(self, save_name)
|
||||
return simple_save_manager.save_maze_with_path(self, save_name, format_type)
|
||||
|
||||
def load_game(self, save_file):
|
||||
"""从CSV存档文件加载游戏状态"""
|
||||
load_data = simple_save_manager.load_maze_from_csv(save_file)
|
||||
"""从存档文件加载游戏状态(支持JSON和CSV格式)"""
|
||||
load_data = simple_save_manager.load_maze_from_file(save_file)
|
||||
if load_data is None:
|
||||
return False
|
||||
|
||||
@ -103,8 +128,10 @@ class Maze:
|
||||
|
||||
# 使用包含路径信息的网格作为显示网格
|
||||
self.grid = load_data['path_grid']
|
||||
self.update_display_size() # 更新显示尺寸
|
||||
|
||||
print(f"成功加载游戏状态,路径长度: {len(self.full_path)}")
|
||||
file_format = load_data.get('format', '未知')
|
||||
print(f"成功加载游戏状态 ({file_format}格式),路径长度: {len(self.full_path)}")
|
||||
print(f"当前显示完整路径")
|
||||
return True
|
||||
|
||||
@ -119,11 +146,18 @@ class Maze:
|
||||
|
||||
|
||||
def draw(self, screen, wall_texture, coin_texture, trap_texture):
|
||||
tile_size = wall_texture.get_width()
|
||||
|
||||
if len(self.grid) == 0:
|
||||
return
|
||||
|
||||
# 使用动态计算的墙壁尺寸
|
||||
tile_size = self.actual_wall_size
|
||||
|
||||
# 根据需要缩放贴图
|
||||
if wall_texture.get_width() != tile_size:
|
||||
wall_texture = pygame.transform.scale(wall_texture, (tile_size, tile_size))
|
||||
coin_texture = pygame.transform.scale(coin_texture, (tile_size, tile_size))
|
||||
trap_texture = pygame.transform.scale(trap_texture, (tile_size, tile_size))
|
||||
|
||||
for y in range(self.size):
|
||||
for x in range(self.size):
|
||||
if self.grid[y][x] == '1':
|
||||
@ -145,8 +179,6 @@ class Maze:
|
||||
text_rect = text.get_rect(center=center)
|
||||
screen.blit(text, text_rect)
|
||||
|
||||
|
||||
|
||||
if self.grid[y][x].startswith('t'):
|
||||
screen.blit(trap_texture, (x * tile_size, y * tile_size))
|
||||
|
||||
@ -205,7 +237,7 @@ class Maze:
|
||||
text = font.render(text, True, (0, 0, 0))
|
||||
text_rect = text.get_rect(center=center)
|
||||
screen.blit(text, text_rect)
|
||||
|
||||
|
||||
pygame.draw.line(screen, (0, 0, 0), (self.maze_size, 0), (self.maze_size, self.maze_size), 5)
|
||||
|
||||
# 绘制迷宫边界线(动态位置)
|
||||
pygame.draw.line(screen, (0, 0, 0), (self.actual_display_size, 0), (self.actual_display_size, self.actual_display_size), 3)
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import random
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class MazeGenerator:
|
||||
@ -286,6 +288,64 @@ class MazeGenerator:
|
||||
return False
|
||||
return True
|
||||
|
||||
def export_to_json(self, filename):
|
||||
"""导出迷宫到JSON文件"""
|
||||
try:
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# 转换迷宫格式
|
||||
json_maze = self._convert_to_json_format()
|
||||
|
||||
# 创建JSON数据结构
|
||||
json_data = {
|
||||
"maze": json_maze,
|
||||
"metadata": {
|
||||
"name": self.name,
|
||||
"size": self.size,
|
||||
"export_time": datetime.now().isoformat() if 'datetime' in globals() else None,
|
||||
"special_elements_count": len(self.special_elements)
|
||||
}
|
||||
}
|
||||
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
json.dump(json_data, f, indent=2, ensure_ascii=False)
|
||||
print(f"迷宫已导出至: {os.path.abspath(filename)}")
|
||||
except Exception as e:
|
||||
print(f"JSON导出失败: {str(e)}")
|
||||
|
||||
def _convert_to_json_format(self):
|
||||
"""
|
||||
将内部迷宫格式转换为JSON格式
|
||||
'1' -> '#', '0' -> ' ', 's' -> 'S', 'e' -> 'E'
|
||||
'g数字' -> 'G', 't数字' -> 'T', 'l数字' -> 'L', 'b数字' -> 'B'
|
||||
"""
|
||||
json_maze = []
|
||||
for row in self.maze:
|
||||
json_row = []
|
||||
for cell in row:
|
||||
cell_str = str(cell)
|
||||
if cell_str == '1':
|
||||
json_row.append('#')
|
||||
elif cell_str == '0':
|
||||
json_row.append(' ')
|
||||
elif cell_str == 's':
|
||||
json_row.append('S')
|
||||
elif cell_str == 'e':
|
||||
json_row.append('E')
|
||||
elif cell_str.startswith('g'):
|
||||
json_row.append('G')
|
||||
elif cell_str.startswith('t'):
|
||||
json_row.append('T')
|
||||
elif cell_str.startswith('l'):
|
||||
json_row.append('L')
|
||||
elif cell_str.startswith('b'):
|
||||
json_row.append('B')
|
||||
else:
|
||||
json_row.append(' ') # 默认为通路
|
||||
json_maze.append(json_row)
|
||||
return json_maze
|
||||
|
||||
def main():
|
||||
# 示例1: 生成带技能陷阱的迷宫
|
||||
generator = MazeGenerator(
|
||||
|
146
md/NEW_FEATURES_README.md
Normal file
146
md/NEW_FEATURES_README.md
Normal file
@ -0,0 +1,146 @@
|
||||
# 迷宫游戏 - 新按钮功能说明
|
||||
|
||||
## 🎮 更新后的按钮功能
|
||||
|
||||
### 1. 🚀 Start Button (开始按钮)
|
||||
- **功能**: 生成全新的随机迷宫
|
||||
- **操作**: 点击"开始"按钮
|
||||
- **结果**:
|
||||
- 生成新的迷宫布局
|
||||
- 自动计算最优路径
|
||||
- 可以开始路径演示
|
||||
|
||||
### 2. 💾 Save Button (保存按钮) - **新功能**
|
||||
- **功能**: 自动保存当前迷宫为JSON格式
|
||||
- **操作**: 点击"保存"按钮
|
||||
- **结果**:
|
||||
- 将当前迷宫保存为 `saves/maze_save_时间戳.json`
|
||||
- JSON格式符合您要求的标准格式
|
||||
- 包含完整的路径信息
|
||||
|
||||
### 3. 📂 Load Button (加载按钮) - **新功能**
|
||||
- **功能**: 加载样例迷宫并生成路径
|
||||
- **操作**: 点击"加载"按钮
|
||||
- **行为逻辑**:
|
||||
1. **优先加载**: `saves/sample.json` 文件(如果存在)
|
||||
2. **自动生成路径**: 加载后自动计算最优路径
|
||||
3. **备选方案**: 如果 sample.json 不存在,打开存档选择界面
|
||||
|
||||
## 🎯 JSON格式标准
|
||||
|
||||
生成的JSON文件严格按照您的要求格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"maze": [
|
||||
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||
["#", "S", "#", " ", "#", " ", "#", " ", "#", "#"],
|
||||
["#", " ", "#", " ", "#", " ", "#", " ", "#", "#"],
|
||||
["#", " ", " ", " ", " ", " ", " ", " ", "E", "#"],
|
||||
["#", "T", "#", "G", "#", "L", "#", "B", "#", "#"],
|
||||
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#"]
|
||||
],
|
||||
"metadata": {
|
||||
"save_name": "maze_save_20250630_120000",
|
||||
"save_time": "2025-06-30T12:00:00",
|
||||
"maze_size": 10,
|
||||
"path_length": 25
|
||||
},
|
||||
"path_data": {
|
||||
"full_path": [[1,1], [2,1], [3,1], ...],
|
||||
"current_step": 0,
|
||||
"is_path_complete": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎮 元素映射
|
||||
|
||||
| 内部代码 | JSON显示 | 说明 |
|
||||
|---------|---------|------|
|
||||
| `'1'` | `'#'` | 墙壁 |
|
||||
| `'0'` | `' '` | 通路 |
|
||||
| `'s'` | `'S'` | 起点 |
|
||||
| `'e'` | `'E'` | 终点 |
|
||||
| `'g数字'` | `'G'` | 金币 |
|
||||
| `'t数字'` | `'T'` | 陷阱 |
|
||||
| `'l数字'` | `'L'` | 机关 |
|
||||
| `'b数字'` | `'B'` | BOSS |
|
||||
|
||||
## ⌨️ 快捷键和操作
|
||||
|
||||
### 游戏主界面
|
||||
- **Ctrl+S**: 保存为JSON格式
|
||||
- **Shift+S**: 保存为CSV格式(兼容旧版本)
|
||||
- **Ctrl+L**: 打开存档选择界面
|
||||
- **空格键**: 路径下一步
|
||||
- **R键**: 重置路径
|
||||
- **A键**: 自动播放路径
|
||||
|
||||
### 存档选择界面
|
||||
- **↑↓方向键**: 选择存档
|
||||
- **回车键**: 加载选中的存档并生成路径
|
||||
- **鼠标双击**: 直接加载存档并生成路径
|
||||
- **Delete键**: 删除选中的存档
|
||||
- **N键**: 新建存档
|
||||
- **ESC键**: 关闭存档界面
|
||||
|
||||
## 📁 文件结构
|
||||
|
||||
```
|
||||
saves/
|
||||
├── sample.json # 样例迷宫文件(Load按钮优先加载)
|
||||
├── maze_save_时间戳.json # Save按钮生成的存档
|
||||
└── *.csv # 旧格式存档文件
|
||||
```
|
||||
|
||||
## 🔄 使用流程
|
||||
|
||||
1. **生成新迷宫**: 点击 Start → 自动生成迷宫和路径
|
||||
2. **保存当前迷宫**: 点击 Save → 保存为JSON格式
|
||||
3. **加载样例迷宫**: 点击 Load → 加载sample.json并生成路径
|
||||
4. **演示路径**: 使用路径控制按钮或快捷键观看路径演示
|
||||
|
||||
## ✅ 测试验证
|
||||
|
||||
所有新功能已通过测试:
|
||||
- ✅ JSON格式保存功能正常
|
||||
- ✅ sample.json加载功能正常
|
||||
- ✅ 自动路径生成功能正常
|
||||
- ✅ 格式转换功能正常
|
||||
- ✅ 向后兼容CSV格式
|
||||
- ✅ **存档界面加载后自动生成路径** ← 已修复
|
||||
- ✅ **双击加载功能** ← 新增功能
|
||||
- ✅ **动态UI布局适应** ← 新修复功能
|
||||
|
||||
### UI自适应测试结果
|
||||
- ✅ 10x10迷宫: 墙壁60px, 显示600px, 按钮位置正确
|
||||
- ✅ 15x15迷宫: 墙壁53px, 显示795px, 按钮位置正确
|
||||
- ✅ 20x20迷宫: 墙壁40px, 显示800px, 按钮位置正确
|
||||
- ✅ 25x25迷宫: 墙壁32px, 显示800px, 按钮位置正确
|
||||
- ✅ 加载不同存档: UI自动调整布局
|
||||
|
||||
## 🔧 问题修复
|
||||
|
||||
### 修复了存档界面加载问题
|
||||
之前通过 Ctrl+L 选择存档读取时,地图能够加载但没有生成路径。现在已修复:
|
||||
|
||||
1. **键盘回车加载**: 选中存档后按回车键,自动加载并生成路径
|
||||
2. **鼠标双击加载**: 双击存档项,直接加载并生成路径
|
||||
3. **自动路径生成**: 无论通过哪种方式加载,都会自动重新计算最优路径
|
||||
|
||||
### 修复了UI布局自适应问题 ← 新修复
|
||||
之前加载不同大小的地图时,UI布局会出现问题。现在已修复:
|
||||
|
||||
1. **动态尺寸计算**: 根据地图大小自动计算合适的显示尺寸
|
||||
2. **智能墙壁缩放**: 自动调整墙壁大小,确保地图不会太大或太小
|
||||
3. **按钮位置自适应**: 所有按钮和控制面板会根据地图大小自动调整位置
|
||||
4. **实时布局更新**: 当加载不同大小的地图时,UI会立即重新布局
|
||||
|
||||
#### 技术特性
|
||||
- **最小墙壁尺寸**: 20像素(确保可视性)
|
||||
- **最大墙壁尺寸**: 60像素(防止过大)
|
||||
- **最大显示尺寸**: 800像素或窗口宽度减去400像素(为控制面板留空间)
|
||||
- **智能缩放算法**: 根据地图大小自动选择最佳显示参数
|
||||
|
||||
现在您的迷宫游戏完全支持您要求的JSON存档格式!
|
44
save_ui.py
44
save_ui.py
@ -13,6 +13,11 @@ class SaveLoadUI:
|
||||
self.scroll_offset = 0
|
||||
self.max_visible_saves = 8
|
||||
|
||||
# 双击检测
|
||||
self.last_click_time = 0
|
||||
self.last_clicked_index = -1
|
||||
self.double_click_threshold = 500 # 毫秒
|
||||
|
||||
# 界面元素
|
||||
button_positions = get_button_positions()
|
||||
self.list_area = pygame.Rect(*button_positions['save_list_area'])
|
||||
@ -67,6 +72,16 @@ class SaveLoadUI:
|
||||
if 0 <= self.selected_save < len(self.save_list):
|
||||
save_file = self.save_list[self.selected_save]['path']
|
||||
if maze.load_game(save_file):
|
||||
# 加载成功后重新生成路径
|
||||
if maze.generater.maze:
|
||||
from SourceCollector import SourceCollector
|
||||
maze.source_collector = SourceCollector(maze=maze.generater.maze)
|
||||
maze.source_collector.run()
|
||||
maze.full_path = maze.source_collector.get_path()
|
||||
maze.path_step = 0
|
||||
maze.is_path_complete = False
|
||||
maze.grid = maze.generater.maze # 重置显示网格
|
||||
print(f"已为加载的存档重新生成路径,路径长度: {len(maze.full_path)}")
|
||||
self.show_save_list = False
|
||||
return "load_success"
|
||||
return "load_failed"
|
||||
@ -97,7 +112,32 @@ class SaveLoadUI:
|
||||
if relative_y >= 0:
|
||||
clicked_index = relative_y // 25 # 每个存档项25像素高
|
||||
if 0 <= clicked_index < len(self.save_list):
|
||||
self.selected_save = clicked_index
|
||||
current_time = pygame.time.get_ticks()
|
||||
|
||||
# 检查是否为双击
|
||||
if (clicked_index == self.last_clicked_index and
|
||||
current_time - self.last_click_time < self.double_click_threshold):
|
||||
# 双击加载存档
|
||||
save_file = self.save_list[clicked_index]['path']
|
||||
if maze.load_game(save_file):
|
||||
# 加载成功后重新生成路径
|
||||
if maze.generater.maze:
|
||||
from SourceCollector import SourceCollector
|
||||
maze.source_collector = SourceCollector(maze=maze.generater.maze)
|
||||
maze.source_collector.run()
|
||||
maze.full_path = maze.source_collector.get_path()
|
||||
maze.path_step = 0
|
||||
maze.is_path_complete = False
|
||||
maze.grid = maze.generater.maze # 重置显示网格
|
||||
print(f"已为加载的存档重新生成路径,路径长度: {len(maze.full_path)}")
|
||||
self.show_save_list = False
|
||||
return "load_success"
|
||||
return "load_failed"
|
||||
else:
|
||||
# 单击选择
|
||||
self.selected_save = clicked_index
|
||||
self.last_clicked_index = clicked_index
|
||||
self.last_click_time = current_time
|
||||
else:
|
||||
# 点击外部关闭界面
|
||||
self.toggle_save_list()
|
||||
@ -136,7 +176,7 @@ class SaveLoadUI:
|
||||
input_text = self.small_font.render(self.save_input + "|", True, COLOR_BLACK)
|
||||
screen.blit(input_text, (input_rect.x + 5, input_rect.y + 5))
|
||||
else:
|
||||
hint_text = self.small_font.render("↑↓选择 回车加载 Delete删除 N新建 ESC关闭", True, COLOR_BLACK)
|
||||
hint_text = self.small_font.render("↑↓选择 回车/双击加载 Delete删除 N新建 ESC关闭", True, COLOR_BLACK)
|
||||
screen.blit(hint_text, (self.list_area.x + 10, self.list_area.y + 30))
|
||||
|
||||
# 绘制存档列表
|
||||
|
19
saves/sample.json
Normal file
19
saves/sample.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"maze": [
|
||||
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
|
||||
["#", "S", "#", " ", "#", " ", "#", " ", "#", " ", " ", " ", " ", " ", "#"],
|
||||
["#", " ", "#", " ", "#", " ", "#", " ", "#", "#", "#", " ", "#", "#", "#"],
|
||||
["#", " ", "#", " ", " ", " ", "#", " ", "#", " ", " ", " ", "#", " ", "#"],
|
||||
["#", " ", "#", " ", "#", "#", "#", " ", "#", " ", "#", "#", "#", " ", "#"],
|
||||
["#", " ", " ", " ", "#", " ", " ", " ", " ", " ", " ", " ", "#", " ", "#"],
|
||||
["#", "#", "#", " ", "#", " ", "#", "#", "#", " ", "#", "#", "#", " ", "#"],
|
||||
["#", " ", " ", "T", "G", " ", " ", " ", "#", " ", "L", " ", " ", " ", "#"],
|
||||
["#", " ", "#", "#", "#", "#", "#", "#", "#", " ", "#", " ", "#", " ", "#"],
|
||||
["#", " ", " ", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#", " ", "#"],
|
||||
["#", "#", "#", "#", "#", " ", "#", " ", "#", "#", "#", "#", "#", " ", "#"],
|
||||
["#", " ", " ", "G", " ", "G", " ", " ", "#", " ", " ", " ", " ", " ", "#"],
|
||||
["#", " ", "#", "#", "#", " ", "#", " ", "#", "#", "#", " ", "#", "#", "#"],
|
||||
["#", "G", " ", " ", "#", " ", "#", " ", " ", "G", " ", "B", " ", "E", "#"],
|
||||
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"]
|
||||
]
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from config import DEFAULT_MAZE_FILE
|
||||
|
||||
class SimpleSaveManager:
|
||||
"""简化的存档管理器 - 只保存CSV格式的迷宫文件"""
|
||||
"""简化的存档管理器 - 支持JSON和CSV格式的迷宫文件"""
|
||||
|
||||
def __init__(self):
|
||||
self.save_directory = "saves"
|
||||
@ -15,13 +16,14 @@ class SimpleSaveManager:
|
||||
if not os.path.exists(self.save_directory):
|
||||
os.makedirs(self.save_directory)
|
||||
|
||||
def save_maze_with_path(self, maze_instance, save_name=None):
|
||||
def save_maze_with_path(self, maze_instance, save_name=None, format_type="json"):
|
||||
"""
|
||||
保存包含路径信息的迷宫到CSV文件
|
||||
保存包含路径信息的迷宫到文件
|
||||
|
||||
Args:
|
||||
maze_instance: Maze类的实例
|
||||
save_name: 存档名称,如果为None则使用时间戳
|
||||
format_type: 文件格式 "json" 或 "csv"
|
||||
|
||||
Returns:
|
||||
str: 保存的文件路径
|
||||
@ -30,28 +32,15 @@ class SimpleSaveManager:
|
||||
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
|
||||
# 根据格式类型确定文件扩展名
|
||||
if format_type.lower() == "json":
|
||||
if not save_name.endswith('.json'):
|
||||
save_name += '.json'
|
||||
return self._save_maze_json(maze_instance, save_name)
|
||||
else:
|
||||
if not save_name.endswith('.csv'):
|
||||
save_name += '.csv'
|
||||
return self._save_maze_csv(maze_instance, save_name)
|
||||
|
||||
def create_path_grid(self, maze_instance):
|
||||
"""
|
||||
@ -101,6 +90,76 @@ class SimpleSaveManager:
|
||||
|
||||
return path_grid
|
||||
|
||||
def load_maze_from_file(self, file_path):
|
||||
"""
|
||||
从文件加载迷宫,自动检测文件格式
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
dict: 包含迷宫数据和路径信息的字典
|
||||
"""
|
||||
if file_path.endswith('.json'):
|
||||
return self.load_maze_from_json(file_path)
|
||||
elif file_path.endswith('.csv'):
|
||||
return self.load_maze_from_csv(file_path)
|
||||
else:
|
||||
print(f"不支持的文件格式: {file_path}")
|
||||
return None
|
||||
|
||||
def load_maze_from_json(self, json_file):
|
||||
"""
|
||||
从JSON文件加载迷宫
|
||||
|
||||
Args:
|
||||
json_file: JSON文件路径
|
||||
|
||||
Returns:
|
||||
dict: 包含迷宫数据和路径信息的字典
|
||||
"""
|
||||
try:
|
||||
with open(json_file, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# 检查数据结构
|
||||
if 'maze' not in data:
|
||||
print("JSON文件格式错误:缺少maze字段")
|
||||
return None
|
||||
|
||||
# 转换JSON格式到内部格式
|
||||
internal_maze = self.convert_from_json_format(data['maze'])
|
||||
|
||||
result = {
|
||||
'original_grid': internal_maze,
|
||||
'path_grid': internal_maze, # 对于JSON格式,初始时路径网格与原始网格相同
|
||||
'path_sequence': [],
|
||||
'path_positions': {},
|
||||
'metadata': data.get('metadata', {}),
|
||||
'format': 'json'
|
||||
}
|
||||
|
||||
# 如果有路径数据,也加载路径信息
|
||||
if 'path_data' in data:
|
||||
raw_path = data['path_data'].get('full_path', [])
|
||||
# 确保路径数据是元组格式 (JSON会将元组转换为列表)
|
||||
result['path_sequence'] = [tuple(pos) if isinstance(pos, list) else pos for pos in raw_path]
|
||||
result['path_positions'] = {i+1: tuple(pos) if isinstance(pos, list) else pos
|
||||
for i, pos in enumerate(result['path_sequence'])}
|
||||
|
||||
# 如果有路径,创建包含路径的网格
|
||||
if result['path_sequence']:
|
||||
result['path_grid'] = self.create_path_grid_from_data(internal_maze, result['path_sequence'])
|
||||
|
||||
print(f"成功从 {os.path.abspath(json_file)} 加载迷宫")
|
||||
if result['path_sequence']:
|
||||
print(f"路径长度: {len(result['path_sequence'])}")
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
print(f"JSON加载失败: {str(e)}")
|
||||
return None
|
||||
|
||||
def load_maze_from_csv(self, csv_file):
|
||||
"""
|
||||
从CSV文件加载迷宫,解析路径信息
|
||||
@ -126,7 +185,8 @@ class SimpleSaveManager:
|
||||
'original_grid': original_grid,
|
||||
'path_grid': grid,
|
||||
'path_sequence': path_data['path_sequence'],
|
||||
'path_positions': path_data['path_positions']
|
||||
'path_positions': path_data['path_positions'],
|
||||
'format': 'csv'
|
||||
}
|
||||
|
||||
print(f"成功从 {os.path.abspath(csv_file)} 加载迷宫")
|
||||
@ -134,9 +194,39 @@ class SimpleSaveManager:
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
print(f"加载失败: {str(e)}")
|
||||
print(f"CSV加载失败: {str(e)}")
|
||||
return None
|
||||
|
||||
def create_path_grid_from_data(self, original_grid, path_sequence):
|
||||
"""从原始网格和路径序列创建包含路径信息的网格"""
|
||||
path_grid = [row[:] for row in original_grid] # 深拷贝
|
||||
|
||||
for idx, (y, x) in enumerate(path_sequence):
|
||||
if y >= len(path_grid) or x >= len(path_grid[0]):
|
||||
continue
|
||||
|
||||
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'):
|
||||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||||
elif current_cell.startswith('t'):
|
||||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||||
elif current_cell.startswith('l'):
|
||||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||||
elif current_cell.startswith('b'):
|
||||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||||
elif current_cell == '0':
|
||||
path_grid[y][x] = path_info
|
||||
else:
|
||||
path_grid[y][x] = f"{current_cell}{path_info}"
|
||||
|
||||
return path_grid
|
||||
|
||||
def extract_path_from_grid(self, grid):
|
||||
"""从网格中提取路径信息"""
|
||||
path_positions = {} # {step_number: (y, x)}
|
||||
@ -186,20 +276,26 @@ class SimpleSaveManager:
|
||||
return original_grid
|
||||
|
||||
def get_save_list(self):
|
||||
"""获取所有CSV存档文件列表"""
|
||||
"""获取所有存档文件列表(支持JSON和CSV格式)"""
|
||||
saves = []
|
||||
if os.path.exists(self.save_directory):
|
||||
for filename in os.listdir(self.save_directory):
|
||||
if filename.endswith('.csv'):
|
||||
if filename.endswith('.csv') or filename.endswith('.json'):
|
||||
file_path = os.path.join(self.save_directory, filename)
|
||||
try:
|
||||
stat = os.stat(file_path)
|
||||
# 确定文件格式
|
||||
file_format = 'json' if filename.endswith('.json') else 'csv'
|
||||
# 移除扩展名作为名称
|
||||
name = filename.replace('.json', '').replace('.csv', '')
|
||||
|
||||
saves.append({
|
||||
'filename': filename,
|
||||
'path': file_path,
|
||||
'name': filename.replace('.csv', ''),
|
||||
'name': name,
|
||||
'save_time': datetime.fromtimestamp(stat.st_mtime).isoformat(),
|
||||
'size': stat.st_size
|
||||
'size': stat.st_size,
|
||||
'format': file_format
|
||||
})
|
||||
except:
|
||||
continue
|
||||
@ -215,6 +311,151 @@ class SimpleSaveManager:
|
||||
except Exception as e:
|
||||
print(f"删除失败: {str(e)}")
|
||||
return False
|
||||
|
||||
def _save_maze_json(self, maze_instance, save_name):
|
||||
"""保存迷宫为JSON格式"""
|
||||
save_file = os.path.join(self.save_directory, save_name)
|
||||
|
||||
try:
|
||||
# 转换迷宫格式
|
||||
json_maze = self.convert_to_json_format(maze_instance)
|
||||
|
||||
# 创建保存数据结构
|
||||
save_data = {
|
||||
"maze": json_maze,
|
||||
"metadata": {
|
||||
"save_name": save_name.replace('.json', ''),
|
||||
"save_time": datetime.now().isoformat(),
|
||||
"maze_size": maze_instance.size,
|
||||
"path_length": len(maze_instance.full_path) if maze_instance.full_path else 0
|
||||
}
|
||||
}
|
||||
|
||||
# 如果有路径信息,也保存路径
|
||||
if maze_instance.full_path:
|
||||
save_data["path_data"] = {
|
||||
"full_path": maze_instance.full_path,
|
||||
"current_step": maze_instance.path_step,
|
||||
"is_path_complete": maze_instance.is_path_complete
|
||||
}
|
||||
|
||||
# 保存为JSON文件
|
||||
with open(save_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(save_data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"迷宫已保存至: {os.path.abspath(save_file)}")
|
||||
return save_file
|
||||
|
||||
except Exception as e:
|
||||
print(f"JSON保存失败: {str(e)}")
|
||||
return None
|
||||
|
||||
def _save_maze_csv(self, maze_instance, 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"CSV保存失败: {str(e)}")
|
||||
return None
|
||||
|
||||
def convert_to_json_format(self, maze_instance):
|
||||
"""
|
||||
将内部迷宫格式转换为JSON格式
|
||||
|
||||
内部格式 -> JSON格式:
|
||||
'1' -> '#' (墙壁)
|
||||
'0' -> ' ' (通路)
|
||||
's' -> 'S' (起点)
|
||||
'e' -> 'E' (终点)
|
||||
'g数字' -> 'G' (金币)
|
||||
't数字' -> 'T' (陷阱)
|
||||
'l数字' -> 'L' (机关)
|
||||
'b数字' -> 'B' (BOSS)
|
||||
"""
|
||||
if not maze_instance.generater.maze:
|
||||
return []
|
||||
|
||||
json_maze = []
|
||||
for row in maze_instance.generater.maze:
|
||||
json_row = []
|
||||
for cell in row:
|
||||
cell_str = str(cell)
|
||||
if cell_str == '1':
|
||||
json_row.append('#')
|
||||
elif cell_str == '0':
|
||||
json_row.append(' ')
|
||||
elif cell_str == 's':
|
||||
json_row.append('S')
|
||||
elif cell_str == 'e':
|
||||
json_row.append('E')
|
||||
elif cell_str.startswith('g'):
|
||||
json_row.append('G')
|
||||
elif cell_str.startswith('t'):
|
||||
json_row.append('T')
|
||||
elif cell_str.startswith('l'):
|
||||
json_row.append('L')
|
||||
elif cell_str.startswith('b'):
|
||||
json_row.append('B')
|
||||
else:
|
||||
# 未知类型,默认为通路
|
||||
json_row.append(' ')
|
||||
json_maze.append(json_row)
|
||||
|
||||
return json_maze
|
||||
|
||||
def convert_from_json_format(self, json_maze):
|
||||
"""
|
||||
将JSON格式转换为内部迷宫格式
|
||||
|
||||
JSON格式 -> 内部格式:
|
||||
'#' -> '1' (墙壁)
|
||||
' ' -> '0' (通路)
|
||||
'S' -> 's' (起点)
|
||||
'E' -> 'e' (终点)
|
||||
'G' -> 'g10' (金币,默认值10)
|
||||
'T' -> 't15' (陷阱,默认值15)
|
||||
'L' -> 'l20' (机关,默认值20)
|
||||
'B' -> 'b50' (BOSS,默认值50)
|
||||
"""
|
||||
internal_maze = []
|
||||
for row in json_maze:
|
||||
internal_row = []
|
||||
for cell in row:
|
||||
if cell == '#':
|
||||
internal_row.append('1')
|
||||
elif cell == ' ':
|
||||
internal_row.append('0')
|
||||
elif cell == 'S':
|
||||
internal_row.append('s')
|
||||
elif cell == 'E':
|
||||
internal_row.append('e')
|
||||
elif cell == 'G':
|
||||
internal_row.append('g10') # 默认金币值
|
||||
elif cell == 'T':
|
||||
internal_row.append('t15') # 默认陷阱值
|
||||
elif cell == 'L':
|
||||
internal_row.append('l20') # 默认机关值
|
||||
elif cell == 'B':
|
||||
internal_row.append('b50') # 默认BOSS值
|
||||
else:
|
||||
# 未知类型,默认为通路
|
||||
internal_row.append('0')
|
||||
internal_maze.append(internal_row)
|
||||
|
||||
return internal_maze
|
||||
|
||||
# 全局简化存档管理器实例
|
||||
simple_save_manager = SimpleSaveManager()
|
||||
|
106
tests/test_button_functions.py
Normal file
106
tests/test_button_functions.py
Normal file
@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试新的按钮功能
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from maze import Maze
|
||||
from SourceCollector import SourceCollector
|
||||
|
||||
def test_load_and_generate_path():
|
||||
"""测试加载样例文件并生成路径的功能"""
|
||||
print("=== 测试加载样例文件并生成路径 ===\n")
|
||||
|
||||
# 创建迷宫实例
|
||||
maze = Maze(wall_size=20, maze_size=400, file_name="test.csv")
|
||||
|
||||
# 测试加载sample.json
|
||||
sample_file = "saves/sample.json"
|
||||
print(f"1. 尝试加载 {sample_file}...")
|
||||
|
||||
if os.path.exists(sample_file):
|
||||
print(f"文件存在,开始加载...")
|
||||
|
||||
# 加载文件
|
||||
if maze.load_game(sample_file):
|
||||
print("✓ 加载成功")
|
||||
print(f"迷宫大小: {maze.size}x{maze.size}")
|
||||
|
||||
# 重新生成路径
|
||||
print("\n2. 重新生成路径...")
|
||||
if maze.generater.maze:
|
||||
maze.source_collector = SourceCollector(maze=maze.generater.maze)
|
||||
maze.source_collector.run()
|
||||
maze.full_path = maze.source_collector.get_path()
|
||||
maze.path_step = 0
|
||||
maze.is_path_complete = False
|
||||
maze.grid = maze.generater.maze
|
||||
|
||||
print(f"✓ 路径生成成功")
|
||||
print(f"路径长度: {len(maze.full_path)}")
|
||||
print(f"路径前10步: {maze.full_path[:10]}")
|
||||
|
||||
# 显示迷宫的起点和终点
|
||||
start_pos = None
|
||||
end_pos = None
|
||||
for y in range(maze.size):
|
||||
for x in range(maze.size):
|
||||
if maze.generater.maze[y][x] == 's':
|
||||
start_pos = (y, x)
|
||||
elif maze.generater.maze[y][x] == 'e':
|
||||
end_pos = (y, x)
|
||||
|
||||
print(f"起点位置: {start_pos}")
|
||||
print(f"终点位置: {end_pos}")
|
||||
|
||||
if maze.full_path:
|
||||
print(f"路径起点: {maze.full_path[0]}")
|
||||
print(f"路径终点: {maze.full_path[-1]}")
|
||||
|
||||
return True
|
||||
else:
|
||||
print("✗ 迷宫数据无效")
|
||||
return False
|
||||
else:
|
||||
print("✗ 加载失败")
|
||||
return False
|
||||
else:
|
||||
print(f"✗ 文件不存在: {sample_file}")
|
||||
return False
|
||||
|
||||
def test_save_json():
|
||||
"""测试保存JSON功能"""
|
||||
print("\n=== 测试保存JSON功能 ===\n")
|
||||
|
||||
# 创建并生成新迷宫
|
||||
maze = Maze(wall_size=20, maze_size=400, file_name="test.csv")
|
||||
maze.generate()
|
||||
|
||||
print(f"生成迷宫大小: {maze.size}x{maze.size}")
|
||||
print(f"路径长度: {len(maze.full_path)}")
|
||||
|
||||
# 保存为JSON
|
||||
result = maze.save_game("test_button_save", "json")
|
||||
if result:
|
||||
print(f"✓ JSON保存成功: {result}")
|
||||
return True
|
||||
else:
|
||||
print("✗ JSON保存失败")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
success1 = test_load_and_generate_path()
|
||||
success2 = test_save_json()
|
||||
|
||||
print(f"\n=== 测试结果 ===")
|
||||
print(f"加载并生成路径: {'成功' if success1 else '失败'}")
|
||||
print(f"保存JSON: {'成功' if success2 else '失败'}")
|
||||
|
||||
if success1 and success2:
|
||||
print("✓ 所有测试通过!新按钮功能正常工作。")
|
||||
else:
|
||||
print("✗ 部分测试失败,需要检查。")
|
99
tests/test_dynamic_ui.py
Normal file
99
tests/test_dynamic_ui.py
Normal file
@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试动态UI布局功能
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from maze import Maze
|
||||
from config import get_button_positions, MAZE_SIZE
|
||||
|
||||
def test_dynamic_ui():
|
||||
"""测试动态UI布局功能"""
|
||||
print("=== 测试动态UI布局功能 ===\n")
|
||||
|
||||
# 测试不同大小的迷宫
|
||||
test_cases = [
|
||||
("小迷宫", 10), # 10x10
|
||||
("中迷宫", 15), # 15x15
|
||||
("大迷宫", 20), # 20x20
|
||||
("超大迷宫", 25), # 25x25
|
||||
]
|
||||
|
||||
for name, size in test_cases:
|
||||
print(f"{name} ({size}x{size}):")
|
||||
|
||||
# 创建迷宫实例
|
||||
maze = Maze(wall_size=40, maze_size=size*40, file_name="test.csv")
|
||||
|
||||
# 模拟网格数据(创建指定大小的迷宫)
|
||||
maze.grid = [['1' for _ in range(size)] for _ in range(size)]
|
||||
maze.size = size
|
||||
|
||||
# 更新显示尺寸
|
||||
maze.update_display_size()
|
||||
|
||||
print(f" 实际墙壁尺寸: {maze.actual_wall_size}")
|
||||
print(f" 实际显示尺寸: {maze.actual_display_size}")
|
||||
|
||||
# 测试按钮位置
|
||||
button_positions = get_button_positions(maze.actual_display_size)
|
||||
print(f" 开始按钮位置: {button_positions['start_button']}")
|
||||
print(f" 保存按钮位置: {button_positions['save_button']}")
|
||||
print(f" 加载按钮位置: {button_positions['load_button']}")
|
||||
print()
|
||||
|
||||
# 测试加载不同存档文件的效果
|
||||
print("=== 测试加载不同存档文件 ===\n")
|
||||
|
||||
saves_dir = "saves"
|
||||
if os.path.exists(saves_dir):
|
||||
save_files = [f for f in os.listdir(saves_dir) if f.endswith('.json')][:3]
|
||||
|
||||
for save_file in save_files:
|
||||
print(f"加载存档: {save_file}")
|
||||
maze = Maze(wall_size=40, maze_size=800, file_name="test.csv")
|
||||
|
||||
full_path = os.path.join(saves_dir, save_file)
|
||||
if maze.load_game(full_path):
|
||||
print(f" 迷宫大小: {maze.size}x{maze.size}")
|
||||
print(f" 实际显示尺寸: {maze.actual_display_size}")
|
||||
print(f" 墙壁尺寸: {maze.actual_wall_size}")
|
||||
|
||||
# 计算按钮位置
|
||||
button_positions = get_button_positions(maze.actual_display_size)
|
||||
print(f" 控制面板起始X: {button_positions['start_button'][0]}")
|
||||
print()
|
||||
else:
|
||||
print(f" 加载失败")
|
||||
print()
|
||||
|
||||
print("=== 按钮位置适应性测试完成 ===")
|
||||
|
||||
def test_button_positions():
|
||||
"""测试按钮位置计算函数"""
|
||||
print("\n=== 测试按钮位置计算函数 ===\n")
|
||||
|
||||
test_sizes = [400, 600, 800, 1000, 1200]
|
||||
|
||||
for size in test_sizes:
|
||||
print(f"迷宫显示尺寸: {size}")
|
||||
positions = get_button_positions(size)
|
||||
|
||||
print(f" 开始按钮: {positions['start_button']}")
|
||||
print(f" 存档区域: {positions['save_list_area']}")
|
||||
|
||||
# 检查按钮是否在合理位置(不超出屏幕范围)
|
||||
control_x = positions['start_button'][0]
|
||||
if control_x < 1500: # UI_WIDTH
|
||||
print(f" ✓ 按钮位置合理")
|
||||
else:
|
||||
print(f" ✗ 按钮位置可能超出屏幕")
|
||||
print()
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_dynamic_ui()
|
||||
test_button_positions()
|
145
tests/test_json_format.py
Normal file
145
tests/test_json_format.py
Normal file
@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试JSON存档格式功能
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from maze_generator import MazeGenerator
|
||||
from maze import Maze
|
||||
from simple_save_manager import simple_save_manager
|
||||
import json
|
||||
|
||||
def test_json_save_load():
|
||||
"""测试JSON格式的保存和加载功能"""
|
||||
print("=== 测试JSON存档格式功能 ===\n")
|
||||
|
||||
# 1. 生成一个测试迷宫
|
||||
print("1. 生成测试迷宫...")
|
||||
maze = Maze(wall_size=20, maze_size=400, file_name="test_maze.csv")
|
||||
maze.generate()
|
||||
print(f"迷宫大小: {maze.size}x{maze.size}")
|
||||
print(f"路径长度: {len(maze.full_path)}")
|
||||
|
||||
# 2. 保存为JSON格式
|
||||
print("\n2. 保存为JSON格式...")
|
||||
json_save_file = maze.save_game("test_maze_json", "json")
|
||||
if json_save_file:
|
||||
print(f"JSON保存成功: {json_save_file}")
|
||||
|
||||
# 查看JSON文件内容
|
||||
with open(json_save_file, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
print("JSON文件结构:")
|
||||
print(f"- maze: {len(data['maze'])}x{len(data['maze'][0])} 网格")
|
||||
print(f"- metadata: {data.get('metadata', {})}")
|
||||
if 'path_data' in data:
|
||||
print(f"- path_data: 包含{len(data['path_data']['full_path'])}步路径")
|
||||
|
||||
# 显示迷宫的前5行作为示例
|
||||
print("\n迷宫前5行示例:")
|
||||
for i, row in enumerate(data['maze'][:5]):
|
||||
print(f"第{i+1}行: {row}")
|
||||
|
||||
else:
|
||||
print("JSON保存失败")
|
||||
return False
|
||||
|
||||
# 3. 保存为CSV格式(对比)
|
||||
print("\n3. 保存为CSV格式...")
|
||||
csv_save_file = maze.save_game("test_maze_csv", "csv")
|
||||
if csv_save_file:
|
||||
print(f"CSV保存成功: {csv_save_file}")
|
||||
else:
|
||||
print("CSV保存失败")
|
||||
|
||||
# 4. 测试JSON加载
|
||||
print("\n4. 测试JSON加载...")
|
||||
new_maze = Maze(wall_size=20, maze_size=400, file_name="test_load.csv")
|
||||
if new_maze.load_game(json_save_file):
|
||||
print("JSON加载成功")
|
||||
print(f"加载后迷宫大小: {new_maze.size}x{new_maze.size}")
|
||||
print(f"加载后路径长度: {len(new_maze.full_path)}")
|
||||
|
||||
# 验证加载的数据
|
||||
original_path = maze.full_path
|
||||
loaded_path = new_maze.full_path
|
||||
if original_path == loaded_path:
|
||||
print("✓ 路径数据完全一致")
|
||||
else:
|
||||
print("✗ 路径数据不一致")
|
||||
print(f"原始路径前5步: {original_path[:5]}")
|
||||
print(f"加载路径前5步: {loaded_path[:5]}")
|
||||
else:
|
||||
print("JSON加载失败")
|
||||
return False
|
||||
|
||||
# 5. 测试存档列表
|
||||
print("\n5. 测试存档列表...")
|
||||
save_list = simple_save_manager.get_save_list()
|
||||
print(f"找到{len(save_list)}个存档文件:")
|
||||
for save in save_list:
|
||||
print(f"- {save['name']} ({save['format']}格式) - {save['filename']}")
|
||||
|
||||
# 6. 验证JSON格式转换
|
||||
print("\n6. 验证JSON格式转换...")
|
||||
print("内部格式 -> JSON格式转换测试:")
|
||||
test_conversions = [
|
||||
('1', '#', '墙壁'),
|
||||
('0', ' ', '通路'),
|
||||
('s', 'S', '起点'),
|
||||
('e', 'E', '终点'),
|
||||
('g10', 'G', '金币'),
|
||||
('t15', 'T', '陷阱'),
|
||||
('l20', 'L', '机关'),
|
||||
('b50', 'B', 'BOSS')
|
||||
]
|
||||
|
||||
for internal, expected_json, desc in test_conversions:
|
||||
# 创建单元素测试迷宫
|
||||
test_maze = [[internal]]
|
||||
json_format = simple_save_manager.convert_to_json_format_helper(test_maze)
|
||||
actual_json = json_format[0][0]
|
||||
status = "✓" if actual_json == expected_json else "✗"
|
||||
print(f"{status} {desc}: '{internal}' -> '{actual_json}' (期望: '{expected_json}')")
|
||||
|
||||
print("\n=== 测试完成 ===")
|
||||
return True
|
||||
|
||||
def simple_save_manager_convert_to_json_format_helper(maze_grid):
|
||||
"""辅助函数:转换迷宫格式用于测试"""
|
||||
json_maze = []
|
||||
for row in maze_grid:
|
||||
json_row = []
|
||||
for cell in row:
|
||||
cell_str = str(cell)
|
||||
if cell_str == '1':
|
||||
json_row.append('#')
|
||||
elif cell_str == '0':
|
||||
json_row.append(' ')
|
||||
elif cell_str == 's':
|
||||
json_row.append('S')
|
||||
elif cell_str == 'e':
|
||||
json_row.append('E')
|
||||
elif cell_str.startswith('g'):
|
||||
json_row.append('G')
|
||||
elif cell_str.startswith('t'):
|
||||
json_row.append('T')
|
||||
elif cell_str.startswith('l'):
|
||||
json_row.append('L')
|
||||
elif cell_str.startswith('b'):
|
||||
json_row.append('B')
|
||||
else:
|
||||
json_row.append(' ')
|
||||
json_maze.append(json_row)
|
||||
return json_maze
|
||||
|
||||
# 为simple_save_manager添加辅助方法
|
||||
simple_save_manager.convert_to_json_format_helper = simple_save_manager_convert_to_json_format_helper
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_json_save_load()
|
133
tests/test_save_ui_fix.py
Normal file
133
tests/test_save_ui_fix.py
Normal file
@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试存档界面加载并生成路径功能
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from maze import Maze
|
||||
from SourceCollector import SourceCollector
|
||||
|
||||
def test_load_via_save_ui():
|
||||
"""测试通过存档界面加载存档并生成路径"""
|
||||
print("=== 测试存档界面加载功能 ===\n")
|
||||
|
||||
# 创建迷宫实例
|
||||
maze = Maze(wall_size=20, maze_size=400, file_name="test.csv")
|
||||
|
||||
# 模拟存档界面的加载逻辑
|
||||
print("1. 模拟通过存档界面加载sample.json...")
|
||||
save_file = "saves/sample.json"
|
||||
|
||||
if os.path.exists(save_file):
|
||||
# 执行加载
|
||||
if maze.load_game(save_file):
|
||||
print("✓ 存档加载成功")
|
||||
|
||||
# 模拟存档界面中的路径重新生成逻辑
|
||||
if maze.generater.maze:
|
||||
maze.source_collector = SourceCollector(maze=maze.generater.maze)
|
||||
maze.source_collector.run()
|
||||
maze.full_path = maze.source_collector.get_path()
|
||||
maze.path_step = 0
|
||||
maze.is_path_complete = False
|
||||
maze.grid = maze.generater.maze
|
||||
|
||||
print(f"✓ 路径重新生成成功")
|
||||
print(f"迷宫大小: {maze.size}x{maze.size}")
|
||||
print(f"路径长度: {len(maze.full_path)}")
|
||||
print(f"路径前5步: {maze.full_path[:5]}")
|
||||
print(f"路径后5步: {maze.full_path[-5:]}")
|
||||
|
||||
# 验证起点和终点
|
||||
if maze.full_path:
|
||||
start_pos = maze.full_path[0]
|
||||
end_pos = maze.full_path[-1]
|
||||
|
||||
# 检查起点是否为起点标记
|
||||
start_cell = maze.generater.maze[start_pos[0]][start_pos[1]]
|
||||
end_cell = maze.generater.maze[end_pos[0]][end_pos[1]]
|
||||
|
||||
print(f"路径起点: {start_pos}, 网格值: {start_cell}")
|
||||
print(f"路径终点: {end_pos}, 网格值: {end_cell}")
|
||||
|
||||
if start_cell == 's' and end_cell == 'e':
|
||||
print("✓ 路径起点和终点验证正确")
|
||||
else:
|
||||
print("✗ 路径起点或终点验证失败")
|
||||
return False
|
||||
|
||||
return True
|
||||
else:
|
||||
print("✗ 迷宫数据无效")
|
||||
return False
|
||||
else:
|
||||
print("✗ 存档加载失败")
|
||||
return False
|
||||
else:
|
||||
print(f"✗ 文件不存在: {save_file}")
|
||||
return False
|
||||
|
||||
def test_multiple_saves():
|
||||
"""测试加载多个不同的存档文件"""
|
||||
print("\n=== 测试多个存档文件 ===\n")
|
||||
|
||||
# 获取所有存档文件
|
||||
saves_dir = "saves"
|
||||
if not os.path.exists(saves_dir):
|
||||
print("saves目录不存在")
|
||||
return False
|
||||
|
||||
save_files = [f for f in os.listdir(saves_dir) if f.endswith('.json') or f.endswith('.csv')]
|
||||
|
||||
if not save_files:
|
||||
print("没有找到存档文件")
|
||||
return False
|
||||
|
||||
print(f"找到{len(save_files)}个存档文件:")
|
||||
for save_file in save_files:
|
||||
print(f"- {save_file}")
|
||||
|
||||
# 测试加载每个文件
|
||||
results = []
|
||||
for save_file in save_files[:3]: # 只测试前3个文件
|
||||
print(f"\n测试加载: {save_file}")
|
||||
|
||||
maze = Maze(wall_size=20, maze_size=400, file_name="test.csv")
|
||||
full_path = os.path.join(saves_dir, save_file)
|
||||
|
||||
if maze.load_game(full_path):
|
||||
# 重新生成路径
|
||||
if maze.generater.maze:
|
||||
maze.source_collector = SourceCollector(maze=maze.generater.maze)
|
||||
maze.source_collector.run()
|
||||
maze.full_path = maze.source_collector.get_path()
|
||||
|
||||
print(f" ✓ 加载成功,路径长度: {len(maze.full_path)}")
|
||||
results.append(True)
|
||||
else:
|
||||
print(f" ✗ 迷宫数据无效")
|
||||
results.append(False)
|
||||
else:
|
||||
print(f" ✗ 加载失败")
|
||||
results.append(False)
|
||||
|
||||
success_count = sum(results)
|
||||
print(f"\n测试结果: {success_count}/{len(results)} 个文件加载成功")
|
||||
return success_count == len(results)
|
||||
|
||||
if __name__ == "__main__":
|
||||
success1 = test_load_via_save_ui()
|
||||
success2 = test_multiple_saves()
|
||||
|
||||
print(f"\n=== 总体测试结果 ===")
|
||||
print(f"存档界面加载测试: {'成功' if success1 else '失败'}")
|
||||
print(f"多文件加载测试: {'成功' if success2 else '失败'}")
|
||||
|
||||
if success1 and success2:
|
||||
print("✓ 所有测试通过!存档界面现在会正确重新生成路径。")
|
||||
else:
|
||||
print("✗ 部分测试失败,需要进一步检查。")
|
Loading…
Reference in New Issue
Block a user