0

I'm developing the Nim game right now, and I'll get straight-to-the-point here. I have a function with "player1" and "player2" defined, and I want to use both of them in another function. Here's the function where they're both defined:

void ScoreKeeperInfo::welcome() {
    cout << "Welcome to the Game of Nim.\n\nWhat is your name? ";
    cin >> playerName;
    Player player1 = new PlayerInfo(playerName);
    Player player2 = new AutomatedPlayerInfo("HAL 9000", new IntermediateStrategyInfo);

    cout << "Number of wins for " << player1->getName() << ": " << numberOfWinsPlayer << endl;
    cout << "Number of wins for HAL 9000: " << numberOfWinsCPU << endl;
}

I'm attempting to use them in this function here, where it says "Game game = new GameInfo(player1, player2, state)":

void ScoreKeeperInfo::playRepeatedly() {
    int pile1 = Utils::generateRandomInt(6, 12);
    int pile2 = Utils::generateRandomInt(6, 12);
    int pile3 = Utils::generateRandomInt(6, 12);

    string userInput;

    GameState state = new GameStateInfo(pile1, pile2, pile3);

    string stateDisplay = state->toString();

    if (playerFirst == true) {
        Game game = new GameInfo(player1, player2, state);
        Player winner = game->play();
        cout << winner->getName() << " wins.\n";

I have this for a header file for this class:

class ScoreKeeperInfo {
public:
    void start();
private:
    Player player1, player2;
    int numberOfWinsPlayer = 0;
    int numberOfWinsCPU = 0;
    bool playerFirst;
    string playerName;
    void welcome();
    void flipCoin();
    void playRepeatedly();
    void restart();
};

#endif  /* SCOREKEEPER_H */

Then I used typedef for declaring the Player pointers:

typedef class MoveInfo* Move;
typedef class GameStateInfo* GameState;
typedef class PlayerInfo* Player;
typedef class AutomatedPlayerInfo* AutomatedPlayer;
typedef class StrategyInfo* Strategy;
typedef class IntermediateStrategyInfo* IntermediateStrategy;
typedef class GameInfo* Game;
typedef class ScoreKeeperInfo* ScoreKeeper;

Would I be able to get a pointer (bad pun) with where to go when I'm trying to use the player1 and player2 pointers out-of-scope? "player1->getName()" in the first function outputs exactly what I want, and I need it in the second block of code.

Thanks!

Eric206
  • 5
  • 3
  • "_when I'm trying to use the player1 and player2 pointers_" But.. Those aren't pointers.. – Algirdas Preidžius Dec 06 '19 at 01:13
  • What you've encountered is Scope. No you don't have bad breath. `Player player1` is scoped by, only exists within, the narrowest set of surrounding braces. No one outside can interact with `player1`. This is true even if you `Player * player1 = new PlayerInfo(playerName);`. The new `Player` pointed at by `player1` has a dynamic lifetime. It can outlive the scope of the variable pointing at it, but the pointer that is `player1` will still go out of scope. If nothing with a wider scope is pointing at the `Player`, that `Player` is lost and you have a memory leak. – user4581301 Dec 06 '19 at 01:54
  • 1
    Before you go all-in on pointers everywhere, please read [Why should C++ programmers minimize use of 'new'?](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new) – user4581301 Dec 06 '19 at 01:56
  • Hi. All of the "new" statements are just from a template that my professor gave me for this assignment. I'm aware of what scope is, and I've tried using the keyword static with these pointers, which didn't work. I'm unsure how he wants me to do this, since I've been told that player1 should be defined as an instance variable in the ScoreKeeper class. I'm just coming to here because I'm still really unsure of how this is supposed to work. (Pointers are difficult...) – Eric206 Dec 06 '19 at 02:00
  • That explains a lot. The `player1` and `player2` you're setting are not member variables. They are local variables that are [shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) the member variables.They are also not pointers so you cannot assign the results of `new` to them. boyanhristov96 is bang-on correct in his answer here. A note: If your instructor is requiring you to play this loose with pointers, get yourself some [supplemental reference materials](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) you can check their teachings against. – user4581301 Dec 06 '19 at 02:12

2 Answers2

0

You need to make Player be a pointer in your welcome() function like this:

Player * player1;
Player * player2;

and then in your ScoreKeeperInfo file have them as:

Player *player1, *player2;

also you need to make sure that GameInfo takes Player* parameters.

This:

    GameState state = new GameStateInfo(pile1, pile2, pile3);

    string stateDisplay = state->toString();

    if (playerFirst == true) {
        Game game = new GameInfo(player1, player2, state);
        Player winner = game->play();
        cout << winner->getName() << " wins.\n";
    }

Should be:

    GameState* state = new GameStateInfo(pile1, pile2, pile3);

    string stateDisplay = state->toString();

    if (playerFirst == true) {
        Game* game = new GameInfo(player1, player2, state);
        Player* winner = game->play();
        cout << winner->getName() << " wins.\n";
    }
bhristov
  • 2,947
  • 2
  • 7
  • 25
  • I forgot to add into the post that I already have pointers declared. I attempted what you suggested, but it left me with 30 errors. I changed the post so that it shows what I have for declared pointers already. – Eric206 Dec 06 '19 at 01:24
0

I figured out the issue. I had to remove Player from the player1 and player2 declarations.

Eric206
  • 5
  • 3