# 1 greedy snake logic statement

## 1.1 creating a snake object

Before creating the snake object, you should print a map of demo, after all, you are going to print it with the console.

```const int N = 30;  	//Map width
const int M = 81;  	//Length of map
char map[N][M];		//Map array
```

Map generate map

```void Map()
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < M - 1; j++)
{
if (i == 0 || i == N - 1 || j == 0 || j == M - 2)
map[i][j] = '*';
else
map[i][j] = ' ';
}
map[i][j] = '\n';
}
map[i][j] = '\0';
}
```

Common dos commands under the console:
system("cls"); for screen clearing
system("pause"); pause
Sleep function needs to add related header file, shortcut key Alt + Enter ()
Windows.h header files under some compilers

```void Show_map()
{
system("cls");
printf("%s", map);
Sleep(100);
}
```

Create a snake node to store the connection between the snake head and the snake body

```struct Node
{
char x;
char y;
struct Node* next;
};

```

Of course, there are many ways about snake objects. You can type the function directly, and the structure is OK. The example here is just a snake implementation.

```/*
Features: - create Snake:
@
Description:
Example: s.Create_snake(s1);
*/
void Snake::Create_snake(Node* snake)
{
srand((unsigned)time(NULL));

snake->x = rand() % 78 + 1;
snake->y = rand() % 26 + 1;
//snake->x = 40;
//snake->y = 16;
char _x = snake->x;
char _y = snake->y;
while (snake_length--[--snakeNum])
{
//snake->next = (Node*)malloc(sizeof(Node));
snake->next = new Node;
if (!(snake->next))
{
cerr << "Failed to apply for snake node" << endl;
}
else
{
//Cerr < < successfully applied for snake node < < endl;
snake = snake->next;
snake->x = _x;
snake->y = ++_y;
}
}
snake->next = NULL;
delete (snake->next);
snakeNum++;
//free(snake->next);
}
```

## 1.2 Snake Movement

The code is relatively simple, so it will not be explained. The movement here does not refer to the movement of control
Note: local variable, private member variable, often preceded by 'U' or 'm': access permission and action space

```/*
Features: - Snake move:
@
Description:
Example: s.moveUp(s1);;
*/
void Snake::Move_snake(Node* snake)
{
static char  _x, _y, _x1, _y1;
_x = snake->x;
_y = snake->y;
while (snake = snake->next)
{
_x1 = snake->x;
_y1 = snake->y;
snake->x = _x;
snake->y = _y;
_x = _x1;
_y = _y1;
}
}
```

This is the real control of movement. In fact, it doesn't need to be separated when it's done. Just put it in the switch. Continue passing snake nodes

```//Move up 'w'
void Snake::moveUp(Node* snake)
{
snake->y--;
}
//Move down's'
void Snake::moveDown(Node* snake)
{
snake->y++;
}
//Move 'a' left
void Snake::moveLeft(Node* snake)
{
snake->x--;
}
//Move right'd '
void Snake::moveRight(Node* snake)
{
snake->x++;
}
```

## 1.3 positioning of snake body

Here's how the growth of the snake's body works. The bottom moves with the skull

```/*
Functions: - body position of Snake growth:
@
Description:
Example:
*/
void Snake::Growth(char ch, Node* snake)
{
char _x = snake->x;
char _y = snake->y;
snake = snake->next;
switch (ch)
{
case 'w':
snake->x = _x;
snake->y = ++_y;
break;
case 's':
snake->x = _x;
snake->y = --_y;
break;
case 'a':
snake->x = ++_x;
snake->y = _y;
break;
case 'd':
snake->x = --_x;
snake->y = _y;
break;
default:
break;
}
snake->next = NULL;
}
```

## 1.4 hiring snake

The above logic of rolling snake needs to be printed on the map

```/*
Functions: - hire Snake:
@
Description:
Example:
*/
void Snake::Entry_snake(Node* snake)
{
Map();
map[snake->y][snake->x] = '@';
while (snake = snake->next)
map[snake->y][snake->x] = '+';
map[food.y][food.x] = '\$';
}
```

## 1.5 test the normal operation of snake object

Now test whether the snake is moving normally. Run at will to confirm whether there is any problem with the snake

```void SnakeTest()
{
Snake s;
Node* s1 = new Node;
//Node* s2 = new Node;
s.Map();
s.Create_snake(s1);

//s.Create_snake(s2);
//s.Entry_snake(s2);
s.Refresh_Food(s1);
for (int i = 0; i < 3; i++)
{
s.Move_snake(s1);
s.moveUp(s1);
s.Entry_snake(s1);
Sleep(100);
s.Show_map();
}
for (int i = 0; i < 3; i++)
{
s.Move_snake(s1);
s.moveDown(s1);
s.Entry_snake(s1);
Sleep(100);
s.Show_map();
}
for (int i = 0; i < 3; i++)
{
s.Move_snake(s1);
s.moveLeft(s1);
s.Entry_snake(s1);
Sleep(100);
s.Show_map();
}
for (int i = 0; i < 3; i++)
{
s.Move_snake(s1);
s.moveRight(s1);
s.Entry_snake(s1);
Sleep(100);
s.Show_map();
}
delete s1;
}
```

Because it's still in demo, it's all plugged into public temporarily

```#ifndef __SNAKE_H
#define __SNAKE_H

const int N = 30;  //Map width
const int M = 81;  //Length of map
//const int N = 20; / / width of map
//const int M = 61; / / length of map
//Structure of snake node
struct Node
{
char x;
char y;
struct Node* next;
};

//Structure of food
struct Food
{
char x;
char y;
};

class Snake
{
public:
Snake();
Snake(int);
~Snake();

void Create_snake(Node*);	//Create snake
void Move_snake(Node*);		//Mobile snake
void Growth(char, Node*);	//Position the new body

void moveUp(Node*);			//Upward movement
void moveDown(Node*);		//Downward movement
void moveLeft(Node*);		//Move to the left
void moveRight(Node*);		//Move to the right

void Entry_snake(Node*);	//Entry of snake

void Refresh_Food(Node*);	//Refresh food

void Map();					//Snake map
void Show_map();			//Output function

int* snake_length;			//Length of snake
int snakeNum = 1;			//Number of snakes / / no two snakes yet

Food food;					//Define the structure of food

private:

};
#endif // !__SNAKE_H
```

# 2 food

## 2.1 food structure

Food is simple, just two coordinates

```//Structure of food
struct Food
{
char x;
char y;
};
```

## 2.2 update food

Snakes update when they eat

```/*
Features: - update food:
@
Description:
Example:
*/
void Snake::Refresh_Food(Node* snake)
{
food.x = rand() % 78 + 1;
food.y = rand() % 28 + 1;
while (snake)
{
if (food.x == snake->x && food.y == snake->y)
{
Refresh_Food(snake);
}
snake = snake->next;
}
}
```

# 3 Game

I'm afraid of chaos. I'll pull out a game class directly. There's only one game in it
1) : snake initialization
2) : snake control
3) Judge whether the snake is dead

## 3.1 initialization of snake

All initialization has to do is create the snake, start refreshing a food, and refresh the map

```/*
Features: - Construction: Game()
@
Description:
Example:
*/
Game::Game()
{
snake = new Node;
s.Map();
s.Create_snake(snake);

s.Refresh_Food(snake);

s.Entry_snake(snake);
Sleep(100);
s.Show_map();
}
```

## 3.2 snake control

Get the key value of the keyboard and judge it.
Don't try to use goto. It's just convenient. You can use it directly without much code

```/*
Functions: - Snake control:
@
Description:
Example:
*/
void Game::Control()
{
while (!_kbhit());
char c = _getch();
char nextC;
z:	s.Move_snake(snake);
switch (c)
{
case 'w':	s.moveUp(snake);		break;	//Upward movement
case 's':	s.moveDown(snake);		break;	//Downward movement
case 'a':	s.moveLeft(snake);		break;	//Move to the left
case 'd':	s.moveRight(snake);		break;	//Move to the right
default:							break;
}
died(c);
s.Entry_snake(snake);	//Hiring snake
s.Show_map();			//Update map
if (_kbhit())
{
nextC = _getch();
if (nextC == 'w' || nextC == 'a' || nextC == 'd' || nextC == 's')
{
if ((nextC == 'w' && c == 's') || (nextC == 's' && c == 'w') || (nextC == 'a' && c == 'd') || (nextC == 'd' && c == 'a'))
nextC = c;
else
c = nextC;
}
}
else
nextC = c;

//Bite and die
goto z;
}
```

## 3.3 judge whether the snake is still alive

How did the snake die?
Bite yourself?
Hit a wall and die?
Is there any other way to die?
It's a single person, don't think too much. It's faster for two people to make the engine. Unit processing is much simpler than this.
Paste code directly

```/*
Function: - judge the survival of Snake:
@
Description:
Example:
*/
void Game::died(char c)
{
Node* _snake = snake;
if ((snake->x == s.food.x) && (snake->y == s.food.y))
{
while (_snake->next)
_snake = _snake->next;
_snake->next = (Node*)malloc(sizeof(Node));
s.Growth(c, _snake);
s.snake_length++;
if (s.snake_length[s.snakeNum - 1] == (N - 2) * (M - 3))
{
fprintf(stderr, "Congratulations on your success, you are so amazing!!!");
exit(EXIT_FAILURE);
}
s.Refresh_Food(snake);
return;
}
if ((snake->x == 0) || (snake->x == (M - 2)) || (snake->y == 0) || (snake->y == (N - 1)))
{
fprintf(stderr, "Why are you hitting the wall");
exit(EXIT_FAILURE);
}
while (_snake = _snake->next)
{
if (snake->x == _snake->x && snake->y == _snake->y)
{
fprintf(stderr, "you TMD What are you doing? You can't go back");
exit(EXIT_FAILURE);
}
}
}
```

```#ifndef __GAME_H
#define __GAME_H

#include "Snake.h"

class Game
{
public:
Game();
~Game();
void Control();
void died(char c);

private:
Snake s;
Node* snake;
};
#endif // !__GAME_H
```

Finally, add the following related contents to the main function

```void GameTest();

int main()
{
GameTest();
//cout << "time = " << (double)(clock()) / CLOCKS_PER_SEC << "s" << endl;
//_CrtDumpMemoryLeaks();
system("pause");
return 0;
}

void GameTest()
{
Game g1;
while (1)
{
g1.Control();
}
}
```

The operation results are as follows:

wsad: control up, down, left and right Run successfully, don't panic, I've sorted out two copies of my own source code for reference, all of which can run normally
Here's the source code of greedy snake
Greedy Snake source code  Published 3 original articles, praised 0 and visited 25

Tags: Windows Mobile

Posted on Wed, 29 Jan 2020 01:26:34 -0800 by skalooky