Problem5780--(示例)贪吃蛇简易智能

5780: (示例)贪吃蛇简易智能

[Creator : ]
Time Limit : 1.000 sec  Memory Limit : 256 MiB

Description

#include <bits/stdc++.h>
#include <conio.h>
#include <windows.h>
using namespace std;

char m[32][32]; //地图 
int N,M; //地图行数、列数 
int fx,fy; //食物位置 
int snk_x[10000],snk_y[10000]; //蛇身体各点的x,y坐标
int sfront,srear;//贪吃蛇头和尾的位置  

void gotoxy(int x,int y)//定位光标位置 
{
	COORD point;
	point.X=y; point.Y=x; 
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),point);
}

/*初始化图*/
void init_map()
{
	memset(m,'#',sizeof(m));//初始化地图中所有元素为# 
	for(int i=1;i<=N;i++)
		for(int j=1;j<=M;j++)
			m[i][j]=' '; 
}

/*把食物放入图中*/
void init_food()
{
	m[fx][fy]='o';
}

/*把蛇放入图中*/
void init_snake()
{
	for(int i=srear;i<=sfront;i++)//从蛇头到蛇尾遍历 
	{
		int px=snk_x[i],py=snk_y[i] ;
		m[px][py]='*';
	}	
}

/*蛇往dct方向移动一步*/
void snake_move(char drct)
{
	int head_x=snk_x[sfront],head_y=snk_y[sfront];//蛇头的位置 
	int next_x,next_y;//蛇头下一步的位置
	
	if(drct=='w')  next_x=head_x-1, next_y=head_y; //向上 
	if(drct=='s')  next_x=head_x+1, next_y=head_y;  //向下 
	if(drct=='a')  next_x=head_x, next_y=head_y-1;//向左 
	if(drct=='d')  next_x=head_x, next_y=head_y+1;//向右 
	
	sfront++;  snk_x[sfront]=next_x; snk_y[sfront]=next_y; //把下步的位置作为蛇头入队 
	
	int rx=snk_x[srear],ry=snk_y[srear];//蛇尾的位置 
	gotoxy(rx,ry); cout<<' ';	//把蛇尾清除 
	srear++;// 蛇尾出队 
} 


/*选择一个最近的方向前进*/
char bestDrct()
{
	int cor[]={-1,0,1,0,0,-1,0,1};
	char drct[]={'w','s','a','d'};
	init_map();
	init_snake();
	
	char bestD=NULL;	int closestDis=INT_MAX;
	for(int i=0;i<4;i++)
	{
		int x=snk_x[sfront]+cor[i*2],y=snk_y[sfront]+cor[i*2+1];
		if(m[x][y]==' '||m[x][y]=='o')
		{
			int dis=abs(fx-x)+abs(fy-y);
			if(dis<closestDis) closestDis=dis,bestD=drct[i]; 
		}
	}
	return bestD;
}



/*画蛇*/ 
void drawSnake()
{
	//画蛇身 
	for(int i=srear;i<=sfront;i++)
	{
		int x=snk_x[i],y=snk_y[i];
		gotoxy(x,y);
		cout<<"*";
	}
	
	//画蛇头 
	int hx=snk_x[sfront],hy=snk_y[sfront];
	gotoxy(hx,hy);
	cout<<"@";
} 

/*判断食物是否被蛇身体的任一部分覆盖,是就返回1,不是就返回0*/
int foodCanEat()
{
	for(int i=sfront;i>=srear;i--)
	{
		int xi=snk_x[i],yi=snk_y[i];
		if(xi==fx && yi==fy)
		 return 1;
	}
	return 0;
}

/*在随机位置生成一个食物*/
void creatFood()
{
	srand(time(0));
	fx=rand()%N+1;
	fy=rand()%M+1;
	//循环确保新食物不在蛇的身体上 
	while(foodCanEat())
	{
		fx=rand()%N+1;
		fy=rand()%M+1;	
	}
}

/*生成食物,并显示*/
void dropFood()
{
	creatFood();
	gotoxy(fx,fy);	cout<<'o'; 
}


/*吃掉食物*/
void eatFood()
{
	sfront++; snk_x[sfront]=fx; snk_y[sfront]=fy;//把食物加入到队头 
}

/*判断是否撞墙,是就返回1,否则返回0*/
int meetWall()
{
	int hx=snk_x[sfront],hy=snk_y[sfront];//获取蛇头的位置 
	if( hx==0 || hx==N+1 || hy==0 || hy==M+1 ) return 1;//判断蛇头是否在边界 
	return 0;
}

/*画图*/
void drawMap()
{
	for(int i=0;i<=N+1;i++)
	{
		for(int j=0;j<=M+1;j++)
			cout<<m[i][j];
		cout<<endl;
	} 
}

/*初始化设置*/
void init_set()
{
	N=20,M=20; //设置地图尺寸 
	
	sfront=2; srear=0;//设置蛇头,蛇尾的位置 
	snk_x[0]=10,snk_y[0]=10;
	snk_x[1]=10,snk_y[1]=11;
	snk_x[2]=10,snk_y[2]=12;
	
	creatFood();
}


int main()
{
	init_set();
	init_map();//初始化图 	
	drawMap();	//画图 
	drawSnake();//画蛇 
	dropFood();
	
	while(1)
	{
		if(meetWall()==1) break;//如果撞墙就退出 
		

		char drct=bestDrct();
		if(drct==NULL) break;
		
		snake_move(drct); 	

		if(foodCanEat()==1) //如果食物能吃,就吃掉食物,并生成另一个食物 
		{
			eatFood();
			dropFood();
		}	
		drawSnake();//重画蛇 
		Sleep(200);		
	} 
}

Source/Category