2010-03-24 7 views
9

Was wäre der beste Weg, um Art von Cheat-Codes im Allgemeinen zu implementieren? Ich habe WinForms Anwendung im Auge, wo ein Cheat-Code ein Osterei entsperren würde, aber die Implementierungsdetails sind nicht relevant.Wie Cheat-Codes korrekt implementiert werden?

Der beste Ansatz, der mir in den Sinn kommt, ist, den Index für jeden Code zu behalten - lassen Sie uns die berühmten DOOM-Codes IDDQD und IDKFA in einer fiktiven C# -App betrachten.

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

Ist dies der richtige Weg?

Edit: Wahrscheinlich das Schlimmste, was ich hätte tun sollen, war, die ersten Cheat-Codes, die aus dem oberen Teil meines Kopfes kamen, als ein Beispiel zu nehmen. Ich wirklich nicht wollen Dooms Quellcode oder ihre Implementierung sehen, aber allgemeine Lösung für dieses Problem.

Antwort

6

Ich denke, dass dies ein bisschen leichter zu verstehen ist, wenn auch wahrscheinlich Ihre Originale als besser abschneiden werden diese:

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

, aber Ihr Code wird wahrscheinlich nicht mit Codes variabler Länge funktionieren, oder? – Axarydax

+0

@Axarydax: Sicher, es funktioniert. Überprüfen Sie noch einmal :) –

+0

mein schlechtes. Ich habe den "EndsWith" -Teil nicht gesehen;) – Axarydax

11

Warum nicht die DOOM-Quelle herunterladen und selbst sehen? =) http://www.doomworld.com/idgames/?id=14576

+0

im Grunde ist es ungefähr das gleiche, wenn auch strukturierter und aufwendiger. Aber was kann man sonst noch von ID soft erwarten? – Axarydax

+1

Ihr Code gibt mir tatsächlich einen ganz neuen Respekt für dieses Spiel. – MHarrison

+0

Haha. Ich liebe immer, wenn eine kluge Antwort wie diese wirklich die beste Lösung für das Problem ist +1 –

1

hier ist die DOOM betrug Implementierung des Untergang Quelle:

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