import pygame TILE_SIZE = 32 # Color definitions COLOR_BG = (0, 0, 0) COLOR_WALL = (0, 0, 255) COLOR_DOT = (255, 255, 255) COLOR_POWER = (255, 255, 255) class Maze: def __init__(self, file_path): self.file_path = file_path self.layout = [] self.dots = set() self.power_pellets = set() self.load_maze() def load_maze(self): with open(self.file_path, "r") as f: self.layout = [line.strip() for line in f.readlines()] self.rows = len(self.layout) self.cols = len(self.layout[0]) self.width = self.cols * TILE_SIZE self.height = self.rows * TILE_SIZE # Track collectible positions self.dots.clear() self.power_pellets.clear() for y, row in enumerate(self.layout): for x, char in enumerate(row): if char == ".": self.dots.add((x, y)) elif char == "*": self.power_pellets.add((x, y)) elif char == "M": self.pacman_start = (x * TILE_SIZE + TILE_SIZE // 2, y * TILE_SIZE + TILE_SIZE // 2 + 32) self.pacman_location = (x, y) def draw(self, screen): for y, row in enumerate(self.layout): for x, char in enumerate(row): rect = pygame.Rect(x * TILE_SIZE, y * TILE_SIZE + 32, TILE_SIZE, TILE_SIZE) if char == "W": pygame.draw.rect(screen, COLOR_WALL, rect) # Draw dots for (x, y) in self.dots: center = (x * TILE_SIZE + TILE_SIZE // 2, y * TILE_SIZE + TILE_SIZE // 2 + 32) pygame.draw.circle(screen, COLOR_DOT, center, 2) # Draw power pellets for (x, y) in self.power_pellets: center = (x * TILE_SIZE + TILE_SIZE // 2, y * TILE_SIZE + TILE_SIZE // 2 + 32) pygame.draw.circle(screen, COLOR_POWER, center, 5) def tile_at(self, x, y): """Return the tile character at a specific (x, y) tile coordinate.""" if 0 <= y < self.rows and 0 <= x < self.cols: return self.layout[y][x] return " " # Treat out-of-bounds as path def is_wall(self, x, y): return self.tile_at(x, y) == "W" def is_ghost_home(self, x, y): return self.tile_at(x, y) == "H" def collect_dot(self, x, y): """Mark a dot as collected. Return True if there was a dot or power pellet.""" pos = (x, y) if pos in self.dots: self.dots.remove(pos) return "dot" elif pos in self.power_pellets: self.power_pellets.remove(pos) return "power" return None def reset_collectibles(self): """Reloads only dot/pellet positions from the layout.""" self.load_maze() def pixel_to_tile(self, px, py): """Convert pixel coordinates to tile (grid) coordinates.""" return px // TILE_SIZE, py // TILE_SIZE def tile_to_pixel(self, tx, ty): """Convert tile (grid) coordinates to top-left pixel position.""" return tx * TILE_SIZE, ty * TILE_SIZE