贪吃蛇实验报告

这篇具有很好参考价值的文章主要介绍了贪吃蛇实验报告。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:概要设计

  1. 程序功能:通过“w a s d”按键实现对蛇移动方向的控制,通过吃豆增加蛇身长度, 同时获得并记录游戏分数;game over之后可以选择结束或再次进行游戏

  1. 函数定义调用关系:

int main():主函数; 调用所有函数;

void setpos(int x,int y):坐标设置函数;

int HitWall():判断是否撞墙函数;调用void setpos(int x,int y);

int SelfBite():判断蛇身是否打结;调用void setpos(int x,int y);system();

int Move():移动函数;调用int HitWall();int SelfBite();void setpos(int x,int y);sleep();free();

void Welcome():初始界面函数;调用void setpos(int x,int y);

void DrawFrame():画边框函数;

void InitSnake():初始化蛇函数;

void CreateFood():创建豆函数;调用void setpos(int x,int y);

void PlayGame():游戏移动循环函数;调用void setpos(int x,int y);

void free_snake(Snake*head):释放资源函数;

char GetKeyBoard():键盘控制函数;

void Restart():重新开始函数;调用 void setpos(int x,int y);

  1. 程序流程:

将蛇身,食物,墙数据化: 蛇身用链表表示并用“@”打印,食物位置由随机数函数确认并用“?”打印,而墙的范围 可随意改变,确认一组长宽后,用“#”打印。

设定初始参数:

规定一个适当的初始速度,一个初始蛇身长度。

获取键位指示,模拟蛇的移动:

规定蛇初始的移动方向为向右方向,用GetAsyncKeyState()函数来判断键位指令判断其合理性,如果键位输入的命令是有效命令,则执行这条命令。蛇的运动过程则用链表头插法表示,同时去除蛇尾。

判断吃到食物和撞到自己和撞到墙:

吃食物:

通过比较蛇头下一次出现的位置和目标处的物体,使用if-else语句做出判断如果目标处是食物,则将其变为新的蛇头,蛇尾不变。

撞到墙:

比较蛇头下一次出现的位置和目标处的物体,使用if-else语句做出判断,如果目标处是墙或者自己身体则游戏结束。

细节处理和游戏引导:

在游戏开始和结束出给出相应文字引导,过程中给出分数等基本信息。

  1. 调用库函数:stdio.h;conio.h;stdlib.h;time.h;string.h;windows.h;

二:详细设计

  1. 地图初始化

void DrawFrame(){
    int i=0;
    for(i=0;i<60;i+=2)
    {
        setpos(i,0);
        printf("#");
        setpos(i,DOWN_WALL);
        printf("#");
    }
    for(i=0;i<DOWN_WALL;i++)
    {
        setpos(0,i);
        printf("#");
        setpos(RIGHT_WALL,i);
        printf("#");
    }
 return 0;
} 
  1. 豆的创建

void CreateFood(){
    srand(time(0));
flag:
    while(1)
    {foody=rand()%(DOWN_WALL-1+1-1)+1;
     foodx=rand()%(RIGHT_WALL-2+1-3)+3;
     if(foodx%2==0)
     break;
    }
    p=head;
    while(1)
    {
        if(p->x==foodx&&p->y==foody)
        {goto flag;
        }
        if(p->next==NULL)
        {break;
        }
        p=p->next;
        
    }
    setpos(foodx,foody);
    printf("?");
}
  1. 控制蛇身移动

int Move()
{int ret;
  if((key!='a')&&(key!='w')&&(key!='s')&&(key!='d'))
  {return 0;
  }
  ret=HitWall();
  ret+=SelfBite();
  if(ret==1)
  { 
  return 1;

  }
  p=(Snake*)malloc(sizeof(Snake));
  p->next=head;
  switch(key)
  {case'd':
      p->x=head->x+2;
      p->y=head->y;
      break;
      case'w':
      p->x=head->x;
      p->y=head->y-1;
      break;
      case's':
      p->x=head->x;
      p->y=head->y+1;
      break;
      case'a':
      p->x=head->x-2;
      p->y=head->y;
      break;
  }
  setpos(p->x,p->y);
  printf("@");
  head=p;
  Sleep(speed);
  if(p->x==foodx&&p->y==foody)
  {
      CreateFood();
      score+=10;
      setpos(60,7);
      printf("得分%d",score);
  }
  else{
  while(p->next->next!=NULL)
  p=p->next;
  setpos(p->x,p->y);
  printf(" ");
  free(p->next);
  p->next=NULL;
  p=head;
  }
  return 0;
}
  1. 判断game是否over

int HitWall(){//判断是否撞墙
    if(head->x==0||head->x==RIGHT_WALL||head->y==0||head->y==DOWN_WALL)
    {
    setpos(DOWN_WALL,14);
    printf("Game Over!");
    return 1;        
    }
    return 0;
} 
int SelfBite(){//判断是否打结
    while(p->next!=NULL)
    {
        p=p->next;
        if(head->x==p->x&&head->y==p->y)
        {setpos(DOWN_WALL,14);
         printf("Game Over!");
         
         return 1;
         system("cls");
         main();
        }    
    }
    return 0;    
}
  1. 通过键盘控制

char GetKeyBoard() {//获取键盘输入
   char key=0;
   if(_kbhit()){
       key=_getch();
   } 
return key;

}

三:功能展示

  1. 游戏开始

贪吃蛇实验报告总结,c语言,算法,链表,Powered by 金山文档
  1. 吃豆并获得分数

贪吃蛇实验报告总结,c语言,算法,链表,Powered by 金山文档
  1. game over之后可以选择重开gg下一把或者摆烂不玩了

贪吃蛇实验报告总结,c语言,算法,链表,Powered by 金山文档

四:成员分工

  1. @assassin_zzy :代码创建

  1. @dlkd20:代码优化

  1. @MySQL搬砖人:实验报告撰写

五:总结与建议

c语言功能之简陋实在是令人叹为观止,但不断编写新函数并使用也确实增强了我们的代码编写能力。在编写贪吃蛇的过程中,需要思考并逐步完成游戏的各项功能,并在不断修改调试之中对程序代码进行纠错与完善,无形之中提升了c语言能力,也给我们带来无与伦比的成就感与收获感。简而言之,获益良多。

六:于文末附上完整代码

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<windows.h>
#define DOWN_WALL 20
#define RIGHT_WALL 58
typedef struct s_snake
{
    int x; //蛇头横坐标
    int y;//蛇头纵坐标
    struct s_snake*next ;
} Snake;
void setpos(int x,int y);
int HitWall();
int SelfBite();
int Move();
Snake *head, *end;
Snake *p;
int speed=310;
int level=0, score=0;
int foodx, foody;
char key;
void Welcome();
void DrawFrame();
void InitSnake();
void CreateFood();
void PlayGame();
void free_snake(Snake*head);
char GetKeyBoard();
void Restart();
int main(){
    GetKeyBoard();
     ConsoleSettings();
     Welcome();
     DrawFrame();
    InitSnake();
    CreateFood();
    PlayGame();
    Restart();
    free_snake(head);
    return 0;
}
void setpos( int x, int y){//设置光标 
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),(COORD){
      x,y
  });
}
int HitWall(){
    if(head->x==0||head->x==RIGHT_WALL||head->y==0||head->y==DOWN_WALL)
    {
    setpos(DOWN_WALL,14);
    printf("Game Over!");
    return 1;        
    }
    return 0;
} 
int SelfBite(){
    while(p->next!=NULL)
    {
        p=p->next;
        if(head->x==p->x&&head->y==p->y)
        {setpos(DOWN_WALL,14);
         printf("Game Over!");
         
         return 1;
         system("cls");
         main();
        }    
    }
    return 0;    
}
void DrawFrame(){
    int i=0;
    for(i=0;i<60;i+=2)
    {
        setpos(i,0);
        printf("#");
        setpos(i,DOWN_WALL);
        printf("#");
    }
    for(i=0;i<DOWN_WALL;i++)
    {
        setpos(0,i);
        printf("#");
        setpos(RIGHT_WALL,i);
        printf("#");
    }
 return 0;
} 
void InitSnake()
{int i=0;
end=(Snake*)malloc(sizeof(Snake));
end->x=20;
end->y=15;
end->next=NULL;
for(i=1;i<=3;i++)
{
    head=(Snake*)malloc(sizeof(Snake));
    head->x=20+2*i;
    head->y=15;
    head->next=end;
    end=head;
}
while(end->next!=NULL)
{setpos(end->x,end->y);
printf("@");
end=end->next;
}
}
void CreateFood(){
    srand(time(0));
flag:
    while(1)
    {foody=rand()%(DOWN_WALL-1+1-1)+1;
     foodx=rand()%(RIGHT_WALL-2+1-3)+3;
     if(foodx%2==0)
     break;
    }
    p=head;
    while(1)
    {
        if(p->x==foodx&&p->y==foody)
        {goto flag;
        }
        if(p->next==NULL)
        {break;
        }
        p=p->next;
        
    }
    setpos(foodx,foody);
    printf("?");
}
void PlayGame(){
    int mv_ret=0;
    key='d';
    while(1)
    {if((GetAsyncKeyState(0x57)&&0x8000)&&key!='s')
    {key='w';
    }
    else if((GetAsyncKeyState(0x53)&&0x8000)&&key!='w')
    {key='s';
    }
    else if((GetAsyncKeyState(0x44)&&0x8000)&&key!='a')
    {key='d';
    }
    else if((GetAsyncKeyState(0x41)&&0x8000)&&key!='d')
    {key='a';
    }
    else if (GetAsyncKeyState(0x50)&&0x8000)
    {while(p->next!=NULL)
    p=p->next;
    setpos(p->x,p->y);
    printf("@");
    while(1)
    {
        Sleep(100);
        if(GetAsyncKeyState(0x50)&&0x8000)
        {break;
        }
    }
    setpos(p->x,p->y);
    printf(" ");
    }
    else if(GetAsyncKeyState(0x51)&&0x8000)
    {return ;
    }
    if(score==level&&speed>10)
    {speed-=10;
    level+=30;
    }
    mv_ret=Move();
    if(mv_ret==1)
    {break;
    }
     } 
}
int Move()
{int ret;
  if((key!='a')&&(key!='w')&&(key!='s')&&(key!='d'))
  {return 0;
  }
  ret=HitWall();
  ret+=SelfBite();
  if(ret==1)
  { 
  return 1;

  }
  p=(Snake*)malloc(sizeof(Snake));
  p->next=head;
  switch(key)
  {case'd':
      p->x=head->x+2;
      p->y=head->y;
      break;
      case'w':
      p->x=head->x;
      p->y=head->y-1;
      break;
      case's':
      p->x=head->x;
      p->y=head->y+1;
      break;
      case'a':
      p->x=head->x-2;
      p->y=head->y;
      break;
  }
  setpos(p->x,p->y);
  printf("@");
  head=p;
  Sleep(speed);
  if(p->x==foodx&&p->y==foody)
  {
      CreateFood();
      score+=10;
      setpos(60,7);
      printf("得分%d",score);
  }
  else{
  while(p->next->next!=NULL)
  p=p->next;
  setpos(p->x,p->y);
  printf(" ");
  free(p->next);
  p->next=NULL;
  p=head;
  }
  return 0;
}
void Welcome()
{DrawFrame();
 setpos(25,8);
 printf("press any key to start!");
 while((getch())==1)
 continue ;
 system("cls");
}
char GetKeyBoard() {//获取键盘输入
   char key=0;
   if(_kbhit()){
       key=_getch();
   } 
return key;

}
 void ConsoleSettings(){//设置控制台字体
 CONSOLE_CURSOR_INFO cursor;
 cursor.bVisible=FALSE;
 cursor.dwSize=sizeof(cursor);
 HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
 SetConsoleCursorInfo(handle, &cursor);
 CONSOLE_FONT_INFOEX cfi;
 cfi.cbSize=sizeof cfi;
 cfi.nFont=0;
 cfi.dwFontSize.X=20; 
 cfi.dwFontSize.Y=20;
 cfi.FontFamily=FF_DONTCARE;
 cfi.FontWeight=FW_NORMAL;
 wcscpy_s(cfi.FaceName,_countof(cfi.FaceName),L"Raster");
 SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE),FALSE,&cfi);
 }
void free_snake(Snake*head)
 {if(head==NULL||head->next==NULL){
     return;
 }
 while((p=head)!=NULL)
 {head=head->next;
 free(p);
 }
 }
 void Restart(){
     while(1)
     {
      setpos(60,8);
      printf("Try again? y/n");
      flag:
      getch();
      if(getch()=='y')
    {
     system("cls");
     score=0;
      main();
    } 
    if(getch()=='n')
    { exit (0);
    }
    else 
    {setpos(60,9);
    printf("please choose one right key");
    goto flag;
    }    
    
     }
 } 

感谢观看!take care of yourself and be well!文章来源地址https://www.toymoban.com/news/detail-537274.html

到了这里,关于贪吃蛇实验报告的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 贪吃蛇项目(基于C语言和数据结构中的链表)

    首先先建立3个文件。 Snake.h 函数的声明 Snake.c 函数的定义 Test.c     贪吃蛇的测试    我们分析这整个项目 首先在我们实现游戏开始的部分之前,我们要先创建贪吃蛇的节点,再由此创建整个贪吃蛇所包含的一些信息: 我们枚举一下这个贪吃蛇中所有的一些状态: 然后我们

    2024年02月20日
    浏览(57)
  • Discuz论坛网站标题栏Powered by Discuz!版权信息如何去除或是修改?

    当我们搭建好DZ论坛网站后,为了美化网站,想把标题栏的Powered by Discuz!去除或是修改,应该如何操作呢?今天飞飞和你分享,在操作前务必把网站源码和数据库都备份到本地或是网盘。   Discuz的版权信息存在两处地方,一个是标题栏,一个是底部。一般为了美化修改个标

    2024年02月08日
    浏览(82)
  • (C#) IIS 响应标头过滤敏感信息(如:Server/X-Powered-By等) 运维知识

    再一次净网行动中,客户要求安全改造发现了接口请求的header标头中出现如图中的敏感信息。   其意义在于告知浏网站是用什么语言或者框架编写的。解决办法就是修改该响应头为一个错误的值,将攻击者导向一个错误的方向。 这里只说windows 的iis环境,不考虑其他服务器的

    2024年02月11日
    浏览(73)
  • C语言实验报告范例

    一, 实验类型:设计型 二, 实验室: 三, 指导老师: 四, 日期: 五, 实验名称:if分支语句的嵌套 六, 实验目的: 1, 学习if嵌套结构,能够用C语言编程解决日常生活的实例 2, 明确if语句在实现分支结构控制语句方面的特点和优势 3, 熟练掌握关系运算符、关系表达

    2023年04月24日
    浏览(35)
  • 银行家算法的实验报告

    一、实验内容 银行家算法是避免死锁的一种重要方法,本实验要求编写和调试一个简单的银行家算法程序。 1.设计进程对各类资源最大申请表示及初值的确定。 2.设定系统提供资源的初始状况。 3.设定每次某个进程对各类资源的申请表示。 4.编制程序,依据银行家算法

    2023年04月26日
    浏览(45)
  • 银行家算法 源码+实验报告(用了自取)

    XI`AN TECHNOLOGICAL UNIVERSITY 课程设计报告 实验课程名称 操作系统—银行家算法     专    业 :计算机科学与技术          班    级 :                姓    名 :                   学    号 :          实验学时 :                     

    2024年02月09日
    浏览(42)
  • 数据结构实验报告(四)——查找和排序算法

    1. 掌握顺序查找技术和拆半查找技术以及部分排序算法的设计思想; 2. 掌握查找、部分排序算法的实现与执行过程。 查找算法 1.顺序查找: 从数组第一个元素开始逐个比较,找到后返回相应下标。 2.折半查找: 从数组中间开始比较,如果需查找值比中间值大,则在中间值右

    2024年02月07日
    浏览(44)
  • 中北大学算法分析与设计实验报告六(最大团问题)

    1.实验名称 实验六 回溯与分支限界算法实验 2.实验目的 题目:最大团问题 强化学生利用回溯算法和优化处理实际问题的能力。 3.训练知识点集群 (1)根据实验内容设计算法伪代码进行算法描述; (2)利用C++/C/Java等编程语言对算法伪代码进行工程化实现; (3)输入测试用

    2024年02月06日
    浏览(42)
  • 实验报告——基于Dijsktra算法的最短路径求解

    一个不知名大学生,江湖人称菜狗 original author: jacky Li Email : 3435673055@qq.com Last edited: 2022.12.3   目录 一、实验目的 二、实验设备 三、实验内容 【问题描述】 【输入要求】 【输出要求】 【输入样例】 【输出样例】 四、实验提示 五、实验步骤 5.1 六、实验结果 6.1程序完成后

    2024年02月07日
    浏览(47)
  • 中北大学算法分析与设计实验报告三(数字旋转方阵)

    1.实验名称 实验三 分治与减治算法实验 2.实验目的 (1)掌握分治法的设计思想; (2)掌握数字旋转方阵的具体实现过程; (3)熟练掌握二维数组的使用方法; (4)在掌握的基础上编程实现数字旋转方阵的实现过程。 3.训练知识点集群 (1)根据实验内容设计算法伪代码

    2023年04月08日
    浏览(76)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包