Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I am attempting to implement the simple subtype functions in this program, but I

ID: 3859482 • Letter: I

Question

I am attempting to implement the simple subtype functions in this program, but I can't seem to get them to work. I am not entirely sure what I am doing wrong.

My assignment states to :Add sub type functions to the Sub types of the Actor base type.

These functions are as follows:
Roar() - for the Monster subtype

Rally() - for the Hero subtype

Hide() - for the villager subtype

All I need them to do is print out:
"Hero: rallies those around him."

"Monster: roars fiercely"

"Villager: *hides*"

by using the lines that are similar to std::cout << "Monster: " << message << std::endl;

Can someone help me get these working? Thanks in advance.

#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<map>
#include<vector>

void tokenize(const std::string& str,
std::vector<std::string>& tokens,
const std::string& delimiters = " ") {
// Skip delimiters at beginning.
std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
std::string::size_type pos = str.find_first_of(delimiters, lastPos);

while (std::string::npos != pos || std::string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
class Actor;
class InvItem;

typedef std::map<std::string,Actor*> ActorMap;
typedef std::vector<InvItem> InvBag;
typedef std::vector<std::string> TokenVector;

std::ostream& operator<<(std::ostream& o,TokenVector v) {
   for(int i=0; i<v.size(); i++)
   o << v[i] << " ";
   return o;
}

typedef struct {
int health,manna,stamina,intel;

} VitalStruct;

typedef struct {
std::string name, type;
} EntityInfo;

std::ostream& operator<<(std::ostream& o,VitalStruct v) {
o << "health:" << v.health << std::endl;
o << "manna:" << v.manna << std::endl;
o << "stamina:" << v.stamina << std::endl;
o << "intel:" << v.intel << std::endl;
   return o;
}

class Actor {
protected:
VitalStruct vitals;
InvBag inventory;
EntityInfo info;
  
public:
VitalStruct get_vitals();
InvBag get_inventory();
  
EntityInfo set_type(const EntityInfo& attribute);
EntityInfo get_type();
EntityInfo set_name(const EntityInfo& attribute);
EntityInfo get_name();
  
void set_inventory(const InvBag&);
virtual void speak(const std::string &message)=0;

//created a function that all subtypes can use
virtual void hit(const std::string &message)=0;
};

class InvItem {

};

InvBag& operator<<(InvBag& bag,InvItem iv) {
bag.push_back(iv);
return bag;
}

EntityInfo Actor::set_type(const EntityInfo& attribute) {
info.type = attribute.type;
return info;
}


EntityInfo Actor::set_name(const EntityInfo& attribute) {
info.name = attribute.name;
return info;
}
EntityInfo Actor::get_name() {
return info;
}

EntityInfo Actor::get_type() {
return info;
}

VitalStruct Actor::get_vitals() {
return vitals;
}

void Actor::set_inventory(const InvBag& ivbag) {
inventory = ivbag;
}

InvBag Actor::get_inventory() {
return inventory;
}

class Monster : public Actor {
public:
void speak(const std::string& message);
void hit(const std::string& message);
void roar(const std::string& message);
};

void Monster::roar(const std::string& message) {
std::cout << "Monster: " << message << std::endl;
}

void Monster::speak(const std::string& message) {
std::cout << "Monster: " << message << std::endl;
}

void Monster::hit(const std::string& message) {
std::cout << "Monster: " << message << std::endl;
}

class Hero : public Actor {
void speak(const std::string& message);
void hit(const std::string& message);
void rally(const std::string& message);
};

void Hero::rally(const std::string& message) {
std::cout << "Hero: " << message << std::endl;
}

void Hero::speak(const std::string& message) {
std::cout << "Hero: " << message << std::endl;
}

void Hero::hit(const std::string& message) {
std::cout << "Hero: " << message << std::endl;
}

class Villager : public Actor {
void speak(const std::string& message);
void hit(const std::string& message);
void hide(const std::string& message);

};

void Villager::hit(const std::string& message) {
std::cout << "Villager: " << message << std::endl;
}

void Villager::speak(const std::string& message) {
std::cout << "Villager: " << message << std::endl;
}

void Villager::hide(const std::string& message) {
std::cout << "Villager: " << message << std::endl;
}

int main() {
ActorMap actormap;
InvBag bag;
EntityInfo type;
EntityInfo name;

  
std::ifstream in_file("./characters.txt");
if(in_file.fail()) {
std::cout << "Cannot open file";
exit(1);
}
  
std::string buf="";
while(!in_file.eof()) {
std::getline(in_file,buf);
if(buf.at(0) == '-') {
break;
}
  
TokenVector tokens;
tokenize(buf,tokens,":");
  
std::string name = tokens[0];
std::string type = tokens[1];
  
if(type == "Hero") {
actormap[name] = new Hero();
//set name
//set type
}
else if(type == "Monster") {
actormap[name] = new Monster();

}
else if(type == "Villager") {
actormap[name] = new Villager();
}
actormap[name]->speak("I speak");
actormap[name]->hit("*swings to hit*");
actormap[name]->get_name();
}

actormap["trundle"] = new Monster();   
  
//testing of my type / naming storage
   // It worked!
  
std::cout << std::endl;
std::cout << "Testing Type / Name Storage: " << std::endl;
EntityInfo e;
e.name = "Trundle";
e.type="Monster";
   actormap["trundle"]->set_type(e);   
actormap["trundle"]->set_name(e);
   EntityInfo s = actormap["trundle"]->get_type();
   std::cout << s.name << " " << s.type << std::endl;
   std::cout << "End of Test ";
   std::cout << std::endl;
  
actormap["tim"] = new Hero();
actormap["penelope"] = new Villager();
  
bag << InvItem();
actormap["trundle"]->set_inventory(bag);

std::cout << actormap["trundle"]->get_vitals();

actormap["trundle"]->speak("I am trundle, prepare to meet your maker!");
actormap["penelope"]->speak("Where's my hero?");
actormap["tim"]->speak("Let's roll!");

  
return 0;
}

Explanation / Answer

make following changes in your respectice classes and methods, IF YOU WANT THESE MESSGES TO BE DEFAULT

TO THE STRINGS GIVEN. i.e whenever you call monster->roar() it should print roars fiercely and so on.

add an instance variable message in monster class and initialize it as follows

string message="roars fiercely "

void Monster::roar() {

std::cout << " "Monster: " << this->message <<" " "<<std::endl;


}

add an instance variable message in hero class and initialize it as follows

string message= "rallies those around him."

void Hero::rally() {

std::cout << " "Hero: " << this->message <<" " "<<std::endl;


}

add an instance variable message in villager class and initialize it as follows

message="*hides"

void Villager::hide() {

std::cout << " "Villager: " << this->message <<" " "<<std::endl;


}

IF YOU DONT WANT THEM TO BE DEAFULT

THEN JUST LET THE METHODS AS THEY ARE AND IN MAIN METHOD DO THE FOLLOWING.

actormap["trundle"]->roar("roars fiercely") and so on.