专栏首页wym手把手教你写linux系统下贪吃蛇(二)

手把手教你写linux系统下贪吃蛇(二)

转载请注明出处

完善后的代码:贪吃蛇过关版

在上一篇博客的基础上完成贪吃蛇(上一篇)。

需求:c语言基础。

这里需要线程的东西,不需要很了解,会用就行。

对线程不理解直接看第六部分主函数。

创建线程后把第一篇用到的refresh()函数都删除,不然因为缓存区的原因产生乱码

此时全局变量值要改变

第二部分写好以下几个函数

一)方向函数;(改变方向dirch)

二)删除头结点函数;(链表插入是尾插法,删除头节点,前进的‘头’是链表的‘尾部’。然后再增加结点,实现移动)

三)移动蛇身函数;(moveSnake())

四)线程函数一:(refresh_thread(),实现蛇的移动,调用第三个函数)

五)线程函数二;(operation_thread(),实现方向的改变,调用函数一)

六)主函数

为什么要用线程?

我们的c语言程序一般是单线程的,从主函数开始,一行一行执行,遇到函数就跳进函数,线程是让两个函数同时执行。

就像你现在看我的博客又在玩qq,这就是多线程。

 如果不用线程,就会让操作不能立刻显现,显得你的蛇很'笨'。

一)方向函数;(改变方向dirch)

void turn(int direction) { if(abs(direction) != dir){ dir = direction; } return ;

}

二)删除头结点函数;

void deleteHead() { node *tmp = head; head = head->next; free(tmp); tmp=NULL;

}

三)移动蛇身函数;

void moveSnake() { addSnakeBody(); if(food->x==tail->x && food->y==tail->y){ createFood(); num++; }else{ deleteHead(); } printw("score:%d",num); refreshInterface();

}

四)线程函数一:

void refresh_thread() { usleep(300000);//延时300000毫秒 moveSnake();

}

五)线程函数二

void operate_thread() { int op; // int num = 0; initCurses(); initDir(); createFood(); initSnake(); refreshInterface();         while(1){ op = getch(); switch(op){ case KEY_UP: turn(UP); break; case KEY_DOWN: turn(DOWN); break; case KEY_LEFT: turn(LEFT); break; case KEY_RIGHT: turn(RIGHT); break; } usleep(300000); moveSnake(); } }

六 。主函数

int main() { initCurses(); initDir(); createFood(); initSnake(); refreshInterface(); pthread_t pt_operate; pthread_t pt_refresh; pthread_create(&pt_operate,NULL,(void *)operate_thread,NULL);

pthread_create(&pt_refresh,NULL,(void *)refresh_thread,NULL);

//创建线程函数,原型:

/*int  pthread_create(pthread_t  *  thread,

pthread_attr_t * attr,

void * (*start_routine)(void *),

void * arg)*/

//第一个参数: 创建线程的ID     第二个参数: 线程属性,调度策略,优先级都在这里设置,如果NULL为默认属性

//第三个参数: 线程入口函数,可返回一个(void*)类型的返回值,该返回值可由pthread_join接收

//第四个参数:设置为NULL就好

pthread_join(pt_operate,NULL); pthread_join(pt_refresh,NULL);

/*一般来讲,进程中各个函数都是独立的,线程的终止并不会通知,也不会影响其他线程,终止的线程占用的资源也不会随着线程的终止得到释放,正如进程可以用wait()系统调用来同步终止并释放一切内存一样,在linux中没有进程,却有类似的函数

pthread_join();

函数原型:int pthread_join(pthread_t th, void **thread_return)

第一个参数线程ID,第二个设置为NULL就行

*/

        endwin();         return 0;

}

这个代码还不完善,根据需要自行修改。

汇总:

#include <curses.h> #include <stdlib.h> #include <pthread.h> #define BOADSIZE 20 #define UP       1 #define DOWN     -1 #define LEFT     2 #define RIGHT    -2 typedef struct SnakeBody { int x; int y; struct SnakeBody *next; }node; node *head; node *tail; node *food; int dir; int num = 0; void initCurses() {     initscr();     noecho();     keypad(stdscr,TRUE);     timeout(1); } void refreshInterface() { int x; int y;         mvprintw(0,0,""); printw("---------------Snake Game-----------------\n"); for(y=0;y<BOADSIZE;y++){ if(y==0){ for(x=0;x<=BOADSIZE;x++){ printw("--"); } printw("\n"); } for(x=0;x<BOADSIZE;x++){ if(x==0){ printw("|"); } if(hasSnake(x,y)==1){ printw("[]"); }else if((food->x==x)&&(food->y==y)){ printw("##"); }else{ printw("  "); } if(x==BOADSIZE-1){ printw("|"); } } printw("\n"); if(y==BOADSIZE-1){ for(x=0;x<=BOADSIZE;x++){ printw("--"); } printw("\n"); } } } void addSnakeBody() { node *new; node *tmp; tmp = (node *)malloc(sizeof(node)); new = (node *)malloc(sizeof(node)); tail->next = new; tmp = tail; tail = new; new->next = NULL; switch(dir){ case UP: new->x = tmp->x; new->y = tmp->y-1; break; case DOWN: new->x = tmp->x; new->y = tmp->y+1; break; case LEFT: new->x = tmp->x-1; new->y = tmp->y; break; case RIGHT: new->x = tmp->x+1; new->y = tmp->y; break; } } void initDir() { dir = RIGHT; } int hasSnake(int x,int y) { node *tmp; tmp = (node *)malloc(sizeof(node)); tmp = head; while(tmp!=NULL){ if(tmp->x==x && tmp->y==y){ return 1; } tmp = tmp->next; } return 0; } void initSnake() { head = tail = (node *)malloc(sizeof(node)); head->x = 0; head->y = 0; addSnakeBody(); addSnakeBody(); addSnakeBody(); } void createFood() { food = (node *)malloc(sizeof(node)); food->x = rand()&BOADSIZE-1; food->y =1 + rand()%BOADSIZE-1; } void deleteHead() { node *tmp = head; head = head->next; free(tmp); tmp=NULL; } void moveSnake() { // int num = 0; addSnakeBody(); if(food->x==tail->x && food->y==tail->y){ createFood(); num++; }else{ deleteHead(); } // if(tail->x<0||tail->x>BAODSIZE||tail->y<0||tail->y>BOADSIZE){ // } printw("score:%d",num); refreshInterface(); } void turn(int direction) { if(abs(direction) != dir){ dir = direction; // moveSnake(); } return ; } /*void updateScore() { printw("") } */ /* char *getTime() { time_t t; t = time(&t); return ctime(&t); } */ void operate_thread() { int op; // int num = 0; initCurses(); initDir(); createFood(); initSnake(); refreshInterface();         while(1){ op = getch(); switch(op){ case KEY_UP: turn(UP); // moveSnake(); break; case KEY_DOWN: turn(DOWN); // moveSnake(); break; case KEY_LEFT: turn(LEFT); // moveSnake(); break; case KEY_RIGHT: turn(RIGHT); // moveSnake(); break; } usleep(300000); moveSnake(); } } void refresh_thread() { usleep(300000); moveSnake(); } int main() { // int op; // int num = 0; initCurses(); initDir(); createFood(); initSnake(); refreshInterface(); /*         while(1){ op = getch(); switch(op){ case KEY_UP: turn(UP); // moveSnake(); break; case KEY_DOWN: turn(DOWN); // moveSnake(); break; case KEY_LEFT: turn(LEFT); // moveSnake(); break; case KEY_RIGHT: turn(RIGHT); // moveSnake(); break; } usleep(300000); moveSnake(); */ pthread_t pt_operate; pthread_t pt_refresh; pthread_create(&pt_operate,NULL,(void *)operate_thread,NULL); pthread_create(&pt_refresh,NULL,(void *)refresh_thread,NULL); pthread_join(pt_operate,NULL); pthread_join(pt_refresh,NULL); // operate(); // refresh();         endwin();         return 0; }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • P3834 【模板】可持久化线段树 1(主席树) (多次查询第k大或第k小)

    用户2965768
  • HDU 6370 Werewolf(并查集+dfs) 18年暑假多校赛第六场

    讲解博客:http://www.cnblogs.com/curieorz/p/9447454.html

    用户2965768
  • 2019 CCPC 重现赛 1006 基环树

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    用户2965768
  • 经典笔试题-try{}里有一个return语句,那么紧跟在这个try后的finally{}里德code会不会被执行?什么时候被执行,在return之前还是

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    cwl_java
  • 策略模式(Strategy)

    - 1.Strategy:策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略,实现定义的策略。

    qubianzhong
  • 挑战程序竞赛系列(24):3.5最大流与最小割

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    用户1147447
  • LintCode 802. 数独(回溯)/ LeetCode 37. 解数独

    编写一个程序,通过填充空单元来解决数独难题。 空单元由数字0表示。 你可以认为只有一个唯一的解决方案。

    Michael阿明
  • LeetCode 1353. 最多可以参加的会议数目(贪心)

    题目链接:https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-atten...

    Ch_Zaqdt
  • LeetCode164. 最大间距

     这道题用到了桶排序的思想,但是跟排序没啥关系,思路是这样的,数组中有n个元素,那么就构建n+1个桶,桶的属性有三个,最大值最小值以及是否为空。桶的下标从0...

    mathor
  • HDU 6370 Werewolf(并查集+dfs) 18年暑假多校赛第六场

    讲解博客:http://www.cnblogs.com/curieorz/p/9447454.html

    用户2965768

扫码关注云+社区

领取腾讯云代金券