/*
* http://www.softwarematrix.cn/blog/
*
*这是我写的第一个比较长的程序。还可以吧。
*
*
*/
/*
*
*程序员:黄江斌
*功能:小游戏 贪吃蛇
*时间:2004.11.23
*最后修改时间:2004.11.23
*
*/
#include "stdio.h"
#include "graphics.h"
#include "bios.h"
#include "stdlib.h"
#include "dos.h"
#include "string.h"
#define ERROR 1
#define OK 0
#define MAXLENGTH 400
#define MAXWALL 200
#define WALLCOLOR YELLOW
#define SNAKEHEAD GREEN
#define SNAKEBODY LIGHTGRAY
#define FOODCOLOR RED
#define BACKCOLOR BLACK
#define TEXTCOLOR LIGHTGRAY
#define EXPLODE WHITE
#define HELP 59
#define ESC 27
#define ENTER 13
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define MAXLEVEL 20
#define LOOP 1
#define DELAY 0xffff
struct location
{
int x;
int y;
};
struct snakeType
{
struct location body[MAXLENGTH];
int length;
int life;
int direction;
};
struct foodType
{
int x;
int y;
int yes;
};
int LEVELUPLEN;
int worldTop;
int worldLeft;
int worldX;
int worldY;
int gameLevel;
struct snakeType snake;
struct location wall[MAXWALL];
struct foodType food;
int setGraphMode(void);
void snakeInit(void);
void wallInit(void);
void gameInit(void);
void foodInit(void);
void clearFood(void);
void worldDraw(void);
int tick(void);
void levelup(void);
void drawHead(int);
void drawTail(int);
void win(void);
int dead(int,int);
void help(void);
int main()
{
int ret;
if(setGraphMode()==ERROR)
return ERROR;
do
{
gameInit();
worldDraw();
ret=LOOP;
do
{
ret=tick();
if(ret==HELP)
{
help();
break;
}
}while(ret!=ESC);
}while(ret!=ESC);
getch();
closegraph();
}
int setGraphMode()
{
int drive=DETECT,mode;
initgraph(&drive,&mode,"");
registerbgidriver(EGAVGA_driver);
setbkcolor(BACKCOLOR);
return OK;
}
void snakeInit()
{
snake.body[0].x=3;
snake.body[0].y=2;
snake.body[1].x=2;
snake.body[1].y=2;
snake.length=2;
snake.life=1;
snake.direction=RIGHT;
}
void wallInit()
{
int i,k=0;
for(i=0;i<MAXWALL;i++)
{
wall[i].x=0;
wall[i].y=0;
}
for(i=1;i<=worldX;i++)
{
wall[k].x=i;
wall[k].y=1;
k++;
wall[k].x=i;
wall[k].y=worldY;
k++;
}
for(i=2;i<worldY;i++)
{
wall[k].x=1;
wall[k].y=i;
k++;
wall[k].x=worldX;
wall[k].y=i;
k++;
}
}
void foodInit()
{
int i,flag,x,y;
randomize();
flag=0;
do
{
x=random(worldX)%worldX;
y=random(worldY)%worldY;
while(x<1) x++;
while(x>worldX) x--;
while(y<1) y++;
while(y>worldY) y--;
flag=1;
for(i=0;i<snake.length;i++)
if(x==snake.body[i].x && y==snake.body[i].y)
{
flag=0;
break;
}
if(flag==0)
continue;
i=0;
do
{
if(wall[i].x==0 || wall[i].y==0)
break;
if(x==wall[i].x && y==wall[i].y)
{
flag=0;
break;
}
i++;
}while(1);
}while(flag!=1);
food.x=x;
food.y=y;
food.yes=1;
setcolor(FOODCOLOR);
setfillstyle(SOLID_FILL,FOODCOLOR);
bar(worldLeft+food.x*10,worldTop+food.y*10,worldLeft+food.x*10+9,worldTop+food.y*10+9);
}
void clearFood()
{
setcolor(BACKCOLOR);
setfillstyle(SOLID_FILL,BACKCOLOR);
bar(worldLeft+food.x*10,worldTop+food.y*10,worldLeft+food.x*10+9,worldTop+food.y*10+9);
food.yes=0;
}
void gameInit()
{
worldX=(int)(getmaxx()/100)*10;
worldY=(int)(getmaxy()/100*0.75)*10;
worldTop=(getmaxy()-worldY*10)/2;
worldLeft=(getmaxx()-worldX*10)/2;
gameLevel=1;
LEVELUPLEN=5;
wallInit();
snakeInit();
}
void worldDraw()
{
int k=0;
cleardevice();
setcolor(WALLCOLOR);
do
{
if(wall[k].x==0 || wall[k].y==0 || k>=MAXWALL)
break;
rectangle(worldLeft+wall[k].x*10,worldTop+wall[k].y*10, worldLeft+wall[k].x*10+9,worldTop+wall[k].y*10+9);
k++;
}while(1);
setcolor(SNAKEHEAD);
setfillstyle(SOLID_FILL,SNAKEHEAD);
bar(worldLeft+snake.body[0].x*10,worldTop+snake.body[0].y*10,worldLeft+snake.body[0].x*10+9,worldTop+snake.body[0].y*10+9);
setcolor(SNAKEBODY);
setfillstyle(SOLID_FILL,SNAKEBODY);
for(k=1;k<snake.length;k++)
{
bar(worldLeft+snake.body[k].x*10,worldTop+snake.body[k].y*10,worldLeft+snake.body[k].x*10+9,worldTop+snake.body[k].y*10+9);
}
setcolor(BACKCOLOR);
setfillstyle(SOLID_FILL,TEXTCOLOR);
bar(worldLeft+10,worldTop-20,worldLeft+worldX*10+10,worldTop-10);
outtextxy(worldLeft+12,worldTop-18,"GAME LEVEL:1");
outtextxy(worldLeft+150,worldTop-18,"SNAKE LENGTH:2");
bar(worldLeft+10,worldTop+worldY*10+30,worldLeft+worldX*10+10,worldTop+worldY*10+40);
outtextxy(worldLeft+12,worldTop+worldY*10+32,"Press F1 for Help ...");
foodInit();
}
int tick()
{
char ch;
char str1[80];
char str2[80];
int x,y;
int i;
int flag=1;
if(food.yes==0)
foodInit();
if(bioskey(1)!=0)
{
ch=getch();
if(ch==0)
ch=getch();
switch(ch)
{
case UP:
if(snake.direction==LEFT || snake.direction==RIGHT)
snake.direction=UP;
break;
case DOWN:
if(snake.direction==LEFT || snake.direction==RIGHT)
snake.direction=DOWN;
break;
case LEFT:
if(snake.direction==UP || snake.direction==DOWN)
snake.direction=LEFT;
break;
case RIGHT:
if(snake.direction==UP || snake.direction==DOWN)
snake.direction=RIGHT;
break;
case ESC:
return ESC;
case HELP:
return HELP;
}
}
switch(snake.direction)
{
case UP:
x=snake.body[0].x;
y=snake.body[0].y-1;
break;
case DOWN:
x=snake.body[0].x;
y=snake.body[0].y+1;
break;
case LEFT:
x=snake.body[0].x-1;
y=snake.body[0].y;
break;
case RIGHT:
x=snake.body[0].x+1;
y=snake.body[0].y;
break;
}
flag=1;
for(i=0;i<snake.length;i++)
if(x==snake.body[i].x && y==snake.body[i].y)
{
flag=0;
break;
}
i=0;
do
{
if(x==wall[i].x && y==wall[i].y)
{
flag=0;
break;
}
if(wall[i].x==0 || wall[i].y==0)
break;
i++;
}while(1);
if(flag==0)
{
return dead(x,y);
}
if(food.yes==1)
drawTail(BACKCOLOR);
drawHead(SNAKEBODY);
if(snake.body[0].x==food.x && snake.body[0].y==food.y)
{
clearFood();
for(i=snake.length;i>=1;i--)
{
snake.body[i].x=snake.body[i-1].x;
snake.body[i].y=snake.body[i-1].y;
}
snake.length++;
strcpy(str1,"SNAKE LENGTH:");
itoa(snake.length,str2,10);
strcat(str1,str2);
setcolor(BACKCOLOR);
setfillstyle(SOLID_FILL,TEXTCOLOR);
bar(worldLeft+150,worldTop-20,worldLeft+worldX*10+10,worldTop-10);
outtextxy(worldLeft+150,worldTop-18,str1);
if(snake.length>=LEVELUPLEN)
levelup();
return LOOP;
}
else
for(i=snake.length-1;i>=1;i--)
{
snake.body[i].x=snake.body[i-1].x;
snake.body[i].y=snake.body[i-1].y;
}
snake.body[0].x=x;
snake.body[0].y=y;
drawHead(SNAKEHEAD);
delay(DELAY-gameLevel*0x0aff);
return LOOP;
}
void levelup()
{
char str1[80];
char str2[80];
gameLevel++;
LEVELUPLEN=LEVELUPLEN+gameLevel+5;
if(gameLevel==MAXLEVEL+1)
win();
strcpy(str1,"GAME LEVEL:");
itoa(gameLevel,str2,10);
strcat(str1,str2);
setcolor(BACKCOLOR);
setfillstyle(SOLID_FILL,TEXTCOLOR);
bar(worldLeft+10,worldTop-20,worldLeft+149,worldTop-10);
outtextxy(worldLeft+12,worldTop-18,str1);
}
void drawHead(int color)
{
setcolor(color);
setfillstyle(SOLID_FILL,color);
bar(worldLeft+snake.body[0].x*10,worldTop+snake.body[0].y*10,worldLeft+snake.body[0].x*10+9,worldTop+snake.body[0].y*10+9);
}
void drawTail(int color)
{
setcolor(color);
setfillstyle(SOLID_FILL,color);
bar(worldLeft+snake.body[snake.length-1].x*10,worldTop+snake.body[snake.length-1].y*10,worldLeft+snake.body[snake.length-1].x*10+9,worldTop+snake.body[snake.length-1].y*10+9);
}
void win()
{
cleardevice();
printf("/n/n");
printf("/tThank you for playing this game!/n");
printf("/tThe game is written by HuangJiangbin at 2004.11.23/n");
printf("/n/n");
printf("/tIt's time to study. Bye-bye./n");
getch();
exit(1);
}
int dead(int x,int y)
{
char ch;
setcolor(EXPLODE);
setfillstyle(SOLID_FILL,EXPLODE);
bar(worldLeft+(x-1)*10,worldTop+(y-1)*10,worldLeft+(x-1)*10+30,worldTop+(y-1)*10+30);
do
{
ch=getch();
if(ch==ESC)
return ESC;
else if(ch==HELP)
return HELP;
}while(ch!=ENTER);
cleardevice();
gameInit();
worldDraw();
return ENTER;
}
void help()
{
cleardevice();
printf("/n/n");
printf("/tThe program is written by: HuangJiangBin/n");
printf("/t 2004.11.23/n");
printf("/n/n");
printf("/tFunction of keys.../n");
printf("/tF1 List this message/n");
printf("/tESC Quit the game/n");
printf("/tENTER Start a new game after die/n");
printf("/tUP Move direction turn to UP/n");
printf("/tDOWN Move direction turn to DOWN/n");
printf("/tLEFT Move direction turn to LEFT/n");
printf("/tRIGHT Move direction turn to RIGHT/n");
printf("/n/n");
printf("/tPRESS ENTER RETURN TO GAME...");
while(getch()!=ENTER);
}