C language simple greedy snake learning

Keywords: Mobile Attribute C

Just finished learning C language, I want to write a small project to consolidate the basic knowledge and lay a solid foundation for the next step of learning. Then I began to look for projects that can be done in the major websites and blogs, and finally I chose the snake eating game, most of which are called library functions, without the use of chain tables, pointers and other more complex knowledge points.

Code directly!

#define _CRT_SECURE_NO_WARNINGS / / prevent compilation errors
#include<stdio.h>
#Include < graphics. H > / / according to Easy graphics library
#include<conio.h>
#include<time.h>
#include<stdlib.h>
typedef struct point
{
	int x;
	int y;
}mypoint;

//Attributes of snake
struct Snake
{
	mypoint xy[100];        //The longest snake body is 100 knots
	int num;                //Length of snake
	char position;          //direction
}snake;

//The nature of food
struct Food
{
	mypoint fdxy;
	int flag;
	int grade;
}food;

//Window handle
HWND hwnd = NULL;

//Direction enumeration
enum position{up,down,left,right};

//Initialize snake
void initSnake()
{
	snake.xy[2].x = 0;
	snake.xy[2].y = 0;

	snake.xy[1].x = 10;
	snake.xy[1].y = 0;

	snake.xy[0].x = 20;			//Initialize coordinates
	snake.xy[0].y = 0;

	snake.num = 3;				//Initialization length

	snake.position = right;		        //Initialization direction
}

//Draw a snake
void drawSnake()
{
	for (int i = 0; i < snake.num; i++)
	{
		setlinecolor(BLUE);    //Rectangle border color
		setfillcolor(RED);     //Rectangle square color
		fillrectangle(snake.xy[i].x, snake.xy[i].y, snake.xy[i].x + 10, snake.xy[i].y + 10);//Determine the coordinates of the upper left corner and the lower right corner draw a rectangle
	}
}

//Moving snake
void moveSnake()
{
	for (int i = snake.num - 1; i > 0; i--) //Forward and backward position exchange to realize movement
	{
		snake.xy[i].x = snake.xy[i-1].x;
		snake.xy[i].y = snake.xy[i - 1].y;
	}
	switch (snake.position)               //Moving direction setting
	{
	case up:
		snake.xy[0].y -= 10;
		break;
	case down:
		snake.xy[0].y += 10;
		break;
	case left:
		snake.xy[0].x -= 10;
		break;
	case right:
		snake.xy[0].x += 10;
	}
}
//Mobile control
void keyDown()
{
	char key = _getch();  //Get key value
	switch (key)
	{
	case 'w':
	case 'W':
	case 72:
		if (snake.position != down)
			snake.position = up;
		break;
	case 's':
	case 'S':
	case 80:
		if (snake.position != up)
			snake.position = down;
		break;
	case 'a':
	case 'A':
	case 75:
		if (snake.position != right)
			snake.position = left;
		break;
	case 'd':
	case 'D':
	case 77:
		if (snake.position != left)
			snake.position = right;
		break;
	}
}
//Initialize food
void initFood()
{
	srand((unsigned int)time(NULL));	//Random seed
	food.fdxy.x = rand() % 80 * 10;		//Determine the range of random occurrence
	food.fdxy.y = rand() % 60 * 10;
	food.flag = 1;						//Food appearance sign
	for (int i = 0; i < snake.num; i++)	//Judge whether the snake coincides with the food. If it coincides, it will regenerate
	{
		if (food.fdxy.x == snake.xy[i].x&&food.fdxy.y == snake.xy[i].y)
		{
			food.fdxy.x = rand() % 80 * 10;
			food.fdxy.y = rand() % 60 * 10;
		}
	}
}
//Draw the food
void drawFood()		
{
	setlinecolor(BLUE);		//Set rectangular border line
	setfillcolor(BLUE);		//Set rectangle color
	fillrectangle(food.fdxy.x, food.fdxy.y, food.fdxy.x + 10, food.fdxy.y + 10);
}

//Snake eating food: the coordinate between food and snake head
void eatFood()
{
	if (snake.xy[0].x == food.fdxy.x&&snake.xy[0].y == food.fdxy.y)
	{
		food.flag = 0;		//Clear the food mark
		snake.num++;		//Snake length plus one
		food.grade += 10;   //Score plus 10
	}
}
//Show scores
void showGread()
{
	char grade[100] = "";
	sprintf(grade, "fraction:%d", food.grade);
	setbkmode(TRANSPARENT);		//Set text type to transparent
	settextcolor(LIGHTBLUE);	//Set text color to light blue
	outtextxy(650, 30, grade);	//Specific position of text display
}
//game over
//1. The position of snake head is beyond the range of frame
//2. The position of snake head and body coincide
int endSnake()
{
	if (snake.xy[0].x < 0 || snake.xy[0].x>800 || snake.xy[0].y < 0 || snake.xy[0].y>600)
	{
		MessageBox(hwnd, "Hit the wall, the game is over!", "game over", 0);
		return 1;
	}
	for (int i = 1; i < snake.num; i++)
	{
		if (snake.xy[0].x == snake.xy[i].x&&snake.xy[0].y == snake.xy[i].y)
		{
			MessageBox(hwnd, "Suicide, game over!", "game over", 0);
			return 1;
		}
	}
	return 0;
}

int main()
{
	//Draw window
	hwnd=initgraph(800, 600);
	setbkcolor(WHITE);			//Set the window background to white
	cleardevice();				//Refresh interface
	initSnake();
	while (1)
	{
		cleardevice();//Refresh interface
		drawSnake();
		moveSnake();
		eatFood();
		showGread();
		drawFood();

		//Quit at the end of the game
		if (endSnake()){
			break;
			exit(0);
		}

		//Produce new food only when it's eaten
		if (food.flag == 0){
			initFood();
		}

		//Read whether the keyboard is pressed
		if (_kbhit()){
			keyDown();
		}

		//set speed
		Sleep(150);
	}
	_getch();		//Prevent screen flicker    
	closegraph();   //Turn off graphic display mode
	return 0;
}


Some difficulties encountered:

1. compiler error

It's a compiler problem. Add it above the code

#define _CRT_SECURE_NO_WARNINGS 

2. Compile attribute error


 

Right click to open select properties - > General - > character set

Change character set to use multi character character character set

In addition, there are some delays in the process of the game. I hope you can answer them!

 

 

At the end:

Easy-x official website: https://easyx.cn/downloads/

The operation of the 2018 vernal equinox is relatively simple

Posted by loki1664 on Wed, 20 May 2020 08:33:06 -0700