C语言小项目-贪吃蛇第3天走位吃食物撞死重开

1. 实现贪吃蛇四方向的疯烧走位(149.19)

  • snake13.c
#include <curses.h>//ncurse的头文件
#include <stdlib.h>//malloc的头文件
#include <unistd.h>//usleep的头文件
#include <pthread.h>//pthread线程的头文件

#define UP    1
#define DOWN  2
#define LEFT  3
#define RIGHT 4

struct Snake
{
	int line;
	int list;
	struct Snake *next;
};

struct Snake *head=NULL;
struct Snake *tail=NULL;
int key;
int dir;

void initNcurse()//初始化,开始运行,接受功能键
{
	initscr();	//ncurse界面的初始化函数
	keypad(stdscr,1);//从标准的stdscr中接受功能键,1代表是接受
}

void addNode()//增加节点
{
	struct Snake *new=(struct Snake*)malloc(sizeof(struct Snake));
	
	switch(dir){
		case UP:
			new->line=tail->line-1;
			new->list=tail->list;
			break;
		case DOWN:
			new->line=tail->line+1;
			new->list=tail->list;
			break;
		case LEFT:
			new->line=tail->line;
			new->list=tail->list-1;
			break;
		case RIGHT:
			new->line=tail->line;
			new->list=tail->list+1;
			break;
	}
	new->next=NULL;

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

void initSnake()//初始化蛇的位置和节点个数
{
	struct Snake *p;
	dir=RIGHT;

	while(head != NULL){
		p=head;
		head=head->next;
		free(p);
	}
	head=(struct Snake*)malloc(sizeof(struct Snake));
	tail=(struct Snake*)malloc(sizeof(struct Snake));
	head->line=1;
	head->list=1;
	head->next=NULL;

	tail=head;
	
	addNode();
	addNode();
	addNode();
	addNode();
}

int hasSnakeNode(int line,int list)//定位蛇的起始位置
{
	struct Snake *p=head;
	while(p != NULL){
		if(p->line==line && p->list==list){
			return 1;
		}
		p=p->next;
	}
	return 0;
}

void gamePic()//打印游戏地图
{
	int line;
	int list;

	move(0,0);//改变光标位置为原型
	for(line=0;line<20;line++){
		if(line==0){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\n");
		}
		if(line>=0 && line<=19){
			for(list=0;list<=20;list++){
				if(list==0 || list==20){
					printw("|");
				}else if(hasSnakeNode(line,list)){
					printw("[]");
				}
				else{
					printw("  ");
				}
			}
		  	printw("\n");
		}
		if(line==19){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\nBy Jessie,key=%d\n",key);
		}
		
	}

}

void deleNode()//删除节点
{
	struct Snake *p=head;
	head=head->next;
	free(p);
}
void moveSnake()//控制蛇移动的函数
{
	addNode();
	deleNode();
	if(tail->line==0||tail->line==20||tail->list==0||tail->list==20){
		initSnake();
	}
}

void* refreshInt()
{
	while(1){
			moveSnake();//蛇移动
			gamePic();//刷新地图
			refresh();//刷新
			usleep(100000);//100毫秒
	}
}

void* changeDir()
{
	while(1){
		key=getch();
		switch(key){
			case KEY_DOWN:
				dir=DOWN;
				break;
			case KEY_UP:
				dir=UP;
				break;
			case KEY_LEFT:
				dir=LEFT;
				break;
			case KEY_RIGHT:
				dir=RIGHT;
				break;
		}
	}
}

int main()//主函数
{
	pthread_t t1;
	pthread_t t2;

	initNcurse();//nurse界面初始化,开始运行,接受功能键
	initSnake();//初始化蛇的位置和节点个数
	gamePic();//打印游戏地图
	
	pthread_create( &t1, NULL, refreshInt, NULL );
	pthread_create( &t2, NULL, changeDir, NULL );

	while(1);

	getch();
	endwin();

	return 0;
}

2. 绝对值方式解决不合理走位一(150.20)

  • snake14.c
#include <curses.h>//ncurse的头文件
#include <stdlib.h>//malloc的头文件
#include <unistd.h>//usleep的头文件
#include <pthread.h>//pthread线程的头文件

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

struct Snake
{
	int line;
	int list;
	struct Snake *next;
};

struct Snake *head=NULL;
struct Snake *tail=NULL;
int key;
int dir;

void initNcurse()//初始化,开始运行,接受功能键
{
	initscr();	//ncurse界面的初始化函数
	keypad(stdscr,1);//从标准的stdscr中接受功能键,1代表是接受
	noecho();//关闭字符输入时的回显功能:不把无关的功能键的信息显示出来
}

void addNode()//增加节点
{
	struct Snake *new=(struct Snake*)malloc(sizeof(struct Snake));
	
	switch(dir){
		case UP:
			new->line=tail->line-1;
			new->list=tail->list;
			break;
		case DOWN:
			new->line=tail->line+1;
			new->list=tail->list;
			break;
		case LEFT:
			new->line=tail->line;
			new->list=tail->list-1;
			break;
		case RIGHT:
			new->line=tail->line;
			new->list=tail->list+1;
			break;
	}
	new->next=NULL;

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

void initSnake()//初始化蛇的位置和节点个数
{
	struct Snake *p;
	dir=RIGHT;

	while(head != NULL){
		p=head;
		head=head->next;
		free(p);
	}
	head=(struct Snake*)malloc(sizeof(struct Snake));
	tail=(struct Snake*)malloc(sizeof(struct Snake));
	head->line=1;
	head->list=1;
	head->next=NULL;

	tail=head;
	
	addNode();
	addNode();
	addNode();
	addNode();
}

int hasSnakeNode(int line,int list)//定位蛇的起始位置
{
	struct Snake *p=head;
	while(p != NULL){
		if(p->line==line && p->list==list){
			return 1;
		}
		p=p->next;
	}
	return 0;
}

void gamePic()//打印游戏地图
{
	int line;
	int list;

	move(0,0);//改变光标位置为原型
	for(line=0;line<20;line++){
		if(line==0){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\n");
		}
		if(line>=0 && line<=19){
			for(list=0;list<=20;list++){
				if(list==0 || list==20){
					printw("|");
				}else if(hasSnakeNode(line,list)){
					printw("[]");
				}
				else{
					printw("  ");
				}
			}
		  	printw("\n");
		}
		if(line==19){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\nBy Jessie,key=%d\n",key);
		}
		
	}

}

void deleNode()//删除节点
{
	struct Snake *p=head;
	head=head->next;
	free(p);
}
void moveSnake()//控制蛇移动的函数
{
	addNode();
	deleNode();
	if(tail->line==0||tail->line==20||tail->list==0||tail->list==20){
		initSnake();
	}
}

void* refreshInt()
{
	while(1){
			moveSnake();//蛇移动
			gamePic();//刷新地图
			refresh();//刷新
			usleep(100000);//100毫秒
	}
}

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

void* changeDir()
{
	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 t1;
	pthread_t t2;

	initNcurse();//nurse界面初始化,开始运行,接受功能键
	initSnake();//初始化蛇的位置和节点个数
	gamePic();//打印游戏地图
	
	pthread_create( &t1, NULL, refreshInt, NULL );
	pthread_create( &t2, NULL, changeDir, NULL );

	while(1);

	getch();
	endwin();

	return 0;
}

3. 绝对值方式解决不合理走位二(151.21)

  • snake14.c
void initNcurse()//初始化,开始运行,接受功能键
{
	initscr();	//ncurse界面的初始化函数
	keypad(stdscr,1);//从标准的stdscr中接受功能键,1代表是接受
	noecho();//关闭字符输入时的回显功能:不把无关的功能键的信息显示出来
}

4. 贪吃蛇吃饭咯(152.22)

  • snake15.c
#include <curses.h>//ncurse的头文件
#include <stdlib.h>//malloc的头文件
#include <unistd.h>//usleep的头文件
#include <pthread.h>//pthread线程的头文件

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

struct Snake
{
	int line;
	int list;
	struct Snake *next;
};

struct Snake *head=NULL;
struct Snake *tail=NULL;
int key;
int dir;

struct Snake food;

void initFood()//初始化食物位置
{
	static int x=3;//静态变量,函数再次被调用时,其值不会改变
	static int y=4;

	food.line=x;
	food.list=y;

	x+=2;
	y+=2;
}

void initNcurse()//初始化,开始运行,接受功能键
{
	initscr();	//ncurse界面的初始化函数
	keypad(stdscr,1);//从标准的stdscr中接受功能键,1代表是接受
	noecho();//关闭字符输入时的回显功能:不把无关的功能键的信息显示出来
}

void addNode()//增加节点
{
	struct Snake *new=(struct Snake*)malloc(sizeof(struct Snake));
	
	switch(dir){
		case UP:
			new->line=tail->line-1;
			new->list=tail->list;
			break;
		case DOWN:
			new->line=tail->line+1;
			new->list=tail->list;
			break;
		case LEFT:
			new->line=tail->line;
			new->list=tail->list-1;
			break;
		case RIGHT:
			new->line=tail->line;
			new->list=tail->list+1;
			break;
	}
	new->next=NULL;

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

void initSnake()//初始化蛇的位置和节点个数
{
	struct Snake *p;
	dir=RIGHT;

	while(head != NULL){
		p=head;
		head=head->next;
		free(p);
	}

	/*food.line=3;//初始化食物位置
	food.list=4;*/
	initFood();//初始化食物位置
	head=(struct Snake*)malloc(sizeof(struct Snake));
	tail=(struct Snake*)malloc(sizeof(struct Snake));
	head->line=1;
	head->list=1;
	head->next=NULL;

	tail=head;
	
	addNode();
	addNode();
	addNode();
	addNode();
}

int hasSnakeNode(int line,int list)//帮助定位蛇的起始位置
{
	struct Snake *p=head;
	while(p != NULL){
		if(p->line==line && p->list==list){
			return 1;
		}
		p=p->next;
	}
	return 0;
}

int hasFood(int line,int list)//帮助定位食物的起始位置
{
	if(food.line==line && food.list==list){
		return 1;
	}
	return 0;
}

void gamePic()//打印游戏地图
{
	int line;
	int list;

	move(0,0);//改变光标位置为原型
	for(line=0;line<20;line++){
		if(line==0){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\n");
		}
		if(line>=0 && line<=19){
			for(list=0;list<=20;list++){
				if(list==0 || list==20){
					printw("|");
				}else if(hasSnakeNode(line,list)){
					printw("[]");
				}else if(hasFood(line,list)){
					printw("##");
				}
				else{
					printw("  ");
				}
			}
		  	printw("\n");
		}
		if(line==19){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\nBy Jessie,key=%d\n",key);
		}
	}
}

void deleNode()//删除节点
{
	struct Snake *p=head;
	head=head->next;
	free(p);
}
void moveSnake()//控制蛇移动的函数
{
	addNode();
	if(hasFood(tail->line,tail->list)){
		initFood();
	}else{
		deleNode();
	}
	if(tail->line==0||tail->line==20||tail->list==0||tail->list==20){
		initSnake();
	}
}

void* refreshInt()//刷新界面
{
	while(1){
			moveSnake();//蛇移动
			gamePic();//刷新地图
			refresh();//刷新
			usleep(100000);//100毫秒
	}
}

void turn(int direction)//绝对值作规则:只能90度转弯,不可180度
{
	if(abs(dir)!=abs(direction)){//abs是绝对值函数
		dir=direction;
	}
}

void* changeDir()//上下左右移动蛇的位置
{
	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 t1;
	pthread_t t2;

	initNcurse();//nurse界面初始化,开始运行,接受功能键
	initSnake();//初始化蛇的位置和节点个数
	gamePic();//打印游戏地图
	
	pthread_create( &t1, NULL, refreshInt, NULL );
	pthread_create( &t2, NULL, changeDir, NULL );

	while(1);

	getch();
	endwin();

	return 0;
}

5. 贪吃蛇食物位置随机(153.23)

  • snake16.c
#include <curses.h>//ncurse的头文件
#include <stdlib.h>//malloc的头文件
#include <unistd.h>//usleep的头文件
#include <pthread.h>//pthread线程的头文件

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

struct Snake
{
	int line;
	int list;
	struct Snake *next;
};

struct Snake *head=NULL;
struct Snake *tail=NULL;
int key;
int dir;

struct Snake food;

void initFood()//初始化食物位置
{
	int x=rand()%20;//rand()是生成随机数函数
	int y=rand()%20;//%20是随机数对20取余

	food.line=x;
	food.list=y;
}

void initNcurse()//初始化,开始运行,接受功能键
{
	initscr();	//ncurse界面的初始化函数
	keypad(stdscr,1);//从标准的stdscr中接受功能键,1代表是接受
	noecho();//关闭字符输入时的回显功能:不把无关的功能键的信息显示出来
}

void addNode()//增加节点
{
	struct Snake *new=(struct Snake*)malloc(sizeof(struct Snake));
	
	switch(dir){
		case UP:
			new->line=tail->line-1;
			new->list=tail->list;
			break;
		case DOWN:
			new->line=tail->line+1;
			new->list=tail->list;
			break;
		case LEFT:
			new->line=tail->line;
			new->list=tail->list-1;
			break;
		case RIGHT:
			new->line=tail->line;
			new->list=tail->list+1;
			break;
	}
	new->next=NULL;

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

void initSnake()//初始化蛇的位置和节点个数
{
	struct Snake *p;
	dir=RIGHT;

	while(head != NULL){
		p=head;
		head=head->next;
		free(p);
	}

	/*food.line=3;//初始化食物位置
	food.list=4;*/
	initFood();//初始化食物位置
	head=(struct Snake*)malloc(sizeof(struct Snake));
	tail=(struct Snake*)malloc(sizeof(struct Snake));
	head->line=1;
	head->list=1;
	head->next=NULL;

	tail=head;
	
	addNode();
	addNode();
	addNode();
	addNode();
}

int hasSnakeNode(int line,int list)//帮助定位蛇的起始位置
{
	struct Snake *p=head;
	while(p != NULL){
		if(p->line==line && p->list==list){
			return 1;
		}
		p=p->next;
	}
	return 0;
}

int hasFood(int line,int list)//帮助定位食物的起始位置
{
	if(food.line==line && food.list==list){
		return 1;
	}
	return 0;
}

void gamePic()//打印游戏地图
{
	int line;
	int list;

	move(0,0);//改变光标位置为原型
	for(line=0;line<20;line++){
		if(line==0){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\n");
		}
		if(line>=0 && line<=19){
			for(list=0;list<=20;list++){
				if(list==0 || list==20){
					printw("|");
				}else if(hasSnakeNode(line,list)){
					printw("[]");
				}else if(hasFood(line,list)){
					printw("##");
				}
				else{
					printw("  ");
				}
			}
		  	printw("\n");
		}
		if(line==19){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\nBy Jessie,key=%d,food.line=%d,food.list=%d\n",key,food.line,food.list);
		}
	}
}

void deleNode()//删除节点
{
	struct Snake *p=head;
	head=head->next;
	free(p);
}
void moveSnake()//控制蛇移动的函数
{
	addNode();
	if(hasFood(tail->line,tail->list)){
		initFood();
	}else{
		deleNode();
	}
	if(tail->line==0||tail->line==20||tail->list==0||tail->list==20){
		initSnake();
	}
}

void* refreshInt()//刷新界面
{
	while(1){
			moveSnake();//蛇移动
			gamePic();//刷新地图
			refresh();//刷新
			usleep(100000);//100毫秒
	}
}

void turn(int direction)//绝对值作规则:只能90度转弯,不可180度
{
	if(abs(dir)!=abs(direction)){//abs是绝对值函数
		dir=direction;
	}
}

void* changeDir()//上下左右移动蛇的位置
{
	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 t1;
	pthread_t t2;

	initNcurse();//nurse界面初始化,开始运行,接受功能键
	initSnake();//初始化蛇的位置和节点个数
	gamePic();//打印游戏地图
	
	pthread_create( &t1, NULL, refreshInt, NULL );
	pthread_create( &t2, NULL, changeDir, NULL );

	while(1);

	getch();
	endwin();

	return 0;
}

6. 贪吃蛇撞墙找死和想不开咬死自己来结束游戏的代码优化(154.24)

  • snake17.c
#include <curses.h>//ncurse的头文件
#include <stdlib.h>//malloc的头文件
#include <unistd.h>//usleep的头文件
#include <pthread.h>//pthread线程的头文件

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

struct Snake
{
	int line;
	int list;
	struct Snake *next;
};

struct Snake *head=NULL;
struct Snake *tail=NULL;
int key;
int dir;

struct Snake food;

void initFood()//初始化食物位置
{
	int x=rand()%20;//rand()是生成随机数函数
	int y=rand()%20;//%20是随机数对20取余

	food.line=x;
	food.list=y;
}

void initNcurse()//初始化,开始运行,接受功能键
{
	initscr();	//ncurse界面的初始化函数
	keypad(stdscr,1);//从标准的stdscr中接受功能键,1代表是接受
	noecho();//关闭字符输入时的回显功能:不把无关的功能键的信息显示出来
}

void addNode()//增加节点
{
	struct Snake *new=(struct Snake*)malloc(sizeof(struct Snake));
	
	switch(dir){
		case UP:
			new->line=tail->line-1;
			new->list=tail->list;
			break;
		case DOWN:
			new->line=tail->line+1;
			new->list=tail->list;
			break;
		case LEFT:
			new->line=tail->line;
			new->list=tail->list-1;
			break;
		case RIGHT:
			new->line=tail->line;
			new->list=tail->list+1;
			break;
	}
	new->next=NULL;

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

void initSnake()//初始化蛇的位置和节点个数
{
	struct Snake *p;
	dir=RIGHT;

	while(head != NULL){
		p=head;
		head=head->next;
		free(p);
	}

	/*food.line=3;//初始化食物位置
	food.list=4;*/
	initFood();//初始化食物位置
	head=(struct Snake*)malloc(sizeof(struct Snake));
	tail=(struct Snake*)malloc(sizeof(struct Snake));
	head->line=1;
	head->list=1;
	head->next=NULL;

	tail=head;
	
	addNode();
	addNode();
	addNode();
	addNode();
}

int hasSnakeNode(int line,int list)//帮助定位蛇的起始位置
{
	struct Snake *p=head;
	while(p != NULL){
		if(p->line==line && p->list==list){
			return 1;
		}
		p=p->next;
	}
	return 0;
}

int hasFood(int line,int list)//帮助定位食物的起始位置
{
	if(food.line==line && food.list==list){
		return 1;
	}
	return 0;
}

void gamePic()//打印游戏地图
{
	int line;
	int list;

	move(0,0);//改变光标位置为原型
	for(line=0;line<20;line++){
		if(line==0){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\n");
		}
		if(line>=0 && line<=19){
			for(list=0;list<=20;list++){
				if(list==0 || list==20){
					printw("|");
				}else if(hasSnakeNode(line,list)){
					printw("[]");
				}else if(hasFood(line,list)){
					printw("##");
				}
				else{
					printw("  ");
				}
			}
		  	printw("\n");
		}
		if(line==19){
			for(list=0;list<20;list++){
				printw("--");
			}
			printw("\nBy Jessie,key=%d,food.line=%d,food.list=%d\n",key,food.line,food.list);
		}
	}
}

void deleNode()//删除节点
{
	struct Snake *p=head;
	head=head->next;
	free(p);
}

int ifDie()
{
	struct Snake *p;
	p=head;

	if(tail->line<0||tail->line==20||tail->list==0||tail->list==20){
		return 1;
	}
	while(p->next!=NULL){
		if(head->line==tail->line && head->list==tail->list){
			return 1;
		}
		p=p->next;
	}
	return 0;
}

void moveSnake()//控制蛇移动的函数
{
	addNode();
	if(hasFood(tail->line,tail->list)){
		initFood();
	}else{
		deleNode();
	}
	if(ifDie()){	
		initSnake();
	}
}

void* refreshInt()//刷新界面
{
	while(1){
			moveSnake();//蛇移动
			gamePic();//刷新地图
			refresh();//刷新
			usleep(200000);//100毫秒
	}
}

void turn(int direction)//绝对值作规则:只能90度转弯,不可180度
{
	if(abs(dir)!=abs(direction)){//abs是绝对值函数
		dir=direction;
	}
}

void* changeDir()//上下左右移动蛇的位置
{
	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 t1;
	pthread_t t2;

	initNcurse();//nurse界面初始化,开始运行,接受功能键
	initSnake();//初始化蛇的位置和节点个数
	gamePic();//打印游戏地图
	
	pthread_create( &t1, NULL, refreshInt, NULL );
	pthread_create( &t2, NULL, changeDir, NULL );

	while(1);

	getch();
	endwin();

	return 0;
}

7. 贪吃蛇小游戏总结(155.25)

  • ncurse、ncurse按键响应、贪吃蛇项目整体逻辑规划、地图规划及算法优化、蛇的节点和完整身子、Linux线程、蛇的移动和走位同时进行、蛇吃食物
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值