Fix: Wal springt nicht mehr, Farben korrekt

Alle 12 Frames normalisiert auf 8 Zeilen (3 Fontäne + 1 Separator + 4 Körper).
Vorher variierten die Frame-Höhen (6–8 Zeilen), sodass der Körper zwischen
Zeilen 2/3/4 sprang. Maske hatte 7 Zeilen → bei 8-Zeilen-Frames um 1 Zeile
versetzt → falsche Körperfarben.

- mask_r/l: leere Trennzeile zwischen Fontänen-Farben und Körper-Farben
- Fontänen-Zeilen auf genau 3 aufgefüllt (oben mit Leerstrings)
- Frames direkt als Listen gebaut statt über _p()-String-Konkatenation

Außerdem aus vorheriger Session:
- add_all_fish: Anzahl relativ zu wl (statt hardcodiert)
- main: Terminalgröße erst nach ALT_ON lesen (Split-Pane-Fix)
- --debug Flag
This commit is contained in:
rene 2026-03-29 15:20:18 +02:00
parent 177e66c626
commit 66671eda8b

View file

@ -473,7 +473,8 @@ class Aquarium:
# ── Fish ───────────────────────────────────────────────────────────────── # ── Fish ─────────────────────────────────────────────────────────────────
def add_all_fish(self): def add_all_fish(self):
count = max(8, (self.rows - 9) * self.cols // 200) underwater_rows = max(1, self.rows - (self.wl + 4))
count = max(15, underwater_rows * self.cols // 120)
for _ in range(count): for _ in range(count):
self.add_fish(None) self.add_fish(None)
@ -859,6 +860,7 @@ yywwwyyyyyyyyyyyyyyyyyyyy
C C C C
CCCCCCC CCCCCCC
C C C C C C
BBBBBBB BBBBBBB
BB BB BB BB
B B BWB B B B BWB B
@ -868,6 +870,7 @@ BBBBB BBBB
C C C C
CCCCCCC CCCCCCC
C C C C C C
BBBBBBB BBBBBBB
BB BB BB BB
B BWB B B B BWB B B
@ -890,17 +893,24 @@ BBBB BBBBB
mask_str = mask_r_str if going_right else mask_l_str mask_str = mask_r_str if going_right else mask_l_str
x = -18 if going_right else self.cols - 2 x = -18 if going_right else self.cols - 2
# 4 body lines; all frames are 8 rows: 3 spout + 1 separator + 4 body.
# This keeps the body at the same rows (4-7) in every frame so the
# whale doesn't jump, and the mask aligns correctly.
body_lines = _p(body_str)
mask_lines = _p(mask_str)
frames, masks = [], [] frames, masks = [], []
# 5 frames without spout # 5 frames without spout: 4 empty rows + 4 body rows
for _ in range(5): for _ in range(5):
frames.append(_p('\n\n\n' + body_str)) frames.append(['', '', '', ''] + body_lines)
masks.append(_p(mask_str)) masks.append(mask_lines)
# 7 frames with animated spout # 7 frames with animated spout: spout padded to 3 rows, then separator, then body
for spout in spouts: for spout in spouts:
sp_lines = spout.strip('\n').split('\n') sp_lines = [' ' * spout_align + l for l in spout.strip('\n').split('\n')]
aligned = '\n'.join(' ' * spout_align + l for l in sp_lines) while len(sp_lines) < 3:
frames.append(_p(aligned + '\n' + body_str)) sp_lines = [''] + sp_lines
masks.append(_p(mask_str)) frames.append(sp_lines + [''] + body_lines)
masks.append(mask_lines)
self._add(Entity( self._add(Entity(
frames=frames, masks=masks, frames=frames, masks=masks,
@ -1544,6 +1554,8 @@ def main():
help='disable all predators (shark, big fish, fishhook)') help='disable all predators (shark, big fish, fishhook)')
parser.add_argument('--any-key', action='store_true', parser.add_argument('--any-key', action='store_true',
help='any key press exits (default: q/Q/Esc/Ctrl-C)') help='any key press exits (default: q/Q/Esc/Ctrl-C)')
parser.add_argument('--debug', action='store_true',
help='show terminal size / entity count overlay')
args = parser.parse_args() args = parser.parse_args()
cfg = Config( cfg = Config(
@ -1555,8 +1567,6 @@ def main():
any_key = args.any_key, any_key = args.any_key,
) )
rows, cols = term_size()
aq = Aquarium(rows, cols, cfg)
inp = Input() inp = Input()
paused = False paused = False
needs_reset = False needs_reset = False
@ -1568,7 +1578,11 @@ def main():
signal.signal(signal.SIGWINCH, on_resize) signal.signal(signal.SIGWINCH, on_resize)
fd = sys.stdout.fileno() fd = sys.stdout.fileno()
# Activate alternate screen first, THEN read terminal size so the
# size reflects the actual pane dimensions (important in split panes).
os.write(fd, (ALT_ON + HIDE_CUR + "\033[2J\033[H").encode()) os.write(fd, (ALT_ON + HIDE_CUR + "\033[2J\033[H").encode())
rows, cols = term_size()
aq = Aquarium(rows, cols, cfg)
try: try:
TICK = 0.1 / cfg.speed TICK = 0.1 / cfg.speed
@ -1595,6 +1609,13 @@ def main():
if not paused: if not paused:
aq.step() aq.step()
frame = aq.render() frame = aq.render()
if args.debug:
fish_ys = [f"{int(e.y)}" for e in aq.entities
if e.entity_type == 'fish'][:8]
dbg = (f" rows={aq.rows} cols={aq.cols} wl={aq.wl}"
f" ents={len(aq.entities)}"
f" fish_y=[{','.join(fish_ys)}] ")
frame += f"\033[1;1H\033[0;7m{dbg}\033[m"
os.write(fd, frame.encode()) os.write(fd, frame.encode())
elapsed = time.monotonic() - t0 elapsed = time.monotonic() - t0