当前位置:网站首页>C language (circular list) to achieve the basic function of snake

C language (circular list) to achieve the basic function of snake

2020-11-09 12:58:00 osc_0tqqardd

The general idea

The coordinates of a snake are stored in a circular list , And then use it gotoxy() function ( You can position the cursor at the specified position ), At this point, according to the coordinates of the snake output “@”, More output can produce a snake . Move the snake by traversing the circular list , Insert elements to the circular list , It produces a snake lengthening effect . The following is the function of each function

1. Snake map function map()
2. The movement of the snake move(),up(),left() Such as function
3. Produce food food() And eating food eat_food()
4. The lengthening effect that snakes produce when they eat food snake_link() function
5. Judge the death of the snake , They are hitting the wall hit_wall() And suicide suicide()




1. Snake map function map()

The game map uses areas that should be closed , Take an array a[25][50], Initialize the array to 0, Assign the edge of the game wall to 1, When array is 0, Output " ", The array is 1, Output “#”, Generate a map .
The code is as follows :

void map()   // Create a map of snakes 
{
   
    
    int a[25][50] = {
   
    0};
    int i,j;
    for(i = 0; i < 50; i++)
    {
   
    
        a[0][i] = 1;
        a[24][i] =1;
    }
    for(i = 0; i < 25; i++)
    {
   
    
        a[i][0] = 1;
        a[i][49] =1;
    }
    for(i = 0; i < 25; i++)
        for(j = 0; j < 50; j++)
        {
   
    
            if(j%50 == 0)
                printf("\n");
            if(a[i][j] == 0)
            {
   
    
                printf(" ");
            }
            else
            {
   
    
                printf("#");
            }
        }
}

2. The movement of the snake move(),up(),left() Such as function

move() Function is used to change the snake's top, bottom, left and right switch Function to solve ( In the following code ch Is a global variable )
The code is as follows

void move(struct snake *p)   // The snake's moving function 
{
   
     
    while(1)
    {
   
     
        ch = getch();
        switch(ch)
        {
   
     
        case 'W':p = up(p);break;
        case 'A':p = left(p);break;
        case 'D':p = right(p);break;
        case 'S':p = down(p);break;
        }
    }
}


What makes the snake move is that we mainly change the coordinates of the snake , At this point, once the snake head moves, we use gotoxy() Function to output “@”, And then output at the tail of the snake “ ”, The effect of the snake's movement can be produced by cycling , The snake's top, bottom, left, right, and left only need to move in one direction to a single coordinate x or y Make changes , Then save the changed coordinates into the loop list . Moving functions mainly include up(),left() etc. , Because it's almost the same , It's only for up() Function
The code is as follows

struct snake *up(struct snake *p) // Move up 
{
   
     

    int x;
    int y;
    x = p->pre->x;                 // Assign snake head coordinates to x,y
    y = p->pre->y;
    while(p)                      // Traversal of a circular list , That is, the traversal of snakes 
    {
   
     
        Sleep(SNAKE_SPEED);        // The speed at which the snake moves 
        y--;                       // If you move up, you just subtract the ordinate , You can achieve the effect of the snake moving up 
        gotoxy(p->x,p->y);         // To the tail of the snake , Output “ ” The snake tail disappears 
        printf(" ");
        gotoxy(x, y);              // Position to snakehead output ,"@", Combined with the disappearance of the snake tail above, the snake head is printed again , Produces the effect of Snake Movement 
        printf("@");
        suicide(p,x,y);            // Judge whether the head of the snake hit the body of the snake 
        p = p->next;               // Change the coordinates of the snake head to the next 
        p->pre->x = x;             // At this point, change the head of the previous snake into the tail of the snake , Through continuous traversal to produce the effect of continuous movement 
        p->pre->y = y;
        food();                    // Produce food 
        eat_food(p,x,y);           // Judge whether you have food 
        hit_wall(y);               // Judge if you hit the wall 
        if(kbhit()) break;        // Determine whether there is a key input , If yes, change the direction of the snake's movement 
    }

    return p;
}


3. Produce food food() And eating food eat_food()

Food and eating food , The random number is used to produce food , Producing a food x,y Coordinates are stored in global variables food_xy[2] In an array , The use of gotoxy(food_xy[0],food_xy[1]) Randomly produce food
The code is as follows

void food()                       // Produce food 
{
   
     
    int i;
    if(!flag)                     // according to flag To determine whether there is food on the map 
    {
   
     
        srand( (unsigned)time( NULL ) );
        for( i = 0; i < 2; i++ )  // Yes food_(x,y) To assign random values to 
        {
   
     
            food_xy[i] = rand()%24+2;
            while(food_xy[0] == 1 || food_xy[0] == 25) // these two items. while To prevent food 
                food_xy[0] = rand()%24+2;             // The coordinates of the map overlap the edge of the map 
            while(food_xy[1] >= 49 || food_xy[1] == 1)
                food_xy[1] =rand()%24+2;
        }
        gotoxy(food_xy[0],food_xy[1]);  // Print food 
        printf("*");
        flag = 1;
    }
}

Eat food eat_food(), Then we just need to determine whether the snake head overlaps the coordinates of the food , If it overlaps, it means the snake has eaten food
The code is as follows

void eat_food(struct snake *p,int x, int y)           // Snakes eat food , That is, mainly for the snake head x,y Coordinates and 
{
   
                                                          //food_xy To match and compare , If they are the same, they will adjust 
    if(x == food_xy[0] && y == food_xy[1])            //snake_link Function 
    {
   
     
        p = snake_link(p);
        flag = 0;                                     // Indicates that the food was eaten , Ready to regenerate food 
        printSnake(p);
        gotoxy(8,0);
        score = score + 1;                            // score 
        printf("%d",score);
    }
}

4. The lengthening effect that snakes produce when they eat food snake_link() function

Snake's lengthening , When the snake gets the food , Now we change the coordinates of the food into the head of the snake , And then print the snake again , That is, you can have the effect of turning a snake into , The essence is to insert the elements of the circular linked list .
 Insert picture description here
In this way, the coordinates of food are inserted into the circular list , To achieve the effect of becoming a snake
The code is as follows


struct snake *snake_link(struct snake *p)      // The connection of the snake 
{
   
     
    struct snake *q;
    q = (struct snake *)malloc(sizeof(struct snake)); // That is, it mainly realizes the insertion elements of the circular linked list , Again 
    q->x = food_xy[0];                                // Print snake , You can eat the food and the snake grows longer 
    q->y = food_xy[1];
    q->pre = p->pre;
    p->pre->next = q;
    p->pre = q;
    q->next = p;
    return p;
}

5. Judge the death of the snake , They are hitting the wall hit_wall() And suicide suicide()

Against the wall , Then we only need to determine the single coordinates of the snake head x Axis or y Whether the axis is equal to the coordinates of the wall , If it's equal, it means the snake hit the wall
The code is as follows

void hit_wall(int n)       // Judge if the snake hit the wall , That's a single coordinate for the snake x perhaps y Judge , If it's equal to the value of the wall , The end of the game 
{
   
     
    if(ch == 'W'|| ch == 'S' )
        if(n == 1 || n == 25)              // The coordinates of the wall 
        {
   
     
            gotoxy(0,26);
            printf(" Game over !");
            printf(" Your score :%d",score);
            exit(0);
        }
    if(ch == 'A'|| ch == 'D' )
        if(n == 0 || n == 49)
        {
   
     
            gotoxy(0,26);
            printf(" Game over !");
            printf(" Your score :%d",score);
            exit(0);
        }
}

commit suicide suicide() Whether the head of the snake has hit the body of the snake , The way to do this is to take out the coordinates of the snake head , Compared with the coordinates of the snake, if it's equal , It means that the head of the snake hit the body of the snake , It's essentially a circular list of values to match , Traverse
The code is as follows

void suicide(struct snake *p, int x, int y) // commit suicide , That is, when you hit yourself, the game ends 
{
   
     
    struct snake *q;                         // Pass in the coordinates of the snake head , Then compare it with its own body coordinates. If it is equal, it means , The head of the snake hit the body of the snake 
    q = p;
    while(q != p->next)                      // That is, the traversal matching of the circular linked list 
    {
   
     
        if(p->x == x && p->y == y)
        {
   
     
            gotoxy(0,26);
            printf(" Game over !");
            printf(" Your score :%d",score);
            exit(0);
        }
        else
            p = p->next;
    }
}

So far, the basic functions of snakes have been discussed , Here's the whole code .


All codes are as follows

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
#define SNAKE_SPEED 200 // The speed at which the snake moves 
int score = 0;         // Scores 
int flag = 0;          // Used to determine if there is food on the map ,0 For there is no food 
int food_xy[2];         // Positioning food 
char ch;               // Used to determine the direction of the snake's movement 
struct snake   // The snake that defines a circular list 
{
   
      
    int x;
    int y;
    struct snake *next;
    struct snake *pre;
};

void HideCursor()// Hide the cursor when the snake moves , Hide cursor function 
{
   
      
	CONSOLE_CURSOR_INFO cursor;
	cursor.bVisible = FALSE;
	cursor.dwSize = sizeof(cursor);
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorInfo(handle, &cursor);
}

void gotoxy(int x, int y)   // Positioning cursor function , To move the snake , And the emergence of food ( delivery x,y You can position the cursor to x,y)
{
   
      
    HideCursor();
    COORD coord = {
   
      x,y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

void map()   // Create a map of snakes 
{
   
      
    int a[25][50] = {
   
      0};
    int i,j;
    for(i = 0; i < 50; i++)
    {
   
      
        a[0][i] = 1;
        a[24][i] =1;
    }
    for(i = 0; i < 25; i++)
    {
   
      
        a[i][0] = 1;
        a[i][49] =1;
    }
    for(i = 0; i < 25; i++)
        for(j = 0; j < 50; j++)
        {
   
      
            if(j%50 == 0)
                printf("\n");
            if(a[i][j] == 0)
            {
   
      
                printf(" ");
            }
            else
            {
   
      
                printf("#");
            }
        }
}

struct snake *createSnake()   // Initialize the snake , Build a snake , The essence is a circular list 
{
   
      
    int i;
    struct snake *head,*p,*q;
    p = q = (struct snake *)malloc(sizeof(struct snake));
    head = NULL;
    head = p;
    head->pre = NULL;
    for( i = 0; i < 5; i++)
    {
   
      
        p->x = 25 - i;
        p->y = 13;
        p->pre = head->pre;
        head->pre = p;
        q->next = p;
        q = p;
        p = (struct snake *)malloc(sizeof(struct snake));
    }
    q->next = head;
    return head;

}

void printSnake(struct snake *p)   // Print snake , utilize gotoxy() To print snakes , The coordinates can be visualized as a snake by traversing the circular list once 
{
   
      
    struct snake *q;
    q = p;
    while(q != p->next)             // Loop list traversal 
    {
   
      
        gotoxy(p->x,p->y);          // According to the coordinates and positioning cursor function to type @, Realize the output snake 
        printf("@");
        p = p->next;
    }
    gotoxy(p->x,p->y);
    printf("@");
    gotoxy(0,0);
    printf(" Your score :");          // Initialization score 
}

void food()                       // Produce food 
{
   
      
    int i;
    if(!flag)                     // according to flag To determine whether there is food on the map 
    {
   
      
        srand( (unsigned)time( NULL ) );
        for( i = 0; i < 2; i++ )  // Yes food_(x,y) To assign random values to 
        {
   
      
            food_xy[i] = rand()%24+2;
            while(food_xy[0] == 1 || food_xy[0] == 25) // these two items. while To prevent the coordinates of the food from overlapping the edges of the map 
                food_xy[0] = rand()%24+2;
            while(food_xy[1] >= 49 || food_xy[1] == 1)
                food_xy[1] =rand()%24+2;
        }
        gotoxy(food_xy[0],food_xy[1]);  // Print food 
        printf("*");
        flag = 1;
    }
}

struct snake *snake_link(struct snake *p)      // The connection of the snake 
{
   
      
    struct snake *q;
    q = (struct snake *)malloc(sizeof(struct snake)); // That is, it mainly realizes the insertion elements of the circular linked list , Then print the snake , You can eat the food and the snake grows longer 
    q->x = food_xy[0];
    q->y = food_xy[1];
    q->pre = p->pre;
    p->pre->next = q;
    p->pre = q;
    q->next = p;
    return p;
}

void eat_food(struct snake *p,int x, int y)           // Snakes eat food , That is, mainly for the snake head x,y Coordinates and food_xy To match and compare , If the same is called snake_link Function 
{
   
      
    if(x == food_xy[0] && y == food_xy[1])
    {
   
      
        p = snake_link(p);
        flag = 0;
        printSnake(p);
        gotoxy(8,0);
        score = score + 1;
        printf("%d",score);
    }
}

void hit_wall(int n)       // Judge if the snake hit the wall , That's a single coordinate for the snake x perhaps y Judge , If it's equal to the value of the wall , The end of the game 
{
   
      
    if(ch == 'W'|| ch == 'S' )
        if(n == 1 || n == 25)
        {
   
      
            gotoxy(0,26);
            printf(" Game over !");
            printf(" Your score :%d",score);
            exit(0);
        }
    if(ch == 'A'|| ch == 'D' )
        if(n == 0 || n == 49)
        {
   
      
            gotoxy(0,26);
            printf(" Game over !");
            printf(" Your score :%d",score);
            exit(0);
        }
}


void suicide(struct snake *p, int x, int y) // commit suicide , That is, when you hit yourself, the game ends 
{
   
      
    struct snake *q;                         // Pass in the coordinates of the snake head , Then compare it with its own body coordinates. If it is equal, it means , The head of the snake hit the body of the snake 
    q = p;
    while(q != p->next)                      // That is, the traversal matching of the circular linked list 
    {
   
      
        if(p->x == x && p->y == y)
        {
   
      
            gotoxy(0,26);
            printf(" Game over !");
            printf(" Your score :%d",score);
            exit(0);
        }

        else
            p = p->next;
    }
}

struct snake *up(struct snake *p) // Move up 
{
   
      

    int x;
    int y;
    x = p->pre->x;                 // Assign snake head coordinates to x,y
    y = p->pre->y;
    while(p)                      // Traversal of a circular list , That is, the traversal of snakes 
    {
   
      

        Sleep(SNAKE_SPEED);        // The speed at which the snake moves 
        y--;                       // If you move up, you just subtract the ordinate , You can achieve the effect of the snake moving up 
        gotoxy(p->x,p->y);         // To the tail of the snake , Output “ ” The snake tail disappears 
        printf(" ");
        gotoxy(x, y);              // Position to snakehead output ,"@", Combined with the disappearance of the snake tail above, the snake head is printed again , Produces the effect of Snake Movement 
        printf("@");
        suicide(p,x,y);            // Judge whether the head of the snake hit the body of the snake 
        p = p->next;               // Change the coordinates of the snake head to the next 
        p->pre->x = x;             // At this point, change the head of the previous snake into the tail of the snake , Through continuous traversal to produce the effect of continuous movement 
        p->pre->y = y;
        food();                    // Produce food 
        eat_food(p,x,y);           // Judge whether you have food 
        hit_wall(y);               // Judge if you hit the wall 
        if(kbhit()) break;        // Determine whether there is a key input , If yes, change the direction of the snake's movement 
    }

    return p;


}

struct snake *left(struct snake *p) // Move to the left 
{
   
      
    int x;
    int y;
    x = p->pre->x;
    y = p->pre->y;
    while(p)
    {
   
      

        Sleep(SNAKE_SPEED);
        x--;
        gotoxy(p->x,p->y);
        printf(" ");
        gotoxy(x, y);
        printf("@");
        suicide(p,x,y);
        p = p->next;
        p->pre->x = x;
        p->pre->y = y;
        food();
        eat_food(p,x,y);
        hit_wall(x);
        if(kbhit()) break;
    }
    return p;
}

struct snake *down(struct snake *p)  // Move down the 
{
   
      
    int x;
    int y;
    x = p->pre->x;
    y = p->pre->y;
    while(p)
    {
   
      

        Sleep(SNAKE_SPEED);
        y++;
        gotoxy(p->x,p->y);
        printf(" ");
        gotoxy(x, y);
        printf("@");
        suicide(p,x,y);
        p = p->next;
        p->pre->x = x;
        p->pre->y = y;
        food();
        eat_food(p,x,y);
        hit_wall(y);
        if(kbhit()) break;
    }
    return p;
}

struct snake *right(struct snake *p)   // To the right 
{
   
      
    int x;
    int y;
    x = p->pre->x;
    y = p->pre->y;
    while(p)
    {
   
      

        Sleep(SNAKE_SPEED);
        x++;
        gotoxy(p->x,p->y);
        printf(" ");
        gotoxy(x, y);
        printf("@");
        suicide(p,x,y);
        p = p->next;
        p->pre->x = x;
        p->pre->y = y;
        food();
        eat_food(p,x,y);
        hit_wall(x);
        if(kbhit()) break;
    }
    return p;


}
void move(struct snake *p)   // The snake's moving function 
{
   
      
    while(1)
    {
   
      
        ch = getch();
        switch(ch)
        {
   
      
        case 'W':p = up(p);break;
        case 'A':p = left(p);break;
        case 'D':p = right(p);break;
        case 'S':p = down(p);break;
        }
    }
}
int main()
{
   
      
    struct snake *p;
    map();      // Generating maps 
    p = createSnake(); //  Initialize snake 
    printSnake(p);   //  Print snake 
    move(p);        // Move the snake 

    return 0;
}

版权声明
本文为[osc_0tqqardd]所创,转载请带上原文链接,感谢