Snake Representation of the grid

498 views Asked by At

I want to code a little Snake game in C++ and I want to know what is the best way to represent the game matrix.

I could use a 2DArray (something like vector< vector< int > >) which will contain some values representing different objects (for example : 0 nothing, 1 snake, 2 wall, 3 food, ...) On the other hand, I could use no array for the grid, and use multiples arrays for the differents game objects (for example : vector< Wall >, vector < SnakeTile >, vector< Food >, ...).

Should I also consider using std::deque to represent my snake ?

Thank you for your help.

3

There are 3 answers

0
Aziuth On

Think about collision - you want to check if the snake collides with itself. Accessing a grid at the position to which the head moves is constant, searching the whole body of the snake is not. If a player is somewhat good, the snake will at some point fill most of the grid anyway, which means that there is not really any memory saved.

However: You have two other tasks at hand: Deleting the tail when the snake moves and painting the snake. For painting it, I assume that you want the player to be able to see how it wiggles, so you need an order in which the snake traverses the fields. This sounds like a queue for the positions of the snake.

We have talked about memory, but... is memory relevant in here? 400 tiles or so is nothing for a modern machine. The thing about having to search the whole body is still relevant, because that is less readable than accessing a grid tile.

Therefore, how I'd do it: Have one 2D-vector representing the grid for collisions AND a queue for the snake. Everything but the snake can be stored in the 2D-vector, if we are talking about food and walls. Go with that for now, implement it and see if problems arise, in the worst case, you will acquire experience, eh?

0
Amadeusz On

I think you shold start with writing a wrapper around std vector that provides col, row based access:

template<typename T>
class Matrix
{
private:
    std::vector<T> grid;
    size_t _cols, _rows;

public:
    Matrix(const size_t& cols, const size_t& rows) : 
        _cols(cols), _rows(rows), grid(cols*rows);
    {
    }

    T& at(const size_t& col, const size_t& row)
    {
        return grid[col + row * _cols];
    }
}

and that will represent you grid. Type T (or class) can represent Cell object that will contain all informations about cell. This way your grid data will be packed tightly ane easy to access.

You should also throughoutly think about how your Scake interacts with your Grid, and what will be the rues of that (you can't put a fruit where snake is right?). Then you can impelent these inetractions in your code and that will determine how your Grid and your Snake should exchange infromations (and which of them).

0
Phillipe Alakša On

My solution is to have a vector of a structure. i.e:

 struct item
{
    int xCoord;
    int yCoord;
    int colour; // or object
};

and declare vector<item> gridInfo;.

Then iterate through every x, y coordinate to see if there is something.

for(int y = 0; y < 10; y++)
{
    for(int x = 0; x < 10; x++)
    {
        //Display nothing
        for(auto it = gridInfo.begin(); it != gridInfo.end(); ++it)
        {
            if((*it).xCoord == x && (*it).yCoord == y)
            {
                //Display object
            }
        }
    }

No need for walls as you can check if the head of the snake goes out of bounds.