2

I would like the fruit class to be instantiated once and only once at one time, so there would be only one fruit object on the map. When the snake eats it, its destructor is being called and the existence flag is being set to false again. How should I implement this behaviour?

fruit.h

class Fruit {
protected:
    char fruit;
    bool exists;
    int fruitPosX;
    int fruitPosY;
public:
    Fruit();
    char getFruitType();
    int getFruitPosX();
    int getFruitPosY();
    bool getExistenceFlag();
    void setExistenceFlag(bool value);
    ~Fruit();
};

map.cpp

void Map::displayEverythingOnMap(Snake& snake){

    snakeBody* tmp = snake.firstNode;
    while (tmp != NULL) {
        gameArea[snake.getSnakePosX()][snake.getSnakePosY()] = tmp->bodyPart;
        tmp = tmp->next;
    }

    Fruit* fruit = new Fruit;
    fruit->setExistenceFlag(false);
    if (fruit->getExistenceFlag() == false) {
        gameArea[fruit->getFruitPosX()][fruit->getFruitPosY()] = fruit->getFruitType();
        fruit->setExistenceFlag(true);
        if ((fruit->getFruitPosX() == snake.getSnakePosX()) && (fruit->getFruitPosY() == snake.getSnakePosY())) {
            delete fruit;
            fruit->setExistenceFlag(false);
            snake.grow();
        }
    }
}
  • Don't do `fruit->setExistenceFlag(false);` after `delete fruit;` as it will throw an exception. Realistically you could probably do this by making your fruit a member of your `Map` class and create it and delete it as required i.e. create it upon construction of the `Map`, delete it when the snake eats it and then re-create it. Fundamentally you could probably just change the Fruit class to have a `regenerate` or `refresh` etc style of method that you can call when the snake eats the fruit which will move it around the map. – Dillanm May 08 '17 at 13:05
  • Should I use static variables instead? If yes, how should I implement that? –  May 08 '17 at 13:06
  • 7
    You mean a [singleton object](https://stackoverflow.com/questions/1008019/c-singleton-design-pattern)? –  May 08 '17 at 13:07
  • 4
    Possible duplicate of [C++ Singleton design pattern](http://stackoverflow.com/questions/1008019/c-singleton-design-pattern) – Richard Critten May 08 '17 at 13:08
  • 2
    "so there would be only one fruit object on the map" so maybe the map object should own one fruit object? – Chris Drew May 08 '17 at 13:11
  • I don't really know how to do this. Can you please help me with the implementation? –  May 08 '17 at 13:45
  • @needed See VittorioRomeo's answer which shows a `game_state` object that owns one `fruit` object. – Chris Drew May 08 '17 at 13:56

3 Answers3

7

I would like the fruit class to be instantiated once and only once at one time, so there would be only one fruit object on the map.

Stop. Having only a single instance of fruit in the map at any given time is a terrible use case for a singleton. You don't need to play around with the lifetime of the object:

  • Simply store an instance of fruit inside your "game state" class whose lifetime as a value. Its lifetime will match the game state's lifetime.

  • When the player collects the fruit, simply increase the snake's length and move the fruit somewhere else. No need to create/destroy objects.


Pseudocode:

struct game_state
{
    fruit _fruit;
    // ...

    game_state()
    {
        _fruit.position = get_random_location();
    }

    void update()
    {
        if(_player.position == _fruit.position)
        {
            grow();
            _fruit.position = get_random_location();
        }
    }
};
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
1

You want a singleton:

class Fruit {
protected:
    char fruit;
    bool exists;
    int fruitPosX;
    int fruitPosY;
public:
    static Fruit& instance();
    char getFruitType();
    int getFruitPosX();
    int getFruitPosY();
    bool getExistenceFlag();
    void setExistenceFlag(bool value);
   private:
    Fruit();
    ~Fruit();
};

Fruit& Fruit::instance() {
    static Fruit _self;
    return _self;
}

Because the constructor is private, only functions from the class can call it, and because you have only one method that can create the fruit (the instance() method) it will only create one fruit. ever.

Tomaz Canabrava
  • 2,320
  • 15
  • 20
-1

Don't.

You will only complicate your program and make a strange design, if you try to enforce that only one Fruit can exist at any one time.

Instead, simply create one Fruit and no more.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055