from __future__ import annotations from copy import deepcopy from random import randint from typing import * # type: ignore from rio import Component, event, Column, Row, Color, Rectangle class ConwayPage(Component): """ This is an Easter egg. """ active_generation: list[list] = [] rows: int = 36 cols: int = 20 @event.periodic(1) async def calc_next_gen(self) -> None: self.create_next_grid() @event.on_populate def prepare(self) -> None: self.active_generation = self.create_initial_grid() def create_initial_grid(self) -> list[list]: grid = [] for row in range(self.rows): grid_rows = [] for col in range(self.cols): if randint(0, 7) == 0: grid_rows += [1] else: grid_rows += [0] grid += [grid_rows] return grid def create_next_grid(self) -> None: next_grid = deepcopy(self.active_generation) for row in range(self.rows): for col in range(self.cols): live_neighbors = self.get_live_neighbors(row, col, self.active_generation) if live_neighbors < 2 or live_neighbors > 3: next_grid[row][col] = 0 elif live_neighbors == 3 and self.active_generation[row][col] == 0: next_grid[row][col] = 1 else: next_grid[row][col] = self.active_generation[row][col] self.active_generation = next_grid def get_live_neighbors(self, row: int, col: int, grid: list[list]) -> int: life_sum = 0 for i in range(-1, 2): for j in range(-1, 2): if not (i == 0 and j == 0): life_sum += grid[((row + i) % self.rows)][((col + j) % self.cols)] return life_sum def grid_changing(self, next_grid: list[list]) -> bool: for row in range(self.rows): for col in range(self.cols): if not self.active_generation[row][col] == next_grid[row][col]: return True return False def build(self) -> Component: rows = [] for row in self.active_generation: rectangles = [] for cell in row: color = Color.WHITE if cell == 1 else Color.BLACK rectangles.append(Rectangle(fill=color, transition_time=0.3)) rows.append(Row(*rectangles)) return Column(*rows)