Teach you to make your own version of C language snake!

Snake?
That's right. It's snake eating. You don't know that. Then you must be wondering, can you write greedy snake in code? Of course, today I will teach you to write a greedy snake of your own!
What you need to prepare is: a certain knowledge of linked list, CodeBlocks (the best use of the software, or it may not succeed), like it, pay attention to a wave ~ ~ there are good things in the future, I will continue to share!

Design thinking
First, you need to print out the background. The functions needed here are described below. Then randomly generate the head of the snake, generate the body of the snake according to the head of the snake, print out the whole snake, and generate the food (make sure not to overlap with the snake), so the first step is completed. Next, the main step is to move the snake and eat. What I use here is to clear the snake body first, and then print it to the position after moving. It's the same with eating. The direction control of snake needs keyboard control.

Calling function
void Menu();    //Initialization menu
void Gotoxy(int x, int y);    //Cursor location
void GotoChange(int x, int y);   //Change ■ to space
void GotoPrint(int x, int y);    //Go to (x,y) print ■
void CreatWall();    //Build a fence
void CreatSnake();    //Initialize build snake
void PrintBody();    //Print snake body
void Initialization();    //Initialization interface
void CreatFood();    //Generate random food
int Control();    //Control snake
int Judge();    //End of judgement
void MovingBody();   //Mobile snake
void ChangeBody(int x, int y);   //Snake change
void Eating();    //Snake "eating"
void End();    //End page
  //The more difficult and important functions are as follows:
gotoxy()Function -->Portal
Control()Li_kbhit()->Portal
Control()Li_getch()->Portal
//Unlisted discoloration function SetConsoleTextAttribute -- > Portal

Code implementation:

#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<time.h>
#include<conio.h>

#define up 'w'
#define down 's'
#define left 'a'
#define right 'd'
#define stop 'p'

typedef struct snake
{
    int x, y;
    struct snake *next;
}SNAKE;

void Menu();       //Initialization menu
void Gotoxy(int x, int y);      //Cursor location
void GotoChange(int x, int y);     //Change ■ to space
void GotoPrint(int x, int y);       //Go to (x,y) print ■
void CreatWall();       //Build a fence
void CreatSnake();        //Initialize build snake
void PrintBody();       //Print snake body
void Initialization();      //Initialization interface
void CreatFood();       //Generate random food
int Control();     //Control snake
int Judge();        //End of judgement
void MovingBody();      //Mobile snake
void ChangeBody(int x, int y);      //Snake change
void Eating();      //Snake "eating"
void End();     //End page

char name[66];
int speed = 50, score = 0, co;
SNAKE *head, *tail;
int food_x, food_y;
char input = 1;

int main()
{
    Menu();
    CreatWall();
    CreatSnake();
    Initialization();
    CreatFood();
	if(Control() == 0)
        return 0;
    return 0;
}

void Menu()
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
| FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    Gotoxy(40, 16);
    printf("Welcome to the snake game~~~\n");
    Gotoxy(40, 17);
    printf("Please enter your user name:");
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    scanf("%s", name);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
| FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    Gotoxy(40, 19);
    printf("Please select the difficulty of the game:\n\
           \t\t\t\t\t1:Xiao Bai mode\n\
           \t\t\t\t\t2:Normal mode (recommended)\n\
           \t\t\t\t\t3:Difficult mode\n\
           \t\t\t\t\t4:Limit mode\n\
           \t\t\t\t\t5:Abnormal mode\n\
           \t\t\t\t\t6:Adventure mode\n\t\t\t\t\t");
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    scanf("%d", &co);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE);
    if(co > 0 && co < 6)
        speed *= (6-co);
    else
        speed = 300;
	system("cls");
	Gotoxy(42, 14);
	printf("Loading~~~\n");
    Gotoxy(20, 16);
    printf("Tips:\n");
    Gotoxy(24, 18);
    printf("Please operate in English input method. Reverse movement is equivalent to eating yourself, wasd control p suspend\n");
    Gotoxy(36, 20);
    printf("\t Full screen game is better~~~");
    Sleep(3000);
    system("cls");
}
void Gotoxy(int x, int y)
{
    COORD pos = {x, y};
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);      // Get standard output device handle
    SetConsoleCursorPosition(hOut, pos);        //The two parameters respectively specify which form and specific location
}
void GotoPrint(int x, int y)
{
    Gotoxy(x, y);
    printf("■");
}
void GotoChange(int x, int y)
{
    Gotoxy(x, y);
    printf(" ");
}
void CreatWall()
{
    int i, j;
    for (i = 0; i < 36; i++)
    {
        for(j = 0; j < 72; j += 2)
        {
            if(i == 0 || i == 35 || j == 0 || j == 70)
                printf("■");
            else
                printf("  ");
        }
        printf("\n");
    }
}
void CreatSnake()
{
    srand((unsigned)time(NULL));
    head = (SNAKE*)malloc(sizeof(SNAKE));
	head->x = rand()%30+3;
	if(head->x % 2 != 0)
    {
        head->x++;
    }
	head->y = rand()%30+3;
	tail = (SNAKE*)malloc(sizeof(SNAKE));
	SNAKE *p = (SNAKE*)malloc(sizeof(SNAKE));
	SNAKE *q = (SNAKE*)malloc(sizeof(SNAKE));
	p->x = head->x;
	p->y = head->y+1;
	q->x = head->x;
	q->y = head->y+2;
	head->next = p;
	p->next = q;
	q->next = tail;
    tail->next = NULL;
}
void PrintBody()
{
    SNAKE *t = head;
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    GotoPrint(t->x, t->y);
    t = t->next;
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
	while(t->next != NULL)
    {
        GotoPrint(t->x, t->y);
        t = t->next;
    }
    Gotoxy(0, 36);
}
void Initialization()
{
	PrintBody();
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    Gotoxy(128, 2);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE);
    printf("p:(start/suspend)");
    Gotoxy(120, 3);
    printf("If the snake hits a wall or body while it's moving");
    Gotoxy(120, 4);
    printf("Cross (snake head hits his body) end of game");
    Gotoxy(100, 12);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    printf("%s", name);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE);
    printf(",Come on come on~~~");
    Gotoxy(100, 18);
    printf("Your current score is:");
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    Gotoxy(116, 18);
    printf("%d", score);
    Gotoxy(100, 24);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE);
    printf("Author:");
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    printf("ChrisPhantom");
}
void CreatFood()
{
    lable:
	food_y = rand()%(34) + 1;
	food_x = rand()%(67) + 2;
	if (food_x % 2 != 0)
	{
		food_x = food_x + 1;
	}
	SNAKE *t = head;
	while(1)       //Traverse to eliminate snake body repetition
	{
		if(t->next == NULL)
            break;
		if(food_x == t->x && food_y == t->y)
		{
			goto lable;
		}
		t = t->next;
	}
	Gotoxy(food_x, food_y);
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
	printf("⊙");
}
int Control()
{
	while (1)
	{
		if (Judge() == 0)
            return 0;
		if (_kbhit())
		{
			input = _getch();
		}
		MovingBody();
		Eating();
	}
	return 1;
}
int Judge()
{
    if (head->x == 0 || head->x == 70 || head->y == 0 || head->y == 35)     //Bump into the wall
    {
        End();
        return 0;
    }
	SNAKE *p = head->next;
	while (1)
	{
		if (p->next == NULL)
            break;
		if (head->x == p->x && head->y == p->y)     //Body crossing
        {
            End();
            return 0;
        }
		p = p->next;
	}
	return 1;
}
void MovingBody()       //Realize animation effect by first clearing and then printing
{
    int x = head->x, y = head->y;
	SNAKE *p = head;
	while (1)
	{
		if (p->next == NULL)
            break;
		GotoChange(p->x, p->y);
		p = p->next;
	}
	switch (input)
	{
		case up:
			head->y -= 1;
			ChangeBody(x, y);
			break;
		case down:
			head->y += 1;
			ChangeBody(x, y);
			break;
		case left:
			head->x -= 2;
			ChangeBody(x, y);
			break;
		case right:
			head->x += 2;
			ChangeBody(x, y);
			break;
		case stop:
			break;
	}
	PrintBody();
	Sleep(speed);
}
void ChangeBody(int x, int y)
{
    SNAKE *p = head->next;
	int mid1, mid2, tmid1, tmid2;
	mid1 = p->x;
	mid2 = p->y;
	while (1)
	{
		if (p->next->next == NULL)
            break;
		tmid1 = p->next->x;
		tmid2 = p->next->y;
		p->next->x = mid1;
		p->next->y = mid2;
		mid1 = tmid1;
		mid2 = tmid2;
		p = p->next;
	}
	p = head->next;
	//if (p->next!= NULL)
	{
		p->x = x;
		p->y = y;
	}
}
void Eating()
{
    if (head->x == food_x && head->y == food_y)
	{
	    printf("\a");
		CreatFood();
		SNAKE *t = (SNAKE*)malloc(sizeof(SNAKE));
		SNAKE *p;
		p = head;
		while (1)
		{
			if (p->next->next == NULL)
                break;
			p = p->next;
		}
		p->next = t;
		t->next = tail;
		score += 10;
		if(co == 6 && speed > 40)
        {
            speed -= 20;
        }
		Gotoxy(116, 18);
		HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
		printf("%d", score);
	}
}
void End()
{
    system("cls");
    Gotoxy(56, 14);
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    printf("%s,", name);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE);
    printf("Your score is:");
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    printf("%d", score);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE);
    Gotoxy(56, 16);
    if(score <= 30)
        printf("Don't be discouraged. Keep going ~_~");
    else if(score <= 70)
        printf("You're already pretty good. Can you be better @_@");
    else if(score <=120)
        printf("You're so awesome. You've surpassed most people ^_^");
    else
        printf("Do you?...You are the legend dalao !_!");
    Gotoxy(48, 19);
    printf("Author:");
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
    printf("ChrisPhantom(That's right it's me ChrisPhantom I myself.,Manual comic)");
    Gotoxy(48, 20);
    SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE);
    printf("If you like it, give me a compliment~~~");
    Gotoxy(48, 22);
	system("pause");
}

Reference material
https://blog.csdn.net/qq_40935723/article/details/86553391
https://blog.csdn.net/qq_40953281/article/details/79315254
https://mbd.baidu.com/newspage/data/error
Because some of the code notes are not explained in detail, you can consult privately if you don't understand. If you like, please like it.

If you feel that this code is regular enough but not clear about the specification, you can check another post "C language code specification" – > Portal

Thank you for visiting, not skilled, please do not make complaints about it. Please leave a message if you have any questions.

Published 15 original articles, won praise 21, visited 3257
Private letter follow

Tags: Mobile Windows C

Posted on Tue, 17 Mar 2020 05:39:39 -0400 by webdes03