Voir si une certaine configuration de grille correspond à une certaine recette est simple si vous codez la grille 3x3 sous forme de chaîne et utilisez une correspondance d' expression régulière . Accélérer la recherche est une autre affaire, dont je parlerai à la fin. Lisez la suite pour plus d'informations.
Étape 1) Encoder la grille en tant que chaîne
Donnez simplement un identifiant de caractère à chaque type de cellule et concaténez tout dans cet ordre:
123
456 => 123456789
789
Et comme exemple plus concret, considérons la recette du bâton, dans laquelle W représente le bois et E la cellule vide (vous pouvez simplement utiliser un caractère vide ''):
EEE
WEE => EEEWEEWEE
WEE
Étape 2) Match Recipe using Regular Expression (ou String.Contains avec un peu de traitement sur les données)
En reprenant l'exemple ci-dessus, même si nous déplaçons la formation, il reste un motif dans la chaîne (WEEW complété par E des deux côtés):
EEW
EEW => EEWEEWEEE
EEE
Ainsi, peu importe où vous déplacez le bâton, il correspondra toujours à l'expression régulière suivante: /^E*WEEWE*$/
Les expressions régulières vous permettent également d’effectuer le comportement conditionnel que vous avez mentionné. Par exemple (recette préparée), si vous vouliez une pioche en fer ou en pierre pour obtenir le même résultat, à savoir:
III SSS
EWE or EWE
EWE EWE
Vous pouvez combiner les deux dans l'expression régulière: /^(III)|(SSS)EWEEWE$/
Des retournements horizontaux peuvent également être ajoutés tout aussi facilement (en utilisant l'opérateur |).
Edit: Quoi qu’il en soit, la partie regex n’est pas strictement nécessaire. C'est juste une façon d'encapsuler le problème dans une seule expression. Mais pour le problème d'emplacement de variable, vous pouvez également couper la chaîne de grille de tout espace de remplissage (ou E dans cet exemple) et faire un String.Contains (). Et pour le problème des ingrédients multiples ou les recettes en miroir, vous pouvez simplement les traiter comme des recettes multiples (c.-à-d. Séparées) avec le même résultat.
Étape 3) Accélération de la recherche
En ce qui concerne la réduction de la recherche, vous devrez créer une structure de données pour regrouper les recettes et faciliter la recherche. Traiter la grille en tant que chaîne présente également certains avantages :
Vous pouvez définir la "longueur" d'une recette comme étant la distance entre le premier caractère non vide et le dernier caractère non vide. Un simple Trim().Length()
vous donnerait cette information. Les recettes peuvent être regroupées par longueur et stockées dans un dictionnaire.
ou
Une autre définition de "longueur" pourrait être le nombre de caractères non vides. Rien d'autre ne change. Vous pouvez également regrouper les recettes selon ce critère.
Si le point 1 ne suffit pas, vous pouvez également regrouper les recettes en fonction du type de premier ingrédient figurant dans la recette. Cela serait aussi simple que de le faire Trim().CharAt(0)
(et d' éviter que Trim ne crée une chaîne vide).
Ainsi, par exemple, vous stockeriez des recettes dans un:
Dictionary<int, Dictionary<char, List<string>>> _recipes;
Et effectuez la recherche comme suit:
// 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
}
}