classes not recognied inside another classeven with headers - c++

I have to make a snake and ladders game with classes (MyGame, Board, Player, Dice). MyGame needs all the other classes at some point or another thus I have the headers for the other classes in the MyGame.h file. Yet I get 3 errors that read:
Line 18 -----"error: ‘Board’ has not been declared."
Line 18 -----"error: ‘Player’ has not been declared."
Line 19 -----"error: ‘Player’ has not been declared."
An object MyGame is initialized in my main (skanes.cpp), and then inside the function MyGame::start() the other objects are created. I thought that maybe the classes Board or Player require something from MyGame in order to be build thus cycling but Player and Board are not dependent of MyGame besides the initialization of the obejct. HELP!
MyGame.h
#ifndef MYGAME_H
#define MYGAME_H
#include "Board.h"
#include "Player.h"
#include "Dice.h"
#include "Player.h"
class MyGame
{
protected:
static const int numPlayers = 2;
public:
MyGame();
~MyGame();
void start();
void play(Player[], Dice, Board); <-------Line 18
void win(Player[]); <-------Line 19
int getNumPLayers();
};
#endif
MyGame.cpp
#include <iostream>
#include <vector>
#include "MyGame.h"
#include "Board.h"
#include "Player.h"
#include "Dice.h"
MyGame::MyGame()
{
}
MyGame::~MyGame()
{
}
void MyGame::start()
{
Board brd;
Player plyr[numPlayers];
Dice dc;
while (plyr[0].getPosition() != brd.getBoardSize() && plyr[1].getPosition() != brd.getBoardSize() && plyr[numPlayers - 1].getTurn() <= plyr[numPlayers - 1].getMaxTurn())
play(plyr, dc, brd);
win(plyr);
}
void MyGame::play(Player p[], Dice d, Board b)
{
for (int i = 0; i < b.getBoardSize(); i++)
{
p[i].setPosition(d.roll());
if(p[i].getPosition() > b.getBoardSize())
{
p[i].setPosition( (b.getBoardSize() - p[i].getPosition()) * 2 );
}
if (b.getType(p[i].getPosition()) == 'S')
p[i].setPosition(-b.getSnakeLadderMove());
else if (!b.getType(p[i].getPosition()) == 'L')
p[i].setPosition(b.getSnakeLadderMove());
p[i].setTurn();
}
}
void MyGame::win(Player p[])
{
for (int i = 0; i > numPlayers; i++)
{
if (p[i].getPosition() == 30)
std::cout << "Payer " << i << "wins!!" << std::endl;
}
}
Board.h
#ifndef BOARD_H
#define BOARD_H
#include "MyGame.h"
class Board
{
public:
Board();
~Board();
bool getType(int);
int getNumeber(int);
int getSnakeLadderMove();
int getBoardSize();
private:
struct tile
{
char type;
int number;
};
static const int boardSize = 30;
static const int snakeLadderMove = 3;
tile place[boardSize];
};
#endif
Board.cpp
#include <stdlib.h>
#include <time.h>
#include "Board.h"
Board::Board()
{
int count = 0;
//initialize random seed to randomize snakes and ladders.
srand(time(NULL));
for (int k = 0; k < boardSize; k++)
{
place[k].type = 'N';
place[k].number = k + 1;
}
while(count <= 3)
{
int index = rand() % boardSize + 1;
while (index < 4)
{
index = rand() % boardSize + 1;
// Makes sure it only replaces tiles with type = 'N'
while(getType(index) != 'N')
index = rand() % boardSize + 1;
}
place[index].type = 'S';
while (index > boardSize - 3)
{
index = rand() % boardSize + 1;
// Makes sure it only replaces tiles with type = 'N'
while(getType(index) != 'N')
index = rand() % boardSize + 1;
}
place[index].type = 'L';
count++;
}
}
Board::~Board()
{
}
int Board::getNumeber(int index)
{
return place[index].number;
}
bool Board::getType(int index)
{
return place[index].type;
}
int Board::getBoardSize()
{
return boardSize;
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include "MyGame.h"
#include "Board.h"
class Player
{
public:
Player();
~Player();
void setPosition(int);
void setTurn();
int getPosition();
int getTurn();
int getMaxTurn();
int getNumPlayers();
private:
static const int maxTurn = 20;
int position;
int turn;
};
#endif
Player.cpp
#include <iostream>
#include "Player.h"
#include "Board.h"
Player::Player()
{
/*
In order for the setters to work position and turn
have to be equal to 1;
*/
position = 1;
turn = 1;
}
Player::~Player()
{
}
void Player::setPosition(int move)
{
//Assumes constructor setted the value to 0
position += move;
;
}
void Player::setTurn()
{
//Assumes constructor sette4d the value to 0
turn++;
}
int Player::getPosition()
{
return position;
}
int Player::getTurn()
{
return turn;
}
int Player::getMaxTurn()
{
return maxTurn;
}
Dice.h
#ifndef CDADO_H_INCLUDED
#define CDADO_H_INCLUDED
#include <ctime>
#include <cstdlib>
class Dice{
public:
Dice();
int roll();
};
#endif
Dice.cpp
#include <iostream>
#include "Dice.h"
using namespace std;
Dice::Dice()
{
srand(time(0));
}
int Dice::roll()
{
return (rand() % 6) + 1;
}
skanes.cpp //It was supposed to be snakes.
#include <iostream>
#include "MyGame.h"
using namespace std;
int main()
{
MyGame snakes;
snakes.start();
}

#define BOARD_H
#include "MyGame.h" // <--- here lies the problem
Do not include MyGame.h in Board.h and Player.h. You have a circular dependency.

Pretend that you are a C++ compiler that's compiling your Player.cpp:
#include <iostream>
#include "Player.h"
At this point the compiler starts reading Player.h:
#ifndef PLAYER_H
#define PLAYER_H
#include "MyGame.h"
Now your C++ compiler goes to read MyGame.h. Remember that this is all that your compiler has processed up to now. It has not processed anything else.
In MyGame.H there's another #include "Player.H", however it does absolutely nothing whatsoever, since the include guard was defined, so the second inclusion of Player.H becomes a big fat nothing.
Your compiler continues to process MyGame.H, and finds a reference to some mysterious class named Player that has never been defined anywhere. That's the explanation for your compilation error.
There does not appear to be any need for Player.H to include MyGame.H, so just get rid of that include.
It's a circular reference that's completely unneeded, and easily fixable by getting rid of it. If you do need real circular references between header files, your C++ textbook should have a good explanation of what forward references are, and how to use them.

Related

How to determine a template parameter at runtime in c++

I define a ThreadPoolclass, and it has a memeber: std::array<Worker, ThreadNum> Workerlist.
The code is as follows:
#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <pthread.h>
#include <memory>
#include "Worker.h"
#include <vector>
#include <array>
const int MAX_THREAD_NUM = 16;
class ThreadPool
{
private:
const unsigned int ThreadNum;
std::shared_ptr<EventLoop> MainLoop;
std::array<std::shared_ptr<Worker>, ThreadNum> WorkerList;
std::array<std::shared_ptr<EventLoop>, ThreadNum> EventLoopList;
unsigned int NextLoopIndex;
public:
ThreadPool(std::shared_ptr<EventLoop> loop, int threadNum = 12);
~ThreadPool();
void RunThreadPool();
std::shared_ptr<EventLoop> GetNextEventLoop();
}
#endif
ThreadPool.cpp
ThreadPool::ThreadPool(std::shared_ptr<EventLoop> loop, int threadNum): MainLoop(loop), ThreadNum(threadNum), NextLoopIndex(0)
{
if (ThreadNum<=0 || ThreadNum> MAX_THREADS)
{
LOG << "The num of threads is out of range.\n";
}
}
ThreadPool::~ThreadPool() {}
void ThreadPool::RunThreadPool()
{
WorkerList.fill(std::make_shared<Worker>());
for (auto i = 0; i < ThreadNum; i++)
{
EventLoopList.at(i) = WorkerList.at(i)->ReturnEventLoopPtr();
}
}
std::shared_ptr<EventLoop> ThreadPool::GetNextEventLoop()
{
if (!EventLoopList.empty())
{
std::shared_ptr<EventLoop> nextLoop = EventLoopList[NextLoopIndex];
NextLoopIndex = (NextLoopIndex + 1) % ThreadNum;
return nextLoop;
}
return;
}
The error message is:
invalid use of data member ThreadPool::ThreadNum
In my opinion, the template parameter ThreadNum should be a constant, but now I need to infer its value when the class is constructed. Any solutions? Thank you very much.

error: 'object' was not declared in this scope

I am pretty new at c++ and trying to make Monopoly game. Unfortunately it still shows me error in declaration between two classes.
I've already tried everything and really have no idea where the problem can be.
The error: 'Player' is not declared in this scope.
Engine.h
#ifndef ENGINE_H
#define ENGINE_H
#include "Player.h"
#include <vector>
using namespace std;
class Engine{
public:
Engine(); // method that starts with game, take random number for getting number of players, set players to vector
void play(); // method where players are playing.
bool returnBalance(int a_money) const; // method that return True, if the players has still some amount on account, False otherwise
bool isWinner();
int setBalance(); // method that set curretn player amount
void printWinner(); // method that print winter of the game
void payBills(int amount); // player pay any bills with this method
virtual ~Engine();
private:
vector<Player*> players;
int i_player;
int balance;
int currentPlayer;
};
#endif /* ENGINE_H */
Engine.cpp
#include "Engine.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
Engine::Engine() {
int numPlayers = rand()*(6-2)+2;
for (int i = 0; i <= numPlayers; i++){
Player* p = new Player;
players.push_back(p);
}
cout << players.size() << endl;
int p_index = 0;
for(int i = 1; i <= players.size(); i++){
p_index = i;
p_index++;
cout << p_index ;
}
currentPlayer = p_index;
cout << "Welcome to MonOOpoly game, the game will be played in the same order you already are." << endl;
}
void Engine::play() {
do{
}while(!isWinner());
}
bool Engine::isWinner(){
int count = 0;
for(int i = 1; i <= players.size(); i++){
if(players[i]->getAmount() > 0)
count++;
}
if(count <= 1)
return true;
return false;
}
int Engine::setBalance(){
int amount = players[currentPlayer]->amount;
return players[currentPlayer]->amount;
}
bool Engine::returnBalance(int a_money) const{
if (players[currentPlayer]->amount < a_money)
return false;
else
return true;
}
void Engine::payBills(int amount) {
players[currentPlayer]->amount = players[currentPlayer]->amount - amount;
}
void Engine::printWinner() {
int winner = 0;
int newWinner = 0;
for(int i = 1; i <= players.size(); i++){
if(players[i] > 0){
winner = players[i]->getAmount();
if(newWinner < winner)
newWinner = winner;
}
}
cout << "Winner of the game MonOOpoly is: " << newWinner << endl;
}
Engine::~Engine() {
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include "Engine.h"
#include <string>
using namespace std;
class Player {
friend class Engine;
public:
Player(); // constructor
int getAmount() const; // return how much of amount the player has yet
void setAmount(int a); // set amount
int getPosition() const; // return position of the player
void setPosition(int p); // to set position
virtual ~Player(); // destructor
private:
int position; // the position of the player
int amount; // the total amount
};
#endif /* PLAYER_H */
Player.cpp
#include <iostream>
#include <stdlib.h>
#include "Player.h"
using namespace std;
Player::Player() {
amount = 5000;
position = 0;
}
int Player::getAmount() const {
return amount;
}
void Player::setAmount(int a) {
amount = a;
}
int Player::getPosition() const {
return position;
}
void Player::setPosition(int p) {
position = p;
}
Player::~Player() {
}
You have circular includes in your headers, likely causing the compiler issues you're seeing. Engine.h includes Player.h and Player.h includes Engine.h
You should:
move the #include Player.h from Engine.h to Engine.cpp
forward declare the Player class in the Engine.h (with a class Player;) line.
Forward declarations are useful here since Engine.h only needs to know the some Player class exists and not it's entire definition, since it just defines a simple vector of pointers to that class.

Function does not take 1 arguments when passing this into it

I'm trying to pass an instance of this (the instance in question being the GameEngine class) into my PlayerBrain.run method which takes a GameEngine * const argument corresponding to what this is. I'm curious as to what would cause such an error to be thrown in this case, especially when there are no alternative function definitions for run() or anything like that. PlayerBrain is its own class, not descending from anything. So there's no alternative definitions to run that might cause problems. Here's the relevant code:
All public methods in PlayerBrain.h
#pragma once
#include "GameEngine.h"
#include "Species.h"
#include "Neuron.h"
#include "Genome.h"
#include "GenePool.h"
#include "Gene.h"
#include <sys/stat.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
class PlayerBrain {
private:
int popSize;
int stalenessThreshold;
int timeoutConstant;
int currentTimeout;
int maxNodes;
int farthestDistance;
bool buttons[6]; // JASON - shoot, left, right, up, down, jump in that order
GenePool p;
bool fileExists(string filename);
bool fitnessAlreadyMeasured();
void nextGenome();
void evaluateCurrent(Genome * g);
void evaluateNetwork(vector<Neuron*> * network, vector<int> inputs);
void loadPool(string filename);
double sigmoid(double sum);
vector<int> getInputs();
Genome templateGenome();
void pressAKey();
void unPressAKey();
vector<INPUT *> oldbuttons;
public:
PlayerBrain();
void intialize();
void run(GameEngine const *);
void close();
};
The actual implementation in its .cpp
void PlayerBrain::run(GameEngine const * g) {
Genome * current = p.getCurrentGenome();
int xPos = 0;
int bossLives = 0;
double fitness;
double timeoutBonus;
unPressAKey();
if ((p.getCurrentFrame() % 5) == 0)
evaluateCurrent(current);
pressAKey();
xPos = g->getXPosAckVar();
bossLives = g->getBossLivesAckVar();
if (xPos > farthestDistance) { farthestDistance = xPos; currentTimeout = timeoutConstant; }
currentTimeout--;
timeoutBonus = p.getCurrentFrame() / 4;
if ((currentTimeout + timeoutBonus) <= 0) {
fitness = (farthestDistance - (p.getCurrentFrame() / 2)) + 2000 * bossLives;
if (fitness == 0) { fitness = -1; }
current->setFitness(fitness);
if (fitness > p.getMaxFitness()) { p.setMaxFitness(fitness); }
p.setCurrentSpecies(0);
p.setCurrentGenome(0);
while (fitnessAlreadyMeasured()) { nextGenome(); }
}
p.setCurrentFrame(p.getCurrentFrame() + 1);
}
The function call in GameEngine.cpp`
while (true)
{
......//irrelevant stuff
if (tickTimeNow > tickTimeTrigger)
{
if (dTimeTrigger > m_PaintTimeTrigger)
{
....
brain->run(this);
....
}
else Sleep(1);
}
else WaitMessage();
}
}
The error I get is as follows:
Error C2660 'PlayerBrain::run': function does not take 1 arguments

Virtual keyword seems to be ignored

This is my first "big" C++ project and I am stuck. I am trying to create a simple ASCII roguelike. I have a character class that is inherited by a Player class and a Monster class. The Monster class is inherited by Vampire and Werewolf classes.
In the startGame function of the GameSystem class I submit every element of a Monsters array (that is supposed to be filled with Vampire and Werewolf objects) to the function moveAround. Vampires, Werewolfs, and Monsters all have this function yet only the Monster moveAround function is being accessed. If you notice in the code below I have the virtual keyword provided in the Monster class.
This leads me to think I messed up when I filled the Monster array with the subclasses. I did this in the GameSystem constructor by randomly determining if a particular element of the Monster array was going to be a werewolf or a vampire.
I am using codeblocks and in terms of compiling I have g++ following C++11.
GameSystem.cpp
#include <iostream>
#include <string>
#include "GameSystem.h"
#include "Map.h"
#include "Player.h"
#include "Werewolf.h"
#include "Vampire.h"
#include "conio.h"
#include <cstdio>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <time.h>
GameSystem::GameSystem(string mapName){
srand (time(NULL));
_map.load(mapName);
_map.obtainSpawningLocations(_player.getToken(),_player);
Werewolf werewolf;
Vampire vampire;
for(int i = 0; i < 5; i++){
_spawnValue = rand() % 2; //We generate either 1 or 2
if(_spawnValue==1){
_theMonsters[i] = werewolf;
cout<<"Werewolf"<<endl;
}
else{
_theMonsters[i] = vampire;
cout<<"Vampire"<<endl;
}
_map.obtainSpawningLocations(_theMonsters[i].getToken(),_theMonsters[i]);
}
}
void GameSystem::startGame(){
bool isOver = false;
while(isOver!=true){
_map.print();
movePlayer();
for(int i = 0; i <5; i++){
_theMonsters[i].moveAround(); //prints out Monster.moveAround()
//I need it to print out Vampire.moveAround() and //Werewolf.moveAround
}
}
}
void GameSystem::movePlayer(){
char input;
input = getch();
string clearScreenString(100,'\n'); //Prints out a newLine char 100 times
cout << clearScreenString;
_map.checkMovement(input, _player);
}
char GameSystem::getch(){
char buf=0;
struct termios old={0};
fflush(stdout);
if(tcgetattr(0, &old)<0)
{perror("tcsetattr()");}
old.c_lflag&=~ICANON;
old.c_lflag&=~ECHO;
old.c_cc[VMIN]=1;
old.c_cc[VTIME]=0;
if(tcsetattr(0, TCSANOW, &old)<0)
{perror("tcsetattr ICANON");}
if(read(0,&buf,1)<0)
{perror("read()");}
old.c_lflag|=ICANON;
old.c_lflag|=ECHO;
if(tcsetattr(0, TCSADRAIN, &old)<0)
{perror ("tcsetattr ~ICANON");}
//printf("%c\n",buf);
return buf;
}
GameSystem.h
#pragma once
#include "Map.h"
#include <string>
#include <list>
using namespace std;
class GameSystem
{
public:
GameSystem(string mapName); //Constructor
void startGame(); //Start the game
char getch();
void movePlayer();
private:
//int _numberOfMonsters = 5; //We'll make this a random number later
Map _map;
Player _player;
Monster _monster;
Monster _theMonsters[5];
int _x;
int _y;
int _spawnValue;
};
Character.cpp
#include <string>
#include "Character.h"
using namespace std;
Character::Character(){
}
char Character::getToken(){
return _token;
}
void Character::setLocation(int x, int y){
_x = x;
_y = y;
}
void Character::getLocation(int &x, int &y){
x = _x;
y = _y;
}
Character.h
#pragma once
#include <string>
class Character{
public:
Character();
char getToken();
void setLocation(int x, int y);
void getLocation(int &x, int &y);
protected:
int _x;
int _y;
char _token = '!';
};
Map.cpp
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <cstring>
#include <random>
#include <ctime>
#include <tuple>
#include "Map.h"
#include <time.h>
Map::Map(){
srand (time(NULL));
}
void Map::load(string levelName){
ifstream theStream;
theStream.open(levelName);
if(theStream.fail()){
perror(levelName.c_str());
system("PAUSE");
exit(1);
}
string line;
while(getline(theStream, line)){
_mapData.push_back(line);
}
theStream.close();
}
void Map::obtainSpawningLocations(char characterToken,Character &_character){
/*
Below code provides all the possible spawning locations for the player
and stores them in an array of tuples.
*/
tuple<int,int> myTuple[600]; //Hard coded 600 value is messy. Change later
int numberOfSpawnPoints = 0;
int upperLimitForNumberGenerator = 0;
/*
The for loop below records all of the possible spawning locations and stores them in the tuple array
*/
for(int i = 0; i<_mapData.size();i++){
for(int j = 0; j<_mapData[i].size();j++){
if(_mapData[i][j]=='.'){
get<0>(myTuple[numberOfSpawnPoints]) = j;
get<1>(myTuple[numberOfSpawnPoints]) = i;
numberOfSpawnPoints++;
}
}
}
upperLimitForNumberGenerator = numberOfSpawnPoints;
int characterCoordinates = rand()%upperLimitForNumberGenerator;
int xCoordinate = get<0>(myTuple[characterCoordinates]);
int yCoordinate = get<1>(myTuple[characterCoordinates]);
_mapData[yCoordinate][xCoordinate] = characterToken; //Remember y is first and x is second
_character.setLocation(xCoordinate, yCoordinate);
}
void Map::print(){
for(int i=0;i<_mapData.size(); i++){
printf("%s\n", _mapData[i].c_str());
}
printf("\n");
}
void Map::checkMovement(char input, Player &aPlayer){
int x;
int y;
aPlayer.getLocation(x,y);
char aLocation;
switch(input) {
case 'w':
case 'W': //If 1 up from the player token is a '.' then we move him up
//via a different function
//Otherwise we do nothing.
aLocation = returnLocation(x,y-1);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y-1][x] = '#';
aPlayer.setLocation(x,y-1);
}
else
cout<<"Can't go here!"<<endl;
break;
case 'a':
case 'A':
aLocation = returnLocation(x-1,y);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y][x-1] = '#';
aPlayer.setLocation(x-1,y);
}
else
cout<<"Can't go here!"<<endl;
break;
case 's':
case 'S':
aLocation = returnLocation(x,y+1);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y+1][x] = '#';
aPlayer.setLocation(x,y+1);
}
else
cout<<"Can't go here!"<<endl;
break;
case 'd':
case 'D':
aLocation = returnLocation(x+1,y);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y][x+1] = '#';
aPlayer.setLocation(x+1,y);
}
else
cout<<"Can't go here!"<<endl;
break;
default:
cout<<"Invalid input";
system("PAUSE");
break;
}
}
char Map::returnLocation(int x, int y){
cout<<x<<endl;
cout<<y<<endl;
char aSpot = _mapData[y][x];
return aSpot;
}
Map.h
#pragma once
#include <vector>
#include <fstream>
#include <string>
#include <tuple>
#include <ctime>
#include <random>
#include "Player.h"
#include "Monster.h"
using namespace std;
class Map
{
public:
Map(); //Constructor
void load(string levelName);
void obtainSpawningLocations(char characterToken, Character &aCharacter);
void checkMovementMonsters(char input, Monster &aMonster);
//void obtainSpawningLocationsForMonsters(char characterToken, Monster aMonster);
void print();
void checkMovement(char input, Player &aPlayer);
void movement(char characterToken);
char returnLocation(int x,int y);
// int numberOfSpawnPoints;
private:
vector <string> _mapData;
Player _player;
Monster _monster;
};
Monster.cpp
#include <iostream>
#include <string>
#include "Monster.h"
using namespace std;
Monster::Monster(){
}
void Monster::moveAround(){
cout<<"Monster Mash"<<endl;
}
Monster.h
#pragma once
#include <string>
#include "Character.h"
class Monster: public Character{
public:
Monster();
virtual void moveAround();
protected:
char _token = 'M';
int _x;
int _y;
};
Werewolf.cpp
#include <iostream>
#include <string>
#include "Werewolf.h"
using namespace std;
Werewolf::Werewolf(){
}
void Werewolf::moveAround(){
cout<<"Werewolf moving around"<<endl;
}
Werewolf.h
#pragma once
#include <string>
#include "Character.h" //For inheritance/polymorphism
#include "Monster.h"
class Werewolf: public Monster{
public:
Werewolf();
void moveAround();
private:
char _token = 'W';
};
Vampire.cpp
#include <iostream>
#include <string>
#include "Vampire.h"
using namespace std;
Vampire::Vampire(){
}
void Vampire::moveAround(){
cout<<"Vampire moving around"<<endl;
}
Vampire.h
#pragma once
#include <string>
#include "Character.h" //For inheritance/polymorphism
#include "Monster.h"
class Vampire: public Monster{
public:
Vampire();
virtual void moveAround();
private:
char _token = 'V';
};
Player.cpp
Player::Player(){
}
Player.h
#pragma once
#include <string>
#include "Character.h"
using namespace std;
class Player : public Character {
public:
Player();
protected:
int _x;
int _y;
char _token = '#';
};
Main
#include <iostream>
#include "GameSystem.h"
using namespace std;
int main()
{
GameSystem gameSystem("LevelOne.txt");
gameSystem.startGame();
return 0;
}
The level text file:
############################################
#..........................................#
#..........................................#
#...........................^..............#
#..........................................#
#......................#...................#
#......................#...................#
#......................#...................#
#............^.........#...................#
#......######..........#..&................#
#......\...............#...................#
#......................#...................#
#..........................................#
#..........................................#
############################################
There is no virtual dispatch happening on _theMonsters[i].moveAround(). You need to have an array of pointers to objects of type monster. In fact, there are quite some problems in the way you try to set up the class hierarchy, like, having identically named member variables in derived classes.
There are a couple of issues here.
Monster::_token, Werewolf::_token, and Vampire::_token are all different variables. A Werewolf object has both Monster::_token and Werewolf::_token.
Monster _theMonsters[5] is an array of 5 Monster objects. It will never be a Vampire or a Werewolf, always a Monster. There is no virtual dispatch to be done since the objects will always be the same type: Monster.
Virtual dispatch only applies to pointers and references. To make this work, you'll need to use an array of pointers to Monsters: Monster* _theMonsters[5]. Then you can fill it like _theMonsters[i] = new Vampire(). If you do this, you'll need to remember to delete the objects when you're done with them, or you could use a smart pointer like std::unique_ptr or std::shared_ptr instead of raw Monster*s.

why does push_back vomit a char in the string member in of upcasted object?

i am making a rock paper & scissors game. Contains 3 classes as below:
Human class:- user puts number of games he wants to play and the choices respectively
Computer class:- Plays the same number of game as human but always plays 'ROCK'.
RandomComputer class :- Derived class of computer class, but plays Random Moves or choices.
When i pass any 2 object, a Human and Computer to Refree class it makes a decision by comparing each moves of two players.
Refree Decision method works perfect when (Human, Computer) passed BUT unexpected strange output when passed (Human,RandomComputer).
EXAMPLE:- user input: 3 R P S
output when Refree(Human A, Computer B) : Tie Win Lose
output when Refree(Human A, RandomComputer C): Lose ' ' Win
#ifndef _HUMAN_H
#define _HUMAN_H
#include <string>
#include <iostream>
using namespace std;
class Human{
public:
Human();
Human(int number, string game);
public:
int h_number;
string h_game;
};
#endif //_HUM
//=========HUMAN.CPP=====
#include "human.h"
Human::Human(int number, string game){
h_number = number;
h_game = game;
}
//========COMPUTER.h=====
#ifndef _COMPUTER_H
#define _COMPUTER_H
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Computer{
public:
Computer();
Computer(int number);
int get_c_number();
public:
string c_game;
int c_number;
};
#endif //_COMPUTER_H
//========COMPUTER.CPP=====
#include "computer.h"
Computer::Computer(){
}
Computer::Computer(int number){
c_number = number;
for(int i=0; i<c_number; i++)
{
c_game.push_back('R');
}
}
int Computer::get_c_number()
{
return c_number;
}
//=============RANDOMCOMPUTER.H========
#ifndef _RANDOMCOMPUTER_H
#define _RANDOMCOMPUTER_H
#include "computer.h"
#include <string>
#include <iostream>
#include <time.h>
#include <ctime>
#include <stdlib.h>
using namespace std;
class RandomComputer:public Computer{
public:
RandomComputer();
RandomComputer(int number);
private:
static const char r_games[3];
};
#endif //_RANDOMCOMPUTER_H
//===============RANDOMCOMPUTER.CPP=========
#include "randomcomputer.h"
const char RandomComputer::r_games[3]= {'R','P','S'};
RandomComputer::RandomComputer(){}
RandomComputer::RandomComputer(int number){
c_number = number;
srand ( time(NULL) );
for(int i=0; i<c_number; i++)
{
int RandIndex = rand() % 3;
c_game.push_back(r_games[RandIndex]);
}
}
//==============REFREE.H======
#ifndef _REFREE_H
#define _REFREE_H
#include "computer.h"
#include <iostream>
#include <string>
#include "human.h"
#include "randomcomputer.h"
using namespace std;
class Refree{
public:
Refree();
Refree (Human h_temp, Computer c_temp);
void decision();
Human *x;
Computer *y;
private:
int r_number;
string output;
};
#endif //_REFREE_H
//============REFREE.CPP========
#include "refree.h"
#include <iostream>
#include <string>
Refree::Refree(){}
Refree::Refree (Human h_temp, Computer c_temp){
x = &h_temp;
y = &c_temp;
r_number = x->h_number;
cout<<"HUMAN CHOICES: "<<x->h_game<<" COMPUTER CHOICES: "<<y->c_game<<endl;
}
void Refree::decision(){
for(int i =0; i<r_number; i++){
cout<<x->h_game[i]<<"-----------------------"<<y->c_game[i]<<endl;
}
for(int j =0; j<r_number; j++)
{
cout<<x->h_game[j]<<"---COMPARING WITH---"<<y->c_game[j]<<endl;
if(x->h_game[j] == 'R')
{
if(y->c_game[j] == 'P')
{
output.push_back('L');
output.push_back(' ');
}
else if(y->c_game[j]=='S')
{
output.push_back('W');
output.push_back(' ');
}
else if(y->c_game[j]=='R')
{
output.push_back('T');
output.push_back(' ');
}
}
else if(x->h_game[j] == 'P')
{
if(y->c_game[j] == 'P')
{
output.push_back('T');
output.push_back(' ');
}
else if(y->c_game[j]=='S')
{
output.push_back('L');
output.push_back(' ');
}
else if(y->c_game[j]=='R')
{
output.push_back('W');
output.push_back(' ');
}
}
else if(x->h_game[j] == 'S')
{
if(y->c_game[j] == 'P')
{
output.push_back('W');
output.push_back(' ');
}
else if(y->c_game[j]=='S')
{
output.push_back('T');
output.push_back(' ');
}
else if(y->c_game[j]=='R')
{
output.push_back('L');
output.push_back(' ');
}
}
}//forrr looop
size_t endpos = output.find_last_not_of(" \t");
if( string::npos != endpos )
{
output = output.substr( 0, endpos+1 );
}
cout<<output<<endl;
output.clear();
}
//============================MAIN.CPP====================
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include "human.h"
#include "computer.h"
#include "refree.h"
#include "randomcomputer.h"
using namespace std;
int main()
{
string user_input;
getline(cin, user_input);
//converting the numbers in the string to int.
int number_of_games = atoi(user_input.c_str());
//remove the digits and the spaces
user_input.erase(remove_if(user_input.begin(), user_input.end(), ::isdigit), user_input.end());
user_input.erase(remove_if(user_input.begin(), user_input.end(), ::isspace), user_input.end());
Human player_1(number_of_games, user_input); //HUMAN PLAYER OBJECT
Computer computer_1(number_of_games); // COMPUTER PLAYER TAKES ONLY innt number because it will always play ROCK in this class
Refree refree_1(player_1, computer_1);
refree_1.decision();
RandomComputer random_computer(number_of_games);
cout<<"HERE IS THE RANDOM CHOICES FROM COMPUTER AI: "<<random_computer.c_game<<endl; // make random choices instead of only ROCKS.
Refree refree_2(player_1, random_computer);
refree_2.decision();
return 0;
}
You are copying your Human and Computer object when passing them to the Referee:
Refree::Refree (Human h_temp, Computer c_temp){
You should use either const references or pointers here.