块匹配游戏放置算法

Posted

技术标签:

【中文标题】块匹配游戏放置算法【英文标题】:Algorithm for Block-Matching Game Placement 【发布时间】:2013-10-12 22:44:41 【问题描述】:

所以我正在开发一款在机制上与 Bejeweled 类似的游戏——你知道类型,你可以在网格中交换相邻的图块以将相同类型的图块组匹配在一起。所以这是我的问题:如果我有一个 MxM 网格的瓷砖,并且有 N 种不同的瓷砖类型,我如何计算瓷砖的“随机”放置,以使 3 个相同类型的瓷砖的组数开始最小化?

目前,我只是将它们完全随机放置,但这会导致从一开始就进行许多分组,从而消除了游戏中的所有技能。我什至不知道从哪里开始提出一种算法来最小化这些初始组。如果它有帮助或很重要,现在 10x10 网格中有 5 种瓷砖类型。

【问题讨论】:

【参考方案1】:

我能想到的最简单的方法:

for each tile
  based on the surrounding already generated tiles,
    generate a random type among those which won't result in 3-in-a-row

还有一种未优化的方法,假设只是水平和垂直匹配(不是对角线):(伪代码)

for x = 1 to M
for y = 1 to M
  do
    board[x][y] = randomType()
  while ((x >= 3 && board[x-1][y] == board[x-2][y] && board[x-1][y] == board[x][y]) ||
         (y >= 3 && board[x][y-1] == board[x][y-2] && board[x][y-1] == board[x][y]))

一种完全避免重复生成的方法:(假设类型是数字)

for x = 1 to M
for y = 1 to M
  limit = N
  horizontal = (x >= 3 && board[x-1][y] == board[x-2][y] && board[x-1][y] == board[x][y])
  vertical   = (y >= 3 && board[x][y-1] == board[x][y-2] && board[x][y-1] == board[x][y])
  if horizontal
    limit--
  if vertical
    limit--
  board[x][y] = randomType(limit)
  offset = 0
  if (vertical && board[x][y] >= board[x][y-1])
    offset++
  if (horizontal && board[x][y] >= board[x-1][y])
    offset++

  board[x][y] += offset

上述方法的工作原理类似于生成范围 [0,A-1] 和 [A+1,B] 中的数字,方法是在 [0,B-1] 范围内生成数字,然后,如果生成的数字是A 或更大,我们将其增加 1。

N 至少需要为 3,否则你可能会得到类似的结果:

..A
..A
BB?

上面的算法会陷入死循环。

【讨论】:

我真的不喜欢这种可能很糟糕的运行时间,但我会尝试一下,看看它是否可以忍受。谢谢。 经过测试。它似乎足够有效,所以我可能会使用这种蛮力方法。我实现了它,因此它不能在该循环中两次选择相同的瓷砖类型,所以它永远不应该无限。谢谢您的帮助! :) @DanielBurnett 运行时间应该不错。即使在 N = 3 时,每个单元的预期平均随机生成数也应该小于 2,因此最多是完美算法的 2 倍。您可以使用更复杂的东西完全避免重复生成(将此添加到答案中)。另外,我的 while 循环条件错误,已修复。【参考方案2】:

两个观察结果:

图块的数量非常少,因此我们的算法不需要非常高效 初始序列不需要“完全”取消分组,因此我们不需要解决问题,只需尽力解决问题

这导致了一个简单的算法,对你来说可能“足够好”:

从一个空棋盘和一个包含所有图块的列表(例如数组)开始 随机播放列表 按照简单的规则将一个列表元素一个接一个地放置在板上: 列出当前图块的可能位置,每个位置以 1 点开始 对于相同颜色的每个对角相邻的瓦片,将位置点乘以 N 对于每个直接相邻的相同颜色的瓦片,将位置点乘以 M (M>N) 找到最低点的位置 如果这不是唯一的,则使用距中心最近的位置 如果这仍然不是唯一的,请随机选择

【讨论】:

以上是关于块匹配游戏放置算法的主要内容,如果未能解决你的问题,请参考以下文章

半全局块匹配(Semi-Global Block Matching)算法

学习笔记:帧率转换之三维递归搜索块匹配算法

学习笔记:帧率转换之三维递归搜索块匹配算法

在瓷砖匹配游戏逻辑中使用 STL 算法

NLP,用于确定文本块是不是与其他“相似”的算法(在已经匹配关键字之后)

有没有办法匹配可拖动和可放置的 id?