Informatika gyűjtemény

Egy szinttel feljebb Megoldás

2004050607080910

NézetNyomtat

A megoldás menete

(Megoldás az alapfeladatra.)

Adatstruktúrák

A pályát egy annyi elemű palya[] tömbben célszerű tárolni, ahány mező lehetséges a pályán. A bemeneti tesztadatokban a mezők sorszámai 1-el kezdődnek, így a tömböt is 1-től érdemes indexelni. Az órán tanultak szerint, a tömb elemei legyenek mezőket leíró struktúrák (rekordok). Minden mezőhöz két információt kell tárolni, a létra / csúszda ugrási célmezőt, és a mező típusát. Ezek egy az egyben betölthetők a fájlból, mint számok. Az i. mező adatai: mezok[i].ugras az ugrási cél; mezok[i].tipus a mező típusa. (Tehát nemnulla esetén "egyszer kimaradsz".)
A játékosokat is érdemes egy rekordokból álló tömbbe rakni. Legyen jlista[i].mezo az i.-ik játékos aktuális mezőjének a sorszáma, amin éppen áll; a jlista[i].kimarad logikai érték pedig az, hogy az aktuális körből ki fog-e maradni a játékos, ennek használatáról részeleteket később...

Felépítés

A fokozatos, felülről lefelé finomítás elvét fogjuk követni. Első megközelítésben a programunk betölti az adatokat, az első mezőre helyezi a játékosokat, majd pedig körökre bontva elkezd játékot szimulálni, amíg valamelyik játékos be nem érkezik...
Eljárás Lejátsz()
    Betöltés();
    AlapHelyzet();
    Ciklus i:= 1-től maxKörök-ig
        JátékKör(voltBeérő);
        Ha (voltBeérő = Igaz) Akkor
            Kiír(i);
            Kilép;
        Elágazás Vége
    Ciklus Vége
Eljárás Vége
A Betöltés() eljárás a palya() tömböt tölti fel az AlapHelyzet() pedig a jatekos[] tömböt. A Játékkör() függvény sorraveszi a játékosokat, és mindet lépteti a szabályok szerint. Egy paraméteren át képes jelezni, hogy az adott körben beért egy játékos a célba.
Eljárás Játékkör(voltBeérő)
    voltBeérő := Hamis;
    Ciklus i:= 1-től játékosok számá-ig
        JátékosLép(i);
        Ha jatekos[i].mezo = utolsó mező száma Akkor
            voltBeérő := Igaz;
            kilép az eljárásból
        Elágazás Vége
    Ciklus vége
Eljárás Vége
A program bonyolultabb része a JátékosLép(j) eljárásban koncentrálódik. A kimaradásokat úgy kezeljük, hogy ha a játékos egy kimaradsz típusú mezőre lép, akkor igaz-ba billen nála a kimarad logikai rekordmező. Amikor legközelebb (a következő körben) erre a játékosra kerül a sor, akkor ez a rekordmező fogja jelezni, hogy ki kell egyszer maradnia, tehát nem lép, csak újra hamis-ba állítja az értékét.
Eljárás JátékosLép(j)
    Ha jlista[j].kimarad = Igaz Akkor
        jlista[j].kimarad = Hamis;
        Kilép az eljárásból;
    Elágazás Vége
    
    dobás := Véletlenszám(1..6);
    újmező:= jlista[j].mező + dobás;
 
    {a mezők száma ugyanaz, mint az utolsó mező sorszáma}
    Ha újmező < a mezők számánál Akkor újmező := pálya[újmezo].ugrás;
    Ha újmező >= a mezők számánál Akkor
        {győzelem}
        újmező := az utolsó mező sorszáma;
        Kilép az eljárásból;
    Elágazás Vége
 
    Leüt(újmező);
    jlista[j].mező:= újmező;
    
    If palya[újmező].tipus <> 0 Akkor lista[j].kimarad:= TRUE;
Eljárás Vége
A Leüt(i) leüti, azaz az 1. mezőre helyezi az i. mezőn lévő játékost, természetesen csak ha nem üres az i. mező. Az újmező változóra azért volt szükség, hogy a Leüt() eljárás ne üthesse le az aktuális (j.-ik) játékost.
Amennyiben valaki szeretné csökkenteni az eljárások számát, akkor a Lejátsz és a Játékkör eljárások összevonását fontolja meg. Ez az egyedüli két olyan eljárásunk ugyanis, amik még ketten együtt sem képviselnek jelentősebb bonyolultságot. Így programunkban minden eljárás egy jól elhatárolt funkciót fog elvégezni, tehát mindenkinek (de legalább is e cikk írójának) tetszeni fog.

Megoldások