0

I'm trying to implement a turn based game for the course project. The game has a 'status' base class and from which derived the actual statuses such as 'poisoned', 'paralyzed' or 'choke'(which is the test case that goes wrong).

A status need to be setup first before it is inflicted to a character object by a move object, and the SetupStatus() function varies between different derived classes of the status class.

The problem is, when I am trying to call the SetupStatus() function of the 'choke' class (choke::SetupStatus()), which is derived from the base class 'status', it always call the function status::SetupStatus(). The function is called in the cmove::LaunchMove(...).

Where did I do wrong?

I missed the virtual declaration in the first place. I added it, but it didn't solve the problem.

main.cpp

int main() {
    cmove aqua_ball = AquaBall();
    field TestField;
    character Irrawa = IRRAWA();
    character Mew = MEW();
    aqua_ball.LaunchMove(&Irrawa, &Mew, &TestField);
}

cmove.cpp

void cmove::LaunchMove(character *speller, character *taker, field *thisField) {
    //some other codes...
    if (slf_adStat.size() != 0) {
        for (int i = 0; i < slf_adStat.size(); i++) {
            status tempStatus = slf_adStat[i];
            cout << tempStatus.get_information() << endl; //Output tempStatus info
            tempStatus.SetupStatus(speller, taker, thisField);//Where the function call goes wrong
            cout << tempStatus.get_information() << endl; //Output tempStatus info

            (*speller).add_status(tempStatus);
        }
    }
    //some other codes...
};

status.h

class status{
public:
    string sta_name, sta_info;
    //some other codes...

    virtual void SetupStatus(character* selfCharacter, character* oppoCharacter, field* currentField);
    string get_information();

    //some other codes...
};

class choke : public status{
public:
    choke(){
        sta_name = "CHOKE";
        sta_info = "Reduce speed by 15. Last 3 turns.";
        //some codes...
    }
    virtual void SetupStatus(character* selfCharacter, character* oppoCharacter, field* currentField);
    //some codes...
};

status.cpp

void status::SetupStatus(character* selfCharacter, character* oppoCharacter, field* currentField){
    cout << "General status setup..."<< endl;
}
string status::get_information(){
string output = "[" + sta_name + "]" + ":\n" + sta_info + "\nLEFT:" + to_string(nT) + "turns\n";
return output;
}
void choke::SetupStatus(character* selfCharacter, character* oppoCharacter, field* currentField){
    sta_ds = -15;
    cout << sta_ds << "Choke status setup..." << endl;
}

Output:

[CHOKE]:
Reduce speed by 15. Last 3 turns.
LEFT:3turns

General status setup...
[CHOKE]:
Reduce speed by 15. Last 3 turns.
LEFT:3turns

Since the tempStatus objects before and after the SetupStatus() function are all printed as expected, the tempStatus is a choke class object, this is not a problem related to object slicing.

All the code can be find here if necessary: https://github.com/Irrawa/godsFighting

Irrawa
  • 23
  • 5
  • 1
    `status tempStatus = slf_adStat[i];` Here you have an object of type `status`, no matter if `slf_adStat[i]` was `status` or `choke`. The information is lost due to object slicing. – Yksisarvinen May 21 '19 at 09:19
  • What is `slf_adStat`? – vahancho May 21 '19 at 09:22
  • @vahancho slf_adstat is a vector that contains the statuses the cmove will inflict. – Irrawa May 21 '19 at 09:26
  • 2
    You don't have a `choke` object then, you sliced any copying them into `slf_adstat` – Caleth May 21 '19 at 09:27
  • @Irrawa, in order to make it work as you expect, you need to use pointers instead, i.e. `slf_adstat` roughly should be `std::vector` and it should contain pointers to `choke` or `poinsoned` objects, for example. – vahancho May 21 '19 at 09:30
  • @vahancho I tried to tesity if the information of the tempStatus object was lost due to possible slicing. But it seems it didn't. The information of tempStatus was printed fully. – Irrawa May 21 '19 at 13:03

0 Answers0