C课程设计论文报告贪吃蛇游戏

目  录

第1章  课程设计的目的与要求. 1

1.1 课程设计目的. 1

1.2 课程设计的实验环境. 1

1.3 课程设计的预备知识. 1

1.4 课程设计要求. 1

第2章  课程设计内容. 2

2.1程序功能介绍. 2

2.2程序整体设计说明. 2

2.2.1设计思路. 2

2.2.2数据结构设计及用法说明. 2

2.2.3程序结构(流程图). 3

2.2.4各模块的功能及程序说明. 6

2.3程序源代码及注释. 9

第3章 课程设计总结. 16

参考资料  17

第1章  课程设计的目的与要求

1.1 课程设计目的

本课程设计是计算机科学与技术专业重要的实践性环节之一,是在学生学习完《程序设计语言(C)》课程后进行的一次全面的综合练习。本课程设计的目的和任务:

1. 巩固和加深学生对C语言课程的基本知识的理解和掌握

2. 掌握C语言编程和程序调试的基本技能

3. 利用C语言进行基本的软件设计

4. 掌握书写程序设计说明文档的能力

5. 提高运用C语言解决实际问题的能力

1.2 课程设计的实验环境

硬件要求能运行Windows 2000/XP操作系统的微机系统。C语言程序设计及相应的开发环境。

1.3 课程设计的预备知识

熟悉C语言及C语言开发工具。

1.4 课程设计要求

1. 分析课程设计题目的要求
2. 写出详细设计说明
3. 编写程序代码,调试程序使其能正确运行
4. 设计完成的软件要便于操作和使用
5. 设计完成后提交课程设计报告
 

第2章  课程设计内容

2.1程序功能介绍

     贪吃蛇游戏是一个深受人们喜爱的游戏,一条在密闭的围墙内,在围墙内随机出现一个食物,通过按键盘上四个光标键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被蛇吃掉,这时蛇的身体长一节,同时计10分,接着又出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁或身体交叉蛇头撞到自己的身体游戏结束。

2.2程序整体设计说明

2.2.1设计思路

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

2.2.2数据结构设计及用法说明

表示食物与蛇的矩形块设计为10*10个像素单位,食物的基本数据域为他所出现的位置,用x和y座标表示,则矩形块用函数rectangle(x,y,x+10,y+10)或rectangle(x,y,x+10,y-10)可以画出。由于每次只出现一个食物,所以设定yes表示是否要出现食物。蛇的一节身体为一个矩形块,表示矩形块只需起点座标x,y。身体不断增长,用数组存放每节座标,最大设定为N=200,node表示当前节数。保存蛇的移动方向的变量direction和生命的变量life,一旦life为1,表示蛇死,结束。
#define N 200
struct Food
{
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
struct Snake
{
int x[N];
int y[N];
int node;/*蛇的节数*/
int direction;/*蛇移动方向*/
int life;/* 蛇的生命,0活着,1死亡*/
}snake;

2.2.3程序结构(流程图)

本程序流程图如下:

C课程设计论文报告贪吃蛇游戏    C课程设计论文报告贪吃蛇游戏

C课程设计论文报告贪吃蛇游戏

2.2.4各模块的功能及程序说明

1.蛇身基本单元模块 SnakeSegment.cs
基本单元用一个矩形(Rectangle)来描述,详细构造如下
private Rectangle m_rect;
/**//************构造函数,传入顶点坐标和块宽度****************/
public SnakeSegment(Point location,int width)
...{
m_rect = new Rectangle(location,new Size(width,width));
}
//属性
public Rectangle Rectangle
...{
get
...{
return m_rect;
}
}
public Point Location
...{
get
...{
return this.m_rect.Location;
}
set
...{
this.m_rect.Location = value;
}
}
public Size Size
...{
get
...{
return this.m_rect.Size;
}
}
2. 蛇身结构位置模块 Snake.cs
    蛇身由若干基本单元组成,这些单元存放在一个Queue结构中,Queue处于命名空间System.Collections之下,表示对象的先进先出集合。Snake类里面主要包含Add(添加新对象),Clear(清除对象),Slither(蛇身移动), PointOnSnake(判断某点是否在蛇身内部)几个方法。
//向蛇身添加一个新节点
public void Add(Point newLocation)
...{
SnakeSegment newhead = new SnakeSegment(newLocation,m_width);
//Check if the Queue Exists
if(m_segs == null)
...{
m_segs = new Queue(MAXSNAKELENGTH);
}
else if(m_segs.Count == MAXSNAKELENGTH)
...{
Slither(newLocation);
return;
}
m_segs.Enqueue(newhead);
}
public void Slither(Point newLocation)
...{
SnakeSegment newhead = new SnakeSegment(newLocation, this.m_width);
this.m_segs.Enqueue(newhead);
this.m_segs.Dequeue();
}
public bool PointOnSnake(Point pt)...{
IEnumerator myenum = this.m_segs.GetEnumerator();
while (myenum.MoveNext())
...{
if (((SnakeSegment) myenum.Current).Rectangle.Contains(pt))
...{
return true;
}
}
return false;
}
   3. 控制蛇身移动模块 Control.cs
  首先定义了三个全局变量
private Point m_location;
private int m_increment;
private SnakeDirection m_direction;

其中的SnakeDirection的定义为
internal enum SnakeDirection
...{
None = -1, //保持默认
Down = 1,
Left = 0,
Right = 2,
Up = 3
}

2.3程序源代码及注释

#define N 200

#include

#include

#include

#define LEFT 0x4b00

#define RIGHT 0x4d00

#define DOWN 0x5000

#define UP 0x4800

#define ESC 0x011b

int i,key;

int score=0;/*得分*/

int gamespeed=50000;/*游戏速度自己调整*/

struct Food

{

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

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

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

}food;/*食物的结构体*/

struct Snake

{

   int x[N];

   int y[N];

   int node;/*蛇的节数*/

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

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

}snake;

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

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

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

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

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

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

/*主函数*/

void main(void)

{

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

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

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

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

}

/*图形驱动*/

void Init(void)

{

   int gd=DETECT,gm;

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

   cleardevice();

}

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

void DrawK(void)

{

/*setbkcolor(LIGHTGREEN);*/

   setcolor(11);

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

   for(i=50;i<=600;i+=10)/*画围墙*/

   {

      rectangle(i,40,i+10,49); /*上边*/

      rectangle(i,451,i+10,460);/*下边*/

   }

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

  {

     rectangle(50,i,59,i+10); /*左边*/

     rectangle(601,i,610,i+10);/*右边*/

  }

}

/*玩游戏具体过程*/

void GamePlay(void)

{

   randomize();/*随机数发生器*/

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

   snake.life=0;/*活着*/

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

   snake.x[0]=100;snake.y[0]=100;/*蛇头*/

   snake.x[1]=110;snake.y[1]=100;

   snake.node=2;/*节数*/

   PrScore();/*输出得分*/

   while(1)/*可以重复玩游戏,压ESC键结束*/

   {

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

      {

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

     {

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

         food.y=rand()%350+60;

         while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

        food.x++;

         while(food.y%10!=0)

        food.y++;

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

     }

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

     {

              setcolor(GREEN);

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

     }

         for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/

         {

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

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

     }

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

     switch(snake.direction)

     {

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

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

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

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

     }

     for(i=3;i

     {

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

        {

               GameOver();/*显示失败*/

               snake.life=1;

               break;

        }

        }

    if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||

       snake.y[0]>455)/*蛇是否撞到墙壁*/

    {

        GameOver();/*本次游戏结束*/

        snake.life=1; /*蛇死*/

    }

    if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/

           break;

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

    {

           setcolor(0);/*把画面上的食物东西去掉*/

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

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

          /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/

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

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

       score+=10;

       PrScore();/*输出新得分*/

    }

    setcolor(4);/*画出蛇*/

    for(i=0;i

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

               snake.y[i]-10);

    delay(gamespeed);

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

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

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

     }  /*endwhile(!kbhit)*/

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

        break;

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

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

       break;

    else

       if(key==UP&&snake.direction!=4)

/*判断是否往相反的方向移动*/

      snake.direction=3;

       else

      if(key==RIGHT&&snake.direction!=2)

         snake.direction=1;

      else

         if(key==LEFT&&snake.direction!=1)

        snake.direction=2;

         else

        if(key==DOWN&&snake.direction!=3)

           snake.direction=4;

   }/*endwhile(1)*/

}

/*游戏结束*/

void GameOver(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();

}

第3章 课程设计总结

通过对数据结构的课程设计,我了解并发现了很多调试程序的方法,而且懂得了如何处理错误的方法。对C语言以及C++的使用得到了进一步的提高。针对数据结构的书本知识得到了进一步的巩固,具体化就是加深了我对线性表的结构的理解,栈和队链认识,二叉树的的应用,查找的方法,数的排序等。对程序的深层理解,清楚程序中每一步的功能,在程序的运行中是十分重要的,一个好的结构在运行中能够充分的发挥程序的功能。结构设计的合理性决定了这个程序的价值。在今后的学习中我要注意这方面,使得我的编程能力能有进一步的提高。     

学写程序自己一定先要把框架打好,已经程序间的联系一定要想清楚,这次失败的主要原因就是没有先写明白具体的框架,具体某个类要实现的功能,某个类里面要的一些具体变量和这变量所起的作用一定要在开始就描述清楚,已经一些函数功能的实现也要开始想好,这样在编写代码的时候逻辑关系搞的会比较清楚,编写程序的时候不会因为程序庞大而把搞的太复杂,最后自己也搞乱了,搞不清楚变量和函数的关系,终于理解到编程的开始工作很 重要,好的开始就成功了一大半。其实写代码才是时间花的最少的。

在这几天的学习中,我体会到老师对我们实训的目的,以及实训对每个人综合能力的检验。对自己平时积攒下来的知识那么少感到是多么的羞愧,通过实训我能充分的学习到一些平时书本上学不到的知识、与自己的动手操作能力。并且结合此次实训我能够通过上网或者是在图书馆查询一些相关的资料。通过这一过程,使我学会了很多,以前有好多时间都没有认真学习,此次实习,我深深体会到了积累知识的重要性。

经历了这次课程设计,不仅对我的学习提供了帮助,而且在意志力方面也得到了锻炼。我相信在未来的生活中不论遇到什么困难我都会向这次学习C程序一样,一步一步解决问题找出问题的实质,加以解决。没有足够的耐力和信心就很难坚持对课程设计每一步的顺利进。


 

参考资料

[1] 刘振安,刘大路,张蕊,秦俊。《C++ Builder 4编程技术》1999年10月第一版。北京,人民邮电出版社,1999年10月出版,P204

[2]马秀丽,刘志无,李筠。《C语言程序设计》20##年3月第一版。北京,清华大学出版社,20##年3月第一次印刷,P145   P30   P97---P100

[3] 李大友。《C语言程序设计》1999年9月第一版,北京,清华大学出版社,1999年9月第一次印刷,P40   P85

[4] 顾元刚,《C语言程序设计教程》20##年6月第一版,北京,机械工程出版社,20##年6月第一次印刷,P68   P30

[5] 苏玮,《三级C语言上机指导》20##年7月第一版,北京,清华大学出版社,20##年7月第一次印刷

[6]陈世忠,《C++编码规范》20##年6月第一版,北京,人民邮电出版社,20##年6月北京第一次出版,P31—P43

[7]叶核亚,《数据结构C++版》20##年1月第一版,北京,机械工程出版社,20##年1月第一次出版,  P25—P27

[8]张德慧,周元哲,《C++面向对象程序设计》20##年7月第一版,北京,科学出版社,20##年7月第一次印刷, P95—P96

[9]谭浩强,《C程序设计教程学习辅导》20##年10月第一版,北京,清华大学出版社,20##年10月第一次出版,  P26—P40

[10]李海文,吴乃陵,《C++程序设计实践教程》20##年9月第一版,北京,高等教育出版社,20##年9月第一次出版,  P161  P69

[11]全国计算机等级考试命题研究组编,《上机考试习题集二级C语言程序设计》20##年3月第5版,南京,南开大学出版社,20##年3月第5次印刷,  P21—P22

[12]李玲,桂玮珍,刘莲英,《C语言程序设计教程》20##年2月第一版,北京,人民邮电出版社,20##年2月第一次印刷,  P53—P54

[13]卢鹏丽,《C++语言上机指导实用教程》20##年1月第一版,北京,机械工程出版社,20##年1月第2次印刷,  P4  P37

[14]陈雪飞,《C++Builder实例入门》20##年1月第一版,北京,中国青年出版社,20##年1月第一次印刷,  P273  P268

[15]夏涛,《C语言程序设计》20##年3月第一版,北京,北京邮电大学出版社,20##年3月第一次印刷,  P79—P90     P14—P22

相关推荐