0

i'm pretty much a beginner / self teaching c++ programmer. i wanted to test my own skills a little bit. i made this program and id be very happy if you guy / girls could tell me how i can improve it. this is my first class (please tell me if you'd like to clean it up a bit)

 class race {public: 
enum raceOpt { orc, elf, human };

race(raceOpt c_raceOpt, int *STR, int *DEX, int *CON, int *INT, int* WIS, int* CHR);
//race opt outcomes 
void ORC(int** STR, int** INT, int** CHR) {
    **STR = **STR + 2;
    **INT = **INT - 2;
    **CHR = **CHR - 2;
}

void ELF(int** DEX) {
    //elf code and stat changes
}
//I still have to add human

};


// here's my constructor

  race::race(raceOpt c_raceOpt, int* STR, int* DEX, int* CON, int* INT, int* WIS, int* CHR) {
switch (c_raceOpt) {
case orc:
    ORC(&STR, &INT, &CHR);
    break;
case human:
    //human code
    break;
case elf:
    //elf code
    break;
}
}

this is my next base class

class classes {
public:

enum classOpt { fighter, mage, soccerPlayer };

classes(classOpt c_classOpt, double ModStats[_MAX_PATH], int* Sneak, int* Bluff, int* Deplomacy, int* Swim, int* Mana, int* Run);

void Fighter(int** SWIM, int** RUN, int** BLUFF, double ModStats[_MAX_PATH]) {
    **SWIM = static_cast<int>(**SWIM + std::round(((ModStats[2] * 2.3))));
    **RUN = static_cast<int>(**RUN + (std::round(((ModStats[2] * 2)))));
    **BLUFF = static_cast<int>(**BLUFF + std::round(((ModStats[1] * 2.5))));

}
void Mage(int** MANA, int** DEPLOMACY, int** BLUFF, double ModStats[_MAX_PATH]) {
    //code to be added

}
void SoccerPlayer(int** RUN, int** SWIM, int** DEPLOMACY, int** SNEAK, double ModStats[_MAX_PATH]) {
    //code to be added

}
};

// here's my constructor

classes::classes(classOpt c_classOpt, double ModStats[_MAX_PATH], int* Sneak, int* Bluff, int* Deplomacy, int* Swim, int* Mana, int* Run) {
switch (c_classOpt) {
case fighter:
    Fighter(&Swim, &Run, &Bluff, ModStats);
    break;
case mage:
    Mage(&Mana, &Deplomacy, &Bluff, ModStats);
    break;
case soccerPlayer:
    SoccerPlayer(&Run, &Swim, &Deplomacy, &Sneak, ModStats);
    break;
}
}

and here is my final hero class constructor and main.

class hero {
protected:
int sneak = 0, bluff = 0, deplomacy = 0, swim = 0, mana = 0, run = 0;

int //stats
    Str = 16,
    Dex = 18,
    Con = 11,
    Int = 10,
    Wis = 8,
    Chr = 13;


double modStats[6] = {};
//vvvv gets proper stat mods based on D&D
void getAndSetMods(){
    double modStats[6] = {
        this->modStats[1] = std::round(Str / 2) - 5,
        this->modStats[2] = std::round(Dex / 2) - 5,
        this->modStats[3] = std::round(Con / 2) - 5,
        this->modStats[4] = std::round(Int / 2) - 5,
        this->modStats[5] = std::round(Wis / 2) - 5,
        this->modStats[6] = std::round(Chr / 2) - 5,
    };//stats above in order
}


public:
void raceAndClass() {
    race c_race(race::orc, &Str, &Dex, &Con, &Int, &Wis, &Chr);
    getAndSetMods();
    classes c_classes(classes::fighter, modStats, &sneak, &bluff, &deplomacy, &swim, &mana, &run);
        using 

namespace std;
        cout << Str << endl << Dex << endl << Con << endl << Int << endl << Wis << endl << Chr << endl;
        cout << endl << endl << endl;
        cout << sneak << endl << bluff << endl << deplomacy << endl << swim << endl << mana << endl << run << endl;
    }
};

     int main()
        {
                hero H;
                H.raceAndClass();
                while (true);
        }
Pie Pie
  • 13
  • 4
  • You seem to be better off if you have a book and work on the examples: https://www.amazon.com/Programming-Principles-Practice-Using-C/dp/0321543726 – macroland Nov 04 '17 at 04:10
  • `this->modStats[6] = std::round(Chr / 2) - 5,` -- Memory overwrite. Arrays start at 0, not 1. Just that one mistake shows that you really need to get a book, and not learn by winging it. – PaulMcKenzie Nov 04 '17 at 04:41
  • thanks! i did a lot of research on keywords and headers but i'm just learning now i don't have much practice with the actual logic of coding. also two more notes, i did know arrays start at 0 for some reason ig i was working on this while listening to my teachers lecture. as well as i was writing this on a bad compilers c++ shell (i hate chrome books) i didn't have time to do it at home on my desktop so there are a few things that make me look really noob-ish as a programmer, that i wouldn't normally. – Pie Pie Nov 04 '17 at 05:06
  • You seem to be learning from examples that are not teaching you about the container library and references. The first is unfortunately typical, but the second is outright harmful. Consider replacing all of your pointers with references. – user4581301 Nov 04 '17 at 05:56
  • IMHO, learning C++ without a book (and "while listening to my teachers lecture") seems not to be a good concept. Book recommendations: [SO: The Definitive C++ Book Guide and List](https://stackoverflow.com/a/388282/7478597). If you really want to learn C++, please, do it seriously (at home) and patiently. – Scheff's Cat Nov 04 '17 at 07:14
  • Again thanks! one question on pointers and references though, when should i use which, how do ik when i should be using references or when i should be using pointers? Scheff ik what you are saying i was impatient and i had started to write this at school. i am very serious at learning. – Pie Pie Nov 04 '17 at 12:52

1 Answers1

3

First pointer, you have too many pointers.

Everywhere you take the address of a variable because you need to change it in the called method you should use a reference in the called method instead.

SomeCall(&someVar);

void SomeCall(int* theVar);

should be

SomeCall(someVar);

void SomeCall(int& theVar);

make a helper class Stats

class Stats {
protected: // or private and write a bunch of access methods
int //default stats
    Str = 16,
    Dex = 18,
    Con = 11,
    Int = 10,
    Wis = 8,
    Chr = 13;

    Stats(int STR, int DEX, int CON, int INT, int WIS, int CHR) :
      Str(STR), Dex(DEX), Con(CON), Int(INT), Wis(WIS), Chr(CHR) {
    }
}

Then your race class could be simplified like this

class race {
public: 
    enum raceOpt { orc, elf, human };

race(raceOpt c_raceOpt, Stats& stats) {
  switch (c_raceOpt) {
    case orc:
       ORC(stats);

//race opt outcomes 
void ORC(Stats& stats) {
    stats.Str += 2;
    stats.Int -= 2; 
    stats.Chr -= 2;
}

And the re-factoring could continue with

  • Use an std::array to hold the stats in the Stats class.
  • move the modStat to the Stats class as they are the same concern. potentially
  • make an enum for the stats to use a lookup (not enum class as that would be a pain here).
  • make a class for each major concept.
Surt
  • 15,501
  • 3
  • 23
  • 39
  • Thanks! but now i have a really embarrassing question, and it does not help my cause about the book (i don't want to book b/c, i will be majoring in c++ soon, i plan to learn most there), what is a helper class and how come this function looks so weird. this probably has to do with being a helper class – Pie Pie Nov 04 '17 at 12:43
  • `Stats(int STR, int DEX, int CON, int INT, int WIS, int CHR) : Str(STR), Dex(DEX), Con(CON), Int(INT), Wis(WIS), Chr(CHR) { } ` – Pie Pie Nov 04 '17 at 12:55
  • Its the constructor for `Stats` using an initialization list with an empty body. – Surt Nov 04 '17 at 14:03
  • alright, alright, alright, i see what your saying. ima gonna use this knowledge and rewrite my code. im also gonna see if i can expand on what i learned form you guys. if theirs any other flaws you think i should fix plz tell me. ima eager beaver – Pie Pie Nov 04 '17 at 14:19
  • please forgive my ignorance. i've waited till a good time to program as i was told not to do it unless i have real time to do so. idk what you want me to do with stats and how to pass it as you saw up above i was bad with pointers and references could you plz help me one more time – Pie Pie Nov 05 '17 at 23:33
  • You use classes to encapsulate same type information, so that you know where they are and don't accidentally change them. Some become building blocks for your program others are used only once. Classes also help you with DRY (don't repeat yourself). – Surt Nov 06 '17 at 06:36
  • so wait then, if stats is gonna only be used for my hero class should stats inherit hero??? – Pie Pie Nov 06 '17 at 14:06
  • Hero should inherit stats I would say or have a member variable called stats. – Surt Nov 06 '17 at 17:22
  • im having a problem. i went back to my code cuz i got some time. it says hero is calling a deleted function? – Pie Pie Nov 10 '17 at 20:25
  • ` class hero : public Stats { //protected: public: //Stats HeroStats(10, 10, 10, 10, 10, 10); void raceAndClass() { Stats S(10,10,10,10,10,10); race c_race(race::orc, S); //classes c_classes(classes::fighter, modStats, sneak, bluff, deplomacy, swim, mana, run); using namespace std; } }; int main() { hero H; H.raceAndClass(); while (true); } ` it wont turn into code format srry – Pie Pie Nov 10 '17 at 20:26
  • You should make a new question on "Code Review" (https://codereview.stackexchange.com/) with the updated code. – Surt Nov 11 '17 at 08:38