Soutěž v programování – 31. ročník
Celostátní kolo 2016/2017
Přestože to asi nevíte, minulou neděli jsme oslavili významné jubileum – uplynulo 420 kilohodin od prvního přistání na Měsíci (nemáte-li rádi kilohodiny, jakkoliv je to nepochopitelné, jedná se o 17,5 kilodní neboli 2,5 kilotýdnů). Kvůli nadbytečnému použití motorů v první fázi přistání dosedal modul kilometry od plánované lokality, na místo plné velkých kamenů. Proto převzal Neil Armstrong řízení a přistál ručně. Po dosednutí zbylo v nádrži palivo na méně než 30 vteřin letu.
I vy máte možnost si dnes zkusit přistát na Měsíci s ručním řízením a také naprogramovat automatického pilota. Pro zjednodušení si přistání představujme pouze v rovině. Přistání probíhá tak, že získáte kontrolu nad modulem v jisté výšce nad zvoleným místem přistání a vaším cílem je na tomto místě přistát tak, aby rychlost v okamžiku přistání umožnila bezpečné dosednutí modulu na povrch.
K dispozici máte tři motory – jeden urychlující modul směrem vzhůru, druhý doleva a třetí doprava. Každý z nich samozřejmě spotřebovává palivo, kterého máte jen omezené množství.
Modul ovládáte tak, že posíláte požadavky serveru, který vám poskytuje informace
o pozici a rychlosti modulu a kterému signalizujete spuštění či vypnutí
motorů. Komunikace probíhá pomocí protokolu HTTP, všechny požadavky se
provádějí metodou GET
, server vrací data typu
text/plain
v ASCII kódování a odděluje řádky pomocí
znaků CR
a LF
.
Přistání začne požadavkem na http://adresa/start
(adresa bude popsána později). Odpověď serveru má 5 řádků.
První řádek obsahuje identifikační číslo přistání (celé číslo od jedné do miliardy).
Druhý řádek obsahuje pozici středu modulu – dvě čísla X a Y (viz obrázek na následující straně).
Třetí řádek obsahuje rychlost modulu, opět jako dvě čísla
VX a VY. Na čtvrtém řádku je množství
paliva P v nádrži. Na posledním řádku je pozice přistávací plochy
jako dvě čísla L a R. Všechna čísla (kromě identifikačního čísla
přistání) jsou desetinná, jsou zapsána pomocí desetinné tečky (bez použití
exponentu) a pokud jich je na řádku víc, jsou oddělena právě jednou mezerou.
Souřadnice X se měří horizontálně a roste zleva doprava, souřadnice Y je výška nad povrchem a směrem dolů klesá. Povrch měsíce i přistávací plocha jsou ve výšce 0. Přistávací modul má velikost 20×20.
Pokud máte rádi fyziku a zajímá vás, v jakých jednotkách se souřadnice X a Y vyjadřují, vězte, že v jakometrech, které mají značku jm.
Od okamžiku, kdy je zahájeno, probíhá přistání na serveru v reálném čase. Aktuální stav můžete
zjistit kdykoliv pomocí požadavku
http://adresa/stav?id=identifikační-číslo-přistání
,
přičemž server odpoví stejně jako v předchozím případě. Můžete navíc ovládat
motory – požadavek stav
má tři nepovinné argumenty
doleva
, doprava
a nahoru
, které
pomocí hodnot 0
a 1
vypínají či zapínají motory
působící v daném směru (tedy například zapnout motor působící směrem nahoru
a vypnout všechny ostatní lze pomocí požadavku
http://adresa/stav?id=id&nahoru=1&doleva=0&doprava=0
).
Činnost motoru se změní přesně v době požadavku. Pokud nějaký z parametrů
doleva
, doprava
či nahoru
není
přítomen, činnost příslušného motoru se nemění.
Od chvíle, kdy přistání skončí, odpovídá server na požadavek
stav
vždy jedním řádkem, a to buď s hodnotou Zdar!
(v případě úspěšného přistání) nebo Krach!
(v případě neúspěšného přistání).
Řekněme, že modul se nachází na pozici X, Y s rychlostí VX, VY a množstvím paliva P. Proměnné doleva, doprava a nahoru mají hodnotu 0 nebo 1 podle toho, zda je příslušný motor vypnutý či zapnutý. Za T sekund, ve kterých nedošlo ke změně činnosti motorů, bude pozice, rychlost a množství paliva následující:
Přistání je úspěšné, pokud v okamžiku dosednutí modulu na povrch (Y=10) je celý modul nad přistávací plochou (X-10≥L a současně X+10≤R) a jeho rychlost není v žádném směru vyšší než 5. Pokud modul tyto podmínky v okamžiku dosednutí na povrch nesplňuje, je přistání neúspěšné. Když modulu dojde palivo, pokračuje v letu, ale motory od této doby již nepracují (tj. pohyb pokračuje dle uvedených rovnic, ale doleva, doprava a nahoru mají hodnotu 0).
Vaším úkolem je naprogramovat klienta pro přistání na Měsíci. Můžete napsat
klienta, který umožní interaktivní ovládání modulu uživatelem nebo automatické
řízení. Pokud to stihnete, můžete naprogramovat klienty oba dva. Oba klienti
mohou být součástí jedné aplikace, nebo to mohou být aplikace dvě. Každý klient se
musí umět připojit k libovolnému serveru a na libovolný port, výchozí
adresa je localhost:8000
. Při psaní programu můžete
předpokládat, že odpovědi serveru jsou korektní, a nemusíte tedy
ošetřovat chybný formát odpovědi serveru.
Kromě níže uvedených bodů za funkcionalitu můžete získat až 20 bodů za přehlednost zdrojového kódu a komentáře.
Implementujte nejprve obě následující funkce:
Dále v libovolném pořadí implementujte následující funkce:
Bude hodnocena i grafická úroveň, plynulost simulace a ergonomie ovládání. Dostáváte k dispozici obrázek modulu, ale můžete použít i vlastní.
Implementujte klienta automatického řízení přistání počítačem. Klient bude vyhodnocen na několika simulacích přistání. Za každé úspěšné přistání získá 50 % bodů a zbytek podle množství ušetřeného paliva (nejlepší z vašich řešení získá za přistání 100 %, a přistání, po kterém nezůstane žádné palivo, získá 50 %).
Klienty budeme testovat na třech různých druzích přistání – můžete tedy implementovat jen některé z nich:
Kvůli možnosti automatického vyhodnocení musí klient používat
parametry z příkazového řádku – první je adresa serveru (např.
localhost:8000
) a druhý je omezení maximální rychlosti
(hodnota omezení maximální rychlosti je nula pro první
dva druhy přistání). V případě, že jsou tyto parametry zadány, musí
klient bez další interakce začít přistání s automatickým řízením.
Tedy například váš_spustitelný_soubor localhost:8000 0
.
Na adrese https://soutez.github.io/
si můžete stáhnout
ukázkový server. Po spuštění poslouchá
server na portu 8000 a ovládat ho můžete z internetového prohlížeče zadáním
adresy http://localhost:8000
– můžete měnit startovní podmínky
a prohlížet probíhající a již proběhlá přistání. Každé přistání se také
ukládá do vlastního souboru v podadresáři logy
.