嗯,这个版本的贪吃蛇用链表实现
创建一个蛇头 连接蛇身(随机初始化整条蛇)
因为在蛇移动的过程中 可以蛇头更新为新到达的位置 蛇尾删除并将原来的链接蛇尾的那节作为新的蛇尾
使用gotoxy进行屏幕的更新操作 避免 system(“cls”)频繁刷新造成的闪屏
具体代码如下
//ILSSWFR
#include<iostream>
#include<conio.h>
#include<cstdlib>
#include"windows.h"
#include<ctime>
using namespace std;
int speed[9]={0,500,400,350,300,250,200,150};
int speed2[13]={0,400,400,400,300,300,300,200,200,200,150,150};
int cc2[13]={0,1,2,3,4,5,6,7,4,5,6,7};
int level1[17][27]
,level3[17][27]={{1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}
,{1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1}}
,level2[17][27]={{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}
,level4[17][27]={{1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
,{1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0}
,{1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0}
,{0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0}
,{0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0}
,{0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1}
,{0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,0,0,0,1}
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1}
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1}}
,level5[17][27]={{1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0}
,{1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0}
,{1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0}
,{1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1}
,{1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1}
,{0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1}
,{0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1}
,{1,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1}
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1}}
,level6[17][27]={{1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
,{1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
,{1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0}
,{1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0}
,{1,0,0,0,0,1,0,0,0,1,0,0,1,1,1,1,0,0,0}
,{1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,1,0,0,0}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}
,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}
,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0}}
,level7[17][27]={{1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0}
,{0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}
,{0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}
,{0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0}
,{0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1}
,{0,0,0,1,0,0,1,0,0,1,0,0,0,1,1,1,1,1,1}
,{0,0,0,1,0,0,1,0,0,1,1,1,1,1,0,0,0,0,1}
,{0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1}
,{0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1}
,{0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1}
,{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
int *point[10]={NULL,level1[0],level2[0],level3[0],level4[0],level5[0],level6[0],level7[0]};
int p[17][27];//记录蛇身的位置
struct snake
{
int x;
int y;
struct snake* next;
};
void gotoxy(int x, int y)
{
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
int rad(int n)
{
srand(unsigned(time(NULL)));
return rand()%n;
}
struct snake* judge(struct snake* head,char choose )//嗯,这个比俄罗斯方块方便一点,如果不能移动就直接GAMEOVER了
{
int a,b;
struct snake* s=(struct snake*)malloc(sizeof(struct snake));
if (choose=='w')
a=-1,b=0;
else if(choose=='s')
a=1,b=0;
else if (choose=='a')
a=0,b=-1;
else if (choose=='d')
a=0,b=1;
s->x=head->x+a;
s->y=head->y+b;
s->next=head;
//system("pause");
if (s->x==0){
if (p[0][s->y]==1||p[10][s->y]==1)
return NULL;
s->x=9;
}
if (s->x==10){
if (p[0][s->y]==1||p[10][s->y]==1)
return NULL;
s->x=1;
}
if (s->y==0){
if (p[s->x][0]==1||p[s->x][18]==1)
return NULL;
s->y=17;
}
if (s->y==18){
if (p[s->x][0]==1||p[s->x][18]==1)
return NULL;
s->y=1;
}
if (p[s->x][s->y]==1||p[s->x][s->y]==2)
return NULL;
return s;
}
void makeapple()//制造苹果
{
int x,y;
for (;;){
x=rad(11);
y=rad(19);
if (!p[x][y]&&x!=0&&x!=10&&y!=0&&y!=18){
p[x][y]=3;
gotoxy(y,x);
cout<<'$';
return;
}
}
}
void moving(struct snake* head,char choose,int* score)//就是删除链表的尾节点,新增一个头节点
{
gotoxy(head->y,head->x);
cout<<'*';
//system("pause");
if (p[head->x][head->y]==3){
*score+=50;
gotoxy(25,3);
cout<<*score;
makeapple();
return;
}
p[head->x][head->y]=2;
struct snake* s=head,*k;
for (;s->next->next!=NULL;)
s=s->next;
//cout<<"sss"<<endl;
// system("pause");
k=s;
s=s->next;
k->next=NULL;
// cout<<"sss"<<endl;
//system("pause");
gotoxy(s->y,s->x);
if (s->y==0||s->y==18||s->x==0||s->x==10)
cout<<'.';
else
cout<<' ';
gotoxy(k->y,k->x);
cout<<'~';
p[s->x][s->y]=0;
free(s);
}
struct snake* makesnake(char *fx)//产生一个在随机位置的蛇,返回蛇头
{
int sx,sy,flag=0;
int arrow[4]={0,0,0,0};//上0,下1,左2,右3
for (;;){
sx=rad(11);
sy=rad(19);
if (sx==0||sx==10||sy==0||sy==18)
continue;
int i;
for (i=0;i<5;++i){
if (i+sx>10||p[i+sx][sy]) break;
}
if (i==5) arrow[1]++,flag=1;
for (i=0;i<5;++i){
if (sx-i<0||p[sx-i][sy]) break;
}
if (i==5) arrow[0]++,flag=1;
for (i=0;i<5;++i){
if (sy-i<0||p[sx][sy-i]) break;
}
if (i==5) arrow[2]++,flag=1;
for (i=0;i<5;++i){
if (sy+i>18||p[sx][sy+i]) break;
}
if (i==5) arrow[3]++,flag=1;
if (flag)
break;
}
int k=rad(4),local;
for (int i=k;i<4;++i)
if (arrow[i]) {local=i;flag=0;break;}
for (int i=0;i<k&&flag;++i)
if (arrow[i]) {local=i;break;}
//找到一个满足存放蛇的长度的地方
struct snake* s,*s1,*s2;
s=(struct snake* )malloc(sizeof(struct snake));
s1=(struct snake* )malloc(sizeof(struct snake));
s2=(struct snake* )malloc(sizeof(struct snake));
int a=0,b=0;
if (local==0) a=-1,b=0,*fx='s';
if (local==1) a=1,b=0,*fx='w';
if (local==2) a=0,b=-1,*fx='d';
if (local==3) a=0,b=1,*fx='a';
s->x=sx+a;
s->y=sy+b;
s->next=s1;
s1->x=s->x+a;
s1->y=s->y+b;
s1->next=s2;
s2->x=s1->x+a;
s2->y=s1->y+b;
s2->next=NULL;
p[s->x][s->y]=p[s1->x][s1->y]=p[s2->x][s2->y]=2;
return s;//返回蛇头
}
bool findapple()//清
{
for (int i=0;i<11;++i)
for (int j=0;j<19;++j)
if (p[i][j]==3) return true;
return false;
}
void outscreen(struct snake* head)
{
struct snake* s=head;
for (;s->next!=NULL;)
s=s->next;
for (int i=0;i<11;++i){
for (int j=0;j<19;++j){
if (p[i][j]==1)
cout<<'+';
else if (p[i][j]==2){
if (s->x==i&&s->y==j)
cout<<'~';
else
cout<<'*';
}
else if (p[i][j]==3)
cout<<'$';
else if (i==0||i==10||j==0||j==18)
cout<<'.';
else
cout<<' ';
}
cout<<endl;
}
gotoxy(20,2);
cout<<"分数:";
gotoxy(25,3);
cout<<0;
gotoxy(20,9);
cout<<"1:暂停";
gotoxy(20,10);
cout<<"2:退出";
}
void gamestart(int level,int speeds,int tip,int *re)
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(hOut,&cci);
system("cls");
struct snake* head;
for (int i=0;i<11;++i){
for (int j=0;j<19;++j)
p[i][j]=*(point[level]+i*27+j);
}
char choose,record;
head=makesnake(&choose);
record=choose;
double start=clock(),startapple=clock();
makeapple();
int flag=0,score=0;
system("cls");
outscreen(head);
// system("pause");
for (;!flag;){
while (!kbhit()||!(choose=getch())){
if(int(clock()-start)<speeds) continue;
start=clock();
if ((head=judge(head,record))==NULL){ flag=1;break;}
moving(head,choose,&score);
if(tip&&score>=1000) {*re=3;return;}
}
if ((choose=='w'&&record=='s')||
(choose=='a'&&record=='d')||
(choose=='s'&&record=='w')||
(choose=='d'&&record=='a')||
(choose!='w'&&choose!='s'&&choose!='a'&&choose!='d'))
;
else
record=choose;
if (choose=='1'){
gotoxy(0,12);
system("pause");
gotoxy(0,12);
for (int q=0;q<19;++q)
cout<<' ';
}
if (choose=='2'){
system("cls");
*re=1;
return;
}
}
system("cls");
cout<<"您获得的分数是:"<<score<<endl;
system("pause");
*re=2;
}
int main()
{
for(;;){
system("cls");
cout<<"-----------------------"<<endl;
cout<<"| 贪吃蛇 |"<<endl;
cout<<"-----------------------"<<endl;
cout<<"| |"<<endl;
cout<<"| |"<<endl;
cout<<"| |"<<endl;
cout<<"| 1:开始游戏 |"<<endl;
cout<<"| 2:游戏介绍 |"<<endl;
cout<<"| 3:退出游戏 |"<<endl;
cout<<"| |"<<endl;
cout<<"-----------------------"<<endl;
char choose;
choose=getch();
if (choose=='3')
return 0;
else if (choose=='2'){
system("cls");
cout<<"传统模式一共有7个关卡,分别对应不同的地图";
cout<<"并且有7个速度等级,玩家自选速度"<<endl<<endl;
cout<<"极限模式一共有13个关卡,每关获得1000分后自动升级"<<endl<<endl;
cout<<"具体操作如下"<<endl;
cout<<"向左:a"<<endl;
cout<<"向右:d"<<endl;
cout<<"向上:w"<<endl;
cout<<"向下:s"<<endl;
system("pause");
}
else if (choose=='1'){
char user1;
system("cls");
cout<<"1:传统模式\n2:极限模式"<<endl;
user1=getch();
system("cls");
if (user1=='1'){
cout<<"请选择关卡(1~7):"<<endl;
char game=getch();
system("cls");
cout<<"请选择速度(1~7):"<<endl;
user1=getch();
int tip=0;
gamestart(game-'0',speed[user1-'0'],0,&tip);
}
else if (user1=='2'){
int j,re=3;
for (j=1;j<=11&&re==3;++j){
Sleep(300);
gamestart(cc2[j],speed2[j],1,&re);
}
if(j==12){
system("cls");
cout<<"恭喜您通过所有关卡"<<endl;
system("pause");
}
}
}
}
return 0;
}