块匹配游戏放置算法
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)算法