""" Reads map files and returns a Map object. It provides a method to read a map file by it's name and return the corresponding Map object. It provides a method to get all of the map names in the maps directory. """ import os from game.map import Map import tomllib class MapReader: DIRECTORY = "maps/" def __init__(self): pass def get_map_names(self): return [f[:-5] for f in os.listdir(self.DIRECTORY) if f.endswith('.toml')] def read_map(self, map_name): import configparser map_path = os.path.join(self.DIRECTORY, map_name + ".toml") if not os.path.exists(map_path): raise FileNotFoundError(f"Map file {map_name} not found in {self.DIRECTORY}") with open(map_path, 'rb') as f: config = tomllib.load(f) layout = config.get('layout', '') map_data = { 'name': map_name, 'difficulty': config.get('difficulty', 0.0), 'layout': self._parse_layout(layout) } if config.get('min_moves') is not None: map_data['min_moves'] = config.get('min_moves') return Map(map_data) def _get_block_characters_mapping(self): # Returns a dictionary mapping block characters to their corresponding block classes. from game.blocks import BLOCKS return {block().character: block for block in BLOCKS} def _parse_layout(self, mapString): # Takes the blocks and translates their characters into the corresponding block objects. # Makes sure tthe width is consistent across all rows by padding with None if necessary. block_mapping = self._get_block_characters_mapping() layout = [] for line in mapString.splitlines(): row = [] for char in line: block_class = block_mapping.get(char) if block_class: row.append(block_class()) else: row.append(None) # Unknown character, treat as empty space layout.append(row) max_width = max(len(row) for row in layout) for row in layout: while len(row) < max_width: row.append(None) # Pad with None to ensure consistent width return layout