Different way to initialize - c++

I am making a game that includes orcish enemies. I have one problem, how do initialize their HP, MP, Attack, defense, and speed without writing different code for each like this:
int orcishHP = 50;
int orcishMP = 5;
int orcishAttack = 15;
int orcishDef = 10;
int orcishSpeed = 20;
Isn't there some way to initialize all that when I refer to the orc, like this:
int orcishStats(){
int HP = 50
etc...
}
So instead of calling orcish MP HP and all that stuff, I have all of it in one one place.
If this made sense, please help. If this didn't make sense, don't help.

Here's the correct way to do this:
You define your attributes in a class/struct, and when that struct is initialized, the constructor(OrcishAttributes()) is called:
struct OrcishAttributes
{
int m_orcishHP;
int m_orcishMP;
int m_orcishAttack;
int m_orcishDef;
int m_orcishSpeed;
OrcishAttributes(int orcishHP, int orcishMP, int orcishAttack, int orcishDef, int orcishSpeed)
{
m_orcishHP=orcishHP;
m_orcishMP = orcishMP;
m_orcishAttack = orcishAttack
m_orcishDef = orcishDef;
m_orcishSpeed = orcishSpeed;
}
}
class Orc
{
public:
Orc(OrcishAttributes oa)
{
m_orcAttributes = oa;
}
private:
OrcishAttributes m_orcAttributes;
}
int main()
{
OrcishAttributes oa(50,5,15,10,20);
Orc* o = new Orc(oa);
}

That's why we have OOP.
You can define a base class, lets say Unit. It can store common members like fields or methods:
class Unit
{
protected:
int HP;
int MP;
int Attack;
int Def;
int Speed;
public:
int getHPplusMP()
{
return HP + MP;
}
};
Then, you can create inherited classes and initialize these values in its constructors:
class OrcUnit : public Unit
{
public:
OrcUnit()
{
HP = 20;
MP = 0;
Attack = 13;
Def = 4;
Speed = 5;
}
};
class ElfUnit : public Unit
{
public:
ElfUnit()
{
HP = 25;
MP = 15;
Attack = 15;
Def = 1;
Speed = 8;
}
};
Then, you will be able to work with it:
ElfUnit elf;
OrcUnit orc;
Unit u = elf;
cout << u.getHPplusMP();
Unit u = orc;
cout << u.getHPplusMP();
In general, it is definitely a good idea to learn OOP very well before trying to implement games.

Related

How to concatenate name of variables in Cpp?

I have class Walls in my program. Inside of class are objects Wall1, Wall2 etc.
I want to do something like this:
class definition:
class Walls {
public:
Walls(){
nPositionX = nMapWidth - 1;
nHoleSize = 1;
nHolePosition = rand()%(nMapHeight - nHoleSize);
count++;
}
static int getCount() {
return count;
}
int getPositionX()
{
return nPositionX;
}
private:
int nPositionX;
int nHolePosition;
int nHoleSize;
static int count;
};
access to object
for (int i = 0; i < Walls::getCount(); i++) {
int nPosx = Wall"i".getPositionX();
}
}
Is that possible in c++?
Ok big thanks for everyone for help. I don't know why I didn't tried it before.
You can use an array or std::vector for that, eg:
std::array<Wall, MAX_WALLS> m_walls;
or
std::vector<Wall> m_walls;
...
// initialize m_walls[0], m_walls[1], etc as needed...
...
for (size_t i = 0; i < m_walls.size(); i++) {
int nPosx = m_walls[i].getPositionX();
...
}
Or, you can use a std::map, eg:
std::map<std::string, Wall> m_walls;
...
// initialize m_walls["Wall1"], m_walls["Wall2"], etc as needed...
...
for (int i = 1; i <= getCount(); i++) {
int nPosx = m_walls["Wall" + std::to_string(i)].getPositionX();
...
}
The code is not executed until you execute your program, but in the executable there are no variable names anymore. Hence, no.
You can use an array or vector:
struct Wall { int get_position() const { return 42; } };
using Walls = std::vector<Wall>;
Walls walls;
for (const auto& wall : walls) {
int nPosx = wall.get_position();
}
Or if you really want to map names to objects, use a std::map:
std::map<std::string,Wall> named_walls;
named_walls["stone wall"] = Wall();

Use Before Declaration with Classes

I'm having this issue with code evaluation. I want to use a function in one class, and use a function in another but I can't seem to get a prototype working for the function in the class.
class Pride
{
public:
std::string firstMinion = "Pride";
int prideAttackPlayer()
{
int damage = (rand() % 20 + 1) * attack;
return damage;
}
int damagePride()
{
health = health - play.attackEnemy();
}
int outputHealth()
{
return health;
}
private:
int health = 20;
int attack = 0;
int defence = 0;
int money = 0;
}pride;
class Player
{
public:
int attackEnemy()
{
int damage = (rand() % 20 + 1) * attack;
return damage;
}
void userAttack()
{
getline(std::cin, userInput);
if (userInput == "1")
{
std::cout << pride.damagePride();
}
}
private:
int health = 100;
int attack = 0;
int defence = 0;
std::string userInput = "";
}play;
I want to use play.attackEnemy in the Pride class but it won't work due to evaluation errors. I think the fix is to use a prototype but I've tried with int Player::attackEnemy() {}; and class Player but it doesn't do anything.

C++ class inherit (game structure)

I'm trying to make some game engine (I know, should do an actual game instead).
Sadly have defeat at project structure. it looks like this (footage from my fifth attempt):
#include <iostream>
#include <vector>
#include <windows.h>
using namespace std;
class Player;
class Engine {
private:
CHAR_INFO *chiBuffer;
int width = 0;
int height = 0;
vector <Player> players;
public:
Engine(int x = 120, int y = 30) {
chiBuffer = new CHAR_INFO[x*y];
}
void addPlayer(Player player) {
players.push_back(player);
}
void render() {
for (int i = 0; i < players.size(); i++) {
Player *player = &players[i];
player->draw();
}
}
protected:
inline CHAR_INFO& getPixel(int x, int y) { return chiBuffer[x + width * y]; }
};
class Drawable : Engine {
protected:
inline CHAR_INFO& getPixel(int x, int y) { return Engine::getPixel(x, y); }
virtual void draw() = 0;
};
class Player : Drawable {
protected:
int x = 0;
int y = 0;
public:
void draw() {
getPixel(x, y).Char.UnicodeChar = L'*';
}
};
int main() {
Engine *eng = new Engine(120, 30);
Player p;
eng->addPlayer(p);
return 0;
}
I would like to make it easily extensible, so in my mind had been born an idea of creating master class (Engine) sub class Drawable which will have draw() method and later Tickable which would have onTick() etc... But I'm pretty sure I'm doing it so wrong. Could you tell me better idea of doing this? Or make this just working because this gives me too many errors to write it right here (VS 2017)
First, why use this ?
for (int i = 0; i < players.size(); i++) {
Player *player = &players[i];
player->draw();
}
It's the same as: for(...) { players[i].draw() ;}.
Don't use variables and pointers where you don't need to (like in your main, don't use the new keyword: it's pointless. Engine e = Engine(120,30) is ok.).
The for loop on a vector should use Iterators :
for (auto it = begin (vector); it != end (vector); ++it) {
it->draw;
}
In manners of good practice, you should write your code in different files.
Engine.h for Engine declaration, Engine.cpp for implementation.
Same for Player.

In what circumstances is a default constructor always called for a class?

I recently realized how rusty I have gotten at C++ so I decided to work on a small text-based RPG. I have a class for weapons and a class for a player. My default Player constructor is this:
Player::Player()
{
name = "Henry";
hp = 50;
mp = 25;
xp = 0;
Weapon wep = Weapon::Weapon("Club", 5);
}
I have two constructors for my weapons, as follows:
Weapon::Weapon()
{
name = "Hands";
damage = 1;
}
Weapon::Weapon(string n, int d)
{
name = n;
damage = d;
}
My Weapon class:
class Weapon
{
private:
string name;
int damage;
public:
Weapon();
Weapon(string n, int d);
string getName();
int getDmg();
};
The problem, however, is when I call the getName() function in my main file, it returns "Hands". Likewise, getDmg() returns 1. Is this normal or did I do something wrong?
Weapon wep = Weapon::Weapon("Club", 5); is local to your Player constructor, you probably mean wep = Weapon("Club", 5);
or even better:
Player::Player() :
name("Henry"),
hp(50),
mp(25),
xp(0),
wep("Club", 5)
{
}

I can't display variables of different types included in array

I have to do a program for college.
I have 3 classes already declared in the statement of the problem.
First class:
class piesa_a{
protected:
int id;
char *tip;
int pret;
};
Second class:
class piesa_b:public piesa_a
{
private:
float lungime;
bool bw;
};
Third class:
class piesa_c:public piesa_a
{
private:
int nr;
piesa_b *buf;
};
In main I need to create an array in which to store items such piesa_a, piesa_b, piesa_c. Then I have to sort items by price.
I have this code so far: http://pastebin.com/nx2FGSfe
The program is incomplete because it does not displays each item in the array.
I got stuck here. But if you display the array's elements when they are outside of it, it works.
SHORT: I have an error on line 143 and I want to solve it.
main.cpp:143:18: error: request for member ‘afisare’ in ‘*(v + ((unsigned int)(((unsigned int)i) * 4u)))’, which is of non-class type ‘piesa_a*’
The code is here:
#include <cstdlib>
#include<iostream>
#include<string.h>
using namespace std;
class piesa_a{
protected:
int id;
char *tip;
int pret;
public:
piesa_a()
{
id = 0;
tip = new char[1];
pret = 0;
}
piesa_a(int aidi, char *typ, int pretz)
{
id = aidi;
tip = new char[strlen(typ)+1];
strcpy(tip,typ);
pret = pretz;
}
piesa_a&operator =(piesa_a alta)
{
id = alta.id;
tip = new char[strlen(alta.tip)+1];
strcpy(tip,alta.tip);
pret = alta.pret;
return *this;
}
virtual void afisare()
{
cout<<"\n Piesa A: "<<id<<" "<<tip<<" "<<pret;
}
};
class piesa_b:public piesa_a
{
private:
float lungime;
bool bw;
public:
piesa_b():piesa_a(){lungime = 0;bw = 0;}
piesa_b(float lg,bool bl, int aid, char *tipi, int pretzz):piesa_a(aid,tipi,pretzz)
{
lungime = lg;
bw = bl;
}
piesa_b&operator =(piesa_b &c)
{
id = c.id;
tip = new char[strlen(c.tip)+1];
strcpy(tip,c.tip);
pret = c.pret;
lungime = c.lungime;
bw = c.bw;
return *this;
}
void afisare()
{
piesa_a::afisare();
cout<<"impreuna cu piesa B: "<<lungime<<" "<<bw<<"\n";
}
};
class piesa_c:public piesa_a
{
private:
int nr;
piesa_b *buf;
public:
piesa_c():piesa_a(){nr=0; buf = new piesa_b[nr];}
piesa_c(int n, piesa_b *bu,int aid, char *tipi, int pretzz):piesa_a(aid,tipi,pretzz)
{
nr = n;
buf = new piesa_b[nr];
for(int i=0;i<nr;i++)
buf[i]= bu[i];
}
piesa_c&operator =(piesa_c &alta)
{
id = alta.id;
tip = new char[strlen(alta.tip)+1];
strcpy(tip,alta.tip);
pret = alta.pret;
nr = alta.nr;
for(int i=0;i<alta.nr;i++)
buf[i] = alta.buf[i];
}
void afisare()
{
for(int i=0;i<nr;i++)
buf[i].afisare();
}
};
int main(int argc, char** argv) {
piesa_b *H;
H = new piesa_b[2];
piesa_a A(4,"TIPA",120);
piesa_b B(100,1,3,"TIPA",120);
H[0]=B;
H[1]=B;
piesa_c C(2, H,14,"TIPC",20);
piesa_a** v = new piesa_a*[3];
v[0] = &A;
v[1] = &B;
v[2] = &C;
for(int i=0;i<3;i++)
v[i].afisare();
return 0;
}
What's wrong?
In C++ (and current C), casts are almost always a sign that the programmer didn't know how to use the language as it is supposed to be used. If you need an array of 3 types of data, the cleanest solution is an array of objects of a class that is base to the 3. And if you want to display each item differently, you'll want to overload the << operator, so you just iterate over the array and go << on each item. Sorted by price means that the class includes a price field, and you use the sort from the standard template library, passing a comparison operation that just compares prices.