67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
"""
|
|
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 |