eaten to get to next level */
/* ,and this is not related with score,but only */
/* eaten number of food
*/
/*
*/
/* level standard:let highlevel stand for the number of */
/* pieces of food that can be put int the */
/* vertical direction of play area,and */
/* before level 5,as long as the snake eat */
/* a quarter of highlevel,it will go to next */
/* level,and between level 5 and 7,as long */
/* as the snake eat one thirds of highlevel, */
/* it will go to next level,and between */
/* level 8 and 9,the snake will go to next */
/* level as long as it eat half of highlevel */
/* note: level is between 1 to 9. */
void show_infor_to_level()
{
int highlevel;
int size;
int tempx,tempy;
int toeat;
void *buf;
char s[50];
highlevel = (border_RB.y - border_LT.y)
/ SCALE;
switch(level)
{
case 1:
case 2:
case 3:
case 4:
toeat = (highlevel / 4) * level - snake_head.eatenC;
break;
case 5:
case 6:
case 7:
toeat = (highlevel highlevel / 3 * (level - 4)) -
snake_head.eatenC;
break;
case 8:
case 9:
toeat = (highlevel * 2 highlevel / 2 * (level - 7)) -
snake_head.eatenC;
break;
default:
break;
}
settextstyle(DEFAULT_FONT,0,1);
setcolor(DEFAULT_COLOR);
if(snake_head.next == NULL)
{
sprintf(s,"next level");
tempx = 0;
tempy = border_LT.y textheight(s) * 2;
outtextxy(tempx,tempy,s);
}
if(toeat < 0)
toeat = 0;
sprintf(s,"%d:%d",level 1,toeat);
tempx = 0;
tempy = border_LT.y textheight(s) * 4;
size = imagesize(tempx,tempy,tempx textwidth(s)
textwidth("A"),tempy
textheight(s));
buf = malloc(size);
getimage(tempx,tempy,tempx textwidth(s) textwidth("A"),tempy
textheight(s),buf);
putimage(tempx,tempy,buf,XOR_PUT);
outtextxy(tempx,tempy,s);
free(buf);
}
/* sub function: win() */
/* function:if the player pass level 9,this function */
/* will be called ,to show "YOU WIN information */
/* and after a key is pressed,the game will go */
/* on,but all is back to begin,excepte the */
/* snake body length.
*/
void win()
{
char s[] = "YOU WIN";
int tempx,tempy;
settextstyle(DEFAULT_FONT,0,8);
setcolor(WELCOME_COLOR);
tempx = border_LT.x (border_RB.x -
border_LT.x - textwidth(s)) / 2;
tempy = border_LT.y (border_RB.y - border_LT.y - textheight(s)) /
2;
outtextxy(tempx,tempy,s);
while(!bioskey(1));
}
/* sub function: can_promote() */
/* function:see if the snake can go to next level on basis */
/* of the snake length.
*/
/*
*/
/* note:standards of promote level is insucted above */
int can_promote()
{
/* compare SCORE with standard level score */
int high_level;
static int last_score = 0;
high_level = (border_RB.y - border_LT.y)
/ SCALE;
switch(level)
{
case 1:
case 2:
case 3:
case 4:
if(snake_head.eatenC == (high_level / 4 * level))
level ;
last_score = score;
break;
case 5:
case 6:
case 7:
if(snake_head.eatenC == (high_level high_level / 3 * (level -
4)))
level ;
last_score = score;
break;
case 8:
if(snake_head.eatenC == (high_level * 2 high_level / 2 ))
level ;
last_score = score;
break;
case 9:
if(snake_head.eatenC == (high_level * 3))
{
win();
score = 0;
last_score = 0;
level = DEFAULT_LEVEL;
}
break;
default:
break;
}
show_level();
}
/* sub function: calulate_hop() */
/* function: calculate the shortest path from snake head to
*/
/* the food it will eaten. */
void calculate_hop()
{
hopcount = (snake_head.posx >= current->posx) ?
((snake_head.posx - current->posx) /
SCALE) :
((current->posx - snake_head.posx) / SCALE);
hopcount = (snake_head.posy >= current->posy) ?
((snake_head.posy - current->posy) /
SCALE) :
((current->posy - snake_head.posy) / SCALE);
}
/* sub function: release()
*/
/* function:free memory before exit game or restart */
void release(SNAKE_HEAD snake_head)
{
FOOD_INFOR_PTR aceon,last;
aceon = snake_head.next;
snake_head.eatenC = 0;
snake_head.next = NULL;
snake_head.hop = 0;
while(aceon)
if(aceon->next != NULL)
aceon = aceon->next;
else
break;
while(aceon)
{
last = aceon->pre;
free(aceon);
aceon = last;
}
}
/* sub function: show_level()x */
/* function:show level information to player anytime */
void show_level()
{
char s[20];
int size;
void *buf;
settextstyle(DEFAULT_FONT,0,1);
setcolor(DEFAULT_COLOR);
sprintf(s,"Level:%d",level);
size = imagesize(0,border_LT.y,textwidth(s),border_LT.y
textheight(s));
buf = malloc(size);
getimage(0,border_LT.y,textwidth(s),
border_LT.y textheight(s),buf);
putimage(0,border_LT.y,buf,XOR_PUT);
free(buf);
outtextxy(0,border_LT.y,s);
}
/* sub function: change_level() */
/* function:if the play choose "select level " item,
*/
/* this function will be called */
void change_level()
{
int c;
int size;
void *buf;
int tempx,tempy;
char s[] = "new level (1--9):";
settextstyle(DEFAULT_FONT,0,1);
setcolor(DEFAULT_COLOR);
tempx = 0;
tempy = border_LT.y - textheight("A") * 3 / 2;
outtextxy(tempx,tempy,s);
goon:
while(!bioskey(1));
c = bioskey(0);
if((c == 0x1051) || (c == 0x1071))
goto exit;
if(isdigit(c&0x00ff))
level = (c&0x00ff) - 48;
else
goto goon;
exit:
size = imagesize(tempx,tempy,tempx textwidth(s),tempy
textheight(s));
buf = malloc(size);
getimage(tempx,tempy,tempx textwidth(s),tempy
textheight(s),buf);
putimage(tempx,tempy,buf,XOR_PUT);
free(buf);
}
/* sub function: show_score() */
/* function:show score information to player anytime */
void show_score(int count)
{
int th;
int size;
void *buf;
char s[20];
settextstyle(DEFAULT_FONT,0,2);
setcolor(SCORE_COLOR);
sprintf(s,"Score: %d",count);
th = textheight("hello");
if((count == 0) &&
(snake_head.next == NULL))
{
outtextxy(border_LT.x (border_RB.x - border_LT.x) / 4,
border_LT.y - 2 * th,s);
}
else
{
size = imagesize(border_LT.x (border_RB.x - border_LT.x) / 4,
border_LT.y - 2 * th,
border_LT.x (border_RB.x - border_LT.x) / 4
textwidth(s) textwidth("100"),
border_LT.y - 2 * th th);
buf = malloc(size);
getimage(border_LT.x (border_RB.x - border_LT.x) / 4,border_LT.y -
2 * th,
border_LT.x (border_RB.x - border_LT.x) / 4 textwidth(s)
textwidth("100"),
border_LT.y - 2 * th th,buf);
putimage(border_LT.x (border_RB.x - border_LT.x) / 4,
border_LT.y - 2 * th,buf,XOR_PUT);
outtextxy(border_LT.x (border_RB.x - border_LT.x) / 4,
border_LT.y - 2 * th,s);
free(buf);
}
}
/* sub function: help()
*/
/* function: show help information at the beginning of game
*/
/* and let player know how to play the game */
void help()
{
char s[100];
int th;
settextstyle(DEFAULT_FONT,0,1);
setcolor(HELP_COLOR);
th = textheight("hello");
sprintf(s,"move left : %c",27);
outtextxy(border_LT.x,border_RB.y,s);
sprintf(s,"move up : %c",24);
outtextxy(border_LT.x (border_RB.x - border_LT.x) / 2,
border_RB.y,s);
sprintf(s,"move down : %c",25);
outtextxy(border_LT.x,border_RB.y th 2,s);
sprintf(s,"move right: %c",26);
outtextxy(border_LT.x (border_RB.x - border_LT.x) / 2,
border_RB.y th 2,s);
outtextxy(border_LT.x,border_RB.y th * 2
4,"quit ");
outtextxy(border_LT.x textwidth("quit ") * 3 /
2,border_RB.y th * 2 4,
"pause
");
outtextxy(border_LT.x (border_RB.x - border_LT.x) / 2,
border_RB.y th * 2 4,"select level ");
}
/* sub function: show_all()
*/
/* function:redraw the play area,means show wall */
void show_all()
{
int i,j;
setcolor(DEFAULT_COLOR);
/*
for(i = border_LT.x; i <= border_RB.x; i = SCALE)
for(j = border_LT.y; j <= border_RB.y; j = SCALE)
rectangle(i,j,i SCALE, j SCALE);
*/
rectangle(border_LT.x,border_LT.y,border_RB.x,border_RB.y);
}
/* sub function: generate_food()
*/
/* function:after the food is eaten by snake,the function will
*/
/* be called to generate another food,and it will */
/* ensure that the generated food shouldn't appeare */
/* in the snake body.
*/
void generate_food()
{
FOOD_INFOR_PTR aceon;
int tempx,tempy;
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 ;
aceon = snake_head.next;
while(aceon)
{
if((aceon->posx == current->posx) && (aceon->posy
== current->posy))
goto generate;
aceon = aceon->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);
}
/* sub function: init_graphics()
*/
/* function:initialize the game interface */
void init_graphics()
{
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) %
FOOD_SIZE)
(border_RB.x) ;
while((border_RB.y - border_LT.y) % FOOD_SIZE)
(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);
help();
show_level();
}
/* sub function: generateX_first_step()
*/
/* function:generate snake head and first food to prepare for
*/
/* game to start,and this function will also initialize*/
/* the move direction of snake head,and show welcome */
/* information to player.
*/
void generate_first_step()
{
char s[] = "welcome to snake game,press ENTER key to start";
int size;
int tempx,tempy;
void *buf;
randomize();
/* generate snake head */
snake_head.posx = random(border_RB.x - SCALE / 2);
while((snake_head.posx <= border_LT.x) || ((snake_head.posx -
border_LT.x) % SCALE == 0)
||<