#include<stdio.h>
#include<time.h>
#include<graphics.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#define SCALE 8
#define UP_KEY 0x4800
#define DOWN_KEY 0x5000
#define LEFT_KEY 0x4b00
#define RIGHT_KEY 0x4d00
#define MOVE_UP 1
#define MOVE_LEFT 2
#define MOVE_DOWN 3
#define MOVE_RIGHT 4
#define DEFAULT_COLOR GREEN
#define FOOD_COLOR YELLOW
#define SNAKE_HEAD_COLOR RED
struct food
{
int posx; /* position for each piece of snake body */
int posy;
int next_move; /* next move direction */
int pre_move; /* previous move direction,seems unuseful */
int beEaten; /* xidentifier for snake body or food */
struct food* next; /* pointer to next piece of snake body */
struct food* pre; /* pointer to previous piece of snake body */
}*current;
struct _snake_head
{
int posx;
int posy;
int next_move;
int pre_move;
int eatenC; /* number of food that have been eaten */
struct food* next;
}snake_head;
struct point
{
int x;
int y;
}border_LT,border_RB;
float speed=0.01;
int eaten;
int snake_color = FOOD_COLOR;
void init_graphics();
void first_step();
int judge_death();
int willeatfood();
void food();
void addonefood();
void redrawsnake();
void show_all();
void sort_all();
void change_direction();
void release(struct _snake_head);
void main()
{
/* fail information */
clock_t start;
int querykey;
int tempx,tempy;
retry:
init_graphics();
show_all(); /* show wall */
first_step(); /* generate food and snake head */
eaten = 0;
while(1)
{
if(judge_death() == 1) /* die */
break;
if(willeatfood() == 1)
{
eaten = 1;
addonefood();
}
sort_all();
redrawsnake();
show_all();
change_direction();
if(eaten == 1)
{
food();
eaten = 0;
}
start = clock();
while((clock() - start) / CLK_TCK < speed)
{
querykey = bioskey(1);
if(querykey != 0)
{
switch(bioskey(0))
{
case UP_KEY:
snake_head.next_move = MOVE_UP;
break;
case LEFT_KEY:
snake_head.next_move = MOVE_LEFT;
break;
case DOWN_KEY:
snake_head.next_move = MOVE_DOWN;
break;
case RIGHT_KEY:
snake_head.next_move = MOVE_RIGHT;
break;
default:
break;
}
}
}
}
select:
while(!bioskey(1));
querykey = bioskey(0);
if((querykey == 0x1372) || (querykey == 0x1352))
{
release(snake_head);
closegraph();
goto retry;
}
if(querykey != 0x1c0d)
goto select;
closegraph();
return;
exit_game:
release(snake_head);
closegraph();
}
void release(struct _snake_head snake_head)
{
struct food* traceon,*last;
traceon = snake_head.next;
snake_head.eatenC = 0;
snake_head.next = NULL;
while(traceon)
if(traceon->next != NULL)
traceon = traceon->next;
else
break;
while(traceon)
{
last = traceon->pre;
free(traceon);
traceon = last;
}
}
void show_all()
{
int i,j;
setcolor(DEFAULT_COLOR);
rectangle(border_LT.x,border_LT.y,border_RB.x,border_RB.y);
}
void food()
{
struct food* traceon;
generate:
current->posx = random(border_RB.x - SCALE / 2);
while((current->posx <= border_LT.x) || ((current->posx - border_LT.x) % SCALE == 0) ||
((current->posx - border_LT.x) % SCALE % (SCALE / 2) != 0))
current->posx ++;
current->posy = random(border_RB.y - SCALE / 2);
while((current->posy <= border_LT.y) || ((current->posy - border_LT.y) % SCALE == 0) ||
((current->posy - border_LT.y) % SCALE % (SCALE / 2) != 0))
current->posy ++;
traceon = snake_head.next;
while(traceon)
{
if((traceon->posx == current->posx) && (traceon->posy == current->posy))
goto generate;
traceon = traceon->next;
}
if(current->posx - border_LT.x == SCALE / 2)
current->posx += SCALE;
if(border_RB.x - current->posx == SCALE / 2)
current->posx -= SCALE;
if(current->posy - border_LT.y == SCALE / 2)
current->posy += SCALE;
if(border_RB.y - current->posy == SCALE / 2)
current->posy -= SCALE;
setcolor(DEFAULT_COLOR);
rectangle(current->posx - SCALE / 2,current->posy - SCALE / 2,
current->posx + SCALE / 2,current->posy + SCALE / 2);
setfillstyle(SOLID_FILL,YELLOW);
floodfill(current->posx,current->posy,DEFAULT_COLOR);
}
void init_graphics()
{int driver,mode;
int maxx,maxy;
driver = DETECT;
mode = 0;
initgraph(&driver,&mode,"*.bgi");
maxx = getmaxx();
maxy = getmaxy();
border_LT.x = maxx / SCALE;
border_LT.y = maxy / SCALE;
border_RB.x = maxx * (SCALE - 1) / SCALE;
border_RB.y = maxy * (SCALE - 1) / SCALE;
while((border_RB.x - border_LT.x) % 8)
(border_RB.x) ++;
while((border_RB.y - border_LT.y) % 8)
(border_RB.y) ++;
while((border_RB.y - border_LT.y) % ( 12 * SCALE))
border_RB.y += SCALE;
setcolor(DEFAULT_COLOR);
rectangle(border_LT.x,border_LT.y,border_RB.x,border_RB.y);
}
void first_step()
{
int size;
int tempx,tempy;
void *buf;
randomize();
snake_head.posx = random(border_RB.x - SCALE / 2);
while((snake_head.posx <= border_LT.x) || ((snake_head.posx - border_LT.x) % SCALE == 0) ||
((snake_head.posx - border_LT.x) % SCALE % (SCALE / 2) != 0))
snake_head.posx ++;
snake_head.posy = random(border_RB.y - SCALE / 2);
while((snake_head.posy <= border_LT.y) || ((snake_head.posy - border_LT.y) % SCALE == 0) ||
((snake_head.posy - border_LT.y) % SCALE % (SCALE / 2) != 0))
snake_head.posy ++;
setcolor(DEFAULT_COLOR);
rectangle(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,
snake_head.posx + SCALE / 2,snake_head.posy + SCALE / 2);
setfillstyle(SOLID_FILL,SNAKE_HEAD_COLOR);
floodfill(snake_head.posx,snake_head.posy,DEFAULT_COLOR);
current = (struct food*)malloc(sizeof(struct food));
goon_generate:
current->posx = random(border_RB.x - SCALE / 2);
while((current->posx <= border_LT.x) || ((current->posx - border_LT.x) % SCALE == 0) ||
((current->posx - border_LT.x) % SCALE % (SCALE / 2) != 0))
current->posx ++;
current->posy = random(border_RB.y - SCALE / 2);
while((current->posy <= border_LT.y) || ((current->posy - border_LT.y) % SCALE == 0) ||
((current->posy - border_LT.y) % SCALE % (SCALE / 2) != 0))
current->posy ++;
if((current->posx == snake_head.posx) && (current->posy == snake_head.posy))
goto goon_generate;
rectangle(current->posx - SCALE / 2,current->posy - SCALE / 2,
current->posx + SCALE / 2,current->posy + SCALE / 2);
setfillstyle(SOLID_FILL,FOOD_COLOR);
floodfill(current->posx,current->posy,DEFAULT_COLOR);
snake_head.next = NULL;
snake_head.eatenC = 0;
current->next = NULL;
current->pre = NULL;
current->beEaten = 0;
current->next_move = 0;
current->pre_move = 0;
if(snake_head.posx == current->posx)
{
if(snake_head.posy > current->posy)
snake_head.next_move = MOVE_UP;
else
snake_head.next_move = MOVE_DOWN;
}
else
{
if(snake_head.posx < current->posx)
snake_head.next_move
- 1
- 2
前往页