2010-03-24 6 views
9

quale sarebbe il modo migliore per implementare una specie di cheat in generale? Ho in mente l'applicazione WinForms, in cui un codice cheat sbloccherebbe un easter egg, ma i dettagli dell'implementazione non sono rilevanti.Come implementare correttamente i cheat codes?

L'approccio migliore che mi viene in mente è quello di mantenere l'indice per ogni codice - prendiamo in considerazione i famosi codici DOOM - IDDQD e IDKFA, in un'app C# fittizia.

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

È questo il modo giusto per farlo?

Modifica: Probabilmente la cosa peggiore che avrei dovuto fare era includere i primi trucchi che venivano dalla cima della mia testa come esempio. Io davvero non ho voglio vedere il codice sorgente di Doom o la loro implementazione, ma la soluzione generale a questo problema.

risposta

6

Penso che questo sia un po 'più facile da capire, anche se l'originale sarà probabilmente un rendimento migliore rispetto a questo:

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

ma il tuo codice probabilmente non funzionerà con codici a lunghezza variabile, vero? – Axarydax

+0

@Axarydax: certo che funziona. Controlla di nuovo :) –

+0

il mio male. Non ho visto la parte "EndsWith";) – Axarydax

11

Perché non scaricare la sorgente DOOM e vedere di persona? =) http://www.doomworld.com/idgames/?id=14576

+0

in pratica è più o meno lo stesso, anche se più strutturato ed elaborato. Ma che altro ci si può aspettare da ID soft :) – Axarydax

+1

Il loro codice mi sta davvero dando un nuovo rispetto per quel gioco. – MHarrison

+0

Haha. Mi piace sempre quando una risposta furba come questa è davvero la migliore soluzione al problema +1 –

1

Ecco l'DOOM imbrogliare implementazione dalla sorgente di 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; 
}