Implementace Conwayovy Hry života v okenní aplikaci. Vývoj generací je zobrazován za sebou ve snímcích jako animace. Program umožňuje:
- Nakreslit počáteční rozložení buněk.
- Nastavit počty sousedů buněk pro přežití a narození nových.
- Změnit rychlost animace na některou z přednastavených hodnot.
- Přiblížit a oddálit herní plochu.
- Uložit a načíst sestavu buněk.
Před spuštěním programu si musíte nainstalovat Python.
Spolu s Pythonem se stáhne program pip, pomocí něj nainstalujte knihovnu Pillow:
- Otevřete příkazový řádek jako správce.
- Stáhněte knihovnu příkazem:
Path\pip install Pillow
,
kdePath
je cesta k programu pip na vašem počítači.
Na operačním systému Windows spusťtě soubor main.pyw. Pokud máte jiný operační systém, spusťte main.py (zobrazí se s konzolí, tu ignorujte).
Otevře se okno programu. V horním panelu jsou k dispozici tlačítka pro minimalizaci, maximalizaci a zavření okna.
- Prázdnou mřížku vytvoříte kliknutím na New Board.
- Držením levého tlačítka myši můžete kreslit buňky. Úpravy lze provádět jen před spuštěním animace nebo po jejím resetování. V pravém menu jsou k dispozici 3 módy:
- Add - přidat buňku.
- Remove - odebrat buňku.
- Toggle - změnit současný stav buňky. Po celou dobu jednoho tahu je nastaven jako Add nebo Remove podle stavu 1. buňky, na kterou bylo kliknuto.
- Plochu přibližujte a oddalujte pomocí posuvníku Zoom nebo klávesami "+" a "-".
- Obrazem pohybujte pomocí šipek.
- Pro uložení použijte tlačítko Save. Zobrazí se dialog, v něm vyberte název souboru a cestu, potvrzením soubor uložte.
- Načtení provedete kliknutím na Open. V dialogu nalezněte příslušný soubor a potvrďte.
Ve složce examples najdete některé hotové mřížky pro načtení.
Všechny mřížky mají šířku a výšku 1000 - dohromady 1 milion buněk.
- Animaci spustíte tlačítkem Play. Text tlačítka se změní na Stop a opětovným kliknutím animaci pozastavíte.
- Při pozastavené animaci můžete přejít k další generaci tlačítkem Step.
- Rychlost animace lze upravit posuvníkem Speed.
- Číslo současné generace je označeno nápisem Gen.
- Animaci resetujte pomocí tlačítka Reset.
Pravidlo hry se zapisuje ve formátu "Bx/Ry", kde x jsou počty sousedů pro narození buňky a y počty sousedů pro přežití. Čísla se v těchto částech nesmí opakovat a nula je zakázána.
Současné pravidlo je označeno nápisem Rule nad herní plochou. Změníte jej následovně:
- Text kolonky v pravém menu nahraďte novým pravidlem.
- Nastavení potvrďte tlačítkem Set Rule.
Detaily najdete v kódu, zde jsou uvedeny pouze nejdůležitější metody a datové struktury.
Zejména pro vzhled aplikace byly použity některé knihovny:
- Tkinter - okno programu a jeho komponenty, zpracování událostí od uživatele.
- Pillow - kreslení na obrázek v paměti.
- Time - měření času mezi snímky animace.
- Os - nalezení cesty k adresáři hlavního programu, která se použije jako výchozí při načítání hry ze souboru.
- Sys - předčasné ukončení programu.
- Typing - označení proměnných datovými typy, které nepatří mezi standardní.
- gol.py:
Třídy určené pro výpočet, kreslení a animaci:Board
,Rule
,Painter
,Animator
. - main.py / main.pyw:
Hlavní program se třídami:FileManager
,TkState
,Application
.
Obsahuje informace o herní ploše (seznam buněk) a stará se o výpočet dalších generací. Umožňuje přidávat a odebírat buňky.
- current: list
Mřížka současné generace buněk jako 2D seznam proměnných bool (True
= živá buňka,False
= mrtvá buňka). - living: list
Seznam souřadnic (dvojice celých čísel) živých buněk v seznamucurrent
.
- next_gen() → None:
Spočítá další generaci buněk podle počtu jejich sousedů. Prochází pouze živé buňky a jejich sousedy, protože ostatní buňky zůstanou nezměněné.
Slouží pro snadnější nastavování pravidel hry (počtů sousedů) pomocí textového řetězce. Uloží si množiny čísel, které se pak mohou předat objektu Board
a ten podle nich přizpůsobí výpočet dalších generací.
- birth_rule: set
Počty sousedů pro narození nové buňky. - remain_rule: set
Počty sousedů pro přežití buňky.
- try_set_rule(value: str) → bool:
Pokusí se nastavit textový řetězecvalue
jako nové pravidlo. VracíTrue
, pokud je pravidlo správné, jinakFalse
.
Kreslí herní plochu Board
na plátno Canvas
.
- grids: list
Obrázky s mřížkou (svislými a vodorovnými čárami) pro různé velikosti buněk. Slouží jako pozadí, na které se budou buňky kreslit. Vytváří se v metoděreset
, kterou je proto nutné zavolat před jakýmkoliv kreslením. Lze mezi nimi přepínat a tím mřížku „přibližovat / oddalovat“. - m_cell: Tuple[int, int]
Souřadnice buňky, která je kreslena doprostřed mřížky. Se změnou těchto souřadnic se bude zobrazovat jiná část herní plochy. Obraz se tak může posouvat nahoru, dolů, anebo do stran. - canvas_image: int
Obrázek na plátněCanvas
knihovnytkinter
(ve skutečnosti jen jeho index). Je natažen na celou velikost plátna, pokud nepřekračuje velikost mřížek. Nakreslení herní plochy je provedeno změnou jeho parametruimage
.
- reset(...,cell_sizes: list,...) → None:
Vytváří obrázky mřížek pro zadané velikosti buněk. - draw_board() → None:
Nakreslí herní plochu v těchto krocích:- Ořízne prostřední část mřížky z
grids
na velikost plátna. - Podle souřadnic buňky kreslené doprostřed (
m_cell
) nakreslí všechny viditelné buňky na oříznutou mřížku. - Výsledný obrázek nastaví jako parametr
image
obrázkucanvas_image
.
- Ořízne prostřední část mřížky z
S využitím objektu typu Painter
kreslí generace buněk za sebou jako animaci.
- time_per_gen: int
Čas mezi kreslením generací v milisekundách.
- play() → None:
Spustí animaci. - stop() → None:
Pozastaví animaci.
Statická třída, která načítá a ukládá Board
do souboru. Výsledek zobrazuje v okně se zprávou - messagebox
.
Statická třída, která aktivuje a deaktivuje komponenty tkinter
(především tlačítka).
Propojuje výpočet a grafické rozhraní programu. Obsahuje komponenty okna a objekty modulu gol.py
, se kterými manipuluje podle událostí.
U většího počtu buněk nebo některých pravidel (např. B1/R23) je vidět, že počítání generací je velmi pomalé.
V současné verzi program prochází všechny živé buňky a spočte jejich stav. Výpočet by se dal potenciálně zlepšit:
- Knihovna
numpy
nabízí datovou strukturu pole, kterým se mohou nahradit seznamy standardního Pythonu. - Použití bitových operací umožní pracovat s celými řádky najednou. Problém by nastal při kreslení, kdy se v řádcích musí najít živé buňky - bity 1 nebo 0. V nejhorším případě se tak znovu projde celá mřížka.
Objekt Painter
vytváří obrázek pro každou velikost buňky zvlášť. To je zejména kvůli tomu, aby se mřížky nemusely kreslit v každém snímku. Pro rychlejší kreslení tento problém nenastane a v jednu chvíli by tak mohl existovat pouze 1 obrázek.
S využitím bitových operací (viz Rychlost) se značně ušetří na paměti. Každá buňka se uloží jako 1 bit a seznam živých buněk se vůbec nepoužije.
- Přesunutí na konrétní pozici v mřížce pomocí kolonky a tlačítka.
- Kreslení buněk i po spuštění animace.
- Změna barvy pozadí, buněk, atd.