今天看啥  ›  专栏  ›  尝山爪子茸

连连看算法——布局生成与相连消除

尝山爪子茸  · 掘金  ·  · 2021-02-12 22:40
阅读 56

连连看算法——布局生成与相连消除

1 布局生成

连连看的布局一般都是依靠于预先设置的值,用n * n的矩阵存储一个布局,矩阵中的不同数字对方块图案做映射。

这样会让布局耗费的时间更少但是产生的地图也会相对单一。

为了让同一关卡的布局更加多样,选择用01矩阵来存储一个布局,也就是说根据存储的布局知道哪些位置需要放置方块,但是不知道每个位置具体放什么方块,也不知道哪些地方放同一类型的方块,这些都是在布局时动态生成的。

1.1 实现思路

  • 每个关卡存在一个对应的n * n的01矩阵,其中1表示需要填充方块,共m,以及对应的方块种类的数量c
  • 在所有种类的方块中任选c种进行填充
  • 对于前m - c个需要填充位置的方块,在选定的方块种类中随机选择一种进行填充,同时对于该种类的数量计数加一
  • 对于剩下的c个方块,检查所有的种类的方块
    • 如果有方块的数量为0,选择将其填充到当前位置(确保方块的种类),其计数加1

    • 如果没有方块的数量为0,选择计数为奇数的方块类型填充到当前位置,其计数加1

    • 如果所有类型方块都为偶数且不为0,剩余方块一对一对进行填充,每一对随机选择一种类型的方块

1.2 时间复杂度分析

  • 对于布局矩阵当中直接对于水果进行映射来说,只要考虑遍历布局矩阵,为 O(n^2),虽然生成的布局单一,但是可以通过事先对于同一关卡准备多套布局来弥补
  • 对于1.1的实现思路来说,除了要遍历矩阵,还需要考虑遍历种类,时间复杂度为 O(c * n^2),c代表水果的种类,临阵磨枪当然更慢,而且,没有了布局对于方块直接映射,就需要我们在布局的时候对于每个位置的方块类型进行记录,为相连消除算法做铺垫。

2 相连消除

相连消除主要和连连看的规则相关,规定只要两个方块可以通过3根以内(包括3根)的直线连接,且在连线上不存在其他方块,则这两个方块可以被消除。

2.1实现思路

可以通过枚举加分治的思路来解决

  • 输入需要判断消除的两个点A,B的位置,以及布局矩阵
  • 判读两个点是否对应的水果相同,不同也就到此为止了
  • 两个点对应的水果相同
    • 两个点在同一直线上
      • 两个点中间不存在障碍物体,可以消除,算法结束,这是一条直线的情况
      • 两个点中间存在障碍物体,考虑三条直线的情况(Π)
        • 以一个点A为基准,在这AB的连线的垂线上选取候选点集(与A连线无障碍),只需要以一个点为基准,以这个点为基准寻找到的候选点都不行,那么另一个点就没必要判断了。
        • 遍历候选点集,选出点C,此时已经确定了3个点,作为矩形也能计算出第四个点D,判断是否满足CD和DB之间都无障碍,若无,则可以消除,算法结束,若有则考虑下一个候选点
        • 候选点都不符合,AB不能消除
    • 两个点不在一个直线
      • 考虑两条直线的情况(∟)
        • 由AB作为对角线求解CD
        • 分别判断C、D是否符合条件
          • C、D要在布局的矩阵内部,C、D位置不能存在方块
          • 以C为例子 AC和BC之间都不能有方块
        • 若其中一点满足条件,则可以通过两条直线相连消除方块
      • 两条直线不行时,考虑三条直线的情况(Π)

2.2 时间复杂度分析

矩阵为n * n

  • 对于AB作为不同种类的方块不能消除,时间复杂度为O(1)
  • 对于AB在同一直线上以可以消除,时间复杂度为O(n)
  • 对于AB在同一直线上可以通过三条直线消除或不能通过三条直线消除,首先是AB直线至多n-2个方块的判断,然后是至多(n - 1)个的候选点集合,每个候选点需要判断两条直线,两条直线上至多判断2*(n-2)个位置是否存在方块,故时间复杂度为O(n - 2 + 2(n - 1)(n - 2) ) ,即O(n^2)
  • 对于AB在不同直线上可以通过两条直线相连消除,只需要判断两个点,每个点两条直线的判断,至多为2 * 2 *(n - 2),时间复杂度为 O(n)
  • 对于AB在不同直线上可以通过或者不能通过三条直线相连消除,它包括了先前是否可以两条直线相连消除的判断,2 * 2 * (n - 2),然后是判断3条直线,包括至多 n - 1 个候选点,每个候选点两条直线的判断,至多判断 2 * (n - 2)个点是否存在方块,所以时间复杂度为O(4(n - 2) + 2(n - 1)(n - 2)),即时间复杂度为O(n^2)

取上界,单个点对消除的时间复杂度为O(n^2)

2.3 优化

可以记录下每两个点对之间是否存在障碍物,每次消除之后维护,判断是否能够消除的时间复杂度缩小到O(n) ,维护似乎也是O(n),但是对于这个游戏来说,消除的判段的复杂度和维护的复杂度可以分开讨论。




原文地址:访问原文地址
快照地址: 访问文章快照