贪吃蛇项目
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <curses.h>
#include <pthread.h>
#include <time.h>
struct snake {
int hang;
int lie;
struct snake *next
};
struct snake *head=NULL;
struct snake *tail=NULL;
struct snake *food=NULL;
int foodsigal=0;//吃食信号
int dir=0;//保持运动方向数据
//下面互锁数据
int ddata=0;
int udata=0;
int ldata=0;
int rdata=0;
void initcurse()//Ncurse初始化
{ initscr();
keypad(stdscr,1);
}
void addsnake() //每用到一次给蛇添加一个行的节点
{
struct snake *pfstruct=head;//(struct snake*) malloc(sizeof(struct snake));
//pfstruct=head; //制造一个分身来替代头文件,避免污染头文件。
struct snake *new ;
new=(struct snake*)malloc(sizeof(struct snake)) ;//定义新的结构体指针
while (pfstruct->next!=NULL)
{
pfstruct=pfstruct->next;
}
if(pfstruct->next==NULL){ //每次定位到链表的尾巴,
new->hang=pfstruct->hang;
new->lie=pfstruct->lie+1;
new ->next=NULL;
pfstruct->next=new;//追踪到尾巴之后,把尾巴的位置传递给NEW。
tail=new;
}
}
void makesnake(int ls)//定义起始蛇的长度。
{head=(struct snake*) malloc(sizeof(struct snake));
head->hang=2;
head->lie=2;
head->next=NULL;
int i=0;
for(i=0;i<ls-1;i++)
{
addsnake();
}
}
void dlsnake()//蛇身的删除,每进行一次删除蛇的头
{
head=(head)->next;
//更改后的头还是head;
}
int foodeat(){
if(tail->hang==food->hang&&tail->lie==food->lie)
{
return 1;// 反馈用于蛇身
}
else {return 0;}
}
int foodfunc(int hang,int lie)//食物的随机产生程序rand函数
{
if(hang==food->hang&&lie==food->lie){
return 1;
}
else{ return 0;}
}
int isnake(int hang,int lie )//对蛇身的链表做一个判断
{
struct snake *slink=(struct snake*)malloc(sizeof(struct snake)) ;
slink=head;
while(slink!=NULL)//对整个链表进行对比
{
if(slink->hang==hang&&slink->lie==lie)
{
return 1;
}
slink=slink->next;
}
return 0;
}
void mapsetup(void)//地图产生规则,产生一个正方形的框架
{
int data1,data2;
int hang=0;
int lie =0;
move (0,0);
for (hang=0;hang<20;hang++){
if (hang==0||hang==19) {
for (lie=0;lie<20;lie++)
{printw("--"); }
}
if(hang>0&&hang<19){
for (lie=0;lie<=20;lie++)
{
if(lie==0||lie==20)
{printw("|");}
if(lie>0 && lie<20){
data1=isnake(hang,lie);data2=foodfunc(hang,lie);
if(data1==1||data2==1){
if(data1)//每次只要链表的行列对的上,就产生一个蛇身。
{ printw("[]");}
if(data2)//判断产生食物,mapsetep函数调用foodfunc程序,foodfunc程序调用ifeat程序。
{ printw("##");}
}
else
{printw(" ");}
}
}
}
printw("\n");
}
}
int eatself(){
struct snake *phead=head;
while(phead->next!=NULL){
if(phead->hang==tail->hang&&phead->lie==tail->lie)
{return 1;}
else{ phead=phead->next;}
}
return 0;
}
void ifdiedo()//死亡规则,撞墙和自食
{
int data=eatself();
struct snake *head1=(struct snake *)malloc(sizeof(struct snake));
head1=head;
struct snake *head2;
if(data==1||tail->hang==0||tail->hang==20||tail->lie==0||tail->lie==20){
{
while(head1!=NULL){//清除缓存,防止过载
head2=head1;
head1=head1->next;
free(head2);
}
dir=0;//清除原来的运动方向
makesnake(4);//重新设定蛇的长度,位置
//下面清除互锁
ddata=0;
udata=0;
ldata=0;
rdata=0;
}
}
}
void movesnake()//判断蛇的下一步行动
{
if(dir==3||dir==4||dir==5||dir==2){
switch(dir){ //顺序上下左右
case 3:{
struct snake *new1=(struct snake *)malloc (sizeof(struct snake));
new1->hang=tail->hang-1;
new1->lie=tail->lie;
new1->next=NULL;
tail->next=new1;///
tail=new1;
break;}
case 2:{
struct snake *new2=(struct snake *)malloc (sizeof(struct snake));
new2->hang=tail->hang+1;
new2->lie=tail->lie;
new2->next=NULL;
tail->next=new2;///
tail=new2;
break;
}
case 4:{
struct snake *new3=(struct snake *)malloc (sizeof(struct snake));
new3->hang=tail->hang;
new3->lie=tail->lie-1;
new3->next=NULL;
tail->next=new3;///
tail=new3;
break;
}
case 5: {
struct snake *new4=(struct snake *)malloc (sizeof(struct snake));
new4->hang=tail->hang;
new4->lie=tail->lie+1;
new4->next=NULL;
tail->next=new4;
tail=new4;///
break;
}
}}
else {
addsnake();
}
if (foodeat())//吃到食物返回0,不删除。
{
food->hang=rand()%18+1;
food->lie=rand()%19+1;
food ->next=NULL;
struct snake *phead=head;
while(phead!=NULL){//食物和蛇身重合则重新产生食物
if(phead->hang==food->hang&&phead->lie==food->lie){
food->hang=rand()%18+1;
food->lie=rand()%19+1;
food ->next=NULL;
phead=head;
}
else{phead=phead->next;}
}
}
else{dlsnake();}
}
void *func1(){
int data=0;
while(1){
data=getch();
//用if语句进行互锁,不能做方向相反的运动
switch (data){
case 0402:
if(ddata==0)
{
udata=1;
ldata=0;
rdata=0;
dir=2;
}
break;
case 0403:
if(udata==0)
{
ddata=1;
ldata=0;
rdata=0;
dir=3;
}
break;
case 0404:
if(ldata==0)
{
rdata=1;
udata=0;
ddata=0;
dir=4;
}
break;
case 0405:
if(rdata==0)
{
ldata=1;
udata=0;
ddata=0;
dir=5;
}
break;
}
}
}
void *func2()
{
food->hang=5;
food->lie=5;
food->next=NULL;
while (1){ //运动->判断死亡->构建画面,包括蛇身和食物。
movesnake();
ifdiedo();//再每次前进一步的时候都做一次死亡判断
foodeat();
mapsetup();
refresh();
usleep(100000);
}
}
int main()
{
food= (struct snake*)malloc(sizeof(struct snake));
pthread_t th1;
pthread_t th2;
makesnake(4);
initcurse();
mapsetup();
pthread_create(&th1,NULL,func1 ,NULL);
pthread_create(&th2,NULL,func2 ,NULL);
while(1);
getch();
endwin();
return 0;
}
//60行 initcurse();//发现一个问题只要在initcurse之前设置了代码就会发现有报错:Segmentation fault (core dumped),原因是addsnake函数中用initcurse的函> 数,main函数中在还没声明initcurse函数之前使用了inicurse中的函数,initcusre用于启用Ncurse功能。
通过这个程序对稍微复杂项目有了更系统的认知,正确的项目步骤应该是构建一个程序开始。
对C语言的编程经验也有更细节的了解,对linux系统的操作也更熟练了。