from dataclasses import dataclass, field
from typing import Optional
from gropro.teil import Teil
[Doku]
@dataclass
class Ebene:
dimension: int
teile: list[Teil] = field(default_factory=list)
lower: Optional["Ebene"] = None
quer: bool = False
def __post_init__(self):
"""Bestimme die Ausrichtung anhand der nächsttieferen Ebene"""
self.quer = not self.lower.quer if self.lower else False
@property
def voll(self) -> bool:
return len(self.teile) >= self.dimension
@property
def depth(self) -> int:
if self.lower:
return self.lower.depth + 1
return 0
[Doku]
def add(self, t: Teil) -> bool:
"""Füge ein zulässiges Teil in die nächste Freie Position ein oder melde Unzulässigkeit"""
if not self.fits(t):
return False
self.teile.append(t)
return True
[Doku]
def fits(self, t: Teil) -> bool:
"""Weise unzulässige Teile für die nächste freie Position ab"""
if self.voll:
return False
teil = t.value
pos = len(self.teile)
if self.lower:
for i in range(self.dimension):
lowpos = self.lower.teile[i].value[pos]
curpos = teil[i]
# This check came straight from hell
# But its a necessary evil as it covers the following cases:
# 1. If the current piece has at least a bump downwards and the piece below is not a hole
# 2. If the piece below has at least a bump upwards but the current piece is not a hole
# 3. If the current piece has at least a bump downwards and the piece below has a hole but also the piece below that has at least a bump upwards
# in any of these cases the current piece is not fit for this position!
bumpdown = curpos in (2, 3)
clear_below = lowpos == 0
if (
(bumpdown and not clear_below)
or (lowpos in (1, 3) and curpos != 0)
or (
bumpdown
and clear_below
and (
self.lower.lower.teile[i].value[pos] in (1, 3)
if self.lower.lower
else False
)
)
):
return False
return True
def __str__(self) -> str:
"""Schreibe die Repräsentation gemäß der Aufgabenstellung"""
repr: list[list[str]] = []
q = self.quer
for i in range(self.dimension):
line: list[str] = []
for j in range(self.dimension):
line.append(str(self.teile[i if q else j].value[j if q else i]))
if q:
line.append(self.teile[i].name)
repr.append(line)
if not q:
repr.append([t.name for t in self.teile])
return "\n".join([" ".join(line) for line in repr])