制作游戏“三连冠”遇到了这样一个问题。我需要像这样销毁组:
Буква T: Буква L: Знак +:
1 1 1 1 0 0 0 1 0
0 1 0 1 0 0 1 1 1
0 1 0 1 1 1 0 1 0
其中一个是相同颜色的块,而零是其他一些。而且,这些字母可以旋转 90、-90、180 度。
到目前为止,我已经能够让程序明白,某个组合是这样一个字母:
// Определяем, сколько точек есть на одной линии при определенном X и Y
// conn - это массив Vector2Int единичек
Dictionary<int, int> dictX, dictY;
dictX = dictY = new Dictionary<int, int>();
for (int i = 0; i < conn.Length; i++)
{
if (!dictX.ContainsKey(conn[i].x))
dictX.Add(conn[i].x, 1);
else dictX[conn[i].x]++;
if (!dictY.ContainsKey(conn[i].y))
dictY.Add(conn[i].y, 1);
else dictY[conn[i].y]++;
}
if (dictX.ContainsValue(3) && dictY.ContainsValue(3))
return true;
else return false;
如果 3x3 数组包含一列 3 个 1 + 一行 3 个 1,则此函数返回 true。
不过,除了简单的破坏之外,我还想加一个特殊的加成,激活时会爆炸——这现在不那么重要了。我希望在这些线和一列 3 条线的交汇处形成这个奖金。那是:
2 : 1 1 1
1 : 1 0 0
0 :1 0 0
__ 0_1_2 _
奖金应出现在坐标 (0,2) 中 - 在交叉点处。
所以,我不明白如何找到这个交叉路口。为了不毫无根据和“没有自己的意识形态”,我可以说有一个想法来考虑那个(X,Y)的交集,在
(X,1) == 1 && (X, 2) == 1 && (X, 3) == 1... && (1, Y) == 1 && (2, y) == 1 && (3, Y) == 1...
但我不知道如何确切地实施它。我将添加我将列表提供给我指定的函数的输入。我用递归填充它。它存储了与我开始查看的与它直接接触或通过直接接触的那些间接接触的块相同颜色的所有块的位置;那些与那些直接接触的人接触的人,等等。简而言之,对于这样的数组:
1 1 0 0
0 1 0 1
0 1 0 0
1 1 0 0
conn = { (0,0), (0,3), (1,0), (1,1), (1,2), (1,3) } 如果从左下角开始搜索。
更新: conn 数组不必是 3x3。例如,它可以是这样的:
1 0 0 0
1 0 1 1
1 1 1 0
在这种情况下,必须再次删除字母 L,以便我们得到:
* 0 0 0
* 0 1 1
* * * 0
* 标记那些已被删除的块,因为它们组成了字母 L。
将每个可能的选项描述为一个单独的选项既困难又毫无意义。
找到所有 3+ 行!通过水平和垂直梳理整个阵列非常简单。您将找到的组写入对象
Figure。我们得到
List<Figure> Figures,它可以相交。我们将每个与每个进行比较,如果它们相交,我们将两个中的一个新图形写入一个数组,并在创建它的那些中List<Figure> CombineFigures留下指向这个新图形的链接( )。Contains结果,结果将是 all
CombineFiguresand allFigures没有组合 (Contains == null)。一切都适用于任何组合,即使这样
额头的解决方案之一。也许还有更优雅的方式。
conn搜索是否包含Vector2Int通过稍微扩展比较方法,您可以教这个东西不仅可以使用二进制数组,还可以使用 int 数组,以便一次搜索整个字段上的数字。