#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;imap[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(ymap[(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(xmap[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; }