免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 12377 | 回复: 20
打印 上一主题 下一主题

[C] 字符界面的打字游戏 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-09-06 22:16 |只看该作者 |倒序浏览
这是在七月份完成的。
那时候我刚大学毕业,在家待着,看了一点linux多线程方面的东西,于是就写出了这个程序。
后来到工作单位报道,实习,工作,一直忙着,也没心思弄这些东西了。

现在将这个程序贴出来。。。
程序使用了三个线程,主线程绘制产生随机字母,并且绘制屏幕,一个线程接受输入并且与屏幕上的字母作比较,
另一个线程消去打中的字母,并且判断字母是否降落到了最下面。。。

使用了信号和线程之间的信号量来同步。
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <sys/time.h>
  7. #include <curses.h>
  8. #include <pthread.h>
  9. #include <semaphore.h>
  10. #include <signal.h>
  11. void *checkkey (void *arg);
  12. void *changekey (void *arg);
  13. void *isover (void *arg);
  14. WINDOW *a_win,*b_win,*c_win;
  15. pthread_t main_tid;
  16. sem_t sem_one,sem_two;
  17. int location,hit=0,n=400000,FLAG=1,hited_num=0,typed_num=0;
  18. void contin ()
  19. {
  20.         touchwin(a_win);wrefresh(a_win);
  21. }
  22. void paus ()
  23. {
  24.         touchwin(b_win);wrefresh(b_win);
  25.         pause();
  26. }
  27. void game_over ()
  28. {
  29.         touchwin(c_win);wrefresh(c_win);
  30.         pause();
  31.         FLAG=0;
  32.         return;
  33. }
  34. void stop (int usec)
  35. {
  36.         struct timeval tv;
  37.         tv.tv_sec=0;
  38.         tv.tv_usec=usec;
  39.         select(0,NULL,NULL,NULL,&tv);
  40. }
  41. int main ()
  42. {
  43.         int i,j,res,s=0,randnum;
  44.         struct sigaction to_pause,to_continue,to_over;
  45.         initscr();
  46.         noecho();cbreak();keypad(stdscr,TRUE);curs_set(0);
  47.         char *darwscr=(char *)malloc((LINES-2)*(COLS-16));
  48.         if(darwscr==NULL)
  49.         {
  50.                 perror("Malloc Failure");endwin();exit(1);
  51.         }
  52.         pthread_t new_one,new_two;
  53.         WINDOW *topwin,*pausewin,*overwin,*numwin;
  54.         topwin=newwin(LINES-2,COLS-16,0,8);
  55.         pausewin=newwin(1,COLS/2,LINES/2,COLS/4);
  56.         overwin=newwin(3,COLS/2,LINES/2+1,COLS/4);
  57.         numwin=newwin(1,9,LINES-1,COLS/2+18);
  58.         if(topwin==NULL || pausewin==NULL || overwin==NULL || numwin==NULL)
  59.         {
  60.                 perror("Create window Failure");endwin();exit(1);
  61.         }
  62.         a_win=topwin;b_win=pausewin;c_win=overwin;
  63.         if(!has_colors())
  64.         {
  65.                 perror("Devices not support colors");
  66.                 delwin(topwin);delwin(pausewin);delwin(overwin);
  67.                 delwin(numwin);endwin();exit(1);
  68.         }
  69.         if(start_color()!=OK)
  70.         {
  71.                 perror("Initialize Colors Failure");
  72.                 delwin(topwin);delwin(pausewin);delwin(overwin);
  73.                 delwin(numwin);endwin();exit(1);
  74.         }
  75.         init_pair(1,4,4);init_pair(2,7,4);
  76.         init_pair(3,1,1);init_pair(4,7,1);
  77.         clear();
  78.         for(i=0;i<LINES;i++)
  79.         {
  80.                 move(i,7);vline(0,1);
  81.                 move(i,COLS-7);vline(0,1);
  82.         }
  83.         wattron(stdscr,COLOR_PAIR(1));
  84.         for(i=0;i<COLS;i++) mvwaddch(stdscr,LINES-1,i,'a');
  85.         wattroff(stdscr,COLOR_PAIR(1));
  86.         wattron(stdscr,COLOR_PAIR(2));
  87.         mvwprintw(stdscr,LINES-1,(COLS-30)/2,"%s","Press '1' to PAUSE,'2' to QUIT");
  88.         wattroff(stdscr,COLOR_PAIR(2));
  89.         wattron(numwin,COLOR_PAIR(2));
  90.         refresh();
  91.         mvwprintw(numwin,0,0,"[%3d/%-3d]",hited_num,typed_num);
  92.         wrefresh(numwin);
  93.         wattron(pausewin,COLOR_PAIR(1));
  94.         for(i=0;i<COLS/2;i++) mvwaddch(pausewin,0,i,'a');
  95.         wattroff(pausewin,COLOR_PAIR(1));
  96.         wattron(pausewin,COLOR_PAIR(2));
  97.         mvwprintw(pausewin,0,2,"%s","Press 'CTRL-C' to Continue.");
  98.         wattroff(pausewin,COLOR_PAIR(2));
  99.         wattron(overwin,COLOR_PAIR(3));
  100.         for(i=0;i<3;i++)
  101.         {
  102.                 for(j=0;j<COLS/2;j++) mvwaddch(overwin,i,j,'a');
  103.         }
  104.         wattroff(overwin,COLOR_PAIR(3));
  105.         wattron(overwin,COLOR_PAIR(4));
  106.         mvwprintw(overwin,1,COLS/4-4,"%s","GAME OVER");
  107.         mvwprintw(overwin,2,COLS/4-8,"%s","'CTRL-C' to QUIT");
  108.         wattroff(overwin,COLOR_PAIR(4));
  109.         memset(darwscr,'\0',sizeof(darwscr));
  110.         to_pause.sa_handler=paus;
  111.         sigemptyset(&to_pause.sa_mask);
  112.         to_pause.sa_flags=0;
  113.         sigaction(SIGUSR1,&to_pause,0);
  114.         to_continue.sa_handler=contin;
  115.         sigemptyset(&to_continue.sa_mask);
  116.         to_continue.sa_flags=0;
  117.         sigaction(SIGINT,&to_continue,0);
  118.         to_over.sa_handler=game_over;
  119.         sigemptyset(&to_over.sa_mask);
  120.         to_over.sa_flags=0;
  121.         sigaction(SIGUSR2,&to_over,0);
  122.         main_tid=pthread_self();
  123.         res=pthread_create(&new_one,NULL,checkkey,(void *)darwscr);
  124.         res=pthread_create(&new_two,NULL,changekey,(void *)darwscr);
  125.         if(res!=0)
  126.         {
  127.                 perror("Thread Create Failure");
  128.                 delwin(topwin);delwin(pausewin);delwin(overwin);
  129.                 delwin(numwin);endwin();exit(1);
  130.         }
  131.         res=sem_init(&sem_one,0,0);
  132.         res=sem_init(&sem_two,0,0);
  133.         if(res!=0)
  134.         {
  135.                 perror("Semaphore Initialize Failure");
  136.                 delwin(topwin);delwin(pausewin);delwin(overwin);
  137.                 delwin(numwin);endwin();exit(1);
  138.         }
  139.         s=(int)time(NULL);
  140.         while(FLAG)
  141.         {
  142.                 s+=n/1000;
  143.                 srand(s);
  144.                 for(i=0;i<COLS-16;i++)
  145.                 {
  146.                         randnum=(int)(rand()/(double)RAND_MAX*1000);
  147.                         if(randnum<994)  *(darwscr+i)=' ';
  148.                         else
  149.                         {
  150.                                 randnum=(int)(rand()/(double)RAND_MAX*(123-97)+97);
  151.                                 *(darwscr+i)=(char)randnum;
  152.                         }
  153.                 }
  154.                 for(i=0;i<LINES-2;i++)
  155.                         mvwaddstr(topwin,i,0,darwscr+i*(COLS-16));
  156.                 wrefresh(topwin);
  157.                 sem_post(&sem_one);
  158.                 sem_wait(&sem_two);
  159.                 memmove(darwscr+COLS-16,darwscr,(LINES-3)*(COLS-16));
  160.                 mvwprintw(numwin,0,0,"[%3d/%-3d]",hited_num,typed_num);
  161.                 wrefresh(numwin);
  162.         }
  163.         free(darwscr);sem_destroy(&sem_one);sem_destroy(&sem_two);
  164.         delwin(topwin);delwin(pausewin);delwin(numwin);
  165.         delwin(overwin);endwin();exit(0);
  166. }
  167. void *checkkey (void *arg)
  168. {
  169.         int i,key;
  170.         char *p=(char *)arg;
  171.         while(1)
  172.         {
  173.                 key=getch();
  174.                 ++typed_num;
  175.                 if(key=='1') pthread_kill(main_tid,SIGUSR1);
  176.                 else if(key=='2') FLAG=0;
  177.                 else if(key>='a' && key<='z')
  178.                 {
  179.                         for(i=(LINES-2)*(COLS-16)-1;i>=0;i--)
  180.                         {
  181.                                 if(*(p+i)==key)
  182.                                 {
  183.                                         location=i;
  184.                                         hit=1;
  185.                                         ++hited_num;
  186.                                         break;
  187.                                 }
  188.                         }
  189.                 }
  190.         }
  191. }
  192. void *changekey (void *arg)
  193. {
  194.         const char *space=" ";
  195.         const char *over="@";
  196.         char *p=(char *)arg;
  197.         int last_location=0,times=0,m;
  198.         while(1)
  199.         {
  200.                 sem_wait(&sem_one);
  201.                 ++times;
  202.                 if(times<30) n=400000;
  203.                 else if(times>=30 && times <60) n=350000;
  204.                 else if(times>=60 && times<100) n=300000;
  205.                 else if(times>=100 && times<160) n=250000;
  206.                 else if(times>=160 && times <220) n=200000;
  207.                 else n=150000;
  208.                 stop(n);
  209.                 if(last_location) memcpy(p+last_location,space,1);
  210.                 last_location=0;
  211.                 if(hit)
  212.                 {
  213.                         memcpy(p+location,over,1);
  214.                         last_location=location+COLS-16;
  215.                 }
  216.                 for(m=(LINES-2)*(COLS-16)-1;m>(LINES-3)*(COLS-16);m--)
  217.                 {
  218.                         if(*(p+m)>='a' && *(p+m)<='z')
  219.                                 pthread_kill(main_tid,SIGUSR2);
  220.                 }
  221.                 sem_post(&sem_two);
  222.                 hit=0;
  223.         }
  224. }
复制代码

评分

参与人数 1可用积分 +5 收起 理由
lenky0401 + 5 支持原创

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2010-09-06 22:19 |只看该作者
这是运行时的截图

使用信号来完成的暂停功能。。。

show.png (29.59 KB, 下载次数: 37)

show.png

show1.png (30.29 KB, 下载次数: 32)

show1.png

论坛徽章:
0
3 [报告]
发表于 2010-09-06 22:53 |只看该作者
还是高级语言好! 用汇编写少说也得300+行

论坛徽章:
0
4 [报告]
发表于 2010-09-06 22:59 |只看该作者
初学要鼓励{:3_200:}
我记得我在学校编写的第一个c语言游戏程序是扫雷{:3_204:}

论坛徽章:
0
5 [报告]
发表于 2010-09-06 23:00 |只看该作者
TC2.0编写的 鼠标操作 15G的硬盘 坏掉了{:3_201:}

论坛徽章:
0
6 [报告]
发表于 2010-09-06 23:49 |只看该作者
TC2.0编写的 鼠标操作 15G的硬盘 坏掉了
lenky0401 发表于 2010-09-06 23:00



   

感谢前辈指导,,,

TC 有很好的图形库  ,可无奈的是 linux中 就一个 curses  ,还只能操作字符。。。

我完成这个打字游戏后 ,就觉得我一直想写的 俄罗斯方块 也离成功不远了 ,因为基本思路都是一样了。只是一直没去写。



前辈可知道有比CURSES更好的 图形库?

论坛徽章:
0
7 [报告]
发表于 2010-09-06 23:51 |只看该作者
同时在弱弱的问一下

硬盘是如何坏掉的。。。   

论坛徽章:
0
8 [报告]
发表于 2010-09-07 12:14 |只看该作者
记得上学时好像在TC下写过一个俄罗斯方块和一个台球游戏。

论坛徽章:
0
9 [报告]
发表于 2010-09-07 12:56 |只看该作者
用libsdl吧, 在X下写个图形界面的.

论坛徽章:
0
10 [报告]
发表于 2010-09-09 10:00 |只看该作者
感谢前辈指导,,,

TC 有很好的图形库  ,可无奈的是 linux中 就一个 curses  ,还只能操 ...
the4king 发表于 2010-09-06 23:49



    楼主做的很不错,支持。
我试过用printf在终端下作俄罗斯方块,效果如下。楼主可以尝试printf,不必用curse或其它什么。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP