三木社区

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 334|回复: 0
打印 上一主题 下一主题

贪吃蛇游戏-Snake.c

[复制链接]

1562

主题

1564

帖子

4904

积分

博士

Rank: 8Rank: 8

积分
4904
跳转到指定楼层
楼主
发表于 2017-9-1 10:10:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include "Snake.h"  
  2.   
  3.   
  4. pSnake head = NULL; //定义蛇头指针  
  5. pSnake Food = NULL; //定义食物指针  
  6.   
  7. int sleeptime = 500;//间隔时间,用来控制速度  
  8. int Score = 0;  //总分  
  9. int everyScore = 1; //每步得分  
  10.   
  11. //定义游戏中用到的符号  
  12. const char food = '#';  
  13. const char snake = '*';  
  14.   
  15. void Pos(int x, int y)   //控制输出光标  
  16. {  
  17.     COORD pos;  //pos为结构体  
  18.     pos.X = x;  //控制列  
  19.     pos.Y = y;  //控制行  
  20.     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);//读取标准输出句柄来控制光标为pos  
  21. }  
  22.   
  23. void Face()  
  24. {  
  25.     system("color 0C");  
  26.     printf("*******************************************************\n");  
  27.     printf("*                Welcome to Snake Game!               *\n");  
  28.     printf("*                                                     *\n");  
  29.     printf("*             ->开始游戏请按 enter键                  *\n");  
  30.     printf("*             ->退出游戏请按 esc键                    *\n");  
  31.     printf("*             ->暂停游戏请按 space键                  *\n");  
  32.     printf("*             ->通过上下左右键来控制蛇的移动          *\n");  
  33.     printf("*             ->通过F1键减速        F2键加速          *\n");  
  34.     printf("*******************************************************\n");  
  35. }  
  36. void Map()   //初始化地图  
  37. {  
  38.     int i = 0;  
  39.     for(i = 0; i<COL_MAP; i+=2)   //打印上下边框(每个■占用两列)  
  40.     {  
  41.         Pos(i, 0);  
  42.         printf("■");  
  43.         Pos(i, ROW_MAP-1);  
  44.         printf("■");  
  45.     }  
  46.     for(i = 0; i<ROW_MAP; i++)   //打印左右边框  
  47.     {  
  48.         Pos(0, i);  
  49.         printf("■");  
  50.         Pos(COL_MAP-2, i);  
  51.         printf("■");  
  52.     }  
  53. }  
  54. void PrintSnake()  //打印蛇  
  55. {  
  56.     pSnake cur = head;  
  57.     while(cur)  
  58.     {  
  59.         Pos(cur->y, cur->x);  
  60.         printf("%c", snake);  
  61.         cur = cur->next;  
  62.     }  
  63. }  
  64. void InitSnake()    //初始化蛇身  
  65. {  
  66.     int initNum = 3;  
  67.     int i = 0;  
  68.     pSnake cur;  
  69.     head = (pSnake)malloc(sizeof(Snake));  
  70.     head->x = 5;  
  71.     head->y = 10;  
  72.     head->next = NULL;  
  73.   
  74.     cur = head;  
  75.     for(i = 1; i < initNum; i++)  
  76.     {  
  77.         pSnake newNode = (pSnake)malloc(sizeof(Snake));  
  78.         newNode->x = 5+i;  
  79.         newNode->y = 10;  
  80.         newNode->next = NULL;  
  81.         cur->next = newNode;  
  82.         cur = cur->next;  
  83.     }  
  84.   
  85.     PrintSnake();  
  86. }  
  87.   
  88. void CreateFood()  //在地图上随机产生一个食物  
  89. {  
  90.     pSnake cur = head;  
  91.     Food = (pSnake)malloc(sizeof(Snake));  
  92.   
  93.     //产生x~y的随机数 k=rand()%(Y-X+1)+X;  
  94.     srand((unsigned)time(NULL));  
  95.     Food->x = rand()%(ROW_MAP-2 - 1 + 1)+1;  
  96.     Food->y = rand()%(COL_MAP-3 - 2 + 1)+2;  
  97.     Food->next = NULL;  
  98.     while(cur)   //检查食物是否与蛇身重合  
  99.     {  
  100.         if(cur->x == Food->x && cur->y == Food->y)  
  101.         {  
  102.             free(Food);  
  103.             Food = NULL;  
  104.             CreateFood();  
  105.             return;  
  106.         }  
  107.         cur = cur->next;  
  108.     }  
  109.     Pos(Food->y, Food->x);  
  110.     printf("%c", food);  
  111. }  
  112.   
  113. void StartGame()  //游戏开始的所有设置  
  114. {  
  115.     Face();  
  116.     system("pause");  
  117.   
  118.     if(GetAsyncKeyState(VK_RETURN))  
  119.     {  
  120.         system("cls");  
  121.         Pos(COL_MAP+5, 1);  
  122.         printf("当前分数/通关分数:");  
  123.         Pos(COL_MAP+20, 1);  
  124.         printf("%d/%d", Score, SUCCESS_SCORE);  
  125.         Pos(COL_MAP+5, 2);  
  126.         printf("当前分每步得分:");  
  127.         Pos(COL_MAP+20, 2);  
  128.         printf("%d", everyScore);  
  129.         Pos(COL_MAP+5, 3);  
  130.         printf("\n");  
  131.         Pos(COL_MAP+5, 4);  
  132.         printf("速度越快 得分越高哦!!\n");  
  133.   
  134.         Map();  
  135.         InitSnake();  
  136.         CreateFood();  
  137.     }  
  138.     else if(GetAsyncKeyState(VK_ESCAPE))  
  139.     {  
  140.         exit(0);  
  141.     }  
  142. }  
  143.   
  144. int IsCrossWall()             //判断是否碰到墙  
  145. {  
  146.     if(head->x <= 0 || head->x >= ROW_MAP-1  
  147.         ||head->y <= 1 || head->y >= COL_MAP-2)  
  148.     {  
  149.         State = ERROR_WALL;  
  150.         return 0;  
  151.     }  
  152.     return 1;  
  153. }  
  154.   
  155. int IsEatSelf(pSnake newHead)  //判断是否咬到自己  
  156. {  
  157.     pSnake cur = head;  
  158.     assert(newHead);  
  159.     while(cur)  
  160.     {  
  161.         if(cur->x == newHead->x && cur->y == newHead->y)  
  162.         {  
  163.             State = ERROR_SELF;  
  164.             return 0;  
  165.         }  
  166.         cur = cur->next;  
  167.     }  
  168.     return 1;  
  169. }  
  170.   
  171. int IsFood(pSnake pos)  //判断该位置是不是食物  
  172. {  
  173.     assert(pos);  
  174.     if(pos->x == Food->x && pos->y == Food->y)  
  175.     {  
  176.         return 1;  
  177.     }  
  178.     return 0;  
  179. }  
  180.   
  181. void SnakeMove()   //蛇移动一次  
  182. {  
  183.     pSnake newHead = NULL;  
  184.     newHead = (pSnake)malloc(sizeof(Snake));  
  185.   
  186.     if(Direction == R)  
  187.     {  
  188.         newHead->x = head->x;  
  189.         newHead->y = head->y+1;  
  190.         newHead->next = head;  
  191.     }  
  192.     else if(Direction == L)  
  193.     {  
  194.         newHead->x = head->x;  
  195.         newHead->y = head->y-1;  
  196.         newHead->next = head;  
  197.     }  
  198.     else if(Direction == U)  
  199.     {  
  200.         newHead->x = head->x-1;  
  201.         newHead->y = head->y;  
  202.         newHead->next = head;  
  203.       
  204.     }  
  205.     else if(Direction == D)  
  206.     {  
  207.         newHead->x = head->x+1;  
  208.         newHead->y = head->y;  
  209.         newHead->next = head;  
  210.     }  
  211.   
  212.     if(IsFood(newHead))  
  213.     {  
  214.         head = newHead;  
  215.         PrintSnake();  
  216.         CreateFood();  
  217.         Score += everyScore;  
  218.         Pos(COL_MAP+20, 1);  
  219.         printf("%d/%d", Score, SUCCESS_SCORE);  
  220.         if(Score >= SUCCESS_SCORE)  
  221.         {  
  222.             State = SUCCESS;  
  223.         }  
  224.     }  
  225.     else   
  226.         {  
  227.             if(IsCrossWall() && IsEatSelf(newHead))  
  228.             {  
  229.                 pSnake cur = NULL;  
  230.                 head = newHead;  
  231.                 cur = head;  
  232.                 //删除蛇尾并打印  
  233.                 while(cur->next->next != NULL)  
  234.                 {  
  235.                     Pos(cur->y, cur->x);  
  236.                     printf("%c", snake);  
  237.                     cur = cur->next;  
  238.                 }  
  239.                   
  240.                 Pos(cur->y, cur->x);  
  241.                 printf("%c", snake);  
  242.                 Pos(cur->next->y, cur->next->x);  
  243.                 printf(" ");  //打印空格来覆盖频幕上的蛇尾  
  244.                 free(cur->next);  
  245.                 cur->next = NULL;  
  246.             }  
  247.             else  
  248.             {  
  249.                 free(newHead);  
  250.                 newHead = NULL;  
  251.             }  
  252.     }  
  253. }  
  254.   
  255. void Pause()  
  256. {  
  257.     while(1)  
  258.     {  
  259.         Sleep(sleeptime);  
  260.         if(GetAsyncKeyState(VK_SPACE))  
  261.         {  
  262.             break;  
  263.         }  
  264.     }  
  265. }  
  266.   
  267. void ControlSnake() //用键盘控制游戏  
  268. {  
  269.     if(GetAsyncKeyState(VK_UP) && Direction!=D)  
  270.     {  
  271.         Direction = U;  
  272.     }  
  273.     else if(GetAsyncKeyState(VK_DOWN) && Direction!=U)  
  274.     {  
  275.         Direction = D;  
  276.     }  
  277.     else if(GetAsyncKeyState(VK_LEFT) && Direction!=R)  
  278.     {  
  279.         Direction = L;  
  280.     }  
  281.     else if(GetAsyncKeyState(VK_RIGHT) && Direction!=L)  
  282.     {  
  283.         Direction = R;  
  284.     }  
  285.     else if(GetAsyncKeyState(VK_F1))  
  286.     {  
  287.         if(sleeptime != 500)  
  288.         {  
  289.             sleeptime = 500;  
  290.             everyScore = 1;  
  291.             Pos(COL_MAP+20, 2);  
  292.             printf("%d", everyScore);  
  293.         }  
  294.     }  
  295.     else if(GetAsyncKeyState(VK_F2))  
  296.     {  
  297.         if(sleeptime != 300)  
  298.         {  
  299.             sleeptime = 300;  
  300.             everyScore = 2;  
  301.             Pos(COL_MAP+20, 2);  
  302.             printf("%d", everyScore);  
  303.         }  
  304.     }  
  305.     else if(GetAsyncKeyState(VK_SPACE))  
  306.     {  
  307.         Pause();  
  308.     }  
  309.     else if(GetAsyncKeyState(VK_ESCAPE))  
  310.     {  
  311.         exit(0);  
  312.     }  
  313. }  
  314.   
  315. void StateGame() //判断游戏失败或成功  
  316. {  
  317.     if(State == ERROR_SELF)  
  318.     {  
  319.         system("cls");  
  320.         printf("很遗憾,蛇咬到自己,游戏失败!\n");  
  321.     }  
  322.     else if(State == ERROR_WALL)  
  323.     {  
  324.         system("cls");  
  325.         printf("很遗憾,蛇碰到墙壁,游戏失败!\n");  
  326.     }  
  327.     else if(State == SUCCESS)  
  328.     {  
  329.         system("cls");  
  330.         printf("恭喜您,已通关!!!\n");  
  331.     }  
  332.       
  333. }  
  334. void RunGame()  
  335. {  
  336.     Direction = R; //蛇初始行走方向为右  
  337.     State = NORMAL;//游戏初始为正常状态  
  338.     while(1)  
  339.     {  
  340.         ControlSnake();  
  341.         SnakeMove();  
  342.         if(State != NORMAL)  
  343.         {  
  344.             StateGame();  
  345.             break;  
  346.         }  
  347.         Sleep(sleeptime);  
  348.     }  
  349. }  
  350.   
  351. void EndGame()  //释放链表并恢复默认值  
  352. {  
  353.     pSnake cur = head;  
  354.     while(cur)  
  355.     {  
  356.         pSnake del = cur;  
  357.         cur = cur->next;  
  358.         free(del);  
  359.         del = NULL;  
  360.     }  
  361.     head = NULL;  
  362.     if(Food != NULL)  
  363.     {  
  364.         free(Food);  
  365.         Food = NULL;  
  366.     }  
  367.     Score = 0;  
  368.     everyScore = 1;  
  369.     sleeptime = 500;  
  370. }  
  371. 3.Test.c
  372. [cpp] view plain copy
  373. #include "Snake.h"  
  374.   
  375. int main()  
  376. {  
  377.     while(1)  
  378.     {  
  379.         StartGame();  
  380.         RunGame();  
  381.         EndGame();  
  382.     }  
  383.     system("pause");  
  384.     return 0;  
  385. }  
复制代码


回复

使用道具 举报

Archiver|手机版|小黑屋|三木电子社区 ( 辽ICP备11000133号-4 )

辽公网安备 21021702000620号

GMT+8, 2025-10-22 00:40 , Processed in 0.027448 second(s), 22 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表