#include "Conio.h"
#include<graphics.h>
#include<stdlib.h>
#include<dos.h>
#include<stdio.h>
#define closegr closegraph
#define NULL 0
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int t=1,scord=0,speed=1;
char scordc[20],speedc[12];
void initgr(void) /* BGI初始化 */
{
int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */
registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */
initgraph(&gd, &gm, "");
}
typedef struct node{ /*蛇每个节点的结构体*/
int x;
int y;
struct node *next;
}snake,*snakep;
typedef struct{ /*食物的结构体*/
int x;
int y;
}foodf,*foodp;
int main(void)
{
snakep init();
void draw(int x,int y,int p);
void start();
void drawsnake(snakep sn);
void sport(snakep *sn,int f,foodp food);
int check(snakep sn);
int foodcheck(snakep,foodp);
char ch;
start();
while((ch=getch())!='Q'&&ch!='q')
{}; /* 按Q退出*/
closegr(); /* 恢复TEXT屏幕模式 */
return 0;
}
snakep init()
{
int i;
snakep L,p;
initgr(); /* BGI初始化 */
setbkcolor(6);/*设置屏幕背景色*/
setviewport(80,50,550,450,1);/*设置可活动区域*/
sprintf(scordc,"SCORD:%d",scord);
outtextxy(20,20,scordc);/*分数和速度栏*/
sprintf(speedc,"SPEED:%d",speed);
outtextxy(200,20,speedc);
outtextxy(350,20,"SM VS ZG");
for(i=0;i<=390;i+=10)/*初始化场景*/
{
draw(0,i,2);
draw(460,i,2);
}
for(i=10;i<=450;i+=10)
{
draw(i,0,2);
draw(i,30,2);
draw(i,390,2);
}
for(i=10;i<=40;i+=10)/*蛇身初始化,i=40时,为头结点*/
{
p=(snake *)malloc(sizeof(snake));
p->x=i;p->y=40;
if(i==10)
{
p->next=NULL;
L=p;
}
else
{
p->next=L;
L=p;
}
}
return L;
}
void draw(int x,int y,int p) /*画小元件*/
{
setcolor(p);
rectangle(x+1,y+1,x+9,y+9);
rectangle(x+3,y+3,x+7,y+7);
}
void start()
{
int f=0,p=1,i,key;
snakep sn;
foodp food;
randomize();
sn=init();
drawsnake(sn); /*初始化场景和蛇身*/
food=(foodf *)malloc(sizeof(foodf));
while(1)
{
while(!kbhit())
{
while(t==1) /*需要实物*/
{
food->x=(rand()%45+1)*10;
food->y=(rand()%35+4)*10;
if(foodcheck(sn,food))
{
draw(food->x,food->y,15);
t=0;
}
}
delay(31000-2000*speed);
sport(&sn,f,food); /*蛇运动*/
if(check(sn)==1)
{
p=0;
break;
}
}
if(p==0)
{
setcolor(RED);
settextstyle(0,0,4);
outtextxy(80,160,"GAME OVER");
settextstyle(0,0,1);
outtextxy(100,200,"PRESS \"Q\" TO QUIT GAME");
break;
}
key=bioskey(0);
if(key==ESC)
break;
else if(key==RIGHT&&f!=2)
f=0;
else if(key==DOWN&&f!=3)
f=1;
else if(key==LEFT&&f!=0)
f=2;
else if(key==UP&&f!=1)
f=3;
}
}
void drawsnake(snakep sn) /*在屏幕上画出初始蛇*/
{
snakep p=sn->next;
while(p)
{
draw(p->x,p->y,4);
p=p->next;
}
}
void sport(snakep *k,int f,foodp food) /*蛇运动图像*/
{
snakep snb,h,p=(*k)->next;
while(p->next->next)
p=p->next;
snb=p;
h=p; /*snb,k是蛇的尾节点的前一个节点指针*/
p=(*k)->next; /*把蛇的最后一个节点放在最前面*/
snb->next->next=p;
p=snb->next;
snb->next=NULL;
draw(p->x,p->y,6); /*最后一个节点与背景色相同(即去掉最后一个节点)*/
snb=p->next;
switch(f)
{
case 0: /*蛇往右走*/
{
p->x=snb->x+10;
p->y=snb->y;
break;
}
case 1: /*蛇往下走*/
{
p->x=snb->x;
p->y=snb->y+10;
break;
}
case 2: /*蛇往左走*/
{
p->x=snb->x-10;
p->y=snb->y;
break;
}
case 3: /*蛇往上走*/
{
p->x=snb->x;
p->y=snb->y-10;
break;
}
}
draw(p->x,p->y,4);
if(p->x==food->x&&p->y==food->y) /*吃到食物,蛇加长*/
{
snb=(snake *)malloc(sizeof(snake));
snb->next=NULL;
snb->x=h->x;
snb->y=h->y;
h->next=snb;
t=1;
setcolor(6);
outtextxy(20,20,scordc);
scord++;
if(scord%5==0)/*若吃了5个,则升级,速度加快*/
{
setcolor(6);
outtextxy(200,20,speedc);
speed++;
setcolor(15);
sprintf(speedc,"SPEED:%d",speed);
outtextxy(200,20,speedc);
}
setcolor(15);
sprintf(scordc,"SCORD:%d",scord);
outtextxy(20,20,scordc);
}
(*k)->next=p;
}
int check(snakep sn)/*检测蛇是否撞墙或撞自己的身体*/
{
snakep p=sn->next;
if(p->x<10||p->x>450||p->y<40||p->y>380)
return 1;
while(p->next)
{
p=p->next;
if(sn->next->x==p->x&&sn->next->y==p->y)
return 1;
}
return 0;
}
int foodcheck(snakep sn,foodp food)/*检测食物出现的位置是否和蛇的身体重合*/
{
while(sn->next)
{
sn=sn->next;
if(sn->x==food->x&&sn->y==food->y)
return 0;
}
return 1;
}