Hra - třídy, podtřídy, přístup k nim a jejich mazání – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Hra - třídy, podtřídy, přístup k nim  a jejich mazání – C / C++ – Fórum – Programujte.comHra - třídy, podtřídy, přístup k nim a jejich mazání – C / C++ – Fórum – Programujte.com

 

Tuqi
~ Anonymní uživatel
12 příspěvků
16. 5. 2014   #1
-
0
-

Ahoj, píšu menší hru a narazila jsem na dva (nejspíš spolu související) problémy. Jeden se týká ukládání samotných postav do souboru a druhý práce s třídou Bag a Suit - batoh a oblečení postavy.

Vytvořila jsem třídu Player, která má 4 téměř identické podtřídy. Nadtřída Player mimo jiné obsahuje ukazatele na třídy Bag a Suit. Program funguje tak, že v jedné funkci vytvořím instanci Player, kterou vracím do základní funkce, která s Playerem dál pracuje -> načítání postav ze souboru. Při vytváření postavy se také vytvoří ukazatel na třídu Player a zavolá se metoda, která postavu vypíše do souboru. Problémem je, že se mi nepovedlo donutit batoh a oblečení, aby se vypsalo.  

class Player{
protected:
    //...
    
    Bag * batoh;
    Suit * oblek;
    
public:

    Player(){

    };
    Player(char * jmeno, char p){
        //...
        
        batoh = new Bag;
        oblek = new Suit;
        
        Vec mec("Kyj zacatecnika", 1, 0, 1, 0, 1);
        Vec boty("Platene botky", 0, 0, 1, 0, 2);
        
        oblek->suitUp(mec);
        oblek->suitUp(boty);
        delete [] mec.jmeno;
        delete [] boty.jmeno;
    }

    virtual ~Player(){
        delete [] name;
        delete [] povolani;
        delete batoh;
        delete oblek;
    }

    
    int printB(WINDOW * win, const Player & a){
        return (a.batoh->print(win));
    } 
    
    void printS(WINDOW * win, const Player & a){
        (a.oblek->print(win));
    }
    
    virtual void writeIn(const Player & a, const char * kam) const = 0;

    //...
};

Funkce zapisující postavy do souboru:

virtual void writeIn(const Player & b, const char * kam) const{
        ofstream out ("./temp");
        ifstream in (kam);
        string radek;
        char pom[21];
        int i, j, cnt = 0;

        PClovek * a = (PClovek*) & b; //podtrida Player
        
        while(getline(in, radek)){
            for(i = 0; i < radek.size(); i++){
                if(radek[i] == '}') break;
                pom[i] = radek[i];
            }
            if(strncmp(pom, a->name, i) != 0)
                out << radek << endl;
            else {out << a->name << "}" << a->pohlavi << "}" << a->rasa << "}"
                    << a->povolani << "}" << a->level << "}" << a->hp << "}"
                    << a->sila << "}" << a->obrat << "}" << a->intel << "}"
                    << a->sarm << "}" << (a->batoh) << (a->oblek) << " " << endl;
            cnt++;}
        for(j = 0; j < i; j++) pom[j] = ' ';
        }
        if(cnt == 0) out << a->name << "}" << a->pohlavi << "}" << a->rasa << "}"
                    << a->povolani << "}" << a->level << "}" << a->hp << "}"
                    << a->sila << "}" << a->obrat << "}" << a->intel << "}"
                    << a->sarm << "}" << (a->batoh) << (a->oblek) << " " << endl;
        
        remove(kam);
        rename("temp", kam);
    }

 

Bag a Suit:

class Bag{
    Vec * pole;
    int size;
    int pocet;
    
public:
    Bag(){
        size = 10;
        pole = new Vec[size];
        pocet = 0;
    }
    ~Bag(){
        for(int i = 0; i < pocet; i++) {
            delete [] pole[i].jmeno;
        }
        delete [] pole;
    }
    
    friend ostream & operator<<(ostream & os, const Bag & bag){
        int i, ok = 0;
        for(i = 0; i < bag.pocet; i++){
            if(ok == 1) os << ",";
            if(strcmp(bag.pole[i].jmeno, "Kyj zacatecnika") == 0 
                    || strcmp(bag.pole[i].jmeno, "Platene botky") == 0)
                continue;
            os << bag.pole[i].jmeno << "}" << bag.pole[i].a << "}" 
                    << bag.pole[i].b << "}" << bag.pole[i].c << "}" 
                    << bag.pole[i].d << "}" << bag.pole[i].typ << "}";
            ok = 1;
        }
        
        return os;
    } 

int print(WINDOW * win) const{
        int i;
        for(i = 0; i < pocet; i++){
            //if(pole[i].jmeno != NULL)
                mvwprintw(win, 3+i, 3, "%s (%d-%d-%d-%d-%d)", pole[i].jmeno,
                        pole[i].a, pole[i].b, pole[i].c,
                        pole[i].d, pole[i].typ);
            
        }
        return i;
    } 
    //...
    
};



class Suit{
private:
    Vec * pole;
    int size;
    int pocet;
public:
    Suit(){
        size = 5;
        pole = new Vec[size];
        pocet = 1;
    }
    ~Suit(){
        for(int i = 0; i < 5; i++) {
            if(pole[i].jmeno != NULL)
                delete [] pole[i].jmeno;
        }
        delete [] pole;
    }
    
    friend ostream & operator<<(ostream & os, const Suit & suit){
        int i, ok = 0;
        for(i = 0; i < suit.size; i++){
            if(suit.pole[i].jmeno != NULL){
                if(ok == 1) os << ",";
                if(strcmp(suit.pole[i].jmeno, "Kyj zacatecnika") == 0 
                    || strcmp(suit.pole[i].jmeno, "Platene botky") == 0)
                continue;
                os << suit.pole[i].jmeno << "}" << suit.pole[i].a << "}" 
                    << suit.pole[i].b << "}" << suit.pole[i].c << "}" 
                    << suit.pole[i].d << "}" << suit.pole[i].typ << "}";
            }}
        
        return os;
    } 

void print(WINDOW * win) const{
        int i;
        for(i = 0; i < size; i++){
            if(pole[i].jmeno != NULL)
                mvwprintw(win, 16+i, 3, "%s (%d-%d-%d-%d-%d)",
                        pole[i].jmeno, pole[i].a, pole[i].b,
                        pole[i].c, pole[i].d, pole[i].typ);
        }
    }
   //...
};

Vec je struktura obsahující přetíženy operátor =.

Nevím, jak docílit toho, aby se věci z batohu a oblečení správně vypsalo, zvládám jen vypsat adresu...

Druhý problém je v tom, že když hraji s jakoukoli postavou, pozměním něco v batohu, obleču si věci a tak, vše funguje, jak by mělo. "Ukončím" kolo - odejdu ze hry, ale ne z programu, vyberu si znovu jakoukoli postavu, stačí, abych jen otevřela batoh a program spadne. Zjistila jsem, že za to můžou metody Player::printS a printB, čili nějaká špatná práce s batohem/oblečením, možná špatné mazání, ale nevím, kde...

Díky za jakékoliv nápady...

Nahlásit jako SPAM
IP: 46.13.101.–
voty+1
Návštěvník
16. 5. 2014   #2
-
0
-

Nějak nerozumím hned konstruktoru Player, kde vytváříš na stacku "mec" a "boty" a pak na jejich clenskou proměnnou voláš delete.

Nahlásit jako SPAM
IP: 85.71.146.–
Jednu rozbil a tu druhou ztratil.
Tuqi
~ Anonymní uživatel
12 příspěvků
16. 5. 2014   #3
-
0
-

Ve suitUp() se pokouším udělat hlubokou kopii, tak zbytek mažu...

Nahlásit jako SPAM
IP: 90.177.3.–
KIIV
~ Moderátor
+43
God of flame
16. 5. 2014   #4
-
0
-

#3 Tuqi
jestli musis mazat i ve staticky alokovanem objektu, tak to mas hodne spatne... od toho je destruktor

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
z
~ Anonymní uživatel
268 příspěvků
16. 5. 2014   #5
-
0
-

Pro co máš ten operátor definovaný a co mu dáváš? Takhle to bude fungovat:

<< *a->batoh

Jinak je to teda fakt hrůza   

Nahlásit jako SPAM
IP: 78.156.159.–
voty+1
Návštěvník
16. 5. 2014   #6
-
0
-

Zkus sem dát i zbytek zdrojáku, protože mám pocit, že chyba bude někde dříve.

Edit: Hlavně bych potřeboval vidět "Vec" a metody "suitUp".

Nahlásit jako SPAM
IP: 88.100.230.–
Jednu rozbil a tu druhou ztratil.
Tuqi
~ Anonymní uživatel
12 příspěvků
16. 5. 2014   #7
-
0
-

Bude to asi hodně prasácký, tohle jsem zkoušela a padá to... :(

Vec:

struct Vec{
        char * jmeno;
        int a;
        int b;
        int c;
        int d;
        int typ;
        Vec(){
            
        }
        Vec(char * name, int i, int ii, int iii, int iiii, int t){
            int delka = strlen(name);
            jmeno = new char[delka+1];
            strcpy(jmeno, name);
            a = i;
            b = ii;
            c = iii;
            d = iiii;
            typ = t;
        };
        ~Vec(){
        }
        
        Vec & operator=(const Vec & predmet){
            int delka = strlen(predmet.jmeno); 
            jmeno = new char[delka + 1];
            strcpy(jmeno, predmet.jmeno);
            
            a = predmet.a;
            b = predmet.b;
            c = predmet.c;
            d = predmet.d;
            typ = predmet.typ;
            
            return *this;
        }
        
    };

suitUp() 

void Player::suitUp(int x){
        Vec pom = batoh->del(x);
        Vec pom2 = oblek->suitUp(pom);
        if(pom2.typ < 10){
            sila -= pom2.a;
            intel -= pom2.b;
            obrat -= pom2.c;
            sarm -= pom2.d;
            batoh->add(pom2);
        }
        sila += pom.a;
        intel += pom.b;
        obrat += pom.c;
        sarm += pom.d;
    }

Vec Bag::del(int i){
        // vyhodi vec z batohu, vraci ji navratovou hodnotou
        Vec pom = pole[i];
        //delete [] pole[i].jmeno;
        
        if(i != pocet-1){
            pole[i] = pole[pocet-1];
            //delete [] pole[pocet-1].jmeno;
        }
        
        pocet--;
        
        return pom;
    }



Vec Suit::suitUp(const Vec & oblek){
        // oblece vec, pokud je oblecena vec stejneho typu, 
        // oblece novou a starou return, jinak vrati tu samou
        //int i, j;
        Vec pom = oblek;
        
        if((pocet % oblek.typ == 0 && oblek.typ != 2 && oblek.typ != 1)
                || oblek.typ == 1 || oblek.typ == 2){
            Vec pom2 = pole[oblek.typ-1];
            //delete [] pole[oblek.typ-1].jmeno;
            pole[oblek.typ-1] = pom;
            return pom2;
        }
        
        pocet *= oblek.typ;
        
        pole[oblek.typ-1] = pom;
        pom.typ *= 10;
        return pom;
    }
Nahlásit jako SPAM
IP: 46.13.101.–
voty+1
Návštěvník
16. 5. 2014   #8
-
0
-

Nevím, kde přesně začít. Měl bych pár připomínek na věci, které sice nejsou vyloženě chybné, ale...

1) Místo char* použij std::string. Ušetříš si spoustu práce a kód bude lépe čitelný.

2) Místo (dynamických) polí používej standardní STL kontejnery. Ušetříš si spoustu práce a kód bude lépe čitelný.

Například Vec by mohla vypadat nějak takto

struct Vec{
  string jmeno;
  int a;
  int b;
  int c;
  int d;
  int typ;

  Vec()
  {
            
  }

  Vec(string name, int i, int ii, int iii, int iiii, int t)
     :jmeno(name), a(i), b(ii), c(iii), d(iiii), typ(t)
  {

  };
 
};

Sice nevím, zda má smysl ten prázdný konstruktor a názvy parametrů druhého konstruktoru nejsou úplně OK, ale principiálně by to mohlo být.

Edit: Trik je v tom, že v tomto případě není potřeba přepisovat ani operátor přiřazení, ani copy constructor (ten ti tam asi chybí úplně), ani destructor.

Nahlásit jako SPAM
IP: 88.100.230.–
Jednu rozbil a tu druhou ztratil.
Tuqi
~ Anonymní uživatel
12 příspěvků
16. 5. 2014   #9
-
0
-

Zkusím to takhle všude přehodit... Dá se nějakým způsobem vypsat string s ncurses knihovnou bez přetypování?

Nahlásit jako SPAM
IP: 37.188.234.–
KIIV
~ Moderátor
+43
God of flame
17. 5. 2014   #10
-
0
-

#9 Tuqi
na co pretypovani, kdyz to ma metodu c_str() co vrati const char *

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 57 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý