4it101»Adv Zamcena

Adv Zamcena

Zamčená místnost

Do zamčené místnosti nelze vejít, ve výpisu východů se zvýrazní, že konkrétní místnost je zamčená. Zamčenou místnost budu vysvětlovat na zamčení bufetu v základní verzi adventury. Ukáži zde též příkaz odemknout, je zde popsána i neviditelná místnost.

Základní kroky

1. datový atribut u třídy Místnost
místnost buď je nebo není zamčená, takže můžeme použít datový atribut typu boolean, počáteční hodnota by měla být false (tj. že vytvořená místnost je na začátku odemčená). Budu používat tento datový atribut: private boolean zamcena .
2. doplnit metody do třídy Mistnost
je potřeba metoda pro nastavení datového atributu a pro zjištění datového atributu. Konkrétně by to mohli být metody public void zamknout(boolean zamceno) a public boolean jeZamceno() ,
3. upravit popis východů
ve třídě Mistnost upravit metodu seznamVychodu() , aby se vyznačila zamčená místnost. Přidaný kód je zvýrazněn červeně:
    private String seznamVychodu() {
        String vracenyText = "vychody:";
        for (Mistnost sousedni : vychody) {
             vracenyText += " " + sousedni.getNazev();
             if (sousedni.jeZamcena()) {
                 vracenyText += "(zamknuto)";
             }
        }
        return vracenyText;
    }
4. neumožnit vstup do zamčené místnosti
je potřeba upravit metodu proved v PrikazJdi. Když se najde sousední místnost, je potřeba ještě otestovat, zda není zamčená. Pokud ano, vypíše se zpráva o pokusu vstoupit do zamčené místnosti. Přidaný kód do metody proved je zvýrazněn červeně:
    public String proved(String ... parametry) {
        if (parametry.length == 0) {
	    return "Kam mám jít? Musíš zadat jméno místnosti";
        }
        String smer = parametry[0];
        Mistnost sousedniMistnost = plan.getAktualniMistnost().sousedniMistnost(smer);
        if (sousedniMistnost == null) {
            return "Tam se odsud jit neda!";
        }
        else {
            if (sousedniMistnost.jeZamcena()) {
                return "dveře do místnosti "+sousedniMistnost.getNazev()
                     +" jsou zamčené";
            }
            plan.setAktualniMistnost(sousedniMistnost);
            return sousedniMistnost.dlouhyPopis();
        }
    }
5. zamknout - kde a jak
ve většině případů se bude zamykat místnost na začátku v herním plánu, bufet zamknu příkazem
bufet.zakmnout(true);
6. odemknout - kde a jak
je potřeba si rozmyslet, po zadání kterého příkazu se místnost odemkne. Napadlo mně několik možností, určitě lze vymyslet i další.
zvláštní příkaz pro odemykání
zadá se např. příkaz odemknout bufet či otevři laboratoř. Tato varianta zde bude popsána podrobněji.
příkaz použij
např. po zadání použij klíč se odemkne místnost,
příkaz dej
např. po zadání dej zlato skřítek skřítek odemkne místnost,
příkaz mluv
např. po zadání mluv Gandalf vytvoří Gandalf kouzlem most, přes který lze přejít na druhou stranu propasti,
7. různé výpisy (volitelné)
někdy se může hodit, aby každá zamčená místnost vypisovala něco jiného. Např. při pokusu o vstup do komory se vypíše Komora je zamknuta a klíč ve dveřích není. Budeš ho muset nejdříve najít, při pokusu o vstup na dvůr se vypíše Nakoukl jsi dveřmi na dvůr a uviděl jsi velkého hladového psa. Rychle jsi dveře zabouchl. Bez salámu pro psa se dvůr nedostaneš.. V této situaci je nejvhodnější zřídit ve třídě Mistnost další datový atribut (např. zamcenoVypis), který by se nastavil v herním plánu a poté použil v příkazu jdi (v metodě proved ve třídě PrikazJdi).

Neviditelná místnost

Neviditelná místnost se programuje a používá podobně jako zamčená místnost. U místnosti se vytvoří datový atribut typu boolean (např. private boolean viditelna = true;). Je potřeba vytvořit dvě metody - jednu pro nastavení datového atributu, jednu pro zjištění viditelnosti:

      public void budeVidet(boolean viditelna) { //..... };
      public boolean jeVidet() { //..... };

Je potřeba upravit metody vypisující seznam východů (východy do neviditelné místnosti se nezobrazí) a metodu proved v PrikazJdi (do neviditelné místnosti by nejspíš nemělo být možné vejít). Neviditelné místnosti je potřeba nejspíš v herním plánu nastavit. Je potřeba neviditelnou místnost též v nějakém příkazu zviditelnit, např. po vstupu do nějaké místnosti či po zabití draka, po promluvě s nějakou postavou atd.

Neviditelnou místnost lze řešit i pomocí zkrakty - přiřadit východ (v podstatě probourat průchod) až v okamžiku, kdy je splněna podmínka pro zviditelnění.

Příkaz odemkni

Příkaz pro odemčení se může chovat různě, je zde ukážu odemčení bufetu, kdy se pro jeho odemčení použije příkaz:

       odemkni bufet

s tím, že pro odemknutí musí mít hráč u sebe věc paklíč, aby se místnost odemkla. V popsaném řešení je možné mít ve hře více zamčených místností. Každá místnost má odlišný klíč (odlišnou věc v batohu k odemčení).

1. třídu Mistnost doplníme od dva datové atributy
Datový atribut typu boolean bude udávat, zda je místnost zamčená. Druhý datový atribut udává věc, pomocí které lze místnost odemknout.
    private boolean zamcena=false;
    private Vec klic;
2. doplnit metody pro zamčení, upravit metody proveď a seznamVychodu()
Je to popsáno v první části v bodech 2., 3. a 4.
3. doplnit do třídy Mistnost metody pro nastavení klíče a pro získání klíče
       public void nastavKlic(Vec klic) {
             this.klice = klic;
       }

       public Vec getKlic() {
             return klic;
       }
4. nastavit místnost v herním plánu
       bufet.zamknout(true);
       Vec paklic = new Vec("paklic", true);
       bufet.nastavKlic(paklic);
5. vytvořit třídu PrikazOdemkni
/**
 *  Třída PrikazOdemkni implementuje pro hru příkaz odemkni.
 *  
 */

public class PrikazOdemkni implements Prikaz {
    private static final String NAZEV = "odemkni";
    private HerniPlan plan;

    /**
    *  Konstruktor třídy
    *  
    *  @param plan herní plán, je potřeba zjistit, zda jsem v místnosti
    *                    vedle místnosti, která se má odemknout
    */
   
    public PrikazOdemkni(HerniPlan plan) {
        this.plan = plan;
    }

    /**
     *  Provádí příkaz "odemkni". Zjišťuji, zda z aktuální místnosti je
     *  východ do zadané místnosti. Pokud místnost existuje a je zamčená,
     *  tak se zjistí, zda v batohu je potřebný klíč. Pokud ano, odemknu
     *  místnost.
     *
     *@param parametry - jako  parametr obsahuje jméno místnosti,
     *                         do které se má jít.
     *@return zpráva, kterou vypíše hra hráči
     */

    public String proved(String... parametry) {
        if (parametry.length == 0) {
            // pokud chybí druhé slovo (sousední místnost), tak ....
            return "Co mám odemknout? Musíš zadat jméno místnosti";
        }

        String mistnost = parametry[0];

        // hledám zadanou místnost mezi východy
        Mistnost sousedniMistnost = plan.getAktualniMistnost().sousedniMistnost(mistnost);

        if (sousedniMistnost == null) {
            return "Odsud nevedou dveře do místnosti "+mistnost+" !";
        }
        else {
            if (sousedniMistnost.jeZamceno()) {
                if (plan.getBatoh().obsahujeVec(sousedniMistnost.getKlic())) {
                    sousedniMistnost.zamknout(false);
                    return "Podařilo se ti otevřít dveře do místnosti "
                           + mistnost + ". Nyní je cesta volná.";
                }
                else {
                    return "Pro odemčení dveří do "+mistnost+" potřebuješ mít "
                        + "u sebe "+mistnost.getKlic().getNazev();
                }
            }
            else {
                return "Místnost "+mistnost+" již byla odemčená!!!";
            }
        }
    }

    /**
     *  Metoda vrací název příkazu (slovo které používá hráč pro jeho vyvolání)
     *  
     *  @ return nazev prikazu
     */

    public String getNazev() {
        return NAZEV;
    }

}
6. někam se musí paklíč umístit
Hráč musí paklíč někde sebrat a poté s ním dojít před bufet.