Skúška 22.1.2021 - Indiana Jones


Indiana Jones sa dostal do labyrintu (štvorcová sieť) s množstvom schránok s rôznymi cennosťami. Tieto ležia na niektorých políčkach labyrintu, pričom v každej schránke sa nachádza nejaký drahocenný predmet (napríklad zlato, diamant, striebro, …). Budeme ich označovať písmenami malej abecedy (rovnaký druh rovnakým písmenom). Indiana získa tento predmet vtedy, keď príde na políčko so schránkou (a vtedy sa schránka z plochy odstráni).

Pri štarte sa hráč (Indiana) nachádza na prázdnom políčku (bez schránky) a je otočený v jednom zo smerov:

  • 0 = východ, 1 = juh, 2 = západ, 3 = sever

Ďalej budeme hráča riadiť postupnosťou celých čísel takto:

krok1 otoč1 krok2 otoč2 ...

Funguje to takto:

  • urobí krok1 krokov vpred vo svojom momentálnom smere, pričom krok1 je nezáporné číslo; ak sa krok urobiť nedá kvôli prekážke (alebo okraja plochy), tak sa ignoruje a hráč ostáva na mieste

  • otočí sa otoč1 krát vpravo vbok (o 90 stupňov), pričom otoc1 môže byť aj záporné číslo; napríklad, ak je momentálne otočený na sever (smer=3) a číslo otočení je 2, tak sa otočí na juh

  • takto postupne pokračuje so všetkými číslami postupnosti; táto postupnosť môže byť párnej aj nepárnej dĺžky

  • pri pohybe, ak má pred sebou schránku, tak ju otvorí a vyberie obsah - takto si postupne zbiera písmená drahocenných predmetov

Celá mapa labyrintu aj s vyznačenými schránkami (s písmenami) je zaznačená do štvorcovej siete: každé políčko je buď prázdne (budeme značiť '.'), je tam stena, teda prekážka (budeme značiť 'M'), alebo schránka s cennosťou (budeme zobrazovať '#'). Štruktúra súboru s popisom labyrintu je nasledovná:

  • v prvom riadku sú dve celé čísla (oddelené medzerou): počet riadkov a počet stĺpcov štvorcovej siete

  • v každom ďalšom riadku súboru je na začiatku nejaký jeden znak, za ktorým nasleduje niekoľko celých čísel (oddelených medzerou)

  • ak riadok začína znakom 'M', tak za tým nasleduje postupnosť pozícií (riadok, stĺpec), na ktorých sa nachádzajú prekážky

  • ak riadok začína malým písmenom (od 'a' po 'z'), za tým nasledujú pozície v ploche, kde sa nachádzajú tieto drahocennosti - pri zobrazovaní plochy sa budú vykresľovať znakom '#'

  • ak riadok začína znakom '@', za tým nasledujú tri celé čísla: riadok a stĺpec pozície hráča a jeho štartový smer natočenia (číslo od 0 do 3)

Môžeš predpokladať, že súbor je zadaný korektne a okrem prvého riadku s rozmermi obsahuje ešte aspoň jeden riadok s pozíciou hráča (začína znakom '@').

Napríklad pre 'subor1.txt':

4 5
M 1 2 3 0
c 2 3
@ 0 2 2
a 2 4 1 4
M 0 4
b 3 3

labyrint by sa zobrazil takto:

..@.M
..M.#
...##
M..#.

Napíš metódy triedy IndianaJones:

class IndianaJones:
    def __init__(self, meno_suboru):
        ...

    def __str__(self):
        return ''

    def pohyb(self, *postupnost):
        return set()

    def ziskane(self):
        return set()

kde metóda:

  • init(meno_suboru) - prečíta súbor s popisom labyrintu

  • __str__() - vráti znakový reťazec, ktorý reprezentuje stav labyrintu s hráčom: prázdne políčka zobrazuje ako '.', navštívené políčka ako '+', prekážky ako 'M', ešte nezozbierané schránky ako '#' a momentálnu pozíciu hráča ako '@'

  • pohyb(*postupnost) - dostane neprázdnu postupnosť celých čísel pre pohyb hráča; v postupnosti sa striedajú čísla pre počty krokov a počty otočení; ak je postupnosť nepárnej dĺžky, na konci sa neurobí žiadne otočenie; funkcia vráti množinu zozbieraných predmetov v tomto ťahu (ak je v tejto množine viackrát nejaké písmeno, tak sa upraví podobne ako v metóde ziskane)

  • ziskane() - vráti množinu zozbieraných predmetov (písmen); ak sa v tejto množine má objaviť niektoré písmeno viackrát, tak sa uvedie aj s číslom o počte výskytov, napríklad množina s jedným 'a' a tromi 'e' sa zapíše {'a', '3e'}

Napríklad, takýto test:

ij = IndianaJones('subor1.txt')
print(ij)
print('zozbieral:', ij.pohyb(1, 3, 2, 3, 3, 1))
print(ij)
print('zozbieral:', ij.pohyb(1, 1, 1))
print(ij)
print('spolu ziskal:', ij.ziskane())

vypíše:

..@.M
..M.#
...##
M..#.
zozbieral: {'c', 'a'}
.++.M
.+M.#
.+++@
M..#.
zozbieral: {'b'}
.++.M
.+M.#
.++++
M..@+
spolu ziskal: {'c', 'a', 'b'}

Z úlohového servera L.I.S.T. si stiahni kostru programu skuska.py. Pozri si testovacie dáta v súboroch 'subor1.txt', 'subor2.txt', …, ktoré bude používať aj testovač.

Aby si mohol spúšťať skúškové testy, program ulož do súboru skuska.py. Riešenie (bez dátových súborov) odovzdaj na úlohový server https://list.fmph.uniba.sk/. Tvoj odovzdaný program musí začínať tromi riadkami komentárov:

# 1. skuska: indiana jones
# autor: Janko Hraško
# datum: 22.1.2021