簡體   English   中英

有沒有更優雅的方法來實現C ++游戲的“作弊代碼”實現?

[英]Is there a more elegant way to achieve a “cheat code” implementation for a game in C++?

我通過研究一個簡單的2D游戲項目來學習C ++。 我已經嘗試實現一些作弊功能,但是我是弦操作的新手。 我敢肯定,比下面的代碼有一種更優雅的方式來實現我想要的功能。

根據要求, stringBuffer只是一個包含最后按下的12個字符的字符串。 我將其作為前綴,因為稍后會通過調整大小對其進行修整,因此,我的作弊技巧必須倒退。 我對字符串操作非常了解,我知道這里有問題,這就是為什么我要求對其進行研究並可能加以改進。

//The following code is in my keyPressed function
cheatBuffer = (char)key + cheatBuffer;
cheatBuffer.resize(12);
string tempBuffer;
string cheats[3] = {"1taehc","2taehc","3taehc"};
for(int i = 0;i < 3;i++){
    tempBuffer = cheatBuffer;
    tempBuffer.resize(cheats[i].size());
    if(cheats[i] == tempBuffer){
        switch(i){
            case 1:
                //activate cheat 1
                break;
            case 2:
                //active cheat 2
                break;
            case 3:
                //active cheat 3
                break;
        }
    }
}

代碼分別是“ cheat1”,“ cheat2”和“ cheat3”。 我忍不住想這會好得多。 任何見識將不勝感激。

您可能要考慮使用:

std::map<std::string, std::function<void ()>> (如果可以使用C ++ 0x)

std::map<std::string, std::tr1::function<void ()>> (如果可以使用TR1)

std::map<std::string, boost::function<void ()>> (如果可以使用Boost的話)

(當然,函數的簽名可以不同)

使用C ++ 0x的示例

#include <map>
#include <functional>
#include <string>
#include <iostream>

typedef std::map<std::string, std::function<void ()>> cheat_map;

inline void cheat1()
{
    std::cout << "cheat 1 used!" << std::endl;
}

inline void cheat2()
{
    std::cout << "cheat 2 used!" << std::endl;
}

int main()
{
    cheat_map myCheats;
    myCheats.insert(std::pair<std::string, std::function<void ()>>("cheat1", std::function<void ()>(cheat1)));
    myCheats.insert(std::pair<std::string, std::function<void ()>>("cheat2", std::function<void ()>(cheat2)));

    std::string buffer;
    while (std::getline(std::cin, buffer)) {
        if (!std::cin.good()) {
            break;
        }

        cheat_map::iterator itr = myCheats.find(buffer);
        if (itr != myCheats.end()) {
            myCheats[buffer]();
        }
    }
}

輸入:

notourcheat
cheat1
cheat2
cheat1

輸出:

cheat 1 used!
cheat 2 used!
cheat 1 used!

現場演示

我將字符串存儲在一個trie中:

http://en.wikipedia.org/wiki/特里

(在Wikipedia文章中,也有指向C ++實現的鏈接)。

在特里樹的葉子中,您可以添加有關作弊的其他數據。

查找字符串時,只需檢查字符串中是否包含作弊代碼即可。 如果是,您將獲得其他數據(例如,指向執行您要執行的功能的函數指針;或者更多面向對象:指向類實例的指針,當您調用其成員函數之一執行“作弊”東西”)。

該代碼可以通過幾種方式進行改進。

使您的不可變字符串const靜態

static const std::string const foo[] = { "1taehc", "2taehc", "3taehc" };

因此,不必每次都在“ KeyPressed”處理程序中分配它們。

將每個作弊項與您可以在case語句中使用的值相關聯

我不認為所有其他有助於switch邏輯都是一個好主意。 像這樣的事情呢:

const int CHEAT_ONE = 1;
const int CHEAT_TWO = 2;
const int CHEAT_THREE = 3;

static const std::pair<std::string, int> const foo[] = { 
    std::make_pair("1taehc", CHEAT_ONE),
    std::make_pair("2taehc", CHEAT_TWO),
    std::make_pair("3taehc", CHEAT_THREE),
};

這樣,您將獲得一個整數,可以將其用作每個作弊代碼的大小寫標簽。

搜索作弊以激活

您希望能夠搜索已輕松激活的作弊代碼。 讓我們分解std::pair實例,並使用std::map代替。

const int CHEAT_ONE = 1;
const int CHEAT_TWO = 2;
const int CHEAT_THREE = 3;

std::pair<std::string, int> cheatcodes[] = {
    std::make_pair("1taehc", CHEAT_ONE),
    std::make_pair("2taehc", CHEAT_TWO),
    std::make_pair("3taehc", CHEAT_THREE),
};

std::map<std::string, int> cheatmap(
    cheatcodes, cheatcodes + sizeof (cheatcodes) / sizeof (cheatcodes[0]));

現在,假設candidate是您的按鍵緩沖區,您可以

auto pair = cheatmap.find(candidate);
if (pair != cheatmap.end()) {
    switch(pair->second) {
        case CHEAT_ONE:
        case CHEAT_TWO:
        case CHEAT_THREE:
    }
}

我將以這種方式執行此操作:當首先按下某個特定按鈕(例如Enter)時,它將開始填充cheatBuffer,並且在緩沖區末尾填充一個字符之后,它將使用該緩沖區來檢查值是否為它存在於std :: map中。 當該值存在時,它將執行一個函數,該指針存儲在std :: map中。

這可能是多余的,並且工作量過多,但是您可以使用有限狀態機來處理您的鍵輸入,而不是存儲鍵歷史記錄,而是存儲當前狀態。 您的起始狀態0表示沒有按下任何適用的鍵。 'c'將使您進入狀態1,其中'h'將使您進入狀態2,'c'將使您進入狀態1,其他任何情況都將使您回到0。打開當前狀態,並在其中內部,打開提供的字符以查看您轉換到的狀態。 如果是最終狀態,則執行作弊並過渡回0。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM