C课程设计报告—贪吃蛇

程序设计基础课程设计

C课程设计报告—贪吃蛇  

院    系:  计算机学院网络工程系

班    级:      12 – 2 班       

姓    名:            

指导教师:             

20## 年 12 月 25 日

程序设计基础课程设计任务书

一、题目:贪吃蛇

二、设计要求

(1)XXX负责设计与实现。

(2)查阅相关资料,自学具体课题中涉及到的新知识。

(3)采用结构化、模块化程序设计方法,功能要完善,具有一定的创新。

(4)所设计的程序应有输入、输出。

(5)按要求写出课程设计报告,并于设计结束后1周内提交。其主要内容包括:封皮、课程设计任务书,指导教师评语与成绩、目录、概述、软件总体设计、详细设计、软件的调试、总结、谢启、附录:带中文注释的程序清单、参考文献。报告一律用A4纸打印,中文字体为宋体,西文字体用Time New Roma,一律用小四号字,行距采用“固定值”18磅,首行缩进2字符。总体设计应配合软件总体模块结构图来说明软件应具有的功能。详细设计应用传统或N-S流程图和屏幕抓图说明,调试的叙述应配合出错场景的抓图来说明出现了哪些错误,如何解决的。

三、课程设计工作量

由于是设计小组团结协作完成设计任务,一般每人的程序量在200行有效程序行左右,不得抄袭。

四、课程设计工作计划

20##年12月17日,指导教师讲课,学生根据题目准备资料;

20##年12月18日,设计小组进行总体方案设计和任务分工;

20##年12月19日~20##年12月21日,每人完成自己承担的程序模块并通过独立编译;

20##年12月22日~20##年12月26日,将各模块集成为一个完整的系统,并录入足够的数据进行调试运行;

20##年12月27日,软件发布

20##年12月28日,验收、撰写报告;

20##年1月5日,交课程设计报告

                            指导教师签章:              

                            教研室主任签章              

程序设计基础课程设计指导教师评语与成绩

 

一 概述(宋体,三号,加粗,居中)................................................. 5

二 总体方案设计................................................................................................ 6

三 详细设计........................................................................................................... 8

四 程序的调试与运行结果说明............................................................... 15

五 课程设计总结............................................................................................... 18

六 后记.................................................................................................................... 18

参考文献................................................................................................................. 19

七 附录.................................................................................................................... 20

一 概述

1.     课程设计的目的

⑴学生更深入地理解和掌握该课程中的基本概念,程序设计的思

想、技术和方法。

  ⑵培养学生综合运用所学知识独立完成课题以及撰写课程设计报

告的能力。

  ⑶培养学生勇于探索、严谨推理、实事求是、有过必改,用实践

来检验理论,全方位考虑问题等科学技术人员应具有的素质。

  ⑷提高学生对工作认真负责、一丝不苟,对同学团结友爱、协作

攻关的基本素质。

  ⑸培养学生从资料文献、科学实验中获得新知识的能力,提高学

生从别人的经验中找到解决问题的新途径的悟性,初步培养工

程意识和创新能力。

  ⑹对学生掌握知识的深度,运用理论去处理问题的能力、实践动

手的能力,课程设计的能力、书面及口头表达能力进行综合考

核。

2.     课程设计的要求

 ⑴学生自由组成课程设计软件开发小组(及开发团队),可由指导

教师确定每组的人数,建议每组三人左右,并选举一人为组长。

指导教师可根据各个小组的实际情况进行必要的调整。

  ⑵该软件系统运行时应先播放同步的动画音乐,播放完后,通过

选择进入游戏。

  ⑶进一步掌握C语言集成开发环境。

  ⑷熟练掌握C语言的数据类型、几种基本结构、数组、指针、结

构体、模块化  设计等知识点。

  ⑸从书中或互联网上查阅相关资料,自学具体课题中涉及到新的

知识。

  ⑹采用结构化、模块化程序设计方法进行设计,功能要完善,界

面要美观,应具有一定的创新。

  ⑺要求开发小组的每个成员都应独立设计若干个模块,每个人设

计的有效资源程序代码应在200行以上。同时要读懂其他组员

完成的任务。

3.     课程设计的主要设计思想

这个程序的关键点是表示蛇的图形以及蛇的移动。用一个小矩形块表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示。移动时必须从蛇头开始,所以蛇不能向相反方向移动,也就是蛇尾不能改作蛇头。如果不按任何键,蛇自行在当前方向上前移,当游戏者按了有效的方向键后,蛇头朝着指定的方向移动,一步移动一节身体,所以当按了有效的方向键后,先确定蛇头的位置,然后蛇身体随着蛇头移动,图形的实现是从蛇头的新位置开始画出蛇,这时,由于没有清屏的原因,原来蛇的位置和新蛇的位置差一个单位,所以看起来蛇会多一节身体,所以将蛇的最后一节用背景色覆盖。食物的出现和消失也是画矩形块和覆盖矩形块。为了便于理解,定义了两个结构体:食物和蛇。

总体方案设计

整体框图

   模块划分

C课程设计报告—贪吃蛇

主控模块

  主控模块由main函数实现,主要用来依次调用各个下层模块,从而控制完成整个程序的功能。

动画音乐函数

  该模块用来同步播放下雪的动画和简单的音乐,并在屏幕的中间输出颜色不断变换的欢迎词语。

画主界面函数

  画主界面模块由函数Drawk实现,他画出了一个封闭的围墙。在单人模式下,用两个循环语句在水平方向和垂直方向上输出连续的宽度和高度均为10单位(像素)的浅青色矩形方块,围成密闭图形表示围墙。在双人模式下,在单人模式下画的围墙的基础上再加一条垂直方向上的围墙就可以。函数setlinstyle设置线型宽度为1像素。这样避免了蛇贴墙走的时候,会檫掉一部分影响界面美观这种情况。

游戏过程模块

  该模块是整个程序的核心模块,他完成整个游戏过程,在我们组做的这个贪吃蛇游戏中,有两个这个模块,分别由Gameplay1和Gameplay2来实现,每次蛇移动的时候,从最后一节开始到第二节,

将前一节的坐标赋给后一节的坐标,移动后把最后一节用背景色覆盖,然后蛇头位置按方向键更改位置,要确保食物出现在10的倍数位置上,判断蛇是否吃到食物的是蛇头坐标和食物坐标是否相同。我们设计的这个贪吃蛇游戏中还有另一个特色,那就是在游戏运行的时候会出现随机障碍,这些障碍是蛇在吃了三个食物之后,会出现一个位置不定的红色的随机障碍,而且它存在一会就会消失,蛇在吃够三个食物后又会出现,就这样一直循环知道蛇死了为止。

游戏结束处理模块

  当游戏结束时,则调用Endplay函数进行游戏结束处理,在该模块中将依次调用读取记录、成绩排序、写入文件、排行榜等模块,实现有关处理。由于我们的贪吃蛇有双人模式还有单人模式,所以我们有两套读取记录、成绩排序、写入文件、排行榜等模块。

读取记录模块

  该模块由ReadFiles1和ReadFiles2函数来实现。即用用来读取排行榜1和排行榜2的信息记录。如果是首次读取文件,将调用InitScoreFiles函数,将初始记录文件,两个排行榜都设置五名选手,

初始姓名都为“nobody”,初始分数都是0.

成绩排序模块

  该模块由CompareScore1和CompareScore2函数来实现。当游戏者1和游戏者2的成绩比排行榜1和排行榜2中第五名的成绩高时,即调用该模块将成绩加入排行榜中排序,将原来的第五名删除。

写入文件模块

  该模块由WriterFiles1和WriterFiles2来实现,将两个新的排行榜信息写入文件。

排行榜模块

  该模块由pain_board1和pain_board2来实现。主要功能是建立两个排行榜界面,输出五个最高分玩家姓名和成绩。

退出

 显示排行榜后,返回主界面选择exit按一下空格键就可以退出游戏了。

三 详细设计

流程图:

/*下雪的动画并同时播放音乐函数*/

void DrawSnow()

{

  int i;

  int sx[62];

  setlinestyle(SOLID_LINE,0,THICK_WIDTH);

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

  line(0,5,10,5);

  line(9,1,1,9);

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

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

  cleardevice();   /*清屏*/

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

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

  sx[i]=(i+2)*10;   /*计算雪花位置的横坐标数组*/

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

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

  {

    Pr();          /*调用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

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

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

    cleardevice();       /*清屏*/

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

    if(snownum!=100)snownum++;

    setfillstyle(SOLID_FILL,15);

    for(i=0;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 Pr()     {

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

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

  settextstyle(0,0,4);

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

   drawmat(tan64S,64,200,100,YELLOW);

   drawmat(chi64S,64,300,100,RED);

   drawmat(she64S,64,400,100,GREEN);

   drawmat(zu24S,24,30,330,YELLOW);

   drawmat(zhang24S,24,60,330,GREEN);

   drawmat(lin48K,48,180,315,CYAN);

   drawmat(yang48K,48,240,315,BROWN);

   drawmat(bo48K,48,300,315,RED);

   drawmat(zu24S,24,30,410,YELLOW);

   drawmat(yuan24S,24,60,410,GREEN);

   drawmat(guo48K,48,100,400,CYAN);

   drawmat(zhi48K,48,160,400,BROWN);

   drawmat(jia48K,48,220,400,RED);

   drawmat(wang48K,48,300,400,CYAN);

   drawmat(chun48K,48,360,400,BROWN);

   drawmat(xu48K,48,420,400,RED);

   drawmat(mou48K,48,500,400,CYAN);

   drawmat(ting48K,48,550,400,BROWN);

   drawmat(ting48K,48,600,400,YELLOW);

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

}

/*图形驱动,图形系统初始化函数*/

void Init(void)

{

   int gd=DETECT,gm;

   registerbgidriver(EGAVGA_driver);

   initgraph(&gd,&gm,"c:\\program files\\winyes\\tc20h\\bgi");

   cleardevice();

}

 /*下雪动画并同步播放音乐函数 */

void Background(int i)          {

    setlinestyle(SOLID_LINE,0,THICK_WIDTH);

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

    line(0,5,10,5);

    line(9,1,1,9);

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

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

    cleardevice();                     /*清屏*/

    settextstyle(0,0,0);

    outtextxy(300,150,"Newgame");

    outtextxy(300,200,"pain broad");

    outtextxy(300,250,"exit");

    if(i==1)

    putimage(250,150,save,COPY_PUT);

    else if(i==2)

    putimage(250,200,save,COPY_PUT);

    else

putimage(250,250,save,COPY_PUT);}

 /*玩游戏具体过程*/

void GamePlay()

{

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

   food0.yes=1;

   zhang.yes=1;                      /*1表示需要出现新食物,0表示已经存在食物  */

   snake0.life=0;                     /*蛇活着 */

   snake0.direction=1;                /*方向往右 */

   snake0.x[0]=100;snake0.y[0]=100;    /*蛇头坐标初值 */

   snake0.x[1]=110;snake0.y[1]=100;    /*蛇尾坐标初值 */

   snake0.node=2;                     /*蛇节数初值*/

   PrScore();                        /*玩游戏“死”循环,按ESC键或蛇死时结束 */

   while(1)

   {

      while(!kbhit())                /*在没有按键的情况下,蛇自己移动身体 */

      {

       if(zhang.yes==1)                  /*需要出现新食物 */

     {

         zhang.x=rand()%400+60;

         zhang.y=rand()%350+60;         /*食物出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

         while(zhang.x%10!=0)

        zhang.x++;

         while(zhang.y%10!=0)

        zhang.y++;

        zhang.yes=0;                     /*画面上有食物了 */

     }

     if(zhang.yes==0)                     /*画面上有食物就要显示*/

     {

              setcolor(RED);

              rectangle(zhang.x,zhang.y,zhang.x+30,zhang.y-10);

     }

     if(food0.yes==1)                  /*需要出现新食物 */

     {

         food0.x=rand()%400+60;

         food0.y=rand()%350+60;         /*食物出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

         while(food0.x%10!=0)

        food0.x++;

         while(food0.y%10!=0)

        food0.y++;

        food0.yes=0;                     /*画面上有食物了 */

     }

     if(food0.yes==0)                     /*画面上有食物就要显示*/

     {

              setcolor(GREEN);

              rectangle(food0.x,food0.y,food0.x+10,food0.y-10);

     }

         for(i=snake0.node-1;i>0;i--)

         {

            snake0.x[i]=snake0.x[i-1];

        snake0.y[i]=snake0.y[i-1];

     }

     /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/

     switch(snake0.direction)

     {

        case 1:snake0.x[0]+=10;break;

        case 2: snake0.x[0]-=10;break;

        case 3: snake0.y[0]-=10;break;

        case 4: snake0.y[0]+=10;break;

       /*从蛇的第四节开始判断是否撞到自己了,因为第3节可能拐不过来*/     }

     for(i=3;i

     {

        if(snake0.x[i]==snake0.x[0]&&snake0.y[i]==snake0.y[0])

        {

               GameOver0();

               snake0.life=1;    /*置蛇死标志 */

               break;

        }

        }/*判断蛇是否撞到墙壁*/

    if(snake0.x[0]<55||snake0.x[0]>595||snake0.y[0]<55||snake0.y[0]>455)

    {

        GameOver0();

        snake0.life=1;     /*置蛇死标志 */

    }

    if(snake0.x[0]>190&&snake0.x[0]<310&&snake0.y[0]>100&&snake0.y[0]<130)

    {

        GameOver0();

        snake0.life=1;

    }

     if(snake0.x[0]==zhang.x&&snake0.y[0]==zhang.y)

    {

        GameOver0();

        snake0.life=1;

    }

      if(snake0.x[0]==zhang.x+10&&snake0.y[0]==zhang.y)

    {

        GameOver0();

        snake0.life=1;

    }

      if(snake0.x[0]==zhang.x+20&&snake0.y[0]==zhang.y)

    {

        GameOver0();

        snake0.life=1;

    }

    if(snake0.life==1)     /*以上判断后,如果蛇死就跳出内循环*/

           break;

    if(snake0.x[0]==food0.x&&snake0.y[0]==food0.y)

    {

           setcolor(0);

           rectangle(food0.x,food0.y,food0.x+10,food0.y-10);

       snake0.x[snake0.node]=-20;snake0.y[snake0.node]=-20;

       snake0.node++;         /*蛇的身体长一节 */

       food0.yes=1;           /*画面需要出现新的食物 */

       zhang.yes=1;

       setcolor(0);

           rectangle(zhang.x,zhang.y,zhang.x+30,zhang.y-10);

       score+=10;             /*没吃一个食物增加10分 */

       PrScore();

    }

    setcolor(5);

    rectangle(snake0.x[0],snake0.y[0],snake0.x[0]+10,

               snake0.y[0]-10);

    setcolor(4);                /*画出红色蛇的循环体*/

    for(i=1;i

       rectangle(snake0.x[i],snake0.y[i],snake0.x[i]+10,

               snake0.y[i]-10);

    delay(gamespeed);        /*用延迟gamespeed毫秒,以控制蛇的爬行速度 */

    setcolor(0);              /*用背景色黑色去除蛇的最后一节 */

    rectangle(snake0.x[snake0.node-1],snake0.y[snake0.node-1],

    snake0.x[snake0.node-1]+10,snake0.y[snake0.node-1]-10);

     }                        /*endwhile(!kbhit) */

    if(snake0.life==1)

        break;;               /*如果蛇死就跳出循环 */

    key=bioskey(0);            /*接收按键 */

    if(key==ESC)                /*如果按ESC键就退出 */

       break;

    else

       if(key==UP1&&snake0.direction!=4)

      snake0.direction=3;         /*判断是否往相反的方向移动 */

       else

      if(key==RIGHT1&&snake0.direction!=2)

         snake0.direction=1;

      else

         if(key==LEFT1&&snake0.direction!=1)

        snake0.direction=2;

         else

        if(key==DOWN1&&snake0.direction!=3)

           snake0.direction=4;

   }         /* endwhile(1)*/

}            /* 游戏结束 */

            程序的调试与运行结果说明

(1)游戏开始时的画面

(2)开始游戏时的画面

  3)一下情况蛇死亡(蛇撞到墙或障碍)

单人模式

双人模式

课程设计总结

我们按照程序运行的错误提示对原程序进行修改,在调试过程中有时也会遇到不懂的问题,我去图书馆或上网查阅一些资料或者是向老师请教也解决了对源程序一一修改直到运行成功,修改成功后,我们开始进行程序改进,在开始画面上加上我们组员的名字,把一条蛇改成了两条蛇,同时运行游戏,后来又在这个基础上给游戏加上了固定障碍和随机障碍,是我们的游戏更加有挑战性,更加完美。

在设计这个程序中我主要学会了如何运用以下有关C语言的知识

(1) 函数定义是要做到顾名思义是很重要的,它对读程序的人正确认识程序
十分重要,在修改这个程序的过程中也能很快找到程序各模块的作用,大大增
加了程序的可读性。

(2)分析函数先从main()函数入手。Main()函数是C源程序编译时的开始,
从main()函数开始读函数可将其他函数的功能理解得更透彻。
(3) 在做程序的时候先列框架,将这个程序所要达到的目的(功能)分析出
来,选择正确的数据结构然后在将程序模块化,按照模块编写函数更加简单合理。
(4) 我还了解了很多的库函数的作用,如字符串函数中有很多对字符串进行
处理的函数,起功能我都有所了解。
同时我也获得了许多宝贵的经验:
1) 在设计程序之前,务必要对你所设计的题目和内容有一个系统的了解,
知道所设计的题目和内容包含那些资源。
2) 设计程序采用什么编程语言并不是非常重要,关键要有一个清晰的思路
和一个完整的软件流程图,因而,要先把设计原理与思路搞清楚,再把流程图画出来,这样设计起来就简单多了。
3) 在设计程序时,不能妄想一次就将整个程序设计好,“反复修改,不断改
进”是程序设计的必经之路,发现错误也是取得成绩的一种。
4) 要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而
应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便。

后记

设计心得体会:  

    经过短短两星期的课程设计,让我对C程序有了一个更深的了解,以前总认为C语言很枯燥,认为那些我们所设计的程序没有什么用处,但现在通过设计贪吃蛇游戏这个程序使我懂得了如何将所学的知识运用于生活当中。虽然在刚开始设计程序时不太明白如何去设计这程序,但当我看完《C语言课程设计》并用C语言做出这个贪吃蛇程序后,让我深深感受到C程序的神奇。

通过贪吃蛇游戏的编程练习思考数据结构的使用,比如定义食物的坐标来控制它出现的位置,用函数rectangle来画出矩形,用life变量的值表示蛇的生命,用direction变量的值表示蛇移动的方向等,还有用数组来存放蛇身各节的坐标,这些都让我们熟悉了对数组的操作,此外还熟悉了各种函数的应用。

对于初学者来说,学习编写贪吃蛇的游戏对掌握C语言的知识有很大的帮助。通过编程实践,还能拓展思路,让我们去寻找需要调用那些函数,怎样提高程序的质量等。

要写出好的程序,需要我们有扎实的基础,这样遇到一些基本算法的时候就会游刃有余了。在编译时我们要有丰富的想象力,不要拘泥于固定的思维方式,遇到问题时要多想几种解决问题的方案。丰富的想象力是建立在丰富的知识的基础上,所以我们要通过多个途径来帮助自己建立较丰富的知识结构。

在编译时我们遇到了很多困难,这就需要我们多与别人交流。在编译的过程中,我们也发现有良好的编译风格是十分重要的,至少在时间效率上就体现了这一点。养成良好的习惯,代码的缩进编排,变量的命名规则要始终保持一致,这些都是提高我们编程能力的要点。

还有在编程中最能体现简单的原则,简单的方法更容易被人理解,更容易实现,也更容易维护。遇到问题时要优先考虑简单的方案,只有简单方案不能满足要求时再考虑复杂的方案。

在进行课程设计的过程中我们也学到了许多别的东西。首先,我们学会了合作,要以别人的眼光看看问题,也许这样得到的会比各自得到的都要多;其次,我们学会了分工,分工是为了更好的合作,分工才能提高合作的效率;最后,我们学会了奋斗,我们相信,通过四年的学习,我们一定能写出更精彩的程序,将来会描绘出更精彩的人生。

                  参考文献

[1] 谭浩强,C程序设计题解与上机指导(第二版),北京,清华大学出版社,20##年9月。

[2] 徐金梧,杨德斌等,《TURBO C实用大全》,机械工程出版社,1996.5。
[3] 李丽娟,《C语言程序设计教程》,人民邮电出版社。
[4] 林华聪,《C语言程序设计思想与实践》,冶金工业出版社。
[5] 张继温,《C语言程序设计教程》,高等教育出版社。
[6] 孙家广等,计算机图形学(第三版),清华大学出版社,2004。
[7] 陈元琰编著,计算机图形学实用技术,北京,科学出版社,2000。
[8] 和青芳著,计算机图形学原理及算法教程,北京,清华大学出版社。
[9]  陆润民,C语言绘图教程,北京,清华大学出版社,1996。

[10] 郭翠英,《C语言课程设计案例精编》,中国水利水电出版社,2004.3。

七 附录

源程序

#include

#include

#include

#include

#include

#include

#include

#include

#define N 200

#define LEFT 0x1e61

#define RIGHT 0x2064

#define DOWN 0x1f73

#define UP 0x1177

#define LEFT1 0x4b00

#define RIGHT1 0x4d00

#define DOWN1 0x5000

#define UP1 0x4800

#define ESC 0x011b

#define space 0x3920

#define closegr closegraph

#define FILENAME1 "c:\\person.dat"

#define FILENAME2 "c:\\person2.dat" /*定义一个文件名称,用来储存第二个排行榜的分数情况!*/

#define FILENAME "c:\\person.dat"

 void InitScoreFiles();

 void drawmat(char *mat,int matsize,int x,int y,int color)

/*依次:字模指针、点阵大小、起始坐标(x,y)、颜色*/

{

  int i, j, k, n;

  n = (matsize - 1) / 8 + 1;

  for(j = 0; j < matsize; j++)

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

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

        if(mat[j * n + i] & (0x80 >> k))  /*测试为1的位则显示*/

          putpixel(x + i * 8 + k, y + j, color);

}

 /*单人游戏*/

struct person    /*得分结构体*/

{

    char name[20];

    int score;

}per[5];

int score=0; /*记录游戏分数*/

int size;

int score;

int i,key;

int gamespeed=100000;/*游戏速度*/

struct Snow  /*雪花结构体*/

{

   int x;

   int y;

   int speed;

}snow[100];

int snownum=0;

int size;

int change=10;

void *save;

struct Zhang

{

    int x;    /*障碍的横坐标*/

    int y;    /*障碍的纵坐标*/

    int yes;/*判断是否要出现障碍的变量*/

}zhang;

struct Food0

{

    int x;    /*食物的横坐标*/

    int y;    /*食物的纵坐标*/

    int yes;/*判断是否要出现食物的变量*/

}food0;

struct Snake0

{

    int x[N];

    int y[N];

    int node;  /*蛇的节数*/

    int direction; /*蛇移动方向*/

    int life;   /* 蛇的生命,0活着,1死亡*/

}snake0;

void Init(void);  /*图形驱动*/

void Close(void);  /*图形结束*/

void DrawK0(void);    /*开始画面*/

void GameOver0(void); /*结束游戏*/

void GamePlay(void);  /*玩游戏具体过程*/

void PrScore(void);    /*输出成绩*/

/*输出欢迎词并播放音乐*/

void Pr();

void pain_borad();/*绘制排行榜函数*/

/*下雪的动画并同时播放音乐函数*/

void DrawSnow()

{

  int i;

  int sx[62];

  setlinestyle(SOLID_LINE,0,THICK_WIDTH);

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

  line(0,5,10,5);

  line(9,1,1,9);

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

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

  cleardevice();   /*清屏*/

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

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

  sx[i]=(i+2)*10;   /*计算雪花位置的横坐标数组*/

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

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

  {

     drawmat(yi64S,64,100,100,BROWN);

   drawmat(ren64S,64,200,100,CYAN);

    Pr();          /*调用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

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

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

    cleardevice();       /*清屏*/

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

    if(snownum!=100)snownum++;

    setfillstyle(SOLID_FILL,15);

    for(i=0;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 DrawSnow2()

{

  int i;

  int sx[62];

  setlinestyle(SOLID_LINE,0,THICK_WIDTH);

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

  line(0,5,10,5);

  line(9,1,1,9);

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

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

  cleardevice();   /*清屏*/

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

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

  sx[i]=(i+2)*10;   /*计算雪花位置的横坐标数组*/

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

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

  {

   drawmat(er64S,64,100,100,BROWN);

   drawmat(ren64S,64,200,100,CYAN);

    Pr();          /*调用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

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

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

    cleardevice();       /*清屏*/

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

    if(snownum!=100)snownum++;

    setfillstyle(SOLID_FILL,15);

    for(i=0;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 Pr()     /*输出欢迎词并播放音乐*/

{

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

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

  settextstyle(0,0,4);

  outtextxy(90,200,"ARE YOU READY!!");   /*输出欢迎词 */

   drawmat(tan64S,64,300,100,YELLOW);

   drawmat(chi64S,64,400,100,RED);

   drawmat(she64S,64,500,100,GREEN);

   drawmat(zu24S,24,30,330,YELLOW);

   drawmat(zhang24S,24,60,330,GREEN);

   drawmat(lin48K,48,180,315,CYAN);

   drawmat(yang48K,48,240,315,BROWN);

   drawmat(bo48K,48,300,315,RED);

   drawmat(zu24S,24,30,410,YELLOW);

   drawmat(yuan24S,24,60,410,GREEN);

   drawmat(guo48K,48,100,400,CYAN);

   drawmat(zhi48K,48,160,400,BROWN);

   drawmat(jia48K,48,220,400,RED);

   drawmat(wang48K,48,300,400,CYAN);

   drawmat(chun48K,48,360,400,BROWN);

   drawmat(xu48K,48,420,400,RED);

   drawmat(mou48K,48,500,400,CYAN);

   drawmat(ting48K,48,550,400,BROWN);

   drawmat(ting48K,48,600,400,YELLOW);

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

}

/*图形驱动,图形系统初始化函数*/

void Init(void)

{

   int gd=DETECT,gm;

   registerbgidriver(EGAVGA_driver);

   initgraph(&gd,&gm,"c:\\program files\\winyes\\tc20h\\bgi");

   cleardevice();

}

   /*游戏开始画面,左上角坐标为(50,40),右下角坐标为(60,460)的围墙*/

void DrawK0(void)

{

   cleardevice();

   setcolor(12);

   setlinestyle(SOLID_LINE,0,THICK_WIDTH); /*设置线型*/

   setfillstyle(1,9);

   bar(40,30,620,48);

    bar(40,452,620,470);

    bar(40,30,58,470);

    bar(602,30,620,470);

   for(i=203;i<=297;i+=13)

   {rectangle(i,103,i+13,116);

   }

   for(i=40;i<=600;i+=20)  /*循环画围墙*/

   {

      rectangle(i,30,i+20,48);    /*上边 */

      rectangle(i,452,i+20,470);  /*下边 */

   }

  for(i=30;i<=450;i+=20)

  {

     rectangle(40,i,58,i+20);    /*左边 */

     rectangle(602,i,620,i+20);   /*右边 */

  }

}

 /*玩游戏具体过程*/

void GamePlay()

{

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

   food0.yes=1;

   zhang.yes=1;                      /*1表示需要出现新食物,0表示已经存在食物  */

   snake0.life=0;                     /*蛇活着 */

   snake0.direction=1;                /*方向往右 */

   snake0.x[0]=100;snake0.y[0]=100;    /*蛇头坐标初值 */

   snake0.x[1]=110;snake0.y[1]=100;    /*蛇尾坐标初值 */

   snake0.node=2;                     /*蛇节数初值*/

   PrScore();                        /*玩游戏“死”循环,按ESC键或蛇死时结束 */

   while(1)

   {

      while(!kbhit())                /*在没有按键的情况下,蛇自己移动身体 */

      {

       if(zhang.yes==1)                  /*需要出现新食物 */

     {

         zhang.x=rand()%400+60;

         zhang.y=rand()%350+60;         /*食物出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

         while(zhang.x%10!=0)

        zhang.x++;

         while(zhang.y%10!=0)

        zhang.y++;

        zhang.yes=0;                     /*画面上有食物了 */

     }

     if(zhang.yes==0)                     /*画面上有食物就要显示*/

     {

              setcolor(RED);

              rectangle(zhang.x,zhang.y,zhang.x+30,zhang.y-10);

     }

     if(food0.yes==1)                  /*需要出现新食物 */

     {

         food0.x=rand()%400+60;

         food0.y=rand()%350+60;         /*食物出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

         while(food0.x%10!=0)

        food0.x++;

         while(food0.y%10!=0)

        food0.y++;

        food0.yes=0;                     /*画面上有食物了 */

     }

     if(food0.yes==0)                     /*画面上有食物就要显示*/

     {

              setcolor(GREEN);

              rectangle(food0.x,food0.y,food0.x+10,food0.y-10);

     }

         for(i=snake0.node-1;i>0;i--)

         {

            snake0.x[i]=snake0.x[i-1];

        snake0.y[i]=snake0.y[i-1];

     }

     /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/

     switch(snake0.direction)

     {

        case 1:snake0.x[0]+=10;break;

        case 2: snake0.x[0]-=10;break;

        case 3: snake0.y[0]-=10;break;

        case 4: snake0.y[0]+=10;break;

       /*从蛇的第四节开始判断是否撞到自己了,因为第3节可能拐不过来*/     }

     for(i=3;i

     {

        if(snake0.x[i]==snake0.x[0]&&snake0.y[i]==snake0.y[0])

        {

               GameOver0();

               snake0.life=1;    /*置蛇死标志 */

               break;

        }

        }/*判断蛇是否撞到墙壁*/

    if(snake0.x[0]<55||snake0.x[0]>595||snake0.y[0]<55||snake0.y[0]>455)

    {

        GameOver0();

        snake0.life=1;     /*置蛇死标志 */

    }

    if(snake0.x[0]>190&&snake0.x[0]<310&&snake0.y[0]>100&&snake0.y[0]<130)

    {

        GameOver0();

        snake0.life=1;

    }

     if(snake0.x[0]==zhang.x&&snake0.y[0]==zhang.y)

    {

        GameOver0();

        snake0.life=1;

    }

      if(snake0.x[0]==zhang.x+10&&snake0.y[0]==zhang.y)

    {

        GameOver0();

        snake0.life=1;

    }

      if(snake0.x[0]==zhang.x+20&&snake0.y[0]==zhang.y)

    {

        GameOver0();

        snake0.life=1;

    }

    if(snake0.life==1)     /*以上判断后,如果蛇死就跳出内循环*/

           break;

    if(snake0.x[0]==food0.x&&snake0.y[0]==food0.y)

    {

           setcolor(0);

           rectangle(food0.x,food0.y,food0.x+10,food0.y-10);

       snake0.x[snake0.node]=-20;snake0.y[snake0.node]=-20;

       snake0.node++;         /*蛇的身体长一节 */

       food0.yes=1;           /*画面需要出现新的食物 */

       zhang.yes=1;

       setcolor(0);

           rectangle(zhang.x,zhang.y,zhang.x+30,zhang.y-10);

       score+=10;             /*没吃一个食物增加10分 */

       PrScore();

    }

    setcolor(5);

    rectangle(snake0.x[0],snake0.y[0],snake0.x[0]+10,

               snake0.y[0]-10);

    setcolor(4);                /*画出红色蛇的循环体*/

    for(i=1;i

       rectangle(snake0.x[i],snake0.y[i],snake0.x[i]+10,

               snake0.y[i]-10);

    delay(gamespeed);        /*用延迟gamespeed毫秒,以控制蛇的爬行速度 */

    setcolor(0);              /*用背景色黑色去除蛇的最后一节 */

    rectangle(snake0.x[snake0.node-1],snake0.y[snake0.node-1],

    snake0.x[snake0.node-1]+10,snake0.y[snake0.node-1]-10);

     }                        /*endwhile(!kbhit) */

    if(snake0.life==1)

        break;;               /*如果蛇死就跳出循环 */

    key=bioskey(0);            /*接收按键 */

    if(key==ESC)                /*如果按ESC键就退出 */

       break;

    else

       if(key==UP1&&snake0.direction!=4)

      snake0.direction=3;         /*判断是否往相反的方向移动 */

       else

      if(key==RIGHT1&&snake0.direction!=2)

         snake0.direction=1;

      else

         if(key==LEFT1&&snake0.direction!=1)

        snake0.direction=2;

         else

        if(key==DOWN1&&snake0.direction!=3)

           snake0.direction=4;

   }         /* endwhile(1)*/

}            /* 游戏结束 */

void GameOver0(void)        /*游戏结束*/

{

    cleardevice();

    PrScore();

   setcolor(RED);

   settextstyle(0,0,4);

   outtextxy(200,200,"GAME OVER");

   getch();

}

void PrScore(void)           /*输出成绩*/

{  

   char str[10];

   setfillstyle(SOLID_FILL,YELLOW);

   bar(50,15,220,35);

   setcolor(6);

   settextstyle(0,0,2);

   sprintf(str,"score:%d",score);

   outtextxy(55,20,str);

}

void Close(void)

{  

    getch();

    closegraph();

}

void ReadFiles1()

{

    FILE *fpread;

    if((fpread=fopen(FILENAME,"ab+"))==NULL)

    {

        printf("can't open the file person.dat");

        exit(0);

    }

    if(fgetc(fpread)==EOF)InitScoreFiles();

    rewind(fpread);

    fread(per,sizeof(struct person),5,fpread);

    fclose(fpread);

}

void WriteFiles(struct person *tmp)

{

    FILE *fpwrite;

    if((fpwrite=fopen(FILENAME,"wb+"))==NULL)

    {

        printf("can't open the file person.dat");

        exit(0);

    }

    fwrite(tmp,sizeof(struct person),5,fpwrite);

    fclose(fpwrite);

}

void InitScoreFiles()

{

    int i;

    struct person a[5];

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

    {

        a[i].score=0;

        strcpy(a[i].name,"nobody");

    }

    WriteFiles(a);

}

void CompareScore(struct person des)

{

    int i,j;

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

    {

        if(des.score>per[i].score)

        {

            for(j=4;j>=i;j--)

            per[j]=per[j-1];

        }

        per[i]=des;

        break;

    }

}

void pain_board()            /*显示排行函数 */

{

    int i;

    char string[10];

    ReadFiles1();

    setfillstyle(1,9);

    bar(482,227,599,239);

    outtextxy(490,230,"Highest board");

    setcolor(15);

    rectangle(480,225,600,240);

    setcolor(8);

    rectangle(481,226,601,241);

    setfillstyle(1,7);

    bar(475,257,610,426);

    setcolor(15);

    line(475,257,610,257);

    line(475,257,475,426);

    setcolor(8);

    line(475,426,610,426);

    line(610,257,610,426);

    setcolor(1);

    outtextxy(480,260,"name     score");

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

    {

        setcolor(4);

        outtextxy(480,290+i*30,per[i].name);

        itoa(per[i].score,string,10);

        setcolor(14);

        outtextxy(580,290+i*30,string);

        setcolor(8);

        line(476,280+i*30,609,280+i*30);

        setcolor(15);

        line(476,281+i*30,609,281+i*30);

    }

}

void EndPlay0()                  /*游戏结束处理函数 */

{

    struct person CurPerson;

    ReadFiles1();     /*调用从文件中读取排行榜信息的函数

    比较当前玩家分数和最低记录分数,如果满足条件,则将玩家分数写入记录中*/

    settextstyle(0,0,0);

    if(score>per[4].score)

    {

        setfillstyle(1,9);

        bar(14,14,447,419);

        outtextxy(50,250,"Refueling!Your Score Enter the Board!");

        outtextxy(50,270,"please enter your name:");

        gotoxy(7,19);

        printf("          ");       /*用背景色输出空格,建立姓名输入框 */

        gotoxy(7,19);

        scanf("%s",CurPerson.name);

        CurPerson.score=score;

        CompareScore(CurPerson);      /*调用排序函数,对进榜的5人排序 */

        WriteFiles(per);               /*调用写文件函数,写入排行榜记录 */

    }

    else outtextxy(70,250,"Your Score id not enough on the Board!");

    pain_board();           /*调用显示排行榜函数 */

}

void Background(int i)           /*下雪动画并同步播放音乐函数 */

{

    setlinestyle(SOLID_LINE,0,THICK_WIDTH);

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

    line(0,5,10,5);

    line(9,1,1,9);

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

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

    cleardevice();                     /*清屏*/

    settextstyle(0,0,0);

    outtextxy(300,150,"Newgame");

    outtextxy(300,200,"pain broad");

    outtextxy(300,250,"exit");

    if(i==1)

    putimage(250,150,save,COPY_PUT);

    else if(i==2)

    putimage(250,200,save,COPY_PUT);

    else

    putimage(250,250,save,COPY_PUT);

}

 /*双人游戏*/

struct  person1    /*得分结构体*/

  {

    char name[20];

    int  score;

   };    /*定义一个结构体变量用来储存第一个人的名字及分数!*/

struct person1  per1[5];   /*定义结构体变量名称。*/

struct  person2

  {

    char name[20];

    int  score;

  };   /*定义一个结构体变量用来储存第二个人的名字及分数!*/

struct person2  per2[5];  /*定义第二个结构体变量名称。*/

int score1=0; /*记录游戏分数*/

int score2=0;

int size;

int score;

int i,key1;

int size;

void *save;

 struct Zhang1

{

    int x;    /*食物的横坐标*/

    int y;    /*食物的纵坐标*/

    int yes;/*判断是否要出现食物的变量*/

}zhang1[5];

struct Food

{

    int x;    /*食物的横坐标*/

    int y;    /*食物的纵坐标*/

    int yes;/*判断是否要出现食物的变量*/

}food[5];

struct Snake

{

    int x[N];

    int y[N];

    int node;  /*蛇的节数*/

    int direction; /*蛇移动方向*/

    int life;   /* 蛇的生命,0活着,1死亡*/

}snake[5];

void  WriteFiles1(struct person1  *tmp);     /*利用结构体变量指针找到所存的文件!*/

void  WriteFiles2(struct person2  *tmp);

void  InitScoreFiles1();

void  CompareScore1(struct person1);     /*排行榜函数!*/

void  CompareScore2(struct person2) ;

void Init(void); /*图形驱动*/

void Close(void);  /*图形结束*/

void DrawK(void);    /*开始画面*/

void GameOver(void); /*结束游戏*/

void GamePlay(void);  /*玩游戏具体过程*/

void PrScore(void);    /*输出成绩*/

/*输出欢迎词并播放音乐*/

void Pr();

void pain_borad();/*绘制排行榜函数*/

/*下雪的动画并同时播放音乐函数*/

 void  pain_board();

/*图形驱动,图形系统初始化函数*/

   /*游戏开始画面,左上角坐标为(50,40),右下角坐标为(60,460)的围墙*/

void DrawK(void)

{  int i;

   setcolor(YELLOW);

   setlinestyle(SOLID_LINE,0,THICK_WIDTH);       /*设置线形*/

   for(i=50;i<=328;i+=10)     /*循环画围墙313  343*/

   {  

       circle(i+5,44,5);

       circle(i+5,455,5);

    }

    for(i=40;i<=450;i+=10)

   {  

       circle(55,i+5,5);

       circle(328,i+5,5);

   }

   for(i=328;i<602;i+=10)

   {

     circle(i+5,44,5);

     circle(i+5,455,5);

   }

   for(i=40;i<450;i+=10)

   {

    circle(328,i+5,5);

    circle(604,i+5,5);  /*此为循环画围墙的程序,围墙为半径为5的圆!*/

   }

    outtextxy(20,5,"      Greedy Snake Game 1.4.0_1");

    outtextxy(480,10,"score   level");

}

 /*玩游戏具体过程*/

void GamePlay1(void)

{

   int level1=1,level2=1;  /*记录游戏的等级*/

   char buffer[10];   /*字符数组用于转换整形数据*/

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

   food[1].yes=1;/*1表示需要出现新食物,0表示已经存在食物*/

   food[2].yes=1;

   zhang1[1].yes=1;

   zhang1[2].yes=1;

   snake[1].life=0;/*蛇1活着*/

   snake[2].life=0; /*蛇1活着*/

   snake[1].direction=1;/*蛇1的方向往右*/

   snake[2].direction=1; /*蛇2的方向往右*/

   snake[1].x[1]=100; snake[1].y[1]=100;/*蛇1身坐标初值*/ 

   snake[1].x[0]=110; snake[1].y[0]=100;/*蛇1头坐标初值。*/

   snake[2].x[1]=440; snake[2].y[1]=100; /*蛇2身坐标初值*/

   snake[2].x[0]=450; snake[2].y[0]=100; /*蛇2头坐标初值。*/

   snake[1].node=3;/*蛇节数*/

   snake[2].node=3;

   while(1)/*玩游戏"死"循环,按ESC键或蛇死时结束*/

   { while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/

     {

       if(zhang1[1].yes==1)/*需要出现新食物*/

       {

     zhang1[1].x=rand()%200+60;

     zhang1[1].y=rand()%175+60;

/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

     while(zhang1[1].x%10!=0)

     zhang1[1].x++;

     while(zhang1[1].y%10!=0)  zhang1[1].y++;

     zhang1[1].yes=0;/*画面上有食物了*/

       }

       if(zhang1[2].yes==1)

       { zhang1[2].x=rand()%240+345;

         zhang1[2].y=rand()%350+60;/*此为定义食物随机出现位置的函数。*/

     while(zhang1[2].x%10!=0)

     zhang1[2].x++;

     while(zhang1[2].y%10!=0)  zhang1[2].y++;

     zhang1[2].yes=0;

       }

 if(zhang1[1].yes==0)/*画面上有食物了就要显示*/

  {

    setcolor(RED);

    rectangle(zhang1[1].x,zhang1[1].y,zhang1[1].x+30,zhang1[1].y-10);

  }

  if(zhang1[2].yes==0)

  {

    setcolor(RED);

    rectangle(zhang1[2].x,zhang1[2].y,zhang1[2].x+30,zhang1[2].y-10);

  }

        if(food[1].yes==1)/*需要出现新食物*/

       {

     food[1].x=rand()%200+60;

     food[1].y=rand()%175+60;

/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

     while(food[1].x%10!=0)

     food[1].x++;

     while(food[1].y%10!=0)  food[1].y++;

     food[1].yes=0;/*画面上有食物了*/

       }

       if(food[2].yes==1)

       { food[2].x=rand()%240+345;

         food[2].y=rand()%350+60;/*此为定义食物随机出现位置的函数。*/

     while(food[2].x%10!=0)

     food[2].x++;

     while(food[2].y%10!=0)  food[2].y++;

     food[2].yes=0;

       }

 if(food[1].yes==0)/*画面上有食物了就要显示*/

  {

    setcolor(GREEN);

    rectangle(food[1].x,food[1].y,food[1].x+10,food[1].y-10);

  }

  if(food[2].yes==0)

  {

    setcolor(GREEN);

    rectangle(food[2].x,food[2].y,food[2].x+10,food[2].y-10);

  }

   setfillstyle(1,1);

 bar(60,18,175,35);/*画出显示分数及关数红色矩形条*/

 setcolor(RED);

 itoa(score1,buffer,10);/*将整型数据分数转换成字符串*/

 outtextxy(65,20,buffer);/*输出分数*/

 itoa(level1,buffer,10);/*将整形数据关数转换成字符串*/

 outtextxy(145,20,buffer);/*输出关数*/

/*循环使蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/

   for(i=snake[1].node-1;i>0;i--)

     {

      snake[1].x[i]=snake[1].x[i-1];

      snake[1].y[i]=snake[1].y[i-1];

      }

/*1、2、3、4表示右左上下四个方向,通过这个判断来移动蛇头*/

   switch(snake[1].direction)

{

case 1:snake[1].x[0]+=10;break;

case 2:snake[1].x[0]-=10;break;

case 3:snake[1].y[0]-=10;break;

case 4:snake[1].y[0]+=10;break;

}

/*从蛇的第四节开始判断是否撞倒自己了,因为第三节不可能拐过来*/

  for(i=3;i

    {

      if(snake[1].x[i]==snake[1].x[0]&&snake[1].y[i]==snake[1].y[0])

     {snake[1].life=1;/*置蛇死标志*/

      break;

      }

}

/*判断蛇是否撞倒墙壁*/

  if(snake[1].x[0]<55||snake[1].x[0]>310||snake[1].y[0]<55||snake[1].y[0]>455)

     snake[1].life=1;/*蛇置死标记*/

    if(snake[1].x[0]==zhang1[1].x&&snake[1].y[0]==zhang1[1].y)/*吃到障碍以后*/

    {

        snake[1].life=1;

    }

    if(snake[1].x[0]==zhang1[1].x+10&&snake[1].y[0]==zhang1[1].y)/*吃到障碍-+以后*/

    {

        snake[1].life=1;

    }

     if(snake[1].x[0]==zhang1[1].x+20&&snake[1].y[0]==zhang1[1].y)/*吃到食物以后*/

    {

        snake[1].life=1;

    }

/*以上两种判断以后,如果蛇死就跳出内循环*/

  if(snake[1].life==1)

   break;

  if(snake[1].x[0]==food[1].x&&snake[1].y[0]==food[1].y)/*吃到食物以后*/

    {

     setcolor(0);/*把画面上的食物擦除*/

     rectangle(food[1].x,food[1].y,food[1].x+10,food[1].y-10);

     snake[1].node++;/*蛇的身体长一节*/

     food[1].yes=1;/*画面上需要出现新的食物*/

     zhang1[1].yes=1;

     setcolor(0);/*把画面上的食物擦除*/

     rectangle(zhang1[1].x,zhang1[1].y,zhang1[1].x+30,zhang1[1].y-10);

     score1+=10;/*每吃一个食物赠加10分*/

    

   if(score1%50==0)/*吃够5个食物 进入下一关*/

   {

    level1+=1;/*关数加一*/

     gamespeed-=50;/*控制速度 的值减少50,以便加快速度*/

     }

  }

  setfillstyle(1,1);

 bar(475,18,590,35);

 setcolor(RED);

 itoa(score2,buffer,10);

 outtextxy(480,20,buffer);

 itoa(level2,buffer,10);

 outtextxy(560,20,buffer);

   for(i=snake[2].node-1;i>0;i--)

     {

      snake[2].x[i]=snake[2].x[i-1];

      snake[2].y[i]=snake[2].y[i-1];

      }

   switch(snake[2].direction)

{

case 1:snake[2].x[0]+=10;break;

case 2:snake[2].x[0]-=10;break;

case 3:snake[2].y[0]-=10;break;

case 4:snake[2].y[0]+=10;break;

}

  for(i=3;i

    {

      if(snake[2].x[i]==snake[2].x[0]&&snake[2].y[i]==snake[2].y[0])

     {snake[2].life=1;

      break;

      }

    }

  if(snake[2].x[0]<330||snake[2].x[0]>590 ||snake[2].y[0]<55||snake[2].y[0]>455)

     snake[2].life=1;

  if(snake[2].x[0]==zhang1[2].x&&snake[2].y[0]==zhang1[2].y)/*吃到障碍以后*/

    {

        snake[2].life=1;

    }

    if(snake[2].x[0]==zhang1[2].x+10&&snake[2].y[0]==zhang1[2].y)/*吃到障碍以后*/

    {

        snake[2].life=1;

    }

    if(snake[2].x[0]==zhang1[2].x+20&&snake[2].y[0]==zhang1[2].y)/*吃到障碍以后*/

    {

        snake[2].life=1;

    }

  if(snake[2].life==1)

   break;

  if(snake[2].x[0]==food[2].x&&snake[2].y[0]==food[2].y)

    {

     setcolor(0);

     rectangle(food[2].x,food[2].y,food[2].x+10,food[2].y-10);

     snake[2].node++;

     food[2].yes=1;

     zhang1[2].yes=1;

     setcolor(0);

     rectangle(zhang1[2].x,zhang1[2].y,zhang1[2].x+30,zhang1[2].y-10);

     score2+=10;

    

   if(score2%50==0)

   {

    level2+=1;

     gamespeed-=50;

     }

  }

setcolor(5);/*画出粉色蛇的循环*/

for(i=0;i

  rectangle(snake[1].x[i],snake[1].y[i],snake[1].x[i]+10,

               snake[1].y[i]-10);

delay(gamespeed);/*延迟gamespeed毫秒,以便控制蛇的爬行速度*/

setcolor(0);/*用背景色黑色去除蛇的最后一节*/

rectangle(snake[1].x[snake[1].node-1],snake[1].y[snake[1].node-1],

   snake[1].x[snake[1].node-1]+10,snake[1].y[snake[1].node-1]-10);

setcolor(4);/*设置蛇身体为红色。*/

for(i=0;i

  rectangle(snake[2].x[i],snake[2].y[i],snake[2].x[i]+10,

               snake[2].y[i]-10);

delay(gamespeed);

setcolor(0);

rectangle(snake[2].x[snake[2].node-1],snake[2].y[snake[2].node-1],

  snake[2].x[snake[2].node-1]+10,snake[2].y[snake[2].node-1]-10);

}

  if(snake[1].life==1)  break;/*如果蛇死就跳出循环*/

  key1=bioskey(0);/*接受按键*/

  if(key1==ESC)  break;/*按ESC键退出*/

  switch(key1)

  {case UP:if(snake[1].direction!=4)

       snake[1].direction=3;break;

   case RIGHT:if(snake[1].direction!=2)

       snake[1].direction=1;break;

   case LEFT:if(snake[1].direction!=1)

       snake[1].direction=2;break;

   case DOWN:if(snake[1].direction!=3)

       snake[1].direction=4;break;

   case UP1:if(snake[2].direction!=4)

       snake[2].direction=3; break;

   case RIGHT1:if(snake[2].direction!=2)

           snake[2].direction=1;break;

   case LEFT1:if(snake[2].direction!=1)

           snake[2].direction=2;break;

   case DOWN1:if(snake[2].direction!=3)

  snake[2].direction=4;break;  

  } /*用switch函数实现两条蛇的方向控制。只有这样才能够实现两条蛇的同步控制!*/   

  }

}

  /*读取文件操作函数*/

  void ReadFiles()

{

   FILE *fpread1;/*定义读取指针*fpread1,用来读取文件。*/

   FILE *fpread2;

/*如果文件不存在,则创建一个空文件,否则打开该文件*/

     if((fpread1=fopen(FILENAME1,"ab+"))==NULL)

       {

     printf("can't open the file person1.dat!");

      exit(0);

       }

    if((fpread2=fopen(FILENAME2,"ab+"))==NULL)

       {

     printf("can't open the file person2.dat!");

      exit(0);

       }

/*如果该文件名为空,则进行记录初始化工作*/

     if(fgetc(fpread1)==EOF)  InitScoreFiles1();

     if(fgetc(fpread2)==EOF)  InitScoreFiles1();/*如果文件为空,就执行文件的初始化功能!*/

     rewind(fpread1);/*重新复位文件位置指针*/

     rewind(fpread2);

/*将排行榜信息读入Per数组中*/

   fread(per1,sizeof(struct person1),5,fpread1);

   fclose(fpread1); /*关闭排行榜文件*/

   fread(per2,sizeof(struct person2),5,fpread2);

   fclose(fpread2);

}

/*文件写入操作函数*/

void WriteFiles1(struct person1 *tmp)

{  FILE *fpwrite1;

/*以读写方式打开文件,文件内原有的函数 将被清空*/

   if((fpwrite1=fopen(FILENAME1,"wb+"))==NULL)

   {  printf("can't open the file person1.dat!");exit(0); 

   }

   fwrite(tmp,sizeof(struct person1),5,fpwrite1);

   fclose(fpwrite1);

}

/*初始化记录函数,默认的分数值和名字可以自己更改*/

void WriteFiles2(struct person2 *tmp)

{  FILE *fpwrite2;

   if((fpwrite2=fopen(FILENAME2,"wb+"))==NULL)

   {  printf("can't open the file person2.dat!");exit(0); 

   }

   fwrite(tmp,sizeof(struct person2),5,fpwrite2);

   fclose(fpwrite2);

}

void GameOver(void)        /*游戏结束*/

{

    cleardevice();

    PrScore();

   setcolor(RED);

   settextstyle(0,0,4);

   outtextxy(200,200,"GAME OVER");

   getch();

}

void InitScoreFiles1()    /*定义分数的初始化函数。*/

{  int i;

   struct person1 a[5];

   struct person2 b[5];

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

   {  a[i].score=0;

      strcpy(a[i].name,"nobody");

   }

   WriteFiles1(a);

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

   {  a[i].score=0;

      strcpy(a[i].name,"nobody");

   }

   WriteFiles2(b);

}

/*排序函数,如果玩家分数超过最低记录,则将玩家分数插入到合适的位置,同时删除原先的最低记录*/

void CompareScore1(struct person1  des)

{  int i,j;

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

   {  if(des.score>=per1[i].score)

      {  if(i<5)

     {

        for(j=4;j>=i+1;j--)

        per1[j]=per1[j-1];

     }

     per1[i]=des;

     break;

     }

   }

}

/*显示排行榜函数*/

void CompareScore2(struct person2  des)

{  int i,j;

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

   {  if(des.score>=per2[i].score)

      {  if(i<5)

         {for(j=4;j>=i+1;j--)

        per2[j]=per2[j-1];

     }

     per2[i]=des;

     break;

     }

   }

}/*定义第一个贪吃蛇的排行榜函数。实现第一个排行榜的功能!*/

void pain1_board()

{

  int i;

  char string[10];

  ReadFiles();

  setfillstyle(1,9);

  bar(482,227,599,239);   /*定义Highest board所在区域的矩形框!*/

  outtextxy(490,230,"Highest board");

  setcolor(15);/*Highest board矩形框的背景色!*/

  rectangle(480,225,600,240);/*设置排行榜第一个人的矩形框位置!*/

  setcolor(8);/*设置背景颜色!*/

  rectangle(481,226,601,241);

  setfillstyle(1,7);

  bar(475,257,610,426);

  setcolor(15);

  line(475,257,610,257);

  line(475,257,475,426);

  setcolor(1);

  outtextxy(480,265,"name        score");

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

  {  setcolor(4);

     outtextxy(480,290+i*30,per1[i].name);

     itoa(per1[i].score,string,10);

     setcolor(14);

     outtextxy(580,290+i*30,string);

     setcolor(8);

     line(476,280+i*30,609,280+i*30);

     setcolor(15);

     line(476,281+i*30,609,281+i*30);

  }

  getch();

}/*定义第二个贪吃蛇的排行榜函数。实现第二个排行榜的功能!*/

void pain2_board()

{

  int i;

  char string[10];

  ReadFiles();

  setfillstyle(1,9);

  bar(182,227,299,239);

  outtextxy(190,230,"Highest board");

  setcolor(15);

  rectangle(180,225,300,240);

  setcolor(8);

  rectangle(181,226,301,241);

  setfillstyle(1,7);

  bar(175,257,310,426);

  setcolor(15);

  line(175,257,310,257);

  line(175,257,175,426);

  setcolor(1);

  outtextxy(180,265,"name        score");

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

  {  setcolor(4);

     outtextxy(180,290+i*30,per2[i].name);

     itoa(per2[i].score,string,10);

     setcolor(14);

     outtextxy(280,290+i*30,string);

     setcolor(8);

     line(176,280+i*30,309,280+i*30);

     setcolor(15);

     line(176,281+i*30,309,281+i*30);

  }

  getch();

}

/*游戏结束处理函数*/

void EndPlay()

{  struct person1  CurPerson1;

   struct person2  CurPerson2;

   ReadFiles();/*调用从文件中读取排行榜信息的函数*/

/*比较当前玩家分数和最低记录分数,如满足条件,则将玩家分数写入记录中*/

   if(score1>per1[4].score)

   {  setfillstyle(1,9);

      bar(14,214,400,419);

      outtextxy(50,250,"Refueling!Your Score Enter the Board!");

      outtextxy(50,270,"please enter your name:");

      gotoxy(7,19);

      printf("     ");/*用背景色输出空格,建立姓名输入框*/

      gotoxy(7,19);

      scanf("%s",CurPerson1.name);

      CurPerson1.score=score1;

      CompareScore1(CurPerson1);/*调用排序函数,对进榜 的5人排序*/

      WriteFiles1(per1);/*调用写文件函数,写入排行榜记录*/

   }

   else outtextxy(70,250,"Your Score is not enough on the Board!");

   pain1_board();/*调用显示排行榜函数*/

   ReadFiles();

   if(score2>per2[4].score)

   {  setfillstyle(1,9);

      bar(14,14,400,200);

      outtextxy(50,90,"Refueling!Your Score Enter the Board!");

      outtextxy(50,110,"please enter your name:");

      gotoxy(7,19);

      printf("     ");

      gotoxy(7,19);

      scanf("%s",CurPerson2.name);

      CurPerson2.score=score2;

      CompareScore2(CurPerson2);

      WriteFiles2(per2);

   }

   else outtextxy(70,70,"Your Score is not enough on the Board!");

   pain2_board();

}

void Pr1()     /*输出欢迎词并播放音乐*/

{

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

  settextstyle(0,0,4);

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

   drawmat(tan64S,64,200,100,YELLOW);

   drawmat(chi64S,64,300,100,RED);

   drawmat(she64S,64,400,100,GREEN);

   drawmat(xuan64S,64,50,260,YELLOW);

   drawmat(ze64S,64,130,260,RED);

   drawmat(yi64S,64,210,260,GREEN);

   drawmat(ren64S,64,290,260,YELLOW);

   drawmat(huo64S,64,370,260,GREEN);

   drawmat(er64S,64,450,260,CYAN);

   drawmat(ren64S,64,530,260,BROWN);

}

void DrawSnow1()

{

  int i;

  int sx[62];

  setlinestyle(SOLID_LINE,0,THICK_WIDTH);

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

  line(0,5,10,5);

  line(9,1,1,9);

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

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

  cleardevice();   /*清屏*/

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

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

  sx[i]=(i+2)*10;   /*计算雪花位置的横坐标数组*/

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

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

  {

    Pr1();          /*调用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

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

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

    cleardevice();       /*清屏*/

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

    if(snownum!=100)snownum++;

    setfillstyle(SOLID_FILL,15);

    for(i=0;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 main(void)

{

   void DrawSnow();

   int elective=1;

    int elect,n ;

    Init();

    DrawSnow1();

    scanf("%d",&n);

    if(n==1)

    {

      Init();                /*调用图形系统初始化函数 */

   DrawSnow();           /*调用动画音乐函数 */

   while(1)

    {

        score=0;

        Background(elective);

        elect=bioskey(0);

        if(elect==UP1)

            elective-=1;

        if(elect==DOWN1)

            elective+=1;

        if(elective>3)elective=1;

        if(elective<1)elective=3;

        if(elect==space)

        {

            if(elective==1)

           {

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

                GamePlay();     /*玩游戏具体过程 */

                EndPlay0();       /* 调用游戏结束处理函数  */

                getchar();           /*  等待任意键 */

            }

            else if(elective==2)

            {

                pain_board();

                getchar();

            }

            else break;

        }

    }

   getch();

   Close();

    }

    if(n==2)

   {

    Init();                /*调用图形系统初始化函数 */

    DrawSnow2();           /*调用动画音乐函数 */

    while(1)

     {

        score=0;

        Background(elective);

        elect=bioskey(0);

        if(elect==UP1)

            elective-=1;

        if(elect==DOWN1)

            elective+=1;

        if(elective>3)elective=1;

        if(elective<1)elective=3;

        if(elect==space)

        {    cleardevice(); 

            if(elective==1)

           {

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

                GamePlay1();     /*玩游戏具体过程 */

                EndPlay();       /* 调用游戏结束处理函数  */

                getchar();           /*  等待任意键 */

            }

            else if(elective==2)

            {

                pain1_board();

                pain2_board();

                getchar();

            }

            else break;

        }

    }

   getch();

   Close();

    }}

相关推荐