(Linux下)基于Nucrses的贪吃蛇小游戏

代码核心是基于链表的使用
要运行此代码,需要安装Nucrses库

使用的嵌入式C语言知识主要有,链表,多线程。

#include<curses.h>
#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>

#define UP	 	 1
#define DOWN	-1
#define LEFT	 2
#define RIGHT	-2

struct Snack
{
        int row;
        int line;
        struct Snack *next;

};

struct Snack *head = NULL;
struct Snack *tail = NULL;
int key;
int dir;
struct Snack Food;


//随机生成食物
void initFood()
{
	int x;
	int y;

	x = rand()%19+1;
	y = rand()%19+1;

	Food.row = x;
	Food.line = y;
}

//Ncurses函数
void initNcurses()
{
	initscr();
	keypad(stdscr,1);
	noecho();
}
//判断是否有食物
int hasSnackFood(int i,int j)
{
		if(Food.row == i && Food.line == j){
			return 1;
		}
	
		return 0;
}
//判断是否是蛇的身子
int hasSnackNode(int i,int j)
{
	struct Snack *p;
	p = head;
	while(p->next != NULL){
		if(p->row == i && p->line == j){
	                return 1; 
        	}
		p = p->next;
	}
	return 0; 

}

//建地图
void Map()
{
        int row;
        int line;
	move(0,0);

        for(row = 0;row <= 20;row++){
		for(line = 0;line < 20;line++){
			printw("--");
                }
		printw("\n");
		if(row <= 20){
			for(row = 1;row < 20;row++){
				for(line = 0;line <= 20;line++){
					if(line == 0 || line == 20){
						printw("|");
					}else if(hasSnackNode(row,line)){
						printw("[]");
						
					}else if(hasSnackFood(row,line)){
						printw("##");
					}else{
						printw("  ");
				
					}
				}
				printw("\n");
				
			}	
				for(line = 0;line < 20;line++){
					printw("--");
				}
		}
	}
			printw("\n");
			printw("By Aaron\n\n");
}

//限制方向,不可直接
void turn(int direction)
{
	if(abs(dir) != direction){
		dir = direction;
	}
}

//根据输入的方向添加节点
void addNode()
{
        struct Snack *new;
        new = (struct Snack *)malloc(sizeof(struct Snack));

	new->next = NULL;
	switch(dir){
		case UP:
			new->row = tail->row-1;
			new->line = tail->line;
			break;
		case DOWN:
                        new->row = tail->row+1;
                        new->line = tail->line;
                        break;
		case LEFT:
                        new->row = tail->row;
                        new->line = tail->line-1;
                        break;
		case RIGHT:
                        new->row = tail->row;
                        new->line = tail->line+1;
                        break;

	
	}
        tail->next = new;
	tail = new;

}

//对蛇初始化添加节点
void initSnack()
{
	struct Snack *p;
	dir  = RIGHT;
	while(head != NULL){
		
		p = head;
		head = head->next;
		free(p);
	}
	initFood();
	head = (struct Snack *)malloc(sizeof(struct Snack));
	head->row  = 1;
	head->line = 1;
	head->next = NULL;

	tail = head;

	addNode();
	addNode();
	addNode();
	addNode();

}

//前进同时删掉后面节点
void delNode()
{
	struct Snack *p;
	p = head;
	head = head->next;
	free(p);	
}

int ifDie()
{
	struct Snack *p;
        p = head;
	if(tail->row < 0 || tail->line < 0 || tail->row > 20 || tail->line > 20){ 
                return 1;
        }
	while(p->next != NULL){
		if(p->row == tail->row && p->line == tail->line){
			return 1;
		}
		p = p->next;
	}

	return 0;
}

//小蛇蛇动起来啦
void moveSnack()
{
	
	addNode();
	if(hasSnackFood(tail->row,tail->line)){
		initFood();

	}else{
		delNode();
	}
	if(ifDie()){	
		initSnack();
	}
	printw("Food row:%d  Food line:%d\n",Food.row,Food.line);

}

//小蛇蛇转弯啦
void* changeDir()
{
	while(1){
		key = getch();
	 	switch(key){
       			 case KEY_UP:
                      		turn(UP);
                        	break;
               		 case KEY_DOWN:
				turn(DOWN);
        	                break;
            		 case KEY_LEFT:
				turn(LEFT);
                      		 break;
        	       	 case KEY_RIGHT:
				turn(RIGHT);
                        	break;
                        
        	}

	}	
}

//不断刷新地图
void* refreshMap()
{
	while(1){
		moveSnack();	
		Map();
		refresh();
		usleep(50000);//调整速度
	}

}

int main()
{

	//使用多线程,保证小蛇移动,不断刷新地图保证食物生成和方向改变
	pthread_t t1;
	pthread_t t2;
        
	initNcurses();
	initSnack();
	Map();

	pthread_create(&t1,NULL,refreshMap,NULL);
	pthread_create(&t2,NULL,changeDir,NULL);
	
	while(1);
        getch();
        
	endwin();
  	return 0;

}

水平不高,能力有限,
学识浅薄,希望能帮到您

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值