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;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|