1

In a snake game, I have two classes defined in seperate files: Snake and Map (a game map, not the usual container).

This is a simplified Map implementation:

#include "Snake.hpp"

using Coordinates = std::pair<std::size_t, std::size_t>;

class Map
{
   public:
    Map(Coordinates dimensions);
    void generateFruit(const Snake &);

   private:
    friend class Snake;
    const Coordinates m_dimensions;
    std::unordered_set<Coordinates, boost::hash<Coordinates>> m_fruit_positions;
};

generateFruit generates a fruit at a random position in the map, and it can't place a fruit where the snake exists, which means it needs to know where the snake is, hence the argument Snake.

And this is a simplified Snake implementation:

#include "Map.hpp"

class Snake
{
   public:
    enum class Orientation
    {
        Up,
        Down,
        Left,
        Right
    };
    Snake(const Map &);
    bool isAlive(const Map &) const;
    void move(Map &);
    void turn(Orientation);

   private:
    std::deque<Coordinates> s_snake;
    Orientation s_orientation;
};

Most methods in Snake require a Map for bounds checking.

What's the best way to resolve this dependency?

EDIT: Forward declaring any class causes incomplete type errors.

  • 1
    `Map` only needs a reference to Snake, so it doesn't need a full include. Remove the `#include "Snake.hpp"` and forward declare. That said, map's in the same position. Just pick one. – user4581301 Jan 16 '19 at 00:33
  • 1
    That edit about "incomplete type errors" cries out for further explanation, and perhaps a [minimal complete example](https://stackoverflow.com/help/mcve). – Beta Jan 16 '19 at 00:34
  • 3
    Make sure that in the cpp files you're actually including the headers you need. But the headers themselves can just forward declare. – Kevin Jan 16 '19 at 00:38
  • @Beta forward declaring `class Snake` in `Map.hpp` or `class Map` in `Snake.hpp` is fine, but the compiler doesn't allow accessing members of the forward declared class, which I need to do in `generateFruit` and all the methods that require a `Map` in the `Snake` implementation. –  Jan 16 '19 at 00:41
  • Extra recommendations: **1** Always include matching header file first from the source file. **2** Minimize `#include` in the header file when appropriate to reduce compile-time dependencies. – Phil1970 Jan 16 '19 at 00:42
  • @Kevin Including `Snake.hpp` in `Map.cpp` instead of in `Map.hpp`, as you suggested, along with a `class Snake` forward declaration in `Map.hpp` seemed to fix the issue. Thank you. –  Jan 16 '19 at 00:53

0 Answers0