#include "graphics.h"

#include "stdlib.h" 

#include "dos.h" 

#include "bios.h"

#include "stdio.h"

#include "time.h"

#include "graphics.h"

#include "conio.h"

#define LEFT 0x4b00 

#define RIGHT 0x4d00 

#define DOWN 0x5000 

#define UP 0x4800 

#define ESC 0x011b 

#define ENTER 0x1c0d

#define SPACE 0x3920 

/*游戏中人物的结构体*/ 
struct play
{ 
 int x;
  
 int y; 
}; 

struct Snow
{

int x;

int y;

int speed;

}snow[100];

int snownum=0;

struct play you,them[5]; 

void *save;

int sum=0;/*统计吃的豆子个数,吃满50颗就算胜利*/

int change=10;


/*0豆子,1空地2,墙壁,3自己,4敌人*/
int a[15][20]={2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
                  2,1,1,0,0,0,0,0,1,0,0,0,1,1,1,1,1,1,0,2,
                  2,1,2,2,2,1,1,2,1,1,0,0,0,1,1,4,1,1,0,2,
                  2,1,1,0,2,1,1,2,0,1,1,2,2,2,2,2,0,0,0,2,
                  2,4,1,0,2,1,1,2,1,1,1,0,1,1,1,1,0,1,1,2,
                  2,1,2,1,2,1,1,2,1,3,2,2,1,1,1,1,2,2,1,2,
                  2,1,2,1,2,1,1,1,1,1,1,1,1,0,0,0,1,1,1,2,
                  2,1,2,1,0,1,1,1,1,2,1,0,1,2,2,2,1,1,1,2,
                  2,1,0,1,0,1,2,1,1,2,1,0,1,2,1,1,4,1,1,2,
                  2,1,0,2,0,1,2,1,1,2,1,0,1,2,1,1,1,1,1,2,
                  2,1,0,2,1,1,2,1,1,2,1,0,2,2,1,0,0,0,1,2,
                  2,1,1,2,1,1,2,1,1,2,1,0,2,1,1,2,2,1,1,2,
                  2,1,2,2,1,2,2,1,1,1,1,0,1,4,1,2,0,0,1,2,
                  2,1,0,0,0,0,0,4,0,1,1,0,1,1,1,1,0,0,1,2,
                  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
        /*数组就是地图( level  1)*/ ;


int b[15][20]={2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
                  2,1,1,0,0,0,0,0,1,0,0,0,1,1,1,1,1,1,0,2,
                  2,1,2,2,2,2,1,2,1,1,0,0,0,1,1,4,1,1,0,2,
                  2,1,1,0,2,2,1,2,0,1,2,2,2,2,2,2,0,0,0,2,
                  2,4,1,0,2,1,1,2,1,1,1,0,1,1,2,1,0,1,1,2,
                  2,1,2,1,2,1,1,2,2,3,2,2,1,1,2,1,2,2,1,2,
                  2,1,2,1,2,2,1,1,1,1,1,1,1,0,0,0,1,1,1,2,
                  2,2,2,1,0,2,1,1,1,2,1,0,1,2,2,2,1,1,1,2,
                  2,2,0,1,0,2,2,1,1,2,1,0,1,2,2,1,4,1,1,2,
                  2,1,0,2,0,1,2,1,2,2,1,0,1,2,1,1,1,1,1,2,
                  2,1,0,2,1,1,2,1,1,2,1,0,2,2,1,0,0,0,1,2,
                  2,1,1,2,1,1,2,1,1,2,1,0,2,1,2,2,2,1,1,2,
                  2,1,2,2,1,2,2,2,1,1,1,0,1,4,1,2,0,0,1,2,
                  2,1,0,0,0,0,0,4,0,1,1,0,1,1,1,1,0,0,1,2,
                  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
        /*数组就是地图( level  2)*/


int c[15][20]={2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
                  2,1,1,0,0,0,0,0,1,0,0,0,1,1,2,1,1,1,0,2,
                  2,1,2,2,2,1,1,2,2,1,0,0,0,1,2,4,1,1,0,2,
                  2,1,1,0,2,2,1,2,0,1,2,2,2,2,2,2,0,0,0,2,
                  2,4,1,0,2,1,1,2,1,1,1,0,1,1,1,1,0,1,1,2,
                  2,1,2,1,2,1,2,2,1,3,2,2,1,1,1,1,2,2,1,2,
                  2,1,2,1,2,1,1,1,1,1,1,1,1,0,0,0,1,1,1,2,
                  2,1,2,1,0,2,1,1,1,2,2,0,1,2,2,2,1,1,1,2,
                  2,2,0,1,0,1,2,1,2,2,1,0,1,2,1,1,4,1,1,2,
                  2,2,0,2,0,1,2,1,1,2,1,0,1,2,2,1,1,1,1,2,
                  2,2,0,2,1,1,2,2,1,2,1,0,2,2,1,0,0,0,1,2,
                  2,1,1,2,1,1,2,1,1,2,2,0,2,1,1,2,2,2,1,2,
                  2,1,2,2,1,2,2,1,2,1,1,0,1,4,1,2,0,0,1,2,
                  2,1,0,0,0,0,0,4,0,1,1,0,1,1,1,1,0,0,1,2,
                  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
        /*数组就是地图( level  3)*/


 
int xx[5][2];/*判断敌人方向用的结构体*/
 
int false=0; /*判断输赢的参数*/



/*************************选择关卡********************************************************************/



void levelchoose(int x)
{
    int j,k;

    switch(x)
    {
    case 1:break;

    case 2:for(j=0;j<15;j++)

                for(k=0;k<20;k++)

                    a[j][k]=b[j][k];

            break;

    case 3:for(j=0;j<15;j++)

                for(k=0;k<20;k++)

                    a[j][k]=c[j][k];

            break;

    default:break;

  }

}




/*********************欢迎界面*************************************************************************/




void hello()
{



/*输出界面*/






printf("XXXXXXXXXXXX  XXXXXXXXXXXXX                XXXXXXXXXXXXXXX  XXXXXXXXXXXX\n");
printf("X       XXX          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXX\n");
printf("X  XXX  XX  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXX\n");
printf("X  XXX  X   XXXXXXXXXXXXXXXX              XXXXXXXXXXXXXXXX  XXXXXXXXXXXX\n");
printf("X  XXX  X  XXXXXXXXXXXXXXXXX  XXXXXXXXXX  XXXXXXXXXXXXXXXX  XXXXXXXXXXXX\n");
printf("X  XXX  XXX        XXXXXXXXX  XXXXXXXXXX  XXXXXXXXXXXXXXX    XXXXXXXXXXX\n");
printf("X  XXX  XXXXXXX   XXXXXXXXXX  XXXXXXXXXX  XXXXXXXXXXXXXXX    XXXXXXXXXXX\n");
printf("X  XXX  XXXXXX  XXXXXXXXXXXX              XXXXXXXXXXXXXX  XX  XXXXXXXXXX\n");
printf("X       XXXX   XXXXXXXXXXXXXXX XXXXXXX XXXXXXXXXXXXXXXX  XXXX  XXXXXXXXX\n");
printf("X  XXX  XXX  XXXXXXXXXXXXXXXXX  XXXXXX  XXXXXXXXXXXXXX  XXXXXX  XXXXXXXX\n");
printf("X  XXX  XXX  XXXXXX  XXXXXXXXXX  XXXX   XXXXXXXXXXXXX   XXXXXXX  XXXXXXX\n");
printf("XXXXXXXXXX  XXXXXXX  XXXXXXXXXX XXXXX  XXXXXXXXXXXXX   XXXXXXXX    XXXXX\n");
printf("XXXXXXXXXXX  XXXXX   XXXXXXXXXXXXXXX  XXXXXXXXXXXX    XXXXXXXXXX    XXXX\n");
printf("XXXXXXXXXXX         XXXXX                    XXXX    XXXXXXXXXXXX    XXX\n");
printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
printf("X         XXXXXX   XXXXXXXX       XXX   XXXX   XXXXX   XXXXXX   XXXXX  X\n");
printf("X  XXXXX  XXXXXX   XXXXXXX   XXX  XXX   XXXX   XXXXX   XXXXXX   XXXXX  X\n");
printf("X  XXXXXX  XXXXX   XXXXXXX  XXXXX  XX    XX    XXXXX   XXXXXX    XXXX  X\n");
printf("X  XXXXXX  XXXX  X  XXXXX  XXXXXX  XX    XX    XXXX  X  XXXXX    XXXX  X\n");
printf("X  XXXXXX  XXXX  X  XXXXX  XXXXXX  XX    XX    XXXX  X  XXXXX  X  XXX  X\n");
printf("X  XXXXXX  XXXX  X  XXXXX  XXXXXXXXXX  X XX X  XXXX  X  XXXXX  X  XXX  X\n");
printf("X  XXXXX  XXXX  XXX  XXXX  XXXXXXXXXX  X    X  XXX  XXX  XXXX  XX  XX  X\n");
printf("X         XXXX  XXX  XXXX  XXXXXXXXXX  X    X  XXX  XXX  XXXX  XX  XX  X\n");
printf("X  XXXXXXXXXXX       XXXX  XXXXXX  XX  X    X  XXX       XXXX  XXX  X  X\n");
printf("X  XXXXXXXXXX  XXXXX  XXX  XXXXXX  XX  X    X  XX  XXXXX  XXX  XXXX    X\n");
printf("X  XXXXXXXXXX  XXXXX  XXXX  XXXX   XX  XX  XX  XX  XXXXX  XXX  XXXX    X\n");
printf("X  XXXXXXXXXX  XXXXX  XXXX   XXX  XXX  XX  XX  XX  XXXXX  XXX  XXXXX   X\n");
printf("X  XXXXXXXXX  XXXXXXX  XXXX      XXXX  XX  XX  X  XXXXXXX  XX  XXXXX   X\n");








}


/*********************游戏说明*************************************************************************/


void instruction()
{

printf("            *****************************************\n");

printf("            *          GAME INSTRUCTIONS            *\n");

printf("            *****************************************\n");

printf("                    WELCOME TO PACMAN WORLD!\n\n");

printf("Press up,down,left,right to play.\n");

printf("Press Esc to quit it.\n");

printf("Press space to reset the game when you are playing.\n");

printf("How to win the game:\n");

printf("\tIf you have aten all of the yellow peans without being in the same location with the green enemy , you win ! \n");

printf("\tIf you are in the same location with the green enemy ,you lose !\n");

printf("Please choose game level number from 1 to 3 and press Enter key to start game :\n");

}





/**************************延时函数 传入微秒数***************************************************************************/



void TimeDelay(unsigned long microsec)  
{ 
 
union REGS r; 
 
r.h.ah=0x86; 
 
r.x.cx=microsec>>16; 
 
r.x.dx=microsec; 
 
int86(0x15,&r,&r); 

} 




/***************************吃豆子的函数*********************************************************************************/




drawblackdou(int x,int y) 
{ 
 
setcolor(0); 
 
circle(100+y*20,100+x*20,3); 

/*吃到豆子后就加一*/
sum++;

/*吃到后这里就成为普通平地*/
 a[x][y]=1;
}




/*******************播放音乐的函数*********************************************************************/


void Pr()
{

int s[15]={0,100,150,200,50,150,250,300,250,300,250,150,100,250,350};


/*改变欢迎词的颜色*/
setcolor(change/10);


/*改变欢迎词的字体*/
settextstyle(0,0,4);


/*输出欢迎词*/
outtextxy(20,200,"WELCOME TO OUR GAME!!");

outtextxy(20,250,"Press Space key  to");

outtextxy(20,300,"continue...");


/*使扬声器以s[change/10]的频率发声*/
sound(s[change/10]);

}




/******************播放动画音乐**************************************************************************************/




void DrawSnow()
{
int i;

int sx[62];

setlinestyle(SOLID_LINE,0,THICK_WIDTH);


/*一次3行画出白色雪花的3条线*/
line(1,1,9,9);

line(0,5,10,5);

line(9,1,1,9);


/*在堆中申请200字节空间*/
save=malloc(200);


/*将雪花位图保存到save中*/
getimage(0,0,10,10,save);


/*清屏*/
cleardevice();


/*设置随机数的种子数*/
randomize();


/*计算雪花位置的横坐标数组*/
for(i=0;i<62;i++)

    sx[i]=(i+2)*10;




/*******************以下的键控while循环控制播放音乐和下雪动画********************************************/





/*如果未按键,执行循环体*/
while(!kbhit())
{

Pr();

if(snownum!=100)
    {
     snow[snownum].speed=2+random(5);

     i=random(62);


    /*取横坐标*/
    snow[snownum].x=sx[i];


    /*计算纵坐标*/
    snow[snownum].y=10-random(100);

    }


/*循环放置snownum个雪花*/
for(i=0;i<snownum;i++)

    putimage(snow[i].x,snow[i].y,save,COPY_PUT);


/*延迟100ms以便看到雪花*/
delay(100);


/*清屏*/
cleardevice();


/*调用 Pr函数输出欢迎词并播放声音*/
Pr();


/*循环画出snownum个雪花*/
if(snownum!=100) snownum++;

    setfillstyle(SOLID_FILL,15);

for(i=0;i<snownum;i++)
    {
    snow[i].y+=snow[i].speed;
    
    putimage(snow[i].x,snow[i].y,save,COPY_PUT);
    
    if(snow[i].y>500) snow[i].y=10-random(200);
    
    }

change++;

if(change==140)
 
    change=10;
}

nosound();

cleardevice();


}




/*****************图形系统初始化函数************************************************************************/




void Init(void)
{

  int gd=DETECT,gm;

  initgraph(&gd,&gm,"c:\\tc");

cleardevice();


}
/***************************开始函数****************************************************************/


 begain() 
{
int i,j; 
 
sleep(1); 
 
for(i=0;i<15;i++)
 
  for(j=0;j<20;j++) 

   /*代表墙壁*/ 
   if(a[i][j]==2)
    { 
     setfillstyle(SOLID_FILL,BLUE);
 
     bar(100+j*20-10,100+i*20+10,100+j*20+10,100+i*20-10); 
    }


   /*代表自己*/
   else if(a[i][j]==3)
    { 
     setcolor(RED);
 
     circle(100+j*20,100+i*20,9); 
    }


    /*代表敌人*/  
   else if(a[i][j]==4)
    { 
     setcolor(GREEN); 

     circle(100+j*20,100+i*20,9); 
    }


    /*代表豆子*/ 
   else if(a[i][j]==0)
   { 
    setcolor(YELLOW);
 
    circle(100+j*20,100+i*20,3); 
   } 


/*敌人也自己的开始坐标*/ 
you.x=5;you.y=9;

them[0].x=2;them[0].y=15; 
 
them[1].x=4;them[1].y=1; 
 
them[2].x=8;them[2].y=16; 
 
them[3].x=12;them[3].y=13; 
 
them[4].x=13;them[4].y=7; 

}





/************************敌人移动的过程********************************************************************/




 
void movethem(struct play *them) 
{
 int i,loop;
 
 randomize();
 
 for(i=0;i<5;i++) 
 { 
 
if(you.x==them[i].x&&(them[i].y+1)==you.y) 

           them[i].y++; 
 
else if(you.x==them[i].x&&(them[i].y-1)==you.y) 

           them[i].y--; 
 
else if(you.y==them[i].y&&(them[i].x+1)==you.x) 

           them[i].x++; 
 
else if(you.y==them[i].y&&(them[i].x-1)==you.x)/*只要控制者在身边就立即靠上去*/ 

            them[i].x--;

else 
{ 
 loop: 


    /*这里的方向采取随机赋值,原则是新的方向不可以和原来的方向相反*/ 
       xx[i][0]=rand()%4+1;

       if(xx[i][0]==1&&xx[i][1]==2||xx[i][0]==2&&xx[i][1]==1) 

            goto loop;
 
       if(xx[i][0]==3&&xx[i][1]==4||xx[i][0]==4&&xx[i][1]==3) 

            goto loop; 

       xx[i][1]=xx[i][0];
 
      if(xx[i][0]==1)/*四个方向*/ 
       {
        them[i].x--;
 
        if(a[them[i].x][them[i].y]==2)/*如果碰墙壁的话就回到原来的地方等待随机的方向*/ 

            {them[i].x++;

            goto loop;
            } 
       } 

      else if(xx[i][0]==2) 
       {
        them[i].x++;
 
        if(a[them[i].x][them[i].y]==2) 

            {them[i].x--;

            goto loop;
            } 
        } 
     
        else if(xx[i][0]==3) 
       {
        them[i].y++; 

        if(a[them[i].x][them[i].y]==2) 

            {them[i].y--;

            goto loop;
            } 
       } 

        else if(xx[i][0]==4) 
       {

        them[i].y--; 

        if(a[them[i].x][them[i].y]==2) 

            {them[i].y++;

            goto loop;
            } 


      }


    }
 

 } 

} 





/**********************敌人移动中的判断************************************************************************/





fun(struct play *them)
{ 
 
int i; 


/*把敌人原来的位置删除*/
setcolor(0);
   
for(i=0;i<5;i++)

    circle(them[i].y*20+100,them[i].x*20+100,9);


/*根据控制者的位置来决定敌人的移动方向*/ 
movethem(them);

}







/*********************胜利的话***********************************************************************************/




 
win() 
{ 
 cleardevice(); 

 settextstyle(0,0,4);
 
 while(!kbhit()) 
 { 
  setcolor(rand()%13+1);
 
  outtextxy(200,200,"YOU WIN!"); 

  delay(1000); 
  }

}






/*********************失败的话***********************************************************************************/





false1() 
{ 
 cleardevice();
 
 settextstyle(0,0,4); 

 while(!kbhit()) 
 { 
  setcolor(rand()%13+1);
 
   outtextxy(180,200,"GAME OVER!"); 

  delay(1000); 

 }
 
}

 
loseyes()/*判断是否失败*/ 
{
int i; 

for(i=0;i<5;i++) 

   if(them[i].x==you.x&&them[i].y==you.y)
   

/*如果失败的话*/
false=1;
 

} 







/*********************主控函数*******************************************************************/





main() 
{
int gd=DETECT,gm;
 
int key,i,loop,jump;

int choice;

initgraph(&gd,&gm,"c:\\tc");


cleardevice();
 

DrawSnow();

 hello();

 getchar();

 instruction();

 scanf("%d",&choice);

 levelchoose(choice);

getchar();

loop:

Init();


/*开始画面*/
begain();

while(!kbhit()) 
   { 


      /*重画敌人*/
      for(i=0;i<5;i++) 

          setfillstyle(SOLID_FILL,GREEN);

         circle(them[i].y*20+100,them[i].x*20+100,9);

     TimeDelay(280000);

    for(i=0;i<5;i++) 

        if(them[i].x==you.x&&them[i].y==you.y)

           false=1;/*如果失败的话*/

        loseyes();/*判断是否失败*/ 

        if(false) 

            break; 

    key=bioskey(0);
  
    setcolor(0);/*把自己原来位置的人给删除掉*/

    circle(100+you.y*20,100+you.x*20,9); 

    fun(them);/*处理敌人*/ 


    /*ESC键退出游戏*/
    if(key==ESC)

        break;


    /*SPACE键重新开始本关游戏*/
    if (key==SPACE)

        goto loop;


    /*这里开始的判断主要是是否吃到豆子和碰到墙壁*/ 
    else if(key==UP)

        {
        you.x--; 

        if(a[you.x][you.y]==2)
            you.x++; 
        else if(a[you.x][you.y]==0)

            drawblackdou(you.x,you.y);

        } 

    else if(key==DOWN)

     {
     you.x++;
     if(a[you.x][you.y]==2)

            you.x--;

    else if(a[you.x][you.y]==0)

     drawblackdou(you.x,you.y);
     } 

    else if(key==RIGHT) 

    {
     you.y++;

     if(a[you.x][you.y]==2)

            you.y--; 

     else if(a[you.x][you.y]==0) 

        drawblackdou(you.x,you.y);

     }

   else if(key==LEFT) 

     {
     you.y--;
     if(a[you.x][you.y]==2)

            you.y++; 

     else if(a[you.x][you.y]==0) 

        drawblackdou(you.x,you.y);
    }

   if(sum==50) 

      break; 


   /*执行了一次键盘后再画出自己的位置*/ 
   setcolor(RED);

   circle(100+you.y*20,100+you.x*20,9);

   for(i=0;i<5;i++)

     {setcolor(GREEN);

    circle(them[i].y*20+100,them[i].x*20+100,9);
     }

    setcolor(RED);


   /*判断自己是否碰到敌人*/
   loseyes();

   if(false) 

       break; 
   } 


 /*吃满豆子了即获胜条件*/
 if(sum==50)

     {win();getch();} 

 if(false) 

     {false1();getch();} 

 closegraph();

}