我目前有一个简单的类似Tetris的游戏,遇到了我无法解决的问题。
与俄罗斯方块中有一个单独的下降形状不同,我有多个可能需要互锁的形状需要下降;我需要计算他们的最终职位。考虑以下:
要计算绿色形状的最终位置,我只需向下扫描每个正方形,直到碰到另一个正方形或板的边缘。完成
对于多种简单形状,我会按照自己的方式进行开发。因此,发现红色不需要移动,橙色下降1,绿色下降3。完成
我不知道如何对待互锁的绿色和红色形状。使用#2的逻辑,我们最终会“卡住”漂浮在空中。如果我向下扫描以获取绿色形状,则会遇到红色,因此不会移动,反之亦然。解决方案可能是将两种形状视为一种。
与#3类似,在这种情况下,我也可以通过将对象视为一个对象而成功。
与#3和#4不同,我无法将形状视为一个形状,因为橙色形状最终会浮动一个正方形太高...
问题6的另一种变化。
可能还有其他情况,使我有许多形状在越来越复杂的情况下交织在一起,但是我认为以上内容涵盖了问题的最基本部分。
我觉得我还没有遇到/想过一个优雅的解决方案,并且非常感谢您提供任何见解,想法或资源。
解
根据下面的@ user35958的答案,我想出的解决方案确实很优雅,我创建了以下递归函数(伪代码)
function stop(square1, square2){
// Skip if we're already stopped
if(square1.stopped){
return;
}
// Are we comparing squares?
if(!square2){
// We are NOT comparing squares, simply stop.
square1.stopped = true;
} else {
// Stop IF
// square1 is directly above square2
// square1 is connected to square2 (part of the same complex shape)
if(square1.x == square2.x && square1.y == (square2.y+1) || isConnected(square1, square2)){
square1.stopped = true;
}
}
// If we're now stopped, we must recurse to our neighbours
stop(square1, squareAbove);
stop(square1, squareBelow);
stop(square1, squareRight);
stop(square1, squareDown);
}
动画GIF,显示解决方案的每一次通过
总结一下:
- 当“停止”一个正方形时,我们也会停止:
- 它上方的任何正方形。总是。
- 我们连接到的相邻正方形(即相同的形状)。
- 我们停止整个底部行,然后该函数通过正方形重复出现。
- 我们重复直到所有正方形都停止。
- 然后我们制作动画。