Linux系统中利用ncurses实现贪吃蛇小项目

附上代码:

#include <curses.h>		//ncurses库
#include <stdlib.h>	
#include <pthread.h>	//线程库
#include <unistd.h>	
 
#define UP     1
#define DOWN  -1
#define LEFT   2
#define RIGHT -2

typedef struct snakes{
    
    
        int row;		//行
        int col;		//列
        struct snakes* next;
}snake,*psnake;

psnake head=NULL;		//全局变量蛇头
psnake tail=NULL;		//全局变量蛇尾

int key;
int dir;
snake food;

/*定义食物位置*/
void initFood(){
    
    
        int x=rand()%20;	/*根据界面大小判断随机数对20求余可以让食物在所画的界面范围内*/
        int y=rand()%20;
        food.row=x;
        food.col=y;
}

void initNcure(){
    
    
        initscr();
        keypad(stdscr,1);
        noecho();		//防止乱码出现
}

/*确定坐标节点*/
int whetherSnakeNode(int i,int j){
    
    
        psnake p;
        p=head;
        while(p!=NULL){
    
    
                if(p->row==i && p->col==j){
    
    
                        return 1;
                }
                        p=p->next;
        }
                        return 0;
}

/*确定食物坐标节点*/
int whetherSnakeFood(int i,int j){
    
    
 
        if(food.row==i && food.col==j){
    
    
                return 1;
        }
                return 0;
}

/*定义游戏界面(范围边界)*/
void gameInterFace(){
    
    
        int row;		//定义行
        int col;		//定义列
        move(0,0);		//移动光标,用来刷新界面
        for(row=0;row<20;row++){
    
    
                if(row==0){
    
    
                        for(col=0;col<20;col++){
    
    
                                printw("--");
                        }
                                printw("\n");
                }
                if(row>=0 && row<=19){
    
    
                        for(col=0;col<=20;col++){
    
    
                                if(col==0 || col==20){
    
    
                                        printw("|");
                                }
                                else if(whetherSnakeNode(row,col)){
    
    	//扫描输出
                                        printw("[]");
                                }
                                else if(whetherSnakeFood(row,col)){
    
    
                                        printw("##");
                                }
                                else{
    
    
                                        printw("  ");
                                }
                        }
                                printw("\n");
                }
                if(row==19){
    
    
                        for(col=0;col<20;col++){
    
    
                                printw("--");
                        }
                        printw("\n");
                        printw("By Leo,key=%d\n",key);
                        printw("food.row=%d food.col=%d\n",food.row,food.col);
                }
        }
}

/*增减关于蛇的身子节点*/
void addNode(){
    
    
        psnake new=NULL;
        new=(psnake)malloc(sizeof(snake));
        new->next=NULL;
        switch(dir){
    
    	//控制蛇身上下左右
                case UP :
                        new->row=tail->row-1;
                        new->col=tail->col;
                        break;
                case DOWN:
                        new->row=tail->row+1;
                        new->col=tail->col;
                        break;
                case LEFT :
                        new->row=tail->row;
                        new->col=tail->col-1;
                        break;
                case RIGHT :
                        new->row=tail->row;
                        new->col=tail->col+1;
                        break;
        }
        tail->next=new;
        tail=new;
}

/*初始化蛇身*/
void initSnake(){
    
    
        psnake p=NULL;
        dir=RIGHT;
        while(head!=NULL){
    
    
                p=head;
                head=head->next;
                free(p);	//重新开始后需要释放空间
        }
        initFood();			//初始化食物
        head=(psnake)malloc(sizeof(snake));
        head->row=1;
        head->col=1;
        head->next=NULL;
        tail=head;
        /*增加蛇身的初始化长度*/
        addNode();			
        addNode();
        addNode();
}

/*删除一个头节点*/
void deleteSnake(){
    
    
        psnake p=NULL;
        p=head;
        head=head->next;
        free(p);		//释放空间,避免空间泄漏
}

/*判断蛇的死亡条件*/
int ifSnakeDie(){
    
    
        psnake p=NULL;
        p=head;
        if(tail->row<0 || tail->col==0 || tail->row==20 || tail->col==20){
    
    	//判断是否撞墙
 
                return 1;
        }
        while(p->next!=NULL){
    
    //
                if(p->row==tail->row && p->col==tail->col){
    
    					//判断节点是否重合,及是否撞到自己
                        return 1;
                }
                        p=p->next;
        }
                        return 0;
}

/*移动蛇*/
void moveSnake(){
    
    
        addNode();	//增加一个节点
        if(whetherSnakeFood(tail->row,tail->col)){
    
    	//判断是否有食物
                initFood();
        }
        else{
    
    
                deleteSnake();//删除一个节点,实现蛇身移动
        }
        if(ifSnakeDie()){
    
    	//判断是否死亡
                initSnake();
        }
}

/*刷新游戏界面*/
void* refreshGameFace(){
    
    
        while(1){
    
    
                moveSnake();	//移动蛇身
                gameInterFace();
                refresh();		//刷新界面
                usleep(100000); //为了不警报,最后在添加<unistd.h>头文件
        }
}

/*使蛇身不能同时上下或者左右移动*/
void turn (int direction){
    
    
        if(abs(dir) != abs(direction)){
    
    
                dir=direction;
        }
 
}

/*方向键*/
void* changeDirection(){
    
    
        while(1){
    
    
                key=getch();	//等待输入键值
                switch(key){
    
    
                        case KEY_DOWN:
                                turn(DOWN);
                                break;
                        case KEY_UP:
                                turn(UP);
                                break;
                        case KEY_LEFT:
                                turn(LEFT);
                                break;
                        case KEY_RIGHT:
                                turn(RIGHT);
                                break;
                }
        }
}

int main(){
    
    
        pthread_t k1;	//linux线程标志
        pthread_t k2;
        initNcure();	//初始化函数
        initSnake();	//初始化蛇身
        gameInterFace();//游戏界面
        pthread_create(&k1,NULL,refreshGameFace,NULL);	//线程1,刷新界面
        pthread_create(&k2,NULL,changeDirection,NULL);	//线程2,改变方向
        while(1);	//主线程
        getch();
        endwin();
        return 0;
}


游戏运行:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zouchengzhi1021/article/details/112880397
今日推荐