【问题标题】:How to properly implement cheat codes?如何正确实施作弊码?
【发布时间】:2010-03-24 10:29:24
【问题描述】:

一般来说,实现某种作弊码的最佳方式是什么? 我想到了 WinForms 应用程序,其中一个作弊码可以解锁一个复活节彩蛋,但实现细节并不相关。

我想到的最佳方法是为每个代码保留索引 - 让我们在一个虚构的 C# 应用程序中考虑著名的 DOOM 代码 - IDDQD 和 IDKFA。

string[] CheatCodes = { "IDDQD", "IDKFA"};
int[] CheatIndexes = { 0, 0 };
const int CHEAT_COUNT = 2;
void KeyPress(char c)
{
    for (int i = 0; i < CHEAT_COUNT; i++) //for each cheat code
    {
        if (CheatCodes[i][CheatIndexes[i]] == c)
        { //we have hit the next key in sequence
            if (++CheatIndexes[i] == CheatCodes[i].Length) //are we in the end?
            {
                //Do cheat work
                MessageBox.Show(CheatCodes[i]);
                //reset cheat index so we can enter it next time
                CheatIndexes[i] = 0; 
            }
        }
        else //mistyped, reset cheat index
            CheatIndexes[i] = 0; 
    }
}

这是正确的做法吗?

编辑:可能我应该做的最糟糕的事情就是将我脑海中出现的第一个作弊码作为示例。我真的不想想看到 Doom 的源代码或它们的实现,而是这个问题的通用解决方案。

【问题讨论】:

    标签: keyboard keystroke


    【解决方案1】:

    为什么不下载 DOOM 源代码并亲眼看看呢? =) http://www.doomworld.com/idgames/?id=14576

    【讨论】:

    • 基本上是一样的,只是结构更精细。但是 ID soft 还有什么可以期待的:)
    • 他们的代码确实让我对那个游戏有了全新的尊重。
    • 哈哈。我总是喜欢这样的聪明答案确实是解决问题的最佳方法+1
    【解决方案2】:

    我认为这个更容易理解,虽然你的原版可能会比这个更好:

    using System.Collections.Generic;
    
    void KeyPress(char c)
    {
        string[] cheatCodes = { "IDDQD", "IDKFA"};
        static Queue<char> buffer; //Contains the longest number of characters needed
        buffer.Enqueue(c);
        if (buffer.Count() > 5) //Replace 5 with whatever your longest cheat code is
            buffer.Dequeue();
        bufferString = new System.String(buffer.ToArray());
        foreach(string code in cheatCodes) {
            if (bufferString.EndsWith(code)) {
                //Do cheat work
            }
        }
    }
    

    【讨论】:

    • 但您的代码可能无法使用可变长度代码,对吧?
    • 我的错。我没有看到“EndsWith”部分;)
    • @Axarydax:开个玩笑,我稍后编辑了结尾部分。查看原件的编辑历史记录。
    • 你很幸运,我在编辑完成后阅读了你的评论 :)
    【解决方案3】:

    这里是来自末日源的 DOOM 作弊实现:

    #define SCRAMBLE(a) \
    ((((a)&1)<<7) + (((a)&2)<<5) + ((a)&4) + (((a)&8)<<1) \
     + (((a)&16)>>1) + ((a)&32) + (((a)&64)>>5) + (((a)&128)>>7))
    
    int cht_CheckCheat ( cheatseq_t* cht, char key )
    {
        int i;
        int rc = 0;
    
        if (firsttime)
        {
            firsttime = 0;
            for (i=0;i<256;i++) cheat_xlate_table[i] = SCRAMBLE(i);
        }
    
        if (!cht->p)
            cht->p = cht->sequence; // initialize if first time
    
        if (*cht->p == 0)
            *(cht->p++) = key;
        else if
            (cheat_xlate_table[(unsigned char)key] == *cht->p) cht->p++;
        else
            cht->p = cht->sequence;
    
        if (*cht->p == 1)
            cht->p++;
        else if (*cht->p == 0xff) // end of sequence character
        {
            cht->p = cht->sequence;
            rc = 1;
        }
    
        return rc;
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-01
      • 1970-01-01
      • 2022-12-22
      • 2020-11-22
      • 2010-11-16
      • 1970-01-01
      • 2013-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多