from typing import Self from zelle import Zelle from random import shuffle, randrange class Laby: """ Klasse für ein Labyrinth, bestehend aus Zellen. Die Richtungen sind wie folgt (im trigonometrischen Umlaufsinn, d.h. von der x- zur y-Achse, nur dass die y-Achse hier nach unten zeigt.) 3 ^ 2 <-o-> 0 positive x-Achse v 1 positive y-Achse Attributes ---------- breite : int Anzahl Zellen in der Breite (x-Richtung) hoehe : int Anzahl Zahlen in der Höhe (y-Richtung, von oben nach unten) zellen : list[list[Zelle]] Zellen als Liste von Listen Methods ------- on(x:int, y:int) -> bool Liefert True, wenn die Koordinate x,y auf dem Labyrinth ist, sonst False clearMarks(clear:str=" ") -> None Löscht die Markierung in allen Zellen. Optional kann die Markierung angegeben werden (anstatt dem Leerschlag) closeAll(self, offenZu:bool=False) -> None: Schliesst alle Wände. closeAll(True) öffnet alle Wände. importBild(self, pnmBild) -> None: Importiert ein pnmBild. Dieses muss die gleiche Breite und Höhe haben. Auf allen Zellen wird die Markierung auf "0" oder "1" gesetzt. Zusätzlich wird allen Zellen ein Attribut bild hinzugefügt, das 0 oder 1 (als Zahl) enthält. """ def __init__(self,breite:int, hoehe:int) -> Self: """Leeres Labyrinth, alle Wände geschlossen. """ self.breite = breite self.hoehe = hoehe self.zellen:list[list[Zelle]] = [[Zelle(x,y,self) for y in range(hoehe)] for x in range(self.breite)] def on(self, x:int,y:int) -> bool: """Liefert True, wenn die Koordinate x,y auf dem Labyrinth ist, sonst False.""" return x>=0 and y>=0 and x None: """Löscht alle Markierungen. clearMarks("X") setzt alle Markierung auf "X". """ for zeile in self.zellen: for zelle in zeile: zelle.mark = clear def closeAll(self, offenZu:bool=False) -> None: """Schliesst alle Wände. closeAll(True) öffnet alle Wände.""" for zeile in self.zellen: for zelle in zeile: for dir in range(4): zelle.zustand(dir, offenZu) def importBild(self, pnmBild) -> None: """Importiert ein pnmBild. Dieses muss die gleiche Breite und Höhe haben. Auf allen Zellen wird die Markierung auf "0" oder "1" gesetzt. Zusätzlich wird allen Zellen ein Attribut bild hinzugefügt, das 0 oder 1 (als Zahl) enthält. """ if self.hoehe!=pnmBild.hoehe or self.breite!=pnmBild.breite: raise RuntimeError("Bild und Labyrinth sind nicht gleich gross!") for y in range(self.hoehe): for x in range(self.breite): self[x,y].bild = pnmBild[x,y] self[x,y].mark = str(pnmBild[x,y]) def __getitem__(self, x:tuple[int,int]) -> Zelle: """Damit kann direkt mit laby[x,y] auf eine Zelle """ if type(x) is list or type(x) is tuple: return self.zellen[x[0]][x[1]] else: raise RuntimeError("Es muss die Form laby[x,y] verwendet werden") def __str__(self) -> str: """ASCII-Art des Labyrinths, zur Ausgabe auf dem Terminal. """ res = "" # Zeilenweise aufbauen (jeweils oben und mitte) for y in range(self.hoehe): # oben res += "+" for x in range(self.breite): if self[x,y].offen[3]: # Kann nach oben? res += " +" else: res += "---+" res += "\n" # Zeilenumbruch # Mitte if self[0,y].offen[2]: # Kann nach links res += " " else: res += "|" for x in range(self.breite): res += f" {self[x,y].mark} " if self[x,y].offen[0]: # Kann nach rechts res += " " else: res += "|" res += "\n" # Unterste Zeile res += "+" for x in range(self.breite): if self[x,y].offen[1]: # Kann nach unten? res += " +" else: res += "---+" res += "\n" return res