Chinaunix

标题: [原创]贡献一个unix的贪吃蛇小游戏 [打印本页]

作者: forest077    时间: 2008-06-25 13:16
标题: [原创]贡献一个unix的贪吃蛇小游戏
许久没来,贡献一个原创小程序,是unix下用终端控制字符实现的贪吃蛇小游戏,供大家一乐。

  1. /***snake.c***/
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. #include <sys/time.h>
  5. #include <sys/types.h>
  6. #include <sys/select.h>
  7. #include <termio.h>
  8. #include <fcntl.h>

  9. #define SNAKE_INITX 5
  10. #define SNAKE_INITY 5
  11. #define SNAKE_SHAPE '*'
  12. #define SNAKE_INITLEN 8

  13. #define WIN_X1 1
  14. #define WIN_X2 80
  15. #define WIN_Y1 1
  16. #define WIN_Y2 24

  17. #define MAX_LEVEL 20
  18. #define MAX_INTER 200000
  19. #define MIN_INTER 0
  20. #define MAX_RICH 10
  21. #define DEVRATE 5
  22. #define OVER "Game Over!!!"

  23. struct stNode
  24. {
  25.         int x;
  26.         int y;
  27.         char shape;
  28.         struct stNode *next;
  29. };

  30. struct stFood
  31. {
  32.         int x;
  33.         int y;
  34. };

  35. struct stNode *gpstHead,*gpstTail;
  36. struct stFood gastFood[MAX_RICH];
  37. int giLevel=1;
  38. int giRich=1;
  39. int giScore=0;
  40. int giLen=0;

  41. void settty(int iFlag)
  42. {
  43.         int fd;
  44.         struct termio stTerm;

  45.         if((fd = open(ttyname(1),O_RDWR))==-1)        return;
  46.         if(iFlag == 1)
  47.         {
  48.                 ioctl(fd,TCGETA,&stTerm);
  49.                 stTerm.c_lflag &= ~ICANON;
  50.                 stTerm.c_lflag &= ~ECHO;
  51.                 stTerm.c_cc[4] = 1;
  52.                 stTerm.c_cc[5] = 0;
  53.                 stTerm.c_iflag &= ~ISTRIP;
  54.                 stTerm.c_cflag |= CS8;
  55.                 stTerm.c_cflag &= ~PARENB;
  56.                 ioctl(fd,TCSETA,&stTerm);
  57.         }
  58.         else
  59.         {
  60.                 ioctl(fd,TCGETA,&stTerm);
  61.                 stTerm.c_lflag |= ICANON;
  62.                 stTerm.c_lflag |= ECHO;
  63.                 stTerm.c_cc[4] = 4;
  64.                 stTerm.c_cc[5] = 5;
  65.                 stTerm.c_iflag &= ~ISTRIP;
  66.                 stTerm.c_cflag |= CS8;
  67.                 stTerm.c_cflag &= ~PARENB;
  68.                 ioctl(fd,TCSETA,&stTerm);
  69.         }
  70.         close(fd);
  71. }

  72. void vDrawOneNode(struct stNode *pstNode,int iFlag)
  73. {
  74.         printf("\033[%dm\033[40;%dm\033[%d;%d;H%c",
  75.                 iFlag,iFlag*3+30,pstNode->y,pstNode->x,pstNode->shape);
  76.         fflush(stdout);
  77. }

  78. void vDrawOneFood(int x,int y)
  79. {
  80.         printf("\033[1m\033[40;36m\033[%d;%d;H%c",y,x,'@');
  81.         fflush(stdout);
  82. }

  83. int iGetDir(int iOriDir)
  84. {
  85.         fd_set rset;
  86.         struct        timeval        hTmo;
  87.         int iRet,iFlag=0;
  88.         char cCh;

  89.         FD_ZERO(&rset);
  90.         FD_SET(0,&rset);
  91.         hTmo.tv_sec=0;
  92.         hTmo.tv_usec=MAX_INTER-(MAX_INTER-MIN_INTER)/MAX_LEVEL*giLevel;

  93.         iRet=select(1,&rset,NULL,NULL,&hTmo);
  94.         if(iRet<=0)
  95.         {
  96.                 return(iOriDir);
  97.         }
  98.         for(;;)
  99.         {
  100.                 cCh=getchar();
  101.                 if(cCh != -1)
  102.                 {
  103.                         switch(cCh)
  104.                         {         
  105.                         case 27  :
  106.                         case 91  :
  107.                                 iFlag++;
  108.                                 break;
  109.                         case 65  ://UP
  110.                         case 66 ://DOWN
  111.                         case 67  ://RIGHT
  112.                         case 68 ://LEFT
  113.                         if(iFlag==2)
  114.                                 return((!((cCh-0x41)^iOriDir^1))^(cCh-0x41));
  115.                         default  :
  116.                                 return(iOriDir);
  117.                         }
  118.                 }
  119.         }
  120. }
  121. void vInitScreen()
  122. {
  123.         settty(1);
  124.         printf("\033[?25l\033[2J");
  125. }

  126. void vRestoreScreen()
  127. {
  128.         printf("\033[24;1H\033[1m\033[40;34m\033[?25h");
  129.         settty(0);
  130. }

  131. void vDrawScope()
  132. {
  133.         int i,j;
  134.        
  135.         for(j=WIN_Y1;j<=WIN_Y2;j+=WIN_Y2-WIN_Y1)
  136.         {
  137.                 printf("\033[%d;%dH+",j,WIN_X1);
  138.                 for(i=WIN_X1+1;i<WIN_X2;i++)
  139.                         printf("-");
  140.                 printf("+");
  141.         }
  142.         for(i=WIN_Y1+1;i<WIN_Y2;i++)
  143.                 printf("\033[%d;%dH|%*c|\n",i,WIN_X1,WIN_X2-WIN_X1-1,' ');
  144. }

  145. void vCreateSnake()
  146. {
  147.         struct stNode *pstNew;
  148.         int i;

  149.         gpstHead=(struct stNode*)malloc(sizeof(struct stNode));
  150.         gpstHead->x=SNAKE_INITX;       
  151.         gpstHead->y=SNAKE_INITY;
  152.         gpstHead->shape=SNAKE_SHAPE;
  153.         gpstHead->next=NULL;
  154.         vDrawOneNode(gpstHead,1);
  155.         gpstTail=gpstHead;
  156.         for(i=1;i<SNAKE_INITLEN;i++)
  157.         {
  158.                 pstNew=(struct stNode*)malloc(sizeof(struct stNode));
  159.                 pstNew->x=gpstHead->x+1;       
  160.                 pstNew->y=gpstHead->y;
  161.                 pstNew->shape=SNAKE_SHAPE;
  162.                 pstNew->next=NULL;
  163.                 vDrawOneNode(pstNew,1);
  164.                 gpstHead->next=pstNew;
  165.                 gpstHead=pstNew;
  166.         }
  167.         return;
  168. }

  169. void vKillSnake()
  170. {
  171.         struct stNode *pstNode;

  172.         for(pstNode=gpstTail;gpstTail!=NULL;)
  173.         {
  174.                 gpstTail=pstNode->next;
  175.                 free(pstNode);
  176.                 pstNode=gpstTail;
  177.         }
  178. }

  179. void vGenFood(int iIdx)
  180. {
  181.         struct stNode *pstNode;
  182.         int i,iFound=0;
  183.        
  184.         for(;!iFound;)
  185.         {
  186.                 iFound=1;
  187.                 gastFood[iIdx].x=rand()%(WIN_X2-WIN_X1-1)+WIN_X1+1;
  188.                 gastFood[iIdx].y=rand()%(WIN_Y2-WIN_Y1-1)+WIN_Y1+1;
  189.                 for(i=0;i<giRich;i++)
  190.                 {
  191.                         if(i!=iIdx && gastFood[iIdx].x==gastFood[i].x &&
  192.                                 gastFood[iIdx].y==gastFood[i].y)
  193.                         {
  194.                                 iFound=0;
  195.                                 break;
  196.                         }
  197.                 }
  198.                 if(!iFound) continue;
  199.                 for(pstNode=gpstTail;pstNode!=NULL;pstNode=pstNode->next)
  200.                 {
  201.                         if(gastFood[iIdx].x==pstNode->x &&
  202.                                 gastFood[iIdx].y==pstNode->y)
  203.                         {
  204.                                 iFound=0;
  205.                                 break;
  206.                         }
  207.                 }
  208.                 if(!iFound) continue;
  209.         }
  210.         vDrawOneFood(gastFood[iIdx].x,gastFood[iIdx].y);
  211. }

  212. void vInitFood()
  213. {
  214.         int i;
  215.        
  216.         srand(getpid());
  217.         for(i=0;i<giRich;i++)        vGenFood(i);
  218. }
  219.        
  220. int iIsValid(int x,int y)
  221. {
  222.         struct stNode *pstNode;

  223.         if(x<=WIN_X1 || x>=WIN_X2 || y<=WIN_Y1 || y>=WIN_Y2)
  224.                 return(0);
  225.         pstNode=gpstTail;
  226.         for(;pstNode!=NULL;)
  227.         {
  228.                 if(x==pstNode->x && y==pstNode->y)
  229.                         return(0);
  230.                 pstNode=pstNode->next;
  231.         }
  232.         return(1);
  233. }

  234. int iEat(int x,int y)
  235. {
  236.         int i,j;
  237.        
  238.         for(i=0;i<giRich;i++)
  239.         {
  240.                 if(x==gastFood[i].x && y==gastFood[i].y)
  241.                 {
  242.                         vGenFood(i);
  243.                         giScore+=giLevel*10;
  244.                         giLen++;
  245.                         if(giLevel<MAX_LEVEL)
  246.                                 if(giLen%DEVRATE==0)
  247.                                         giLevel++;
  248.                         return(1);
  249.                 }
  250.         }
  251.         return(0);
  252. }
  253. main()
  254. {
  255.         int iDir=2,iNextX,iNextY;
  256.         struct stNode *pstNew;
  257.         char sPrompt[80];
  258.        
  259.         vInitScreen();
  260.         vDrawScope();
  261.         vCreateSnake();
  262.         vInitFood();
  263.         for(;;)
  264.         {
  265.                 iDir=iGetDir(iDir);
  266.                 iNextX=gpstHead->x+(iDir>>1)*(5-(iDir<<1));
  267.                 iNextY=gpstHead->y-(!(iDir>>1))*(1-(iDir<<1));
  268.                 if(!iIsValid(iNextX,iNextY))
  269.                 {
  270.                         printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
  271.                                 WIN_Y2-1,(WIN_X1+WIN_X2)/2-strlen(OVER)/2,OVER);
  272.                         break;
  273.                 }
  274.                 pstNew=(struct stNode*)malloc(sizeof(struct stNode));
  275.                 pstNew->x=iNextX;
  276.                 pstNew->y=iNextY;
  277.                 pstNew->shape=SNAKE_SHAPE;
  278.                 pstNew->next=NULL;
  279.                 gpstHead->next=pstNew;
  280.                 gpstHead=pstNew;
  281.                 vDrawOneNode(gpstHead,1);
  282.                 if(!iEat(iNextX,iNextY))
  283.                 {
  284.                         vDrawOneNode(gpstHead,1);
  285.                         vDrawOneNode(gpstTail,0);
  286.                         pstNew=gpstTail;
  287.                         gpstTail=pstNew->next;
  288.                         free(pstNew);
  289.                 }
  290.                 sprintf(sPrompt,"Score:%7d Level:%2d",giScore,giLevel);
  291.                 printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
  292.                         WIN_Y2,(WIN_X1+WIN_X2)/2-strlen(sPrompt)/2,sPrompt);
  293.         }
  294.         vKillSnake();
  295.         vRestoreScreen();
  296. }
复制代码

编译方法:
AIX下:cc -qcpluscmt -o snake snake.c
sco unix下:cc -o snake snake.c

[ 本帖最后由 forest077 于 2008-6-25 13:23 编辑 ]
作者: LinuxKen    时间: 2008-06-25 13:20
代码写得很漂亮,支持,友情帮顶!
作者: LinuxKen    时间: 2008-06-25 13:33
gcc加了-Wall选项之后出现了N多警告,主要是一些头文件没加进去;
另外,不知道搂主是在什么环境下跑这个程序的,我的机器跑了之后没看到什么。
作者: forest077    时间: 2008-06-25 13:37
标题: 回复 #3 LinuxKen 的帖子
我在AIX下开发的。 sco下虽然没试过,但是以我的经验,跑起来应该没问题。
作者: 204tian    时间: 2008-06-25 14:10
跑了就看到个界面, 看不到蛇和豆子, 一会就 GAME OVER了
作者: converse    时间: 2008-06-25 14:14
我还记得刚来CU时看到LZ在shell版发的shell学习体会~~

作者: forest077    时间: 2008-06-25 14:40
标题: 回复 #5 204tian 的帖子
你在什么环境下的?linux下我不敢保证可以运行。
作者: forest077    时间: 2008-06-25 14:42
标题: 回复 #6 converse 的帖子
哈哈,多谢,你还记得呀
作者: forest077    时间: 2008-06-25 14:45
可惜我这边找不到linux环境,要不然可以试试
作者: 5毛党党员    时间: 2008-06-25 15:11
Segmentation fault (core dumped)

在AIX下。。。
作者: forest077    时间: 2008-06-25 15:32
标题: 回复 #10 5毛党党员 的帖子
不会吧?!有清屏吗?有界面出来吗?神奇了,为什么你们运行都不行呢?

[ 本帖最后由 forest077 于 2008-6-25 15:41 编辑 ]
作者: 5毛党党员    时间: 2008-06-25 16:15
有清屏,有方框

Segmentation fault (core dumped) 显示在方框左下角
作者: 77h2_eleven    时间: 2008-06-25 16:18
跪拜高手~~~~~~~~~~~~~~~~·
作者: forest077    时间: 2008-06-25 16:33
标题: 回复 #12 5毛党党员 的帖子
难道你机器执行malloc和free有问题?
作者: 204tian    时间: 2008-06-25 16:40
原帖由 forest077 于 2008-6-25 14:40 发表
你在什么环境下的?linux下我不敢保证可以运行。



恩, 我的确实是linux
作者: Kevin_zqw    时间: 2008-06-25 16:41
没有试,看上去很好
作者: 小公猫    时间: 2008-06-25 16:41
我在RedHat AS4下面编译出现警告:
snack.c: In function `settty':
snack.c:53: warning: passing arg 1 of `open' makes pointer from integer without a cast
不过程序可以运行,吃了两颗豆子,正要吃第三颗的时候毫无提示就Game Over了~
作者: tassard    时间: 2008-06-25 16:42
标题: 回复 #14 forest077 的帖子
我在linux下编译很顺利就通过了

满好玩的,特别是多按几下方向键还能加速,很实用!

等会看看能不能把它移植到把它移植到windows上去
作者: forest077    时间: 2008-06-26 09:06
这下奇怪了,同样是AIX,有人可以有人不行,同样是linux,也是有人可以有人不行,还有人一半行的。大概是编译环境不一样的原因造成的。因为我只有AIX,所以就没办法保证兼容性了。有兴趣的可以在别的环境下调试一下我的程序,也许只是一些函数在使用上有细微区别而已。
作者: cugb_cat    时间: 2008-06-26 12:02
呵呵,前段时间给老婆做UNIX课的作业,做了个弹球的游戏,也是curses库~。
作者: yecheng_110    时间: 2008-06-26 12:42
原帖由 cugb_cat 于 2008-6-26 12:02 发表
呵呵,前段时间给老婆做UNIX课的作业,做了个弹球的游戏,也是curses库~。

LZ没有用curses库
作者: forest077    时间: 2008-06-26 13:54
标题: 回复 #20 cugb_cat 的帖子
呵呵,我这是有一天开会,坐在下面实在无聊,一时兴起写的。后来又花了点时间调试,成功了就放上来了。不过,yecheng_110说得对,我用的不是curses库,是直接写控制字符的。

[ 本帖最后由 forest077 于 2008-6-26 15:09 编辑 ]
作者: c/unix    时间: 2008-06-26 15:55
提示: 作者被禁止或删除 内容自动屏蔽
作者: forest077    时间: 2008-06-30 10:51
标题: 回复 #23 c/unix 的帖子
谢谢,你是什么环境的?有了结果欢迎告诉大家。
作者: ldy2534    时间: 2008-06-30 13:28
lz
我用的是ubuntu ,运行起来,只看到边框,下边的坐标会变,过一会就gameover了
作者: xi2008wang    时间: 2008-06-30 13:45
fc8:编译时,有多个警告,编译后可正常运行.

在加了几个头文件就可以正常编译了
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
另外iEat中的自动变量j没有使用
作者: cugb_cat    时间: 2008-06-30 14:03
原帖由 forest077 于 2008-6-26 13:54 发表
呵呵,我这是有一天开会,坐在下面实在无聊,一时兴起写的。后来又花了点时间调试,成功了就放上来了。不过,yecheng_110说得对,我用的不是curses库,是直接写控制字符的。

ANSI控制字符?
作者: xi2008wang    时间: 2008-06-30 14:16
原帖由 cugb_cat 于 2008-6-30 14:03 发表

ANSI控制字符?

从这里可以看出来
printf("\033[1m\033[40;36m\033[%d;%d;H%c",y,x,'@');
作者: cugb_cat    时间: 2008-06-30 14:20
原帖由 xi2008wang 于 2008-6-30 14:16 发表

从这里可以看出来
printf("\033[1m\033[40;36m\033[%d;%d;H%c",y,x,'@');

那就是了,呵呵,代码没看~
作者: ldy2534    时间: 2008-07-01 11:19
哈哈。可以了,把代码vDrawOneNode 这个函数里边printf 中的 H前边的;去掉就可以了,
还有 vDrawOneFood 里边一样
作者: beepbug    时间: 2008-07-01 12:57
楼主没用curses库,光标操作是用终端控制序列实现的。应该与系统无关,而与终端特性有关。你的终端必须完全支持楼主代码所使用过的所有终端控制序列。
作者: lzm098    时间: 2008-07-04 22:28
还是有很多不爽的地方,比如蛇走过后没有清除路径
作者: 可可熊    时间: 2008-07-05 16:48
写得挺漂亮的~~
作者: flf21    时间: 2008-07-05 17:26
原帖由 beepbug 于 2008-7-1 12:57 发表
楼主没用curses库,光标操作是用终端控制序列实现的。应该与系统无关,而与终端特性有关。你的终端必须完全支持楼主代码所使用过的所有终端控制序列。

这位仁兄说对得有理,呵呵!
作者: chinacio    时间: 2008-07-17 11:11
中标普华Linux 3.0下编译通过,顺利执行,只在编译时报了一个警告:

snake.c: In function `settty':
snake.c:53: warning: passing arg 1 of `open' makes pointer from integer without a cast

环境:
内核:2.6.9-22.0.1
gcc:
gcc-gnat-3.4.4-2
libgcc-3.4.4-2
gcc-3.4.4-2
gcc4-gfortran-4.0.1-4.2
compat-libgcc-296-2.96-132.7.2
compat-gcc-32-c++-3.2.3-47.3
gcc-c++-3.4.4-2
gcc-objc-3.4.4-2
compat-gcc-32-3.2.3-47.3
gcc-g77-3.4.4-2
gcc4-4.0.1-4.2
gcc4-c++-4.0.1-4.2
gcc-java-3.4.4-2
作者: jiangq83    时间: 2010-06-26 15:40
回复 1# forest077


   keyi cankao yixia
作者: bluesea666    时间: 2010-06-26 23:51
学习了.
作者: Magic_LP    时间: 2010-06-27 00:17
楼主,我回帖了,我是Windows....
作者: xiaoQ008    时间: 2010-06-29 19:11
提示: 作者被禁止或删除 内容自动屏蔽
作者: suavelee    时间: 2010-07-01 08:52
提示: 作者被禁止或删除 内容自动屏蔽
作者: eyan422    时间: 2010-08-06 00:50
下来试试
作者: linux爽    时间: 2010-08-14 21:23
:wink:
作者: a_jige    时间: 2010-10-02 00:54
ding ding ding ~~~
作者: DNFCF    时间: 2010-11-13 21:37
顶一下
作者: 谁不虚伪    时间: 2011-10-14 23:43
Linux下已测试,能编译通过,但是不能运行出东西
作者: geekchina    时间: 2012-01-28 13:13
我去 sco unix  下试试
作者: chinesedragon    时间: 2012-01-28 21:18
不错!!!
作者: hanzhenlll    时间: 2012-02-24 14:57
ubuntu 9.10 和 ubuntu 10.04都不行.......中英文语言都有 开始我还是以为是乱码的原因


我都看不到
                    /^\/^\
                  _|__|  O|
         \/     /~     \_/ \
          \____|__________/  \
                 \_______      \
                         `\     \                 \
                           |     |                  \
                          /      /                    \
                         /     /                       \\
                       /      /                         \ \
                      /     /                            \  \
                    /     /             _----_            \   \
                   /     /           _-~      ~-_         |   |
                  (      (        _-~    _--_    ~-_     _/   |
                   \      ~-____-~    _-~    ~-_    ~-_-~    /
                     ~-_           _-~          ~-_       _-~   
                        ~--______-~                ~-___-~
作者: hqs3527    时间: 2012-03-13 12:36
redhat可以运行,不过路径没清空,横向、纵向速度不同
作者: eliry    时间: 2012-03-13 14:13
加上string.h和unistd.h后,编译通过。运行没问题,不过小蛇走过之处都没有恢复背景颜色,算是略微一点点瑕疵吧
作者: hbyiwen    时间: 2012-03-13 18:23
我ubuntu11.10下,编译有几个警告,但可以运行,效果不错
作者: zhyue122    时间: 2012-03-13 19:04
学到了谢谢啊  
作者: ckf513728912    时间: 2012-03-14 00:36
顶一下
作者: xhb8413    时间: 2012-03-16 11:56
。。牛人啊
作者: 饮马黄河源    时间: 2012-03-19 15:10
请问楼主53行“if((fd = open(ttyname(1),O_RDWR))==-1)”中ttyname(1)是什么意思?
作者: 唯吾顾家三少    时间: 2012-05-16 20:45
看看虽然还不是很理解,不过真心感觉很不错
作者: ran3guns    时间: 2012-06-02 22:11
*nix c的编码, 用驼峰式代码, 看着总是很别扭!
作者: comoon    时间: 2012-06-04 22:39
ubuntu12运行正常,顶一个!
作者: jfxl    时间: 2012-07-26 10:43
好帖, 学习了。
作者: ccjsj1    时间: 2012-07-26 12:37
好东西,谢谢分享!
在rhel5.1下make时有几个告警,但运行正常。

[uniadmin@BW-UGC-TAS1 snake]$ make t1
cc     t1.c   -o t1
t1.c: In function 'settty':
t1.c:53: warning: passing argument 1 of 'open' makes pointer from integer without a cast
t1.c: In function 'main':
t1.c:295: warning: incompatible implicit declaration of built-in function 'strlen'
t1.c:316: warning: incompatible implicit declaration of built-in function 'strlen'
作者: zm_wl    时间: 2012-07-26 16:26
这个表示学生时代,意义重大   
作者: galaxy001    时间: 2012-08-07 10:49
把warning都去掉了。
putty下显示正常。

--- a/c_cpp/etc/tiny/snake.c
+++ b/c_cpp/etc/tiny/snake.c
@@ -15,6 +15,9 @@ sco unix下:cc -o snake snake.c
#include <sys/select.h>
#include <termio.h>
#include <fcntl.h>
+#include <unistd.h> // ttyname
+#include <stdlib.h> // rand, srand
+#include <string.h> // strlen

#define SNAKE_INITX 5
#define SNAKE_INITY 5
@@ -265,7 +268,7 @@ int iIsValid(int x,int y)

int iEat(int x,int y)
{
-               int i,j;
+               int i;

                for(i=0;i<giRich;i++)
                {
@@ -282,7 +285,7 @@ int iEat(int x,int y)
                }
                return(0);
}
-main()
+int main()
{
                int iDir=2,iNextX,iNextY;
                struct stNode *pstNew;
@@ -299,7 +302,7 @@ main()
                                iNextY=gpstHead->y-(!(iDir>>1))*(1-(iDir<<1));
                                if(!iIsValid(iNextX,iNextY))
                                {
-                                               printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
+                                               printf("\033[%d;%zdH\033[1m\033[40;34m%s\033[0m",
                                                                WIN_Y2-1,(WIN_X1+WIN_X2)/2-strlen(OVER)/2,OVER);
                                                break;
                                }
@@ -320,7 +323,7 @@ main()
                                                free(pstNew);
                                }
                                sprintf(sPrompt,"Score:%7d Level:%2d",giScore,giLevel);
-                               printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
+                               printf("\033[%d;%zdH\033[1m\033[40;34m%s\033[0m",
                                                WIN_Y2,(WIN_X1+WIN_X2)/2-strlen(sPrompt)/2,sPrompt);
                }
                vKillSnake();

作者: pppaulpeter    时间: 2012-08-17 11:29
linux系统下,一开始在虚拟终端下运行出来的是乱码,后来看到34楼说程序与运行终端有关,才意识到应该换成tty1,运行出来的结果很好,顶一个。不知道lz整个程序都是自己构思一行一行打出来的,还是在一些别人的代码上改进?
作者: yufei19870113    时间: 2012-08-22 06:10
可惜我这边找不到linux环境,要不然可以试试
作者: 我想当好人    时间: 2012-09-06 15:07
回复 25# ldy2534


    我也是这个问题 编译环境和AIX不一样吧
作者: apww    时间: 2012-09-08 18:10
好久不使用UNIX了,看了正亲切!
作者: wlxmhls    时间: 2012-09-11 11:07
本帖最后由 wlxmhls 于 2012-09-11 17:02 编辑

我不明白iGetDir函数的switch分支,为什么要判断iFlag==2呢,iflag初始值是0啊
程序刚运行的时候iflag是0吧
---------------------------
我搞明白了……
作者: elivans    时间: 2012-10-26 17:39
跑完后,把我的终端屏幕改成了黑底黄字
作者: fengyun530    时间: 2012-11-08 21:15
可惜没注释,看不太懂!
作者: 大盛的ai    时间: 2012-11-08 23:23
小弟新手,弱弱的问一下楼主,怎么在论坛中发这种代码风格的帖子?
作者: suwenqiang2011    时间: 2012-11-14 16:15
/***snake.c***/
#include <stdio.h>
#include <malloc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <termio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define SNAKE_INITX 5
#define SNAKE_INITY 5
#define SNAKE_SHAPE '*'
#define SNAKE_INITLEN 8

#define WIN_X1 1
#define WIN_X2 80
#define WIN_Y1 1
#define WIN_Y2 24

#define MAX_LEVEL 20
#define MAX_INTER 200000
#define MIN_INTER 0
#define MAX_RICH 10
#define DEVRATE 5
#define OVER "Game Over!!!"

struct stNode {
        int x;
        int y;
        char shape;
        struct stNode *next;
};

struct stFood {
        int x;
        int y;
};

struct stNode *gpstHead, *gpstTail;
struct stFood gastFood[MAX_RICH];
int giLevel = 1;
int giRich = 1;
int giScore = 0;
int giLen = 0;

void settty(int iFlag)
{
        int fd;
        struct termio stTerm;

        if((fd = open(ttyname(1), O_RDWR)) == -1)        //ttyname()返回tty1的name  
                return;                                        //fd是打开tty1
        if(iFlag == 1)
        {
                ioctl(fd, TCGETA, &stTerm);        //获取tty1的状态
                stTerm.c_lflag &= ~ICANON;        //设置tty1的状态
                stTerm.c_lflag &= ~ECHO;
                stTerm.c_cc[4] = 1;
                stTerm.c_cc[5] = 0;
                stTerm.c_iflag &= ~ISTRIP;
                stTerm.c_cflag |= CS8;
                stTerm.c_cflag &= ~PARENB;
                ioctl(fd, TCSETA, &stTerm);
        } else
        {
                ioctl(fd, TCGETA, &stTerm);
                stTerm.c_lflag |= ICANON;
                stTerm.c_lflag |= ECHO;
                stTerm.c_cc[4] = 4;
                stTerm.c_cc[5] = 5;
                stTerm.c_iflag &= ~ISTRIP;
                stTerm.c_cflag |= CS8;
                stTerm.c_cflag &= ~PARENB;
                ioctl(fd, TCSETA, &stTerm);
        }
        close(fd);
}

//绘制蛇的节点
void vDrawOneNode(struct stNode *pstNode, int iFlag)
{
    if(iFlag == 1)
    {
            printf("\033[%dm\033[%d;%dm\033[%d;%dH%c",
                   iFlag,40, 33, pstNode->y, pstNode->x, pstNode->shape);
    }
    if(iFlag == 0)
    {
            printf("\033[%dm\033[%d;%dH%c",
                   iFlag, pstNode->y, pstNode->x, ' ');
    }
    //修改了蛇的运行轨迹BUG
        //printf("\033[%dm\033[%d;%dm\033[%d;%dH%c",
        //           iFlag,45 - iFlag * 5, 35 - iFlag * 2, pstNode->y, pstNode->x, pstNode->shape);
        fflush(stdout);
}

void vDrawOneFood(int x, int y)
{
        printf("\033[1m\033[40;36m\033[%d;%dH%c", y, x, '@');
        fflush(stdout);
}

int iGetDir(int iOriDir)
{
        fd_set rset;
        struct timeval hTmo;
        int iRet, iFlag = 0;
        char cCh;

        FD_ZERO(&rset);
        FD_SET(0, &rset);
        hTmo.tv_sec = 0;
        hTmo.tv_usec = MAX_INTER - (MAX_INTER - MIN_INTER) / MAX_LEVEL * giLevel;

        iRet = select(1, &rset, NULL, NULL, &hTmo);
        if(iRet <= 0)
        {
                return (iOriDir);
        }
        for (;
        {
                cCh = getchar();
                if(cCh != -1)
                {
                        switch (cCh)
                        {
                        case 27:
                        case 91:
                                iFlag++;
                                break;
                        case 65:                        //UP
                        case 66:                        //DOWN
                        case 67:                        //RIGHT
                        case 68:                        //LEFT
                                if(iFlag == 2)
                                        return ((!((cCh - 0x41) ^ iOriDir ^ 1)) ^ (cCh - 0x41));
                        default:
                                return (iOriDir);
                        }
                }
        }
}

void vInitScreen()
{
        settty(1);
        printf("\033[?25l\033[2J";        //隐藏光标和清屏
}

void vRestoreScreen()
{
    //修正了游戏结束时,屏幕显示的BUG
        //printf("\033[25;1H\033[0m\033[46;37m\033[?25h";
        printf("\033[25;1H\033[0m\033[?25h";
        settty(0);
}

void vDrawScope()
{
        int i, j;

        for (j = WIN_Y1; j <= WIN_Y2; j += WIN_Y2 - WIN_Y1)
        {
                printf("\033[%d;%dH+", j, WIN_X1);        //光标定位和答应每行开头的“+”号
                for (i = WIN_X1 + 1; i < WIN_X2; i++)
                        printf("-";                //打印每行中间的“-”
                printf("+";                        //打印每行末尾的“+”
        }
        for (i = WIN_Y1 + 1; i < WIN_Y2; i++)
                //将第二行到倒数第二行中间设置为空,同时开头和末尾设置为“|”
                //不明白为什么只有三个占位符,却又四个参数?
                printf("\033[%d;%dH|%*c|\n", i, WIN_X1, WIN_X2 - WIN_X1 - 1, ' ');
}

void vCreateSnake()
{
        struct stNode *pstNew;
        int i;

        gpstHead = (struct stNode *) malloc(sizeof(struct stNode));        //为蛇头开辟空间,同时初始化蛇头位置
        gpstHead->x = SNAKE_INITX;
        gpstHead->y = SNAKE_INITY;
        gpstHead->shape = SNAKE_SHAPE;
        gpstHead->next = NULL;
        vDrawOneNode(gpstHead, 1);        //绘制蛇头节点
        gpstTail = gpstHead;
        for (i = 1; i < SNAKE_INITLEN; i++)        //绘制其他蛇身节点
        {
                pstNew = (struct stNode *) malloc(sizeof(struct stNode));
                pstNew->x = gpstHead->x + 1;
                pstNew->y = gpstHead->y;
                pstNew->shape = SNAKE_SHAPE;
                pstNew->next = NULL;
                vDrawOneNode(pstNew, 1);
                gpstHead->next = pstNew;
                gpstHead = pstNew;
        }
        return;
}

void vKillSnake()
{
        struct stNode *pstNode;

        for (pstNode = gpstTail; gpstTail != NULL
        {
                gpstTail = pstNode->next;
                free(pstNode);
                pstNode = gpstTail;
        }
}

void vGenFood(int iIdx)
{
        struct stNode *pstNode;
        int i, iFound = 0;

        for (; !iFound
        {
                iFound = 1;
                gastFood[iIdx].x = rand() % (WIN_X2 - WIN_X1 - 1) + WIN_X1 + 1;
                gastFood[iIdx].y = rand() % (WIN_Y2 - WIN_Y1 - 1) + WIN_Y1 + 1;
                for (i = 0; i < giRich; i++)
                {
                        if(i != iIdx && gastFood[iIdx].x == gastFood.x &&
                           gastFood[iIdx].y == gastFood.y)
                        {
                                iFound = 0;
                                break;
                        }
                }
                if(!iFound)
                        continue;
                for (pstNode = gpstTail; pstNode != NULL; pstNode = pstNode->next)
                {
                        if(gastFood[iIdx].x == pstNode->x && gastFood[iIdx].y == pstNode->y)
                        {
                                iFound = 0;
                                break;
                        }
                }
                if(!iFound)
                        continue;
        }
        vDrawOneFood(gastFood[iIdx].x, gastFood[iIdx].y);
}

void vInitFood()
{
        int i;

        srand(getpid());
        for (i = 0; i < giRich; i++)
                vGenFood(i);
}

int iIsValid(int x, int y)
{
        struct stNode *pstNode;

        if(x <= WIN_X1 || x >= WIN_X2 || y <= WIN_Y1 || y >= WIN_Y2)
                return (0);
        pstNode = gpstTail;
        for (; pstNode != NULL
        {
                if(x == pstNode->x && y == pstNode->y)
                        return (0);
                pstNode = pstNode->next;
        }
        return (1);
}

int iEat(int x, int y)
{
        int i;

        for (i = 0; i < giRich; i++)
        {
                if(x == gastFood.x && y == gastFood.y)
                {
                        vGenFood(i);
                        giScore += giLevel * 10;
                        giLen++;
                        if(giLevel < MAX_LEVEL)
                                if(giLen % DEVRATE == 0)
                                        giLevel++;
                        return (1);
                }
        }
        return (0);
}

int main(void)
{
        int iDir = 2, iNextX, iNextY;
        struct stNode *pstNew;
        char sPrompt[80];

        vInitScreen();                                //初始化tty1和清屏
        vDrawScope();                                //绘制外围边框
        vCreateSnake();                                //创建蛇的原型
        vInitFood();                                //初始化食物
        for (;
        {
                iDir = iGetDir(iDir);
                iNextX = gpstHead->x + (iDir >> 1) * (5 - (iDir << 1));
                iNextY = gpstHead->y - (!(iDir >> 1)) * (1 - (iDir << 1));
                if(!iIsValid(iNextX, iNextY))
                {
                        printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
                                   WIN_Y2 - 1, (WIN_X1 + WIN_X2) / 2 - strlen(OVER) / 2, OVER);
                        break;
                }
                pstNew = (struct stNode *) malloc(sizeof(struct stNode));
                pstNew->x = iNextX;
                pstNew->y = iNextY;
                pstNew->shape = SNAKE_SHAPE;
                pstNew->next = NULL;
                gpstHead->next = pstNew;
                gpstHead = pstNew;
                vDrawOneNode(gpstHead, 1);
                if(!iEat(iNextX, iNextY))
                {
                        //vDrawOneNode(gpstHead, 1);
                        vDrawOneNode(gpstTail, 0);
                        pstNew = gpstTail;
                        gpstTail = pstNew->next;
                        free(pstNew);
                }
                sprintf(sPrompt, "Score:%7d Level:%2d", giScore, giLevel);
                printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
                           WIN_Y2, (WIN_X1 + WIN_X2) / 2 - strlen(sPrompt) / 2, sPrompt);
        }
        vKillSnake();
        vRestoreScreen();
        return 0;
}

我把楼主的代码带了一些注释,另外修改了两个小问题,
1.蛇路过的地方,会留下轨迹。2.游戏结束后会修改背景和字体的颜色
作者: suwenqiang2011    时间: 2012-11-14 16:17
/***snake.c***/
#include <stdio.h>
#include <malloc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <termio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define SNAKE_INITX 5
#define SNAKE_INITY 5
#define SNAKE_SHAPE '*'
#define SNAKE_INITLEN 8

#define WIN_X1 1
#define WIN_X2 80
#define WIN_Y1 1
#define WIN_Y2 24

#define MAX_LEVEL 20
#define MAX_INTER 200000
#define MIN_INTER 0
#define MAX_RICH 10
#define DEVRATE 5
#define OVER "Game Over!!!"

struct stNode {
        int x;
        int y;
        char shape;
        struct stNode *next;
};

struct stFood {
        int x;
        int y;
};

struct stNode *gpstHead, *gpstTail;
struct stFood gastFood[MAX_RICH];
int giLevel = 1;
int giRich = 1;
int giScore = 0;
int giLen = 0;

void settty(int iFlag)
{
        int fd;
        struct termio stTerm;

        if((fd = open(ttyname(1), O_RDWR)) == -1)        //ttyname()返回tty1的name  
                return;                                        //fd是打开tty1
        if(iFlag == 1)
        {
                ioctl(fd, TCGETA, &stTerm);        //获取tty1的状态
                stTerm.c_lflag &= ~ICANON;        //设置tty1的状态
                stTerm.c_lflag &= ~ECHO;
                stTerm.c_cc[4] = 1;
                stTerm.c_cc[5] = 0;
                stTerm.c_iflag &= ~ISTRIP;
                stTerm.c_cflag |= CS8;
                stTerm.c_cflag &= ~PARENB;
                ioctl(fd, TCSETA, &stTerm);
        } else
        {
                ioctl(fd, TCGETA, &stTerm);
                stTerm.c_lflag |= ICANON;
                stTerm.c_lflag |= ECHO;
                stTerm.c_cc[4] = 4;
                stTerm.c_cc[5] = 5;
                stTerm.c_iflag &= ~ISTRIP;
                stTerm.c_cflag |= CS8;
                stTerm.c_cflag &= ~PARENB;
                ioctl(fd, TCSETA, &stTerm);
        }
        close(fd);
}

//绘制蛇的节点
void vDrawOneNode(struct stNode *pstNode, int iFlag)
{
    if(iFlag == 1)
    {
            printf("\033[%dm\033[%d;%dm\033[%d;%dH%c",
                   iFlag,40, 33, pstNode->y, pstNode->x, pstNode->shape);
    }
    if(iFlag == 0)
    {
            printf("\033[%dm\033[%d;%dH%c",
                   iFlag, pstNode->y, pstNode->x, ' ');
    }
    //修改了蛇的运行轨迹BUG
        //printf("\033[%dm\033[%d;%dm\033[%d;%dH%c",
        //           iFlag,45 - iFlag * 5, 35 - iFlag * 2, pstNode->y, pstNode->x, pstNode->shape);
        fflush(stdout);
}

void vDrawOneFood(int x, int y)
{
        printf("\033[1m\033[40;36m\033[%d;%dH%c", y, x, '@');
        fflush(stdout);
}

int iGetDir(int iOriDir)
{
        fd_set rset;
        struct timeval hTmo;
        int iRet, iFlag = 0;
        char cCh;

        FD_ZERO(&rset);
        FD_SET(0, &rset);
        hTmo.tv_sec = 0;
        hTmo.tv_usec = MAX_INTER - (MAX_INTER - MIN_INTER) / MAX_LEVEL * giLevel;

        iRet = select(1, &rset, NULL, NULL, &hTmo);
        if(iRet <= 0)
        {
                return (iOriDir);
        }
        for (;;)
        {
                cCh = getchar();
                if(cCh != -1)
                {
                        switch (cCh)
                        {
                        case 27:
                        case 91:
                                iFlag++;
                                break;
                        case 65:                        //UP
                        case 66:                        //DOWN
                        case 67:                        //RIGHT
                        case 68:                        //LEFT
                                if(iFlag == 2)
                                        return ((!((cCh - 0x41) ^ iOriDir ^ 1)) ^ (cCh - 0x41));
                        default:
                                return (iOriDir);
                        }
                }
        }
}

void vInitScreen()
{
        settty(1);
        printf("\033[?25l\033[2J");        //隐藏光标和清屏
}

void vRestoreScreen()
{
    //修正了游戏结束时,屏幕显示的BUG
        //printf("\033[25;1H\033[0m\033[46;37m\033[?25h");
        printf("\033[25;1H\033[0m\033[?25h");
        settty(0);
}

void vDrawScope()
{
        int i, j;

        for (j = WIN_Y1; j <= WIN_Y2; j += WIN_Y2 - WIN_Y1)
        {
                printf("\033[%d;%dH+", j, WIN_X1);        //光标定位和答应每行开头的“+”号
                for (i = WIN_X1 + 1; i < WIN_X2; i++)
                        printf("-");                //打印每行中间的“-”
                printf("+");                        //打印每行末尾的“+”
        }
        for (i = WIN_Y1 + 1; i < WIN_Y2; i++)
                //将第二行到倒数第二行中间设置为空,同时开头和末尾设置为“|”
                //不明白为什么只有三个占位符,却又四个参数?
                printf("\033[%d;%dH|%*c|\n", i, WIN_X1, WIN_X2 - WIN_X1 - 1, ' ');
}

void vCreateSnake()
{
        struct stNode *pstNew;
        int i;

        gpstHead = (struct stNode *) malloc(sizeof(struct stNode));        //为蛇头开辟空间,同时初始化蛇头位置
        gpstHead->x = SNAKE_INITX;
        gpstHead->y = SNAKE_INITY;
        gpstHead->shape = SNAKE_SHAPE;
        gpstHead->next = NULL;
        vDrawOneNode(gpstHead, 1);        //绘制蛇头节点
        gpstTail = gpstHead;
        for (i = 1; i < SNAKE_INITLEN; i++)        //绘制其他蛇身节点
        {
                pstNew = (struct stNode *) malloc(sizeof(struct stNode));
                pstNew->x = gpstHead->x + 1;
                pstNew->y = gpstHead->y;
                pstNew->shape = SNAKE_SHAPE;
                pstNew->next = NULL;
                vDrawOneNode(pstNew, 1);
                gpstHead->next = pstNew;
                gpstHead = pstNew;
        }
        return;
}

void vKillSnake()
{
        struct stNode *pstNode;

        for (pstNode = gpstTail; gpstTail != NULL;)
        {
                gpstTail = pstNode->next;
                free(pstNode);
                pstNode = gpstTail;
        }
}

void vGenFood(int iIdx)
{
        struct stNode *pstNode;
        int i, iFound = 0;

        for (; !iFound;)
        {
                iFound = 1;
                gastFood[iIdx].x = rand() % (WIN_X2 - WIN_X1 - 1) + WIN_X1 + 1;
                gastFood[iIdx].y = rand() % (WIN_Y2 - WIN_Y1 - 1) + WIN_Y1 + 1;
                for (i = 0; i < giRich; i++)
                {
                        if(i != iIdx && gastFood[iIdx].x == gastFood[i].x &&
                           gastFood[iIdx].y == gastFood[i].y)
                        {
                                iFound = 0;
                                break;
                        }
                }
                if(!iFound)
                        continue;
                for (pstNode = gpstTail; pstNode != NULL; pstNode = pstNode->next)
                {
                        if(gastFood[iIdx].x == pstNode->x && gastFood[iIdx].y == pstNode->y)
                        {
                                iFound = 0;
                                break;
                        }
                }
                if(!iFound)
                        continue;
        }
        vDrawOneFood(gastFood[iIdx].x, gastFood[iIdx].y);
}

void vInitFood()
{
        int i;

        srand(getpid());
        for (i = 0; i < giRich; i++)
                vGenFood(i);
}

int iIsValid(int x, int y)
{
        struct stNode *pstNode;

        if(x <= WIN_X1 || x >= WIN_X2 || y <= WIN_Y1 || y >= WIN_Y2)
                return (0);
        pstNode = gpstTail;
        for (; pstNode != NULL;)
        {
                if(x == pstNode->x && y == pstNode->y)
                        return (0);
                pstNode = pstNode->next;
        }
        return (1);
}

int iEat(int x, int y)
{
        int i;

        for (i = 0; i < giRich; i++)
        {
                if(x == gastFood[i].x && y == gastFood[i].y)
                {
                        vGenFood(i);
                        giScore += giLevel * 10;
                        giLen++;
                        if(giLevel < MAX_LEVEL)
                                if(giLen % DEVRATE == 0)
                                        giLevel++;
                        return (1);
                }
        }
        return (0);
}

int main(void)
{
        int iDir = 2, iNextX, iNextY;
        struct stNode *pstNew;
        char sPrompt[80];

        vInitScreen();                                //初始化tty1和清屏
        vDrawScope();                                //绘制外围边框
        vCreateSnake();                                //创建蛇的原型
        vInitFood();                                //初始化食物
        for (;;)
        {
                iDir = iGetDir(iDir);
                iNextX = gpstHead->x + (iDir >> 1) * (5 - (iDir << 1));
                iNextY = gpstHead->y - (!(iDir >> 1)) * (1 - (iDir << 1));
                if(!iIsValid(iNextX, iNextY))
                {
                        printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
                                   WIN_Y2 - 1, (WIN_X1 + WIN_X2) / 2 - strlen(OVER) / 2, OVER);
                        break;
                }
                pstNew = (struct stNode *) malloc(sizeof(struct stNode));
                pstNew->x = iNextX;
                pstNew->y = iNextY;
                pstNew->shape = SNAKE_SHAPE;
                pstNew->next = NULL;
                gpstHead->next = pstNew;
                gpstHead = pstNew;
                vDrawOneNode(gpstHead, 1);
                if(!iEat(iNextX, iNextY))
                {
                        //vDrawOneNode(gpstHead, 1);
                        vDrawOneNode(gpstTail, 0);
                        pstNew = gpstTail;
                        gpstTail = pstNew->next;
                        free(pstNew);
                }
                sprintf(sPrompt, "Score:%7d Level:%2d", giScore, giLevel);
                printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
                           WIN_Y2, (WIN_X1 + WIN_X2) / 2 - strlen(sPrompt) / 2, sPrompt);
        }
        vKillSnake();
        vRestoreScreen();
        return 0;
}

上面不知道为什么有表情
作者: liwenchengdu    时间: 2012-11-16 00:00
学习下……
作者: zyy_linux    时间: 2013-03-02 16:12
还不错,不该不是linux下的
作者: tansijie    时间: 2013-03-28 19:39
我试着在redhat 下编译了一把,贴上源代码,解释权归楼主哈。

  1. /***snake.c***/
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. #include <sys/time.h>
  5. #include <sys/types.h>
  6. #include <sys/select.h>
  7. #include <termio.h>
  8. #include <fcntl.h>
  9. #include <sys/stat.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #define SNAKE_INITX 5
  14. #define SNAKE_INITY 5
  15. #define SNAKE_SHAPE '*'
  16. #define SNAKE_INITLEN 8

  17. #define WIN_X1 1
  18. #define WIN_X2 80
  19. #define WIN_Y1 1
  20. #define WIN_Y2 24

  21. #define MAX_LEVEL 20
  22. #define MAX_INTER 200000
  23. #define MIN_INTER 0
  24. #define MAX_RICH 10
  25. #define DEVRATE 5
  26. #define OVER "Game Over!!!"

  27. struct stNode
  28. {
  29.         int x;
  30.         int y;
  31.         char shape;
  32.         struct stNode *next;
  33. };

  34. struct stFood
  35. {
  36.         int x;
  37.         int y;
  38. };

  39. struct stNode *gpstHead,*gpstTail;
  40. struct stFood gastFood[MAX_RICH];
  41. int giLevel=1;
  42. int giRich=1;
  43. int giScore=0;
  44. int giLen=0;

  45. void settty(int iFlag)
  46. {
  47.         int fd;
  48.         struct termio stTerm;

  49.         if((fd = open(ttyname(1),O_RDWR))==-1)        return;
  50.         if(iFlag == 1)
  51.         {
  52.                 ioctl(fd,TCGETA,&stTerm);
  53.                 stTerm.c_lflag &= ~ICANON;
  54.                 stTerm.c_lflag &= ~ECHO;
  55.                 stTerm.c_cc[4] = 1;
  56.                 stTerm.c_cc[5] = 0;
  57.                 stTerm.c_iflag &= ~ISTRIP;
  58.                 stTerm.c_cflag |= CS8;
  59.                 stTerm.c_cflag &= ~PARENB;
  60.                 ioctl(fd,TCSETA,&stTerm);
  61.         }
  62.         else
  63.         {
  64.                 ioctl(fd,TCGETA,&stTerm);
  65.                 stTerm.c_lflag |= ICANON;
  66.                 stTerm.c_lflag |= ECHO;
  67.                 stTerm.c_cc[4] = 4;
  68.                 stTerm.c_cc[5] = 5;
  69.                 stTerm.c_iflag &= ~ISTRIP;
  70.                 stTerm.c_cflag |= CS8;
  71.                 stTerm.c_cflag &= ~PARENB;
  72.                 ioctl(fd,TCSETA,&stTerm);
  73.         }
  74.         close(fd);
  75. }

  76. void vDrawOneNode(struct stNode *pstNode,int iFlag)
  77. {
  78.         printf("\033[%dm\033[40;%dm\033[%d;%d;H%c",
  79.                 iFlag,iFlag*3+30,pstNode->y,pstNode->x,pstNode->shape);
  80.         fflush(stdout);
  81. }

  82. void vDrawOneFood(int x,int y)
  83. {
  84.         printf("\033[1m\033[40;36m\033[%d;%d;H%c",y,x,'@');
  85.         fflush(stdout);
  86. }

  87. int iGetDir(int iOriDir)
  88. {
  89.         fd_set rset;
  90.         struct        timeval        hTmo;
  91.         int iRet,iFlag=0;
  92.         char cCh;

  93.         FD_ZERO(&rset);
  94.         FD_SET(0,&rset);
  95.         hTmo.tv_sec=0;
  96.         hTmo.tv_usec=MAX_INTER-(MAX_INTER-MIN_INTER)/MAX_LEVEL*giLevel;

  97.         iRet=select(1,&rset,NULL,NULL,&hTmo);
  98.         if(iRet<=0)
  99.         {
  100.                 return(iOriDir);
  101.         }
  102.         for(;;)
  103.         {
  104.                 cCh=getchar();
  105.                 if(cCh != -1)
  106.                 {
  107.                         switch(cCh)
  108.                         {         
  109.                         case 27  :
  110.                         case 91  :
  111.                                 iFlag++;
  112.                                 break;
  113.                         case 65  ://UP
  114.                         case 66 ://DOWN
  115.                         case 67  ://RIGHT
  116.                         case 68 ://LEFT
  117.                         if(iFlag==2)
  118.                                 return((!((cCh-0x41)^iOriDir^1))^(cCh-0x41));
  119.                         default  :
  120.                                 return(iOriDir);
  121.                         }
  122.                 }
  123.         }
  124. }
  125. void vInitScreen()
  126. {
  127.         settty(1);
  128.         printf("\033[?25l\033[2J");
  129. }

  130. void vRestoreScreen()
  131. {
  132.         printf("\033[24;1H\033[1m\033[40;34m\033[?25h");
  133.         settty(0);
  134. }

  135. void vDrawScope()
  136. {
  137.         int i,j;
  138.         
  139.         for(j=WIN_Y1;j<=WIN_Y2;j+=WIN_Y2-WIN_Y1)
  140.         {
  141.                 printf("\033[%d;%dH+",j,WIN_X1);
  142.                 for(i=WIN_X1+1;i<WIN_X2;i++)
  143.                         printf("-");
  144.                 printf("+");
  145.         }
  146.         for(i=WIN_Y1+1;i<WIN_Y2;i++)
  147.                 printf("\033[%d;%dH|%*c|\n",i,WIN_X1,WIN_X2-WIN_X1-1,' ');
  148. }

  149. void vCreateSnake()
  150. {
  151.         struct stNode *pstNew;
  152.         int i;

  153.         gpstHead=(struct stNode*)malloc(sizeof(struct stNode));
  154.         gpstHead->x=SNAKE_INITX;        
  155.         gpstHead->y=SNAKE_INITY;
  156.         gpstHead->shape=SNAKE_SHAPE;
  157.         gpstHead->next=NULL;
  158.         vDrawOneNode(gpstHead,1);
  159.         gpstTail=gpstHead;
  160.         for(i=1;i<SNAKE_INITLEN;i++)
  161.         {
  162.                 pstNew=(struct stNode*)malloc(sizeof(struct stNode));
  163.                 pstNew->x=gpstHead->x+1;        
  164.                 pstNew->y=gpstHead->y;
  165.                 pstNew->shape=SNAKE_SHAPE;
  166.                 pstNew->next=NULL;
  167.                 vDrawOneNode(pstNew,1);
  168.                 gpstHead->next=pstNew;
  169.                 gpstHead=pstNew;
  170.         }
  171.         return;
  172. }

  173. void vKillSnake()
  174. {
  175.         struct stNode *pstNode;

  176.         for(pstNode=gpstTail;gpstTail!=NULL;)
  177.         {
  178.                 gpstTail=pstNode->next;
  179.                 free(pstNode);
  180.                 pstNode=gpstTail;
  181.         }
  182. }

  183. void vGenFood(int iIdx)
  184. {
  185.         struct stNode *pstNode;
  186.         int i,iFound=0;
  187.         
  188.         for(;!iFound;)
  189.         {
  190.                 iFound=1;
  191.                 gastFood[iIdx].x=rand()%(WIN_X2-WIN_X1-1)+WIN_X1+1;
  192.                 gastFood[iIdx].y=rand()%(WIN_Y2-WIN_Y1-1)+WIN_Y1+1;
  193.                 for(i=0;i<giRich;i++)
  194.                 {
  195.                         if(i!=iIdx && gastFood[iIdx].x==gastFood[i].x &&
  196.                                 gastFood[iIdx].y==gastFood[i].y)
  197.                         {
  198.                                 iFound=0;
  199.                                 break;
  200.                         }
  201.                 }
  202.                 if(!iFound) continue;
  203.                 for(pstNode=gpstTail;pstNode!=NULL;pstNode=pstNode->next)
  204.                 {
  205.                         if(gastFood[iIdx].x==pstNode->x &&
  206.                                 gastFood[iIdx].y==pstNode->y)
  207.                         {
  208.                                 iFound=0;
  209.                                 break;
  210.                         }
  211.                 }
  212.                 if(!iFound) continue;
  213.         }
  214.         vDrawOneFood(gastFood[iIdx].x,gastFood[iIdx].y);
  215. }

  216. void vInitFood()
  217. {
  218.         int i;
  219.         
  220.         srand(getpid());
  221.         for(i=0;i<giRich;i++)        vGenFood(i);
  222. }
  223.         
  224. int iIsValid(int x,int y)
  225. {
  226.         struct stNode *pstNode;

  227.         if(x<=WIN_X1 || x>=WIN_X2 || y<=WIN_Y1 || y>=WIN_Y2)
  228.                 return(0);
  229.         pstNode=gpstTail;
  230.         for(;pstNode!=NULL;)
  231.         {
  232.                 if(x==pstNode->x && y==pstNode->y)
  233.                         return(0);
  234.                 pstNode=pstNode->next;
  235.         }
  236.         return(1);
  237. }

  238. int iEat(int x,int y)
  239. {
  240.         int i,j;
  241.         
  242.         for(i=0;i<giRich;i++)
  243.         {
  244.                 if(x==gastFood[i].x && y==gastFood[i].y)
  245.                 {
  246.                         vGenFood(i);
  247.                         giScore+=giLevel*10;
  248.                         giLen++;
  249.                         if(giLevel<MAX_LEVEL)
  250.                                 if(giLen%DEVRATE==0)
  251.                                         giLevel++;
  252.                         return(1);
  253.                 }
  254.         }
  255.         return(0);
  256. }
  257. main()
  258. {
  259.         int iDir=2,iNextX,iNextY;
  260.         struct stNode *pstNew;
  261.         char sPrompt[80];
  262.         
  263.         vInitScreen();
  264.         vDrawScope();
  265.         vCreateSnake();
  266.         vInitFood();
  267.         for(;;)
  268.         {
  269.                 iDir=iGetDir(iDir);
  270.                 iNextX=gpstHead->x+(iDir>>1)*(5-(iDir<<1));
  271.                 iNextY=gpstHead->y-(!(iDir>>1))*(1-(iDir<<1));
  272.                 if(!iIsValid(iNextX,iNextY))
  273.                 {
  274.                         printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
  275.                                 WIN_Y2-1,(WIN_X1+WIN_X2)/2-strlen(OVER)/2,OVER);
  276.                         break;
  277.                 }
  278.                 pstNew=(struct stNode*)malloc(sizeof(struct stNode));
  279.                 pstNew->x=iNextX;
  280.                 pstNew->y=iNextY;
  281.                 pstNew->shape=SNAKE_SHAPE;
  282.                 pstNew->next=NULL;
  283.                 gpstHead->next=pstNew;
  284.                 gpstHead=pstNew;
  285.                 vDrawOneNode(gpstHead,1);
  286.                 if(!iEat(iNextX,iNextY))
  287.                 {
  288.                         vDrawOneNode(gpstHead,1);
  289.                         vDrawOneNode(gpstTail,0);
  290.                         pstNew=gpstTail;
  291.                         gpstTail=pstNew->next;
  292.                         free(pstNew);
  293.                 }
  294.                 sprintf(sPrompt,"Score:%7d Level:%2d",giScore,giLevel);
  295.                 printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",
  296.                         WIN_Y2,(WIN_X1+WIN_X2)/2-strlen(sPrompt)/2,sPrompt);
  297.         }
  298.         vKillSnake();
  299.         vRestoreScreen();
  300. }
复制代码

作者: huzi74148    时间: 2013-03-30 11:33
不错呀。对新手来说真的是不错
作者: myzonesky    时间: 2013-08-01 10:32
Linux 下可以跑吗?
作者: zhangxinkevin    时间: 2013-08-16 17:31

作者: zhangxinkevin    时间: 2013-08-16 17:33
回复 77# myzonesky


    看截图~
作者: miniuinx    时间: 2013-10-14 16:38
在AIX下。。。
作者: zhangjy2008327    时间: 2013-10-16 13:33
linux下貌似有点问题,不过瑕不掩玉啊,LZ
作者: dididimeme01    时间: 2013-10-16 14:27
我是AIX的环境,没有发现问题。呵呵,挺好的
作者: cobras    时间: 2013-10-17 00:25
windows控制台版本。
  1. /***snake.c***/

  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <time.h>

  6. #include <windows.h>

  7. #define SNAKE_INITX 5
  8. #define SNAKE_INITY 5
  9. #define SNAKE_SHAPE '*'
  10. #define SNAKE_INITLEN 8

  11. #define WIN_X1 0
  12. #define WIN_X2 79
  13. #define WIN_Y1 0
  14. #define WIN_Y2 24

  15. #define MAX_LEVEL 20
  16. #define MAX_INTER 200000
  17. #define MIN_INTER 0
  18. #define MAX_RICH 10
  19. #define DEVRATE 5
  20. #define OVER "Game Over!!!"

  21. struct stNode
  22. {
  23.         int x;
  24.         int y;
  25.         char shape;
  26.         struct stNode *next;
  27. };

  28. struct stFood
  29. {
  30.         int x;
  31.         int y;
  32. };

  33. struct stNode *gpstHead,*gpstTail;
  34. struct stFood gastFood[MAX_RICH];
  35. int giLevel=1;
  36. int giRich=1;
  37. int giScore=0;
  38. int giLen=0;

  39. int con_get_size(int *o_width, int *o_height)
  40. {
  41.         CONSOLE_SCREEN_BUFFER_INFO info;
  42.         HANDLE hStdOutput;
  43.        
  44.         hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  45.         GetConsoleScreenBufferInfo(hStdOutput, &info);
  46.         if (o_width != NULL) {
  47.                 *o_width = info.dwMaximumWindowSize.X;
  48.         }
  49.         if (o_height != NULL) {
  50.                 *o_height = info.dwMaximumWindowSize.Y;
  51.         }
  52.         return 0;
  53. }

  54. int con_rectangle(int x1, int y1, int x2, int y2, char c)
  55. {
  56.         HANDLE hStdOutput;
  57.         COORD coord;
  58.         DWORD dwOutputlen;
  59.         int len;
  60.         int width, height;
  61.        
  62.         con_get_size(&width, &height);
  63.         if (x1 < 0) {
  64.                 x1 = 0;
  65.         }
  66.         if (y1 < 0) {
  67.                 y1 = 0;
  68.         }
  69.         if (x2 >= width) {
  70.                 x2 = width - 1;
  71.         }
  72.         if (y2 >= height) {
  73.                 y2 = height - 1;
  74.         }
  75.         if (x1 <= x2 && y1 <= y2) {
  76.                 hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  77.                 len = x2 - x1 + 1;
  78.                 coord.X = x1;
  79.                 for (coord.Y = y1; coord.Y <= y2; ++coord.Y) {
  80.                         FillConsoleOutputCharacter(hStdOutput, c, len, coord, &dwOutputlen);
  81.                 }
  82.                 return 0;
  83.         }
  84.         return -1;
  85. }

  86. int con_init(void)
  87. {
  88.         HANDLE hStdOutput;
  89.         DWORD dwMode;
  90.        
  91.         hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  92.         GetConsoleMode(hStdOutput, &dwMode);
  93.         dwMode &= ~ENABLE_WRAP_AT_EOL_OUTPUT;
  94.         SetConsoleMode(hStdOutput, dwMode);
  95.         return 0;
  96. }

  97. int con_show_cursor(int yes)
  98. {
  99.         HANDLE hStdOutput;
  100.         CONSOLE_CURSOR_INFO info;
  101.        
  102.         hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  103.         GetConsoleCursorInfo(hStdOutput, &info);
  104.         info.bVisible = yes != 0;
  105.         SetConsoleCursorInfo(hStdOutput, &info);
  106.         return 0;
  107. }

  108. int con_setxy(int x, int y)
  109. {
  110.         HANDLE hStdOutput;
  111.         COORD coord;
  112.        
  113.         hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  114.         coord.X = x;
  115.         coord.Y = y;
  116.         SetConsoleCursorPosition(hStdOutput, coord);
  117.         return 0;
  118. }

  119. int con_putchar(int x, int y, char c)
  120. {
  121.         int width, height;
  122.        
  123.         con_get_size(&width, &height);
  124.         if (x >= 0 && x < width && y >= 0 && y < height) {
  125.                 con_setxy(x, y);
  126.                 putchar(c);
  127.                 return 0;
  128.         }
  129.         return -1;
  130. }

  131. int con_puttext(int x, int y, const char *text, int text_len)
  132. {
  133.         int tx;
  134.         int i;
  135.         int width, height;
  136.        
  137.         con_get_size(&width, &height);
  138.         tx = x;
  139.         for (i = 0; i < text_len; ++i) {
  140.                 switch (text[i]) {
  141.                 case '\n':
  142.                         tx = x;
  143.                         ++y;
  144.                         break;
  145.                 case '\t':
  146.                         tx = (tx + 8 - 1) / 8;
  147.                         tx *= 8;
  148.                         break;
  149.                 case '\r':
  150.                         tx = x;
  151.                         break;
  152.                 case '\b':
  153.                         if (tx > x) {
  154.                                 --tx;
  155.                         }
  156.                         break;
  157.                 default:
  158.                         if (tx >= 0 && tx < width && y >= 0 && y < height) {
  159.                                 con_setxy(tx, y);
  160.                                 putchar(text[i]);
  161.                         }
  162.                         ++tx;
  163.                         break;
  164.                 }
  165.         }
  166.         return 0;
  167. }

  168. int con_box(int x1, int y1, int x2, int y2)
  169. {
  170.         int i;
  171.        
  172.         for (i = x1 + 1; i < x2; ++i) {
  173.                 con_puttext(i, y1, "-", 1);
  174.                 con_puttext(i, y2, "-", 1);
  175.         }
  176.         for (i = y1 + 1; i < y2; ++i) {
  177.                 con_puttext(x1, i, "|", 1);
  178.                 con_puttext(x2, i, "|", 1);
  179.         }
  180.         con_puttext(x1, y1, "+", 1);
  181.         con_puttext(x2, y1, "+", 1);
  182.         con_puttext(x1, y2, "+", 1);
  183.         con_puttext(x2, y2, "+", 1);
  184.         return 0;
  185. }

  186. int con_readkey(void)
  187. {
  188.         HANDLE hStdInput;
  189.         INPUT_RECORD buf;
  190.         DWORD dwRead;
  191.         int retval;
  192.        
  193.         hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  194.         for (;;) {
  195.                 if (PeekConsoleInput(hStdInput, &buf, 1, &dwRead)) {
  196.                         if (dwRead == 1) {
  197.                                 if (ReadConsoleInput(hStdInput, &buf, 1, &dwRead)) {
  198.                                         if (buf.EventType == KEY_EVENT) {
  199.                                                 return buf.Event.KeyEvent.wVirtualScanCode;
  200.                                         }else {
  201.                                                 continue;
  202.                                         }
  203.                                 }else {
  204.                                         retval = -2; /* READ ERROR */
  205.                                 }
  206.                         }else {
  207.                                 retval = 0; /* NO KEY PRESSED */
  208.                         }
  209.                 }else {
  210.                         retval = -1; /* PEEK ERROR */
  211.                 }
  212.                 break;
  213.         }
  214.         return retval;
  215. }

  216. int con_delay(int ms)
  217. {
  218.         Sleep(ms);
  219.         return 0;
  220. }

  221. void vDrawOneNode(struct stNode *pstNode,int iFlag)
  222. {
  223.         con_puttext(pstNode->x, pstNode->y, iFlag ? &pstNode->shape : " ", 1);
  224. }

  225. void vDrawOneFood(int x,int y)
  226. {
  227.         con_puttext(x, y, "@", 1);
  228. }

  229. int iGetDir(int iOriDir)
  230. {
  231.         switch (con_readkey()) {
  232.         case 72  ://UP
  233.                 return 0;
  234.         case 80 ://DOWN
  235.                 return 1;
  236.         case 77  ://RIGHT
  237.                 return 2;
  238.         case 75 ://LEFT
  239.                 return 3;
  240.         default:
  241.                 return iOriDir;
  242.         }
  243. }

  244. void vInitScreen()
  245. {
  246.         con_init();
  247.         con_show_cursor(0);
  248.         con_rectangle(WIN_X1, WIN_Y1, WIN_X2, WIN_Y2, ' ');
  249. }

  250. void vRestoreScreen()
  251. {
  252.         con_show_cursor(1);
  253. }

  254. void vDrawScope()
  255. {
  256.         con_box(WIN_X1, WIN_Y1, WIN_X2, WIN_Y2);
  257. }

  258. void vCreateSnake()
  259. {
  260.         struct stNode *pstNew;
  261.         int i;
  262.        
  263.         gpstHead=(struct stNode*)malloc(sizeof(struct stNode));
  264.         gpstHead->x=SNAKE_INITX;        
  265.         gpstHead->y=SNAKE_INITY;
  266.         gpstHead->shape=SNAKE_SHAPE;
  267.         gpstHead->next=NULL;
  268.         vDrawOneNode(gpstHead,1);
  269.         gpstTail=gpstHead;
  270.         for(i=1;i<SNAKE_INITLEN;i++)
  271.         {
  272.                 pstNew=(struct stNode*)malloc(sizeof(struct stNode));
  273.                 pstNew->x=gpstHead->x+1;        
  274.                 pstNew->y=gpstHead->y;
  275.                 pstNew->shape=SNAKE_SHAPE;
  276.                 pstNew->next=NULL;
  277.                 vDrawOneNode(pstNew,1);
  278.                 gpstHead->next=pstNew;
  279.                 gpstHead=pstNew;
  280.         }
  281.         return;
  282. }

  283. void vKillSnake()
  284. {
  285.         struct stNode *pstNode;
  286.        
  287.         for(pstNode=gpstTail;gpstTail!=NULL;)
  288.         {
  289.                 gpstTail=pstNode->next;
  290.                 free(pstNode);
  291.                 pstNode=gpstTail;
  292.         }
  293. }

  294. void vGenFood(int iIdx)
  295. {
  296.         struct stNode *pstNode;
  297.         int i,iFound=0;
  298.        
  299.         for(;!iFound;)
  300.         {
  301.                 iFound=1;
  302.                 gastFood[iIdx].x=rand()%(WIN_X2-WIN_X1-1)+WIN_X1+1;
  303.                 gastFood[iIdx].y=rand()%(WIN_Y2-WIN_Y1-1)+WIN_Y1+1;
  304.                 for(i=0;i<giRich;i++)
  305.                 {
  306.                         if(i!=iIdx && gastFood[iIdx].x==gastFood[i].x &&
  307.                                 gastFood[iIdx].y==gastFood[i].y)
  308.                         {
  309.                                 iFound=0;
  310.                                 break;
  311.                         }
  312.                 }
  313.                 if(!iFound) continue;
  314.                 for(pstNode=gpstTail;pstNode!=NULL;pstNode=pstNode->next)
  315.                 {
  316.                         if(gastFood[iIdx].x==pstNode->x &&
  317.                                 gastFood[iIdx].y==pstNode->y)
  318.                         {
  319.                                 iFound=0;
  320.                                 break;
  321.                         }
  322.                 }
  323.                 if(!iFound) continue;
  324.         }
  325.         vDrawOneFood(gastFood[iIdx].x,gastFood[iIdx].y);
  326. }

  327. void vInitFood()
  328. {
  329.         int i;
  330.        
  331.         srand(time(NULL));
  332.         for(i=0;i<giRich;i++)        vGenFood(i);
  333. }

  334. int iIsValid(int x,int y)
  335. {
  336.         struct stNode *pstNode;
  337.        
  338.         if(x<=WIN_X1 || x>=WIN_X2 || y<=WIN_Y1 || y>=WIN_Y2)
  339.                 return(0);
  340.         pstNode=gpstTail;
  341.         for(;pstNode!=NULL;)
  342.         {
  343.                 if(x==pstNode->x && y==pstNode->y)
  344.                         return(0);
  345.                 pstNode=pstNode->next;
  346.         }
  347.         return(1);
  348. }

  349. int iEat(int x,int y)
  350. {
  351.         int i;
  352.        
  353.         for(i=0;i<giRich;i++)
  354.         {
  355.                 if(x==gastFood[i].x && y==gastFood[i].y)
  356.                 {
  357.                         vGenFood(i);
  358.                         giScore+=giLevel*10;
  359.                         giLen++;
  360.                         if(giLevel<MAX_LEVEL)
  361.                                 if(giLen%DEVRATE==0)
  362.                                         giLevel++;
  363.                                 return(1);
  364.                 }
  365.         }
  366.         return(0);
  367. }

  368. int main(void)
  369. {
  370.         int iDir=2,iNextX,iNextY;
  371.         struct stNode *pstNew;
  372.         char sPrompt[80];
  373.        
  374.         vInitScreen();
  375.         vDrawScope();
  376.         vCreateSnake();
  377.         vInitFood();
  378.         for(;;) {
  379.                 iDir=iGetDir(iDir);
  380.                 iNextX=gpstHead->x+(iDir>>1)*(5-(iDir<<1));
  381.                 iNextY=gpstHead->y-(!(iDir>>1))*(1-(iDir<<1));
  382.                 if(!iIsValid(iNextX,iNextY)) {
  383.                         con_puttext((WIN_X1+WIN_X2)/2-strlen(OVER)/2, WIN_Y2-1,OVER, strlen(OVER));
  384.                         break;
  385.                 }
  386.                 pstNew=(struct stNode*)malloc(sizeof(struct stNode));
  387.                 pstNew->x=iNextX;
  388.                 pstNew->y=iNextY;
  389.                 pstNew->shape=SNAKE_SHAPE;
  390.                 pstNew->next=NULL;
  391.                 gpstHead->next=pstNew;
  392.                 gpstHead=pstNew;
  393.                 vDrawOneNode(gpstHead, 1);
  394.                 if(!iEat(iNextX,iNextY)) {
  395.                         vDrawOneNode(gpstTail, 0);
  396.                         pstNew = gpstTail;
  397.                         gpstTail = gpstTail->next;
  398.                         free(pstNew);
  399.                 }
  400.                 sprintf(sPrompt,"Score:%7d Level:%2d",giScore,giLevel);
  401.                 con_puttext((WIN_X1+WIN_X2)/2-strlen(sPrompt)/2, WIN_Y2, sPrompt, strlen(sPrompt));
  402.                 con_delay((MAX_INTER-(MAX_INTER-MIN_INTER)/MAX_LEVEL*giLevel)/1000);
  403.         }
  404.         vKillSnake();
  405.         vRestoreScreen();
  406.         return 0;
  407. }
复制代码

作者: 除美灭日平韩    时间: 2013-12-10 17:26
马克刘明!
作者: zsszss0000    时间: 2014-11-25 13:20
楼主,你太牛了
作者: ANONYMOUS419    时间: 2015-04-19 22:55
了不挨砖,喷一下。。楼主代码风骚
作者: jimmy817817    时间: 2015-07-24 10:30
试过了,编辑有错误,不过可以玩。系统是 solaris的
作者: incle    时间: 2015-07-30 10:18
不错,很赞啊。
作者: 创蓝253    时间: 2018-06-08 13:29
lollollol




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2