找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 15391|回复: 8

C 语言贪吃蛇

[复制链接]
发表于 2020-8-27 18:33:00 | 显示全部楼层 |阅读模式
本帖最后由 Gin_Q 于 2020-8-27 20:33 编辑

# 思路来自(知乎 id = int)int
# 还有些功能没有写!
  1. /*
  2. @ BY COOL_BREEZE
  3. @ 2020-08-27
  4. */


  5. #include<stdio.h>
  6. #include<stdlib.h>
  7. #include<time.h>
  8. #include<conio.h>
  9. #include<windows.h>

  10. #define HIGHT 30
  11. #define WIDTH 100

  12. // dos窗口显示模式
  13. #define MODE(X, Y) "MODE CON COLS="#X" LINES="#Y
  14. #define HAD (GetStdHandle(STD_OUTPUT_HANDLE))

  15. // 蛇的结构体开辟内存空间
  16. #define CALLSNAKE ((SNAKEP)malloc(sizeof(SNAKEV)))

  17. void hidecursor(void); // 改变光标的显示方式
  18. void gotoxy_print(int x, int y, char icon); // 移动光标到指定位置打印图标
  19. void __init__(void); // 初始化边框
  20. void create_snake(void); // 生成蛇
  21. void move_snake(void); // 移动蛇
  22. void create_food(void); // 生成食物
  23. void get_keyborad_input(void); // 获取键盘值
  24. int hit_the_wall(void); // 蛇撞墙
  25. void game_method(void);

  26. typedef struct SNAKE
  27. {
  28.         int x;  
  29.         int y;
  30.         struct SNAKE* next;
  31. } SNAKEV, *SNAKEP;

  32. SNAKEP SNAKE_HEAD; //蛇头
  33. SNAKEP SNAKE_FOOD; //食物

  34. //蛇前进的方向
  35. #define U 0X48 // 上
  36. #define D 0X50 // 下
  37. #define L 0X4B // 左
  38. #define R 0X4D // 右
  39. #define S 0X7F // 空格 暂停

  40. char DIRECTION = L; // 默认蛇往左边移动
  41. char HEAD_ICON = 0XF;
  42. char BODY_ICON = 0XB;
  43. char FOOD_ICON = 0X24;
  44. char NULL_ICON = 0X20;

  45. int main(void)
  46. {
  47.         system(MODE(130, 30));
  48.         system("title 贪吃蛇游戏");
  49.         game_method();
  50.         hidecursor();
  51.         __init__();
  52.         SNAKE_FOOD = CALLSNAKE;
  53.         create_snake();
  54.         create_food();
  55.         int ser; // 延迟
  56.         while(1)
  57.         {
  58.                 ser = 0;
  59.                 move_snake();
  60.                 if (kbhit()) // 检查键盘是否被按下,非阻塞的 (相当于多线程)
  61.                 {
  62.                         get_keyborad_input();
  63.                         Sleep(20);
  64.                         ser = 1;
  65.                 }
  66.                 if (hit_the_wall())
  67.                 {
  68.                         gotoxy_print((WIDTH-8) / 2, HIGHT / 2, NULL_ICON);
  69.                         printf("游戏结束");
  70.                         system("pause >nul");
  71.                         break;
  72.                 }
  73.                 if (ser)
  74.                         Sleep(10);
  75.                 else Sleep(200);
  76.         }
  77.         return 0;
  78.        
  79. }

  80. void hidecursor(void)
  81. {
  82.         CONSOLE_CURSOR_INFO show = {1, 0};
  83.         SetConsoleCursorInfo(HAD, &show);
  84. }

  85. void gotoxy_print(int x, int y, char icon)
  86. {
  87.         COORD poin = {x, y}; // 结构体
  88.         SetConsoleCursorPosition(HAD, poin); // 跳转到窗口指定位置
  89.         printf("%c", icon);
  90. }

  91. void game_method(void)
  92. {
  93.         gotoxy_print(WIDTH + 5, HIGHT/2-7, NULL_ICON);
  94.         printf("DATE 2020-08-27");
  95.         gotoxy_print(WIDTH + 5, HIGHT/2-6, NULL_ICON);
  96.         printf("BY COOL_BREEZE");
  97.         gotoxy_print(WIDTH + 5, HIGHT/2-4, NULL_ICON);
  98.         printf("空格 暂停");
  99.         gotoxy_print(WIDTH + 5, HIGHT/2-3, NULL_ICON);
  100.         printf("向上 ↑");
  101.         gotoxy_print(WIDTH + 5, HIGHT/2-2, NULL_ICON);
  102.         printf("向下 ↓");
  103.         gotoxy_print(WIDTH + 5, HIGHT/2-1, NULL_ICON);
  104.         printf("向左 ←");
  105.         gotoxy_print(WIDTH + 5, HIGHT/2, NULL_ICON);
  106.         printf("向右 →");
  107. }

  108. void __init__(void)
  109. {
  110.         int i = 0;
  111.         gotoxy_print(0, 0, 0X1); // 角落  1
  112.         gotoxy_print(WIDTH-1, 0, 0X2); // 角落  2
  113.         for (i=1; i<WIDTH-1; i++) // 上下边框
  114.         {
  115.                 gotoxy_print(i, 0, 0X6);
  116.                 gotoxy_print(i, HIGHT-1, 0X6);
  117.         }
  118.         for (i=1;i<HIGHT-1; i++) // 左右边框
  119.         {
  120.                 gotoxy_print(0, i, 0X5);
  121.                 gotoxy_print(WIDTH-1, i, 0X5);
  122.         }
  123.         gotoxy_print(0, HIGHT-1, 0X3); // 角落  3
  124.         gotoxy_print(WIDTH-1, HIGHT-1, 0X4); // 角落  4
  125. }

  126. void create_snake(void)
  127. {
  128.         int i = 0,x = (WIDTH-6) / 2, y = HIGHT / 2; //在中心创建蛇
  129.         SNAKEP phead, pend;
  130.         for (; i<6; i++) // 蛇默认长度为6
  131.         {
  132.                 pend = CALLSNAKE;
  133.                 if (!i)
  134.                 {
  135.                         SNAKE_HEAD = phead = pend;
  136.                         pend->x = x;
  137.                         pend->y = y;
  138.                         gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
  139.                 }
  140.                 else
  141.                 {
  142.                         phead->next = pend;
  143.                         pend->x = x + i; // 蛇身体在头右方
  144.                         pend->y = y;
  145.                         gotoxy_print(pend->x, pend->y, BODY_ICON);
  146.                         phead = pend;
  147.                 }
  148.         }
  149.         pend->next = NULL;
  150. }

  151. void move_snake(void)
  152. {
  153.         SNAKEP head = CALLSNAKE; // 蛇新的头部
  154.         switch (DIRECTION)
  155.         {
  156.                 case U:
  157.                                 head->x = SNAKE_HEAD->x;
  158.                                 head->y = SNAKE_HEAD->y - 1;
  159.                                 break;
  160.                 case D:
  161.                                 head->x = SNAKE_HEAD->x;
  162.                                 head->y = SNAKE_HEAD->y + 1;
  163.                                 break;
  164.                 case L:
  165.                                 head->x = SNAKE_HEAD->x - 1;
  166.                                 head->y = SNAKE_HEAD->y;
  167.                                 break;
  168.                 case R:
  169.                                 head->x = SNAKE_HEAD->x + 1;
  170.                                 head->y = SNAKE_HEAD->y;
  171.                                 break;
  172.                 case S:
  173.                                 system("pause >nul");
  174.                                 break;
  175.         }
  176.         head->next = SNAKE_HEAD; // 旧头部连接新头部 使旧头部成为身体
  177.         SNAKE_HEAD = head; // 获取头部
  178.         if (SNAKE_HEAD->x == SNAKE_FOOD->x && SNAKE_HEAD->y == SNAKE_FOOD->y) // 检查蛇是否吃到食物
  179.         {
  180.                 while (head) // 吃到了食物蛇蛇尾不需要释放
  181.                 {
  182.                         if (head == SNAKE_HEAD)
  183.                                 gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
  184.                         else
  185.                                 gotoxy_print(head->x, head->y, BODY_ICON);
  186.                         head = head->next;
  187.                 }
  188.                 create_food();
  189.         }
  190.         else
  191.         {
  192.                 while (head->next->next) // 没吃到食物释放掉蛇尾
  193.                 {
  194.                         if (head == SNAKE_HEAD)
  195.                                 gotoxy_print(SNAKE_HEAD->x, SNAKE_HEAD->y, HEAD_ICON);
  196.                         else
  197.                                 gotoxy_print(head->x, head->y, BODY_ICON);
  198.                         head = head->next;
  199.                 }
  200.                 gotoxy_print(head->next->x, head->next->y, NULL_ICON);
  201.                 free(head->next);
  202.                 head->next = NULL;
  203.         }
  204. }

  205. void create_food(void)
  206. {
  207.         SNAKEP  temp;
  208.         while (1)
  209.         {
  210.                 srand(time(NULL)); // 获取新种子 生成新的随机数
  211.                 SNAKE_FOOD->x = rand() % (WIDTH - 2) + 1; // 确保坐标只会出现在表格内(不包括表格)
  212.                 SNAKE_FOOD->y = rand() % (HIGHT - 2) + 1; // 确保坐标只会出现在表格内(不包括表格)
  213.                 temp = SNAKE_HEAD;
  214.                 while(temp) // 食物落在蛇身上重新获取
  215.                 {
  216.                         if (temp->x == SNAKE_FOOD->x && temp->y == SNAKE_FOOD->y)
  217.                                 continue;
  218.                         else
  219.                         {
  220.                                 gotoxy_print(SNAKE_FOOD->x, SNAKE_FOOD->y, FOOD_ICON);
  221.                                 break;
  222.                         }
  223.                 }
  224.                 break;
  225.         }
  226. }

  227. void get_keyborad_input(void)
  228. {
  229.         int key = 0;
  230.     while (1)
  231.     {
  232.         key = getch();
  233.         if (key == 224) // 键盘方向键需要获取两次
  234.         {
  235.             key = getch();
  236.             if (key == U ||\
  237.                 key == D ||\
  238.                 key == L ||\
  239.                 key == R)
  240.             {
  241.                     DIRECTION = key;
  242.                     break;
  243.                         }
  244.             else continue;
  245.         }
  246.     }
  247. }

  248. int hit_the_wall(void)
  249. {
  250.         if (SNAKE_HEAD->x == 0 || SNAKE_HEAD->x == WIDTH-1 ||\
  251.                 SNAKE_HEAD->y == 0 || SNAKE_HEAD->y == HIGHT-1 )
  252.                 return 1;
  253.         return 0;
  254. }
复制代码
发表于 2020-8-27 20:56:22 | 显示全部楼层
回复 1# Gin_Q


这个效果也挺酷:
http://bbs.bathome.net/thread-24093-1-1.html
 楼主| 发表于 2020-8-27 21:02:11 | 显示全部楼层
回复 2# Batcher


    代码哪里有问题,卡卡的!难搞咯!
发表于 2020-8-30 22:29:20 | 显示全部楼层
本帖最后由 wujunkai 于 2020-9-20 11:49 编辑

回复 3# Gin_Q


    断断续续优化了2年,C++的
  1. /* 贪吃蛇 3.40.0 */
  2. #include<cstdio>
  3. #include<windows.h>
  4. #define HIT
  5. #define UP                        1
  6. #define LEFT                2
  7. #define DOWN                3
  8. #define RIGHT                4
  9. #define HEAD                5
  10. #define WALL                22
  11. #define Handle                GetStdHandle(STD_OUTPUT_HANDLE)
  12. #define Pempty(a)        Psame(a,' ')
  13. #define Key(a)                GetAsyncKeyState(a)
  14. #define elif                 else if
  15. struct botton{
  16.         int x ,y ;
  17.         int length ;
  18. };
  19. struct bearing:POINT{
  20.         void walk(int Flag);
  21. };
  22. struct Snake{
  23.         int Sum        ;
  24.         int Flag ;
  25.         int Grade ;
  26.         int Color ;
  27.         int Speed ;
  28.         bool Life ;
  29.         bool Active ;
  30.         bearing End ;
  31.         bearing Head ;
  32.         Snake(int color,int speed,bool life) ;
  33.         void Move() ;
  34.         void Smarter() ;
  35.         void Re(int flag,POINT pos) ;
  36.         void Go(bool iiSmart,bool iiSmarter,int faster) ;
  37.         void Direction(int up,int left,int down,int right) ;
  38. };
  39. bool Pcolor(int,int) ;
  40. bool Hit(botton,int) ;
  41. char*Psame(int,char) ;
  42. bool Pposition(int,int) ;
  43. void Dead() ;
  44. void Menu() ;
  45. void Foods() ;
  46. void Levels() ;
  47. void GradeIn() ;
  48. void Prepare() ;
  49. void Setting() ;
  50. void GradeInput() ;
  51. void Pedge(botton) ;
  52. void GradeOutput(int) ;
  53. void Walk(int,long&,long&) ;
  54. POINT Food = {} ;
  55. //          第一个人                        第二个人                        电脑
  56. Snake Frst(10,1,true)        ,Scnd(14,1,false)        ,Auto( 1,1,false) ;
  57. int Level = 1 ;
  58. int Score[4] = {} ;
  59. int Map[WALL][WALL] = {} ;
  60. //         开始                         菜单                         死亡
  61. bool iBegin        = true         ,iMenu        = false        ,iDead        = true ;
  62. //         加速                         循环地图                 竞技模式
  63. bool iFast        = true        ,iFor        = true        ,iRace        = false ;
  64. //         迷宫模式                 额外奖励                 帮助
  65. bool iMaze        = false ,iPrize        = false ,iHelp        = false        ;
  66. //         调试模式
  67. bool iDebug        = false        ;
  68. const char wLevel[5][5] ={"简单","普通","困难","炼狱","调试"} ;
  69. /* 初始化蛇 */
  70. Snake::Snake(int color,int speed,bool life)
  71. {
  72.         Color=color ;
  73.         Speed=speed ;
  74.         Life=life ;
  75. }
  76. /* 数据导入 */
  77. void GradeIn()
  78. {
  79.         if(fopen("score.log","rb"))
  80.                 fscanf(fopen("score.log","rb"),"%d%d%d",Score,Score+1,Score+2) ;
  81. }
  82. /* 检测击键 */
  83. bool Hit(botton bot,int key)
  84. {
  85.         #ifdef HIT
  86.         RECT rect={} ;
  87.         POINT pos={} ;
  88.         GetCursorPos(&pos) ;
  89.         GetWindowRect(GetConsoleWindow(),&rect) ;
  90.         int x=(pos.x-rect.left-6)/8 , y=(pos.y-rect.top-32)/16 ;
  91.         return(x>=bot.x&&x<bot.x+bot.length&&y>=bot.y&&y<=bot.y+2)&&Key(key) ;
  92.         #endif
  93.         return false;
  94. }
  95. /* 选择菜单 */
  96. void Menu()
  97. {
  98.         int place=0 ;
  99.         void (*function[])()={Prepare,Levels,GradeInput,Setting} ;
  100.         botton bot[5]={{16,7,12},{13,10,18},{13,13,10},{23,13,8},{16,16,12}} ;
  101.         Print:
  102.         system("cls") ;
  103.         printf("\n\n\n%s贪%s吃%s蛇\n\n\n\n",Pempty(17),Pempty(2),Pempty(2),Pcolor(15,3)) ;
  104.         printf("\n%s开始游戏\n\n",Pempty(18)) ;
  105.         printf("\n%s游戏难度 :%s\n\n",Pempty(15),wLevel[Level]) ;
  106.         printf("\n%s排行榜%s设置\n\n",Pempty(15),Pempty(4)) ;
  107.         printf("\n%s退出游戏",Pempty(18)) ;
  108.         Pedge(bot[place]);
  109.         Scan:
  110.         Sleep(125) ;
  111.         if        (Key(' ')||Key(VK_RETURN)){
  112.                 if(place<4)
  113.                         function[place]() ;
  114.                 if(place==0||place==4){
  115.                         iBegin=(place==0);
  116.                         return ;
  117.                 }
  118.                 place=0 ;
  119.         }
  120.         elif ((Key('S')||Key(VK_DOWN))        && place!=4)
  121.                 place+=(place==2)?2:1 ;
  122.         elif ((Key('W')||Key(VK_UP))        && place!=0)
  123.                 place-=(place==3)?2:1 ;
  124.         elif ((Key('D')||Key(VK_RIGHT))        && place==2)
  125.                 place++ ;
  126.         elif ((Key('A')||Key(VK_LEFT))        && place==3)
  127.                 place-- ;
  128.         else
  129.                 goto Scan ;
  130.         goto Print ;
  131. }
  132. /* 难度选择 */
  133. void Levels()
  134. {
  135.         Print:
  136.         system("cls") ;
  137.         printf("\n\n\n%s困 难 度 选 择\n\n\n\n",Pempty(15)) ;
  138.         for(int i=0 ;i<4+iDebug ;i++)
  139.                 printf("%s%s\n\n\n",Pempty(20),wLevel[i]) ;
  140.         Pedge({18,(Level+2)*3,8});
  141.         Scan:
  142.         Sleep(125) ;
  143.         if        ((Key('S')||Key(VK_DOWN))        && Level != 3+iDebug)
  144.                 Level++ ;
  145.         elif((Key('W')||Key(VK_UP))                && Level != 0)
  146.                 Level-- ;
  147.         elif(Key(' ')||Key(VK_RETURN))
  148.                 return ;
  149.         else
  150.                 goto Scan ;
  151.         goto Print ;
  152. }
  153. /* 排行数据 */
  154. void GradeInput()
  155. {
  156.         system("cls") ;
  157.         printf("\n\n\n%s排 行 榜\n\n",Pempty(18)) ;
  158.         for(int i=0 ;i<3 ;i++)
  159.                 printf("%s第%d名: %d\n\n",Pempty(17) ,i+1,Score[i]) ;
  160.         printf("\n\n\n%s知道了\n\n",Pempty(19)) ;
  161.         Pedge({17,13,10});
  162.         for(Sleep(125) ; !(Key(' ') ||Key(VK_RETURN)) ;Sleep(125)) ;
  163. }
  164. /* 游戏设置 */
  165. void Setting()
  166. {
  167.         bool iClear        = false ;
  168.         bool *str[10] =                {&iDead                ,&iFor                ,&iHelp                ,&iMaze                ,&iPrize        ,&iRace                ,&Auto.Life ,&Scnd.Life ,&iClear        ,&iDebug        } ;
  169.         char name[10][9] =        {"死亡判定"        ,"循环地图"        ,"智能辅助"        ,"迷宫地图"        ,"额外奖励"        ,"淘汰模式"        ,"人机模式" ,"双人模式" ,"分数清理" ,"调试模式"        } ;
  170.         int place = 0 ;
  171.         Print:
  172.         system("cls") ;
  173.         printf("\n\n%s设%s置\n\n\n",Pempty(18),Pempty(4)) ;
  174.         for(int i=0;i<10;i+=2){
  175.                 printf("%s%s%s%s\n\n\n",Pempty(4),name[i],Pempty(11),name[i+1],Pposition(0,i/2*3+5),Pcolor(15,3));
  176.                 printf("%s",(*str[i]  )?"  开":"关",Pposition(16,i/2*3+5),Pcolor((*str[i]  )?3:15,(*str[i])?15:3));
  177.                 printf("%s",(*str[i+1])?"  开":"关",Pposition(36,i/2*3+5),Pcolor((*str[i+1])?3:15,(*str[i+1])?15:3));
  178.         }
  179.         printf("\n\n\n%s退%s出",Pempty(16),Pempty(5),Pcolor(15,3));
  180.         if(place<10)
  181.                 Pedge({(place%2)?34:14,place/2*3+4,8}) ;
  182.         else
  183.                 Pedge({14,19,13}) ;
  184.         Scan:
  185.         if  ((iFast||!iDead)&&!iDebug)
  186.                 iDead=true;
  187.         Sleep(125) ;
  188.         if  ( (Key('S')||Key(VK_DOWN))        && place < 10)
  189.                 place+=2 ;
  190.         elif( (Key('W')||Key(VK_UP))        && place > 1)
  191.                 place-=2 ;
  192.         elif( (Key('A')||Key(VK_LEFT))        && place%2 == 1)
  193.                 place-- ;
  194.         elif( (Key('D')||Key(VK_RIGHT))        && place%2 == 0)
  195.                 place++ ;
  196.         elif(Key(' ')||Key(VK_RETURN)){
  197.                 if(place>=10)
  198.                         return ;
  199.                 *str[place]=!(*str[place]);
  200.         }
  201.         else
  202.                 goto Scan ;
  203.         if(iClear)
  204.                 Score[0] = Score[1] = Score[2] = Score[3]= 0 ;
  205.         goto Print ;
  206. }
  207. /* 主函数 */
  208. int main()
  209. {
  210.         system("color 3f&mode con cols=44 lines=24&title 贪吃蛇") ;
  211.         GradeIn() ;
  212.         Menu:
  213.         Menu() ;
  214.         while( iBegin ){
  215.                 Frst.Direction('W','A','S','D' );
  216.                 Scnd.Direction(VK_UP,VK_LEFT,VK_DOWN,VK_RIGHT) ;
  217.                 if( !Scnd.Life )
  218.                         Frst.Direction(VK_UP,VK_LEFT,VK_DOWN,VK_RIGHT) ;
  219.                 Frst.Go(iHelp        ,false        ,'R'                ) ;
  220.                 Scnd.Go(iHelp        ,false        ,VK_NUMPAD0        ) ;
  221.                 Auto.Go(true        ,true        ,-1                        ) ;
  222.                 if(iDead&&(Frst.Active&& Map[Frst.Head.y][Frst.Head.x] != HEAD)||
  223.                                   (Auto.Active&& Map[Auto.Head.y][Auto.Head.x] != HEAD)||
  224.                                   (Scnd.Active&& Map[Scnd.Head.y][Scnd.Head.x] != HEAD))
  225.                         Dead() ;
  226.                 if(iMenu){
  227.                         GradeOutput(Frst.Grade+Scnd.Grade) ;
  228.                         goto Menu ;
  229.                 }
  230.                 Sleep((iDebug&&Level==4)?0 : ( Level < 3)?(150 -(Level * 50)) :(rand() % 80)) ;
  231.         }
  232.         return 0 ;
  233. }
  234. /* 运动处理 */
  235. void Snake::Go(bool iiSmart,bool iiSmarter,int faster)
  236. {
  237.         for(int i=0;((iFast&&Key(faster))||i<Speed)&&Active;i++){
  238.                 iMenu = Key(VK_ESCAPE) ;
  239.                 if(iiSmarter)
  240.                         Smarter() ;
  241.                 if(iiSmart)
  242.                         for(int i=0 ;i<16 ;i++)
  243.                                 if((Flag==LEFT        &&        Map[Head.y]  [Head.x-1])||
  244.                                    (Flag==DOWN        &&        Map[Head.y+1][Head.x]  )||
  245.                                    (Flag==RIGHT        &&        Map[Head.y]  [Head.x+1])||
  246.                                    (Flag==UP        &&        Map[Head.y-1][Head.x]  ))
  247.                                         Flag=rand()%4+1 ;
  248.                 Move() ;
  249.         }
  250. }
  251. /* 智能方向 */
  252. void Snake::Smarter()
  253. {
  254.         Map[Food.y][Food.x]=-2 ;
  255.         for(int nem=0 ;nem<50&&Map[Head.y-1][Head.x]!=-2&&Map[Head.y+1][Head.x]!=-2&&Map[Head.y][Head.x-1]!=-2&&Map[Head.y][Head.x+1]!=-2 ;nem++){
  256.                 for(int i=1 ;i<WALL-1 ;i++){
  257.                         for(int j=1 ;j<WALL-1 ;j++){
  258.                                 if(Map[i][j]==-2){
  259.                                         if(Map[i-1][j]==0)
  260.                                                 Map[i-1][j]=-1 ;
  261.                                         if(Map[i+1][j]==0)
  262.                                                 Map[i+1][j]=-1 ;
  263.                                         if(Map[i][j-1]==0)
  264.                                                 Map[i][j-1]=-1 ;
  265.                                         if(Map[i][j+1]==0)
  266.                                                 Map[i][j+1]=-1 ;
  267.                                 }
  268.                         }
  269.                 }
  270.                 if(iFor){
  271.                         for(int i=0 ;i<WALL ;i++){
  272.                                 for(int j=0 ;j<WALL ;j+=(i==0||i==WALL-1)?1:WALL-1){
  273.                                         if(Map[i][j]==-1){
  274.                                                 Map[(i==0||i==WALL-1)?abs(i-WALL+1):i][(j==0||j==WALL-1)?abs(j-WALL+1):j] = (Map[(i==0||i==WALL-1)?abs(i-WALL+1):i][(j==0||j==WALL-1)?abs(j-WALL+1):j]==0)?-2:Map[(i==0||i==WALL-1)?abs(i-WALL+1):i][(j==0||j==WALL-1)?abs(j-WALL+1):j] ;
  275.                                                 Map[(i==0||i==WALL-1)?abs(i-WALL+2):i][(j==0||j==WALL-1)?abs(j-WALL+2):j] = (Map[(i==0||i==WALL-1)?abs(i-WALL+2):i][(j==0||j==WALL-1)?abs(j-WALL+2):j]==0)?-2:Map[(i==0||i==WALL-1)?abs(i-WALL+2):i][(j==0||j==WALL-1)?abs(j-WALL+2):j] ;
  276.                                         }
  277.                                 }
  278.                         }
  279.                 }
  280.                 for(int i=0 ;i<WALL ;i++)
  281.                         for(int j=0 ;j<WALL ;j++)
  282.                                 Map[i][j]=(Map[i][j]==-1)?-2:Map[i][j] ;
  283.         }
  284.         if        (Map[Head.y-1][Head.x]==-2)
  285.                 Flag=UP ;
  286.         elif(Map[Head.y+1][Head.x]==-2)
  287.                 Flag=DOWN ;
  288.         elif(Map[Head.y][Head.x-1]==-2)
  289.                 Flag=LEFT ;
  290.         elif(Map[Head.y][Head.x+1]==-2)
  291.                 Flag=RIGHT ;
  292.         for(int i=0 ;i<WALL ;i++)
  293.                 for(int j=0 ;j<WALL ;j++)
  294.                         if(Map[i][j]==-2)
  295.                                 Map[i][j]=0 ;
  296. }
  297. /* 定位打印 */
  298. bool Pposition(int x ,int y)
  299. {
  300.         CONSOLE_CURSOR_INFO CurSor ={};
  301.         SetConsoleCursorPosition(Handle, { x,y }) ;
  302.         GetConsoleCursorInfo(Handle,&CurSor) ;
  303.         CurSor.bVisible = false ;
  304.         SetConsoleCursorInfo(Handle,&CurSor) ;
  305. }
  306. /* 字体颜色 */
  307. bool Pcolor( int a ,int b)
  308. {
  309.         SetConsoleTextAttribute(Handle, a + b * 0x10) ;
  310. }
  311. /* 批量打印 */
  312. char*Psame (int n,char word)
  313. {
  314.         char * turn=new char [n+1] ;
  315.         memset(turn,word,n);
  316.         turn[n]=0;
  317.         return turn ;
  318. }
  319. /* 边框打印 */
  320. void Pedge(botton the)
  321. {
  322.         for(int i=0;i<2;i++){
  323.                 printf("%s",Psame(the.length,'-'),Pposition(the.x,the.y+i*2),Pcolor(15,3));
  324.                 printf("#" ,Pposition(the.x+i*(the.length-1),the.y+1));
  325.         }
  326. }
  327. /* 运行准备 */
  328. void Prepare()
  329. {
  330.         Frst.Re(RIGHT,{3,10}) ;
  331.         if(Auto.Life)
  332.                 Scnd.Re(DOWN,{11,3});
  333.         else
  334.                 Scnd.Re(LEFT,{18,10}) ;
  335.         Auto.Re(LEFT,{18,10}) ;
  336.         iMenu = false ;
  337.         system("cls") ;
  338.         for(int i = 0 ; i < WALL ; i++){
  339.                 for(int j = 0 ; j < WALL ; j++){
  340.                         Map[i][j] = 0;
  341.                         if        ( i == 0 || i == WALL -1 || j == 0 || j == WALL -1){
  342.                                 Map[i][j] = (iFor)?0:WALL;
  343.                                 printf("■",Pcolor( 15,3)) ;
  344.                         }
  345.                         else
  346.                                 printf("%s",Pempty(2),Pcolor( 3 , 3)) ;
  347.                 }
  348.         }
  349.         Foods() ;
  350. }
  351. /* 蛇的重置 */
  352. void Snake::Re(int flag,POINT pos)
  353. {
  354.         Sum                = -3 ;
  355.         Grade        = 0 ;
  356.         Flag        = flag ;
  357.         Active        = Life ;
  358.         End.x        = Head.x = pos.x ;
  359.         End.y        = Head.y = pos.y ;
  360. }
  361. /* 蛇皮走位 */
  362. void bearing::walk(int Flag)
  363. {
  364.         switch(Flag){
  365.                 case LEFT:{
  366.                         x-=(iFor&&x==1)?-19:1 ;
  367.                 }return ;
  368.                 case RIGHT:{
  369.                         x+=(iFor&&x==20)?-19:1 ;
  370.                 }return ;
  371.                 case UP:{
  372.                         y-=(iFor&&y==1)?-19:1 ;
  373.                 }return ;
  374.                 case DOWN:{
  375.                         y+=(iFor&&y==20)?-19:1 ;
  376.                 }return ;
  377.         }
  378. }
  379. /* 方向判断 */
  380. void Snake::Direction(int up,int left,int down,int right)
  381. {
  382.         Flag = ((Key(left))        && Flag!=RIGHT        )?        LEFT        :Flag ;
  383.         Flag = ((Key(right))&& Flag!=LEFT        )?        RIGHT        :Flag ;
  384.         Flag = ((Key(up))        && Flag!=DOWN        )?        UP                :Flag ;
  385.         Flag = ((Key(down))        && Flag!=UP                )?        DOWN        :Flag ;
  386. }
  387. /* 蛇的移动 */
  388. void Snake::Move()
  389. {
  390.         printf("●",Pcolor(Color,3) ,Pposition(End.x*2,End.y) ) ;
  391.         Map[Head.y][Head.x] = Flag ;
  392.         Head.walk(Flag) ;
  393.         printf("●",Pcolor( Color ,3),Pposition( Head.x * 2 ,Head.y)) ;
  394.         Map[Head.y][Head.x] += HEAD ;
  395.         if (Head.y==Food.y&& Head.x==Food.x){
  396.                 Grade++ ;
  397.                 Foods() ;
  398.         }
  399.         if (Sum==Grade){
  400.                 int Temp = Map[End.y][End.x] ;
  401.                 Map[End.y][End.x] = 0 ;
  402.                 printf("%s",Pempty(2),Pcolor( 3 ,3), Pposition( End.x * 2 ,End.y) ) ;
  403.                 End.walk(Temp) ;
  404.         }
  405.         else
  406.                 Sum++ ;
  407. }
  408. /* 死亡判断 */
  409. void Dead()
  410. {
  411.         if(iRace&&(Frst.Active||Scnd.Active||Auto.Active)){
  412.                 Snake*they[3]={&Frst,&Scnd,&Auto} ;
  413.                 for(int i=0;i<3;i++)
  414.                         if(Map[they[i]->Head.y][they[i]->Head.x] != HEAD){
  415.                                 they[i]->Active = false ;
  416.                                 Map[they[i]->Head.y][they[i]->Head.x] -= HEAD ;
  417.                         }
  418.                 return ;
  419.         }
  420.         GradeOutput(Frst.Grade+Scnd.Grade) ;
  421.         printf(" Game Over !",Pcolor( 15, 3) ,Pposition( 16 , 9)) ;
  422.         Sleep(1500) ;
  423.         char wDead[3][9] ={"重新开始","返回菜单","退出游戏"} ;
  424.         int place = iBegin = false ;
  425.         Print:
  426.         system("cls") ;
  427.         printf("\n\n\n\n%s游 戏 结 束\n",Pempty(16)) ;
  428.         if        (Scnd.Life&&Frst.Grade!=Scnd.Grade)
  429.                 printf("%s%s 赢 了",Pempty(16),(Frst.Grade>Scnd.Grade)?"左 边":"右 边");
  430.         printf("\n%s分数 : %d\n\n\n\n" ,Pempty(17),Frst.Grade+Scnd.Grade) ;
  431.         for( int i = 0 ; i < 3 ; i++)
  432.                 printf("%s%s\n\n\n",Pempty(18),wDead[i]) ;
  433.         Pedge({16,place*3+9,12}) ;
  434.         Scan:
  435.         Sleep(125) ;
  436.         if        ((Key('W')||Key(VK_UP))                && place != 0)
  437.                 place-- ;
  438.         elif((Key('S')||Key(VK_DOWN))        && place != 2)
  439.                 place++ ;
  440.         elif(Key(' ')||Key(VK_RETURN)){
  441.                 iBegin = (place==0||place==1) ;
  442.                 if        (place==0)
  443.                         Prepare() ;
  444.                 elif(place==1)
  445.                         iBegin = iMenu = true ;
  446.                 return ;
  447.         }
  448.         else
  449.                 goto Scan ;
  450.         goto Print ;
  451. }
  452. /* 随机果实 */
  453. void Foods()
  454. {
  455.         do{
  456.                 Food.x = rand() %(WALL - 2) +1 ,Food.y = rand() %(WALL - 2) +1 ;
  457.         }while( Map[Food.y][Food.x]!=0 ) ;
  458.         printf("★",Pcolor(4,3),Pposition( Food.x * 2 ,Food.y)) ;
  459. }
  460. /* 分数保存 */
  461. void GradeOutput(int grade)
  462. {
  463.         for(int i=2 ;i>=0 ;i--)
  464.                 if(Score[i]<grade){
  465.                         Score[i+1]        = Score[i] ;
  466.                         Score[i]        = grade ;
  467.                 }
  468.         fprintf(fopen("score.log","w+"),"%d\n%d\n%d",Score[0],Score[1],Score[2]) ;
  469. }
复制代码

评分

参与人数 1技术 +1 收起 理由
Gin_Q + 1 很强!

查看全部评分

发表于 2020-8-31 12:40:54 | 显示全部楼层
哇这么热闹,
老早以前用批处理写的咬文嚼字蛇:http://www.bathome.net/thread-43231-1-1.html
由于每个蛇身都不一样,不能直接处理头和尾中间不管,所以实现是全挪一遍233。
happy用纯批写过一个很精简的贪吃蛇,好像只有60行左右,不过链接找不到了。

评分

参与人数 1技术 +1 收起 理由
Gin_Q + 1 赞!

查看全部评分

发表于 2020-9-18 11:26:37 | 显示全部楼层
回复 4# wujunkai

这个是DOS程序吗?
发表于 2020-9-20 11:39:03 | 显示全部楼层
回复 6# netdzb


    不是,是控制台程序
发表于 2020-9-20 12:08:36 | 显示全部楼层
回复 7# wujunkai

在什么平台编译的?mingw可以吗?
发表于 2020-9-20 21:28:33 | 显示全部楼层
回复 8# netdzb


    不知道,我用的是dev C++
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 01:44 , Processed in 0.026595 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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