Błąd "'Rat' does not name a type" - jak go poprawić?

0

Mam problem jak w temacie :

Rat.h

#ifndef RAT_H
#define RAT_H
#include "Potwor.h"


class Rat:public Potwor
{
    public:
    Rat(std::string = "Szczur", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Rat(); //destruktor

    void show();
    void respawn();
    int getScore() const;
    std::string getName() const;
};

#endif // RAT_H
 

Rat.cpp

#include <iostream>
#include <random>
#include <cstdlib>
#include "Postac.h"
#include "Rat.h"

using namespace std;

  random_device rd;   // generator liczb losowych (przynajmniej tak zrozumiałem z tłumaczenia) ;)
  mt19937 gen(rd());  // to seed mersenne twister. - do zasiania mersenne twister

  uniform_int_distribution<> wR(1,2); // zakres losowania pkt. wytrzymałości wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> sR(1,2); // zakres losowania pkt. siły wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zdrR(1,20); // zakres losowania pkt. zdrowia wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zrR(1,5); // zakres losowania pkt. zręczności wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> intelR(1,3); // zakres losowania pkt. inteligencji wyłącznie pomiędzy 1 a 2.


int s1=sR(gen);
int w1=wR(gen);
float zdr1=zdrR(gen);
int zr1=zrR(gen);
int intel1=intelR(gen);

int sila1,wytrzymalosc1,zrecznosc1,inteligencja1;
float zdrowie1;


void Rat::show() //metoda ukazująca dane potworka
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Potwora"<<white<<":" << nazwa <<endl
         <<yellow<< "Sila" <<white<<":"<< sila + s1 << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc + w1<< endl
         <<red<<"Zdrowie"<<white<<":"<< zdrowie + zdr1 << endl
         <<green<<"Zrecznosc"<<white<<":"<< zrecznosc + zr1 << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja + intel1 << endl;

    np = nazwa;

//dodawanie wartości podstawowej do wylosowanej

    sila1=sila + s1;
    wytrzymalosc1=wytrzymalosc + w1;
    zdrowie1=zdrowie + zdr1;
    zrecznosc1=zrecznosc + zr1;
    inteligencja1=inteligencja + intel1;

    wynik = sila1 + wytrzymalosc1 + zrecznosc1 + inteligencja1 / zdrowie1;
}
 //koniec voida

Rat::Rat(string n, int s, int w, float zdr, int zr, int intel) //konstruktor
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Rat::~Rat() //destruktor
{
    cout << "\nMozna dzialac na nowo :D" << endl;
}

int Rat::getScore() const //funkcja zwracająca wartość całkowitą czyli "int"
{
    return wynik;
}

string Rat::getName() const //funkcja zwracająca nazwe czyli "string"
{
    return nazwa;
}

 

Postac.h

#include <iostream>


class Postac : public Creature {

public:
    Postac(std::string = "Mr.Nobody", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Postac(); //destruktor

    void load();
    void show();
    void porownaj(const Rat& monster); //<- tu wskazuje błąd !
};


 

Postac.cpp

 
#include <iostream>
#include <cstdlib>
#include "Rat.h"
#include "Postac.h"
using namespace std;

void Postac::load() //metoda wczytujaca dane postaci
{
    cout << "Czy chcesz wprowadzić Atrybuty Postaci(t/n)?";
    cin >> odp;
    if (odp == 't' || odp == 'T') {
        cout << "\nPodaj "<<Italic_cyan<<"Nazwe Postaci"<<white<<":";
        cin >> nazwa;
        cout << "Podaj "<<yellow<<"Sile "<<white<< nazwa << "'a:";
        cin >> sila;
        cout << "Podaj "<<purple<<"Wytrzymalosc "<<white<< nazwa << "'a:";
        cin >> wytrzymalosc;
        cout << "Podaj Ilosc "<<red<<"Zdrowia "<<white << nazwa << "'a:";
        cin >> zdrowie;
        cout << "Podaj "<<green<<"Zrecznosc "<<white<< nazwa << "'a:";
        cin >> zrecznosc;
        cout << "Podaj "<<blue<<"Inteligencje "<<white<< nazwa << "'a:";
        cin >> inteligencja;
        cout << "\n";
    }
}
void Postac::show() //metoda ukazująca dane postaci
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Postaci"<<white<<":" << nazwa << endl
         <<yellow<<"Sila"<<white<<":" << sila << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc << endl
         <<red<<"Zdrowie"<<white<<":" << zdrowie << endl
         <<green<<"Zrecznosc"<<white<<":" << zrecznosc << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja << endl;
    nP = nazwa;
    wynik1 = sila + wytrzymalosc + zrecznosc + inteligencja / zdrowie;
}

Postac::Postac(string n, int s, int w, float zdr, int zr, int intel) //konstruktor klasy Postac
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Postac::~Postac() //destruktor klasy Postac
{
    cout << "\nJezeli widzisz ten komunikat to znaczy,ze twoj komputer zniknie za…1…2…3 BOOM!" << endl;
}


void Postac::porownaj(const Rat& monster)
{
    if (wynik1 > monster.getScore())

        cout << monster.getName() << " Przegralby z " << nP;

    if (wynik1 < monster.getScore())

        cout << monster.getName() << " Wygralby z " << nP;

    if (wynik1 == monster.getScore())

        cout << "Bylby remis";
}

Log:
/home/kamil/Dokumenty/Programy C++/Klasy/RPG/Postac.h|12|error: ‘Rat’ does not name a type|

2

Postac nie widzi deklaracji Rat. użyj forward-deklaracji:

class Rat;

class Postac : public Creature {
//...
4

ja bym zebral wszystkie te inty ktore przekazujesz do konstruktora i opakowal to w jakas klase, tak by Postac przyjmowala dwa (lub jeden) parametry, a nie 6
Grupowanie danych zeby mialy sens to jest dosc wazna umiejetnosc

nie musisz uzywac funkcji porownaj, mozesz przeladowac operator == przez co bedziesz robil na zasadzie

mojaPostac == mojPrzeciwnikRat

nie mieszaj angielskiego z polskim. Duzo lepiej jakbys pisal tylko po angielsku, ale jak nie potrafisz to trzymaj sie tlyko polskiego. Nie ma zadnego sensu mieszac dwoch jezykow

endl nie sluzy do nowej linii, od tego sluzy "\n"

Zamiast funkcji show mozesz przeciazyc operator <<

zamiast load mozesz przeciazyc operator >>, ale troche bez sensu ze Postac zamiast byc postacia zajmuje sie obsluga zdarzen z konsoli. Od tego powinnienes miec osobna klase i przypisac obiekt typu "Cechy" do postaci.

poczytaj o RuleOfThree

usun zmienne globalne

powtarzasz sie w show. poczytaj o Don't Repeat Yourself

0

Ok,w załączniku dałem ten projekt i tak wiem że nazwy mogą się różnić od nazw klas…
2016-11-01-141628_1280x1024_scrot.png

Postac.h

#include <iostream>

class Rat;
class Postac : public Creature {

public:
    Postac(std::string = "Mr.Nobody", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Postac(); //destruktor

    void load();
    void show();
    void porownaj(const Rat& monster);
};
Postac.cpp

///modyfikacje: Wprowadzenie LVLi oraz losowanie potwora z którym się zmierzymy
#include <iostream>
#include <cstdlib>
#include "Rat.h"
#include "Postac.h"
using namespace std;

void Postac::load() //metoda wczytujaca dane postaci
{
    cout << "Czy chcesz wprowadzić Atrybuty Postaci(t/n)?";
    cin >> odp;
    if (odp == 't' || odp == 'T') {
        cout << "\nPodaj "<<Italic_cyan<<"Nazwe Postaci"<<white<<":";
        cin >> nazwa;
        cout << "Podaj "<<yellow<<"Sile "<<white<< nazwa << "'a:";
        cin >> sila;
        cout << "Podaj "<<purple<<"Wytrzymalosc "<<white<< nazwa << "'a:";
        cin >> wytrzymalosc;
        cout << "Podaj Ilosc "<<red<<"Zdrowia "<<white << nazwa << "'a:";
        cin >> zdrowie;
        cout << "Podaj "<<green<<"Zrecznosc "<<white<< nazwa << "'a:";
        cin >> zrecznosc;
        cout << "Podaj "<<blue<<"Inteligencje "<<white<< nazwa << "'a:";
        cin >> inteligencja;
        cout << "\n";
    }
}
void Postac::show() //metoda ukazująca dane postaci
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Postaci"<<white<<":" << nazwa << endl
         <<yellow<<"Sila"<<white<<":" << sila << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc << endl
         <<red<<"Zdrowie"<<white<<":" << zdrowie << endl
         <<green<<"Zrecznosc"<<white<<":" << zrecznosc << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja << endl;
    nP = nazwa;
    wynik1 = sila + wytrzymalosc + zrecznosc + inteligencja / zdrowie;
}

Postac::Postac(string n, int s, int w, float zdr, int zr, int intel) //konstruktor klasy Postac
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Postac::~Postac() //destruktor klasy Postac
{
    cout << "\nJezeli widzisz ten komunikat to znaczy,ze twoj komputer zniknie za…1…2…3 BOOM!" << endl;
}


void Postac::porownaj(const Rat& monster)
{
    if (wynik1 > monster.getScore())

        cout << monster.getName() << " Przegralby z " << nP;

    if (wynik1 < monster.getScore())

        cout << monster.getName() << " Wygralby z " << nP;

    if (wynik1 == monster.getScore())

        cout << "Bylby remis";
}
Rat.h

#ifndef RAT_H
#define RAT_H
#include "Potwor.h"


class Rat:public Potwor
{
    public:
    Rat(std::string = "Szczur", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Rat(); //destruktor

    void show();
    void respawn();
    int getScore() const;
    std::string getName() const;
};

#endif // RAT_H
Rat.cpp

#include <iostream>
#include <random>
#include <cstdlib>
#include "Postac.h"
#include "Rat.h"

using namespace std;

  random_device rd;   // generator liczb losowych (przynajmniej tak zrozumiałem z tłumaczenia) ;)
  mt19937 gen(rd());  // to seed mersenne twister. - do zasiania mersenne twister

  uniform_int_distribution<> wR(1,2); // zakres losowania pkt. wytrzymałości wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> sR(1,2); // zakres losowania pkt. siły wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zdrR(1,20); // zakres losowania pkt. zdrowia wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zrR(1,5); // zakres losowania pkt. zręczności wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> intelR(1,3); // zakres losowania pkt. inteligencji wyłącznie pomiędzy 1 a 2.


int s1=sR(gen);
int w1=wR(gen);
float zdr1=zdrR(gen);
int zr1=zrR(gen);
int intel1=intelR(gen);

int sila1,wytrzymalosc1,zrecznosc1,inteligencja1;
float zdrowie1;


void Rat::show() //metoda ukazująca dane potworka
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Potwora"<<white<<":" << nazwa <<endl
         <<yellow<< "Sila" <<white<<":"<< sila + s1 << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc + w1<< endl
         <<red<<"Zdrowie"<<white<<":"<< zdrowie + zdr1 << endl
         <<green<<"Zrecznosc"<<white<<":"<< zrecznosc + zr1 << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja + intel1 << endl;

    np = nazwa;

//dodawanie wartości podstawowej do wylosowanej

    sila1=sila + s1;
    wytrzymalosc1=wytrzymalosc + w1;
    zdrowie1=zdrowie + zdr1;
    zrecznosc1=zrecznosc + zr1;
    inteligencja1=inteligencja + intel1;

    wynik = sila1 + wytrzymalosc1 + zrecznosc1 + inteligencja1 / zdrowie1;
}
 //koniec voida

Rat::Rat(string n, int s, int w, float zdr, int zr, int intel) //konstruktor
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Rat::~Rat() //destruktor
{
    cout << "\nMozna dzialac na nowo :D" << endl;
}

int Rat::getScore() const //funkcja zwracająca wartość całkowitą czyli "int"
{
    return wynik;
}

string Rat::getName() const //funkcja zwracająca nazwe czyli "string"
{
    return nazwa;
}

0

@up To co dalej? Bo już nie wiem sam…
EDIT: zmieniłem kod aby był zgodny z diagramem…

Błąd jaki mi pokazuje : /home/kamil/Dokumenty/Programy C++/Klasy/RPG/Character.h|4|error: expected class-name before ‘{’ token|

Character.h

#include <iostream>

class Rat;
class Character : public Creature {  ///<- tu pokazuje błąd

public:
    Character(std::string = "Mr.Nobody", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Character(); //destruktor

    void load();
    void show();
    void porownaj(const Rat& monster);
};
Character.cpp

///modyfikacje: Wprowadzenie LVLi oraz losowanie potwora z którym się zmierzymy
#include <iostream>
#include <cstdlib>
#include "Rat.h"
#include "Character.h"
using namespace std;

void Character::load() //metoda wczytujaca dane postaci
{
    cout << "Czy chcesz wprowadzić Atrybuty Postaci(t/n)?";
    cin >> odp;
    if (odp == 't' || odp == 'T') {
        cout << "\nPodaj "<<Italic_cyan<<"Nazwe Postaci"<<white<<":";
        cin >> nazwa;
        cout << "Podaj "<<yellow<<"Sile "<<white<< nazwa << "'a:";
        cin >> sila;
        cout << "Podaj "<<purple<<"Wytrzymalosc "<<white<< nazwa << "'a:";
        cin >> wytrzymalosc;
        cout << "Podaj Ilosc "<<red<<"Zdrowia "<<white << nazwa << "'a:";
        cin >> zdrowie;
        cout << "Podaj "<<green<<"Zrecznosc "<<white<< nazwa << "'a:";
        cin >> zrecznosc;
        cout << "Podaj "<<blue<<"Inteligencje "<<white<< nazwa << "'a:";
        cin >> inteligencja;
        cout << "\n";
    }
}
void Character::show() //metoda ukazująca dane postaci
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Postaci"<<white<<":" << nazwa << endl
         <<yellow<<"Sila"<<white<<":" << sila << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc << endl
         <<red<<"Zdrowie"<<white<<":" << zdrowie << endl
         <<green<<"Zrecznosc"<<white<<":" << zrecznosc << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja << endl;
    nP = nazwa;
    wynik1 = sila + wytrzymalosc + zrecznosc + inteligencja / zdrowie;
}

Character::Character(string n, int s, int w, float zdr, int zr, int intel) //konstruktor klasy Character
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Character::~Character() //destruktor klasy Character
{
    cout << "\nJezeli widzisz ten komunikat to znaczy,ze twoj komputer zniknie za…1…2…3 BOOM!" << endl;
}


void Character::porownaj(const Rat& monster)
{
    if (wynik1 > monster.getScore())

        cout << monster.getName() << " Przegralby z " << nP;

    if (wynik1 < monster.getScore())

        cout << monster.getName() << " Wygralby z " << nP;

    if (wynik1 == monster.getScore())

        cout << "Bylby remis";
}

Monster.h

#include <iostream>
#include "Creature.h"

class Monster : public Creature {
public:
    Monster(std::string = "Potwor", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Monster(); //destruktor

    void show();
    void respawn();

};

Monster.cpp

#include <iostream>
#include <cstdlib>
#include "Monster.h"
#include "Character.h"

using namespace std;


Monster::Monster(string n, int s, int w, float zdr, int zr, int intel) //konstruktor
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Monster::~Monster() //destruktor
{
    cout << "\nMozna dzialac na nowo :D" << endl;
}


Rat.h

#ifndef RAT_H
#define RAT_H
#include "Monster.h"


class Rat:public Monster
{
    public:
    Rat(std::string = "Szczur", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Rat(); //destruktor

    void show();
    void respawn();
    int getScore() const;
    std::string getName() const;
};

#endif // RAT_H

Rat.cpp

#include <iostream>
#include <random>
#include <cstdlib>
#include "Character.h"
#include "Rat.h"

using namespace std;

  random_device rd;   // generator liczb losowych (przynajmniej tak zrozumiałem z tłumaczenia) ;)
  mt19937 gen(rd());  // to seed mersenne twister. - do zasiania mersenne twister

  uniform_int_distribution<> wR(1,2); // zakres losowania pkt. wytrzymałości wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> sR(1,2); // zakres losowania pkt. siły wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zdrR(1,20); // zakres losowania pkt. zdrowia wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zrR(1,5); // zakres losowania pkt. zręczności wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> intelR(1,3); // zakres losowania pkt. inteligencji wyłącznie pomiędzy 1 a 2.


int s1=sR(gen);
int w1=wR(gen);
float zdr1=zdrR(gen);
int zr1=zrR(gen);
int intel1=intelR(gen);

int sila1,wytrzymalosc1,zrecznosc1,inteligencja1;
float zdrowie1;


void Rat::show() //metoda ukazująca dane potworka
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Potwora"<<white<<":" << nazwa <<endl
         <<yellow<< "Sila" <<white<<":"<< sila + s1 << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc + w1<< endl
         <<red<<"Zdrowie"<<white<<":"<< zdrowie + zdr1 << endl
         <<green<<"Zrecznosc"<<white<<":"<< zrecznosc + zr1 << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja + intel1 << endl;

    np = nazwa;

//dodawanie wartości podstawowej do wylosowanej

    sila1=sila + s1;
    wytrzymalosc1=wytrzymalosc + w1;
    zdrowie1=zdrowie + zdr1;
    zrecznosc1=zrecznosc + zr1;
    inteligencja1=inteligencja + intel1;

    wynik = sila1 + wytrzymalosc1 + zrecznosc1 + inteligencja1 / zdrowie1;
}
 //koniec voida

Rat::Rat(string n, int s, int w, float zdr, int zr, int intel) //konstruktor
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Rat::~Rat() //destruktor
{
    cout << "\nMozna dzialac na nowo :D" << endl;
}

int Rat::getScore() const //funkcja zwracająca wartość całkowitą czyli "int"
{
    return wynik;
}

string Rat::getName() const //funkcja zwracająca nazwe czyli "string"
{
    return nazwa;
}
Creature.h

class Creature //klasa z ktorej dziedzicza klasy Postac i Potwor !
    {
protected:
    std::string nazwa, np, nP; //nazwa <-ogólna potwora,bądź postaci która po tej klasie dziedziczy, np<-nazwa potworka gdyż nie wiem jak wczytać ją z metody load() do metody porownaj() nP<-nazwa postaci też z tych samych pobudek;
    int x, y;
    int sila;
    int wytrzymalosc;
    float zdrowie;
    int inteligencja, zrecznosc;
    char odp;
    int wynik1, wynik; //wartości do porównywania kto by wygrał gdyby doszło do ewentualnego pojedynku
    const std::string white  = "\033[0m";
    const std::string red    = "\033[91m";
    const std::string green  = "\033[32m";
    const std::string yellow = "\033[93m";
    const std::string blue  = "\033[94m";
    const std::string purple = "\033[95m";
    const std::string Italic_cyan = "\033[3;96m";


public:
    virtual void show() = 0;
};
1
class Character : public Creature {  ///<- tu pokazuje błąd

Błąd jaki mi pokazuje :
/home/kamil/Dokumenty/Programy C++/Klasy/RPG/Character.h|4|error: expected class-name before ‘{’ token|

Tuż przed znakiem { jest Creature - wniosek: kompilator nie wie co to jest Creature choć spodziewa się tam jakiejś klasy.
Rozwiązanie:

#include "Creature.h"

Wydaje mi się że dostarczyłem odpowiednią ilość informacji aby ktoś był w stanie mi pomóc
Wrzuciłeś sam kod nie mówiąc czy się kompilują, co się z nimi dzieje itd. Chyba nie oczekujesz, że ktoś stworzy projekt u siebie, skopiuje te wszystkie pliki i skompiluje żeby zobaczyć co jest nie tak? Czasami ktoś tak robi, ale to wyjątek, nie reguła.

0

kod nie chcę się skompilować bo zatrzymuje się na pliku Character.h po dodaniu nagłówka Creature.h wyświetla mi błąd wskazujący na Class Creature w Pliku Creature.h o treści error: redefinition of ‘class Creature’ oraz error: previous definition of ‘class Creature’ wskazujący również tą samą linijke

Creature.h

//klasa z ktorej dziedzicza klasy Character i Monster !
class Creature //<- Tu wyświetla błąd
    {
protected:
    std::string nazwa, np, nP; //nazwa <-ogólna potwora,bądź postaci która po tej klasie dziedziczy, np<-nazwa potworka gdyż nie wiem jak wczytać ją z metody load() do metody porownaj() nP<-nazwa postaci też z tych samych pobudek;
    int x, y;
    int sila;
    int wytrzymalosc;
    float zdrowie;
    int inteligencja, zrecznosc;
    char odp;
    int wynik1, wynik; //wartości do porównywania kto by wygrał gdyby doszło do ewentualnego pojedynku
    const std::string white  = "\033[0m";
    const std::string red    = "\033[91m";
    const std::string green  = "\033[32m";
    const std::string yellow = "\033[93m";
    const std::string blue  = "\033[94m";
    const std::string purple = "\033[95m";
    const std::string Italic_cyan = "\033[3;96m";


public:
    virtual void show() = 0;
};

0

Dodaj w plikach .h dyrektywę #pragma once

0

W porządku zrobiłem to co napisał mi @Shakaz

I obecnie na tą chwilę mam taki błąd: undefined reference to vtable for Monster' `

Monster.cpp

 #include <iostream>
#include <cstdlib>
#include "Monster.h"
#include "Character.h"

using namespace std;

//konstruktor
Monster::Monster(string n, int s, int w, float zdr, int zr, int intel)  //<- Kompilator wskazuje na tą linijkę
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Monster::~Monster() //destruktor
{
    cout << "\nMozna dzialac na nowo :D" << endl;
}

Monster.h

#pragma once
#include <iostream>
#include "Creature.h"

class Monster : public Creature {
public:
    Monster(std::string = "Potwor", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Monster(); //destruktor

    void show();
    void respawn();

};

 
1

Musisz mieć zaimplementowane wszystkie metody wirtualne, które nie są czysto wirtualne (virtual void foo() = 0).

Poza tym, próbowałeś wklepać w google ten błąd, czy od razu przyleciałeś tutaj z problemem? Naucz się korzystać z google, to Ci się przyda w przyszłości.

0

Ok,zrobiłem i działa czyli da się skompilować i nie ma żadnych problemów czytaj błędów! Kod raczej tzw.Kod-Spaghetti ale mniejsza o to…chodzi mi o to,że mam koncept wprowadzenia levelu postaci i expa za danego potworka lecz nie mam za bardzo pomysłu na to…i chodzi o to,że prosiłbym o pomoc w stworzeniu takiej funkcji.Po prostu chodzi mi o to że ta funkcja ma mieć dostęp do expa za danego potworka i ten exp będzie zależny od potworka(bo przecież nie moźna dawać tyle samo expa za smoka co za szczura…Bo gdzie tu sens?)co za tym idzie nie wiem za bardzo jak stworzyć taką uniwersalną funkcję…myślałem coś o wskaźnikach ale nie wiem czy to dobry pomysł…no nic wklejam mój koncept+kod który już napisałem.

Koncept takiej funkcji:

int New_LVL()
{
exp+=exp_m //exp po wygranej walce
Max_exp=100*LVL_P; //próg czyli ile musimy wbić expa aby osiągnąć nowy level!
if(exp==Max_exp) //warunek sprawdzający czy już mam nowy level
{
cout<<"Masz nowy Poziom!\n"<<
"Twoj LVL to"<<LVL_P+1<<
"\nDo wydania :"<<pkt_exp+10; //pkt umiejętności do wydania
}
else //gdy jednak nie będziemy mieli wystarczającej ilości expa
{
cout<<"Brawo,Wygrales ! Dostajesz "<<exp_m<<".Brakuje ci " //exp_m - exp za potworka! i zastanawiam się nad funkcją typu int czyli int getExp_m(Rat& R || Lizard& L ||Goblin& G || Bat& B)
<<Max_exp-exp<<" expa do nowego LVL'a"<<endl;
}
}
main.cpp

///Modyfikacje: Stworzenie lvli i expa za potworki
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include "Rat.h"
#include "Character.h"

using namespace std;

int main()
{
losowanie:
int x;

Character ch;
ch.load(); //metoda oddziedziczona po klasie Creature
ch.show(); //metoda oddziedziczona po klasie Creature

system("clear");
cout<<"Wybierz z kim chcesz walczyć :" //to zamienie na losowanie automatyczne ale na próbe dałem wybór "ręczny"
<<"\n1.Szczur"<<
"\n2.Goblin"<<
"\n3.Nietoperz"<<
"\n4.Jaszczur(Silny !)"<<endl
<<"5.Bierzesz nogi za pas!(Nie polecam! Tylko dla tchórzy!)"<<
"\nTwój wybór to: ";
cin>>x;
if(x==1)
{
Rat rats;

rats.respawn();
rats.LVL(ch);

rats.show();
ch.porownaj(rats);
sleep(2);
}
if(x==2){

system("clear");
cout<<"Goblin!\n";
sleep(2);
}

if(x==3)
{
system("clear");
cout<<"Nietoperz!\n";
sleep(2);
}
if(x==4)
{
system("clear");
cout<<"Aż tak ci śpieszno do grobu!?\n";
sleep(2);
}
if(x==5)
{
}
else{
goto losowanie;
}

return 0;
}
 
Character.h

#pragma once
#include <iostream>
#include "Creature.h"
#include "Rat.h"

class Rat;
class Character : public Creature {

public:
    Character(std::string = "Mr.Nobody", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Character(); //destruktor
    /* //Level
    int pkt_exp=10; //pkt umiejętności do wydania na sam początek jak chyba w każdym RPGu dostajemy punkty umiejętności do wydania…
    int Max_exp,Exp; //Próg expa oraz nasze aktualne pkt doświadczenia
    int New_LVL(); //funkcja sprawdzająca czy wbiliśmy lvl czy też nie…
    */
    void load();
    void show();
    int LVL_P=1; //Level naszej postaci(na początek każda postać ma 1 lvl).
    void porownaj(const Rat& monster);
    int getLVL(); //funkcja zwracająca lvl naszej postaci do losowania lvl'a potworka
};


 
Character.cpp

///modyfikacje: Wprowadzenie LVLi
#include <iostream>
#include <cstdlib>
#include "Rat.h"
#include "Character.h"
#include <unistd.h>
using namespace std;

void Character::load() //metoda wczytujaca dane postaci
{
    cout << "\nCzy chcesz wprowadzić Atrybuty Postaci(t/n)?";
    cin >> odp;
    if (odp == 't' || odp == 'T') {
        cout << "\nPodaj "<<Italic_cyan<<"Nazwe Postaci"<<white<<":";
        cin >> nazwa;
        cout << "Podaj "<<yellow<<"Sile "<<white<< nazwa << "'a:";
        cin >> sila;
        cout << "Podaj "<<purple<<"Wytrzymalosc "<<white<< nazwa << "'a:";
        cin >> wytrzymalosc;
        cout << "Podaj Ilosc "<<red<<"Zdrowia "<<white << nazwa << "'a:";
        cin >> zdrowie;
        cout << "Podaj "<<green<<"Zrecznosc "<<white<< nazwa << "'a:";
        cin >> zrecznosc;
        cout << "Podaj "<<blue<<"Inteligencje "<<white<< nazwa << "'a:";
        cin >> inteligencja;
        cout << "\n";
    }
}
void Character::show() //metoda ukazująca dane postaci
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Postaci"<<white<<":" << nazwa << endl
         <<"Poziom Postaci:"<<LVL_P<<endl
         <<yellow<<"Sila"<<white<<":" << sila << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc << endl
         <<red<<"Zdrowie"<<white<<":" << zdrowie *LVL_P<< endl
         <<green<<"Zrecznosc"<<white<<":" << zrecznosc << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja << endl;
         sleep(2);
    nP = nazwa;
    wynik1 = (sila + wytrzymalosc + zrecznosc + inteligencja )* zdrowie;
}

Character::Character(string n, int s, int w, float zdr, int zr, int intel) //konstruktor klasy Character
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Character::~Character() //destruktor klasy Character
{
    cout << "\nJezeli widzisz ten komunikat to znaczy,ze twoj komputer zniknie za…1…2…3 BOOM!" << endl;
}

int Character::getLVL() //funkcja zwracająca poziom postaci do losowania poziomu Potwora
{
    return LVL_P;
}

/*
//funkcja sprawdzająca czy wbiliśmy lvl jeżeli wygraliśmy rzecz jasna!
//funkcja podobnie działająca do funkcji losującej level lub funkcji porównującej czyli pobieranie z innej klasy zmiennej

int New_LVL()
{
exp+=exp_m //exp po wygranej walce
Max_exp=100*LVL_P; //próg czyli ile musimy wbić expa aby osiągnąć nowy level!
if(exp==Max_exp) //warunek sprawdzający czy już mam nowy level
{
cout<<"Masz nowy Poziom!\n"<<
"Twoj LVL to"<<LVL_P+1<<
"\nDo wydania :"<<pkt_exp+10; //pkt umiejętności do wydania
}
else //gdy jednak nie będziemy mieli wystarczającej ilości expa
{
cout<<"Brawo,Wygrales ! Dostajesz "<<exp_m<<".Brakuje ci " //exp_m - exp za potworka! W tym wypadku zamieniłbym to na funkcję zwracającą exp ale zależnie od potwora jaki nam się wylosuje czyli ta zmienna musi być w jakiś sposób uniwersalna(Jakiś wskaźnik lub coś…)!
<<Max_exp-exp<<" expa do nowego LVL'a"<<endl;
}
}
*/
void Character::porownaj(const Rat& monster)
{
    if (wynik1 > monster.getScore())

        cout << monster.getName() << " Przegralby z " << nP;

    if (wynik1 < monster.getScore())

        cout << monster.getName() << " Wygralby z " << nP;

    if (wynik1 == monster.getScore())

        cout << "Bylby remis";
}
 
Rat.h

#pragma once
#ifndef RAT_H
#define RAT_H
#include "Monster.h"
#include "Character.h"


class Character;
class Rat : public Monster
{
    public:
    Rat(std::string = "Szczur", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Rat(); //destruktor
    int LVL(Character& Char); ///funkcja losująca level
    void respawn(); ///funkcja pokazująca z kim mamy do czynienia…
    void show(); ///funkcja obliczająca oraz pokazująca staty potwora oraz zamiana ich na wynik który ma wpływ na wynik walki
    int getScore() const; ///funkcja zwracająca wynik
    std::string getName() const; ///funkcja zwracająca nazwe potworka
};

#endif // RAT_H
 
Rat.cpp

#include <iostream>
#include <random>
#include <cstdlib>
#include "Character.h"
#include "Rat.h"

using namespace std;

  random_device rd;   // generator liczb losowych (przynajmniej tak zrozumiałem z tłumaczenia) ;)
  mt19937 gen(rd());  // to seed mersenne twister. - do zasiania mersenne twister

  uniform_int_distribution<> wR(1,2); // zakres losowania pkt. wytrzymałości wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> sR(1,2); // zakres losowania pkt. siły wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zrR(1,5); // zakres losowania pkt. zręczności wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> intelR(1,3); // zakres losowania pkt. inteligencji wyłącznie pomiędzy 1 a 2.


int s1=sR(gen);
int w1=wR(gen);
int zr1=zrR(gen);
int intel1=intelR(gen);

int sila1,wytrzymalosc1,zrecznosc1,inteligencja1;
float zdrowie1;

struct lvl //struktura w której jest przechowywana zmienna w której przechowywać się będzie lvl potwora
{
int LVL_M;
};

lvl lvl1; //nazwa struktury i obiekt tej struktury

//zwracanie lvl'a gracza oraz losowanie lvl'a potworka
int Rat::LVL(Character& Char)
{


uniform_int_distribution<> LvL_M(Char.getLVL(),Char.getLVL()+2); // zakres losowania lvli wyłącznie pomiędzy 1 a 10.
lvl1.LVL_M=LvL_M(gen);
cout<<"\nSzczur ma LVL: "<<lvl1.LVL_M<<endl;
///exp_m=10*lvl1.LVL_M; //exp jak naliczyć należy za szczura
}


void Rat::respawn() //funkcja zwracająca Lvl Potworka- Szczura
{
cout<<"UWAGA!To POTWÓR!"<<np<<"!"<<endl;
}




void Rat::show() //metoda ukazująca dane potworka
{
    cout <<Italic_cyan<<"Nazwa Potwora"<<white<<":" << nazwa <<endl
         <<"Poziom Potwora:"<<lvl1.LVL_M<<endl
         <<yellow<< "Sila" <<white<<":"<< sila + s1 * lvl1.LVL_M<< endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc + w1 *lvl1.LVL_M<< endl
         <<red<<"Zdrowie"<<white<<":"<< zdrowie*lvl1.LVL_M<< endl
         <<green<<"Zrecznosc"<<white<<":"<< zrecznosc + zr1 *lvl1.LVL_M<< endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja + intel1 *lvl1.LVL_M<< endl;

    np = nazwa;

//dodawanie wartości podstawowej do wylosowanej

    sila1=sila + s1*lvl1.LVL_M;
    wytrzymalosc1=wytrzymalosc + w1*lvl1.LVL_M;
    zdrowie1=zdrowie*lvl1.LVL_M;
    zrecznosc1=zrecznosc + zr1*lvl1.LVL_M;
    inteligencja1=inteligencja + intel1*lvl1.LVL_M;

    wynik = (sila1 + wytrzymalosc1 + zrecznosc1 + inteligencja1) * zdrowie1;
}
 //koniec voida

Rat::Rat(string n, int s, int w, float zdr, int zr, int intel) //konstruktor
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Rat::~Rat() //destruktor
{
    cout << "\nMozna dzialac na nowo :D" << endl;
}

int Rat::getScore() const //funkcja zwracająca wartość całkowitą czyli "int"
{
    return wynik;
}

string Rat::getName() const //funkcja zwracająca nazwe czyli "string"
{
    return nazwa;
}

 
Monster.h

#pragma once
#include <iostream>
#include "Creature.h"

class Monster : public Creature {
public:
//int exp_m; //exp za potworka
virtual void respawn()=0;

};
 
0

Ok,można pominąć to co wyżej bo juz mniej więcej rozkminiłem koncepcje nie wiem czy słuszną czy też nie…Chodzi o to że mam pewien problem który za bardzo nic mi nie mówi…po prostu nie wiem czemu kod nie chce się z kompilować wyświetlając błąd:

Błąd
error: ld returned 1 exit status

A tu wstawie kod którego zapewne dotyczy:

Lizard.h

#pragma once
#ifndef LIZARD_H
#define LIZARD_H
#include "Monster.h"
#include "Character.h"


class Character;
class Lizard : public Monster
{
    public:

    Lizard(std::string = "Jaszczur", int = 5, int = 5, float = 150, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Lizard(); //destruktor
    int LVL(Character& Char); ///funkcja losująca level
    void respawn(); ///funkcja pokazująca z kim mamy do czynienia…
    void show(); ///funkcja obliczająca oraz pokazująca staty potwora oraz zamiana ich na wynik który ma wpływ na wynik walki
    int getExp_m() const; ///funkcja zwracająca punkty doświadczenia za potworka
    int getScore() const; ///funkcja zwracająca wynik
    std::string getName() const; ///funkcja zwracająca nazwe potworka
};

#endif // LIZARD_H
 
Lizard.cpp

#include <iostream>
#include <random>
#include <cstdlib>
#include "Character.h"
#include "Lizard.h"

using namespace std;

Lizard::Lizard(string n, int s, int w, float zdr, int zr, int intel) //konstruktor
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}

Lizard::~Lizard()
{
  cout << "\nSzacunek…Udało ci się pokonać tą bestie!" << endl;  //dtor
}

  random_device rd;   // generator liczb losowych (przynajmniej tak zrozumiałem z tłumaczenia) ;)
  mt19937 gen(rd());  // to seed mersenne twister. - do zasiania mersenne twister

  uniform_int_distribution<> wR(1,4); // zakres losowania pkt. wytrzymałości wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> sR(1,6); // zakres losowania pkt. siły wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zrR(1,5); // zakres losowania pkt. zręczności wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> intelR(1,2); // zakres losowania pkt. inteligencji wyłącznie pomiędzy 1 a 2.


int s1=sR(gen);
int w1=wR(gen);
int zr1=zrR(gen);
int intel1=intelR(gen);

int sila1,wytrzymalosc1,zrecznosc1,inteligencja1;
float zdrowie1;

struct lvl //struktura w której jest przechowywana zmienna w której przechowywać się będzie lvl potwora
{
int LVL_M;
int Exp_m;
};

lvl lvl1; //nazwa struktury i obiekt tej struktury

//zwracanie lvl'a gracza oraz losowanie lvl'a potworka
int Lizard::LVL(Character& Char1)
{


uniform_int_distribution<> LvL_M(Char1.getLVL(),Char1.getLVL()+2); // zakres losowania lvli wyłącznie pomiędzy 1 a 10.
lvl1.LVL_M=LvL_M(gen);
cout<<"\nJaszczur ma LVL: "<<lvl1.LVL_M<<endl;
} 


void Lizard::respawn() //funkcja zwracająca Lvl Potworka- Szczura oraz naliczająca exp za stworka
{
cout<<"UWAGA!To POTWÓR!"<<np<<"!"<<endl;
lvl1.Exp_m=40*lvl1.LVL_M; //exp jak naliczyć należy za szczura
}




void Lizard::show() //metoda ukazująca dane potworka
{
    cout <<Italic_cyan<<"Nazwa Potwora"<<white<<":" << nazwa <<endl
         <<"Poziom Potwora:"<<lvl1.LVL_M<<endl
         <<yellow<< "Sila" <<white<<":"<< sila + s1 * lvl1.LVL_M<< endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc + w1 *lvl1.LVL_M<< endl
         <<red<<"Zdrowie"<<white<<":"<< zdrowie*lvl1.LVL_M<< endl
         <<green<<"Zrecznosc"<<white<<":"<< zrecznosc + zr1 *lvl1.LVL_M<< endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja + intel1 *lvl1.LVL_M<< endl;

    np = nazwa;

//dodawanie wartości podstawowej do wylosowanej

    sila1=sila + s1*lvl1.LVL_M;
    wytrzymalosc1=wytrzymalosc + w1*lvl1.LVL_M;
    zdrowie1=zdrowie*lvl1.LVL_M;
    zrecznosc1=zrecznosc + zr1*lvl1.LVL_M;
    inteligencja1=inteligencja + intel1*lvl1.LVL_M;

    wynik = (sila1 + wytrzymalosc1 + zrecznosc1 + inteligencja1) * zdrowie1;
}
int Lizard::getExp_m() const //zwracanie exp'a z potworka
{
    return lvl1.Exp_m;
}
int Lizard::getScore() const //funkcja zwracająca wartość całkowitą czyli "int"
{
    return wynik;
}

string Lizard::getName() const //funkcja zwracająca nazwe czyli "string"
{
    return nazwa;
}

 
Character.h

#pragma once
#include <iostream>
#include "Creature.h"
#include "Rat.h"
#include "Lizard.h"
class Rat;
class Lizard;
class Character : public Creature {

public:
    Character(std::string = "Mr.Nobody", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Character(); //destruktor
     //Level
    int Exp=10;
    int Max_exp,pkt_exp;
    int New_LVL_R(const Rat& m);
    int New_LVL_L(const Lizard& l);
    /*int New_LVL_G(const Goblin& g);
      int New_LVL_B(const Bat& b);
    */
    void load();
    void show();
    int LVL_P=1;
    void porownaj_R(const Rat& monster);
    void porownaj_L(const Lizard& monster_l);
    /*
    void porownaj_B(const Bat& monster_b);
    void porownaj_G(const Goblin& monster_g);

    */
    int getLVL();
};

 
Character.cpp

///modyfikacje: Wprowadzenie LVLi
#include <iostream>
#include <cstdlib>
#include "Rat.h"
#include "Lizard.h"
#include "Character.h"
#include <unistd.h>
using namespace std;
struct wins
{
bool win=false;
};
wins win1;
void Character::load() //metoda wczytujaca dane postaci
{
    cout << "\nCzy chcesz wprowadzić Atrybuty Postaci(t/n)?";
    cin >> odp;
    if (odp == 't' || odp == 'T') {
        cout << "\nPodaj "<<Italic_cyan<<"Nazwe Postaci"<<white<<":";
        cin >> nazwa;
        cout << "Podaj "<<yellow<<"Sile "<<white<< nazwa << "'a:";
        cin >> sila;
        cout << "Podaj "<<purple<<"Wytrzymalosc "<<white<< nazwa << "'a:";
        cin >> wytrzymalosc;
        cout << "Podaj Ilosc "<<red<<"Zdrowia "<<white << nazwa << "'a:";
        cin >> zdrowie;
        cout << "Podaj "<<green<<"Zrecznosc "<<white<< nazwa << "'a:";
        cin >> zrecznosc;
        cout << "Podaj "<<blue<<"Inteligencje "<<white<< nazwa << "'a:";
        cin >> inteligencja;
        cout << "\n";
    }
}
void Character::show() //metoda ukazująca dane postaci
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Postaci"<<white<<":" << nazwa << endl
         <<"Poziom Postaci:"<<LVL_P<<endl
         <<yellow<<"Sila"<<white<<":" << sila << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc << endl
         <<red<<"Zdrowie"<<white<<":" << zdrowie *LVL_P<< endl
         <<green<<"Zrecznosc"<<white<<":" << zrecznosc << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja << endl;
         sleep(2);
    nP = nazwa;
    wynik1 = (sila + wytrzymalosc + zrecznosc + inteligencja )* zdrowie;
}

Character::Character(string n, int s, int w, float zdr, int zr, int intel) //konstruktor klasy Character
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Character::~Character() //destruktor klasy Character
{
    cout << "\nJezeli widzisz ten komunikat to znaczy,ze twoj komputer zniknie za…1…2…3 BOOM!" << endl;
}

int Character::getLVL() //funkcja zwracająca poziom postaci do losowania poziomu Potwora
{
    return LVL_P;
}


//funkcja sprawdzająca czy wbiliśmy lvl jeżeli wygraliśmy rzecz jasna!
//funkcja podobnie działająca do funkcji losującej level lub funkcji porównującej czyli pobieranie z innej klasy zmiennej

int Character::New_LVL_R(const Rat& m)
{
Exp+=m.getExp_m(); //exp po wygranej walce
Max_exp=100*LVL_P;
if(Exp==Max_exp)
{
cout<<"Masz nowy Poziom!\n"<<
"Twoj LVL to"<<LVL_P+1<<
"\nDo wydania :"<<pkt_exp+10;
}
else
{
cout<<"Brawo,Wygrales ! Dostajesz "<<m.getExp_m()<<".Brakuje ci "
<<Max_exp-Exp<<" expa do nowego LVL'a"<<endl;
}

}

int Character::New_LVL_L(const Lizard& l)
{
Exp+=l.getExp_m(); //exp po wygranej walce
Max_exp=100*LVL_P;
if(Exp==Max_exp)
{
cout<<"Masz nowy Poziom!\n"<<
"Twoj LVL to"<<LVL_P+1<<
"\nDo wydania :"<<pkt_exp+10;
}
else
{
cout<<"Brawo,Wygrales ! Dostajesz "<<l.getExp_m()<<".Brakuje ci "
<<Max_exp-Exp<<" expa do nowego LVL'a"<<endl;
}

}

void Character::porownaj_R(const Rat& monster)
{
    if (wynik1 > monster.getScore())
        {
        cout << monster.getName() << " Przegralby z " << nP;
        win1.win=true;
        int New_LVL_R(const Rat& monster);
        }
    if (wynik1 < monster.getScore())

        cout << monster.getName() << " Wygralby z " << nP;

    if (wynik1 == monster.getScore())

        cout << "Bylby remis";
}
void Character::porownaj_L(const Lizard& monster_l)
{
    if (wynik1 > monster_l.getScore())
       {
        cout << monster_l.getName() << " Przegralby z " << nP;
                win1.win=true;
                int New_LVL_L(const Lizard& monster_l);
        }
    if (wynik1 < monster_l.getScore())

        cout << monster_l.getName() << " Wygralby z " << nP;

    if (wynik1 == monster_l.getScore())

        cout << "Bylby remis";
}
 
main.cpp

///modyfikacje: Wprowadzenie LVLi
#include <iostream>
#include <cstdlib>
#include "Rat.h"
#include "Lizard.h"
#include "Character.h"
#include <unistd.h>
using namespace std;
struct wins
{
bool win=false;
};
wins win1;
void Character::load() //metoda wczytujaca dane postaci
{
    cout << "\nCzy chcesz wprowadzić Atrybuty Postaci(t/n)?";
    cin >> odp;
    if (odp == 't' || odp == 'T') {
        cout << "\nPodaj "<<Italic_cyan<<"Nazwe Postaci"<<white<<":";
        cin >> nazwa;
        cout << "Podaj "<<yellow<<"Sile "<<white<< nazwa << "'a:";
        cin >> sila;
        cout << "Podaj "<<purple<<"Wytrzymalosc "<<white<< nazwa << "'a:";
        cin >> wytrzymalosc;
        cout << "Podaj Ilosc "<<red<<"Zdrowia "<<white << nazwa << "'a:";
        cin >> zdrowie;
        cout << "Podaj "<<green<<"Zrecznosc "<<white<< nazwa << "'a:";
        cin >> zrecznosc;
        cout << "Podaj "<<blue<<"Inteligencje "<<white<< nazwa << "'a:";
        cin >> inteligencja;
        cout << "\n";
    }
}
void Character::show() //metoda ukazująca dane postaci
{
    system("clear");
    cout <<Italic_cyan<<"Nazwa Postaci"<<white<<":" << nazwa << endl
         <<"Poziom Postaci:"<<LVL_P<<endl
         <<yellow<<"Sila"<<white<<":" << sila << endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc << endl
         <<red<<"Zdrowie"<<white<<":" << zdrowie *LVL_P<< endl
         <<green<<"Zrecznosc"<<white<<":" << zrecznosc << endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja << endl;
         sleep(2);
    nP = nazwa;
    wynik1 = (sila + wytrzymalosc + zrecznosc + inteligencja )* zdrowie;
}

Character::Character(string n, int s, int w, float zdr, int zr, int intel) //konstruktor klasy Character
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Character::~Character() //destruktor klasy Character
{
    cout << "\nJezeli widzisz ten komunikat to znaczy,ze twoj komputer zniknie za…1…2…3 BOOM!" << endl;
}

int Character::getLVL() //funkcja zwracająca poziom postaci do losowania poziomu Potwora
{
    return LVL_P;
}


//funkcja sprawdzająca czy wbiliśmy lvl jeżeli wygraliśmy rzecz jasna!
//funkcja podobnie działająca do funkcji losującej level lub funkcji porównującej czyli pobieranie z innej klasy zmiennej

int Character::New_LVL_R(const Rat& m)
{
Exp+=m.getExp_m(); //exp po wygranej walce
Max_exp=100*LVL_P;
if(Exp==Max_exp)
{
cout<<"Masz nowy Poziom!\n"<<
"Twoj LVL to"<<LVL_P+1<<
"\nDo wydania :"<<pkt_exp+10;
}
else
{
cout<<"Brawo,Wygrales ! Dostajesz "<<m.getExp_m()<<".Brakuje ci "
<<Max_exp-Exp<<" expa do nowego LVL'a"<<endl;
}

}

int Character::New_LVL_L(const Lizard& l)
{
Exp+=l.getExp_m(); //exp po wygranej walce
Max_exp=100*LVL_P;
if(Exp==Max_exp)
{
cout<<"Masz nowy Poziom!\n"<<
"Twoj LVL to"<<LVL_P+1<<
"\nDo wydania :"<<pkt_exp+10;
}
else
{
cout<<"Brawo,Wygrales ! Dostajesz "<<l.getExp_m()<<".Brakuje ci "
<<Max_exp-Exp<<" expa do nowego LVL'a"<<endl;
}

}

void Character::porownaj_R(const Rat& monster)
{
    if (wynik1 > monster.getScore())
        {
        cout << monster.getName() << " Przegralby z " << nP;
        win1.win=true;
        int New_LVL_R(const Rat& monster);
        }
    if (wynik1 < monster.getScore())

        cout << monster.getName() << " Wygralby z " << nP;

    if (wynik1 == monster.getScore())

        cout << "Bylby remis";
}
void Character::porownaj_L(const Lizard& monster_l)
{
    if (wynik1 > monster_l.getScore())
       {
        cout << monster_l.getName() << " Przegralby z " << nP;
                win1.win=true;
                int New_LVL_L(const Lizard& monster_l);
        }
    if (wynik1 < monster_l.getScore())

        cout << monster_l.getName() << " Wygralby z " << nP;

    if (wynik1 == monster_l.getScore())

        cout << "Bylby remis";
}

 
Rat.h

#pragma once
#ifndef RAT_H
#define RAT_H
#include "Monster.h"
#include "Character.h"


class Character;
class Rat : public Monster
{
    public:
    Rat(std::string = "Szczur", int = 5, int = 5, float = 100, int = 5, int = 5); //konstruktor i wartosci domyslne tego konstruktora
    ~Rat(); //destruktor
    int LVL(Character& Char); ///funkcja losująca level
    void respawn(); ///funkcja pokazująca z kim mamy do czynienia…
    void show(); ///funkcja obliczająca oraz pokazująca staty potwora oraz zamiana ich na wynik który ma wpływ na wynik walki
    int getExp_m() const; ///funkcja zwracająca punkty doświadczenia za potworka
    int getScore() const; ///funkcja zwracająca wynik
    std::string getName() const; ///funkcja zwracająca nazwe potworka
};

#endif // RAT_H
Rat.cpp

#include <iostream>
#include <random>
#include <cstdlib>
#include "Character.h"
#include "Rat.h"

using namespace std;

 Rat::Rat(string n, int s, int w, float zdr, int zr, int intel) //konstruktor
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}
Rat::~Rat() //destruktor
{
    cout << "\nMozna dzialac na nowo :D" << endl;
}

  random_device rd;   // generator liczb losowych (przynajmniej tak zrozumiałem z tłumaczenia) ;)
  mt19937 gen(rd());  // to seed mersenne twister. - do zasiania mersenne twister

  uniform_int_distribution<> wR(1,2); // zakres losowania pkt. wytrzymałości wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> sR(1,2); // zakres losowania pkt. siły wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zrR(1,5); // zakres losowania pkt. zręczności wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> intelR(1,3); // zakres losowania pkt. inteligencji wyłącznie pomiędzy 1 a 2.


int s1=sR(gen);
int w1=wR(gen);
int zr1=zrR(gen);
int intel1=intelR(gen);

int sila1,wytrzymalosc1,zrecznosc1,inteligencja1;
float zdrowie1;

struct lvl //struktura w której jest przechowywana zmienna w której przechowywać się będzie lvl potwora
{
int LVL_M;
int Exp_m;
};

lvl lvl1; //nazwa struktury i obiekt tej struktury

//zwracanie lvl'a gracza oraz losowanie lvl'a potworka
int Rat::LVL(Character& Char)
{


uniform_int_distribution<> LvL_M(Char.getLVL(),Char.getLVL()+2); // zakres losowania lvli wyłącznie pomiędzy 1 a 10.
lvl1.LVL_M=LvL_M(gen);
cout<<"\nSzczur ma LVL: "<<lvl1.LVL_M<<endl;
}


void Rat::respawn() //funkcja zwracająca Lvl Potworka- Szczura oraz naliczająca exp za stworka
{
cout<<"UWAGA!To POTWÓR!"<<np<<"!"<<endl;
lvl1.Exp_m=10*lvl1.LVL_M; //exp jak naliczyć należy za szczura
}




void Rat::show() //metoda ukazująca dane potworka
{
    cout <<Italic_cyan<<"Nazwa Potwora"<<white<<":" << nazwa <<endl
         <<"Poziom Potwora:"<<lvl1.LVL_M<<endl
         <<yellow<< "Sila" <<white<<":"<< sila + s1 * lvl1.LVL_M<< endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc + w1 *lvl1.LVL_M<< endl
         <<red<<"Zdrowie"<<white<<":"<< zdrowie*lvl1.LVL_M<< endl
         <<green<<"Zrecznosc"<<white<<":"<< zrecznosc + zr1 *lvl1.LVL_M<< endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja + intel1 *lvl1.LVL_M<< endl;

    np = nazwa;

//dodawanie wartości podstawowej do wylosowanej

    sila1=sila + s1*lvl1.LVL_M;
    wytrzymalosc1=wytrzymalosc + w1*lvl1.LVL_M;
    zdrowie1=zdrowie*lvl1.LVL_M;
    zrecznosc1=zrecznosc + zr1*lvl1.LVL_M;
    inteligencja1=inteligencja + intel1*lvl1.LVL_M;

    wynik = (sila1 + wytrzymalosc1 + zrecznosc1 + inteligencja1) * zdrowie1;
}
 //koniec voida


int Rat::getExp_m() const //zwracanie exp'a z potworka
{
    return lvl1.Exp_m;
}
int Rat::getScore() const //funkcja zwracająca wartość całkowitą czyli "int"
{
    return wynik;
}

string Rat::getName() const //funkcja zwracająca nazwe czyli "string"
{
    return nazwa;
}

Monster.h

#pragma once
#include <iostream>
#include "Creature.h"

class Monster : public Creature {
public:
//int exp_m; //exp za potworka
virtual void respawn()=0;

};
0

error: ld returned 1 exit status

To nie jest cały komunikat błędu. Zwykle linijkę wcześniej jest faktyczny błąd (najczęściej undefined reference to ).

0

@carlosmay

To nie jest cały komunikat błędu. Zwykle linijkę wcześniej jest faktyczny błąd (najczęściej undefined reference to ).
No to chyba mam zepsuty kompilator…
2016-11-04-065004_1280x998_scrot.png
2016-11-04-065103_1280x998_scrot.png

0

Wklejam build logi !


-------------- Build: Debug in RPG (compiler: GNU GCC Compiler)---------------

g++ -L/usr/share/doc/ -L/usr/lib/i386-linux-gnu/ -L/usr/include/ -o bin/Debug/RPG obj/Debug/Character.o obj/Debug/Lizard.o obj/Debug/main.o obj/Debug/Rat.o   
obj/Debug/Rat.o:(.bss+0x0): multiple definition of `rd'
obj/Debug/Lizard.o:(.bss+0x0): first defined here
obj/Debug/Rat.o:(.bss+0x9e0): multiple definition of `gen'
obj/Debug/Lizard.o:(.bss+0x9e0): first defined here
obj/Debug/Rat.o:(.bss+0x13a4): multiple definition of `wR'
obj/Debug/Lizard.o:(.bss+0x13a4): first defined here
obj/Debug/Rat.o:(.bss+0x13ac): multiple definition of `sR'
obj/Debug/Lizard.o:(.bss+0x13ac): first defined here
obj/Debug/Rat.o:(.bss+0x13b4): multiple definition of `zrR'
obj/Debug/Lizard.o:(.bss+0x13b4): first defined here
obj/Debug/Rat.o:(.bss+0x13bc): multiple definition of `intelR'
obj/Debug/Lizard.o:(.bss+0x13bc): first defined here
obj/Debug/Rat.o:(.bss+0x13c4): multiple definition of `s1'
obj/Debug/Lizard.o:(.bss+0x13c4): first defined here
obj/Debug/Rat.o:(.bss+0x13c8): multiple definition of `w1'
obj/Debug/Lizard.o:(.bss+0x13c8): first defined here
obj/Debug/Rat.o:(.bss+0x13cc): multiple definition of `zr1'
obj/Debug/Lizard.o:(.bss+0x13cc): first defined here
obj/Debug/Rat.o:(.bss+0x13d0): multiple definition of `intel1'
obj/Debug/Lizard.o:(.bss+0x13d0): first defined here
obj/Debug/Rat.o:(.bss+0x13d4): multiple definition of `sila1'
obj/Debug/Lizard.o:(.bss+0x13d4): first defined here
obj/Debug/Rat.o:(.bss+0x13d8): multiple definition of `wytrzymalosc1'
obj/Debug/Lizard.o:(.bss+0x13d8): first defined here
obj/Debug/Rat.o:(.bss+0x13dc): multiple definition of `zrecznosc1'
obj/Debug/Lizard.o:(.bss+0x13dc): first defined here
obj/Debug/Rat.o:(.bss+0x13e0): multiple definition of `inteligencja1'
obj/Debug/Lizard.o:(.bss+0x13e0): first defined here
obj/Debug/Rat.o:(.bss+0x13e4): multiple definition of `zdrowie1'
obj/Debug/Lizard.o:(.bss+0x13e4): first defined here
obj/Debug/Rat.o:(.bss+0x13e8): multiple definition of `lvl1'
obj/Debug/Lizard.o:(.bss+0x13e8): first defined here
collect2: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 2 second(s))
1 error(s), 0 warning(s) (0 minute(s), 2 second(s))
 

#Edit Ok,działa wystarczyło pozamieniać nazwy zmiennych… choć próbuje jeszcze zrozumieć co znaczy ten komunikat :
warning: no return statement in function returning non-void [-Wreturn-type]|

ogólnie kod działa znaczy kompiluje się bez problemu…ale ten warning mnie niepokoji…

Jaszczur.cpp

#include <iostream>
#include <random>
#include <cstdlib>
#include "Character.h"
#include "Lizard.h"

using namespace std;

Lizard::Lizard(string n, int s, int w, float zdr, int zr, int intel) //konstruktor
{
    nazwa = n;
    sila = s;
    wytrzymalosc = w;
    zdrowie = zdr;
    zrecznosc = zr;
    inteligencja = intel;
}

Lizard::~Lizard()
{
  cout << "\nSzacunek…Udało ci się pokonać tą bestie!" << endl;  //dtor
}

  random_device rd_L;   // generator liczb losowych (przynajmniej tak zrozumiałem z tłumaczenia) ;)
  mt19937 gen_L(rd_L());  // to seed mersenne twister. - do zasiania mersenne twister

  uniform_int_distribution<> wR_L(1,4); // zakres losowania pkt. wytrzymałości wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> sR_L(1,6); // zakres losowania pkt. siły wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> zrR_L(1,5); // zakres losowania pkt. zręczności wyłącznie pomiędzy 1 a 2.
  uniform_int_distribution<> intelR_L(1,2); // zakres losowania pkt. inteligencji wyłącznie pomiędzy 1 a 2.


int s_L=sR_L(gen_L);
int w_L=wR_L(gen_L);
int zr_L=zrR_L(gen_L);
int intel_L=intelR_L(gen_L);

int sila_L,wytrzymalosc_L,zrecznosc_L,inteligencja_L;
float zdrowie_L;

//zwracanie lvl'a gracza oraz losowanie lvl'a potworka
int Lizard::LVL(Character& Char1)
{


uniform_int_distribution<> LvL_M(Char1.getLVL(),Char1.getLVL()+2); // zakres losowania lvli wyłącznie pomiędzy 1 a 10.
lvl1.LVL_M=LvL_M(gen_L);
cout<<"\nJaszczur ma LVL: "<<lvl1.LVL_M<<endl;
} //<- do tej funkcji się odnosi ten warning


void Lizard::respawn() //funkcja zwracająca Lvl Potworka- Jaszczura oraz naliczająca exp za stworka
{
cout<<"UWAGA!To POTWÓR!"<<np<<"!"<<endl;
lvl1.Exp_m=40*lvl1.LVL_M; //exp jak naliczyć należy za szczura
}




void Lizard::show() //metoda ukazująca dane potworka
{
    cout <<Italic_cyan<<"Nazwa Potwora"<<white<<":" << nazwa <<endl
         <<"Poziom Potwora:"<<lvl1.LVL_M<<endl
         <<yellow<< "Sila" <<white<<":"<< sila + s_L * lvl1.LVL_M<< endl
         <<purple<<"Wytrzymalosc"<<white<<":" << wytrzymalosc + w_L *lvl1.LVL_M<< endl
         <<red<<"Zdrowie"<<white<<":"<< zdrowie*lvl1.LVL_M<< endl
         <<green<<"Zrecznosc"<<white<<":"<< zrecznosc + zr_L *lvl1.LVL_M<< endl
         <<blue<<"Inteligencja"<<white<<":" << inteligencja + intel_L *lvl1.LVL_M<< endl;

    np = nazwa;

//dodawanie wartości podstawowej do wylosowanej

    sila_L=sila + s_L*lvl1.LVL_M;
    wytrzymalosc_L=wytrzymalosc + w_L*lvl1.LVL_M;
    zdrowie_L=zdrowie*lvl1.LVL_M;
    zrecznosc_L=zrecznosc + zr_L*lvl1.LVL_M;
    inteligencja_L=inteligencja + intel_L*lvl1.LVL_M;

    wynik = (sila_L + wytrzymalosc_L + zrecznosc_L + inteligencja_L) * zdrowie_L;
}
int Lizard::getExp_m() const //zwracanie exp'a z potworka
{
    return lvl1.Exp_m;
}
int Lizard::getScore() const //funkcja zwracająca wartość całkowitą czyli "int"
{
    return wynik;
}

string Lizard::getName() const //funkcja zwracająca nazwe czyli "string"
{
    return nazwa;
}

0

Ok,poradziłem sobie z tym warningiem zamieniając int na void ponieważ int nic nie zwracał…czyli nie było

return

Ale mam mały kłopot z metodą ponieważ nie wiem jak przypisać jej obiekt w innej metodzie… a bez obiektu ona się nie wyświetli…
I tak działa program tzn.kompiluje się bez żadnych warning'ów i error'ów

void Character::porownaj_L(const Lizard& monster_l)
{
    if (wynik1 > monster_l.getScore())
       {
        cout << monster_l.getName() << " Przegralby z " << nP;
                win1.win=true;
                void New_LVL_L(const Lizard& l); //<- w tej metodzie nie wiem jak przypisać obiekt taki sam jak w metodzie nadrzędnej
        }
    if (wynik1 < monster_l.getScore())

        cout << monster_l.getName() << " Wygralby z " << nP;

    if (wynik1 == monster_l.getScore())

        cout << "Bylby remis";
}
 

Ciało tej metody:

void Character::New_LVL_L(const Lizard& l)
{
    Exp += l.getExp_m(); //exp po wygranej walce
    Max_exp = 100 * LVL_P; //Exp do wbicia nowego LVL'a

    if (Exp == Max_exp) {

        cout << "Masz nowy Poziom!\n"
               << "Twoj LVL to" << LVL_P + 1 << "\nDo wydania :" << pkt_exp + 10;
        sleep(3);
    }

    else {

        cout << "Brawo,Wygrales ! Dostajesz " << l.getExp_m() << ".Brakuje ci "
             << Max_exp - Exp << " expa do nowego LVL'a" << endl;
        sleep(3);
    }
}
 
0

Ale mam mały kłopot z metodą ponieważ nie wiem jak przypisać jej obiekt w innej metodzie…

Konkretniej. Może napisz co chcesz gdzie przekazać i co chcesz z tym zrobić.

0

A więc tak: Metoda

void Character::New_LVL_L(const Lizard& l)

jest metodą która ma się uruchomić/wyświetlić tylko wtedy gdy Bohater wygra z przeciwnikiem czyli gdy :win1.win=true;

 ale by to zrobić potrzebny mi obiekt klasy <code class="cpp">class Character 

a ta metoda znajduje się w metodzie void Character::porownaj_L(const Lizard& monster_l)

 która sprawdza czy wygraliśmy czy też przegraliśmy albo zremisowaliśmy i w tej metodzie jest już obiekt klasy <code class="cpp">class Character 

i chciałbym jakoś przekazać ten obiekt dla metody void New_LVL_L(const Lizard& l)

0

Czy rozumiesz to co napisałeś? Niezła łamigłówka.

ale by to zrobić potrzebny mi obiekt klasy

class Character 

Przecież metody w przestrzeni nazw klasy Character:: wywoływane są na rzecz obiektu, którego właśnie potrzebujesz.
Dlaczego nie skorzystasz ze wskaźnika this?

0
void New_LVL_L(const Lizard& l); 

Tak nie wywołuje się funkcji i metod (jakoś nie zwróciłem wcześniej uwagi).
Jak już to

New_LVL_L(l); 

lub

this->New_LVL_L(l); 

Jeśli jednak będziesz potrzebował obiektu klasy Character w argumentach wspólnie z obiektem klasy Lizard, to tak

New_LVL_L(l, *this); 

Kodu nie analizowałem, bo się nie da.

0

Sprecyzuj co twój kod miałby robić (ten od początku wątku), czego od niego oczekujesz.

A no tego…
2016-11-05-230558_1280x1024_scrot.png+
Po wybraniu klasy jest losowanie potworków ale tutaj dla przykłädu dałem już wylosowanego potworka czyli Szczur i po wybraniu klasy jest losownanie lvl potworka i decyzja czy walczymy czy też nie, gdy tak to wtedy losuje się atrybuty i zliczanie ich do zmiennej Wynik_M i porównanie z wynikiem Bohatera czyli z Wynik1

P.S jak trochę nie równe to dlatego,że to na telefonie robiłem i tak trochę wyszło

1

Dobra, zabawmy się w proof-of-concept w locie, zobaczymy jak to wyjdzie ;)
Zasady są następujące: ja podaję fragment kodu, ty mówisz co dalej do niego potrzebujesz; kontynuujemy to do momentu, w którym rozwiązane zostają problemy, które do tej pory z Cie dręczyły;

Zacznę od poziomów i doświadczenia; Odniosłem wrażenie, że strasznie dużo jest z tym u Ciebie zamieszania, dlatego proponuję oparcie całości na następującej funkcji matematycznej:
f(x) = ceil(log3(x+1)) gdzie x >= 0, ponieważ nie rozpatrujemy ujemnego doświadczenia

W naszym kodzie wyglądać to będzie tak:

#include <cmath>
#include <cassert>

int calculate_level(int experience) {
    assert(experience >= 0);
	return !experience? 1 : (int) std::ceil(std::log(experience+1)/std::log(3));
}

zadanie dodatkowe dla Ciebie: sporządź wykres przedstawiający zależność poziomu od doświadczenia dla danego wzoru

Mając to do dyspozycji, możemy sklepcić interfejs pozwalający na posiadanie doświadczenia; Notka: wszelakie interfejsy będziemy tworzyli bez pól.

struct levelable_interface {
    virtual ~levelable_interface() = default; //przyp: jeżeli bawimy się z wirtualnymi metodami, to MUSI być zdefiniowany wirtualny destruktor
    virtual int experience() const = 0; //przyp: abstrakcyjna metoda; chcemy, bo została nadpisana przez klasę implementującą ten interfejs
    
    auto level() const //żeby życie było łatwiejsze
    { return calculate_level(experience()); }
};

Teraz czas na zdefiniowanie ogólnie postaci; Według tego co do tej pory zostało (przeze mnie) powiedziane, postać może posiadać doświadczenie; W tym celu zaimplementujemy wcześniej zdefiniowany interfejs

class character: public levelable_interface {
    int experience_;
public:
    character(int experience = 0): experience_(experience){}
    
    virtual int experience() const override 
    { return experience_; }
};

Podsumowanie:
Co możemy zrobić z postacią:

auto const c = character(); //postać bez doświadczenia
cout << c.experience() << c.level() << endl; //out: 01

Naskrobany kod do tej pory: http://melpon.org/wandbox/permlink/ypfij1LCsBXRBmWj

1

Trzymając się wcześniej ustalonej funkcji na poziom, zróbmy odwrotną operację (wyliczanie maksymalnego doświadczenia dla danego poziomu):

int calculate_level_experience(int level) {
    assert(level >= 1);
    return (int) std::exp(level*std::log(3))-1;
}

(proof of concept: http://melpon.org/wandbox/permlink/wm5HP9H9CRutBaDg)

Pdla każdego przeciwnika będziemy narzucali zakres poziomów <min_lvl, max_lvl> używając naszej formułki przekształcającej poziom na doświadczenie

template<typename RNG>
int random_experience_in_range(int min_lvl, int max_lvl, RNG &rng) {
    return calculate_level_experience(
        std::uniform_int_distribution<int>(min_lvl, max_lvl)(rng)
    );
}

(proof of concept: http://melpon.org/wandbox/permlink/Ha4qNodWUPvDhx43)

Zostało nam teraz utworzyć odpowiedni interfejs do generowania postaci:

struct spawner_interface {
    using character_ptr_type = std::unique_ptr<character>;
    using random_level_provider_type = std::function<int(int min, int max)>; //przyjmujemy z zewnątrz funkcję, która zwróci nam poziom z podanego zakresu
    
    virtual ~spawner_interface() = default;
    
    virtual character_ptr_type spawn(random_level_provider_type) const = 0; //ta metoda musi być przykryta(, nadpisana czy jak to się po polsku śmiesznie nazywa)
    
    character_ptr_type operator()(random_level_provider_type provider) const //zamiast `spawner.spawn(...)` możemy całość używać jako np `spawn(...)`
    { return spawn(provider); }
};

Oraz zaimplementować tenże interfejs:

class character_spawner: public spawner_interface {
    int min_lvl, max_lvl;
public:
    character_spawner(int min_lvl, int max_lvl): 
        min_lvl(min_lvl), 
        max_lvl(max_lvl)
    {}
    
    virtual character_ptr_type spawn(random_level_provider_type get_experience_in_range) const override {
        int experience = get_experience_in_range(min_lvl, max_lvl);
        return character_ptr_type { new character(experience) };
    }
};

Przykładowe działanie:

#include <iostream>
int main() {
    using namespace std;
    std::default_random_engine generator;
    auto spawn = character_spawner(1, 10);
    for(size_t i = 0; i < 50; ++i) {
        auto character = spawn(generate_random_level_provider(generator));
        cout << "character experience: " << character->experience() << endl;
        cout << "character level:      " << character->level() << endl;
    }
    return 0;
}

i fragment przykładowego wyjścia:

character experience: 8
character level:      2
character experience: 728
character level:      6
character experience: 2
character level:      1
character experience: 26
character level:      3
character experience: 2
character level:      1
character experience: 19682
character level:      9
character experience: 26
character level:      3
character experience: 26
character level:      3
character experience: 19682
character level:      9
character experience: 26
character level:      3
character experience: 19682
character level:      9
character experience: 8
character level:      2

kod: http://melpon.org/wandbox/permlink/CRiocXz8rYKrbhaZ

Konkretyzacją postaci (że coś jest szczurem a coś jaszczurką) zajmiemy się później. Na razie uzupełnijmy postać należytymi własnościami.

1

To lecimy dalej;
interfejs do walk:

struct fightable_interface {
    using attribute_type = int;
    using attributes_map_type = std::unordered_map<std::string, attribute_type>;
    
    virtual ~fightable_interface() = default;
    
    virtual attributes_map_type const &attributes() const = 0;
    
    std::optional<attribute_type> attribute(std::string const &name) const {
        if(attributes().count(name)) 
            return attributes().at(name);
        return {};
    }
    
    virtual attribute_type overall_power() const = 0;
    
    virtual bool beats(fightable_interface const &rhs) const 
    { return overall_power() > rhs.overall_power(); }
};

Dostosowana do niego klasa postaci:

class character: 
    public levelable_interface,
    public fightable_interface
{
    int experience_;
        
    attributes_map_type attributes_;
public:
    character(int experience = 0): experience_(experience){}
   
    auto health() const {
        return attribute("health").value_or(0);
    }
        
    virtual int experience() const override 
    { return experience_; }
        
    virtual attributes_map_type const &attributes() const override {
        return attributes_;
    }
        
    virtual attribute_type overall_power() const override {
        auto sum = std::accumulate(std::begin(attributes()), std::end(attributes()), 0, [](auto acc, auto &&pair) {
            return acc + pair.second;
        });
        auto h = health();
        return h *(sum - h);
    }
};

Przykładowe użycie:

int main() {
    using namespace std;
    std::default_random_engine generator;
    auto spawn = character_spawner(1, 10);
    for(size_t i = 0; i < 50; ++i) {
        auto character = spawn(generate_random_level_provider(generator));
        cout << "character experience:    " << character->experience() << endl;
        cout << "character level:         " << character->level() << endl;
        cout << "character health:        " << character->health() << endl;
        cout << "character overall power: " << character->overall_power() << endl;
        cout << endl;
    }
    return 0;
}

Wyników łatwo można się domyślić (health = 0, overall_power = 0):

character experience:    8
character level:         2
character health:        0
character overall power: 0

character experience:    728
character level:         6
character health:        0
character overall power: 0

character experience:    2
character level:         1
character health:        0
character overall power: 0

character experience:    26
character level:         3
character health:        0
character overall power: 0

Mając to należy określić garść podstawowych atrybutów dla postaci (jakaś siła, zręczność czy inne duperele) oraz związanych z nich współczynników*
(formuła: podstawa + współczynnik * poziom)
http://melpon.org/wandbox/permlink/CRiocXz8rYKrbhaZ

* - poczekaj chwilę, za ten czas ogarnij ten fragment

1

Skoro atrybut związany z walką jest uzależniony od poziomu to mamy kilka wyjść:

  1. użerać się z zależnościami metod wirtualnych (levelable::level(), fightable::level(), character -> fightable::level() = levelable::level())
  2. wstrzyknąć to jako zależność (złamiemy w ten sposób nasze założenie o braku pól w interfejsach)
  3. dziedziczyć interfejs

Skłaniałbym się ku rozwiązaniu drugiemu, ale w międzyczasie machnąłem już trójeczkę; jeżeli sprawi to później jakieś problemy, to przerobimy to na dwójeczkę;

Nasz interfejs do walk wygląda teraz tak:

struct fightable_interface: public levelable_interface {
    struct attribute_type {
        int base_value = 0;
        int coefficient = 0;
        int operator()(int level) const {
            return base_value + coefficient * level;
        }
    };
    
    using attributes_map_type = std::unordered_map<std::string, attribute_type>;
    
    virtual ~fightable_interface() = default;
    
    virtual attributes_map_type const &attributes() const = 0;
    
    int attribute_value(attribute_type const &attr) const {
        return attr(level());
    }
    
    std::optional<attribute_type> attribute(std::string const &name) const {
        if(attributes().count(name)) 
            return attributes().at(name);
        return {};
    }
    
    virtual int overall_power() const = 0;
    
    virtual bool beats(fightable_interface const &rhs) const 
    { return overall_power() > rhs.overall_power(); }
};

a klasa postaci tak:

class character: public fightable_interface
{
    int experience_;
        
    attributes_map_type attributes_;
public:
    character(int experience = 0): experience_(experience) {
        attributes_["health"]   = attribute_type { 60, 4 };
        attributes_["strength"] = attribute_type { 5, 2 }; 
    }
   
    auto health() const {
        return attribute_value(attribute("health").value_or(attribute_type{}));
    }
        
    virtual int experience() const override 
    { return experience_; }
        
    virtual attributes_map_type const &attributes() const override {
        return attributes_;
    }
        
    virtual int overall_power() const override {
        auto sum = std::accumulate(std::begin(attributes()), std::end(attributes()), 0, [this](auto acc, auto &&pair) {
            return acc + attribute_value(pair.second);
        });
        auto h = health();
        return h *(sum - h);
    }
};

Przykładowe wyniki wcześniej wymienionego przykładowego programu:

character experience:    8
character level:         2
character health:        68
character overall power: 612

character experience:    728
character level:         6
character health:        84
character overall power: 1428

character experience:    2
character level:         1
character health:        64
character overall power: 448

character experience:    26
character level:         3
character health:        72
character overall power: 792

character experience:    2
character level:         1
character health:        64
character overall power: 448

character experience:    19682
character level:         9
character health:        96
character overall power: 2208

character experience:    26
character level:         3
character health:        72
character overall power: 792

character experience:    26
character level:         3
character health:        72
character overall power: 792

Czyli jest postęp, postacie mają konkretną ilość zdrowia uzależnioną od poziomu oraz odpowiednią ilość mocy.

Pytania kontrolne (na które musisz odpowiedzieć, żeby dalsze dłubanie miało sens ;P):

  1. Dlaczego postacie na tych samych poziomach mają tą samą ilość zdrowia?
  2. Dlaczego postacie na tych samych poziomach mają tą samą ilość ogólnej mocy?
  3. Co możemy zrobić, żeby postacie na tych samych poziomach miały różne wartości atrybutów? (wskazówka: pamiętasz rozróżnienie postaci na magów, wojów, szczury i tak dalej?)

Kod na ten moment: http://melpon.org/wandbox/permlink/HQYmPtrQUI3PHT6r
Edit: powoli zaczyna kodu przybywać, dlatego pociąłem całość na kilka plików (ty u siebie powinieneś rozbić .hpp na .hpp i .cpp, ale ja na wandboxie nie zamierzam): http://melpon.org/wandbox/permlink/OhxWFPL9Zr5cCCLP

0

Odpowiedzi na pytania będe w wątkach udzielał aby administracja/moderatorzy się nie czepiali…

1.Bo wzoruje się na dość starym wzorze z gothic'a(swoją drogą dobrej grze :) ) a mianowicie że każda postać ma tyle samo życia i co LVL jej życie wzrasta :)
2.Pytanie na zasadzie czemu mag może równać się wojownikowi choć mag ma 30 hp a obrażenia po 300dmg/s a wojownik ma 300 hp a obrażenia po 30dmg/s…Dlatego chciałem wprowadzić później styl walki na różne specjalne umiejętności coś jak w final fantasy a co do odpowiedzi to - żeby były równe szanse a nie jakaś faworyzacja…
3.Szczury to MOBy a postacie to postacie…tylko wartości początkowe mają takie same…ale można na początek odjąć od jakiegoś atrybutu i dodać do jakiegoś innego i jak mówiłem dla maga np. 10% do inteligencji bonus !

1

W kolejnych krokach będziemy chcieli stworzyć odpowiednią fabrykę schematów, czyli coś, co będzie nam zwracało przeliczniki i podstawowe wartości atrybutów postaci (w tym także ich zakres poziomów).

Żeby się do tego przygotować, musimy zrezygnować z ręcznego przypisywania atrybutów na rzecz wstrzyknięcia ich przez konstruktor:

class character: public fightable_interface {
    attributes_map_type attributes_;
    int experience_;
public:
    character(attributes_map_type const &attrs, int experience = 0): 
        attributes_(attrs),
        experience_(experience) 
    {}
   
    auto health() const {
        return attribute_value(attribute("health").value_or(attribute_type{}));
    }
        
    virtual int experience() const override 
    { return experience_; }
        
    virtual attributes_map_type const &attributes() const override {
        return attributes_;
    }
        
    virtual int overall_power() const override {
        auto sum = std::accumulate(std::begin(attributes()), std::end(attributes()), 0, [this](auto acc, auto &&pair) {
            return acc + attribute_value(pair.second);
        });
        auto h = health();
        return h *(sum - h);
    }
};

Ponieważ robimy mały kroczek, te same atrybuty przeniesiemy zwyczajnie do spawnera:

class character_spawner: public spawner_interface {
    int min_lvl, max_lvl;
public:
    character_spawner(int min_lvl, int max_lvl): 
        min_lvl(min_lvl), 
        max_lvl(max_lvl)
    {}
    
    virtual character_ptr_type spawn(random_level_provider_type get_experience_in_range) const override {
        int experience = get_experience_in_range(min_lvl, max_lvl);
        character::attributes_map_type attrs = {
            { "health", character::attribute_type{60, 4} },
            { "strength", character::attribute_type{5, 2} }
        };
        return character_ptr_type { new character(attrs, experience) };
    }
};

Teraz mamy gotowe pole do popisu - wystarczy, że spawner będzie trzymał jakiś kontakt z instancją fabryki, żeby mógł tworzyć postacie na podstawie jakiś danych;
Przyszłe użycie spawnera do którego będziemy dążyli:

auto spawn = character_spawner(characters_factory);
auto spawned_rat = spawn("rat");
auto spawned_lizard = spawn("lizard");
1

Czas na małe przemodelowanie: ze względu na... naturę generatorów liczb losowych, musimy przekazać szablonowy parametr gdzieś w głąb spawnera. Nie da rady zrobić tego z wirtualnymi funkcjami, więc w cholerę wyrzucamy interfejs spawnera i zostaje nam coś takiego:

//character_spawning.hpp
#pragma once
#include <memory>
#include <functional>
#include "character.hpp"

struct characters_factory {
    struct character_desc {
        character::attributes_map_type attrs = {};
        int min_lvl = 1, max_lvl = 1;
    };
    using character_class_name = std::string;
    using character_descs_map = std::unordered_map<character_class_name, character_desc>;
    
    character_descs_map characters_descs;
};

class characters_spawner {
    characters_factory const &factory;
public:
    using character_class_name = characters_factory::character_class_name const &;
    using character_ptr_type = std::unique_ptr<character>;
    using optional_character_ptr_type = std::optional<character_ptr_type>;
    
    characters_spawner(characters_factory const &factory): factory(factory){}
    
    template<typename RNG>
    optional_character_ptr_type spawn(character_class_name name, RNG &rng) const {
        if(!factory.characters_descs.count(name)) {
            return {};
        }
        auto &desc = factory.characters_descs.at(name);
        int experience = random_experience_in_range(desc.min_lvl, desc.max_lvl, rng);
        
        return character_ptr_type { new character(desc.attrs, experience) };
    }
    
    template<typename RNG>
    auto operator()(character_class_name name, RNG &rng) const {
        return spawn(name, rng);
    }
};

Nasz main:

#include "character.hpp"
#include "character_spawning.hpp"

#include <iostream>

auto characters_descs() {
    return characters_factory {{
        { "rat", characters_factory::character_desc {
            character::attributes_map_type {
                { "health", character::attribute_type{20, 3} },
                { "strength", character::attribute_type{3, 1} }
            },
            /*min*/1, /*max*/10
        }},
        
        { "lizard", characters_factory::character_desc {
            character::attributes_map_type {
                { "health", character::attribute_type{30, 3} },
                { "strength", character::attribute_type{5, 1} }
            },
            /*min*/3, /*max*/15
        }}
    }};
}

int main() {
    using namespace std;
    std::default_random_engine generator;
    
    auto factory = characters_descs();
    auto spawn = characters_spawner(factory);
    
    string characters[] = {
        "rat", "lizard"
    };
    for(size_t i = 0; i < 20; ++i) {
        for(auto ch_name: characters) {
            auto character = *spawn(ch_name, generator);
            cout << "character\'s class name:  " << ch_name << endl;
            cout << "character experience:    " << character->experience() << endl;
            cout << "character level:         " << character->level() << endl;
            cout << "character health:        " << character->health() << endl;
            cout << "character overall power: " << character->overall_power() << endl;
            cout << endl;
        }
    }
    return 0;
}

Przykładowe wyniki:

character's class name:  rat
character experience:    8
character level:         2
character health:        26
character overall power: 130

character's class name:  lizard
character experience:    6560
character level:         8
character health:        54
character overall power: 702

character's class name:  rat
character experience:    2
character level:         1
character health:        23
character overall power: 92

character's class name:  lizard
character experience:    242
character level:         5
character health:        45
character overall power: 450

character's class name:  rat
character experience:    2
character level:         1
character health:        23
character overall power: 92

character's class name:  lizard
character experience:    177146
character level:         11
character health:        63
character overall power: 1008

character's class name:  rat
character experience:    26
character level:         3
character health:        29
character overall power: 174

character's class name:  lizard
character experience:    242
character level:         5
character health:        45
character overall power: 450

character's class name:  rat
character experience:    19682
character level:         9
character health:        47
character overall power: 564

character's class name:  lizard
character experience:    242
character level:         5
character health:        45
character overall power: 450

character's class name:  rat
character experience:    19682
character level:         9
character health:        47
character overall power: 564

character's class name:  lizard
character experience:    80
character level:         4
character health:        42
character overall power: 378

character's class name:  rat
character experience:    80
character level:         4
character health:        32
character overall power: 224

character's class name:  lizard
character experience:    26
character level:         3
character health:        39
character overall power: 312

character's class name:  rat
character experience:    80
character level:         4
character health:        32
character overall power: 224

character's class name:  lizard
character experience:    19682
character level:         9
character health:        57
character overall power: 798

character's class name:  rat
character experience:    19682
character level:         9
character health:        47
character overall power: 564

character's class name:  lizard
character experience:    728
character level:         6
character health:        48
character overall power: 528

character's class name:  rat
character experience:    59048
character level:         10
character health:        50
character overall power: 650

character's class name:  lizard
character experience:    728
character level:         6
character health:        48
character overall power: 528

character's class name:  rat
character experience:    26
character level:         3
character health:        29
character overall power: 174

character's class name:  lizard
character experience:    1594322
character level:         13
character health:        69
character overall power: 1242

character's class name:  rat
character experience:    242
character level:         5
character health:        35
character overall power: 280

character's class name:  lizard
character experience:    728
character level:         6
character health:        48
character overall power: 528

character's class name:  rat
character experience:    6560
character level:         8
character health:        44
character overall power: 484

character's class name:  lizard
character experience:    19682
character level:         9
character health:        57
character overall power: 798

character's class name:  rat
character experience:    80
character level:         4
character health:        32
character overall power: 224

character's class name:  lizard
character experience:    14348906
character level:         15
character health:        75
character overall power: 1500

character's class name:  rat
character experience:    26
character level:         3
character health:        29
character overall power: 174

character's class name:  lizard
character experience:    26
character level:         3
character health:        39
character overall power: 312

character's class name:  rat
character experience:    728
character level:         6
character health:        38
character overall power: 342

character's class name:  lizard
character experience:    6560
character level:         8
character health:        54
character overall power: 702

character's class name:  rat
character experience:    2
character level:         1
character health:        23
character overall power: 92

character's class name:  lizard
character experience:    19682
character level:         9
character health:        57
character overall power: 798

character's class name:  rat
character experience:    26
character level:         3
character health:        29
character overall power: 174

character's class name:  lizard
character experience:    14348906
character level:         15
character health:        75
character overall power: 1500

character's class name:  rat
character experience:    19682
character level:         9
character health:        47
character overall power: 564

character's class name:  lizard
character experience:    4782968
character level:         14
character health:        72
character overall power: 1368

character's class name:  rat
character experience:    242
character level:         5
character health:        35
character overall power: 280

character's class name:  lizard
character experience:    242
character level:         5
character health:        45
character overall power: 450

kod: http://melpon.org/wandbox/permlink/JbRu5X5DucaiU29k

0

Nie wiem czy dobrze to rodzieliłem…
levelable_interface.h

#pragma once
int level() const;
 

levelable_interface.cpp

#include "experience.h"
#include "levelable_interface.h"

struct levelable_interface {
    virtual ~levelable_interface() = default;
    virtual int experience() const = 0;
    
    auto level() const 
    { return calculate_level(experience()); }
}; 

1 użytkowników online, w tym zalogowanych: 0, gości: 1