#include<bios.h>
#include<dos.h>
#include<conio.h>
//#include<conio.c>
#include<stdio.h>
#include<stdlib.h>
#define VGA256 0x13
#define TEXT_MODE 0x03
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define ESC 0x11b
#define ENTER 0x1c0d
#define PAUSE 0x1970
#define SPEED 0x4838
#define START_X 50
#define START_Y 50
#define BACKCOLOR 3
#define FOODCOLOR 4
#define VERGECOLOR 7
#define BODYCOLOR 9
#define ON 1
#define OFF 0
#define EAT 1
#define FALSE 0
#define BODYSIZE 5
#define MAX 100
unsigned char far *video_buffer=(char far *)0xA0000000L;
unsigned char far *rom_char_set = (char far *)0xF000FA6EL;
typedef struct Splace
{
int x;
int y;
}Snak;
Snak sbody[MAX],stemp;
int front, rear, count ;
void Set_Video_Mode(int mode);
void Delay(int clicks);
void put_point(int x,int y,char color);
void show_letter(int x,int y,char color,char bcolor,char c);
void show_str(int x,int y,char color,char bcolor,char*str);
int get_color(int x,int y);
void put_body(Snak a,int status);
void food(void);
int next_status(Snak head);
void initial(void);
void show_point(void);
void show_speed(int v);
int main(void)
{
int key = 0,control = 4,st,v=3;
Set_Video_Mode(VGA256);
initial() ;
show_speed(v);
while(key != ESC)
{
do
{
if(control == OFF )
{
break;
}
switch(control)
{
case 1 : stemp.y = sbody[rear].y-1; break;
case 2 : stemp.y = sbody[rear].y+1; break;
case 3 : stemp.x = sbody[rear].x-1; break;
case 4 : stemp.x = sbody[rear].x+1; break;
}
st = next_status(stemp);
if(st == FALSE)
{
control = OFF;
show_str(90,90,FOODCOLOR,BACKCOLOR,"GAME OVER");
show_str(115,100,FOODCOLOR,BACKCOLOR,"^_^");
show_str(70,110,14,BACKCOLOR,"press Enter to ");
show_str(90,120,14,BACKCOLOR,"continue!");
show_str(70,130,14,BACKCOLOR,"or Esc to exit");
break;
}
rear = (rear + 1)%MAX;
sbody[rear] = stemp;
put_body(sbody[rear], ON);
if(st == EAT)
{
show_point();
++count;
food();
continue;
}
put_body(sbody[front], OFF);
front = (front + 1)%MAX;
Delay(v);
} while(!kbhit());
key = bioskey(0);
switch(key)
{
case UP : if(control != 2 && control != OFF) control = 1; break;
case DOWN : if(control != 1 && control != OFF) control = 2; break;
case LEFT : if(control != 4 && control != OFF) control = 3; break;
case RIGHT: if(control != 3 && control != OFF) control = 4; break;
case PAUSE: if(control != OFF)
while(getch() != 'p'); break;
case ENTER: if(control == OFF)
{
initial();
control = 4;
} break;
case SPEED: v = v % 8 + 1; show_speed(v); break;
}
}
Set_Video_Mode(TEXT_MODE);
return 0;
}
void Set_Video_Mode(int mode)
{
union REGS inregs,outregs;
inregs.h.ah=0;
inregs.h.al=(unsigned char)mode;
int86(0x10,&inregs,&outregs);
}
void Delay(int clicks)
{
unsigned int far *clock=(unsigned int far *)0x0000046CL;
unsigned int now;
now=*clock;
while(abs(*clock-now)<clicks){} // 为什么Delay中的循环后没有冒号也正确
}
void put_point(int x,int y,char color)
{
video_buffer[((y<<8)+(y<<6))+x]=color;
}
void show_letter(int x,int y,char color,char bcolor,char c)
{
char far *w;
int i,j,bit;
w = rom_char_set + c*8;
for(i = 0; i < 8;i++)
{
bit = 0x80;
for(j = 0; j < 8;j++)
{
if(*w & bit)
put_point(x+j,y+i,color);
else
put_point(x+j,y+i,bcolor);
bit = bit>>1;
}
w+=1;
}
}
void show_str(int x,int y,char color,char bcolor,char*str)
{
int i;
for(i =0;str[i] != '\0';i++)
show_letter(x+(i<<3),y,color,bcolor,str[i]);
}
int get_color(int x,int y)
{
x = x*BODYSIZE+ START_X +2;
y = y*BODYSIZE+ START_Y +2;
return video_buffer[((y<<8)+(y<<6))+x];
}
void put_body(Snak a,int status)
{
int x = a.x,y = a.y;
int i,j,color;
if(status == ON)
color = BODYCOLOR ;
else
if(status == OFF)
color = BACKCOLOR;
else
color = FOODCOLOR;
x = x*BODYSIZE+ START_X;
y = y*BODYSIZE+ START_Y;
for(i=1;i<BODYSIZE;i++)
for(j=1;j<BODYSIZE;j++)
put_point(x + j,y + i,color);
}
void food(void)
{
Snak a;
do{
a.x = rand()%29;
a.y = rand()%19;
}while(get_color(a.x,a.y) != BACKCOLOR );
put_body(a,-1);
}
int next_status(Snak head)
{
int st;
st = get_color(head.x,head.y);
if(st == FOODCOLOR)
return EAT;
if(st == VERGECOLOR || st == BODYCOLOR)
return FALSE;
}
/****************************************
* 150*100 =>30*20 5*5 perspace *
* x: 0-29 y: 0-19; *
****************************************/
void initial(void)
{
int x,y;
char *c=" greedy snak ";
randomize();
front = 0,rear = 1,count = 1;
sbody[front].x = 0;sbody[front].y = 0;
sbody[rear].x = 1;sbody[rear].y = 0;
stemp=sbody[rear];
show_str(50,12,VERGECOLOR,0,c);
for(y = START_Y -BODYSIZE; y < START_Y +105; y++)
{
for(x = START_X -BODYSIZE;x < START_X +155;x++)
put_point(x,y,VERGECOLOR);
}
for(y = START_Y ; y<START_Y +100; y++)
{
for(x = START_X ;x<START_X +150;x++)
put_point(x,y,BACKCOLOR);
}
put_body(sbody[front], ON);
put_body(sbody[rear], ON);
show_letter(220,50,FOODCOLOR,BACKCOLOR,'0');
show_letter(230,50,FOODCOLOR,BACKCOLOR,'0');
food();
Delay(5);
}
void show_point(void)
{
char a ,b;
a = count%10 + '0';
b = count/10%10 + '0';
show_letter(220,50,FOODCOLOR,BACKCOLOR,b);
show_letter(230,50,FOODCOLOR,BACKCOLOR,a);
if(count == 90)
{
show_str(60,60,FOODCOLOR,BACKCOLOR,"Congradulations!");
show_str(60,70,FOODCOLOR,BACKCOLOR,"You win!!");
}
}
void show_speed(int v)
{
v = v + '0';
show_str(210,60,BODYCOLOR,BACKCOLOR,"speed");
show_letter(255,60,FOODCOLOR,BACKCOLOR,v);
}
评论