Zu sehen, ob eine bestimmte Gitterkonfiguration mit einem bestimmten Rezept übereinstimmt, ist einfach, wenn Sie das 3x3-Gitter als Zeichenfolge codieren und eine Übereinstimmung mit regulären Ausdrücken verwenden . Das Nachschlagen zu beschleunigen ist eine andere Sache, über die ich am Ende sprechen werde. Lesen Sie weiter für weitere Informationen.
Schritt 1) Codiere das Gitter als String
Geben Sie einfach eine Zeichen-ID für jeden Zellentyp an und verknüpfen Sie alles in dieser Reihenfolge nebeneinander:
123
456 => 123456789
789
Betrachten Sie als konkretes Beispiel das Stabrezept, bei dem W für Holz steht und E eine leere Zelle ist (Sie könnten einfach ein leeres Zeichen '' verwenden):
EEE
WEE => EEEWEEWEE
WEE
Schritt 2) Rezept mit regulärem Ausdruck abgleichen (oder String.Contains mit ein wenig Verarbeitung der Daten)
Selbst wenn wir die Formation bewegen, befindet sich im obigen Beispiel noch ein Muster in der Zeichenfolge (WEEW wird auf beiden Seiten mit E aufgefüllt):
EEW
EEW => EEWEEWEEE
EEE
Unabhängig davon, wo Sie den Stick bewegen, entspricht er dem folgenden regulären Ausdruck: /^E*WEEWE*$/
Mit regulären Ausdrücken können Sie auch das von Ihnen erwähnte bedingte Verhalten ausführen. Zum Beispiel (erfundenes Rezept), wenn Sie eine Spitzhacke aus Eisen oder Stein haben möchten , um das gleiche Ergebnis zu erzielen:
III SSS
EWE or EWE
EWE EWE
Sie können beide zu einem regulären Ausdruck kombinieren: /^(III)|(SSS)EWEEWE$/
Genauso einfach können auch horizontale Flips hinzugefügt werden (auch mit dem Operator |).
Bearbeiten: Wie auch immer, der Regex-Teil ist nicht unbedingt erforderlich. Dies ist nur eine Möglichkeit, das Problem in einem einzelnen Ausdruck zu kapseln. Für das Problem mit der variablen Position können Sie jedoch auch die Rasterzeichenfolge aller Auffüllbereiche (oder in diesem Beispiel die von "E") abschneiden und ein String.Contains () ausführen. Und für das Problem mit mehreren Zutaten oder die gespiegelten Rezepte könnten Sie einfach alle als mehrere (dh separate) Rezepte mit derselben Ausgabe behandeln.
Schritt 3) Beschleunigen der Suche
Um die Suche zu reduzieren, müssen Sie eine Datenstruktur erstellen, um Rezepte zu gruppieren und bei der Suche zu helfen. Das Behandeln des Gitters als Zeichenfolge hat auch hier einige Vorteile :
Sie können die "Länge" eines Rezepts als den Abstand zwischen dem ersten nicht leeren Zeichen und dem letzten nicht leeren Zeichen definieren. Ein einfacher Trim().Length()
würde Ihnen diese Informationen geben. Rezepte können nach Länge gruppiert und in einem Wörterbuch gespeichert werden.
oder
Eine alternative Definition von "Länge" könnte die Anzahl nicht leerer Zeichen sein. Sonst ändert sich nichts. Sie können Rezepte auch nach diesen Kriterien gruppieren.
Wenn Punkt Nummer 1 nicht ausreicht, können die Rezepte auch nach der Art der ersten Zutat, die im Rezept enthalten ist, weiter gruppiert werden. Dies wäre so einfach wie das Ausführen Trim().CharAt(0)
(und das Sichern gegen Trimmen, was zu einer leeren Zeichenfolge führt).
So würden Sie beispielsweise Rezepte speichern in:
Dictionary<int, Dictionary<char, List<string>>> _recipes;
Und führen Sie die Suche wie folgt aus:
// A string encode of your current grid configuration
string grid;
// Get length and first char in our grid
string trim = grid.Trim();
int length = trim.Length();
char firstChar = length==0 ? ' ' : trim[0];
foreach(string recipe in _recipes[length][firstChar])
{
// Check for a match with the recipe
if(Regex.Match(grid, recipe))
{
// We found a matching recipe, do something with it
}
}