2010-03-24 11 views
9

quelle serait la meilleure façon d'implémenter les codes de triche en général? J'ai l'application WinForms à l'esprit, où un code de triche débloquerait un oeuf de Pâques, mais les détails de mise en œuvre ne sont pas pertinents. La meilleure approche qui me vient à l'esprit est de garder un index pour chaque code - considérons les célèbres codes DOOM - IDDQD et IDKFA, dans une application C# fictive.Comment mettre en œuvre correctement les codes de triche?

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; 
    } 
} 

Est-ce la bonne façon de le faire? Edit: Probablement la pire chose que j'aurais dû faire était d'inclure les premiers codes de triche qui viennent du haut de ma tête à titre d'exemple. Je vraiment n'a pas voulez voir le code source de Doom ou leur mise en œuvre, mais une solution générale à ce problème. Pourquoi ne pas télécharger la source DOOM et voir par vous-même?

Répondre

6

Je pense que celui-ci est un peu plus facile à comprendre, bien que votre original sera probablement un meilleur rendement que celui-ci:

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 
     } 
    } 
} 
+0

mais votre code ne fonctionnera probablement pas avec des codes de longueur variable, n'est-ce pas? – Axarydax

+0

@Axarydax: Bien sûr cela fonctionne. Vérifiez à nouveau :) –

+0

mon mauvais. Je n'ai pas vu la partie "EndsWith";) – Axarydax

11
+0

fondamentalement c'est à peu près le même, quoique plus structuré et élaboré. Mais quoi d'autre peut-on attendre de l'ID soft :) – Axarydax

+1

Leur code me donne en effet un tout nouveau respect pour ce jeu. – MHarrison

+0

Haha. J'adore quand une réponse smart-ass comme ceci est vraiment la meilleure solution au problème +1 –

1

ici est la mise en œuvre tricher DOOM de la source 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; 
}