Using an abstract class type as a parameter...? and some more...
Nov 1, 2015 at 12:41am UTC
I'm screwing around with this little game program. I have a Player class and an abstract Enemy class. I need to be able to access the Enemies atk and hp whether the enemy is a Beast or some other derived class. Quite frankly I have no idea how to do this (see the code below).
On a side note...I am quite new to building full comprehensive programs...Does anyone have any recommendations to changing the layout of my header/cpp files? Or perhaps the use of a namespace? etc...
Furthermore, how can I give default values to Enemy::a and Enemy::h in deriving classes?
ex) I always want to have 'a' set to 1 and 'h' set to 5 for every Beast.
entities.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#include "std_lib_facilities.h"
#include "numbers_manager.h"
class Character
{
public :
void set_hp(int x) { h = x; };
int hp() { return h; }
void set_atk(int x) { a = x; };
int atk() { return a; }
void attack(Character c) { c.set_hp(c.hp() - calculate_dmg()); }
Character& operator =(const Character&) = delete ;
virtual ~Character() {};
protected :
Character(int h, int a)
:h{ h }, a{ a } {};
private :
int calculate_dmg();
int h;
int a;
};
class Player : public Character
{
public :
Player(string n) : Character(20, 5) { nm = n; };
void encounter_enemy(Enemy e); // <--------------- Problematic
string name() { return nm; };
private :
string nm;
};
class Enemy : public Character
{
public :
virtual void appear() = 0;
virtual void defeated() = 0;
Enemy(const Enemy&) = delete ;
virtual ~Enemy() {};
protected :
using Character::Character;
private :
};
class Beast : public Enemy
{
public :
Beast() : Enemy(5, 1) {};
void appear() override { cout << "A beast has appeared!\n" ; }
void defeated() override { cout << "The beast has been defeated!\n" ; }
};
Player create_player();
int calculate_dmg();
entities.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
#include "entities.h"
Player create_player()
{
cout << "Enter your name: " ;
string name;
cin >> name;
Player p{ name };
return p;
}
void Player::encounter_enemy(Enemy e) // <----------- Problematic
{
while (true ) {
//TODO
}
}
bool is_crit()
{
int c = randint(1, 100);
//5% crit chance
return c <= 5;
}
int Character::calculate_dmg()
{
int low_hit = atk() - (round(atk()*dmg_mod));
int high_hit = atk() + (round(atk()*dmg_mod));
double damage{ 0 };
damage = randint(low_hit, high_hit);
if (is_crit()) damage *= crit_mod;
return int (damage);
}
Last edited on Nov 1, 2015 at 3:45am UTC
Nov 1, 2015 at 4:09am UTC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#include <iostream>
#include <string>
// using namespace std ;
class Enemy ; // *** declare Enemy
class Player
{
public :
Player( std::string n )
:nm{ n }, h{ 20 }, a{ 1 } {};
std::string name() const { return nm; }; // *** const
void set_hp(int x) { h = x; };
int hp() const { return h; } // *** const
void set_atk(int x) { a = x; };
int atk() const { return a; } // *** const
void attack_enemy( Enemy& e ); // *** pass reference
private :
std::string nm;
int h;
int a;
};
class Enemy
{
public :
void set_hp(int x) { h = x; }
int hp() { return h; }
void attack_player(Player p);
virtual void appear() = 0;
virtual void defeated() = 0;
Enemy(const Enemy&) = delete ;
Enemy& operator =(const Enemy&) = delete ;
virtual ~Enemy() {};
protected :
Enemy(int h, int a)
:h{ h }, a{ a } {};
private :
int h;
int a;
};
class Beast : public Enemy
{
public :
// *** Enemy::Enemy is protected; therefore, the inheriting constructoris also protected
// *** Either make Enemy::Enemy public in the base class
// using Enemy::Enemy; // <-- Problematic code 2
// *** Or write a public constructor
Beast( int h, int a ) : Enemy{h,a} {}
void appear() override { std::cout << "A beast has appeared!\n" ; }
void defeated() override { std::cout << "The beast has been defeated!\n" ; }
};
Player create_player();
Player create_player()
{
std::cout << "Enter your name: " ;
std::string name;
std::cin >> name;
// Player p{ name };
return Player{ name };
}
void Player::attack_enemy( Enemy& e ) // *** pass reference
{
e.set_hp(e.hp() - atk());
}
void Enemy::attack_player(Player p) // pass reference ???
{
p.set_hp( p.hp() - this ->a ) ;
//TODO
}
int main()
{
Player player_one{ "player_one" } ;
player_one.set_atk(25) ;
Beast gargoyle{ 52, 12 } ;
gargoyle.appear() ;
std::cout << gargoyle.hp() << '\n' ;
player_one.attack_enemy(gargoyle) ;
std::cout << gargoyle.hp() << '\n' ;
gargoyle.defeated() ;
}
http://coliru.stacked-crooked.com/a/46ad15cc611ade61
Topic archived. No new replies allowed.