Quick snake algorithm?

When making a snake game how could I make sure that the snake body follows the head?

So far my algorithm put my snake body in an struct array that stores the coordinates an direction. I'm planning to update my snake (make it move), by starting from the snake's tail and letting it read the direction of the bock above it which would theoretically make the snake move.

Would this work? This my plan so far and I'm not sure if it will work (note: I've got other runtime debugging issues I'm currently dealing with, which why I can't test it. But I just hope my work isn't in vain).

1
2
3
4
5
6
typedef struct 
{
int i_X;
int i_Y;
unsigned char uc_DIR;
}SSnake_body;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//void Update_Direction(int newdir){for(){}}




void addnewblock(int * imaxsnake)
{
////////////////////////////////////////////
//INITIALISE FIRST SNAKE_BLOCK
if (*imaxsnake == 0)
{
snake_[*imaxsnake].i_X = 50;
snake_[*imaxsnake].i_Y = 50;
snake_[*imaxsnake].uc_DIR = right_dir;
}
else
{
//////////////////////////////////////////

if ((*imaxsnake +1) < SNAKE_MAXLENGTH)
{
/////////////////////////////////////////////////////////
*imaxsnake++;
snake_[*imaxsnake];
//copysnake previous snakeblock
Copy_Snakeblock(*imaxsnake, (*imaxsnake-1));
/////////////////////////////////////////////////////////
}
else 
{
return;
}
}
}

void Copy_Snakeblock(int irecieve, int icopyfrom)
{
//copy direction
//snake must be a "SNAKE_BLOCK_SIZE" back (hence the opposite +/-)
snake_[irecieve].uc_DIR = snake_[icopyfrom].uc_DIR;
if      (snake_[irecieve].uc_DIR == left_dir)
{snake_[irecieve].i_X += SNAKE_BLOCK_SIZE;}
else if (snake_[irecieve].uc_DIR == right_dir)
{snake_[irecieve].i_X -= SNAKE_BLOCK_SIZE;}
else if (snake_[irecieve].uc_DIR == up_dir)
{snake_[irecieve].i_Y += SNAKE_BLOCK_SIZE;}
else if (snake_[irecieve].uc_DIR == down_dir)
{snake_[irecieve].i_Y -= SNAKE_BLOCK_SIZE;}
}
Just set the n'th body part equal the (n+1)'th body part.

i.e. array contains snake position as [1,2,3,4,5]

Head moves to 6.

1->2
2->3
3->4
4->5
So the other elements just copy the block above them?
Exactly; that's the characteristic of the "snake": at every step, each body part moves to the location of the body part in front of it. Since they are stored linearly (block i is in front of block i+1), you just copy upward.
The easiest way I can think to do it would be to keep a list full of body objects that contain the grid coordinates for each body part. As it moves, the head's coordinates move in the current direction, and then each piece behind the head takes the coordinates of the piece in front of it. For example, the piece behind the head takes the head's previous coordinates, and so on.
Might be fun to experiment with a "moving array": instead of setting each block position to that of the block in front of it (block[i].position = block[i+1].position, or something similar), you move the snake's position in the array.

Imagine you have a snake of 6 blocks. Rather than having your head at block[0] and your tail at block[size-1], your snake moves through the array as well.

For example, a 1piece snake could start at the last block of the array. Then, when you add a piece, the head moves to the block in front of its old position, and its old position now becomes the memory block for the next snake piece. This works, because your head will move to a new location and the second block will be on the head's old location.

Next, if you make a move, then every piece i moves to the location of the i-1'th piece. Rather than copying (complexity O(size)), you just conceptually move the snake in memory: piece i is now on the old memory location of piece i-1, which still contains the old coordinates of piece i-1. The head gets a new memory location (it's the only piece that gets new coordinates) and the last block (old location of the tail) is cleared.

Seems very easy to implement using a deque: push_front the new head data and pop_back the old tail data [unless a new piece was added!].
1
2
3
4
5
6
7
8
 struct SSnake_body
{
int i_X;
int i_Y;
SSnake_body * next;
//don't know what do uc_DIR
unsigned char uc_DIR;
};
Topic archived. No new replies allowed.