搜尋
首頁後端開發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></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
C#.NET:探索核心概念和編程基礎知識C#.NET:探索核心概念和編程基礎知識Apr 10, 2025 am 09:32 AM

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

測試C#.NET應用程序:單元,集成和端到端測試測試C#.NET應用程序:單元,集成和端到端測試Apr 09, 2025 am 12:04 AM

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

高級C#.NET教程:ACE您的下一次高級開發人員面試高級C#.NET教程:ACE您的下一次高級開發人員面試Apr 08, 2025 am 12:06 AM

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

C#.NET面試問題和答案:提高您的專業知識C#.NET面試問題和答案:提高您的專業知識Apr 07, 2025 am 12:01 AM

C#.NET面試問題和答案包括基礎知識、核心概念和高級用法。 1)基礎知識:C#是微軟開發的面向對象語言,主要用於.NET框架。 2)核心概念:委託和事件允許動態綁定方法,LINQ提供強大查詢功能。 3)高級用法:異步編程提高響應性,表達式樹用於動態代碼構建。

使用C#.NET建築微服務:建築師實用指南使用C#.NET建築微服務:建築師實用指南Apr 06, 2025 am 12:08 AM

C#.NET是構建微服務的熱門選擇,因為其生態系統強大且支持豐富。 1)使用ASP.NETCore創建RESTfulAPI,處理訂單創建和查詢。 2)利用gRPC實現微服務間的高效通信,定義和實現訂單服務。 3)通過Docker容器化微服務,簡化部署和管理。

C#.NET安全性最佳實踐:防止常見漏洞C#.NET安全性最佳實踐:防止常見漏洞Apr 05, 2025 am 12:01 AM

C#和.NET的安全最佳實踐包括輸入驗證、輸出編碼、異常處理、以及身份驗證和授權。 1)使用正則表達式或內置方法驗證輸入,防止惡意數據進入系統。 2)輸出編碼防止XSS攻擊,使用HttpUtility.HtmlEncode方法。 3)異常處理避免信息洩露,記錄錯誤但不返回詳細信息給用戶。 4)使用ASP.NETIdentity和Claims-based授權保護應用免受未授權訪問。

c語言中:是什麼意思c語言中:是什麼意思Apr 03, 2025 pm 07:24 PM

C 語言中冒號 (':') 的含義:條件語句:分隔條件表達式和語句塊循環語句:分隔初始化、條件和增量表達式宏定義:分隔宏名和宏值單行註釋:表示從冒號到行尾的內容為註釋數組維數:指定數組的維數

c語言中a  是什麼意思c語言中a 是什麼意思Apr 03, 2025 pm 07:21 PM

C 語言的 a 是後增運算符,其運作機制包括:先獲取變量 a 的值。將 a 的值增加 1。返回自增後的 a 的值。

See all articles

熱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.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境