求一个C++的贪吃蛇游戏源代码,要标注解释的。
1个回答
展开全部
/*因为当时只考虑到了代码可通过,没有考虑代码的质量,所以重复利用率差,不要随意改动哦
运行是完全通过的但是会一闪一闪的*/
#include<iostream>
#include<conio.h>
#include<time.h>
#include<windows.h>
#define X 15
#define Y 15
int score=0;
char ch[X][Y];
char lch = 's';
char nch = 's';
class Snake
{
public:
Snake() { nx = 8;ny = 8;lx = 9;ly = 9;next = NULL; }
Snake(Snake&r);//建立蛇身
void input();//把数据输入到图像
void control();//控制贪吃蛇
void show();//显示图像
void check();//检测食物是否被吃掉
bool gameover();//检测游戏是否结束
int nx;
int ny;
int lx;
int ly;
Snake*next;
};
Snake *head;
namespace Food
{
int x;
int y;
void NEW()
{
Snake*p=head;
x = rand() % X;
y = rand() % Y;
while(p!=NULL)
{
if(p->nx==x&&p->ny==y)
{
x = rand() % X;
y = rand() % Y;
p = head;
}
else
p=p->next;
}
ch[x][y]='$';
}
};
Snake::Snake(Snake&r)
{
this->nx = r.lx;
this->ny = r.ly;
r.next = this;
this->next = NULL;
}
void Snake::show()//显示图像
{
system("cls");
//std::cout << " ------------------------------ \n";
for (int y = 0; y<Y; ++y)
{
//std::cout << "|";
for (int x = 0; x < X; ++x)
std::cerr << ch[x][y] << " " ;
std::cerr <<"|"<< std::endl;
}
std::cout << " ------------------------------ \n";
printf("x = %d,y = %d\n",nx,ny);
printf("x = %0X,y = %0X\n",&nx,&ny);
printf("score = %d\n",score);
}
void Snake::control()//键盘控制
{
if (_kbhit() == 1)
{
nch = _getch();
lx = nx;
ly = ny;
if (nch == 'w' || nch == 's' || nch == 'a' || nch == 'd')
{
lch = nch;
switch (nch)
{
case 'w':if (ny == 0) ny = Y - 1; else --ny; break;
case 's':if (ny == Y - 1) ny = 0; else ++ny; break;
case 'a':if (nx == 0) nx = X - 1; else --nx; break;
case 'd':if (nx == X - 1) nx = 0; else ++nx; break;
}
}
else
{
switch (lch)
{
case 'w':if (ny == 0) ny = Y - 1; else --ny; break;
case 's':if (ny == Y - 1) ny = 0; else ++ny; break;
case 'a':if (nx == 0) nx = X - 1; else --nx; break;
case 'd':if (nx == X - 1) nx = 0; else ++nx; break;
}
}
}
else
{
lx = nx;
ly = ny;
if (nch == 'w' || nch == 's' || nch == 'a' || nch == 'd')
{
lch = nch;
switch (nch)
{
case 'w':if (ny == 0) ny = Y - 1; else --ny; break;
case 's':if (ny == Y - 1) ny = 0; else ++ny; break;
case 'a':if (nx == 0) nx = X - 1; else --nx; break;
case 'd':if (nx == X - 1) nx = 0; else ++nx; break;
}
}
else
{
switch (lch)
{
case 'w':if (ny == 0) ny = Y - 1; else --ny; break;
case 's':if (ny == Y - 1) ny = 0; else ++ny; break;
case 'a':if (nx == 0) nx = X - 1; else --nx; break;
case 'd':if (nx == X - 1) nx = 0; else ++nx; break;
}
}
}
}
void Snake::input()//把对象输入到图像
{
Snake*p = head;
ch[p->lx][p->ly] = ' ';
ch[p->nx][p->ny] = '*';
while (p->next != NULL)
{
p->next->lx = p->next->nx;
p->next->ly = p->next->ny;
p->next->nx = p->lx;
p->next->ny = p->ly;
p = p->next;
ch[p->lx][p->ly] = ' ';
ch[p->nx][p->ny] = '*';
}
}
void Snake::check()//检测食物是否被吃掉
{
Snake*p=head;
if (p->nx == Food::x&&p->ny == Food::y)
{
Snake*p = head;
while (p->next != NULL)
{
p = p->next;
}
p->next = new Snake(*p);
Food::NEW();
++score;
}
}
bool Snake::gameover()//检测游戏是否结束
{
Snake*p = head;
Snake*pn = head->next;
while (p != NULL)
{
while (pn != NULL)
{
if (p->nx == pn->nx&&p->ny == pn->ny)
{
std::cout << "Game Over\n";
return true;
}
pn = pn->next;
}
p = p->next;
}
return 0;
}
int main()
{
//初始化
srand(time(NULL));
for (int y = 0; y<Y; ++y)
for (int x = 0; x<X; ++x)
ch[x][y] = ' ';
head = new Snake;
Food::NEW();
std::cout<<"游戏规则:\n1.wsad(小写)控制蛇\n2.若蛇节数超过2,那么无法反方向运动,\n若反方向运动则GameOver\n3.'*'为蛇,'$'为食物\n";
system("pause");
//开始游戏
while (1)
{
head->control();
head->input();
head->check();
if(head->gameover())
break;
head->show();
Sleep(100);
}
Sleep(1000);
system("pause");
return 0;
}
/*------------------------------------------------------------------------------------
当然你也可以用下面这个,经过一些奇怪的算法,当然可读性极差,不闪,但是有时有些莫名其妙的bug的,这是把输出图像变成了一个一维数组,用一维数组来模拟直角坐标系
------------------------------------------------------------------------------------*/
#include<iostream>
#include<windows.h>
#include<conio.h>
#include<time.h>
#define X 32
#define Y 17
char ch[544];
char nch = 's';
char lch = 's';
int score = 0;
class Snake
{
public:
Snake();//创建蛇头
void Add();//添加蛇身
void Show();//显示图像
bool GameOver();//检测游戏是否结束
void Input();//输入数据
void Check();//检测食物是否被吃
void Control();//输入控制
void INIT();
int GetX(){return nx;}
int GetY(){return ny;}
Snake *next;
private:
int lx;
int ly;
int nx;
int ny;
};
Snake*head;
Snake*finally;
namespace Food
{
int x;
int y;
void GetXY()
{
std::cout<<"Food x = "<<x<<"Food y = "<<y<<"\n";
}
void NEW()
{
Snake*p=head;
x = (rand()%15)+1;
y = (rand()%15)+1;
while(p!=NULL)
{
if(p->GetX()==x&&p->GetY()==y)
{
x = (rand()%15)+1;
y = (rand()%15)+1;
p=head;
}
p=p->next;
}
ch[y*32+x*2-1]='$';
}
};
void Snake :: INIT()//初始化
{
for(int n=0;n<=543;++n)
ch[n]=' ';
for(int n=1;n<30;++n)
ch[n]='-';
for(int n=1;n<30;++n)
ch[n+512]='-';
for(int n=0;n<=16;++n)
ch[n*32+31]='\n';
for(int n=1;n<=16;++n)
ch[n*32+30]='|';
for(int n=1;n<=16;++n)
ch[n*32]='|';
ch[543]='\0';
next=NULL;
Food::NEW();
lx = 4;
ly = 4;
nx = 4;
ny = 5;
ch[ly*32+lx*2-1]='*';
}
Snake :: Snake()//创建蛇头head
{
}
void Snake :: Add()//添加蛇身
{
finally->next = new Snake;
finally->next->nx=finally->lx;
finally->next->ny=finally->ly;
finally->next->next=NULL;
finally=finally->next;
}
void Snake :: Control()//控制输入
{
if(kbhit()==1){
nch=getch();
if(nch=='w'||nch=='s'||nch=='a'||nch=='d'){
lch=nch;
switch(nch)
{
case 'w':if(ny==1) ny=15;else ny--;break;
case 's':if(ny==15) ny=1;else ny++;break;
case 'a':if(nx==1) nx=15;else nx--;break;
case 'd':if(nx==15) nx=1;else nx++;break;
}
}else{
switch(lch)
{
case 'w':if(ny==1) ny=15;else ny--;break;
case 's':if(ny==15) ny=1;else ny++;break;
case 'a':if(nx==1) nx=15;else nx--;break;
case 'd':if(nx==15) nx=1;else nx++;break;
}
}
}else{
switch(lch)
{
case 'w':if(ny==1) ny=15;else ny--;break;
case 's':if(ny==15) ny=1;else ny++;break;
case 'a':if(nx==1) nx=15;else nx--;break;
case 'd':if(nx==15) nx=1;else nx++;break;
}
}
}
void Snake :: Show()//显示图像
{
std::cerr<<ch<<"\nscore = "<<score<<"\t";
}
void Snake :: Input()//输入数据
{
Snake*p = head;
ch[(p->lx)*2+(p->ly)*32-1] = ' ';
ch[(p->nx)*2+(p->ny)*32-1] = '*';
while (p->next != NULL)
{
p->next->lx = p->next->nx;
p->next->ly = p->next->ny;
p->next->nx = p->lx;
p->next->ny = p->ly;
p = p->next;
ch[(p->lx)*2+(p->ly)*32-1] = ' ';
ch[(p->nx)*2+(p->ny)*32-1] = '*';
}
head->lx=head->nx;
head->ly=head->ny;
}
bool Snake :: GameOver()//检测游戏是否结束
{
Snake *p = head;
Snake *pl ;
while(p!=NULL)
{
pl=p->next;
while(pl!=NULL)
{
if(p->nx==pl->nx&&p->ny==pl->ny){
std::cout<<"\nGameOver\n";
return true;
}
pl=pl->next;
}
p=p->next;
}
return false;
}
void Snake :: Check()//检测食物是否被吃掉
{
if(head->nx==Food::x&&head->ny==Food::y)
{
Food::NEW();
head->Add();
score++;
}
}
int main(int argc,char *argv[])
{
srand(time(NULL));
head=new Snake;
head->INIT();
finally = head;
while(1)
{
head->Control();//控制输出
head->Input();//输入数据
system("cls");
head->Show();//显示图像
Sleep(150);
if(head->GameOver())//检测游戏是否结束
break;
head->Check();//检测食物是否被吃
}
Sleep(1000);
printf("请按任意键退出\n");
_getch();
return 0;
}
运行是完全通过的但是会一闪一闪的*/
#include<iostream>
#include<conio.h>
#include<time.h>
#include<windows.h>
#define X 15
#define Y 15
int score=0;
char ch[X][Y];
char lch = 's';
char nch = 's';
class Snake
{
public:
Snake() { nx = 8;ny = 8;lx = 9;ly = 9;next = NULL; }
Snake(Snake&r);//建立蛇身
void input();//把数据输入到图像
void control();//控制贪吃蛇
void show();//显示图像
void check();//检测食物是否被吃掉
bool gameover();//检测游戏是否结束
int nx;
int ny;
int lx;
int ly;
Snake*next;
};
Snake *head;
namespace Food
{
int x;
int y;
void NEW()
{
Snake*p=head;
x = rand() % X;
y = rand() % Y;
while(p!=NULL)
{
if(p->nx==x&&p->ny==y)
{
x = rand() % X;
y = rand() % Y;
p = head;
}
else
p=p->next;
}
ch[x][y]='$';
}
};
Snake::Snake(Snake&r)
{
this->nx = r.lx;
this->ny = r.ly;
r.next = this;
this->next = NULL;
}
void Snake::show()//显示图像
{
system("cls");
//std::cout << " ------------------------------ \n";
for (int y = 0; y<Y; ++y)
{
//std::cout << "|";
for (int x = 0; x < X; ++x)
std::cerr << ch[x][y] << " " ;
std::cerr <<"|"<< std::endl;
}
std::cout << " ------------------------------ \n";
printf("x = %d,y = %d\n",nx,ny);
printf("x = %0X,y = %0X\n",&nx,&ny);
printf("score = %d\n",score);
}
void Snake::control()//键盘控制
{
if (_kbhit() == 1)
{
nch = _getch();
lx = nx;
ly = ny;
if (nch == 'w' || nch == 's' || nch == 'a' || nch == 'd')
{
lch = nch;
switch (nch)
{
case 'w':if (ny == 0) ny = Y - 1; else --ny; break;
case 's':if (ny == Y - 1) ny = 0; else ++ny; break;
case 'a':if (nx == 0) nx = X - 1; else --nx; break;
case 'd':if (nx == X - 1) nx = 0; else ++nx; break;
}
}
else
{
switch (lch)
{
case 'w':if (ny == 0) ny = Y - 1; else --ny; break;
case 's':if (ny == Y - 1) ny = 0; else ++ny; break;
case 'a':if (nx == 0) nx = X - 1; else --nx; break;
case 'd':if (nx == X - 1) nx = 0; else ++nx; break;
}
}
}
else
{
lx = nx;
ly = ny;
if (nch == 'w' || nch == 's' || nch == 'a' || nch == 'd')
{
lch = nch;
switch (nch)
{
case 'w':if (ny == 0) ny = Y - 1; else --ny; break;
case 's':if (ny == Y - 1) ny = 0; else ++ny; break;
case 'a':if (nx == 0) nx = X - 1; else --nx; break;
case 'd':if (nx == X - 1) nx = 0; else ++nx; break;
}
}
else
{
switch (lch)
{
case 'w':if (ny == 0) ny = Y - 1; else --ny; break;
case 's':if (ny == Y - 1) ny = 0; else ++ny; break;
case 'a':if (nx == 0) nx = X - 1; else --nx; break;
case 'd':if (nx == X - 1) nx = 0; else ++nx; break;
}
}
}
}
void Snake::input()//把对象输入到图像
{
Snake*p = head;
ch[p->lx][p->ly] = ' ';
ch[p->nx][p->ny] = '*';
while (p->next != NULL)
{
p->next->lx = p->next->nx;
p->next->ly = p->next->ny;
p->next->nx = p->lx;
p->next->ny = p->ly;
p = p->next;
ch[p->lx][p->ly] = ' ';
ch[p->nx][p->ny] = '*';
}
}
void Snake::check()//检测食物是否被吃掉
{
Snake*p=head;
if (p->nx == Food::x&&p->ny == Food::y)
{
Snake*p = head;
while (p->next != NULL)
{
p = p->next;
}
p->next = new Snake(*p);
Food::NEW();
++score;
}
}
bool Snake::gameover()//检测游戏是否结束
{
Snake*p = head;
Snake*pn = head->next;
while (p != NULL)
{
while (pn != NULL)
{
if (p->nx == pn->nx&&p->ny == pn->ny)
{
std::cout << "Game Over\n";
return true;
}
pn = pn->next;
}
p = p->next;
}
return 0;
}
int main()
{
//初始化
srand(time(NULL));
for (int y = 0; y<Y; ++y)
for (int x = 0; x<X; ++x)
ch[x][y] = ' ';
head = new Snake;
Food::NEW();
std::cout<<"游戏规则:\n1.wsad(小写)控制蛇\n2.若蛇节数超过2,那么无法反方向运动,\n若反方向运动则GameOver\n3.'*'为蛇,'$'为食物\n";
system("pause");
//开始游戏
while (1)
{
head->control();
head->input();
head->check();
if(head->gameover())
break;
head->show();
Sleep(100);
}
Sleep(1000);
system("pause");
return 0;
}
/*------------------------------------------------------------------------------------
当然你也可以用下面这个,经过一些奇怪的算法,当然可读性极差,不闪,但是有时有些莫名其妙的bug的,这是把输出图像变成了一个一维数组,用一维数组来模拟直角坐标系
------------------------------------------------------------------------------------*/
#include<iostream>
#include<windows.h>
#include<conio.h>
#include<time.h>
#define X 32
#define Y 17
char ch[544];
char nch = 's';
char lch = 's';
int score = 0;
class Snake
{
public:
Snake();//创建蛇头
void Add();//添加蛇身
void Show();//显示图像
bool GameOver();//检测游戏是否结束
void Input();//输入数据
void Check();//检测食物是否被吃
void Control();//输入控制
void INIT();
int GetX(){return nx;}
int GetY(){return ny;}
Snake *next;
private:
int lx;
int ly;
int nx;
int ny;
};
Snake*head;
Snake*finally;
namespace Food
{
int x;
int y;
void GetXY()
{
std::cout<<"Food x = "<<x<<"Food y = "<<y<<"\n";
}
void NEW()
{
Snake*p=head;
x = (rand()%15)+1;
y = (rand()%15)+1;
while(p!=NULL)
{
if(p->GetX()==x&&p->GetY()==y)
{
x = (rand()%15)+1;
y = (rand()%15)+1;
p=head;
}
p=p->next;
}
ch[y*32+x*2-1]='$';
}
};
void Snake :: INIT()//初始化
{
for(int n=0;n<=543;++n)
ch[n]=' ';
for(int n=1;n<30;++n)
ch[n]='-';
for(int n=1;n<30;++n)
ch[n+512]='-';
for(int n=0;n<=16;++n)
ch[n*32+31]='\n';
for(int n=1;n<=16;++n)
ch[n*32+30]='|';
for(int n=1;n<=16;++n)
ch[n*32]='|';
ch[543]='\0';
next=NULL;
Food::NEW();
lx = 4;
ly = 4;
nx = 4;
ny = 5;
ch[ly*32+lx*2-1]='*';
}
Snake :: Snake()//创建蛇头head
{
}
void Snake :: Add()//添加蛇身
{
finally->next = new Snake;
finally->next->nx=finally->lx;
finally->next->ny=finally->ly;
finally->next->next=NULL;
finally=finally->next;
}
void Snake :: Control()//控制输入
{
if(kbhit()==1){
nch=getch();
if(nch=='w'||nch=='s'||nch=='a'||nch=='d'){
lch=nch;
switch(nch)
{
case 'w':if(ny==1) ny=15;else ny--;break;
case 's':if(ny==15) ny=1;else ny++;break;
case 'a':if(nx==1) nx=15;else nx--;break;
case 'd':if(nx==15) nx=1;else nx++;break;
}
}else{
switch(lch)
{
case 'w':if(ny==1) ny=15;else ny--;break;
case 's':if(ny==15) ny=1;else ny++;break;
case 'a':if(nx==1) nx=15;else nx--;break;
case 'd':if(nx==15) nx=1;else nx++;break;
}
}
}else{
switch(lch)
{
case 'w':if(ny==1) ny=15;else ny--;break;
case 's':if(ny==15) ny=1;else ny++;break;
case 'a':if(nx==1) nx=15;else nx--;break;
case 'd':if(nx==15) nx=1;else nx++;break;
}
}
}
void Snake :: Show()//显示图像
{
std::cerr<<ch<<"\nscore = "<<score<<"\t";
}
void Snake :: Input()//输入数据
{
Snake*p = head;
ch[(p->lx)*2+(p->ly)*32-1] = ' ';
ch[(p->nx)*2+(p->ny)*32-1] = '*';
while (p->next != NULL)
{
p->next->lx = p->next->nx;
p->next->ly = p->next->ny;
p->next->nx = p->lx;
p->next->ny = p->ly;
p = p->next;
ch[(p->lx)*2+(p->ly)*32-1] = ' ';
ch[(p->nx)*2+(p->ny)*32-1] = '*';
}
head->lx=head->nx;
head->ly=head->ny;
}
bool Snake :: GameOver()//检测游戏是否结束
{
Snake *p = head;
Snake *pl ;
while(p!=NULL)
{
pl=p->next;
while(pl!=NULL)
{
if(p->nx==pl->nx&&p->ny==pl->ny){
std::cout<<"\nGameOver\n";
return true;
}
pl=pl->next;
}
p=p->next;
}
return false;
}
void Snake :: Check()//检测食物是否被吃掉
{
if(head->nx==Food::x&&head->ny==Food::y)
{
Food::NEW();
head->Add();
score++;
}
}
int main(int argc,char *argv[])
{
srand(time(NULL));
head=new Snake;
head->INIT();
finally = head;
while(1)
{
head->Control();//控制输出
head->Input();//输入数据
system("cls");
head->Show();//显示图像
Sleep(150);
if(head->GameOver())//检测游戏是否结束
break;
head->Check();//检测食物是否被吃
}
Sleep(1000);
printf("请按任意键退出\n");
_getch();
return 0;
}
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询