Beautify the greedy snake (EasyX)

Didn’t I write about
Snakes last time? I don’t think it’s good enough. I learned EasyX and decided to beautify him and reconstruct the function. The
general idea is to draw the grid first, and then decide the size of the map. This is the snake’s movement route.
Then you can use the enumeration direction to deal with the snake head in the direction of turning or something. To increase the length is to add the number of snakes. Here I am processing the snake into a structure.
Other ideas are roughly the same. Look at the code for details. Just cross the line.
Look at the code.

#define _CRT_SECURE_NO_WARNINGS
//因为我用的是VS2019,这里取消一下安全性检查(这里代码都是c++了昂)
#include<graphics.h>
//EasyX的库
#include <conio.h>
//随机函数
#include<stdio.h>
#include<time.h>
enum dir{
    
    left,right,up,down};
bool ai = false;
//描述一个点
struct point {
    
    
	int x;
	int y;
};
//蛇的结构体
struct snake {
    
    
	struct point xy[100];
	int num;
	char position;
}bigsnake;
//展示分数用
int score = 0;
void drawline() {
    
    
//这里的函数是设置线的颜色,然后规定窗口大小,然后画线
	setlinecolor(RGB(232, 232, 236));
	rectangle(0, 0, 800, 600);
	for (int x = 0; x <= 800; x += 10) {
    
    
		for (int y = 10; y <= 600; y += 10) {
    
    
			line(x, 0, x, 600);
			line(0, y, 800, y);
		}
	}
}
//初始化蛇
void initSnake() {
    
    
	bigsnake.num = 3;
	bigsnake.position = right;
	for (int i = bigsnake.num - 1; i >= 0; i--) {
    
    
		bigsnake.xy[i].x = 10 *( (bigsnake.num - 1) - i);
		bigsnake.xy[i].y = 20;
	}
}
//画蛇
void drawSnake() {
    
    
	for (int i = 0; i < bigsnake.num; i++)
	{
    
    
		//设置颜色
		setlinecolor(BLACK);
		//设置填充的颜色,随机颜色变成大彩蛇,非常银杏
		setfillcolor(RGB(rand() % 256, rand() % 256, rand() % 256));
		fillrectangle(bigsnake.xy[i].x, bigsnake.xy[i].y, bigsnake.xy[i].x+10, bigsnake.xy[i].y+10);
	}
}
//移动蛇的函数,这里唯一要理解的就是这个枚举类型,其他的就是将前一个的位置付给下一个就能实现移动
void movesnake() {
    
    
	for (int i = bigsnake.num - 1; i>0 ; i--)
	{
    
    
		bigsnake.xy[i].x = bigsnake.xy[i-1].x;
		bigsnake.xy[i].y = bigsnake.xy[i-1].y;
	}
	switch (bigsnake.position)
	{
    
    
	case left:
		bigsnake.xy[0].x -= 10;
		break;
	case right:
		bigsnake.xy[0].x += 10;
		break;
	case up:
		bigsnake.xy[0].y -= 10;
		break;
	case down:
		bigsnake.xy[0].y += 10;
		break;
	}
}
//异步函数不用多说
void keydown() {
    
    
	if (GetAsyncKeyState('W') || GetAsyncKeyState(VK_UP) && bigsnake.position != down) {
    
    
		bigsnake.position = up;
	}
	if (GetAsyncKeyState('S') || GetAsyncKeyState(VK_DOWN) && bigsnake.position != up) {
    
    
		bigsnake.position = down;
	}
	if (GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT) && bigsnake.position != right) {
    
    
		bigsnake.position = left;
	}
	if (GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT) && bigsnake.position != left) {
    
    
		bigsnake.position = right;
	}
	if (GetAsyncKeyState('R')) system("pause");
	if (GetAsyncKeyState('T')) ai = true;
	if (GetAsyncKeyState('Y')) ai = false;
}
//描述食物
struct sfood {
    
    
	struct point xy;
	int flag;
}food;
//这里是实现了自动吃的模块,就是一个简单的计算,自行理解,这个不是真的就是万能的,本人太菜了并不能实现高级的算法
void keyDownAI()
{
    
    
	if (food.xy.x > bigsnake.xy[0].x && bigsnake.position != left)
	{
    
    
		bigsnake.position = right;
	}
	else if (food.xy.x < bigsnake.xy[0].x && bigsnake.position != right)
	{
    
    
		bigsnake.position = left;
	}
	else if (food.xy.y > bigsnake.xy[0].y && bigsnake.position != up)
	{
    
    
		bigsnake.position = down;
	}
	else if (food.xy.y < bigsnake.xy[0].y && bigsnake.position != down)
	{
    
    
		bigsnake.position = up;
	}
}
//初始化食物
void initfood() {
    
    
	food.xy.x = rand() % 80 * 10;
	food.xy.y = rand() % 60 * 10;
	int flag = 1;
	while (flag)
	{
    
    
		flag = 0;
		for (int i = 0; i < bigsnake.num; i++)
		{
    
    
			if (bigsnake.xy[i].x == food.xy.x && bigsnake.xy[i].y == food.xy.y)
			{
    
    
				flag = 1;
				food.xy.x = rand() % 80 * 10;
				food.xy.y = rand() % 60 * 10;
			}
		}
	}
	food.flag = 1;
}
//画食物跟前面一样的
void drawFood()
{
    
    
	setlinecolor(BLACK);
	setfillcolor(RGB(rand() % 256, rand() % 256, rand() % 256));
	fillrectangle(food.xy.x, food.xy.y, food.xy.x + 10, food.xy.y + 10);
}
//吃食物事件
void eatfood() {
    
    
	if (food.xy.x == bigsnake.xy[0].x && food.xy.y == bigsnake.xy[0].y) {
    
    
		bigsnake.num++;
		food.flag = 0;
		score += 10;
	}
}
//显示分数,里面的函数自己可以百度一下
void showscore(int x, int y, int score) {
    
    
	//设置模式
	setbkmode(TRANSPARENT);
	//设置字体颜色,不要问我为什么绿
	settextcolor(GREEN);
	//楷体,十五格高,宽度为零表示自适应
	settextstyle(15, 0, "楷体");
	char scoreStr[20] = "";
	sprintf(scoreStr, "分数:%d", score);
	outtextxy(x, y, scoreStr);
}
//撞墙的事件
bool hitboard() {
    
    
	if (bigsnake.xy[0].x < 0 || bigsnake.xy[0].y < 0 || bigsnake.xy[0].x + 10>800 || bigsnake.xy[0].y + 10>600) {
    
    
		return true;
	}
	return false;
}
bool hitsnake()
{
    
    
	for (int i = 1; i < bigsnake.num; i++)
	{
    
    
		if (bigsnake.xy[0].x == bigsnake.xy[i].x && bigsnake.xy[0].y == bigsnake.xy[i].y)
			return true;
	}
	return false;
}
//主函数
int main() {
    
    
	srand((unsigned int)time(NULL));
	HWND hwnd = initgraph(800, 600);
	setbkcolor(WHITE);//背景颜色设置
	cleardevice();//清空界面
	initSnake();//初始化蛇
	food.flag = 0;//食物默认不存在,之后初始化就存在了
	while (1) {
    
    
		BeginBatchDraw();//开始画画的函数,必须声明
		cleardevice();//清屏
		drawline();
		if (food.flag == 0) {
    
    
			initfood();
		}
		if (hitboard()) {
    
    
			MessageBox(hwnd, "撞到墙了","GAMEOVER", MB_OK);
			break;
		}
		if (hitsnake()) {
    
    
			MessageBox(hwnd,"撞到蛇身了","GAMEOVER",MB_OK);
			break;
		}
		if (ai) keyDownAI();
		drawFood();
		showscore(0, 10, score);
		eatfood();
		movesnake();
		keydown();
		drawSnake();
		EndBatchDraw();
	}
	closegraph();//关掉画
	return 0;
}

The following renderings:
Insert picture description here

Actually it works quite well, and it is a big improvement in life.
That's it for Konjac, the source code is moved away, and everything is fine.

Guess you like

Origin blog.csdn.net/lspdd/article/details/113062056