238 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			238 lines
		
	
	
		
			3.7 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;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 |