Snake Eager Game (printf output C version)

This time, we use printf output to implement a classic little game - Snake Eater. The main difficulties are how snake data is stored, how to achieve the effect of turning, how to increase the length after eating food.

1 Construct Snake

First, display a small still snake in the picture.The corresponding element of the two-dimensional array canvas[High][Width], with a value of 0 output space, -1 output border#, 1 output snake head@, and positive output snake body* greater than 1.The startup() function initializes the snake head in the middle of the canvas (canvas[High/2][Width/2] = 1;) and generates four snake bodies (for (i=1; i<=4; i+) [High/2][Width/2-i] = i+1;) to the left, with element values of 2, 3, 4, and 5, respectively.

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <conio.h>
 4 #include <windows.h>
 5           //C Language Self-Study Network
 6 #define High 20  // Game screen size
 7 #define Width 30
 8 
 9 // global variable
10 int canvas[High][Width] = {0}; // A two-dimensional array stores the corresponding elements in the game canvas
11 // 0 Is a space,-1 Is Border#1 is Snake Head@, positive number greater than 1 is Snake Body*
12 
13 void gotoxy(int x,int y)  //Move cursor to(x,y)position
14 {
15     HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
16     COORD pos;
17     pos.X = x;
18     pos.Y = y;
19     SetConsoleCursorPosition(handle,pos);
20 }
21 
22 void startup() // Data Initialization
23 {
24     int i,j;
25     
26     // Initialize Border
27     for (i=0;i<High;i++)
28     {
29         canvas[i][0] = -1;
30         canvas[i][Width-1] = -1;
31     }
32     for (j=0;j<Width;j++)
33     {
34         canvas[0][j] = -1;
35         canvas[High-1][j] = -1;
36     }
37     
38     // Initialize snake head position
39     canvas[High/2][Width/2] = 1;
40     // Initialize the snake body with element values of 2 in the canvas,3,4,5....
41     for (i=1;i<=4;i++)
42         canvas[High/2][Width/2-i] = i+1;
43 }
44 
45 void show()  // display frame
46 {
47     gotoxy(0,0);  // Move the cursor to the origin and redraw the following screen
48     int i,j;
49     for (i=0;i<High;i++)
50     {
51         for (j=0;j<Width;j++)
52         {
53             if (canvas[i][j]==0)
54                 printf(" ");   //   Output space
55             else if (canvas[i][j]==-1)
56                 printf("#");   //   Output Border#
57             else if (canvas[i][j]==1)
58                 printf("@");   //   Output Snake Head@
59             else if (canvas[i][j]>1)
60                 printf("*");   //   Output Snake Body*
61         }
62         printf("\n");
63     }
64 }    
65 
66 void updateWithoutInput()  // Updates not related to user input
67 {
68 }
69 
70 void updateWithInput()  // Updates related to user input
71 {
72 }
73 
74 int main()
75 {
76     startup();  // Data Initialization    
77     while (1) //  Game Loop Execution
78     {
79         show();  // display frame
80         updateWithoutInput();  // Updates not related to user input
81         updateWithInput();  // Updates related to user input
82     }
83     return 0;
84 }

2 Snake moves automatically

Moving the snake is a difficult point in the game of snake-eating. The following figure lists the changes of two-dimensional array element values after the snake moves to the right and up respectively, from which we can get ideas.

 

Suppose the snake element is 54321, of which 1 is the head, 5432 is the body, and the maximum 5 is the tail.Firstly, add 1 to all the elements greater than 0 to get 65432; change the maximum value 6 to 0, that is, remove the original Snake tail; and then, according to the corresponding moving direction, change the elements in the corresponding direction from 0 to 1; thus, the snake moves.The corresponding flow of the snake moving up is shown in the figure.

 

The definition variable int moveDirection represents the direction of the snake's movement, and the values 1, 2, 3, and 4 represent the upward, downward, left, and right direction of the snake's movement, which is implemented in the moveSnakeByDirection() function.

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <conio.h>
  4 #include <windows.h>
  5 //C Language Self-Study Network
  6 #define High 20  // Game screen size
  7 #define Width 30
  8 
  9 // global variable
 10 int moveDirection; // The snake's direction of movement is indicated by 1, 2, 3, 4 up, down, left and right
 11 int canvas[High][Width] = {0}; // A two-dimensional array stores the corresponding elements in the game canvas
 12             // 0 Is space 0,-1 Is Border#1 is Snake Head@, positive number greater than 1 is Snake Body*
 13 
 14 void gotoxy(int x,int y)  //Move cursor to(x,y)position
 15 {
 16     HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
 17     COORD pos;
 18     pos.X = x;
 19     pos.Y = y;
 20     SetConsoleCursorPosition(handle,pos);
 21 }
 22 
 23 // Move Snake
 24 // First Step Scan Array canvas All elements, found positive elements are+1
 25 // Find the maximum element (snake tail) and change it to zero
 26 // find=2 The corresponding pixel value is set to 1 (New Snake Head) according to the upper, lower and left directions of the output.
 27 void moveSnakeByDirection()
 28 {
 29     int i,j;
 30     for (i=1;i<High-1;i++)
 31         for (j=1;j<Width-1;j++)
 32             if (canvas[i][j]>0)
 33                 canvas[i][j]++;
 34 
 35     int oldTail_i,oldTail_j,oldHead_i,oldHead_j;
 36     int max = 0;
 37 
 38     for (i=1;i<High-1;i++)
 39         for (j=1;j<Width-1;j++)
 40             if (canvas[i][j]>0)
 41             {
 42                 if (max<canvas[i][j])
 43                 {
 44                     max = canvas[i][j];
 45                     oldTail_i = i;
 46                     oldTail_j = j;
 47                 }
 48                 if (canvas[i][j]==2)
 49                 {
 50                     oldHead_i = i;
 51                     oldHead_j = j;
 52                 }
 53             }
 54 
 55     canvas[oldTail_i][oldTail_j] = 0;
 56 
 57     if (moveDirection==1) // Move up
 58         canvas[oldHead_i-1][oldHead_j] = 1;
 59     if (moveDirection==2) // Move down
 60         canvas[oldHead_i+1][oldHead_j] = 1;
 61     if (moveDirection==3) // left
 62         canvas[oldHead_i][oldHead_j-1] = 1;
 63     if (moveDirection==4) // Move right
 64         canvas[oldHead_i][oldHead_j+1] = 1;
 65 }
 66 
 67 void startup() // Data Initialization
 68 {
 69     int i,j;
 70     
 71     // Initialize Border
 72     for (i=0;i<High;i++)
 73     {
 74         canvas[i][0] = -1;
 75         canvas[i][Width-1] = -1;
 76     }
 77     for (j=0;j<Width;j++)
 78     {
 79         canvas[0][j] = -1;
 80         canvas[High-1][j] = -1;
 81     }
 82     
 83     // Initialize snake head position
 84     canvas[High/2][Width/2] = 1;
 85     // Initialize the snake body with element values of 2 in the canvas,3,4,5....
 86     for (i=1;i<=4;i++)
 87         canvas[High/2][Width/2-i] = i+1;
 88     
 89     // Initial Snake Moves Right
 90     moveDirection = 4;    
 91 }
 92 
 93 void show()  // display frame
 94 {
 95     gotoxy(0,0);  // Move the cursor to the origin and redraw the following screen
 96     int i,j;
 97     for (i=0;i<High;i++)
 98     {
 99         for (j=0;j<Width;j++)
100         {
101             if (canvas[i][j]==0)
102                 printf(" ");   //   Output space
103             else if (canvas[i][j]==-1)
104                 printf("#");   //   Output Border#
105             else if (canvas[i][j]==1)
106                 printf("@");   //   Output Snake Head@
107             else if (canvas[i][j]>1)
108                 printf("*");   //   Output Snake Body*
109         }
110         printf("\n");
111     }
112     Sleep(100);
113 }    
114 
115 void updateWithoutInput()  // Updates not related to user input
116 {
117     moveSnakeByDirection();
118 }
119 
120 void updateWithInput()  // Updates related to user input
121 {
122 }
123 
124 int main()
125 {
126     startup();  // Data Initialization    
127     while (1) //  Game Loop Execution
128     {
129         show();  // display frame
130         updateWithoutInput();  // Updates not related to user input
131         updateWithInput();  // Updates related to user input
132     }
133     return 0;
134 }

3 Players Control Snake Movement

This step is simple to implement. Press the asdw key in the updateWithInput() function to change the value of moveDirection, and then call moveSnakeByDirection() to move the snake in different directions, as shown in the figure.

 

 1 void updateWithInput()  // Updates related to user input
 2     //C Language Self-Study Network
 3 {
 4     char input;
 5     if(kbhit())  // Determine if there is input
 6     {
 7         input = getch();  // Move by user's input without entering Enter
 8         if (input == 'a') 
 9         {
10             moveDirection = 3;   // Move Position Left
11             moveSnakeByDirection();
12         }
13         else if (input == 'd')
14         {
15             moveDirection = 4;  // Move Position Right
16             moveSnakeByDirection();
17         }
18         else if (input == 'w')
19         {
20             moveDirection = 1;  // Move Position Up
21             moveSnakeByDirection();
22         }
23         else if (input == 's')
24         {
25             moveDirection = 2;   // Position Down
26             moveSnakeByDirection();
27         }
28     }
29 }

4 Judge Game Failure

When a snake hits a border or hits itself, the game fails, as shown in the figure.

 1 void moveSnakeByDirection()
 2 //C Language Self-Study Network
 3 {
 4     int i,j;
 5     for (i=1;i<High-1;i++)
 6         for (j=1;j<Width-1;j++)
 7             if (canvas[i][j]>0)
 8                 canvas[i][j]++;
 9     int oldTail_i,oldTail_j,oldHead_i,oldHead_j;
10     int max = 0;
11     for (i=1;i<High-1;i++)
12         for (j=1;j<Width-1;j++)
13             if (canvas[i][j]>0)
14             {
15                 if (max<canvas[i][j])
16                 {
17                     max = canvas[i][j];
18                     oldTail_i = i;
19                     oldTail_j = j;
20                 }
21                 if (canvas[i][j]==2)
22                 {
23                     oldHead_i = i;
24                     oldHead_j = j;
25                 }
26             }
27     canvas[oldTail_i][oldTail_j] = 0;
28     int newHead_i,newHead_j;
29     if (moveDirection==1) // Move up
30     {
31         newHead_i = oldHead_i-1;
32         newHead_j = oldHead_j;
33     }
34     if (moveDirection==2) // Move down
35     {
36         newHead_i = oldHead_i+1;
37         newHead_j = oldHead_j;
38     }
39     if (moveDirection==3) // left
40     {
41         newHead_i = oldHead_i;
42         newHead_j = oldHead_j-1;
43     }
44     if (moveDirection==4) // Move right
45     {
46         newHead_i = oldHead_i;
47         newHead_j = oldHead_j+1;
48     }
49 
50     // Whether the snake hit itself or the border, the game failed
51     if (canvas[newHead_i][newHead_j]>0 || canvas[newHead_i][newHead_j]==-1)
52     {
53         printf("Game failed!\n");
54         exit(0);
55     }
56     else
57         canvas[newHead_i][newHead_j] = 1;
58 }

5 Eat food to increase length

Increase food, when the two-dimensional array canvas[High][Width] element value is -2, the output food value'F', as shown in the figure.When the snake head touches food, add one to the length.

 

The idea is similar to that of two small snakes, just keep the original Snake tail and do not change the maximum value to 0. The following image shows the corresponding process of snake moving up to eat food.

 

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <conio.h>
  4 #include <windows.h>
  5 //C Language Self-Study Network
  6 #define High 20  // Game screen size
  7 #define Width 30
  8 
  9 // global variable
 10 int moveDirection; // The snake moves its position, with 1, 2, 3, 4 for top, bottom, left and right
 11 int food_x,food_y; // Location of food
 12 int canvas[High][Width] = {0}; // A two-dimensional array stores the corresponding elements in the game canvas
 13     // 0 Is space 0,-1 Is Border#,-2 for food F, 1 for snake head@, positive number greater than 1 for snake body*
 14 
 15 void gotoxy(int x,int y)  //Move cursor to(x,y)position
 16 {
 17     HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
 18     COORD pos;
 19     pos.X = x;
 20     pos.Y = y;
 21     SetConsoleCursorPosition(handle,pos);
 22 }
 23 
 24 // Move Snake
 25 // First Step Scan Array canvas All elements, found positive elements are+1
 26 // Find the maximum element (snake tail) and change it to zero
 27 // find=2 The corresponding pixel value is set to 1 (New Snake Head) according to the upper, lower and left directions of the output.
 28 void moveSnakeByDirection()
 29 {
 30     int i,j;
 31     for (i=1;i<High-1;i++)
 32         for (j=1;j<Width-1;j++)
 33             if (canvas[i][j]>0)
 34                 canvas[i][j]++;
 35 
 36     int oldTail_i,oldTail_j,oldHead_i,oldHead_j;
 37     int max = 0;
 38 
 39     for (i=1;i<High-1;i++)
 40         for (j=1;j<Width-1;j++)
 41             if (canvas[i][j]>0)
 42             {
 43                 if (max<canvas[i][j])
 44                 {
 45                     max = canvas[i][j];
 46                     oldTail_i = i;
 47                     oldTail_j = j;
 48                 }
 49                 if (canvas[i][j]==2)
 50                 {
 51                     oldHead_i = i;
 52                     oldHead_j = j;
 53                 }
 54             }
 55 
 56     int newHead_i,newHead_j;
 57 
 58     if (moveDirection==1) // Move up
 59     {
 60         newHead_i = oldHead_i-1;
 61         newHead_j = oldHead_j;
 62     }
 63     if (moveDirection==2) // Move down
 64     {
 65         newHead_i = oldHead_i+1;
 66         newHead_j = oldHead_j;
 67     }
 68     if (moveDirection==3) // left
 69     {
 70         newHead_i = oldHead_i;
 71         newHead_j = oldHead_j-1;
 72     }
 73     if (moveDirection==4) // Move right
 74     {
 75         newHead_i = oldHead_i;
 76         newHead_j = oldHead_j+1;
 77     }
 78 
 79     // New snake head if it eats food
 80     if (canvas[newHead_i][newHead_j]==-2)
 81     {
 82         canvas[food_x][food_y] = 0;
 83         // Create a new food
 84         food_x = rand()%(High-5) + 2;
 85         food_y = rand()%(Width-5) + 2;
 86         canvas[food_x][food_y] = -2;
 87 
 88         // Old snake tail left, length automatic+1
 89     }
 90     else // Otherwise, the old snake tail will be reduced and the length will remain the same
 91         canvas[oldTail_i][oldTail_j] = 0;
 92 
 93     // Whether the snake hit itself or the border, the game failed
 94     if (canvas[newHead_i][newHead_j]>0 || canvas[newHead_i][newHead_j]==-1)
 95     {
 96         printf("Game failed!\n");
 97         Sleep(2000);
 98         system("pause");
 99         exit(0);
100     }
101     else
102         canvas[newHead_i][newHead_j] = 1;
103 }
104 
105 void startup() // Data Initialization
106 {
107     int i,j;
108     
109     // Initialize Border
110     for (i=0;i<High;i++)
111     {
112         canvas[i][0] = -1;
113         canvas[i][Width-1] = -1;
114     }
115     for (j=0;j<Width;j++)
116     {
117         canvas[0][j] = -1;
118         canvas[High-1][j] = -1;
119     }
120     
121     // Initialize snake head position
122     canvas[High/2][Width/2] = 1;
123     // Initialize the snake body with element values of 2 in the canvas,3,4,5....
124     for (i=1;i<=4;i++)
125         canvas[High/2][Width/2-i] = i+1;
126 
127     // Initial Snake Moves Right
128     moveDirection = 4;
129     
130     food_x = rand()%(High-5) + 2;
131     food_y = rand()%(Width-5) + 2;
132     canvas[food_x][food_y] = -2;
133 }
134 
135 void show()  // display frame
136 {
137     gotoxy(0,0);  // Move the cursor to the origin and redraw the following screen
138     int i,j;
139     for (i=0;i<High;i++)
140     {
141         for (j=0;j<Width;j++)
142         {
143             if (canvas[i][j]==0)
144                 printf(" ");   //   Output space
145             else if (canvas[i][j]==-1)
146                 printf("#");   //   Output Border#
147             else if (canvas[i][j]==1)
148                 printf("@");   //   Output Snake Head@
149             else if (canvas[i][j]>1)
150                 printf("*");   //   Output Snake Body*
151             else if (canvas[i][j]==-2)
152                 printf("F");   //   Export food F
153         }
154         printf("\n");
155     }
156     Sleep(100);
157 }    
158 
159 void updateWithoutInput()  // Updates not related to user input
160 {
161     moveSnakeByDirection();
162 }
163 
164 void updateWithInput()  // Updates related to user input
165 {
166     char input;
167     if(kbhit())  // Determine if there is input
168     {
169         input = getch();  // Move by user's input without entering Enter
170         if (input == 'a') 
171         {
172             moveDirection = 3;   // Move Position Left
173             moveSnakeByDirection();
174         }
175         else if (input == 'd')
176         {
177             moveDirection = 4;  // Move Position Right
178             moveSnakeByDirection();
179         }
180         else if (input == 'w')
181         {
182             moveDirection = 1;  // Move Position Up
183             moveSnakeByDirection();
184         }
185         else if (input == 's')
186         {
187             moveDirection = 2;   // Position Down
188             moveSnakeByDirection();
189         }
190     }
191 }
192 
193 int main()
194 {
195     startup();  // Data Initialization    
196     while (1) //  Game Loop Execution
197     {
198         show();  // display frame
199         updateWithoutInput();  // Updates not related to user input
200         updateWithInput();  // Updates related to user input
201     }
202     return 0;
203 }

6 Think Questions

1. Increase the props and increase life or slow down after eating;

2. Try to make the two-player version of the Snake Eater

Thank you for your reading, please be aware!Hope it can help you who love learning!!Sharing is also a pleasure!!!Please relay.

Tags: C network Windows

Posted on Tue, 16 Jun 2020 20:25:04 -0400 by mentalist