Rubikarna
10.05.09
Prográmek Rubikarna je interaktivní simulátor Rubikovy kostky. Jeho hlavní součástí je navíc malý skriptovací jazyk pro manipulaci s Rubikovou kostkou, který sem pro tento účel navrhnul. Pokud vás to zajímá podrobněji, tak v dokumentaci níže je celkem vyčerpávající popis prográmku.

Obsahuje program, dokumentaci a zdrojáky.


Aby to fungovalo je potřeba mít nainstalován Microsoft .NET Framework 3.5. Ten by měl být ke stažení tady.




Dokumentace programu Rubikarna

Tomáš Křen
Zápočtový program
Programování II - PRG031
letní semestr 2007/8

Obsah

Stručný popis

Program Rubikarna je interaktivní simulátor Rubikovy kostky. Jeho hlavní součástí je navíc skriptovací jazyk pro manipulaci s Rubikovou kostkou.

Vymezení pojmů

Rubikova kostka

Rubikovou kostkou je myšlen hlavolam ve všeobecně známé podobě. Jedná se o krychli, jejíž každá strana je tvořena 3x3 barevnými čtverci. Kostku můžeme třemi různými způsoby rozdělit na tři vrstvy: horizontálně, vertikálně a předo-zadně. Jak je to myšleno a označení jednotlivých vrstev je patrné z následujícího obrázku:

Každou z těchto myšlených vrstev můžeme otočit a tím dostat kostku do nového stavu. Přesný popis těchto manipulací bude uveden dále.

V počátečním stavu je kostka složená tak, že na každé straně kostky jsou čtverce pouze jedné barvy. Úkolem "hráče" tohoto hlavolamu je pomocí otáčení vrstev kostky dostat zamíchanou kostku (tj. kostku, která byla uvedena otáčením vrstev do jiného než počátečního stavu) do počátečního stavu.

Dva druhy manipulace s kostkou a koncept pevně ukotvené kostky

Ačkoliv je v reálném světě Rubikova kostka předmět, se kterým lze jako s celkem libovolně pohybovat (tzn. mimo to že můžeme pohybovat jednotlivými vrstvami kostky, můžeme také pohybovat s kostkou samotnou), my se na kostku budeme dívat jako na pevně ukotvenou věc. Manipulace s kostkou jako celkem je ale pohodlný prvek pro její řešení, rozšíříme tedy proto sadu možných tahů o tahy odpovídající manipulaci s kostkou v realném prostoru.

Pozice čtverců na kostce

Na čtverce (čtverec je jeden z devíti dílků jedné strany kostky) se díváme tak, že manipulacemi s kostkou se jejich pozice nemění; to co se manipulacemi s kostkou mění je barva čtverců. Proto můžeme každému čtverci přisoudit jednoznačnou pozici. Tato pozice je reprezentována jménem strany, na které se čtverec nachází, a dále pozicí v rámci této strany. Díky tomu, že na kostku hledíme jako na pevně ukotvenou, je přirozené nazvat strany podle pozice jakou zaujímají vůči pozorovateli. V rámci jedné strany přisoudíme jednotlivým čtvercům čísla od 0 do 8. Jak konkrétně to je provedeno je patrné z tohoto obrázku sítě krychle představující kostku v počátečním stavu:

Pozice čtverce je tedy reprezentováná trojmístným kódem, první dva znaky jsou písmena určující stranu kostky, třetí znak je číslo určující pozici v rámci strany.

V programu je někdy použito pro identifikaci strany její stringové označení, jindy číselné označení. Platí následující přiřazení:

  • FR - 0
  • RI - 1
  • BA - 2
  • LE - 3
  • TO - 4
  • BO - 5

Barvy

Čtverce mají vždy jednu z šesti barev. Barvy mají následůjící označení:
  • R - červená
  • G - zelená
  • O - oranžová
  • Y - žlutá
  • B - modrá
  • W - bílá

Kostička

Kostička je pojem přímo inspirovaný fyzickými kostičkamy jimiž je tvořen povrch Rubikovy kostky. Každá kostička má alespoň jeden čtverec (tak jak ho chápeme v rámci Rubikovy kostky). Těchto kostiček je na kostce celkem 26 a jsou trojího druhu:

  • Rohové - Ty mají tři čtverce
  • Hranové - Ty mají dva čtverce
  • Centrální - Ty mají jediný čtverec

Kostičku (přesněji její polohu) můžeme jednoznačně určit pokud uvedeme jeden její čtverec. V programu se pro určení polohy kostičky používá následující notace: c[pozice-nějakeho-jejího-čtverce]
Tedy poloha kostičky, která má čtverce FR2, TO8 a RI0, se zapisuje jako cFR2, cTO8 nebo RI0. Čili může být více možností, jak označit polohu nějaké kostičky.

U kostičky dále hovoříme o její barvě. Barva kostičky je trojice, dvojice nebo jednoice barev, které nabívají čtverce. Pořádí těchto barev není podstatné. Barvy kostiček se značí následovně: c[barva-1][barva-2 (nepovinné)][barva-3 (nepovinné)]
Přičemž pokud je barev více, jejich pořadí v označení je libovolné.
Říkáme, že kostička k má barvu b, pokud odpovídá počet stran kostičky k a počet barev barvy b a pokud barvy čtverců kostičky k odpovídají barvám barvy b (znovu: na pořadí nezáleží).
Příklad: barva cYOW je stejná jako barva cWYO. Kostička cFR0 má barvu cYOW pokud má tři čtverce a ty jsou obarveny žlutou, oranžovou a bílou.

Myslím, že pojem kostičky je dostatečně jasný na to aby zde bylo potřeba výslovně specifikovat, které kostičky mají které čtverce. Uvedu tedy jen několik příkladů:

cFR0 má čtverce FR0, LE2 a TO6 (je to rohová kostička)
cLE2 má také čtverce FR0, LE2 a TO6, protože je to ta samá kostička
cTO2 má čtverce RI2, BA0 a TO2 (také rohová)
cBA3 má čtverce BA3 a RI5 (je to hranová kostička)
cBO4 má jediný čtverec BO4 (je to centrální kostička)

Manipulace s kostkou

Jak bylo řečeno výše, jsou dva základní typy manipulace s kostkou.

Rotace vrstev

První typ manipulace s kostkou je rotace některé z jejích vrstev. Existuje 9 vrstev, které můžeme rotovat, každou z nich dvěma způsoby (po nebo proti směru hodinových ručiček).
Jmenovitě to jsou vrstvy FRa, FRb, FRc, LEa, LEb, LEc, TOa, TOb a TOc.
Vrstvy jsou pojmenovány podle jedné ze stran, která je s nimi rovnoběžná a navíc maji za sebou příponu a, b nebo c podle toho jak jsou od strany daleko. To zda rotujeme vrstvu po nebo proti směru hodinových ručiček se zjistí tak, že na kostku na chvíli hledíme jakoby byla směrem k nám natočena stranou podle které je vrstva pojmenována.
Kód pro jednotlivé manipulace je následující: [jméno-vrstvy]CW nebo [jméno-vrstvy]CC. CW pro rotace po směru hodinových ručiček, CC proti směru.
Tedy například: LEbCC, TOcCW, FRaCW atd.

Navíc existují alternativní kódy pro některé často používané manipulace. Jmenovitě to jsou tyto:

  • U - odpovídá TOaCW (U jako UP)
  • Ui - odpovídá TOaCC (Ui jako UP inverted)
  • D - odpovídá TOcCC (D jako DOWN)
  • Di - odpovídá TOcCW (Di jako DOWN inverted)
  • L - odpovídá LEaCW (L jako LEFT)
  • Li - odpovídá LEaCC (Li jako LEFT inverted)
  • R - odpovídá LEcCC (R jako RIGHT)
  • Ri - odpovídá LEcCW (Ri jako RIGHT inverted)
  • F - odpovídá FRaCW (F jako FRONT)
  • Fi - odpovídá FRaCC (Fi jako FRONT inverted)

Popíšem rotaci TOaCC a TObCW aby nebylo pochyb o tom jak rotace probíhají, ostatní rotace jsou zcela analogické, pokud by bylo pochyb jak probíhají, lze to zjistit přímo v programu nebo si stačí pohrát s Rubikovou kostkou. Manipulace s kostkou na kostku pusobí tak, že se změní obarvení jejích čtverců. TOaCC probíhá následovně: FR0 získá minulou barvu jako LE0, FR1 jako LE1, FR2 jako LE2, RI0 jako FR0, RI1 jako FR1, RI2 jako FR2, BA0 jako RI0, BA1 jako RI1, BA2 jako RI2, LE0 jako BA0, LE1 jako BA1, LE2 jako BA2, tím se zrotoval "plášť" a ještě je potřeba zrotovat "vršek" tedy dále TO0 získá minulou barvu jako TO2, TO1 jako TO5, TO2 jako TO8, TO3 jako TO1, (TO4 zůstane), TO5 jako TO7, TO6 jako TO0, TO7 jako TO3 a TO8 jako TO6.
TObCC probíhá následovně: FR3 získá minulou barvu jako LE3, FR4 jako LE4, FR5 jako LE5, RI3 jako FR3, RI4 jako FR4, RI5 jako FR5, BA3 jako RI3, BA4 jako RI4, BA5 jako RI5, LE3 jako BA3, LE4 jako BA4, LE5 jako BA5, tím se zrotoval "plášť" a jelikož při rotaci prostředních vrstev není žádný "vršek" k rotování, jsme hotovi.

Rotace celé kostky

Je 6 manipulací s celou kostkou, jmenovitě: rTO, rBO, rRI, rLE, rCW, rCC. Všechny tyto rotace jsou rotace celé kostky o 90°. První čtyři mají jako druhé a třetí písmenko v názvu jméno strany která zaujme pozici kterou teď má strana FR. Manipulace rCW a rCC představuje rotaci okolo osy kolmé na stranu FR, rCW je po směru hodinových ručiček, CC proti směru.

Skriptovací jazyk Rublan

Úvod

Rublan je jednoduchý skriptovací (tím je myšleno že je interpretovaný) jazyk určený pro manipulaci s Rubikovou kostkou.

Jde o jazyk řádkově orientovaný, tedy v každém jednom kroku interpretace kódu se načte patřičný řádek kódu, načež se provede příslušná akce a spočítá se další řádek kódu, kde bude program pokračovat v dalším kroku.

Jazyk obsahuje několik vestavěných příkazů a možnost definovat příkazy vlastní ve formě maker. Jmenovitě jsou to tyto příkazy:

  • podmínkové příkazy IF, ELSE a ENDIF
  • cyklový příkaz WHILENOT a ENDWHILE
  • MACRO a ENDMACRO pro definici makra
  • příkaz volání makra _
  • příkaz pro vykonání manipulace s kostkou !
  • příkaz pro textový výstup :
  • komentář #

Makra

Makro je úsek kódu, který se začne provádět, pokud je zavolán příkaz

_[jméno-makra]
Přesněji to znamená to, že pokud interpret narazí na řádek začínající podtržítkem a pokračující jménem makra, bude v příštím kroku zpracovávat první řádek makra. A po spracování posledního řádku makra skočí v dalším kroku na řádek bezprostředně po řádku odkud bylo makro voláno.

Definice makra vypadá následovně: První řádek makra je klíčové slovo MACRO následované jménem makra (to nesmí obsahovat mezery a jiné bílé znaky, jinak může být z libovolných znaků), další řádky obsahují samotný kód makra a na posledním řádku makra je klíčové slovo ENDMACRO. Příklad takového kódu:

MACRO dejNahoru
  #na vršek dáme bílou kostičku
  #nejdřív zjistíme zda není bílá na nějakém boku
  #a pokud jo tak otočime kostkou aby se dostala pryč
  IF $0 ison LE4 | $0 ison RI4
    !rLE
  ENDIF
  #ted ji dame nahoru
  :napisem to i na vystup, ted ji dame nahoru
  WHILENOT $0 ison TO4
   !rBO
  ENDWHILE
ENDMACRO

Každý prováděný kód v jazyce Rublan musí být uvnitř nějakého makra. Po startu interpretace kódu se skočí na povinné makro main. Každý script musí mít definované makro, které má jméno main (podobně jako v C-like jazycích).

Parametry makra

Navíc k tomu, co už bylo řečeno, je možnost volat každé makro s až desíti parametry. Parametrem je libovolný textový řetězec bez bílých znaků. Parametry předáváme makru tak, že při jeho volání za jméno makra napíšeme těchto až deset parametrů oddělných mezerami. Například
_napasujRuzky G R
znamená, že jsme zavolali makro napasujRuzky s argumenty G a R.
Tyto argumenty jsou pak uvnitř makra k dispozici díky tomu, že každá řádka, před tím nežli je vykonána tak jsou v ní nahrazreny všechny výskyty znaku $ následovaného číslem od 0 do 9 argumentem se kterým bylo makro voláno. $0 odpovídá prvnímu argumentu, $1 druhému, $2 třetímu a tak dále.

Ačkoliv parametry mohou být libovolný řetězec, jsou zamýšleny hlavně jako způsob jak makru předat variabilní informaci o tom s jakou barvou/barvami operujeme.

Logické výrazy

Cyklus a podmínkový příkaz využívají toho, že v jazyce Rublan lze sestavit logický výraz, tedy textový řetězec u kterého lze rozhodnout zda je pravdivý či nepravdivý. Logický výraz dostaneme skládáním elementárních logických výrazů za pomoci závorek a binárních operátorů pro logické operace (klasicky v infixové podobě). Jazyk v současnosti podporuje 3 binární operace:
  • & - logický AND
  • | - logický OR
  • x - logický XOR
Jednotlivé prvky logického výrazu můžeme ale nemusíme oddělovat mezerou. Všechny operátory mají stejnou prioritu. Výraz typu x1 op1 x2 op2 x3 (kde x jsou operandy, op operatory) je chápán jako výraz (x1 op1 x2) op2 x3

Elementární logické výrazy

Jednak mezi elementární logické výrazy patří 0 (představující nepravdu) a 1 (představující pravdu). Hlavně sem však patří "trojslovné" výrazy tvaru
[jméno-barvy-čtverce nebo kostičky] ison [jméno-pozice-čtverce nebo kostičky]
Takovýto elementární výraz je pravdivý pokud je pravda, že v aktuálním stavu kostky je pravda že čtverec/kostička na uvedené pozici má uvedenou barvu. Příklady několika takovýchto výrazů:
cRG ison cFR5 
G ison TO7
cYOW ison cRI6
B ison BO7

Několik příkladů logického výrazu

1 | 0 & 1
O ison FR2 & Y ison RI0
cW$0 ison cFR3 | cW$0 ison cFR5 | cW$0 ison cRI5 | cW$0 ison cLE3
1x ( G ison FR6 | (cGR ison cLE1 & B ison TO7) )

IF, ELSE a ENDIF

K větvení slouží v Rublanu příkaz IF následovaný mezerou a logickým výrazem. Pokud je výraz vyhodnocen jako pravdivý, je jako další řádek zpracováván ten bezprostředně za řádkem s příkazem IF pokud je narazeno na odpovídající ELSE, je kód po něm přeskočen. Pokud není výraz vyhodnocen jako pravdivý, skočí se na odpovídající ELSE (pokud existuje, není totož povinné). Pokud neexistuje, skočí se na řádek bezprostředně za odpovídajícím ENDIF. Prostě klasické chování IFu a ELSEu.
Příklady:
IF O ison FR2 & Y ison RI0
  !R
ELSE
  !Ri
  !U
ENDIF

IF cGRB ison RI0
  !R
  !U
  !Di
ENDIF

WHILENOT

WHILENOT je jediný cyklus jazyka Rublan. Slovo WHILENOT je následováno logickým výrazem. Pokud je výraz vyhodnocen jako pravdivý, pak cyklus končí a program bude dále pokračovat na řádce bezprostředně za odpovídajícím ENDWHILE. Pokud je výraz nepravdivý, pokračuje se příkazem bezprostředně za řádkem s WHILENOT a při příchodu na odpovídající ENDWHILE se skáče znovu na WHILENOT aby byla otestována podmínka.
Příklady:
WHILENOT $0 ison FR4
  !rLE
  :a třeba napiš bum
ENDWHILE

WHILENOT $0 ison FR2 & $1 ison RI0
  _mainTrick
ENDWHILE

Příkazy pro manipulaci s kostkou

S kostkou se manipuluje velice jednoduše, stačí napsat vykřičník následovaný kódem manipulace.
Příklady:
  !Ui
  !Li
  !LEaCW
  !rLE
  !L
  !U
  !TOcCC
  !LEaCC
  !U
  !rBO
  !F

Textový výstup a komentář

Vytisknout řádku na textový výstup je v Rublanu jednoduché, je to dvojtečka bezprostředně následovaná textem určeným k vypsání.
Komentář je jakákoliv řádka začínající heškřížem #. Příklady:
  #nejdřív zjistíme zda není bílá na nějakém boku
  :kostku zas otacime zlutou dopredu

Poznámka o absenci proměnných

V jazyce chybí institut proměnné do které by se dala dosazovat hodnota. Není to ani tak zásluha lenosti se s takovou věcí programovat(i když částečně určitě taky), ale možná je to spíš způsobeno myšlenkou, že bez proměnných bude způsob řešní více připomínat reálného hráče Rubikovy kostky, který si při řešení také nepíše nic na papírek a jediné místo kam si něco zaznamenává je kostka samotná.

Uživatelské prostředí

Program má jednoduché grafické uživatelské prostředí.

Prostředí se sestává ze tří hlavních částí. Nalevo je vykreslená Rubikova kostka a její síť. Zde jsou také šipečky, kterými lze vykonávat manipulace s kostkou. Myslím že jsou dost intuitivní, pokud ne tak po jejich stiknutí se vypíše do okna Output jejich význam.
S touto částí souvisejí ještě tyto ovládací prvky:

  • RESET - po zmáčknutí se kostka vrátí do počátečního stavu
  • RandTah - provede se náhodná manipulace s kostkou (neprovadejí se ale rotace s celou kostkou, jen rotace některé vrstvy)
  • shuffle - provede se tolik náhodných manipulací s kostkou, kolik je číslo vedle tlačítka

Uprostřed je textové pole Input, které je určeno k tomu, aby zde uživatel napsal svůj skript v jazyce Rublan.
Program se při svém startu pokusí nahrát do tohoto pole obsah souboru ./scripts/default.txt a pokud se to nepovede tak nechá pole prázdné. S tím souvisí tato tlačítka:

  • RUN! - způsobí že se skript začne provádět
  • RUN macro - způsobí že začne provádět makro napsané do textboxu vedle.
  • start debugging - po stisknutí tohoto tlačítka je interpret připraven začít krokovat program od začátku po jednotlivých krocích
  • 1STEP - interpret provede jeden řádek kódu, při následném stisknutí provede další řádek a tak dále. Pro zahájení tohoto krokování od začátku je potřeba stisknout tlačítko start debugging
  • LOAD - slouží pro nahrání textového souboru jako obsahu pole Input
  • SAVE AS - umožňuje uložit obsah pole Input do textového souboru

Napravo je pole Output kam se vypisují veškeré textové výstupy programu; to znamená že se sem vypisují veškeré provedené manipulace s kostkou, také všechna zdělení od interpretu Rublanu a textový výstup prováděného skriptu. Tlačítkem CLEAR lze obsah okna Output vymazat. Checkboxem show interpret info můžeme zapnout/vypnout vypisování informačních hlášek od interpretu.

Informace o vývoji programu a komapatibilitě

Program byl psán ve vývojovém prostředí Microsoft Visual C# 2008 Express Edition, tedy byl napsán v jazyce C#. Je určen pro platformu Windows a k jeho správnému běhu je potřeba mít nainstalován .NET Framework 3.5.

Možné praktické využití programu

Program je možno využít k tomu abychom mohli porovnat jednotlivé strategie používané lidmi k řešení Rubikovy kostky co se týče jejich efektivity.

Výhled do budoucna programu

Přiznávám se, že program jsem dokončoval dost ve spěchu a tak neobsahuje ještě některé další možnosti, které bych v něm rád viděl.
Jmenovitě jsou to následující nedodělky:

  • Chtěl bych program obohatit o rozsáhlejší sada ukázkových algoritmů na Rubikově kostce
  • Vytvořit prostředí pro porovnávání algoritmů
  • Vytvořit lepší krokovací možnosti (breakpointy atd.)
  • Zpohodlnit práci se soubory zdrojového kódu
  • Implemetovat pojistku proti zacyklení

Poznámky

  • Ve zdrojových kódech se často používa pro pojem v této dokumentaci nazvaný jako čtverec pojem políčko.
  • Alternativní kódy pro některé často používané manipulace byly přejaty z videa http://www.youtube.com/watch?v=HsQIoPyfQzM



Tady k tomu můžete napsat komentář
Jméno:
Opište text v rámečku: