Problem5776--(示例)如何解决闪屏问题

5776: (示例)如何解决闪屏问题

[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 dct)
{
	int head_x=snk_x[sfront],head_y=snk_y[sfront];//蛇头的位置 
	int rx=snk_x[srear],ry=snk_y[srear];//蛇尾的位置 
	int next_x,next_y;//蛇头下一步的位置
	
	if(dct=='w')  next_x=head_x-1, next_y=head_y; //向上 
	if(dct=='s')  next_x=head_x+1, next_y=head_y;  //向下 
	if(dct=='a')  next_x=head_x, next_y=head_y-1;//向左 
	if(dct=='d')  next_x=head_x, next_y=head_y+1;//向右 
	
	sfront++;  snk_x[sfront]=next_x; snk_y[sfront]=next_y; //把下步的位置作为蛇头入队 
	srear++;// 蛇尾出队 
	
	gotoxy(rx,ry); cout<<' ';	//把蛇尾清除 
} 

/*在随机位置生成一个食物*/
void creatFood()
{
	srand(time(0));
	fx=rand()%N+1;
	fy=rand()%M+1;
}

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

/*画蛇*/ 
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 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;//如果撞墙就退出 
		
		if(kbhit())//监测击键,并按方向前进 
		{
			char ch=getch();
			
			//asdw和上下左右方向键 
			if(ch=='a'||ch=='A'||ch==75)	snake_move('a'); 	
			if(ch=='d'||ch=='D'||ch==77)	snake_move('d');
			if(ch=='s'||ch=='S'||ch==80)	snake_move('s');
			if(ch=='w'||ch=='W'||ch==72)	snake_move('w');
			
			drawSnake();//重画蛇 
		}
		
		if(foodCanEat()==1) //如果食物能吃,就吃掉食物,并生成另一个食物 
		{
			eatFood();
			dropFood();
		}			
	} 
}

Source/Category