//程序在运行时还有一些错误没有找出,在左右碰壁时会过一个才结束游戏
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char Map[8][16];//游戏地图
int H=8,L=16;//地图的高和长
void MapInitial();//地图的初始化
void CreteFood();//随机产生食物
void getDirection();//读取方向
void Smove();//蛇的移动
void Move();//蛇头,蛇尾移动 (包含在Smove里面)
void Show();//刷新显示地图
void GameOver();//判断是否撞墙,游戏是否结束
int Slength=2;//蛇的长度
int dx[4]={-1,1,0,0};//-1表示向上移动,1表示向下移动(用于蛇头的移动)
int dy[4]={0,0,-1,1};//-1表示向左运动,1表示向右运动
int over=0;
const char Shead=‘@‘;//蛇头
const char Stail=‘*‘;//蛇尾
const char food=‘$‘; //食物
struct {
int x;
int y;//x,y用来确定蛇的某个部位的位置
int direction;//分别用1,2,3,4表示上下左右,刻画蛇头移动的方向
}Snake[8*16];//蛇的每个位置的信息 。Snake[0]表示蛇头
int main(void)
{
MapInitial();
while(1)
{
Smove();
if(over==1)
{
printf("游戏结束\n");
return 0;
}
}
}
void MapInitial()
{
int i=0,j=0;
for(i=0;i<H;i++)
for(j=0;j<L;j++)
Map[i][j]=‘.‘;//Map内存用‘.‘填充
int x=0,y=0;
srand(time(0));
h:
x=rand()%H; //x表示行,y表示列
y=rand()%L;
if(x<H-1)
{
Map[x][y]=Shead;//第一次随机产生蛇头
Map[x+1][y]=Stail;//!!蛇出生时带个小尾巴
}
else
goto h;
Snake[0].x=x;
Snake[0].y=y;
Snake[1].x=x+1;
Snake[1].y=y;
CreteFood();
for(i=0;i<H;i++)
{for(j=0;j<L;j++)
printf("%c",Map[i][j]);
printf("\n");}
getch();//得到第一个方向使其移动,Smove中的按键改变方向
}
void CreteFood()
{
int x,y;
here: //srand()函数为rand函数提供种子,使得rand()函数产生的随机数发生变化
srand(time(0)); //time(0)返回当前时间的秒数%60
x=rand()%H;
y=rand()%L;
if(Map[x][y]==‘.‘)
Map[x][y]=‘$‘;
else
goto here;
}
void getDirection()
{
char key;//读取方向
_sleep(500);//蛇头移动后要停顿,因为玩家在看到蛇到达某一位置时要有按下按钮的时间,以使玩家按下按钮后再下一个坐标处就改变位置
//否则可能玩家在某一处按下按钮,但电脑则已运行至下一次,使得蛇只能在下下次转弯
//!!而停顿的位置应该在电脑读取按键之前,这时候玩家在停顿时间做出的操作才能第一时间在本回合中得到体现!!
if (kbhit()!=0)
{
while(kbhit() != 0)
key=getch();
switch(key)
{
case 72: Snake[0].direction = 0;//上
break;
case 80: Snake[0].direction = 1; //下
break;
case 75: Snake[0].direction = 2; //左
break;
case 77: Snake[0].direction = 3;//右
break;
}
}
}
void Smove()
{
getDirection();//得到按键,没有按键则朝着一个方向移动,有的话则转弯
Move();//蛇头,蛇尾分别移动
Show();//刷新地图
}
void Move()
{
int sum=Slength;//当前蛇的长度
int x=Snake[0].x+dx[Snake[0].direction];
int y=Snake[0].y+dy[Snake[0].direction];
int p=Snake[0].x;
int q=Snake[0].y;//p,q表示蛇头移动前的位置
if(Map[x][y]==‘.‘)
{
Map[Snake[0].x][Snake[0].y]=‘.‘;
Map[x][y]=‘@‘;
}//没吃到食物,继续移动
else if(Map[x][y]==‘$‘)
{
Map[Snake[0].x][Snake[0].y]=‘*‘;
Map[x][y]=‘@‘;
Snake[Slength].x=p;
Snake[Slength].y=q;//新增的蛇长为原来蛇头部分
CreteFood();
Slength++;
}//吃到食物,原来的地方变为蛇尾,产生新食物,蛇长增加
else
{
over=1;//蛇自身相撞游戏结束
printf("游戏结束");
return 0;
}
GameOver();
Snake[0].x=x;
Snake[0].y=y;//移动后蛇头的位置
///////////////////////////////////////////////////////// 以上为蛇头的移动及蛇头吃到食物时长度加1
///////////////////////////////////////////////////////// (原本的食物变为蛇头,原本的蛇头变为蛇尾)
int i;
if(sum==Slength) //当没有吃到食物时蛇身的移动。
{
for(i=1;i<Slength;i++)
{
if(i==1)
Map[Snake[i].x][Snake[i].y]=‘.‘;//把一个置空,使移动后的总长度不变
if(i == Slength-1)
{
Snake[i].x = p;
Snake[i].y = q;
}
else
{
Snake[i].x = Snake[i+1].x;
Snake[i].y = Snake[i+1].y;//i+1是i前面的部分
}
Map[ Snake[i].x ][ Snake[i].y ] = ‘*‘;
}//for
}//if
}
void Show()
{
system("cls");
int i=0,j=0;
for(i = 0; i < H; i++)
{
for(j = 0; j < L; j++)
printf("%c",Map[i][j]);
printf("\n");
}
}
void GameOver()
{
if(Snake[0].x<0||Snake[0].x>=H||Snake[0].y<0||Snake[0].y>=L)
over=1;
}