首页 后端开发 C#.Net教程 c++贪吃蛇代码是什么

c++贪吃蛇代码是什么

Aug 22, 2020 am 09:42 AM
c++ 贪吃蛇

c++贪吃蛇代码是【snake_position position[(N-2)*(N-2)+1],void snake_position::initialize(int &j),{x = 1;y = j;}char s[N][N]】。

c++贪吃蛇代码是什么

【相关学习推荐:C视频教程

分析思路

下面就来讲讲贪吃蛇的整个设计思路:

一、

           贪吃蛇的特点是随机产生食物后,然后通过上下左右地方向键来控制贪吃蛇的移动,

当碰到食物时,便把它吃掉,从而身体长度增加一个,这里便采用“#”作为蛇头,”*”作为蛇身和食物。

           因此我便想到,产生的食物,是如何达到随机的目的呢?通过查阅资料得知,在time.h头文件中,定义了通过rand()函数来产生随机数。下面是相关知识:

概述

rand()函数是产生随机数的一个随机函数。C语言里还有srand()函数等。

详述

(1)使用该函数首先应在开头包含头文件stdlib.h

#include(C++建议使用#include,下同)

(2)在标准的C库中函数rand()可以生成0~RAND_MAX之间的一个随机数,其中RAND_MAX是stdlib.h 中定义的一个整数,它与系统有关。

(3)rand()函数没有输入参数,直接通过表达式rand()来引用;例如可以用下面的语句来打印两个随机数:

printf("Random numbers are: %i %i\n",rand(),rand());
登录后复制

(4)因为rand()函数是按指定的顺序来产生整数,因此每次执行上面的语句都打印相同的两个值,所以说C语言的随机并不是真正意义上的随机,有时候也叫伪随机数。

(5)为了使程序在每次执行时都能生成一个新序列的随机值,我们通常通过为随机数生成器提供一粒新的随机种子。函数srand()(来自stdlib.h)可以为随机数生成器播散种子。只要种子不同rand()函数就会产生不同的随机数序列。srand()称为随机数生成器的初始化器。

由于一开始没有使用srand()函数,多次运行后发现,每次打开运行后产生的食物位置都是一致的,并没有真正达到随机的目的。因此使用srand()函数,又通过time()函数来每次调用一个系统时间来作为srand()的种子。由于每次调用的系统时间并不相同,所以每次的种子也就不相同,从而使得rand()函数达到了随机数的目的。下面是time()函数相关知识:

time() 函数返回自 Unix 纪元(January 1 1970 00:00:00 GMT)起的当前时间的秒数。

主要用来获取当前的系统时间,返回的结果是一个time_t类型,其值表示从UTC(Coordinated Universal Time)时间1970年1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻的秒数。然后调用localtime函数将time_t所表示的UTC时间转换为本地时间(我们是+8区,比UTC多8个小时)并转成struct tm类型,该类型的各数据成员分别表示年月日时分秒。需要包含头文件<time.h>

C标准库函数

time_t time(time_t *t);
登录后复制

如果t是空指针,直接返回当前时间。如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间。

这样便通过rand()函数产生了随机数,对其进行取模,便得到一定范围内的随机数了。

二、

然后便是吃食的问题了,当蛇头遇到一个食物时(食物在贪吃蛇前进的方向上),便将该食物变为蛇头,然后将原先的蛇头变为蛇身,从而达到了吃食的目的。

那如果没有碰到食物呢?就按照原来的方向或者键盘按下的方向继续前进就是了。

三、

下面就是实现的问题了,如何将每个动态都展现出来呢?就是说贪吃蛇是一下一下往前移动的,这个又是如何实现的呢?

这里我使用了clock()函数,下面是相关知识:

clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t。在MSDN中,查得对clock函数定义如下:

clock_t clock(void) ;
登录后复制

简单而言,就是该程序从启动到函数调用占用CPU的时间。这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock);若挂钟时间不可取,则返回-1。其中clock_t是用来保存时间的数据类型。

因此,通过定义

int start = clock();while(clock()-start<=gamespeed);
登录后复制

这样一个方式来达到了延时的目的,延时的时间则根据gamespeed的值来确定,当gamespeed值越小时,延时时间越短。经过延时后,再执行下一步代码,从而实现了贪吃蛇自动前进的功能和控制其前进的速度啦。

然而,仅仅有这些还是不行的,还需要解决输出问题。

通过查阅资料得知,system(“cls”);具有清屏的功能,清除当前屏幕上的内容,进行下一步的输出,因此我便使用了每动一下都要进行清屏,然后将贪吃蛇棋盘整个画面进行输出。

四、

为了增加游戏的娱乐性,我又从中加入了等级选择功能,通过输入数字来选择等级,等级越高,贪吃蛇移动速度越快,而且得分越高。得分规则:score += grade*20;

考虑到游戏的功能性,在游戏结束后输出得分情况,并提示是否继续游戏,而不是直接退出游戏,这样用户就不必每次游戏失败后重新打开程序进行游戏,而是通过选择的方式决定继续游戏或者退出游戏。

而且加入暂停功能,当玩家玩累了,需要暂停的时候,按下空格(space)键实现暂停,

但由于我的原因,无法解决需要按两下空格才能继续游戏的bug,就暂定为按两下空格键继续游戏吧。

#include <windows.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <cstring>
#include <cstdio>
#include <iostream>
#define  N 22
using namespace std;
 
    int gameover;
 
    int x1, y1; // 随机出米
 
    int x,y;
 
    long start;
 
//=======================================
//类的实现与应用initialize
//=======================================
 
//下面定义贪吃蛇的坐标类
class snake_position
{
public:
 
    int x,y;      //x表示行,y表示列
 
    snake_position(){};
 
    void initialize(int &);//坐标初始化
 
 
};
 
snake_position position[(N-2)*(N-2)+1]; //定义贪吃蛇坐标类数组,有(N-2)*(N-2)个坐标
 
void snake_position::initialize(int &j)
{
        x = 1;
 
        y = j;
}
 
 
//下面定义贪吃蛇的棋盘图
 
class snake_map
{
 
private:
 
    char s[N][N];//定义贪吃蛇棋盘,包括墙壁。
 
    int grade, length;
 
    int gamespeed; //前进时间间隔
 
    char direction; // 初始情况下,向右运动
 
    int head,tail;
 
    int score;
 
    bool gameauto;
 
public:
 
    snake_map(int h=4,int t=1,int l=4,char d=77,int s=0):length(l),direction(d),head(h),tail(t),score(s){}
 
    void initialize();   //初始化函数
 
    void show_game();
 
    int updata_game();
 
    void setpoint();
 
    void getgrade();
 
    void display();
 
 
};
 
//定义初始化函数,将贪吃蛇的棋盘图进行初始化
 
void snake_map::initialize()
{
    int i,j;
 
    for(i=1;i<=3;i++)
 
        s[1][i] = &#39;*&#39;;
 
    s[1][4] = &#39;#&#39;;
 
    for(i=1;i<=N-2;i++)
 
        for(j=1;j<=N-2;j++)
 
            s[i][j]=&#39; &#39;; // 初始化贪吃蛇棋盘中间空白部分
 
    for(i=0;i<=N-1;i++)
 
        s[0][i] = s[N-1][i] = &#39;-&#39;; //初始化贪吃蛇棋盘上下墙壁
 
    for(i=1;i<=N-2;i++)
 
        s[i][0] = s[i][N-1] = &#39;|&#39;; //初始化贪吃蛇棋盘左右墙壁
}
 
 
//============================================
//输出贪吃蛇棋盘信息
 
void snake_map::show_game()
 
{
 
    system("cls"); // 清屏
 
    int i,j;
 
    cout << endl;
 
    for(i=0;i<N;i++)
    {
 
        cout << &#39;\t&#39;;
 
        for(j=0;j<N;j++)
 
            cout<<s[i][j]<<&#39; &#39;; // 输出贪吃蛇棋盘
 
        if(i==2) cout << "\t等级:" << grade;
 
        if(i==6) cout << "\t速度:" << gamespeed;
 
        if(i==10) cout << "\t得分:" << score << "分" ;
 
        if(i==14) cout << "\t暂停:按一下空格键" ;
 
        if(i==18) cout << "\t继续:按两下空格键" ;
 
        cout<<endl;
    }
}
 
//输入选择等级
void snake_map::getgrade()
{
    cin>>grade;
 
    while( grade>7 || grade<1 )
    {
        cout << "请输入数字1-7选择等级,输入其他数字无效" << endl;
 
        cin >> grade;
    }
    switch(grade)
    {
        case 1: gamespeed = 1000;gameauto = 0;break;
 
        case 2: gamespeed = 800;gameauto = 0;break;
 
        case 3: gamespeed = 600;gameauto = 0;break;
 
        case 4: gamespeed = 400;gameauto = 0;break;
 
        case 5: gamespeed = 200;gameauto = 0;break;
 
        case 6: gamespeed = 100;gameauto = 0;break;
 
        case 7: grade = 1;gamespeed = 1000;gameauto = 1;break;
 
    }
 
}
 
//输出等级,得分情况以及称号
 
void snake_map::display()
{
 
    cout << "\n\t\t\t\t等级:" << grade;
 
    cout << "\n\n\n\t\t\t\t速度:" << gamespeed;
 
    cout << "\n\n\n\t\t\t\t得分:" << score << "分" ;
 
}
 
//随机产生米
void snake_map::setpoint()
{
    srand(time(0));
 
    do
    {
 
        x1 = rand() % (N-2) + 1;
 
        y1 = rand() % (N-2) + 1;
 
    }while(s[x1][y1]!=&#39; &#39;);
 
    s[x1][y1]=&#39;*&#39;;
}
 
char key;
 
int snake_map::updata_game()
{
    gameover = 1;
 
    key = direction;
 
    start = clock();
 
    while((gameover=(clock()-start<=gamespeed))&&!kbhit());
 
    //如果有键按下或时间超过自动前进时间间隔则终止循环
 
 
 
        if(gameover)
        {
 
            getch();
 
            key = getch();
        }
 
        if(key == &#39; &#39;)
 
        {
            while(getch()!=&#39; &#39;){};//这里实现的是按空格键暂停,按空格键继续的功能,但不知为何原因,需要按两下空格才能继续。这是个bug。
        }
 
        else
 
            direction = key;
 
        switch(direction)
        {
            case 72: x= position[head].x-1; y= position[head].y;break; // 向上
 
            case 80: x= position[head].x+1; y= position[head].y;break; // 向下
 
            case 75: x= position[head].x; y= position[head].y-1;break; // 向左
 
            case 77: x= position[head].x; y= position[head].y+1; // 向右
 
        }
 
        if(!(direction==72||direction==80||direction==75 ||direction==77))   // 按键非方向键
 
            gameover = 0;
 
        else if(x==0 || x==N-1 ||y==0 || y==N-1)   // 碰到墙壁
 
            gameover = 0;
 
        else if(s[x][y]!=&#39; &#39;&&!(x==x1&&y==y1))    // 蛇头碰到蛇身
 
            gameover = 0;
 
        else if(x==x1 && y==y1)
 
        { // 吃米,长度加1
 
            length ++;
 
            if(length>=8 && gameauto)
 
            {
 
                length -= 8;
 
                grade ++;
 
                if(gamespeed>=200)
 
                    gamespeed -= 200; // 改变贪吃蛇前进速度
 
                else
 
                    gamespeed = 100;
 
            }
 
            s[x][y]= &#39;#&#39;;  //更新蛇头
 
            s[position[head].x][position[head].y] = &#39;*&#39;; //吃米后将原先蛇头变为蛇身
 
            head = (head+1) % ( (N-2)*(N-2) );   //取蛇头坐标
 
            position[head].x = x;
 
            position[head].y = y;
 
            show_game();
 
            gameover = 1;
 
            score += grade*20;  //加分
 
            setpoint();   //产生米
 
        }
 
        else
        { // 不吃米
 
            s[position[tail].x][position[tail].y]=&#39; &#39;;//将蛇尾置空
 
            tail= (tail+1) % ( (N-2) * (N-2) );//更新蛇尾坐标
 
            s[position[head].x][position[head].y]=&#39;*&#39;;  //将蛇头更为蛇身
 
            head= (head+1) % ( (N-2) * (N-2) );
 
            position[head].x = x;
 
            position[head].y = y;
 
            s[position[head].x][position[head].y]=&#39;#&#39;; //更新蛇头
 
            gameover = 1;
 
        }
    return gameover;
 
}
//====================================
//主函数部分
//====================================
int main()
{
    char ctn = &#39;y&#39;;
 
    int nodead;
 
    cout<<"\n\n\n\n\n\t\t\t 欢迎进入贪吃蛇游戏!"<<endl;//欢迎界面;
 
    cout<<"\n\n\n\t\t\t 按任意键马上开始。。。"<<endl;//准备开始;;
 
    getch();
 
    while( ctn==&#39;y&#39; )
    {
        system("cls"); // 清屏
 
        snake_map snake;
 
        snake.initialize();
 
        cout << "\n\n请输入数字选择游戏等级:" << endl;
 
        cout << "\n\n\n\t\t\t1.等级一:速度 1000 \n\n\t\t\t2.等级二:速度 800 \n\n\t\t\t3.等级三:速度 600 ";
 
        cout << "\n\n\t\t\t4.等级四:速度 400 \n\n\t\t\t5.等级五:速度 200 \n\n\t\t\t6.等级六:速度 100 \n\n\t\t\t7.自动升级模式" << endl;
 
        snake.getgrade();//获取等级
 
        for(int i=1;i<=4;i++)
        {
            position[i].initialize(i);//初始化坐标
        }
 
        snake.setpoint();  // 产生第一个米
 
        do
        {
            snake.show_game();
 
            nodead = snake.updata_game();
 
        }while(nodead);
 
        system("cls"); //清屏
 
 
 
        cout << "\n\n\n\t\t\t\tGameover!\n\n"<<endl;
 
        snake.display();//输出等级/得分情况
 
        cout << "\n\n\n\t\t    是否选择继续游戏?输入 y 继续,n 退出" << endl;
 
        cin >> ctn;
 
    }
 
    return 0;
}
登录后复制

以上是c++贪吃蛇代码是什么的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

char在C语言字符串中的作用是什么 char在C语言字符串中的作用是什么 Apr 03, 2025 pm 03:15 PM

在 C 语言中,char 类型在字符串中用于:1. 存储单个字符;2. 使用数组表示字符串并以 null 终止符结束;3. 通过字符串操作函数进行操作;4. 从键盘读取或输出字符串。

在Docker环境中使用PECL安装扩展时为什么会报错?如何解决? 在Docker环境中使用PECL安装扩展时为什么会报错?如何解决? Apr 01, 2025 pm 03:06 PM

在Docker环境中使用PECL安装扩展时报错的原因及解决方法在使用Docker环境时,我们常常会遇到一些令人头疼的问�...

c上标3下标5怎么算 c上标3下标5算法教程 c上标3下标5怎么算 c上标3下标5算法教程 Apr 03, 2025 pm 10:33 PM

C35 的计算本质上是组合数学,代表从 5 个元素中选择 3 个的组合数,其计算公式为 C53 = 5! / (3! * 2!),可通过循环避免直接计算阶乘以提高效率和避免溢出。另外,理解组合的本质和掌握高效的计算方法对于解决概率统计、密码学、算法设计等领域的许多问题至关重要。

c语言多线程的四种实现方式 c语言多线程的四种实现方式 Apr 03, 2025 pm 03:00 PM

语言多线程可以大大提升程序效率,C 语言中多线程的实现方式主要有四种:创建独立进程:创建多个独立运行的进程,每个进程拥有自己的内存空间。伪多线程:在一个进程中创建多个执行流,这些执行流共享同一内存空间,并交替执行。多线程库:使用pthreads等多线程库创建和管理线程,提供了丰富的线程操作函数。协程:一种轻量级的多线程实现,将任务划分成小的子任务,轮流执行。

distinct函数用法 distance函数c  用法教程 distinct函数用法 distance函数c 用法教程 Apr 03, 2025 pm 10:27 PM

std::unique 去除容器中的相邻重复元素,并将它们移到末尾,返回指向第一个重复元素的迭代器。std::distance 计算两个迭代器之间的距离,即它们指向的元素个数。这两个函数对于优化代码和提升效率很有用,但也需要注意一些陷阱,例如:std::unique 只处理相邻的重复元素。std::distance 在处理非随机访问迭代器时效率较低。通过掌握这些特性和最佳实践,你可以充分发挥这两个函数的威力。

蛇形命名法在C语言中如何应用? 蛇形命名法在C语言中如何应用? Apr 03, 2025 pm 01:03 PM

C语言中蛇形命名法是一种编码风格约定,使用下划线连接多个单词构成变量名或函数名,以增强可读性。尽管它不会影响编译和运行,但冗长的命名、IDE支持问题和历史包袱需要考虑。

C  中releasesemaphore的用法 C 中releasesemaphore的用法 Apr 04, 2025 am 07:54 AM

C 中 release_semaphore 函数用于释放已获得的信号量,以便其他线程或进程访问共享资源。它将信号量计数增加 1,允许阻塞的线程继续执行。

Dev-C    版的问题 Dev-C 版的问题 Apr 03, 2025 pm 07:33 PM

Dev-C 4.9.9.2编译错误及解决方案在Windows11系统使用Dev-C 4.9.9.2编译程序时,编译器记录窗格可能会显示以下错误信息:gcc.exe:internalerror:aborted(programcollect2)pleasesubmitafullbugreport.seeforinstructions.尽管最终显示“编译成功”,但实际程序无法运行,并弹出“原始码档案无法编译”错误提示。这通常是因为链接器collect

See all articles