Files
player/Project_App_Snake/App_Src/calc/snake.c

238 lines
3.7 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#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;
}