贪吃蛇(纯C语言版)

/*
**Game:    贪吃蛇(纯C语言版)
**Author:  calm
**Time:    2007-12-28
此游戏在TC2.0下面顺利通过。。
*/

#include<stdio.h>
#include<graphics.h>
#include<alloc.h>
#include<bios.h>
#include<conio.h>
#include<dos.h>

#define LEFT 0x4B00
#define RIGHT 0x4D00
#define UP 0x4800
#define DOWN 0x5000
#define ESC 0x011B
#define ENTER 0x1C0D
#define SPACE 0x3920
/*蛇结点*/
typedef struct snake_node
{
 int x,y;
 struct snake_node *pre,*next;
}*snake;

snake head,trail; /*头、尾指针*/
/*初始化窗口视图坐标*/
int menu1_x1=340-100;
int menu1_y1=240-100;
int menu1_x2=340+100;
int menu1_y2=240+100;
int game_x1=170;
int game_y1=40;
int game_x2=470;
int game_y2=440;
int game_end,end,flag;  /*game_end返回标致 end游戏结束标致0失败,1成功,flag*/
int map[30][30];   /*定义地图为一个二维数组*/
int delay_time=20;   /*初始化时间延迟为20 m_sec*/
int length=3;    /*蛇长*/
int direction;    /*移动方向0-left,1-up,2-right,3-down*/
char *food;     /*记录食物*/

void BarBox(int x,int y,int color,int width,int height)
{/*画矩形方块函数*/
 setfillstyle(SOLID_FILL,color);
 bar(x,y,x+width-1,y+height-1);
}
void Box(int x,int y,int color)
{/*画地图小方块函数*/
 BarBox(x*10+1,y*10+33,color,9,9);
}
void RectangleBox(int x,int y,int color,int width,int height)
{/*画矩形线框*/
 setcolor(color);
 rectangle(x,y,x+width-1,y+height-1);
}
void OutTextxyBox(int x,int y,int color,char *text)
{/*输出指定颜色的字体*/
 setcolor(color);
 outtextxy(x,y,text);
}

void Game_Window()
{/*游戏窗口*/
 int i,j,k=0;
 char *title="Welcome To Game ^_^   Food:";
 char *instructions[]=
 {"   \30  up",
 "   \31 down",
 "   \32 right",
 "   \33 left",
 " Space pause",
 " Enter confirm",
 "  Esc exit"};
 cleardevice();
 setviewport(game_x1,game_y1,game_x2,game_y2,0);
 RectangleBox(-1,0,GREEN,303,30);
 RectangleBox(320,180,BLUE,130,120);
 settextstyle(0,0,1);
 while(k<7)
 {
  OutTextxyBox(322,200+k*10,WHITE,instructions[k]);
  k++;
 }
 BarBox(0,1,GREEN,301,28);
 OutTextxyBox(10,10,6,title);
 RectangleBox(-1,31,GREEN,302,272);
 RectangleBox(0,32,GREEN,301,271);
 for(i=32;i<300;i+=10)
 {
  for(j=0;j<300;j+=10)
  {
   BarBox(j+1,i+1,DARKGRAY,9,9);
  }
 }
}
void InitMap()
{/*初始化地图*/
 int i,j;
 for(i=0;i<30;i++)
  for(j=0;j<30;j++)map[i][j]=0;
}
void InitSnake()
{/*初始化蛇,长度为3*/
 int x=10,y=8,i=0;
 snake sn;
 head=sn=(snake)malloc(sizeof(struct snake_node));  /*蛇头*/
 sn->x=x;
 sn->y=y;
 map[y][x]=1;
 i++;
 x++;
 sn->pre=NULL;
 do
 {
  sn->next=(snake)malloc(sizeof(struct snake_node));
  sn->next->pre=sn;
  sn=sn->next;
  sn->x=x;
  sn->y=y;
  map[y][x]=1;
  i++;
  x++;
 }while(i<length);
 sn->next=NULL;
 trail=sn;
}
void PrintSnake() 
{/*打印贪吃蛇*/
 snake sn=head;
 int snake_color;
 if(length>0&&length<=8)snake_color=1;
 else if(length>8&&length<=15)
  {/*蛇变色*/
   snake_color=3;
   delay_time=15;
  }
  else if(length>15&&length<=20)
  {
   snake_color=5;
   delay_time=10;
  }
  else if(length>20&&length<=30)
  {
   snake_color=7;
   delay_time=5;
  }
 else
 {
  snake_color=RED;
  delay_time=1;
 }
 Box(sn->x,sn->y,BLUE);
 sn=head->next;
 while(sn!=NULL)
 {
  Box(sn->x,sn->y,snake_color);
  sn=sn->next;
 }
}
void SetFood() 
{/*随机放置食物*/
 int x,y;
 do
 {
  x=rand()%30;
  y=rand()%27;
 }while(map[y][x]==1);
 map[y][x]=2;
 Box(x,y,YELLOW);
}
void Game_Over(int end)
{/*游戏结束*/
 char *g_win="You Win !";
 char *g_fail="Game Over ";
 setviewport(0,0,639,479,0);
 settextstyle(0,0,3);
 if(end==1)
 {
  OutTextxyBox(220,200,end+3,g_win);
 }
 else
 {
  OutTextxyBox(220,200,end+4,g_fail);
 }
 length=3;
 delay_time=20;
 game_end=1;
 getch();
 clearviewport();
}
void FreeSnake()
{/*释放蛇所在堆空间*/
 snake sn,sn1;
 sn=head;
 head=NULL;
 while(sn!=NULL)
 {
  sn1=sn->next;
  free(sn);
  sn=sn1;
 }
}
ShowFood()  
{/*显示蛇长度*/
 BarBox(250,10,GREEN,20,15);
 sprintf(food,"%d",length);
 settextstyle(0,0,1);
 OutTextxyBox(250,10,6,food);
}
void SnakeMove()
{/*蛇移动*/
 snake sn=head;
 head=(snake)malloc(sizeof(struct snake_node));
 head->x=sn->x;
 head->y=sn->y;
 switch(direction)
 {
 case 0:
  head->x--;
  break;
 case 1:
  head->y--;
  break;
 case 2:
  head->x++;
  break;
 case 3:
  head->y++;
  break;
 }
 if(head->x<0||head->x>29||head->y<0||head->y>26||map[head->y][head->x]==1)
 {/*撞墙或撞到蛇身*/
  FreeSnake();
  end=0;
  Game_Over(end);
 }
 else
 {
  head->next=sn;
  sn->pre=head;
  head->pre=NULL;
  if(map[head->y][head->x]==2)
  {/*遇到食物*/
   length++;
   ShowFood();
   if(length==33)  /*通过吃子个数*/
   {
    FreeSnake();
    end=1;
    Game_Over(end);
   }
   else
   map[head->y][head->x]=1;
   SetFood();
  }
  else
  {/*既不撞墙也不撞蛇身则去掉蛇尾*/
   map[trail->y][trail->x]=0;
   sn=trail;
   trail=trail->pre;
   trail->next=NULL;
   Box(sn->x,sn->y,DARKGRAY);
   free(sn);
   map[head->y][head->x]=1;
  }
 }
}
void cleartime()
{/*时间设置为0*/
    struct time time_0;
    time_0.ti_min=0;
    time_0.ti_hour=0;
    time_0.ti_hund=0;
    time_0.ti_sec=0;
    settime(&time_0);
}
void Game_Going() /*游戏开始*/
{
 int key=0,pause=0;
 struct time t_last;
 SetFood();
 do
 {
  direction=rand()%4;
 }while(direction==2);
 while(1)
 {
  cleartime();
  ShowFood();
  PrintSnake();
  while(1)
  {
   gettime(&t_last);
            if(t_last.ti_hund>delay_time)break;  /*超过时间延迟没有检测到按键则蛇自己向前运动*/
   if(bioskey(1))
   {/*检测键盘按键*/
    key=bioskey(0);
    switch(key)
    {
    case UP:
     if(direction!=3)direction=1;
     break;
    case DOWN:
     if(direction!=1)direction=3;
     break;
    case LEFT:
     if(direction!=2)direction=0;
     break;
    case RIGHT:
     if(direction!=0)direction=2;
     break;
    case ESC:
     FreeSnake();
     exit(0);
    case SPACE:
     do
     {/*空格键暂停*/
      pause=bioskey(0);
     }while(pause!=SPACE);
     break;
    }
    break;
   }
  }
  SnakeMove();
  if(game_end==1)return; /*game_end为1则返回到选择窗口*/
 }
}
void Begin()
{/*进入游戏窗口*/
 Game_Window();
 InitMap();
 InitSnake();
 Game_Going();
 if(game_end==1)return;
}
void Menu_Display()
{/*选项菜单展示*/
 int i=0;
 char *select[]={"Start Game","Contact","Exit"};
 while(i<3)
 {
  BarBox(50,101+i*21,3,100,20);
  OutTextxyBox(58,106+i*21,WHITE,select[i]);
  i++;
 }
}
void Option_Display(int i,int color)
{/*选择项变色*/
 char *select[]={"Start Game","Contact","Exit"};
 BarBox(50,101+i*21,color,100,20);
 settextstyle(0,0,1);
 OutTextxyBox(58,106+i*21,WHITE,select[i]);
}
void Wink()
{/*文字闪烁*/
 int color;
 char *edition="Edition: The 1st Edition";
 char *author="Author: ZYC-ncuxg061";
 if(0==flag)
 {
  color=YELLOW;
  flag=1;
 }
 else
 {
  color=RED;
  flag=0;
 }
 settextstyle(0,0,2);
 OutTextxyBox(-100,-20,color,edition);
 OutTextxyBox(-83,10,color,author);
}
int Select()
{/*选择菜单*/
 int key,i=0;
 while(1)
 {
  Wink();
  Option_Display(i,7);
  key=bioskey(0);
  if(key==UP&&i!=0)
  {
   Option_Display(i,3);
   i--;
   Option_Display(i,7);
  }
  if(key==DOWN&&i<2)
  {
   Option_Display(i,3);
   i++;
   Option_Display(i,7);
  }
  if(key==ENTER)
  {
   return i;
  }
  if(key==ESC)
  {
   exit(0);
  }
 }
}
void Select_Window();
void Contact()
{/*作者联系方式*/
 int i=0,j=2;
 char *contactInfo[]={"Author: ZYC--ncuxg061"," http://www.ncuxg.cn","E-mail:zycpf@tom.com","QQ:251980417"};
 cleardevice();
 setviewport(menu1_x1,menu1_y1,menu1_x2,menu1_y2,0);
 RectangleBox(0,0,GREEN,199,110);
 settextstyle(0,0,1);
 do{
  i=0;
 while(i<4)
 {
  OutTextxyBox(10,20+i*20,j,contactInfo[i]);
  i++;
 }
 OutTextxyBox(80,200,YELLOW,"Any key to return...");
 j=(j++)%7;
 }while(!bioskey(1));
 game_end=1;
}
void Select_Window()
{/*进入选择窗口*/
 int key=0;
 game_end=0;
 setviewport(menu1_x1,menu1_y1,menu1_x2,menu1_y2,0);  /*设置视图窗口*/
 setbkcolor(BLACK); 
 RectangleBox(48,78,BLUE,104,87); 
 BarBox(50,80,GREEN,100,20);
 settextstyle(0,0,1);
 OutTextxyBox(58,85,WHITE,"WELCOME");
 Menu_Display();
 key=Select();
 switch(key)
 {
  case 0:
  {
   Begin();
   break;
  }
  case 1:
  {
   Contact();
   break;
  }
  case 2:
  {
   exit(0);
  }
 }
 if(game_end==1)return;
}
void Enter_Window()
{/*游戏第一个窗口*/
 setbkcolor(YELLOW);
 setviewport(120,100,520,380,1);
 RectangleBox(0,0,RED,399,279);
 setfillstyle(SOLID_FILL,7);
 floodfill(50,50,4);
 settextstyle(0,0,9);
 OutTextxyBox(20,80,8,"Snake");
 settextstyle(0,0,1);
 OutTextxyBox(130,180,8,"version 1.0");
 OutTextxyBox(130,190,8,"made by ZYC");
 OutTextxyBox(180,220,YELLOW,"Press any key to begin...");
 getch();
 while(1)
 {
  cleardevice();
  Select_Window();
 }
}
void InitGraph()
{/*检测图形*/
 int gdriver,gmode;
 gdriver=DETECT;
 registerbgidriver(EGAVGA_driver);
 initgraph(&gdriver,&gmode,"");
}
void main()
{/*主函数开始*/
 InitGraph();
 Enter_Window();
}

posted @ 2008-04-14 00:06  calm  阅读(839)  评论(0编辑  收藏  举报