4it101»Adv Truhla

Adv Truhla

Truhla

Truhla (může to být i skříň, lednička apod.) je věc umístěná v místnosti, ve které jsou umístěny další věci. Po zadání příkazu prozkoumat truhla se zobrazí seznam věcí v truhle a pomocí příkazu seber je možné sebrat nějak věc z truhly či z místnosti. Lze to řešit několika způsoby, já to rozšířím třídu Vec o seznam věcí a příslušné metody.

Ve třídě HerniPlan vytvořím čtyři věci - sponku, stůl, formulář a razítko s tím, že poslední dvě budou ve stole. Vytvoření věcí by vypadalo takto:

      kancelar.vlozVec(new Vec("sponka",true));
      Vec stul = new Vec("stul",false);
      stul.vlozVec(new Vec("razítko",true));
      stul.vlozVec(new Vec("formulář", true));

Následuje postup řešení:

1. rozšířit třídu Vec o seznam věcí
Pro seznam věcí by bylo možné použít pole, kolekci (např. ArrayList) či mapu. Kolekci jsem popisoval na 9. cvičení, nyní popíši použití mapy.
2. rozšířit třídu Vec o příznak prozkoumání
Já chci umožnit sebrat věc ze stolu až poté, co ji hráč prozkoumá. Proto doplním třídu Vec o boolean datový atribut se jménem prozkoumano, který bude mít na začátku hodnotu false a po prozkoumání se nastaví na true.
3. rozšířit třídu Vec o metody
Třídu Vec je potřeba rozšířit o metody vlozVec(), vyberVec(), obsahujeVec(), popisProzkoumej() , jeProzkoumana() a prozkoumano(). Pokud věc není prozkoumána, vrací metoda obsahujeVec() hodnotu false a metoda vyberVec vrací hodnotu false.
4. upravit příkaz seber
Příkaz seber by měl umožnit sebrat věc z místnosti a pokud je v místnosti nějaká prozkoumaná truhla, tak i z truhly. Není potřeba upravovat třídu PrikazSeber, ale metody obsahujeVec() a vyberVec() ve třídě Mistnost - když se procházejí věci v místnosti, tak je potřeba u každé prozkoumané zjistit, zda náhodou neobsahuje hledanou věc.
5. vytvořit příkaz prozkoumej
Vytvořit třídu PrikazProzkoumej, v rámci které se prozkoumá věc. Pokud věc obsahuje jiné věci, vypíše se jejich seznam.
5. testy
nezapomeňte napsat testy pro třídu Věc a pro novou funkčnost příkazu seber
6. volitelně upravit příkaz polož
Pokud by jste chtěli hráči umožnit odkládat věci do truhly, musíte upravit příkaz polož. Tento příkaz by měl buď jeden parametr (při uložení do místnosti), nebo dva parametry při ukládání do truhly, např.:
      polož sponka stůl
Úpravu příkazu polož zde nebudu popisovat.
7. nadstandardně zrušit duplicity metod
Pokud se pozorně podíváte na třídy Mistnost, Batoh a Vec, tak zjistíte, že mají stejné metody vlozVec(), obsahujeVec(), vyberVec() a částečně popis věcí. To je v rozporu s obvyklými zásadami programování a můžete se pokusit o to, že by příslušný kód byl pouze jednou - lze to řešit přes dědičnost či přes delegování (asi vhodnější). Ani toto zde nebudu dále popisovat.

Třída Vec

Chybí komentáře. Pro seznam věcí jsem použil mapu. Pokud by věci v truhle mohly obsahovat další věci, je potřeba upravit kód metod vyberVec() a obsahujeVec() o prohledání obsahuje vložených věcí.

import java.util.Map;
import java.util.HashMap;

public class Vec {

   private String jmeno;
   private boolean prenositelna;

   private boolean prozkoumana = false;
   private Map<String,Vec> seznamVeci;

   public Vec (String jmeno, boolean prenositelna) {
    this.jmeno = jmeno;
    this.prenositelna = prenositelna;
    seznamVeci = new HashMap<String,Vec>();
   }
   public String getJmeno () {
    return jmeno;
   }
   public boolean jePrenositelna() {
    return prenositelna;
   }

    public boolean jeProzkoumana() {
        return prozkoumana;
    }

    public void prozkoumano (boolean prozkoumana) {
        this.prozkoumana = prozkoumana;
    }

    public void vlozVec (Vec neco) {
        seznamVeci.put(neco.getJmeno(), neco);
    }

    public boolean obsahujeVec(String jmeno) {
        return prozkoumana && seznamVeci.containsKey(jmeno);
    }

    public Vec vyberVec(String jmeno) {
        Vec vec = null;
        if (prozkoumana && seznamVeci.containsKey(jmeno)) {
            vec = seznamVeci.get(jmeno);
            if (vec.jePrenositelna()) {
                seznamVeci.remove(jmeno);
            }
        }
        return vec;
    }

    public String popisProzkoumej() {
        if (seznamVeci.isEmpty()) {
            return "prohlédl jsi si pozorně "+jmeno+", je opravdu dobře udělaný";
        }
        String popis = "Prohlédl jsi si pozorně "+jmeno+" a uvnitř jsi našel:";
        for (String jmeno : seznamVeci.keySet()) {
            popis += " " + jmeno;
        }
        return popis;
    }

    public String toString() {
        return jmeno;
    }
}

Třída místnost

Jsou zobrazeny pouze metody obsahujeVec a vyberVec. Vytvořil jsem si též pomocnou soukromou metodu najdiVecVMistnosti(), která hledá věc v pouze v místnosti a ne již uvnitř případných truhel.


    public boolean obsahujeVec(String jmeno) {
        if (najdiVecVMistnosti(jmeno) == null) { // vec není v místnosti
            for (Vec vec : seznamVeci) {    // prohledávám věci v místnosti
                if (vec.obsahujeVec(jmeno)) { // když nějaká věc obsahuje věc
                    return true;
                }
            }
            return false;  // věc není ani v prozkoumaných věcech (truhlách)
        }
        else {
            return true;
        }

    }

    public Vec vyberVec (String jmeno) {
        Vec vybranaVec = najdiVecVMistnosti(jmeno);
        if (vybranaVec != null && vybranaVec.jePrenositelna()) {
            seznamVeci.remove(vybranaVec);
        }
        else {
            for (Vec vec : seznamVeci) { // hledám, zda není v nějaké věci
                vybranaVec=vec.vyberVec(jmeno);
                if (vybranaVec != null) {
                    break;
                }
            }
        }
        return vybranaVec;
    }

    private Vec najdiVecVMistnosti(String jmeno) {
        Vec vec = null;
        for (Vec neco : seznamVeci) {
            if (neco.getJmeno().equals(jmeno)) {
                vec = neco;
                break;
            }
        }
        return vec;
    }

Třída PrikazProzkoumej

K třídě PrikazProzkoumej mám několik poznámek:

  • pokud uživatel nezadá parametr, prozkoumá se aktuální místnost, tj. vypíší se věci (a popřípadě východy) z aktuální místnosti,
  • pokud uživatel za slovo prozkoumej doplní jméno věci, prozkoumá se tato věc. Pokud obsahuje jiné věci, tak se nastaví, že je prozkoumána a vypíše se seznam předmětů uvnitř věci. Pro vytvoření výpisu je ve třídě Vec připravena metoda popisProzkoumej().