数组版贪吃蛇

关于数组贪吃蛇移动思路,由于蛇身是数组,因此用数组的下标能够很好
的移动到需要操作的位置,每次移动的时候让蛇尾先移动,之后读取下一位
置的坐标再移动,直到数组[1]的位置,(为什么不到[0]因为[0]是蛇头的
位置,我们需要用它来移动位置)之后让[0]自加,(蛇就会移动了)


关于制造食物的思路,需要特别考虑的一点,不要把食物生成到蛇身的坐标
里面,因此,每当产生了新的食物的坐标,我们都要循环一偏蛇身,检测是
否与神身的坐标相同的,如果有则重新产生新的坐标,如果没有则结束循环


关于方向键的思路,先定义两个变量CH1,CH2。其中CH1用爱接受用户的按键
信息,CH2用来作为主函数的实参(它是传给方向函数,操作小蛇的方向)
首先给CH2赋一个向右移动的值,之后我们判断如果CH2向右边移动,那么输入
CH1的值若是向左边就不执行CH2=CH1。

编译器:VC6


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <conio.h>


int	v=200;						//小蛇的移动速度
int foodx;						//食物的坐标
int foody;
int snakeleng=2;				//蛇身的长度(注意数组坐标从0开始)
int count=0;					//计算分数


struct body
{
	int x;
	int y;
};
struct body snake_body[500];	//蛇身的长度




void gotoxy(int x,int y)
{
	HANDLE app;								//定义句柄
	COORD pos;								//定义坐标
	pos.X=x;								//修改X坐标,使X移动
	pos.Y=y;								//修改Y坐标,使Y移动
	app=GetStdHandle(STD_OUTPUT_HANDLE);	//获取句柄
	SetConsoleCursorPosition(app,pos);		//将获取的句柄移动,坐标是POS	
}


void initsnake()			//初始化小蛇
{
	int i,temp=7;


	for(i=0;i<3;i++,temp-=2)
	{
		snake_body[i].x=temp;
		snake_body[i].y=10;


		gotoxy(temp,10);
		printf("■");
	}
}


void direct(char ch)		//小蛇移动方向函数
{
		if(ch=='s'||ch=='S')//支持大小写按键
			snake_body[0].y=snake_body[0].y+1;	


		if(ch=='w'||ch=='W')
			snake_body[0].y=snake_body[0].y-1;


		if(ch=='a'||ch=='A')
			snake_body[0].x=snake_body[0].x-2;


		if(ch=='d'||ch=='D')
			snake_body[0].x=snake_body[0].x+2;
}


void make_food()					//制造食物(有问题,怎么避免把食物生成在蛇身里?)
{
	int i,flag=1;					//此处是flag用于记录蛇身坐标与食物坐标是否相等


	srand((unsigned)time(NULL));


	while(flag)
	{
		foodx=rand()%53+2;
		if(foodx%2==0)				//将食物的X轴坐标变为奇数
			foodx++;


		foody=rand()%22+2;
	
		for(i=snakeleng;i>=0;i--)	//遍历蛇身
		{	//如果产生的食物坐标与蛇身的任意位置相等
			if(snake_body[i].x==foodx && snake_body[i].y==foody)
			{
				flag=1;				//坐标相等则再重新产生新的坐标
				break;				//跳出循环
			}
			else
				flag=0;
		}
		
	}
	gotoxy(foodx,foody);			//画出食物
	printf("●");
}


void drawmap()						//地图函数
{
	int i;


	for(i=1;i<=30;i++)
		printf("□");


	printf("\n");


	for(i=1;i<=23;i++)
	{
		printf("□\t\t\t\t\t\t\t  □");
		printf("\n");
	}


	for(i=1;i<=30;i++)
		printf("□");
	
	gotoxy(66,4);
	printf("贪吃蛇内测");
	gotoxy(65,5);
	printf("软件开发二班");


	gotoxy(64,7);
	printf("======");
	gotoxy(64,8);
	printf("‖玩家得分‖");
	gotoxy(64,9);
	printf("‖\t  ‖");
	gotoxy(64,10);
	printf("======");


	gotoxy(64,13);
	printf("======");
	gotoxy(64,14);
	printf("‖游戏说明 ‖");
	gotoxy(64,15);
	printf("‖w向上移动‖");
	gotoxy(64,16);
	printf("‖s向下移动‖");
	gotoxy(64,17);
	printf("‖a向左移动‖");
	gotoxy(64,18);
	printf("‖d向右移动‖");
	gotoxy(64,19);
	printf("======");
}


int add_snake_body()			//增加蛇身的函数
{
	if(snake_body[0].x==foodx && snake_body[0].y==foody)	//如果食物坐标和蛇头坐标相等,说明蛇已经吃到食物了
	{
		gotoxy(foodx,foody);	//擦去蛇的食物
		printf("■");


		snakeleng++;			//增加蛇的长度
		count++;				//每吃一个食物增加一分
		v--;


		gotoxy(66,9);			//打印得分
		printf("%5d",count);


		snake_body[snakeleng].x=snake_body[snakeleng-1].x;		//增加新的身体,读取下个位置的坐标
		snake_body[snakeleng].y=snake_body[snakeleng-1].y;
			
		return 1;				//记录蛇已经吃了食物
	}
	else
		return 0;
}


void read_next_coord()			//下一位置坐标函数
{
	int i;


	for(i=snakeleng;i>0;i--)	//循环读取下一个位置的坐标
		{
			if(i==snakeleng)	//如果i等于蛇尾(snakeleng最先初始化为2,那么2是蛇尾)
			{
				gotoxy(snake_body[i].x,snake_body[i].y);		//擦除蛇尾
				printf("  ");
			}


			snake_body[i].x=snake_body[i-1].x;					
			snake_body[i].y=snake_body[i-1].y;	
	}
}


void snake_death()				//判断蛇死亡的函数
{
	int i;


	if( (snake_body[0].x<2 || snake_body[0].x>55) || (snake_body[0].y<1 || snake_body[0].y>23))	//检测左右两边是否碰墙,检测上下两边是否碰墙
	{
		printf("撞墙了!游戏结束!");
		exit(0);
	}


	for(i=snakeleng;i>=4;i--)					//能否避免遍历所有数组?
	{
		if(snake_body[0].x==snake_body[i].x && snake_body[0].y==snake_body[i].y)
		{
			printf("咬到身体了!");
			exit(0);
		}
	}
}


int main(void)
{
	int flag=1;						//标记食物是否被吃
	char ch2='d',ch1='a';


	system("color b");				//改变颜色


	drawmap();						//初始化地图
	
	initsnake();					//初始化蛇身


	while(1)
	{
		if(flag)
		{
			make_food();
			flag=0;
		}


		read_next_coord();			//蛇身读取下一个位置的坐标
	
		if(kbhit())					//接受键盘输入的方向
			ch1=getch();
		
		if(ch1!='a' && ch1!='s' && ch1!='w' && ch1!='d')//此语句是为了避免用户按下非a,s,w,d键
			ch1=ch2;				//将上次移动的方向键赋值(如果错误按下,然默认为按原来方向移动)


		if((ch2=='d' && ch1!='a')||(ch2=='w' && ch1!='s')||(ch2=='s' && ch1!='w')||(ch2=='a' && ch1!='d'))
		{
			ch2=ch1;				//此语句要来判断小蛇不往相反方向移动	
		}


		direct(ch2);				//调用方向函数	
		
		gotoxy(snake_body[0].x,snake_body[0].y);				//画出新的蛇头
		printf("■");
		Sleep(v);					//控制蛇的速度


		flag=add_snake_body();		//判断蛇是否吃了食物


		snake_death();				//判断蛇是否死亡
	}	
	return 0;
}


  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值