Zadanie
Táto úloha je špeciálna. Nemusíš odovzdávať nič, vždy keď splníš level automaticky dostaneš body.
Archeológovia z Prasku nedávno narazili na vzácny objav. Ide o historicky prvého robota, ktorý sa takmer okamžite stal hitom a hrubou čiarou sa zapísal do histórie. Za záhadných okolností však po presne jednom roku zmizol a odvtedy sa o ňom už len šírili legendy. Možno si aj ty nejakú počul/a. Ide o robota menom ZergBot.
Teraz, po takmer desaťročí, sa ho podarilo exkavovať. Podišiel patričnú reštauráciu, ale až na drobné detaily bude najbližiu sériu vystavený na nasledovnej adrese: https://www.ksp.sk/specialne/prask/8/1/1/
Úloha
Dostanete prístup k programovaciemu rozhraniu ZergBota, spolu s náhľadom na level. V tomto rozhraní môžete pomocou jednoduchého programovacieho jazyka napísať pre robota program. Po napísaní si program môžete hneď aj spustiť a uvidíte, ako sa robot vďaka nemu pohybuje.
Vašou úlohou bude napísať program, pomocou ktorého robot bez ujmy na obvodoch prejde bludiskom. Samozrejme mu musí vydržať batéria a vystačiť pamäť.
Celý návod k hre ako aj k programovaciemu jazyku nájdete tu alebo v hlavnom menu hry, kliknutím na veľké tlačítko Návod.
Odovzdávanie a bodovanie
V súťažnej sérií bude 5 levelov, každý za 20 bodov. Akonáhle spustíte správny program a robot sa s jeho pomocou dostane do cieľa, budú vám automaticky pripísané body za daný príklad. Nebojte sa ak sa vám body vo výsledkovke nezobrazia hneď, časom sa tam objavia. V prípade problémov nám napíš na [email protected]
1 - Komnata
Tu stačilo robota odnavigovať na správne tlačidlo, prepnúť ho a odnavigovať do cieľa. To, ktoré tlačidlo je správne, sa dalo zistiť napríklad tak, že ste postupne vyskúšali všetky. Správne bolo tretie tlačidlo zdola.
Kód:
doprava
krok
krok
doprava
krok
prepni
doprava
krok
krok
doprava
krok
krok
krok
2 - Učko
V tomto leveli je na prvý pohľad jasné, čo má robot urobiť. Problém ale je, že nemá dosť pamäte na všetky príkazy. Môžeme si však všimnúť, že U-čko sa skladá z troch rovnakých častí. Napíšeme si teda funkciu, ktorá nám prejde jednu časť U-čka a túto funkciu potom zavoláme trikrát za sebou. Treba si však dať pozor, aby bol robot po dokončení jedného ramena U-čka správne otočený, na konci funkcie ho preto otočíme doprava.
Kód:
funkcia0
funkcia0
funkcia0
aha funkcia0:
krok
prepni
krok
krok
doprava
3 - Schody
Potrebujeme prejsť veľa rovnakých schodov, preto sa nám oplatí napísať si funkciu na prejdenie jedného schodu:
aha funkcia0:
krok
doprava
krok
dolava
Teraz však narazíme na problém: môžeme použiť už iba dva príkazy a schodov je oveľa viac, než dva.
Použijeme preto jeden zaujímavý trik: napíšeme funkciu, ktorá prejde jeden schod a potom zavolá sama seba. Keď sa táto funkcia začne vykonávať, prejde jeden schod a sama sa zavolá znovu. Opäť prejde jeden schod a znovu sa zavolá. A takto bude náš program pokračovať až do nekonečna, resp. kým robotovi nedôjde batéria alebo nepríde do cieľa.
Kód:
funkcia0
aha funkcia0:
krok
doprava
krok
dolava
funkcia0
Ako už viete zo študijného textu, tento princíp sa volá
rekurzia. V našom prípade ide o nekonečnú rekurziu, čo pekne
vystihuje Obr. 4. Na našu funkcia0
sa môžeme pozerať tak,
že je to funkcia, ktorá prejde nekonečne veľa schodov. Urobí to tak, že
najprv prejde jeden schod (prvé 4 príkazy) a potom ešte nekonečne veľa
ďalších (posledný príkaz).
4 - Šachovnica
Najjednoduchšie asi bude ísť po riadkoch a cestou prepnúť správne políčka.
Existuje viacero spôsobov, ako prejsť takúto cestu. Jednou z možností je napísať si štyri funkcie, ktoré sa navzájom volajú v nekonečnej rekurzii. My si ale vystačíme aj s niečím jednoduchším.
Budeme potrebovať, aby robot prepol prepínač na každom druhom políčku, cez ktoré prejde. Napíšme si teda funkciu, ktorá prejde dve políčka, pričom to, na ktoré stúpi skôr, prepne:
aha funkcia0:
krok
prepni
krok
S jej pomocou si môžeme napísať funkciu, ktorá prejde jeden riadok šachovnice a prepne pri tom potrebné políčka – za predpokladu, že štartujeme na tom konci riadka, ktorý nemá byť zapnutý:
aha funkcia1:
funkcia0
funkcia0
funkcia0
funkcia0
Všimnime si, že táto funkcia sa po zapnutí posledného prepínača v riadku bude snažiť urobiť ešte jeden krok. To nám ale neprekáža, robot sa iba pokúsi urobiť krok do steny (alebo na JetTorch, ktorý už v tom čase bude vypnutý).
Aj na prejdenie ľavotočivej a pravotočivej zákruty si môžeme napísať funkcie:
aha funkcia2:
dolava
krok
dolava
aha funkcia3:
doprava
krok
doprava
Na ceste, po ktorej má robot prejsť, sa striedajú rovné úseky a zákruty, pričom zákruty sú striedavo ľavotočivé a pravotočivé. Napíšme si teda funkciu, ktorá nám prejde dva rovné úseky a zákruty nasledujúce po nich:
aha funkcia4:
funkcia1
funkcia2
funkcia1
funkcia3
Keď túto funkciu zavoláme štyrikrát po sebe, robot by mal prejsť celú
šachovnicu. Problém ale je, že po prejdení posledného riadka sa bude
snažiť prejsť ešte jednu pravotočivú zákrutu. Preto ju radšej zavoláme
iba trikrát a posledné dva rovné úseky (aj so zákrutou medzi nimi)
rozpíšeme. Robot by potom skončil na políčku s JetTorchom (nezabúdajte,
že funkcia1
sa po prejdení riadka snaží urobiť ešte jeden
krok), preto na koniec pridáme ešte jeden krok.
Hlavný kód:
funkcia4
funkcia4
funkcia4
funkcia1
funkcia2
funkcia1
krok
5 - Zeleno-modrá cesta
Kľúčovým pozorovaním v tomto leveli je to, že po zapnutom tlačidle treba ísť najbližšie dva kroky smerom na juh a po vypnutom prepínači treba ísť najbližšie dva kroky smerom na východ. Po urobení dvoch krokov správnym smerom sa bude robot nachádzať na nasledujúcom prepínači.
Tiež si môžeme všimnúť, že máme povolených iba veľmi málo príkazov. Preto opäť využijeme nekonečnú rekurziu: napíšeme si funkciu, ktorá (za predpokladu, že robot stojí na prepínači) urobí dva kroky správnym smerom, a potom sa zavolá znovu. Ak si sa s rekurziou nestretol/la, odporúčame ti prečítať si text o rekurzívnych funkciách v Kuchárke.
Tu ale narazíme na jeden problém: robot nevie zistiť, ktorým smerom je práve otočený, teda nebude vedieť, ktorým smerom je východ a ktorým smerom je juh. To môžeme vyriešiť tak, že vždy potom, čo robot prejde na ďalší vypínač, sa otočí na východ (teda ak išiel na juh, otočí sa doľava a ak išiel na východ, ostane tak, ako je). Na to si ale bude musieť pamätať, či bolo predošlé tlačidlo stlačené alebo nie. To docielime tak, že namiesto toho, aby sa robot na tlačidle iba otočil alebo neotočil (podľa toho, či je zapnuté), a potom urobil dva kroky, sa na tlačidle zavolá buď funkcia, ktorá urobí dva kroky smerom na východ, alebo funkcia, ktorá urobí dva kroky smerom na juh a potom sa otočí na východ.
Kód:
funkcia0
aha funkcia0:
funkcia1 ak svieti
funkcia2 ak nesvieti
funkcia0
aha funkcia1:
doprava
krok
krok
dolava
aha funkcia2:
krok
krok
Počas behu programu si môžeme všimnúť, že niekedy sa v jednom volaní
funkcia0
zavolá aj funkcia1
aj
funkcia2
(nastane to vtedy, keď je robot na zapnutom
tlačidle, ale po vykonaní funkcia1
sa ocitne na vypnutom
tlačidle). To nám v našom prípade neškodí, ale keby sme chceli, aby sa v
jednom volaní funkcia0
zavolala vždy iba jedna z funkcií 1
a 2, mohli by sme to docieliť napríklad tak, že by sme
funkcia0
zavolali aj na konci funkcia1
. Teda
ak by tlačidlo bolo zapnuté, netestovalo by sa, či sa má spustiť
funkcia2
.
Diskusia
Tu môžte voľne diskutovať o riešení, deliť sa o svoje kusy kódu a podobne.
Pre pridávanie komentárov sa musíš prihlásiť.