本程序为贪吃蛇游戏,想必大家都玩过这个游戏,程序源代码用TC2.0编译通过,需要图形驱动文件的支持,在TC2.0的集成环境中有.

本程序利用数据结构中的链表,来将蛇身连接,同时当蛇吃到一定数目的东西时会自动升级,及移动速度会加快,程序会时刻将一些信息显示在屏幕上,包括所得分数,要吃多少东西才能升级,并且游戏者可以自己手动选择游戏级别,级别越高,蛇的移动速度越快.

另外,此游戏可能与CPU的速度有关系.

源代码如下:

************************************************************ **********************

/*******************************COMMENTS******************** **************/

/* snake_game.c

*/

/* it is a game for entermainment.

*/

/* in the begin,there is only a snake head,and it will have to eat food */

/* to become stronger,and it eat a piece of food each TIme,it will */

/* lengthen it's body,with the number of food the snake eats going up,it */

/* will become long more and more,and the score will goes up also. */

/* there is always useful informaTIon during the game process. */

/* if the path by which the snake goes to eat food is the shortest,the */

/* score will add up a double.

*/

/*

*/

/* enjoy yourself,and any problem,contact */

/*********************************************************** **************/

/* all head file that will be used */

#include

#include

#include

#include

#include

#include

/* useful MACRO */

#define FOOD_SIZE 8

#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 INVALID_DIRECTION 0

#define QUIT_KEYC 0x1051

#define QUIT_KEY 0x1071

#define SELECT_KEYC 0x1f53

#define SELECT_KEY 0x1f73

#define PAUSE_KEYC 0x1950

#define PAUSE_KEY 0x1970

#define DEFAULT_LEVEL 1

#define HELP_COLOR WHITE

#define WELCOME_COLOR WHITE

#define DEFAULT_COLOR GREEN

/* define the macro as follows to improve the game in future */

#define FOOD_COLOR YELLOW

#define SNAKE_HEAD_COLOR RED

#define DEFAULT_SNAKE_COLOR YELLOW

#define EXIT_COLOR WHITE

#define SCORE_COLOR YELLOW

/* sturcture for snake body mainly ,and food also */

typedef struct food_infor *FOOD_INFOR_PTR;

typedef struct food_infor{

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 */

FOOD_INFOR_PTR next; /* pointer to next piece of snake body */

FOOD_INFOR_PTR pre; /* pointer to previous piece of snake body */

}FOOD_INFOR;

/* structure for snake head */

typedef struct _snake_head{

int posx;

int posy;

int next_move;

int pre_move;

int eatenC; /* number of food that have been eaten */

int hop; /* number of steps to eat food */

FOOD_INFOR_PTR next; /* pointer to the first piece of eaten food */

}SNAKE_HEAD;

/* the left-up corner and right-down corner */

typedef struct point{

int x;

int y;

}POINT;

/* standards for game speed

*/

/* before level 5,the time interval is level_b[level - 1] / 10,and after */

/* level 5,the time interval is 1.00 / level_b[level - 1] */

float level_b[9] = {10.0,8.0,6.0,3.0,1.0,20.0,40.0,160.0,640.0};

/* available varary */

SNAKE_HEAD snake_head;

FOOD_INFOR *current; /* always point to food */

POINT border_LT,border_RB;

int driver,mode; /* for graphics driver */

int maxx,maxy; /* max length and width of screen,in pixel */

int eaten; /* identifier if the food is eaten */

int score = 0; /* total score */

int level = DEFAULT_LEVEL; /* level or speed */

float interval; /* based on speed */

int snake_color = DEFAULT_SNAKE_COLOR; /* snake body color */

int hopcount = 0; /* the shortest number of steps for snake */

/* to eat food */

/* all sub function */

void init_graphics();

void generate_first_step();

int judge_death();

int willeatfood();

void generate_food();

void addonefood();

void redrawsnake();

void show_all();

void sort_all();

void change_direction();

void help();

void show_score(int);

void change_level();

void show_level();

void release(SNAKE_HEAD);

int can_promote();

void win();

void show_infor_to_level();

void show_eaten();

void calculate_hop();

/* main function or entry */

void main()

{

char str[50] = "YOU LOSE!!!"; /* fail information */

clock_t start;

int querykey;

int tempx,tempy;

/* if fail and want to resume game,go here */

retry:

init_graphics();

show_all(); /* show wall */

generate_first_step(); /* generate food and snake head */

show_score(score); /* show score to player */

eaten = 0;

/* begin to play game */

while(1)

{

if(judge_death() == 1) /* die */

break;

if(willeatfood() == 1)

{

eaten = 1;

addonefood();

snake_head.hop ++;

if(snake_head.hop == hopcount)

score += level * 2;

else

score += level;

can_promote();

show_score(score);

}

sort_all();

redrawsnake();

snake_head.hop ++;

show_infor_to_level();

show_eaten();

show_all();

change_direction();

if(eaten == 1)

{

generate_food();

calculate_hop();

snake_head.hop = 0;

eaten = 0;

}

if(level <= 5)

interval = level_b[level - 1] / 10.0;

else

interval = 1.00 / level_b[level - 1];

start = clock();

while((clock() - start) / CLK_TCK < interval)

{

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;

case SELECT_KEYC:

case SELECT_KEY:

change_level();

score = 0;

show_score(score);

show_level();

break;

case PAUSE_KEYC:

case PAUSE_KEY:

while(!bioskey(1));

break;

case QUIT_KEYC:

case QUIT_KEY:

goto exit_game;

default:

break;

}

}

}

}

settextstyle(DEFAULT_FONT,0,2);

setcolor(EXIT_COLOR);

tempx = border_LT.x + (border_RB.x - border_LT.x - textwidth(str)) / 2;

tempy = border_LT.y + (border_RB.y - border_LT.y) / 2;

outtextxy(tempx,tempy,str);

strcpy(str,"press to retry,or ENTER key to exit");

tempy += textheight(str) * 2;

settextstyle(DEFAULT_FONT,0,1);

tempx = border_LT.x + (border_RB.x - border_LT.x - textwidth(str)) / 2;

outtextxy(tempx,tempy,str);

select:

while(!bioskey(1));

querykey = bioskey(0);

if((querykey == 0x1372) || (querykey == 0x1352))

{

level = DEFAULT_LEVEL;

score = 0;

release(snake_head);

closegraph();

goto retry;

}

if(querykey != 0x1c0d)

goto select;

closegraph();

return;

exit_game:

release(snake_head);

closegraph();

}

/* sub function show_eaten() */

/* function: to show the total number piece of food */

/* that have been eaten by snake any time */

void show_eaten()

{

int tempx,tempy;

int size;

void *buf;

char str[15];

settextstyle(DEFAULT_FONT,0,1);

setcolor(DEFAULT_COLOR);

sprintf(str,"eaten:%d",snake_head.eatenC);

tempx = 0;

tempy = border_LT.y + textheight(str) * 6;

size = imagesize(tempx,tempy,tempx + textwidth(str) + textwidth("A"),

tempy + textheight(str));

buf = malloc(size);

getimage(tempx,tempy,tempx + textwidth(str) + textwidth("A"),

tempy + textheight(str),buf);

putimage(tempx,tempy,buf,XOR_PUT);

outtextxy(tempx,tempy,str);

free(buf);

}

/* sub function: show_infor_to_level */

/* function:show information to player that how many pieces */

/* of food have to been 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 str[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(str,"next level");

tempx = 0;

tempy = border_LT.y + textheight(str) * 2;

outtextxy(tempx,tempy,str);

}

if(toeat < 0)

toeat = 0;

sprintf(str,"%d:%d",level + 1,toeat);

tempx = 0;

tempy = border_LT.y + textheight(str) * 4;

size = imagesize(tempx,tempy,tempx + textwidth(str) + textwidth("A"),tempy +

textheight(str));

buf = malloc(size);

getimage(tempx,tempy,tempx + textwidth(str) + textwidth("A"),tempy +

textheight(str),buf);

putimage(tempx,tempy,buf,XOR_PUT);

outtextxy(tempx,tempy,str);

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 str[] = "YOU WIN";

int tempx,tempy;

settextstyle(DEFAULT_FONT,0,8);

setcolor(WELCOME_COLOR);

tempx = border_LT.x + (border_RB.x - border_LT.x - textwidth(str)) / 2;

tempy = border_LT.y + (border_RB.y - border_LT.y - textheight(str)) / 2;

outtextxy(tempx,tempy,str);

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 instructed 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 traceon,last;

traceon = snake_head.next;

snake_head.eatenC = 0;

snake_head.next = NULL;

snake_head.hop = 0;

while(traceon)

if(traceon->next != NULL)

traceon = traceon->next;

else

break;

while(traceon)

{

last = traceon->pre;

free(traceon);

traceon = last;

}

}

/* sub function: show_level()x */

/* function:show level information to player anytime */

void show_level()

{

char str[20];

int size;

void *buf;

settextstyle(DEFAULT_FONT,0,1);

setcolor(DEFAULT_COLOR);

sprintf(str,"Level:%d",level);

size = imagesize(0,border_LT.y,textwidth(str),border_LT.y + textheight(str));

buf = malloc(size);

getimage(0,border_LT.y,textwidth(str),

border_LT.y + textheight(str),buf);

putimage(0,border_LT.y,buf,XOR_PUT);

free(buf);

outtextxy(0,border_LT.y,str);

}

/* 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 str[] = "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,str);

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(str),tempy + textheight(str));

buf = malloc(size);

getimage(tempx,tempy,tempx + textwidth(str),tempy + textheight(str),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 str[20];

settextstyle(DEFAULT_FONT,0,2);

setcolor(SCORE_COLOR);

sprintf(str,"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,str);

}

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(str) + 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(str) +

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,str);

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 str[100];

int th;

settextstyle(DEFAULT_FONT,0,1);

setcolor(HELP_COLOR);

th = textheight("hello");

sprintf(str,"move left : %c",27);

outtextxy(border_LT.x,border_RB.y,str);

sprintf(str,"move up : %c",24);

outtextxy(border_LT.x + (border_RB.x - border_LT.x) / 2,

border_RB.y,str);

sprintf(str,"move down : %c",25);

outtextxy(border_LT.x,border_RB.y + th + 2,str);

sprintf(str,"move right: %c",26);

outtextxy(border_LT.x + (border_RB.x - border_LT.x) / 2,

border_RB.y + th + 2,str);

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 traceon;

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 ++;

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);

}

/* 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 str[] = "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)

||

((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);

/* generate first food */

current = (FOOD_INFOR_PTR)malloc(sizeof(FOOD_INFOR));

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);

calculate_hop();

snake_head.next = NULL;

snake_head.eatenC = 0;

snake_head.hop = 0;

current->next = NULL;

current->pre = NULL;

current->beEaten = 0;

current->next_move = INVALID_DIRECTION;

current->pre_move = INVALID_DIRECTION;

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 = MOVE_RIGHT;

else

snake_head.next_move = MOVE_LEFT;

}

snake_head.pre_move = snake_head.next_move;

settextstyle(DEFAULT_FONT,0,1);

setcolor(WELCOME_COLOR);

tempx = border_LT.x + (border_RB.x - border_LT.x - textwidth(str)) / 2;

tempy = border_LT.y - textheight("A") * 6 / 2;

outtextxy(tempx,tempy,str);

size = imagesize(tempx,tempy,tempx + textwidth(str),

tempy + textheight(str));

buf = malloc(size);

getimage(tempx,tempy,tempx + textwidth(str),

tempy + textheight(str),buf);

while(bioskey(0) != 0x1c0d);

putimage(tempx,tempy,buf,XOR_PUT);

free(buf);

}

/* sub function: judge_death()

*/

/* function:judge if the snake will die because of incorrect */

/* move,there are two things that will result */

/* the snake to death:first,it run into the wall */

/* ,and second,it run into its body.

*/

int judge_death()

{

/* return 1 means will die,and return 0 means will survive */

int tempx,tempy;

switch(snake_head.next_move)

{

case MOVE_UP:

tempx = snake_head.posx;

tempy = snake_head.posy - SCALE;

break;

case MOVE_LEFT:

tempx = snake_head.posx - SCALE;

tempy = snake_head.posy;

break;

case MOVE_DOWN:

tempx = snake_head.posx;

tempy = snake_head.posy + SCALE;

break;

case MOVE_RIGHT:

tempx = snake_head.posx + SCALE;

tempy = snake_head.posy;

break;

default:

break;

}

if((tempx < border_LT.x) || (tempx > border_RB.x) ||

(tempy < border_LT.y) || (tempy > border_RB.y))

return 1;

if(getpixel(tempx,tempy) == snake_color)

{

FOOD_INFOR_PTR traceon;

traceon = snake_head.next;

while(traceon != NULL)

{

if((traceon->posx == tempx) && (traceon->posy == tempy))

return 1;

traceon = traceon->next;

}

}

return 0; /* survive */

}

/* sub function: willeatfood() */

/* function:judge if the sanke can eat food.the method like */

/* this:provided that the snake move a step based */

/* on its next move direction,and if this place */

/* have food,then the snake can eat food. */

int willeatfood()

{

/* 1 means will eat food ,and 0 means won't eat food */

int tempx,tempy;

switch(snake_head.next_move)

{

case MOVE_UP:

tempx = snake_head.posx;

tempy = snake_head.posy - SCALE;

break;

case MOVE_LEFT:

tempx = snake_head.posx - SCALE;

tempy = snake_head.posy;

break;

case MOVE_DOWN:

tempx = snake_head.posx;

tempy = snake_head.posy + SCALE;

break;

case MOVE_RIGHT:

tempx = snake_head.posx + SCALE;

tempy = snake_head.posy;

break;

default:

break;

}

if(getpixel(tempx,tempy) == FOOD_COLOR)

return 1;

return 0;

}

/* sub function: addonefood() */

/* function: this function will lengthen the snake body */

/* this function is important because it will */

/* not only locate memory for new snake body, */

/* but also handle the relationship of pointer*/

/* between the new snake body and its previous*/

/* snake body.

*/

void addonefood()

{

FOOD_INFOR_PTR traceon;

snake_head.eatenC ++ ;

traceon = snake_head.next;

if(snake_head.next == NULL) /* haven't eaten any food */

{

traceon = (FOOD_INFOR_PTR)malloc(sizeof(FOOD_INFOR));

switch(snake_head.next_move)

{

case MOVE_UP:

traceon->posx = snake_head.posx;

traceon->posy = snake_head.posy + SCALE;

break;

case MOVE_LEFT:

traceon->posx = snake_head.posx + SCALE;

traceon->posy = snake_head.posy;

break;

case MOVE_DOWN:

traceon->posx = snake_head.posx;

traceon->posy = snake_head.posy - SCALE;

break;

case MOVE_RIGHT:

traceon->posx = snake_head.posx - SCALE;

traceon->posy = snake_head.posy;

break;

default:

break;

}

traceon->next_move = snake_head.next_move;

traceon->pre_move = snake_head.next_move;

traceon->next = NULL;

traceon->pre = NULL;

traceon->beEaten = 1;

snake_head.next = traceon;

}

else

{

while(traceon)

{

if(traceon->next != NULL)

traceon = traceon->next;

else

break;

}

traceon->next = (FOOD_INFOR_PTR)malloc(sizeof(FOOD_INFOR));

traceon->next->next = NULL;

traceon->next->pre = traceon;

traceon = traceon->next;

switch(traceon->pre->next_move)

{

case MOVE_UP:

traceon->posx = traceon->pre->posx;

traceon->posy = traceon->pre->posy + SCALE;

break;

case MOVE_LEFT:

traceon->posx = traceon->pre->posx + SCALE;

traceon->posy = traceon->pre->posy;

break;

case MOVE_DOWN:

traceon->posx = traceon->pre->posx;

traceon->posy = traceon->pre->posy - SCALE;

break;

case MOVE_RIGHT:

traceon->posx = traceon->pre->posx - SCALE;

traceon->posy = traceon->pre->posy;

break;

default:

break;

}

traceon->next_move = traceon->pre->next_move;

traceon->pre_move = traceon->pre->next_move;

traceon->beEaten = 1;

}

}

/* sub function: sort_all()

*/

/* function:this function will calculate the next position of snake */

/* and it is assume the snake has move to next position,but*/

/* haven't appeared yet.

*/

void sort_all()

{

/* sort all food,include snake head,and virtual place */

FOOD_INFOR_PTR traceon;

void *buf;

int size;

size = imagesize(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,

snake_head.posx + SCALE / 2,snake_head.posy + SCALE /

2);

buf = malloc(size);

getimage(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,

snake_head.posx + SCALE / 2,snake_head.posy + SCALE / 2,buf);

putimage(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,

buf,XOR_PUT);

switch(snake_head.next_move)

{

case MOVE_UP:

snake_head.posy -= SCALE;

break;

case MOVE_LEFT:

snake_head.posx -= SCALE;

break;

case MOVE_DOWN:

snake_head.posy += SCALE;

break;

case MOVE_RIGHT:

snake_head.posx += SCALE;

break;

default:

break;

}

traceon = snake_head.next;

while(traceon)

{

getimage(traceon->posx - SCALE / 2,traceon->posy - SCALE / 2,

traceon->posx + SCALE / 2,traceon->posy + SCALE / 2,buf);

putimage(traceon->posx - SCALE / 2,traceon->posy - SCALE / 2,

buf,XOR_PUT);

switch(traceon->next_move)

{

case MOVE_UP:

traceon->posy -= SCALE;

break;

case MOVE_LEFT:

traceon->posx -= SCALE;

break;

case MOVE_DOWN:

traceon->posy += SCALE;

break;

case MOVE_RIGHT:

traceon->posx += SCALE;

break;

default:

break;

}

traceon = traceon->next;

}

free(buf);

}

/* sub function: redrawsnake()

*/

/* function:the function will redraw the snake based on function*/

/* sort_all().

*/

void redrawsnake()

{

FOOD_INFOR_PTR traceon;

setcolor(DEFAULT_COLOR);

/* redraw snake head */

setfillstyle(SOLID_FILL,SNAKE_HEAD_COLOR);

rectangle(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,

snake_head.posx + SCALE / 2,snake_head.posy + SCALE / 2);

floodfill(snake_head.posx,snake_head.posy,DEFAULT_COLOR);

/* redraw all eaten foodd */

setfillstyle(SOLID_FILL,snake_color);

traceon = snake_head.next;

while(traceon)

{

rectangle(traceon->posx - SCALE / 2,traceon->posy - SCALE / 2,

traceon->posx + SCALE / 2,traceon->posy + SCALE / 2);

floodfill(traceon->posx,traceon->posy,DEFAULT_COLOR);

traceon = traceon->next;

}

}

/* sub function: change_direction() */

/* function:this function will assign the next move direction*/

/* of snake,it calculate on basis of the information*/

/* of snake body structure.

*/

void change_direction()

{

FOOD_INFOR_PTR traceon,temp1,temp2;

traceon = snake_head.next;

/*if(traceon == NULL)*/ /* only have snake head */

snake_head.pre_move = snake_head.next_move;

if(traceon != NULL)

{

while(traceon)

{

if(traceon->next != NULL)

traceon = traceon->next;

else

break;

}

while(traceon->pre != NULL)

{

traceon->pre_move = traceon->next_move;

traceon->next_move = traceon->pre->next_move; /***/

traceon = traceon->pre;

}

traceon->pre_move = traceon->next_move;

traceon->next_move = snake_head.pre_move;

}

}

/* SOCRE CODE ENDED */

/* DATE: JUL 2th,01 */

************************************************************ *********************************