Files
2025-06-27 00:32:57 +08:00

238 lines
3.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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