有问题的贪吃蛇(自己撞自己没事)


#include<windows.h>
#include<time.h>
#include<stdlib.h>
#include<conio.h>
#define N 21
FILE *fp;
int S;
void  boundary(void);//开始界面 
void end(void);  //结束 


void gotoxy(int x,int y)//位置函数
{
COORD pos;


pos.X=x;


pos.Y=y;


SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}


void color(int a)//颜色函数


{


SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);


}






void init(int food[2])//初始化函数(初始化围墙、显示信息、苹果)


{


system("cls");


int i,j;//初始化围墙


int wall[N+2][N+2]={{0}};//初始化围墙的二维数组 


for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)


wall[i][j]=1;


}
color(10);


for(i=0;i<N+2;i++)//畵围墙 
{
for(j=0;j<N+2;j++)
{
if(wall[i][j])


printf(" ");


else printf("#") ;
}


printf("\n") ;


}
gotoxy(N+3,3);//显示信息


color(14);


printf("\t\t按a,b,c,d改变方向\n");


gotoxy(N+3,1);


color(14);


printf("\t\t按任意键暂停,按1返回,按2退出\n");


gotoxy(N+5,3);


color(14);


printf("score:\n");


food[0]=rand()%N+1;//随机出现食物 


food[1]=rand()%N+1;


gotoxy(food[0],food[1]);


color(12);


printf("*\n");
}


void play()//具体玩的过程 
{


system("cls");


int i,j;


int** snake=NULL;//定义蛇的二维指针  


int food[2];//食物的数组,food[0]代表横坐标,food[1]代表纵坐标 


int score=0;//为得分 


int tail[2];//此数组为了记录蛇的头的坐标 


int node=3;//蛇的节数 


char ch='p';


srand((unsigned)time(NULL));//随机数发生器的初始化函数 


init(food); 


snake=(int**)realloc(snake,sizeof(int*)*node);//改变snake所指内存区域的大小为node长度 


for(i=0;i<node;i++)


snake[i]=(int*)malloc(sizeof(int)*2);


for(i=0;i<node;i++)//初始化蛇的长度 
{
snake[i][0]=N/2;


snake[i][1]=N/2+i;


gotoxy(snake[i][0],snake[i][1]);


color(14);


printf("*\n");
}
while(1)//进入消息循环
{
gotoxy(5,0);
color(10);
printf("#");
gotoxy(0,5);
color(10);
printf("#");
gotoxy(0,7);
color(10);
printf("#");
gotoxy(0,9);
color(10);
printf("#");
tail[0]=snake[node-1][0];//将蛇的后一节坐标赋给tail数组 


tail[1]=snake[node-1][1];


gotoxy(tail[0],tail[1]);


color(0);


printf(" ");


for(i=node-1;i>0;i--)//蛇想前移动的关键算法,后一节的占据前一节的地址坐标 
{
snake[i][0]=snake[i-1][0];


snake[i][1]=snake[i-1][1];


gotoxy(snake[i][0],snake[i][1]);


color(14);


printf("*\n");
}
if(kbhit())//捕捉输入信息 
{
gotoxy(0,N+2);


ch=getche();
}
switch(ch)
{
case 'w':snake[0][1]--;break;


case 's':snake[0][1]++;break;


case 'a':snake[0][0]--;break;


case 'd':snake[0][0]++;break;


case '1':boundary() ;break;


case '2':end();break;


default: break;
}
gotoxy(snake[0][0],snake[0][1]);


color(14);


printf("*\n");


Sleep(abs(200-0.5*score));//使随着分数的增长蛇的移动速度越来越快 


if(snake[0][0]==food[0]&&snake[0][1]==food[1])//吃掉食物后蛇分数加1,蛇长加1
{
score++;//分数增加 


S=score;


node++;//节数增加 


snake=(int**)realloc(snake,sizeof(int*)*node);


snake[node-1]=(int*)malloc(sizeof(int)*2);


food[0]=rand()%N+1;//产生随机数且要在围墙内部 


food[1]=rand()%N+1;


gotoxy(food[0],food[1]);


color(12);


printf("*\n");


gotoxy(N+12,3);


color(14);


printf("%d\n",score);//输出得分 
}
if(snake[0][1]==0||snake[0][1]==N+1||snake[0][0]==0||snake[0][0]==N+1)//撞到围墙后失败
{
gotoxy(N/2,N/2);


color(30);


printf("GAME  OVER!!!\n");


for(i=0;i<node;i++)


free(snake[i]);


Sleep(INFINITE);


exit(0);
}
}
//从蛇的第四节开始判断是否撞到自己,因为蛇头为两节,第三节不可能拐过来  


for (i=3; i<node; i++)  




{  
for(j=0;j<node;j++)


{
if (snake[i][0]==snake[j][0] && snake[i][1]==snake[j][1])     


{  


gotoxy(N/2,N/2);


color(30);


printf("GAME  OVER!!!\n");


for(i=0;i<node;i++)


free(snake[i]);


Sleep(INFINITE);


exit(0);;  


}  


}




}  


}


void end()//结束函数 
{       


system("cls");


system("cls");


printf("EXIT!!!\n");


}




void grade()//成绩记录函数
{
system("cls");


int i=0; 


char s;


if( (fp=fopen("f:\\贪吃蛇\\贪吃蛇.txt","ar") )==NULL)//打开文件 
{
printf("\nCannot open file!\n");


exit(0);
}


if(i<S)i=S;


color(14);


fwrite(&i,sizeof(i),1,fp);


fclose(fp);


printf("最高的分为:%d\n\n",i); 


printf("\t按1返回\n\n");


printf("\t按2退出\n\n");


s=getche();


switch(s)


{


case '1':boundary();break;


case '2': end();break;


}







void  boundary()//开始界面 
{
system("cls");


char s;


color(14);


printf("\t\t欢迎来玩!!\n\n");


printf("\t\t1:开始\n\n");


printf("\t\t2:查看成绩\n\n");


printf("\t\t3:退出\n\n");


printf("\t\t请选择:");


s=getche();


switch(s)


{


case '1': play();break;


case '2': grade();break;


case '3': end();break;


}


}


int main()
{
boundary();


getchar();


return 0;
}

转载于:https://my.oschina.net/u/928111/blog/98312

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值