本程序为贪吃蛇游戏,想必大家都玩过这个游戏,程序源代码用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 <blldw@etang.com> */
/*********************************************************** **************/
/* 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()
{
后续请点击https://www.elecfans.com/soft/6/2007/200706051208.html下载观看~
|