Zadanie

Ak máte akékoľvek otázky ohľadom tejto úlohy napíšte Mariánovi Horňákovi na

Pracovitým KSP vedúcim, ktorí študujú na matfyze, počas písania nových zadaní vysmädlo. Avšak sú príliš zaneprázdnení a preto si kofolu nestíhajú ísť kúpiť sami. Postavili si preto robota, ktorý kofolu prinesie za nich.

Matfyz je ale miesto veľmi zradné1. Na kľukatých chodbách z podlahy niekedy šľahá oheň (to je bežné, tak sa tam kúri) a preto robot prechádzajúci takým miestom musí najskôr kúrenie pomocou tlačítka vypnúť. Vieš im pomôcť tohoto robota naprogramovať?

Úloha

Dostanete prístup k programovaciemu rozhraniu robota, 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 stačiť pamäť.

Celý návod k hre ako aj k programovaciemu jazyku nájdete 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 3 body. 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. To znamená, že k tejto úlohe nie je nutné odovzdávať žiaden popis alebo tradičným spôsobom odovzdávať program.

Hru nájdete na stránke ksp.sk/specialne/ksp/32/3/1.


  1. Balkóny dvojnásobne

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 študíjneho 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.

Zamýšľaná trajektória

Zamýšľaná trajektória

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.

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. [text o rekurzii]: TO_DO

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ť.