maze_python/maze.py

244 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import pygame
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:
def __init__(self, wall_size, maze_size, file_name):
self.wall_size = wall_size
self.maze_size = maze_size
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)
self.source_collector = None
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):
seed = int(time.time() * 1000) % (2**32)
self.generater.generate(seed=seed)
self.source_collector = SourceCollector(maze=self.generater.maze)
self.source_collector.run()
self.full_path = self.source_collector.get_path()
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):
"""显示路径的下一步"""
if self.path_step < len(self.full_path):
self.path_step += 1
self.update_grid_with_path()
return True
return False
def reset_path(self):
"""重置路径显示"""
self.path_step = 0
self.is_path_complete = False
self.grid = self.generater.maze if self.generater.maze else []
def auto_advance_path(self):
"""自动推进路径显示"""
if not self.is_path_complete:
if not self.next_path_step():
self.is_path_complete = True
def update_grid_with_path(self):
"""根据当前步数更新网格显示"""
if not self.full_path or not self.generater.maze:
return
# 从原始迷宫开始
self.grid = [row[:] for row in self.generater.maze] # 深拷贝
# 只显示到当前步数的路径
for idx in range(min(self.path_step, len(self.full_path))):
y, x = self.full_path[idx]
if self.grid[y][x].startswith('s') or self.grid[y][x].startswith('e'):
continue
if self.grid[y][x].startswith('g') or self.grid[y][x].startswith('t'):
self.grid[y][x] = f"{self.grid[y][x]}p{idx}"
continue
self.grid[y][x] = f"p{idx}"
def export_to_csv(self, filename):
"""导出迷宫到CSV文件兼容旧版本"""
self.generater.export_to_csv(filename=filename)
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, format_type)
def load_game(self, save_file):
"""从存档文件加载游戏状态支持JSON和CSV格式"""
load_data = simple_save_manager.load_maze_from_file(save_file)
if load_data is None:
return False
try:
# 恢复迷宫数据
self.generater.maze = load_data['original_grid']
self.size = len(load_data['original_grid'])
# 恢复路径数据
self.full_path = load_data['path_sequence']
self.path_step = len(self.full_path) # 显示完整路径
self.is_path_complete = True
# 重新创建SourceCollector以便后续操作
self.source_collector = SourceCollector(maze=self.generater.maze)
# 使用包含路径信息的网格作为显示网格
self.grid = load_data['path_grid']
self.update_display_size() # 更新显示尺寸
file_format = load_data.get('format', '未知')
print(f"成功加载游戏状态 ({file_format}格式),路径长度: {len(self.full_path)}")
print(f"当前显示完整路径")
return True
except Exception as e:
print(f"加载游戏状态失败: {str(e)}")
return False
def get_save_list(self):
"""获取所有可用的存档列表"""
return simple_save_manager.get_save_list()
def draw(self, screen, wall_texture, coin_texture, trap_texture):
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':
screen.blit(wall_texture, (x * tile_size, y * tile_size))
continue
if self.grid[y][x].startswith('g'):
screen.blit(coin_texture, (x * tile_size, y * tile_size))
font = pygame.font.SysFont(None, tile_size // 2)
path = self.grid[y][x].rfind('p')
if path == -1:
continue
path = self.grid[y][x][path+1:]
center = (x * tile_size + tile_size // 2, y * tile_size + tile_size // 2)
radius = tile_size // 3
text = font.render(path, True, (255, 255, 255))
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))
font = pygame.font.SysFont(None, tile_size // 2)
path = self.grid[y][x].rfind('p')
if path == -1:
continue
path = self.grid[y][x][path+1:]
center = (x * tile_size + tile_size // 2, y * tile_size + tile_size // 2)
radius = tile_size // 3
text = font.render(path, True, (255, 255, 255))
text_rect = text.get_rect(center=center)
screen.blit(text, text_rect)
if self.grid[y][x].startswith('|') or self.grid[y][x].startswith('-'):
font = pygame.font.SysFont(None, tile_size // 2)
num = int(self.grid[y][x][1:])
center = (x * tile_size + tile_size // 2, y * tile_size + tile_size // 2)
radius = tile_size // 3
pygame.draw.circle(screen, (255, 215, 0), center, radius)
if num:
text = font.render(str(num), True, (0, 0, 0))
text_rect = text.get_rect(center=center)
screen.blit(text, text_rect)
continue
if self.grid[y][x].startswith('s'):
font = pygame.font.SysFont(None, tile_size // 2)
text = "s"
center = (x * tile_size + tile_size // 2, y * tile_size + tile_size // 2)
radius = tile_size // 3
pygame.draw.circle(screen, (255, 215, 0), center, radius)
if text:
text = font.render(text, True, (0, 0, 0))
text_rect = text.get_rect(center=center)
screen.blit(text, text_rect)
continue
if self.grid[y][x].startswith('e'):
font = pygame.font.SysFont(None, tile_size // 2)
text = "e"
center = (x * tile_size + tile_size // 2, y * tile_size + tile_size // 2)
radius = tile_size // 3
pygame.draw.circle(screen, (255, 215, 0), center, radius)
if text:
text = font.render(text, True, (0, 0, 0))
text_rect = text.get_rect(center=center)
screen.blit(text, text_rect)
if self.grid[y][x].startswith('p'):
font = pygame.font.SysFont(None, tile_size // 2)
text = self.grid[y][x][1:]
center = (x * tile_size + tile_size // 2, y * tile_size + tile_size // 2)
radius = tile_size // 3
pygame.draw.circle(screen, (255, 215, 0), center, radius)
if text:
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.actual_display_size, 0), (self.actual_display_size, self.actual_display_size), 3)