如果将3x3网格编码为字符串并使用正则表达式匹配,则查看特定网格配置是否匹配特定配方非常简单。加快查找速度是另一回事,我将在最后讨论。继续读以获取更多信息。
步骤1)将表格编码为字符串
只需为每种类型的单元格提供一个字符ID,然后按此顺序并排连接所有内容:
123
456 => 123456789
789
再举一个更具体的例子,考虑棒配方,其中W代表木头,E是一个空单元格(您可以简单地使用一个空char''):
EEE
WEE => EEEWEEWEE
WEE
第2步)使用正则表达式(或字符串)匹配配方。包含一些对数据的处理
继续上面的示例,即使我们移动编队,字符串中仍然有一个模式(WEEW两侧都用E填充):
EEW
EEW => EEWEEWEEE
EEE
因此,无论您将摇杆移动到何处,它仍将与以下正则表达式匹配: /^E*WEEWE*$/
正则表达式还使您可以执行所提到的条件行为。例如(配方),如果您想要用铁或石头制成的镐来得到相同的结果,即:
III SSS
EWE or EWE
EWE EWE
您可以将两者合并为正则表达式: /^(III)|(SSS)EWEEWE$/
水平翻转也可以轻松添加(也可以使用|运算符)。
编辑: 无论如何,正则表达式部分不是严格必需的。这只是将问题封装在单个表达式中的一种方法,但是对于变量位置问题,您也可以修剪任何填充空间的网格字符串(在此示例中为E)并执行String.Contains()。对于多成分问题或镜像配方,您可以将它们全部作为具有相同输出的多个(即单独的)配方进行处理。
步骤3)加快查找
至于减少搜索,您将需要创建一些数据结构以将配方分组在一起并帮助查找。将网格视为字符串在这里也有一些优点:
您可以将配方的“长度”定义为第一个非空字符与最后一个非空字符之间的距离。一个简单的Trim().Length()
将为您提供此信息。食谱可以按长度分组并存储在字典中。
要么
“长度”的另一种定义可以是非空字符的数量。没有其他改变。您也可以按照此标准对配方进行分组。
如果点号1还不够,则还可以根据配方中出现的第一种成分的类型对配方进行进一步分组。这和操作一样简单Trim().CharAt(0)
(并防止Trim导致空字符串)。
因此,例如,您将配方存储在:
Dictionary<int, Dictionary<char, List<string>>> _recipes;
并执行类似以下的查找:
// 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
}
}