C语言:贪吃蛇

作业要求:  

    用CC++语言实现一个贪食蛇小游戏,游戏规则如下:

  1. 有一个正方形围墙(大小自己定义),蛇只能在围墙中活动。
  2. 食物会在墙中任何位置随机生成,每次蛇吃到了食物,食物将换一个位置随机出现。
  3. 蛇的初始长度为6个单位长度,每次吃一次食物,蛇的长度+1
  4.  玩家有一个游戏分数,初始为0分,蛇每吃到一次+10分。
  5. 每隔一秒,蛇会自动朝着当前前进方向前进一个单位。
  6. 键盘“上下左右”可以改变蛇的运动方向,如果玩家按下的方向键与蛇的前进方向一致则加速蛇的前进。
  7. 蛇头如果咬到自己或碰到墙游戏结束。

因临近期末,时间紧迫,所以先放出完整代码,等到时间充裕之时,再进行分析

  1 /*********************************************************************************************************
  2 Filename    : 贪吃蛇.cpp
  3 Autor       : KongSu
  4 Date        : 2021/12
  5 License     : The Unlicensed
  6 Description : 大一上实验三,用C语言写出贪吃蛇 
  7 **********************************************************************************************************/ 
  8  
  9  /* Includes ********************************************************************************************/
 10  #include <stdio.h>
 11  #include <windows.h>
 12  #include <conio.h>
 13  #include <stdlib.h>
 14  #include <time.h>
 15  /* End Includes ****************************************************************************************/
 16 
 17 /* Defines ********************************************************************************************/
 18 #define FOODSCORE 10
 19 #define MAPSIZE 30
 20 #define UP 72
 21 #define DOWN 80
 22 #define LEFT 75
 23 #define RIGHT 77     
 24 /* End Defines ****************************************************************************************/
 25 
 26 /* Global Variables **********************************************************************************/
 27  int FoodX = 100;
 28  int FoodY = 100;
 29  int score = 0;
 30  int key = RIGHT; //初始向右移动 
 31 /* End Global Variables ******************************************************************************/
 32 
 33 /* 表示蛇的结构体 */
 34 struct snake
 35 {
 36     int len;    //蛇的长度 
 37     int speed;    //蛇的速度 
 38     int x[MAPSIZE*MAPSIZE];        //蛇的每一部分的X坐标 
 39     int y[MAPSIZE*MAPSIZE];        //蛇的每一部分的Y坐标
 40 }snake;
 41  
 42 /* Begin Function : gotoxy ****************************************************************************
 43  Descroption : 定位光标,使输出内容指定一个位置 
 44  Input       : 坐标
 45  Output      : None 
 46 *******************************************************************************************************/
 47 void gotoxy(int x, int y)
 48 {
 49     COORD crd = {x, y};
 50     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), crd);
 51     return; 
 52 }
 53  /* End Function : gotoxy ****************************************************************************/
 54  
 55  /* Begin Function : HideCursor *********************************************************************
 56  Descroption : 隐藏光标 
 57  Input       : None
 58  Output      : None 
 59  ****************************************************************************************************/
 60 void HideCursor()
 61 {
 62     CONSOLE_CURSOR_INFO cursor;    
 63     cursor.bVisible = FALSE;    
 64     cursor.dwSize = sizeof(cursor);    
 65     HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);    
 66     SetConsoleCursorInfo(handle, &cursor);
 67 }
 68 /* End FUnction : HideCursor *************************************************************************/
 69  
 70 /* Begin Function : color ***************************************************************************
 71  Descroptio : 改变文字颜色
 72  Input      : 颜色代号
 73  Output     : None  
 74 ****************************************************************************************************/
 75  void color(short x)
 76  {
 77      SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
 78      return;
 79  }
 80  /*End Function : color ****************************************************************************/
 81  
 82 /* Begin Function : GameDescriptions ****************************************************************
 83  Descroption : 说明游戏规则 
 84  Input       : None 
 85  output      : 游戏说明,即4条游戏规则        
 86 ******************************************************************************************************/
 87  void GameDescriptions()
 88  {
 89      gotoxy(88, 12);        //定位"游戏规则"位置
 90     color(14);  
 91      printf("游戏规则");
 92      gotoxy(65, 14);        //定位游戏规则部分上边框 
 93     color(7);     
 94      for(int i = 1; i <= 27; i++)
 95      {
 96          printf(" =");    //游戏规则部分上边框 
 97     }
 98     
 99     gotoxy(78, 16);         //定位四条游戏规则,改变颜色并输出
100     color(14);                            
101     printf("1. 用键盘上下左右控制蛇的移动。");
102     gotoxy(78, 18);
103     printf("2. 吃到一次食物得10分,蛇身增长。");
104     gotoxy(78, 20);
105     printf("3. 咬到自己即游戏结束。");
106     gotoxy(78, 22);
107     printf("4. 碰到墙壁即游戏结束。");
108     
109     gotoxy(65, 24);        //定位游戏规则部分下边框
110     color(7);
111     for(int i = 1; i <= 27; i++)
112     {
113         printf(" =");    //游戏规则部分下边框
114     }
115     return; 
116  }
117 /* End Function : Game Descriptions ******************************************************************/
118 
119 /* Begin Function : CreatMap ************************************************************************
120  Descriptiion : 打印地图 
121  Input        : None
122  Output       : 地图 
123 *****************************************************************************************************/
124  void CreatMap()
125  {    
126      for(int i = 2; i < MAPSIZE * 2 + 2; i += 2)    //打印地图上下边框 
127      {
128         gotoxy(i, 0);
129          printf("");
130          gotoxy(i, MAPSIZE+1);
131          printf(""); 
132     }
133     for(int i = 0; i < MAPSIZE + 2; i++)        //打印地图左右边框
134     {
135         gotoxy(0, i);
136          printf("");
137          gotoxy(MAPSIZE*2+2, i);
138          printf("");         
139     }
140     for(int i = 2; i < MAPSIZE * 2 + 2; i += 2)    //打印地图 
141     {
142         for(int j = 1; j <= MAPSIZE; j++)
143         {
144             color(2);
145             gotoxy(i, j);
146             printf("");
147         }
148     }
149     return;
150  } 
151 /* End Function : CreatMap **************************************************************************/
152 
153 /* Begin FUnction : InitSnake **********************************************************************
154 Descripition : 初始化蛇
155 Input        : None
156 Output       : 一条长为6的蛇 
157 ****************************************************************************************************/ 
158 void InitSnake()
159 {
160     snake.len = 6;         //初始化蛇的长度 
161     snake.speed = 100;    //初始化蛇的速度 
162     snake.x[0] = MAPSIZE + 2;    
163     snake.y[0] = ( MAPSIZE + 2 ) / 2;    //初始化蛇的坐标 
164     gotoxy(snake.x[0], snake.y[0]);
165     color(6);
166     printf("");       //打印蛇头 
167     for(int i = 1; i < snake.len; i++)
168     {
169         snake.x[i] = snake.x[i - 1] - 2;
170         snake.y[i] = snake.y[i - 1];
171         gotoxy(snake.x[i], snake.y[i]);
172         printf("");
173     }                    //打印蛇身 
174 }
175 /* End Function : InitSanke ***********************************************************************/
176  
177 /* Begin Function : CreatFood ***********************************************************************
178 Description : 生成随机食物 
179 Input       : None
180 OUtput      : 随机输出食物 
181 *****************************************************************************************************/
182 void CreatFood()
183 {
184     gotoxy(FoodX, FoodY);
185     color(2);
186     printf("");
187     int flag;
188     do
189     {
190         flag = 0;
191         srand ((unsigned int)time(NULL));
192         FoodX = rand() % (2*MAPSIZE-2)+2;        //随机生成坐标 
193         FoodY = rand() % (MAPSIZE-1)+1;
194         for(int i = 1; i < snake.len; i++)
195         {
196             if(FoodX == snake.x[i] && FoodY == snake.y[i]) //防止食物生成在蛇身上 
197             {
198                 flag = 1;
199             }
200         } 
201     }
202     while(flag);
203     if(FoodX & 1)  //如果FoodX为奇数,输出的食物只有半个 
204     {
205         FoodX++;    //使FoodX为偶数 
206     } 
207     gotoxy(FoodX, FoodY);
208     color(4);
209     printf("");
210     return;
211 }
212 /* End Function : CreatFood *************************************************************************/
213 
214 /* Begin Function : Gameover ************************************************************************
215 Description : 游戏失败时输出Game over!和分数 
216 Input       : 分数 
217 Outout      : 输出 Game over!和分数 
218 *****************************************************************************************************/
219 void GameOver(int score)
220 {
221     system("cls");
222     color(4);
223     gotoxy(49,15);
224     printf("Game Over!");
225     gotoxy(45,16);
226     printf("你的最终分数是:%d",score);
227     gotoxy(45,18);
228     color(7);
229     system("pause");
230     return; 
231 }
232 /* End Function : GameOver **************************************************************************/
233 
234 /* Begin Function : moveSnake **********************************************************************
235 Description : 根据key进行移动    
236 Input       : 按键对应的key
237 Output      : None
238 ****************************************************************************************************/
239 void moveSanke()
240 {
241     
242     while(1)
243     {
244         if(kbhit()) //按键操控蛇的方向 
245         {
246             int oldKey = key;  //记录之前的方向 
247             key = getch();
248             key = getch();
249             if(oldKey == key)
250             {
251                 snake.speed = 60; //按下相同键速度增加 
252             }
253             else if(oldKey != key)
254             {
255                 snake.speed = 100;    //回到初始速度 
256                 if(oldKey == LEFT && key == RIGHT)  //不能反向移动 
257                 {
258                     key = LEFT;
259                 }
260                 else if(oldKey == RIGHT && key == LEFT)
261                 {
262                     key = RIGHT;
263                 }
264                 else if(oldKey == UP && key == DOWN)
265                 {
266                     key = UP;
267                 }
268                 else if(oldKey == DOWN && key == UP)
269                 {
270                     key = DOWN;
271                 }
272             } 
273         }
274         int oldx,oldy;    //用于记录头原本的位置,在下面更新蛇的每一部分时使用 
275         switch(key)        //根据key对蛇头进行移动 
276         {
277             case LEFT:
278                 oldx = snake.x[0];
279                 oldy = snake.y[0];
280                 snake.x[0] -= 2;
281                 break;
282             case RIGHT:
283                 oldx = snake.x[0];
284                 oldy = snake.y[0];
285                 snake.x[0] += 2;
286                 break;
287             case UP:
288                 oldx = snake.x[0];
289                 oldy = snake.y[0];
290                 snake.y[0]--;
291                 break;
292             case DOWN:
293                 oldx = snake.x[0];
294                 oldy = snake.y[0];
295                 snake.y[0]++;
296                 break;
297             default:
298                 break;                
299         }
300         Sleep(snake.speed);             //控制蛇的速度 
301         if(snake.x[0] == MAPSIZE * 2 + 2 || snake.x[0] == 0 ||snake.y[0] == MAPSIZE + 1 || snake.y[0] == 0) 
302         {
303             GameOver(score);    //碰到墙壁,Game Over!
304             return;
305         }
306         else if(snake.x[0] == FoodX && snake.y[0] == FoodY)                //碰到食物 
307         {        
308             snake.len++;         //蛇身增长 
309             score += FOODSCORE;  //得分增加 
310             for(int i = snake.len - 1; i > 1; i--)        //更新蛇除头外的每一部分的坐标 
311             {
312                 snake.x[i] = snake.x[i - 1];
313                 snake.y[i] = snake.y[i - 1];
314             }            
315             snake.x[1] = oldx;
316             snake.y[1] = oldy;
317             CreatFood();        //创建新的随机食物
318             gotoxy(snake.x[0], snake.y[0]);
319             color(6);
320             printf("");     //打印蛇头    
321         } 
322         else
323         {    
324             for (int i = 1; i < snake.len; i++)                     //碰到身体 ,Game Over!
325             {
326                 if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i])
327                 {
328                     GameOver(score);
329                     return;
330                 }
331             }
332             gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);        //去掉蛇尾 
333             color(2);
334             printf("");
335             for(int i = snake.len - 1; i > 1; i--)       //更新蛇除头外的每一部分的坐标
336             {
337                 snake.x[i] = snake.x[i - 1];
338                 snake.y[i] = snake.y[i - 1];
339             }
340             snake.x[1] = oldx;
341             snake.y[1] = oldy;
342             gotoxy(snake.x[0], snake.y[0]);
343             color(6);
344             printf("");     //打印蛇头 
345         }
346         gotoxy(87,6);
347         color(14);
348         printf("当前分数:%d  ",score);  //每次移动更新分数 
349     }
350 }
351 /* End Function : moveSnake ************************************************************************/
352  
353 /* Begin Function : main *****************************************************************************
354  Description : The entry of the program
355  Input       :    None
356  Output      : int - Rrturns a value to the OS
357 ******************************************************************************************************/
358  int main()
359  {    
360      system("mode con cols=120 lines=32"); 
361      HideCursor(); 
362      GameDescriptions();
363      CreatMap();
364      InitSnake();
365      CreatFood();
366      moveSanke();
367      return 0;
368  }
369 /* End Function : main *******************************************************************************/

 

posted @ 2021-12-20 23:00  空速  阅读(142)  评论(0)    收藏  举报