忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
123456789
最近访问板块 发新帖
楼主: forest077

[算法] [原创]贡献一个unix的贪吃蛇小游戏 [复制链接]

论坛徽章:
0
发表于 2013-10-16 13:33 |显示全部楼层
linux下貌似有点问题,不过瑕不掩玉啊,LZ

论坛徽章:
0
发表于 2013-10-16 14:27 |显示全部楼层
我是AIX的环境,没有发现问题。呵呵,挺好的

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
发表于 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. }
复制代码

论坛徽章:
2
天秤座
日期:2014-01-15 13:50:58天秤座
日期:2014-02-19 17:09:23
发表于 2013-12-10 17:26 |显示全部楼层
马克刘明!

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
发表于 2014-11-25 13:20 |显示全部楼层
楼主,你太牛了

论坛徽章:
0
发表于 2015-04-19 22:55 |显示全部楼层
了不挨砖,喷一下。。楼主代码风骚

论坛徽章:
0
发表于 2015-07-24 10:30 |显示全部楼层
试过了,编辑有错误,不过可以玩。系统是 solaris的

论坛徽章:
18
技术图书徽章
日期:2018-08-22 12:54:30技术图书徽章
日期:2018-08-22 12:54:20技术图书徽章
日期:2018-08-22 12:53:5715-16赛季CBA联赛之北京
日期:2018-08-17 18:43:3315-16赛季CBA联赛之上海
日期:2018-07-25 11:55:2615-16赛季CBA联赛之青岛
日期:2018-07-10 14:13:18IT运维版块每日发帖之星
日期:2016-07-14 06:20:00每日论坛发贴之星
日期:2016-06-10 06:20:00综合交流区版块每日发帖之星
日期:2016-06-10 06:20:00黑曼巴
日期:2016-06-08 11:29:1815-16赛季CBA联赛之同曦
日期:2016-06-07 17:47:2815-16赛季CBA联赛之山东
日期:2016-04-18 10:23:10
发表于 2015-07-30 10:18 |显示全部楼层
不错,很赞啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:wangnan@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP