238 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			238 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "snake.h"
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//创建一个贪吃蛇类
 | 
						||
snak_struct *snake_creat(void)
 | 
						||
{
 | 
						||
	snak_struct *s=mymalloc(sizeof(snak_struct));
 | 
						||
	snake_init(s);
 | 
						||
	return s;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
//初始化
 | 
						||
void snake_init(snak_struct *s)
 | 
						||
{
 | 
						||
	mymemset(s,0,sizeof(snak_struct));
 | 
						||
	for(int i=0;i<MAP_X_SIZE*MAP_Y_SIZE;i++)
 | 
						||
	{
 | 
						||
		cell_struct *cell=&s->map[i];
 | 
						||
		cell->next_x=0xff;
 | 
						||
		cell->next_y=0xff;
 | 
						||
	}
 | 
						||
	
 | 
						||
	//贪吃蛇从左上角出现
 | 
						||
	cell_struct *cell=&s->map[0];
 | 
						||
	cell->next_x=0;cell->next_y=0;cell->type=CELL_TYPE_BODY;
 | 
						||
	cell=&s->map[1];
 | 
						||
	cell->next_x=0;cell->next_y=0;cell->type=CELL_TYPE_HEAD;
 | 
						||
	s->head_x=1;s->head_y=0;
 | 
						||
	s->tail_x=0;s->tail_y=0;
 | 
						||
	s->dir=DIR_RIGHT;
 | 
						||
	
 | 
						||
	snake_food(s);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//删除一个贪吃蛇类
 | 
						||
void snake_delete(snak_struct *s)
 | 
						||
{
 | 
						||
	if(s)
 | 
						||
	{
 | 
						||
		myfree(s);
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//找到新的尾部,返回1,成功,0,失败
 | 
						||
int snake_find_tail_new(snak_struct *s)
 | 
						||
{
 | 
						||
	u8 x=s->tail_x;
 | 
						||
	u8 y=s->tail_y;
 | 
						||
	
 | 
						||
	cell_struct *tail=&s->map[y*MAP_X_SIZE+x];
 | 
						||
	tail->type=CELL_TYPE_AIR;
 | 
						||
	tail->next_x=0xff;
 | 
						||
	tail->next_y=0xff;
 | 
						||
	
 | 
						||
	cell_struct *cell=0;
 | 
						||
	
 | 
						||
	if(y<MAP_Y_SIZE-1)
 | 
						||
	{
 | 
						||
		cell=&s->map[(y+1)*MAP_X_SIZE+x];
 | 
						||
		if(cell->next_x==x&&cell->next_y==y)
 | 
						||
		{
 | 
						||
			s->tail_x=x;
 | 
						||
			s->tail_y=y+1;
 | 
						||
			return 1;
 | 
						||
		}
 | 
						||
	}
 | 
						||
	if(y>0)
 | 
						||
	{
 | 
						||
		cell=&s->map[(y-1)*MAP_X_SIZE+x];
 | 
						||
		if(cell->next_x==x&&cell->next_y==y)
 | 
						||
		{
 | 
						||
			s->tail_x=x;
 | 
						||
			s->tail_y=y-1;
 | 
						||
			return 1;
 | 
						||
		}
 | 
						||
	}
 | 
						||
	if(x>0)
 | 
						||
	{
 | 
						||
		cell=&s->map[y*MAP_X_SIZE+(x-1)];
 | 
						||
		if(cell->next_x==x&&cell->next_y==y)
 | 
						||
		{
 | 
						||
			s->tail_x=x-1;
 | 
						||
			s->tail_y=y;
 | 
						||
			return 1;
 | 
						||
		}
 | 
						||
	}
 | 
						||
	if(x<MAP_X_SIZE-1)
 | 
						||
	{
 | 
						||
		cell=&s->map[y*MAP_X_SIZE+(x+1)];
 | 
						||
		if(cell->next_x==x&&cell->next_y==y)
 | 
						||
		{
 | 
						||
			s->tail_x=x+1;
 | 
						||
			s->tail_y=y;
 | 
						||
			return 1;
 | 
						||
		}
 | 
						||
	}
 | 
						||
	return 0;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
//蛇生长,吃到了食物,返回1,成功
 | 
						||
int snake_grow(snak_struct *s)
 | 
						||
{
 | 
						||
	u8 x=s->tail_x;
 | 
						||
	u8 y=s->tail_y;
 | 
						||
	
 | 
						||
	cell_struct *tail=&s->map[y*MAP_X_SIZE+x];
 | 
						||
	x=tail->next_x;
 | 
						||
	y=tail->next_y;
 | 
						||
	
 | 
						||
	//除非连续生长两次,这不可能
 | 
						||
	if(x>=MAP_X_SIZE||y>=MAP_Y_SIZE) return 0;
 | 
						||
	
 | 
						||
	tail=&s->map[y*MAP_X_SIZE+x];
 | 
						||
	tail->type=CELL_TYPE_BODY;
 | 
						||
	s->tail_x=x;
 | 
						||
	s->tail_y=y;
 | 
						||
	return 1;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//贪吃蛇前进一步,1,成功,0,失败
 | 
						||
int snake_forward(snak_struct *s)
 | 
						||
{
 | 
						||
	u8 x=s->head_x;
 | 
						||
	u8 y=s->head_y;
 | 
						||
	cell_struct *cell=&s->map[y*MAP_X_SIZE+x];
 | 
						||
	
 | 
						||
	//把当前头部设置为身体
 | 
						||
	cell->type=CELL_TYPE_BODY;
 | 
						||
	
 | 
						||
	//没找到新的尾部,正常情况是不可能发生的
 | 
						||
	if(snake_find_tail_new(s)==0) return 0;
 | 
						||
	
 | 
						||
	//头部向前走
 | 
						||
	u8 x_old=x;
 | 
						||
	u8 y_old=y;
 | 
						||
	if(s->dir==DIR_RIGHT) x++;
 | 
						||
	else if(s->dir==DIR_LEFT) x--;
 | 
						||
	else if(s->dir==DIR_UP) y--;
 | 
						||
	else if(s->dir==DIR_DOWN)	y++;
 | 
						||
	
 | 
						||
	//超出边界
 | 
						||
	if(x>=MAP_X_SIZE||y>=MAP_Y_SIZE)
 | 
						||
		return 0;
 | 
						||
	
 | 
						||
	cell_struct *head=&s->map[y*MAP_X_SIZE+x];
 | 
						||
	if(head->type!=CELL_TYPE_AIR)
 | 
						||
	{
 | 
						||
		//头部撞到了东西
 | 
						||
		if(head->type==CELL_TYPE_FOOD)
 | 
						||
		{
 | 
						||
			s->mark++;
 | 
						||
			head->type=CELL_TYPE_HEAD;
 | 
						||
			head->next_x=x_old;
 | 
						||
			head->next_y=y_old;
 | 
						||
			snake_grow(s);
 | 
						||
			snake_food(s);
 | 
						||
		}
 | 
						||
		else
 | 
						||
		{
 | 
						||
			//撞到了其他东西,游戏失败
 | 
						||
			return 0;
 | 
						||
		}
 | 
						||
	}
 | 
						||
	else
 | 
						||
	{
 | 
						||
		head->type=CELL_TYPE_HEAD;
 | 
						||
		head->next_x=x_old;
 | 
						||
		head->next_y=y_old;
 | 
						||
	}
 | 
						||
	s->head_x=x;
 | 
						||
	s->head_y=y;
 | 
						||
	return 1;
 | 
						||
	
 | 
						||
	
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
//生成新的食物,返回1,生成了食物,0,找不到地方生成食物了,游戏结束
 | 
						||
int snake_food(snak_struct *s)
 | 
						||
{
 | 
						||
	if(s->mark>(MAP_X_SIZE*MAP_Y_SIZE-s->wall_num-10))
 | 
						||
		return 0;
 | 
						||
	
 | 
						||
	//使用硬件随机数发生器生成随机数
 | 
						||
	do{
 | 
						||
		u8 x=((u32)rand())%MAP_X_SIZE;
 | 
						||
		u8 y=((u32)rand())%MAP_Y_SIZE;
 | 
						||
		cell_struct *cell=&s->map[y*MAP_X_SIZE+x];
 | 
						||
		
 | 
						||
		if(cell->type==CELL_TYPE_AIR)
 | 
						||
		{
 | 
						||
			cell->type=CELL_TYPE_FOOD;
 | 
						||
			return 1;
 | 
						||
		}
 | 
						||
		
 | 
						||
	} while(1);
 | 
						||
	
 | 
						||
}
 | 
						||
 | 
						||
//运行,返回0,游戏结束
 | 
						||
int snake_run(snak_struct *s)
 | 
						||
{
 | 
						||
	if(snake_forward(s)==0) return 0;
 | 
						||
	return 1;
 | 
						||
	
 | 
						||
}
 | 
						||
 | 
						||
//设置前进方向
 | 
						||
int snake_set_dir(snak_struct *s,int dir)
 | 
						||
{
 | 
						||
	if(s==0) return 0;
 | 
						||
	if(dir>=1&&dir<=4)
 | 
						||
	{
 | 
						||
		s->dir=dir;
 | 
						||
		return 1;
 | 
						||
	}
 | 
						||
	return 0;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 |