[转帖]unix下用终端控制字符实现的贪吃蛇小游戏_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4175 | 回复: 0   主题: [转帖]unix下用终端控制字符实现的贪吃蛇小游戏        下一篇 
yang.liu
注册用户
等级:少校
经验:1182
发帖:77
精华:1
注册:2014-1-3
状态:离线
发送短消息息给yang.liu 加好友    发送短消息息给yang.liu 发消息
发表于: IP:您无权察看 2014-1-9 9:41:17 | [全部帖] [楼主帖] 楼主

贡献一个原创小程序,是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.       
  46.       if((fd = open(ttyname(1),O_RDWR))==-1) return;
  47.       if(iFlag == 1)
  48.       {
  49.             ioctl(fd,TCGETA,&stTerm);
  50.             stTerm.c_lflag &= ~ICANON;
  51.             stTerm.c_lflag &= ~ECHO;
  52.             stTerm.c_cc[4] = 1;
  53.             stTerm.c_cc[5] = 0;
  54.             stTerm.c_iflag &= ~ISTRIP;
  55.             stTerm.c_cflag |= CS8;
  56.             stTerm.c_cflag &= ~PARENB;
  57.             ioctl(fd,TCSETA,&stTerm);
  58.       }
  59.       else
  60.       {
  61.             ioctl(fd,TCGETA,&stTerm);
  62.             stTerm.c_lflag |= ICANON;
  63.             stTerm.c_lflag |= ECHO;
  64.             stTerm.c_cc[4] = 4;
  65.             stTerm.c_cc[5] = 5;
  66.             stTerm.c_iflag &= ~ISTRIP;
  67.             stTerm.c_cflag |= CS8;
  68.             stTerm.c_cflag &= ~PARENB;
  69.             ioctl(fd,TCSETA,&stTerm);
  70.       }
  71.       close(fd);
  72. }
  73. void vDrawOneNode(struct stNode *pstNode,int iFlag)
  74. {
  75.       printf("\033[%dm\033[40;%dm\033[%d;%d;H%c",
  76.       iFlag,iFlag*3+30,pstNode->y,pstNode->x,pstNode->shape);
  77.       fflush(stdout);
  78. }
  79. void vDrawOneFood(int x,int y)
  80. {
  81.       printf("\033[1m\033[40;36m\033[%d;%d;H%c",y,x,'@');
  82.       fflush(stdout);
  83. }
  84. int iGetDir(int iOriDir)
  85. {
  86.       fd_set rset;
  87.       struct timeval hTmo;
  88.       int iRet,iFlag=0;
  89.       char cCh;
  90.       
  91.       FD_ZERO(&rset);
  92.       FD_SET(0,&rset);
  93.       hTmo.tv_sec=0;
  94.       hTmo.tv_usec=MAX_INTER-(MAX_INTER-MIN_INTER)/MAX_LEVEL*giLevel;
  95.       
  96.       iRet=select(1,&rset,NULL,NULL,&hTmo);
  97.       if(iRet<=0)
  98.       {
  99.             return(iOriDir);
  100.       }
  101.       for(;;)
  102.       {
  103.             cCh=getchar();
  104.             if(cCh != -1)
  105.             {
  106.                   switch(cCh)
  107.                   { 
  108.                         case 27 :
  109.                         case 91 :
  110.                         iFlag++;
  111.                         break;
  112.                         case 65 ://UP
  113.                         case 66 ://DOWN
  114.                         case 67 ://RIGHT
  115.                         case 68 ://LEFT
  116.                         if(iFlag==2)
  117.                         return((!((cCh-0x41)^iOriDir^1))^(cCh-0x41));
  118.                         default :
  119.                         return(iOriDir);
  120.                   }
  121.             }
  122.       }
  123. }
  124. void vInitScreen()
  125. {
  126.       settty(1);
  127.       printf("\033[?25l\033[2J");
  128. }
  129. void vRestoreScreen()
  130. {
  131.       printf("\033[24;1H\033[1m\033[40;34m\033[?25h");
  132.       settty(0);
  133. }
  134. void vDrawScope()
  135. {
  136.       int i,j;
  137.       
  138.       for(j=WIN_Y1;j<=WIN_Y2;j+=WIN_Y2-WIN_Y1)
  139.       {
  140.             printf("\033[%d;%dH+",j,WIN_X1);
  141.             for(i=WIN_X1+1;i<WIN_X2;i++)
  142.             printf("-");
  143.             printf("+");
  144.       }
  145.       for(i=WIN_Y1+1;i<WIN_Y2;i++)
  146.       printf("\033[%d;%dH|%*c|\n",i,WIN_X1,WIN_X2-WIN_X1-1,' ');
  147. }
  148. void vCreateSnake()
  149. {
  150.       struct stNode *pstNew;
  151.       int i;
  152.       
  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.       
  177.       for(pstNode=gpstTail;gpstTail!=NULL;)
  178.       {
  179.             gpstTail=pstNode->next;
  180.             free(pstNode);
  181.             pstNode=gpstTail;
  182.       }
  183. }
  184. void vGenFood(int iIdx)
  185. {
  186.       struct stNode *pstNode;
  187.       int i,iFound=0;
  188.       
  189.       for(;!iFound;)
  190.       {
  191.             iFound=1;
  192.             gastFood[iIdx].x=rand()%(WIN_X2-WIN_X1-1)+WIN_X1+1;
  193.             gastFood[iIdx].y=rand()%(WIN_Y2-WIN_Y1-1)+WIN_Y1+1;
  194.             for(i=0;i<giRich;i++)
  195.             {
  196.                   if(i!=iIdx && gastFood[iIdx].x==gastFood[i].x &&
  197.                   gastFood[iIdx].y==gastFood[i].y)
  198.                   {
  199.                         iFound=0;
  200.                         break;
  201.                   }
  202.             }
  203.             if(!iFound) continue;
  204.             for(pstNode=gpstTail;pstNode!=NULL;pstNode=pstNode->next)
  205.             {
  206.                   if(gastFood[iIdx].x==pstNode->x &&
  207.                   gastFood[iIdx].y==pstNode->y)
  208.                   {
  209.                         iFound=0;
  210.                         break;
  211.                   }
  212.             }
  213.             if(!iFound) continue;
  214.       }
  215.       vDrawOneFood(gastFood[iIdx].x,gastFood[iIdx].y);
  216. }
  217. void vInitFood()
  218. {
  219.       int i;
  220.       
  221.       srand(getpid());
  222.       for(i=0;i<giRich;i++) vGenFood(i);
  223. }
  224. int iIsValid(int x,int y)
  225. {
  226.       struct stNode *pstNode;
  227.       
  228.       if(x<=WIN_X1 || x>=WIN_X2 || y<=WIN_Y1 || y>=WIN_Y2)
  229.       return(0);
  230.       pstNode=gpstTail;
  231.       for(;pstNode!=NULL;)
  232.       {
  233.             if(x==pstNode->x && y==pstNode->y)
  234.             return(0);
  235.             pstNode=pstNode->next;
  236.       }
  237.       return(1);
  238. }
  239. int iEat(int x,int y)
  240. {
  241.       int i,j;
  242.       
  243.       for(i=0;i<giRich;i++)
  244.       {
  245.             if(x==gastFood[i].x && y==gastFood[i].y)
  246.             {
  247.                   vGenFood(i);
  248.                   giScore+=giLevel*10;
  249.                   giLen++;
  250.                   if(giLevel<MAX_LEVEL)
  251.                   if(giLen%DEVRATE==0)
  252.                   giLevel++;
  253.                   return(1);
  254.             }
  255.       }
  256.       return(0);
  257. }
  258. main()
  259. {
  260. int iDir=2,iNextX,iNextY;
  261. struct stNode *pstNew;
  262. char sPrompt[80];
  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. }



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




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论