Popis systému

Tato stránka je návodem pro práci s klikátkem. Klikátko je k dispozici jak samostatně (můžete zadat, co potřebujete – může se hodit pro každou úlohu), tak v každé úloze (přednastavené parametry úlohy).

Klikátko

Účelem klikátka je umožnit vám vyzkoušet si, jak se chová vámi vytvořený celulární automat. Celulární automat definujete vytvořením

  • pravidla,
  • počáteční konfigurací (stavem mřížky).

Celulární automat funguje tak, že vždy vezme nějaký stav mřížky, aplikuje na každou buňku pravidlo (na všechny buňky zároveň), což vytvoří mřížku novou. Tento proces se opakuje pořád dokola, dokud uživatel simulaci nezastaví. Příklad pravidla: “když mám alespoň 3 zelené sousedy a jsem zelená, zůstávám zelená, jinak se stávám šedou”.

Klikátko obsahuje 3 části:

Prostor pro zápis pravidla

  • Prostor pro zápis pravidla se nachází na levé straně nahoře. Zapisujete do něj vždy právě jedno přechodové pravidlo. (O způsobu zápisu pravidla se dočtete dále.)
  • Po zapsání přechodového pravidla je třeba kliknout na tlačítko Načíst kód. Po úspěšném načtení se vámi zapsané pravidlo použije při spuštění simulace.

Nastavení automatu

Prostor pro nastavení automatu se nachází na levé straně dole. Nastavujete v něm různé parametry automatu.

  • Šířka a výška mřížky.
  • Zpět: umožňuje vrátit simulaci o krok zpět.
  • Spustit: spustí simulaci a nechá ji trvale běžet (simulaci musíte ručně zastavit!).
  • Další: provede jeden krok simulace.
  • Vyčistit, Zaplnit: nastavit všechny buňky na konkrétní barvu.
  • Rovina/torus: nastavuje, jestli buňky na okraji mřížky sousedí s buňkami "na druhé straně mřížky" (torus), nebo nesousedí s ničím (rovina). U každé úlohy je zadáno, jestli funguje jako rovina nebo jako torus.
  • Načíst, Uložit: Umožňuje uložit si konkrétní stav a ten pak znovu použít.
  • Ze souboru, Do souboru: umožňuje stáhnout a nahrát stav mřížky.
  • R,G,B,K: změní barvu, kterou aktuálně vyklikáváte mřížku.

Mřížka

  • Mřížka se nachází na pravé straně.
  • Její konfiguraci si můžete vyklikat ručně, načíst ze souboru (tlačítko ze souboru), nebo obnovit dříve uloženou (tlačítko načíst). Stejně tak si můžete aktuální konfiguraci uložit – ať už do souboru, nebo pouze pro tuto chvíli (tlačítko uložit). Před zadáváním si nezapomeňte zvolit barvu.
  • Mřížka se indexuje od levého horního rohu, který má souřadnice x=1, y=1. Pravý horní roh má souřadnice x=šířka, y=1 atp.
  • Levý klik na buňku: nastavit aktuální vybranou barvu.
  • Pravý klik na buňku: změnit barvu na další barvu.

Zápis pravidla

Přechodové pravidlo popisuje, jaká bude barva buňky v dalším kroku na základě barvy buňky a barev okolních osmi buněk. Přechodové pravidlo se skládá z jedné nebo více zanořených podmínek. Zápis přechodového pravidla je podobný syntaxi programovacího jazyka Python.

Příklad pravidla:

if ----r---- == 1:
    g
else:
    r

Toto pravidlo říká: pokud je buňka červená (r), změní se na zelenou (g), jinak se změní na červenou (r). Význam ----r---- si ukážeme za chvíli.

Příklad pravidla s více zanořeními:

if ((rrb------ % 2) == 1) or (------bbr >= 2):
    if (bb-----bb + kk-----kk) >= 5:
        b
    else:
        k  # seda barva
else:
    b

Pokud je podmínka splněna (je vyhodnocena jako pravdivá), provede se kód, který za ní následuje (začíná na následujícím řádku za odsazením). Jinak se provede kód ve větvi else – začínající na následujícím řádku za odsazením. Tímto kódem může být buďto písmeno značící barvu, nebo další podmínka.

  1. Každá podmínka musí mít if větevelse větev.
  2. Závorek si do podmínky můžete napsat kolik chcete.
  3. Závorky se nemusí psát nikde. Neuzávorkovaný výraz se uzávorkuje podle priorit operátorů, případně zleva.
  4. Podporované logické spojky jsou or (logické nebo) a and (logické a zároveň).
  5. Podporované porovnávací operátory jsou <=, >=, <, >, == (rovnost), != (nerovnost).
  6. Podporované aritmetické operátory jsou +, -, *, / (celočíselné dělení), % (zbytek po celočíselném dělení).
  7. Priority operátorů jsou standardní. Pokud si nejste jisti prioritou operátorů, použijte závorky.
  8. Ve vašich řešeních pro přehlednost vyžadujeme odsazování kódu dle příkladů na této stránce.
  9. Odsazuje se buď tabulátorem nebo 4 znaky mezera.
  10. Jazyk podporuje jednořádkové komentáře: cokoliv za znakem # se nezpracovává (včetně tohoto znaku).
  11. Na bílých znacích (mezery, tabulátory) nezáleží.

Vyhodnocování podmínky

Podmínka se vyhodnocuje tak, jak byste čekali: výraz and znamená logické a, < znamená menší než atp.

Jediným zvláštním výrazem v podmínce je tzv. selektor: to je například bbb------ nebo kk-----kk.

Selektor se vždy skládá právě z 9 symbolů. Těmito symboly mohou být písmena jednotlivých barev, nebo spojovník -. Těchto 9 symbolů popisuje po řádcích bezprostřední okolí buňky. V našem simulátoru má každá buňka vždy právě 8 sousedů.

Příklad: zápis bbb--r--b značí následující okolí:

bbb
--r
--b

Povolené barvy jsou: r: červená, b: modrá, g: zelená, k: šedá. V konkrétních úlohách mohou být omezeny.

Selektor se v podmínce vyhodnocuje na číslo. Toto číslo značí, kolik buněk z okolí se svou barvou shoduje se selektorem. Při tomto porovnávání se ignorují spojovníky (porovnáváme tedy pouze ty buňky, na jejichž pozicích se v selektoru nachází barva). Za každou shodu se zvýší hodnota selektoru o 1.

Příklad: Máme konfiguraci velikosti 4×4:

Pokud použijeme selektor na políčko (x=2, y=2) (červené), dostáváme číslo 5, protože okolí bbbgrrbbb souhlasí se selektorem bbb--r--b ve všech 5 vybaných barvách.

Počítání nové barvy

Ptáme se, jaká bude barva buňky na pozici (x=3, y=3) (modrá buňka) při použití výše zmiňovaného pravidla s více zanořeními a výše ukázaného čtverce 4×4. Okolí buňky vypadá takto: rrbbbgrrr.

  1. Vyhodnocujeme podmínku na řádku 1: if ((rrb------ % 2) == 1) or (------bbr >= 2):
  2. Protože okolí je rrbbbgrrr, tak hodnota selektoru rrb------ je 3 (všechny 3 barvy souhlasí).
  3. Protože okolí je rrbbbgrrr, tak hodnota selektoru ------bbr je 1 (pouze poslední písmeno r souhlasí).
  4. Máme výraz if ((3 % 2) == 1) or (1 >= 2):. Upravíme: if (1 == 1) or (1 >= 2):. Tento výraz platí, takže pokračujeme na řádek 2 zápisu pravidla.
  5. Vyhodnotíme podmínku if (bb-----bb + kk-----kk) >= 5:.
  6. Přepíšeme selektory podle okolí: if (0 + 0) >= 5:.
  7. Výraz je nepravdivý, skáčeme tedy do else větve.
  8. else větvi už je přímo barva: k, takže buňka v nové generaci bude mít šedou barvu.

Tento proces opakujeme pro každou buňku mřížky.

  • - (spojovník) označuje políčko libovolné barvy. Toto políčko se do výsledné hodnoty selektoru nepočítá.
  • Vytvářejte vždy pouze jedno pravidlo (jednu hlavní podmínku if) s libovolným počtem vnořených podmínek. Pro ty, kteří již mají nějaké zkušenosti s programováním: větve typu elif, else if zde nepoužívejte.
  • U krajních buňek v režimu rovina se selektory vyhodnocují pouze na platných okolních buňkách, tedy například hodnota selektoru na levé dolní buňce nemůže být větší, než 4.

Příklad pravidla

if bbb------ >= 1 or ------bbb >= 2:
    if kkkkkkkkk >= 5:
        b
    else:
        k
else:
    b

Pravidlo zkoumá, jestli je v horním řádku alespoň 1 modrá nebo jsou alespoň 2 modré ve spodním řádku. Pokud ano (tedy platí alespoň jedna z podmínek), tak zjišťuje, jestli je celkem alespoň 5 šedých. Když platí obě podmínky, tak bude prostřední buňka modrá. Pokud platí pouze první podmínka, tak bude šedá. Pokud neplatí ani první podmínka, prostřední buňka bude modrá.


Pro pokročilé: gramatika jazyka pravidla

Pokud byste měli nějaké nejasnosti, můžete nahlédnout do gramatiky jazyka pro zápis přechodového pravidla tak, jak ji akceptuje nástoj pyparsing.

color = Word(allowed_colors, exact=1)
integer = Word(string.digits)

selector = Word(allowed_colors + '-', exact=1) * 9

num_operation = infixNotation(
    (selector | integer),
    [
        ('*', 2, opAssoc.LEFT),
        ('/', 2, opAssoc.LEFT),
        ('+', 2, opAssoc.LEFT),
        ('-', 2, opAssoc.LEFT),
        ('%', 2, opAssoc.LEFT),
    ]
)

operator = oneOf('>= <= != > < ==')
comparison_token = num_operation | selector | integer
comparison = (comparison_token + operator + comparison_token)

bool_expr = infixNotation(
    comparison,
    [
        ('and', 2, opAssoc.LEFT),
        ('or', 2, opAssoc.LEFT),
    ]
)

rule = Forward()
condition = Word('if') + bool_expr + Word(':') + rule + Word('else:') + rule
rule << (condition | color)