############################################################################################################################################################################################################################# INFO ############################################################################################################################################################################################################################# This file is part of the PyRat library.# It is meant to be used as a library, and not to be executed directly.# Please import necessary elements using the following syntax:# from pyrat import <element_name>"""This module provides a maze that is created from a fixed description as a dictionary.It extends ``Maze`` to create a specific type of maze with a fixed structure.This class is especially useful to allow exporting a maze to a file, and then reusing it later.It is also useful to test a player on a fixed maze."""########################################################################################################################################################################################################################### IMPORTS ############################################################################################################################################################################################################################ External importsimportmath# PyRat importsfrompyrat.src.MazeimportMaze########################################################################################################################################################################################################################### CLASSES ###########################################################################################################################################################################################################################
[docs]classMazeFromDict(Maze):""" *(This class inherits from* ``Maze`` *).* This is a maze that is created from a fixed description as a dictionary, where keys are cell indices. Associated values are dictionaries, where keys are neighbors of the corresponding cell, and values are the weights of the corresponding edges. This class is especially useful to allow exporting a maze to a file, and then reusing it later. It is also useful to test a player on a fixed maze, to compare its performance with other players. """############################################################################################################################################## MAGIC METHODS ##############################################################################################################################################
[docs]def__init__(self,description:dict[int,dict[int,int]],*args:object,**kwargs:object)->None:""" Initializes a new instance of the class. Args: description: Fixed maze as a dictionary. *args: Arguments to pass to the parent constructor. **kwargs: Keyword arguments to pass to the parent constructor. """# Inherit from parent classsuper().__init__(*args,**kwargs)# Debugassertisinstance(description,dict),"Argument 'description' must be a dictionary"assertall(isinstance(vertex,int)forvertexindescription),"All keys of 'description' must be integers"assertall(isinstance(neighbor,int)forvertexindescriptionforneighborindescription[vertex]),"All keys of subdictionaries of 'description' must be integers"assertall(isinstance(description[vertex][neighbor],int)forvertexindescriptionforneighborindescription[vertex]),"All values of subdictionaries of 'description' must be integers"assertlen(description)>1,"The maze must have at least two vertices"assertall(len(description[vertex])>0forvertexindescription),"All vertices must have at least one neighbor"assertall(vertexindescription[neighbor]forvertexindescriptionforneighborindescription[vertex]),"The maze must be symmetric"assertall(description[vertex][neighbor]==description[neighbor][vertex]forvertexindescriptionforneighborindescription[vertex]),"The maze must have symmetric weights"assertall(description[vertex][neighbor]>0forvertexindescriptionforneighborindescription[vertex]),"All weights must be positive"# Private attributesself.__description=description# Generate the mazeself._create_maze()
############################################################################################################################################## PROTECTED METHODS ##############################################################################################################################################def_create_maze(self)->None:""" *(This method redefines the method of the parent class with the same name).* Creates a maze from the description provided at initialization. """# Determine the verticesvertices=self.__description.keys()# Determine the edgesedges=[]forvertexinself.__description:neighbors=self.__description[vertex]forneighborinneighbors:edges.append((vertex,neighbor,self.__description[vertex][neighbor]))# Determine the dimensions of the mazeself._width=max([abs(edge[1]-edge[0])foredgeinedges])self._height=math.ceil((max(vertices)+1)/self.get_width())# Add vertices and edgesforvertexinvertices:self.add_vertex(vertex)foredgeinedges:self.add_edge(edge[0],edge[1],edge[2])