+ -
当前位置:首页 → 问答吧 → 字符界面的打字游戏

字符界面的打字游戏

时间:2010-09-06

来源:互联网

这是在七月份完成的。
那时候我刚大学毕业,在家待着,看了一点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. }
复制代码

作者: the4king   发布时间: 2010-09-06

这是运行时的截图

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

show.png (29.59 KB)

下载次数:0

2010-09-06 22:19

show1.png (30.29 KB)

下载次数:0

2010-09-06 22:19

作者: lenky0401:   发布时间: 2010-09-06

还是高级语言好! 用汇编写少说也得300+行

作者: the4king   发布时间: 2010-09-06

初学要鼓励
我记得我在学校编写的第一个c语言游戏程序是扫雷

作者: dibug   发布时间: 2010-09-06

TC2.0编写的 鼠标操作 15G的硬盘 坏掉了

作者: lenky0401   发布时间: 2010-09-06



QUOTE:
TC2.0编写的 鼠标操作 15G的硬盘 坏掉了
lenky0401 发表于 2010-09-06 23:00




   

感谢前辈指导,,,

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

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



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

作者: lenky0401   发布时间: 2010-09-06

同时在弱弱的问一下

硬盘是如何坏掉的。。。   

作者: the4king   发布时间: 2010-09-06

相关阅读 更多

热门下载

更多