- 首页 > it技术 > >
数据结构|贪吃蛇代码--c语言版 visual c++6.0打开
#include"stdafx.h"
#include
#include
#include
#include
#include#define U 1
#define D 2
#define L 3
#define R 4//蛇的状态 U:上 D:下 L:左 R:右
typedef struct snake//蛇身的一个节点
{
int x;
//节点的x坐标
int y;
//节点的y坐标
struct snake *next;
//蛇身的下一个节点
}snake;
int score=0,add=10;
//总得分和每吃一次食物的得分
int highscore=0;
//最高分
int status,sleeptime=200;
//蛇前进状态,每次运行的时间间隔
snake *head,*food;
//蛇头指针,食物指针
snake *q;
//遍历蛇时用的指针
int endgamestatus=0;
//游戏结束时的状态
HANDLE hOut;
//控制台句柄
void gotoxy(int x,int y);
int color(int c);
void printsnake();
void wlcome();
void createmap();
void scoreandtips();
void initsnake();
void createfood();
int biteself();
void cantcrosswall();
void speedup();
void speeddown();
void snakemove();
void keyboardcontrol();
void lostdraw();
void endgame();
void choose();
void file_out();
void file_in();
void explation();
main()
{
system("mode con cols=100 lines=30");
printsnake();
wlcome();
file_out();
keyboardcontrol();
endgame();
}
void gotoxy(int x,int y)//设置光标位置
{COORD c;
c.X=x;
c.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
//定位光标的位置
}
int color(int c)//设置颜色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
return 0;
}
void printsnake()//打印字符蛇
{
gotoxy(2,5);
color(3);
printf("姓名:张小艾");
gotoxy(2,6);
color(3);
printf("学号:1910101099");
gotoxy(35,1);
color(6);
printf("/^\\/^\\");
gotoxy(34,2);
printf("|_| o|");
gotoxy(33,2);
color(2);
printf("_");
gotoxy(25,3);
color(12);
printf("\\/");
gotoxy(31,3);
color(2);
printf("/");
gotoxy(37,3);
color(6);
printf("\\_/");
gotoxy(41,3);
color(10);
printf(" \\");
gotoxy(26,4);
color(12);
printf("\\____");
gotoxy(32,4);
printf("_________");
gotoxy(31,4);
color(2);
printf("|");
gotoxy(43,4);
color(10);
printf("\\");
gotoxy(32,5);
color(2);
printf("\\_______");
gotoxy(44,5);
color(10);
printf("\\");
gotoxy(39,6);
printf("||\\");
gotoxy(38,7);
printf("//\\");
gotoxy(37,8);
printf("//\\ \\");
gotoxy(35,9);
printf("//\\ \\");
gotoxy(34,10);
printf(" //\\\\");
gotoxy(33,11);
printf("//_----_\\\\");
gotoxy(32,12);
printf("//_-~~-_||");
gotoxy(31,13);
printf("((_-~_--_~-__/ |");
gotoxy(32,14);
printf("\\~-____-~_-~~-_~-_-~ /");
gotoxy(33,15);
printf("~-__-~~-__-~");
gotoxy(35,16);
printf("~--____-~~-___-~");
}
void wlcome()//欢迎界面
{int n;
int i,j=1;
gotoxy(43,18);
color(11);
printf("贪吃蛇大作战");
color(14);
for(i=20;
i<=26;
i++)
{
for(j=27;
j<=74;
j++)
{
gotoxy(j,i);
if(i==20||i==26)
{
printf("-");
}
else if(j==27||j==74)
{
printf("|");
}
}
}
color(12);
gotoxy(35,22);
printf("1.开始游戏");
gotoxy(55,22);
printf("2.游戏说明");
gotoxy(35,24);
printf("3.退出游戏");
gotoxy(29,27);
color(3);
printf("请选择1 2 3\n");
color(14);
scanf("%d",&n);
switch(n)
{
case 1:
system("cls");
//清屏
createmap();
initsnake();
createfood();
keyboardcontrol();
break;
case 2:
explation();
break;
break;
case 3:
exit(0);
break;
}
}
void createmap()//创建地图
{
int i,j;
for(i=0;
i<58;
i+=2)
{
gotoxy(i,0);
color(5);
printf("□");
gotoxy(i,26);
printf("□");
}
for(i=0;
i<26;
i++)
{
gotoxy(0,i);
printf("□");
gotoxy(56,i);
printf("□");
}
for(i=2;
i<56;
i+=2)
{
for(j=1;
j<26;
j++)
{
gotoxy(i,j);
color(3);
printf("■\n\n");
} }
}
void scoreandtips()//游戏界面右侧的得分和小提示
{
file_out();
gotoxy(64,4);
color(11);
printf("*最高纪录*: %d",highscore);
gotoxy(64,8);
color(14);
printf("得分: %d ",score);
color(13);
gotoxy(73,11);
printf("小提示");
gotoxy(60,13);
color(6);
printf("+---------------------+");
gotoxy(60,25);
printf("+---------------------+");
color(3);
gotoxy(64,14);
printf("每个食物得分:%d分",add);
gotoxy(64,16);
printf("不能穿墙,不能咬到自己");
gotoxy(64,18);
printf("用↑↓←→分别控制蛇的移动");
gotoxy(64,20);
printf("F1为加速,F2为减速");
gotoxy(64,22);
printf("space: 暂停游戏");
gotoxy(64,24);
printf("ESC:退出游戏");
}
void file_out()//打开文件记录最高分
{
FILE *fp;
fp=fopen("save.txt","a+");
fscanf(fp,"%d",&highscore);
fclose(fp);
}
void initsnake()
{
snake *tail;
int i;
tail=(snake*)malloc(sizeof(snake));
tail->x=24;
tail->y=5;
tail->next=NULL;
for(i=1;
i<=4;
i++)
{
head=(snake*)malloc(sizeof(snake));
head->next=tail;
head->x=24+2*i;
head->y=5;
tail=head;
}
while(tail!=NULL)
{gotoxy(tail->x,tail->y);
color(14);
printf("★");
//蛇身由★组成
tail=tail->next;
}
}
void createfood()//随机出现食物
{
snake *food_1;
srand((unsigned)time(NULL));
food_1=(snake*)malloc(sizeof(snake));
while((food_1->x%2!=0))
{
food_1->x=rand()%52+2;
}
food_1->y=rand()%24+1;
q=head;
while(q->next==NULL)
{
if(q->x==food_1->x&&q->y==food_1->y)
{
free(food_1);
createfood();
}
q=q->next;
}
gotoxy(food_1->x,food_1->y);
food=food_1;
color(12);
printf("@");
}
int biteself()
{
snake *self;
//定义self为蛇身上除蛇头以外的节点
self=head->next;
while(self!=NULL)
{
if(self->x==head->x&&self->y==head->y)
{
return 1;
}
self=self->next;
}
return 0;
}
void cantcrosswall()
{
if(head->x==0||head->x==56||head->y==0||head->y==26)
{
endgamestatus=1;
endgame();
}
}
void speedup()//加速
{
if(sleeptime>=50)
{
sleeptime=sleeptime-10;
add=add+2;
}
}void speeddown()//减速
{
if(sleeptime<350)
{
sleeptime=sleeptime+30;
add=add-2;
if(sleeptime==350)
{
add=1;
}
}
} void snakemove()//控制方向
{
snake *nexthead;
cantcrosswall();
nexthead=(snake*)malloc(sizeof(snake));
if(status==U)//上
{
nexthead->x=head->x;
//向上前进时,x不变,y-1
nexthead->y=head->y-1;
nexthead->next=head;
head=nexthead;
q=head;
//如果下一个位置上有食物,下一个位置的坐标和食物坐标相同
if(nexthead->x==food->x&&nexthead->y==food->y)
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("★");
q=q->next;
}
score=score+add;
speedup();
createfood();
}
else
{
while(q->next->next!=NULL)//如果没有遇见食物
{
gotoxy(q->x,q->y);
color(14);
printf("★");
q=q->next;
}
//经过上面的循环 ,q指向蛇尾,蛇尾的下一步就是蛇走过去的位置
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
//恢复走过的位置
free(q->next);
q->next=NULL;
}}
if(status==D)
{
nexthead->x=head->x;
//向下前进时,x不变,y+1
nexthead->y=head->y+1;
nexthead->next=head;
head=nexthead;
q=head;
//如果下一个位置上有食物,下一个位置的坐标和食物坐标相同
if(nexthead->x==food->x&&nexthead->y==food->y)
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("★");
q=q->next;
}
score=score+add;
speedup();
createfood();
}
else
{
while(q->next->next!=NULL)//如果没有遇见食物
{
gotoxy(q->x,q->y);
color(14);
printf("★");
q=q->next;
}
//经过上面的循环 ,q指向蛇尾,蛇尾的下一步就是蛇走过去的位置
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
//恢复走过的位置
free(q->next);
q->next=NULL;
}
}
if(status==L)//左
{
nexthead->x=head->x-2;
//向左前进时,x不变,y+1
nexthead->y=head->y;
nexthead->next=head;
head=nexthead;
q=head;
//如果下一个位置上有食物,下一个位置的坐标和食物坐标相同
if(nexthead->x==food->x&&nexthead->y==food->y)
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
//食物变成蛇身上的一部分
color(14);
printf("★");
q=q->next;
}
score=score+add;
speedup();
createfood();
}
else
{
while(q->next->next!=NULL)//如果没有遇见食物
{
gotoxy(q->x,q->y);
color(14);
printf("★");
q=q->next;
}
//经过上面的循环 ,q指向蛇尾,蛇尾的下一步就是蛇走过去的位置
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
//恢复走过的位置
free(q->next);
q->next=NULL;
}
}
if(status==R)
{
nexthead->x=head->x+2;
//向上前进时,x不变,y-1
nexthead->y=head->y;
nexthead->next=head;
head=nexthead;
q=head;
//如果下一个位置上有食物,下一个位置的坐标和食物坐标相同
if(nexthead->x==food->x&&nexthead->y==food->y)
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("★");
q=q->next;
}
score=score+add;
speedup();
createfood();
}
else
{
while(q->next->next!=NULL)//如果没有遇见食物
{
gotoxy(q->x,q->y);
color(14);
printf("★");
q=q->next;
}
//经过上面的循环 ,q指向蛇尾,蛇尾的下一步就是蛇走过去的位置
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
//恢复走过的位置
free(q->next);
q->next=NULL;
}
}
if(biteself()==1)
{
endgamestatus=2;
endgame();
}
}
void keyboardcontrol()
{
status=R;
while(1)
{
scoreandtips();
//GetAsyncKeyState函数用来判断函数调用指定虚拟键的状态
if(GetAsyncKeyState(VK_UP)&&status!=D)
{
status=U;
}
else if(GetAsyncKeyState(VK_DOWN)&&status!=U)
{
status=D;
}
else if(GetAsyncKeyState(VK_LEFT)&&status!=R)
{
status=L;
}
else if(GetAsyncKeyState(VK_RIGHT)&&status!=L)
{
status=R;
}
if(GetAsyncKeyState(VK_SPACE))
{
while(1)
{
//调用sleep函数,令进程停止,直到达到其中设定的参数时间
Sleep(300);
if(GetAsyncKeyState(VK_SPACE))
{
break;
}
}
}
else if(GetAsyncKeyState(VK_ESCAPE))
{
endgamestatus=3;
break;
}
else if(GetAsyncKeyState(VK_F1))
{
speedup();
}
else if(GetAsyncKeyState(VK_F2))
{
if(sleeptime<350)
{
sleeptime=sleeptime+30;
add=add-2;
if(sleeptime==350)
{
add=1;
}
}
}
Sleep(sleeptime);
snakemove();
}
}void lostdraw()
{
system("cls");
int i,j;
gotoxy(17,5);
color(11);
printf("+------------------------");
gotoxy(35,5);
color(14);
printf("o00o");
gotoxy(39,5);
color(11);
printf("----------");
gotoxy(48,5);
color(14);
printf("---");
gotoxy(51,5);
color(11);
printf("----------");
gotoxy(61,5);
color(14);
printf("o00o");
gotoxy(65,5);
color(11);
printf("-----------------+");
for(i=6;
i<=19;
i++)
{
gotoxy(17,i);
printf("|");
gotoxy(82,i);
printf("|");
}
gotoxy(17,20);
printf("+----------------------------------");
gotoxy(52,20);
color(11);
printf("-----------------------------+");
} void endgame()
{
system("cls");
if(endgamestatus==1)
{
lostdraw();
gotoxy(35,9);
color(12);
printf("对不起,您撞到墙了。游戏结束!");
}
else if(endgamestatus==2)
{
lostdraw();
gotoxy(35,9);
color(12);
printf("对不起,您咬到自己了。游戏结束!");
}
else if(endgamestatus==3)
{
lostdraw();
gotoxy(40,9);
color(12);
printf("您结束了游戏。");
}
gotoxy(43,12);
color(13);
printf("您的得分是 %d",score);
if(score>=highscore)
{
color(10);
gotoxy(33,16);
printf("创新纪录啦!你真棒!!!");
file_in();
}
choose();
}
void file_in()//将最高分存储到文件中
{
FILE *fp;
fp=fopen("save.txt","w+");
//以读写的方式建立文件
fprintf(fp,"%d",score);
fclose(fp);
}
void choose()
{
int n;
gotoxy(25,23);
color(12);
printf("重玩一局-------1");
gotoxy(52,23);
printf("不玩了,退出-------2");
gotoxy(46,25);
color(11);
printf("选择:");
scanf("%d",&n);
switch(n)
{
case 1:
system("cls");
score=0;
sleeptime=200;
add=10;
printsnake();
wlcome();
break;
case 2:
exit(0);
break;
default:
gotoxy(35,27);
color(12);
printf("您输入有误,请重新输入");
system("pause >nul");
//按任意键
endgame();
choose();
break;
}
}
void explation()
{
int i,j=1;
system("cls");
color(13);
gotoxy(44,3);
printf("游戏说明");
color(2);
for(i=6;
i<=22;
i++)
{
for(j=20;
j<=75;
j++)
{
gotoxy(j,i);
if(i==6||i==22)printf("=");
else if(j==20||j==75)printf("||");
}
}
color(3);
gotoxy(30,8);
printf("1、不能穿墙,不能咬到自己");
color(3);
gotoxy(30,8);
printf("1、不能穿墙,不能咬到自己");
color(10);
gotoxy(30,11);
printf("2、用↑↓←→分别控制蛇的移动");
color(14);
gotoxy(30,14);
printf("3、F1为加速,F2为减速");
color(11);
gotoxy(30,17);
printf("4、按空格键暂停游戏,再按空格键继续");
color(4);
gotoxy(30,20);
printf("5、ESC:退出游戏,space:暂停游戏");
getch();
//按任意键返回主界面
system("cls");
printsnake();
wlcome();
}
推荐阅读