4

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() {
}
Dreamer
  • 112
  • 1
  • 14
  • 6
    Possible duplicate of [Resolve header include circular dependencies](http://stackoverflow.com/questions/625799/resolve-header-include-circular-dependencies) – drescherjm Jan 08 '17 at 14:43
  • try using pragma once or something like that. since Engine.h includes Player.h and Player.h includes Engine.h there might be some collisions here. – eran otzap Jan 08 '17 at 14:43
  • 1
    @eranotzap: He has perfectly good include guards that don't depend on implementation dependant behaviour. The problem is that when he include player.h, it includes engine.h, which tries to include player.h - but actually does nothing. At that pointer engine.h tries to use class player - but it isn't declared. – Martin Bonner supports Monica Jan 08 '17 at 14:45
  • 1
    Unrelated : You should make `players` vector a vector of `std::unique_ptr`. That way, all objects are deleted when the vector is destroyed. Currently, you're leaking everything. – Unimportant Jan 08 '17 at 14:48
  • @MartinBonner firstly didn't notice the protection guards. i'm new to c++ didn't get the issue you described . can we go over it again ? player.h -> engine.h -> tries player.h but is not included because of the protection guard and does not know of any Player class. so how would she be able to use Player in Engine ? – eran otzap Jan 08 '17 at 14:57
  • I notice that despite `Player` having proper getters and setters for its members, `Engine` is accessing the private variables directly. That forces `Player` to declare `Engine` as a friend which is then why Player.h includes Engine.h... But if the getters and setters were to be used as intended in all cases (generally considered better anyway) then no friend relation is needed and so Player doesn't need to include Engine.h which would also eliminate the circular include problem. – TheUndeadFish Jan 08 '17 at 16:38

1 Answers1

4

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.

tinkertime
  • 2,972
  • 4
  • 30
  • 45
  • could you show how you would do this . i didn't get the second point. how could she infect use Player in Engine ? – eran otzap Jan 08 '17 at 14:56
  • 1
    second point is suggesting that in Engine.h she replace the line `#include "Player.h"` with `class Player.h`. – tinkertime Jan 08 '17 at 15:00
  • 2
    @eranotzap: If you say "class Player;", that *declares* the class, but doesn't *define* it. Once you have declared a class, you can use pointers to the class, and references - but you can't have actual objects of the class. class Engine only contains pointers, so it is fine. (Obviously, the member functions of Engine are going to need a full definition of Player, which is why you include it in the .cpp) – Martin Bonner supports Monica Jan 08 '17 at 15:03