I am trying to make a little poker game. In the code below I have a Game class and a Player class. The game class contains a std::vector which contains all the players. The Player class has a name attribute. Now my question is the following: how can I access the Player's attribute name through the vector that contains the Player objects? My problem appears in the last method of the code below, called show().
Thanks for helping!
//Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include <iostream>
#include "Card.h"
class Player
{
public:
Player();
Player(std::string n, double chipsQty);
private:
const std::string name;
double chipsAmount;
Card cardOne;
Card cardTwo;
};
#endif PLAYER_H
//Player.cpp
#include "Player.h"
Player::Player(){}
Player::Player(std::string n, double chipsQty) : name(n), chipsAmount(chipsQty)
{}
//Game.h
#ifndef GAME_H
#define GAME_H
#include "Player.h"
#include <vector>
class Game
{
public:
Game();
Game(int nbr, double chipsQty, std::vector<std::string> vectorNames);
void start();
void show();
private:
std::vector<Player> playersVector;
int nbrPlayers;
};
#endif GAME_H
//Game.cpp
#include "Game.h"
#include "Player.h"
Game::Game(){}
Game::Game(int nbr, double chipsQty, std::vector<std::string> vectorNames) :nbrPlayers(nbr)
{
for (int i = 0; i < vectorNames.size(); i++)
{
Player player(vectorNames[i], chipsQty);
playersVector[i] = player;
}
}
void Game::start(){};
void Game::show()
{
for (int i = 0; i < playersVector.size(); i++)
{
std::cout << playersVector[i] //Why can't I do something like playersVector[i].name here?
}
}
Because name attrbute of a Player class is private, so you cannot access it directly from another class. You should add a method to Player class that will return the name of the player, eg:
class Player
{
private:
std::string name;
public:
std::string getName() const { return name; }
};
Then you can access the player name by
playersVector[i].getName()
Related
I would like to understand aggregation so I tried making a simple test code, but it doesn't work in my compiler, sometimes it works online.
code for main:
#include <iostream>
#include <string>
#include "player.h"
#include "game.h"
using namespace std;
int main(){
game game;
game.playGame();
return 0;
}
code for game.cpp:
#include "game.h"
#include "player.h"
game::game(){
player.setBalance(0);
}
void game::playGame(){
cout << "playing game." ; //just for debugging
}
code for game.h:
#ifndef GAME
#define GAME
#include <iostream>
using namespace std;
class game{
private:
player player;
public:
game();
void playGame();
};
#endif
code for player.cpp:
#include "player.h"
player::player(){
balance = 0;
}
player::player(int theBalance){
balance = theBalance;
}
int player::getBalance(){
return balance;
}
void player::setBalance(int theBalance){
balance = theBalance;
}
code for player.h:
#ifndef PLAYER // used on headers
#define PLAYER
class player{
private:
int balance;
public:
player();
player(int);
int getBalance();
void setBalance(int);
};
#endif
I think the problem is probably on the headers.
the error I get is:
In file included from main.cpp:5:0:
game.h:10:12: error: declaration of 'player game::player' [-fpermissive]
player player;
In file included from main.cpp:4:0:
player.h:5:7: error: changes meaning of 'player' from 'class player' [-fpermissive]
class player{
^~~~~~
I think that the problem is in class game, because it doesn't know a class player, use forward declaration or just write #include "player.h" in game.h
Why does the compiler give me an error of Card deck[5] when the two classes are in different files, but if I put them in the same file the compiler approves?
I did include ".h" to both files.
Header 1
class Card
{
private:
char* card_name;
int card_value;
Color card_color;
public:
Card();
void set_card(char * buffer , Card& c);
Card get_card(int index,Card deck[]);
int get_card_value();
void print_card();
~Card();
};
Header 2
class Player
{
private:
friend class Card;
char* name;
char* id;
int wins;
int losses;
int remains_move;
struct Coordinate cord;
Card deck[MAX_CARDS];
public:
Player();
int Player_Array_Size(char* Creation,const int MAX_PLAYERS);
void Player_Creation_File(char* Creation);
void Player_Simulation_File(char* Simulation,int Array_Size);
void set_player();
Player* get_player();
void print_player();
void move_to_point(int x ,int y);
void attack_using_card(int Attacker ,int Defender,int Attack_card);
void win_match();
void lose_match();
~Player();
You probably have 4 files, card.h, card.cpp, player.h and player.cpp.
In player.h:
#include "card.h"
class Player { ... };
In player.cpp:
#include "player.h"
...
In card.h:
class Player; // Forward declaration
class Card { ... };
In card.cpp:
#include "card.h"
#include "player.h"
...
That's it.
I have Player class defined like this:
"Player.h"
#ifndef PLAYER_h
#define PLAYER_h
#include "cocos2d.h"
USING_NS_CC;
class Player: public Sprite {
public:
Player();
~Player();
private:
Sprite *playerSprite;
__String name;
int maxHP;
int currHP;
int maxMP;
int currMP;
int maxEXP;
int currEXP;
};
#endif
and "Player.cpp":
#include "Player.h"
I want to initialize int maxHP, int maxMP .. etc upon
Player* myPlayer = Player::create();
What would be the proper way to override ::create() function with parameters such that
// create(int maxHP, int currHP, int maxMP, int currMP, int maxEXP, int currEXP)
Player* myPlayer = Player::create(100, 100, 100, 100, 100, 100);
can be used?
You can overload create (have multiple functions with the same name but different signature).
class Player : public Sprite {
public:
static Player* create(int maxHP, int currHP, int maxMP, int currMP, int maxEXP, int currEXP) {
Player* p = Player::create();
p->maxHP = maxHP;
// etc ...
return p;
}
}
OK so i have a few problems.
1. I need to be able to register the childclass when its created with game for broadcasting.
2. I need to be able to call the child class's method from an array of GameObject Pointers.
3. I need it to be the actual classes, not just copys of them.
In the file systemvars.h i have my global methods and some variables.
#pragma once
//=================================
// include guard
#ifndef _SYSTEMVARS_H_
#define _SYSTEMVARS_H_
//=================================
// forward declared dependencies
class Game;
//=================================
// included dependencies
#include <iostream>
using namespace std;
//global enums
const enum CLASSTYPE{CLASSTYPE_NULL,CLASSTYPE_PLAYER,CLASSTYPE_DUNGION,CLASSTYPE_ENTITY,CLASSTYPE_MAP,CLASSTYPE_MENU};
//Global methods
void setGameRefrence(Game*);
Game* getGameRefrence();
systemvars.cpp: definitions
#include "SystemVars.h"
static Game* curentgame;
void setGameRefrence(Game* mygame)
{
curentgame = mygame;
}
Game* getGameRefrence()
{
return curentgame;
}
In my Game.h: a holder for gameobjects
#pragma once
//=================================
// include guard
#ifndef _GAME_H_
#define _GAME_H_
//=================================
// forward declared dependencies
class GameObject;
//class Player;
//=================================
// included dependencies
#include "SystemVars.h"
#include "GameObject.h"
//#include "Player.h"
#include <iostream>
using namespace std;
//=================================
// the actual class
class Game
{
public:
Game(void);
void registerGameObject(GameObject*);
void unregisterGameObject(GameObject*);
void sendMessageToAllObjects(string message,CLASSTYPE recipeint);
~Game(void);
private:
GameObject *gameobjects2[1000];
int numberofobject;
};
#endif
the game.cpp gameclass definition
#include "Game.h"
//#include "Player.h"
Game::Game(void)
{
setGameRefrence(this);
//logHelperMessage(INFO,1,"Registerd game");
numberofobject = 0;
}
void Game::registerGameObject(GameObject* newobj)
{
//logHelperMessage(INFO,1,"Registerd");
newobj->setId(numberofobject);
gameobjects2[numberofobject] = newobj;
numberofobject++;
//gameobjects.push_back(newobj);
}
void Game::unregisterGameObject(GameObject* objtodie)
{
//logHelperMessage(INFO,1,"Unregister");
for(int i = objtodie->getId();i < numberofobject - 1;i++)
{
gameobjects2[i] = gameobjects2[i+1];
gameobjects2[i]->setId(i);
}
gameobjects2[numberofobject-1] = nullptr;
numberofobject--;
}
void Game::sendMessageToAllObjects(string message,CLASSTYPE recipeint)
{
for(int i = 0; i < numberofobject;i++)
{
cout << "Sent the message from game");
//((Player *)gameobjects2[i])->sendMessage(message);
//static_cast<Player*>(gameobjects2[i])->sendMessage(message);
}
}
Game::~Game(void)
{
}
Gameobject.h: the parent of my inner game classes.
#pragma once
//=================================
// include guard
#ifndef _GAMEOBJECT_H_
#define _GAMEOBJECT_H_
//=================================
// forward declared dependencies
enum CLASSTYPE;
//=================================
// included dependencies
#include <iostream>
#include "SystemVars.h"
using namespace std;
//=================================
// the actual class
class GameObject
{
public:
GameObject();
GameObject(CLASSTYPE mytype);
~GameObject(void);
virtual void sendMessage(string data);
virtual CLASSTYPE getMyClassType();
virtual void setMyClassType(CLASSTYPE newrecip);
void setId(int val);
int getId();
protected:
CLASSTYPE _MYCURRENTCLASSTYPE;
int myid;
};
#endif
Gameobject.cpp
#include "GameObject.h"
GameObject::GameObject() : _MYCURRENTCLASSTYPE(CLASSTYPE_NULL)
{
//do not register
}
GameObject::GameObject(CLASSTYPE mytype): _MYCURRENTCLASSTYPE(mytype)
{
//register this object into the gameobject list.
getGameRefrence()->registerGameObject(this);
}
GameObject::~GameObject(void)
{
getGameRefrence()->unregisterGameObject(this);
}
void GameObject::sendMessage(string data)
{
//logHelperMessage(INFO,1,"Recived te message in GameObject");
cout << "Recived te message in GameObject";
}
CLASSTYPE GameObject::getMyClassType()
{
return _MYCURRENTCLASSTYPE;
}
void GameObject::setMyClassType(CLASSTYPE newrecip)
{
}
void GameObject::setId(int val)
{
myid = val;
}
int GameObject::getId()
{
return myid;
}
Player.h:
pragma once
//=================================
// include guard
#ifndef _PLAYER_H_
#define _PLAYER_H_
//=================================
// forward declared dependencies
//=================================
// included dependencies
#include "SystemVars.h"
#include "GameObject.h"
//=================================
// the actual class
class Player : public GameObject
{
public:
Player();
void sendMessage(string data) override;
void test();
}
Player.cpp:
Player::Player() : GameObject(CLASSTYPE_PLAYER)
{
}
void Player::sendMessage(string data)
{
//logHelperMessage(INFO,1,"Recived the message in Player");
cout << "Recived the message in Player";
//logHelperMessage(INFO,1,data.c_str());
cout << data;
}
void Player::test()
{
cout << "Sent message";
getGameRefrence()->sendMessageToAllObjects("Test",CLASSTYPE_PLAYER);
}
main.cpp
#pragma once
#include "SystemVars.cpp"
#include "Player.h"
#include "Game.h"
Game mygame;
int main(int argc, char **argv)
{
setGameRefrence(&mygame);
Player newplayer = Player();
newplayer.test();
}
Now that that is all out of the way.
The expected output is:
Sent message
Sent message from game
Recived message in Player
but insted i get:
Sent message
Sent message from game
Recived message in Gameobject
Im pretty sure i have a sliceing problem, but im not sure what to do about it, or where it is.
So, any ideas gents?
ALso, i tried to cut back the classes a bit so im not posting 2000~ lines of code. So if anyhting missing let me know.
About a dozen classes inherit from gameobject. and i need them all to talk to eachother in one way or another.
Just by having CLASSTYPE_PLAYER, etc. makes me concerned that you're trying to subvert/reinvent C++ OOP. You already have the concept of 'class' in the language, why re-invent it? Forgive me if I'm wrong. Aside from this, I suggest you look up publisher-subscriber frameworks to do the kind of thing you're after, or implement your own. I'm sure somebody will answer your C++ issue more directly.
Edit: tone of first comment.
I have a C++ class and I keep getting this error although I have another class written with similar syntax that compiles without a fuss.
Here is my .h:
#ifndef FISHPLAYER_H
#define FISHPLAYER_H
#include "Player.h"
class FishPlayer : public Player
{
public:
float xThrust;
float yThrust;
static FishPlayer* getInstance();
protected:
private:
FishPlayer();
~FishPlayer();
static FishPlayer* instance;
};
#endif
And Here is my .cpp :
#include "..\include\FishPlayer.h"
FishPlayer* FishPlayer::instance=0; // <== I Get The Error Here
FishPlayer::FishPlayer()
{
//ctor
xThrust = 15.0f;
yThrust = 6.0f;
}
FishPlayer::~FishPlayer()
{
//dtor
}
FishPlayer* FishPlayer::getInstance() { // <== I Get The Error Here
if(!instance) {
instance = new FishPlayer();
}
return instance;
}
I've been searching for a while now and it must be something so big I don't see it.
Here is the inheritance:
#ifndef PLAYER_H
#define PLAYER_H
#include "Ennemy.h"
class Player : public Ennemy
{
public:
protected:
Player();
~Player();
private:
};
#endif // PLAYER_H
And the higher one:
#ifndef ENNEMY_H
#define ENNEMY_H
#include "Doodad.h"
class Ennemy : public Doodad
{
public:
float speedX;
float maxSpeedX;
float speedY;
float maxSpeedY;
float accelerationX;
float accelerationY;
Ennemy();
~Ennemy();
protected:
private:
};
And the superclass
#include <vector>
#include <string>
enum DoodadType{FishPlayer,Player,AstroPlayer,Ennemy,DoodadT = 999};
enum DoodadRange{Close, Medium , Far};
enum EvolutionStage{Tiny, Small, Average, Large};
class Doodad
{
public:
float score;
void die();
EvolutionStage evolutionStage;
DoodadRange range;
Doodad();
virtual ~Doodad();
Doodad(Doodad const& source);
std::vector<Animation> animations;
double posX;
double posY;
std::string name;
std::string currentAnimation;
int currentFrame;
DoodadType type();
SDL_Surface getSpriteSheet();
bool moving;
void update();
protected:
private:
SDL_Surface spriteSheet;
};
Looks like you use FishPlayer as a enum value in Doodad.h
It is the same name as the class you're trying to declare. That might be the source of the problem.
Generally it's a good idea to use FISH_PLAYER, or Type_FishPlayer sort of naming scheme for enum values to avoid clashes like this.