当前位置:   article > 正文

C语言300行代码实现贪吃蛇

C语言300行代码实现贪吃蛇

完整代码:

 

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <conio.h>
  5. #include <windows.h>
  6. #include <time.h>
  7. #define ARRAY_SIZE 20                        // 区域大小
  8. int AreaArray[ARRAY_SIZE][ARRAY_SIZE];        // 数组
  9. #define        WALL            0                // 墙壁
  10. #define        VALID            1                // 可走区域
  11. #define        SELF            2                // 蛇身
  12. #define        NEWP            3                // 果实
  13. #define        HEAD            4                // 蛇头
  14. const char *Shape[] = {
  15.     "■",        // 墙壁图案
  16.     "  ",        // 可走区域图案ww
  17.     "◎",        // 蛇身图案
  18.     "⊙"    ,        // 果实图案
  19.     "●"            // 蛇头图案
  20. };
  21. // 记录分数
  22. int score = 0;
  23. int high_score = 0;
  24. // 蛇的所有坐标
  25. int xy[(ARRAY_SIZE - 2)*(ARRAY_SIZE - 2) + 1][2] = {0};
  26. // 方向状态
  27. enum {
  28.     LEFT,
  29.     TOP,
  30.     RIGHT,
  31.     BOTTOM
  32. } Direction;
  33. // 保存最高记录
  34. void GameSaveHighScore()
  35. {
  36.     FILE *fp = fopen("high_score.txt", "w");
  37.     if (fp == NULL)
  38.     {
  39.         printf("open file error.\n");
  40.         return;
  41.     }
  42.     fprintf(fp, "%d", high_score);
  43.     fclose(fp);
  44. }
  45. // 载入最高记录
  46. void GameLoadHighScore()
  47. {
  48.     FILE *fp = fopen("high_score.txt", "r");
  49.     if (fp == NULL)
  50.     {
  51.         printf("open file error.\n");
  52.         return;
  53.     }
  54.     fscanf(fp, "%d", &high_score);
  55.     fclose(fp);
  56. }
  57. // 生成特定区域内随机数
  58. int GetRand(int start, int end)
  59. {
  60.     static unsigned long count;
  61.     srand((unsigned int)time(0)+ count--);
  62.     return rand() % (end - start + 1) + start;
  63. }
  64. // 刷新果实坐标
  65. void GameUpdateNewp()
  66. {
  67.     static int x, y;
  68.     int i, j, z;
  69.     // 计算蛇长度
  70.     for (i = 0; xy[i][0] || xy[i][1]; i++);
  71.     // 添加上新吃的果实
  72.     i++;
  73.     // 生成随机数
  74.     i = GetRand(0, (ARRAY_SIZE - 2)*(ARRAY_SIZE - 2) - i - 1);
  75.     // 计算新果实坐标
  76.     for (j = 1;i && j < ARRAY_SIZE - 1; j++)
  77.     {
  78.         for (z = 1;i && z < ARRAY_SIZE - 1; z++)
  79.         {
  80.             if (AreaArray[j][z] == VALID)
  81.                 i--;
  82.             if (!i) break;
  83.         }
  84.         if (!i) break;
  85.     }
  86.     // 加入新果实
  87.     AreaArray[j][z] = NEWP;
  88.     // 去掉之前的果实
  89.     if (x || y)
  90.         AreaArray[y][x] = VALID;
  91.     //
  92.     x = z;
  93.     y = j;
  94. }
  95. // 根据用户操作更新游戏, 返回新状态
  96. int GameUpdate()
  97. {
  98.     int x = 0, y = 0, i;
  99.     // 根据方向检测碰撞
  100.     switch (Direction)
  101.     {
  102.         case LEFT:
  103.             x--;
  104.             break;
  105.         case TOP:
  106.             y--;
  107.             break;
  108.         case RIGHT:
  109.             x++;
  110.             break;
  111.         case BOTTOM:
  112.             y++;
  113.             break;
  114.     }
  115.     // 计算蛇长度
  116.     for (i = 0; xy[i][0] || xy[i][1]; i++);
  117.     // 判断下一个位置是否与蛇头碰撞
  118.     switch (AreaArray[xy[0][1] + y][xy[0][0] + x])
  119.     {
  120.         case SELF:
  121.         case WALL:
  122.             return 0;        // 撞自己或者撞墙了
  123.         case NEWP:
  124.             score++;
  125.             i++;            // 吃到果实, 长度加1
  126.             xy[i][0] = 0;    // 加结束标志
  127.             xy[i][1] = 0;    // 加结束标志
  128.             GameUpdateNewp();// 刷新果实坐标
  129.         case VALID:
  130.             i--;
  131.             // 移动蛇
  132.             while (i>0)
  133.             {
  134.                 xy[i][0] = xy[i-1][0];
  135.                 xy[i][1] = xy[i-1][1];
  136.                 i--;
  137.             }
  138.             // 蛇头坐标
  139.             xy[0][0] += x;
  140.             xy[0][1] += y;
  141.             break;
  142.     }
  143.     return 1;
  144. }
  145. // 刷新显示
  146. void GameFresh()
  147. {
  148.     int i, j;
  149.     // 去掉显示数组上蛇身旧状态的痕迹
  150.     for (i = 1; i < ARRAY_SIZE - 1; i++)
  151.         for (j = 1; j < ARRAY_SIZE - 1; j++)
  152.             if(AreaArray[i][j]== SELF || AreaArray[i][j] == HEAD)
  153.                 AreaArray[i][j] = VALID;
  154.     // 把蛇的坐标更新到显示数组
  155.         // 蛇头
  156.     AreaArray[xy[0][1]][xy[0][0]] = HEAD;
  157.         // 蛇身
  158.     for (i = 1; xy[i][0] || xy[i][1]; i++)
  159.         AreaArray[xy[i][1]][xy[i][0]] = SELF;
  160.     // 清屏
  161.     system("cls");
  162.     // 显示
  163.     for (i = 0; i < ARRAY_SIZE; i++)
  164.     {
  165.         for (j = 0; j < ARRAY_SIZE; j++)
  166.                 printf("%s", Shape[AreaArray[i][j]]);
  167.         printf("\n");
  168.     }
  169.     printf("current score: %d\n", score);
  170.     printf("high score: %d\n", high_score);
  171. }
  172. // 游戏初始化
  173. void GameInit()
  174. {
  175.     int i, j;
  176.     // 初始化显示数组整个区域
  177.     for (i = 0; i < ARRAY_SIZE; i++)
  178.         for (j = 0; j < ARRAY_SIZE; j++)
  179.             if (i && j && (i != ARRAY_SIZE - 1) && (j != ARRAY_SIZE - 1))
  180.                 AreaArray[i][j] = VALID;    // 可行走区域
  181.             else
  182.                 AreaArray[i][j] = WALL;        // 墙壁
  183.                                             // 随机生成蛇头坐标
  184.     xy[0][0] = GetRand(2, ARRAY_SIZE - 3);
  185.     xy[0][1] = GetRand(2, ARRAY_SIZE - 3);
  186.     // 根据蛇头坐标生成蛇身坐标
  187.     if (GetRand(0, 1))
  188.     {
  189.         if (xy[0][0] > ARRAY_SIZE / 2)
  190.         {
  191.             i = xy[0][0] + 1;
  192.             Direction = LEFT;
  193.         }
  194.         else
  195.         {
  196.             i = xy[0][0] - 1;
  197.             Direction = RIGHT;
  198.         }
  199.         j = xy[0][1];
  200.     }
  201.     else
  202.     {
  203.         i = xy[0][0];
  204.         if (xy[0][1] > ARRAY_SIZE / 2)
  205.         {
  206.             j = xy[0][1] + 1;
  207.             Direction = TOP;
  208.         }
  209.         else
  210.         {
  211.             j = xy[0][1] - 1;
  212.             Direction = BOTTOM;
  213.         }
  214.     }
  215.     xy[1][0] = i;
  216.     xy[1][1] = j;
  217.     // 蛇身结束标志
  218.     xy[2][0] = 0;
  219.     xy[2][1] = 0;
  220.     // 更新
  221.     GameUpdate();
  222.     GameUpdateNewp();
  223.     GameFresh();
  224. }
  225. void GameStart()
  226. {
  227.     int state = 1;
  228.     int time = 100;
  229.     system("cls");
  230.     printf("================= Game rule ==============\n");
  231.     printf("\tContinue key : \tany\n");
  232.     printf("\tQuit key : \tQ\n");
  233.     printf("\tUp key : \tW\n");
  234.     printf("\tDown key : \tS\n");
  235.     printf("\tLeft key : \tA\n");
  236.     printf("\tRight key : \tD\n");
  237.     printf("==========================================\n");
  238.     score = 0;
  239.     GameLoadHighScore();
  240.     getch();
  241.     GameInit();
  242.     while (state)
  243.     {
  244.         // 检测有输入
  245.         if(kbhit())
  246.             switch (getch())
  247.             {
  248.                 case 'q':
  249.                 case 'Q':
  250.                     state = 0;        // 结束游戏
  251.                     break;
  252.                 case 'w':
  253.                 case 'W':
  254.                     if(Direction != BOTTOM)
  255.                         Direction = TOP;
  256.                     break;
  257.                 case 's':
  258.                 case 'S':
  259.                     if (Direction != TOP)
  260.                         Direction = BOTTOM;
  261.                     break;
  262.                 case 'a':
  263.                 case 'A':
  264.                     if (Direction != RIGHT)
  265.                         Direction = LEFT;
  266.                     break;
  267.                 case 'd':
  268.                 case 'D':
  269.                     if (Direction != LEFT)
  270.                         Direction = RIGHT;
  271.                     break;
  272.                 default:;
  273.             }
  274.         state = GameUpdate();        // 更新
  275.         GameFresh();                // 刷新显示
  276.         Sleep(time);
  277.     }
  278.     printf("######### Game over #########\n");
  279.     // 最高记录
  280.     if (score > high_score) high_score = score;
  281.     GameSaveHighScore();
  282.     getch();
  283. }
  284. int main()
  285. {
  286.     while(1) GameStart();
  287.     return 0;
  288. }

 

运行截图:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/541915
推荐阅读
相关标签
  

闽ICP备14008679号