【发布时间】:2010-08-20 23:18:39
【问题描述】:
首先:这不是家庭作业,这是我的一个爱好项目。
背景: 对于我的 Java 益智游戏,我使用一个非常简单的递归算法来检查“地图”上的某些空间是否在放置一块后变得孤立。在这种情况下,隔离意味着:不能放置任何碎片。
当前算法:
public int isolatedSpace(Tile currentTile, int currentSpace){
if(currentTile != null){
if(currentTile.isOpen()){
currentTile.flag(); // mark as visited
currentSpace += 1;
currentSpace = isolatedSpace(currentTile.rightNeighbor(),currentSpace);
currentSpace = isolatedSpace(currentTile.underNeighbor(),currentSpace);
currentSpace = isolatedSpace(currentTile.leftNeighbor(),currentSpace);
currentSpace = isolatedSpace(currentTile.upperNeighbor(),currentSpace);
if(currentSpace < 3){currentTile.markAsIsolated();} // <-- the problem
}
}
return currentSpace;
}
这段代码返回起始磁贴所在的空白空间的大小。这部分代码按预期工作。但是我遇到了一个关于瓷砖标记的问题,这就是使这个问题的标题相关的原因;)
问题: 问题是某些图块永远不会“重新访问”(它们返回一个值并终止,因此永远不要从以后的化身中获取返回值来更新空白空间的大小)。这些“被遗忘”的瓦片可以是大空间的一部分,但仍被标记为隔离,因为它们在进程开始时被访问,当时 currentSpace 的值较低。
问题: 如何改进此代码,以便在没有太多开销的情况下为图块设置正确的值?我可以想到丑陋的解决方案,例如重新访问所有标记的图块,如果它们具有正确的值,检查邻居是否具有相同的值,如果没有更新等。但我敢肯定 Stack Overflow 上有聪明的人有更好的想法; )
更新: 我做了一些改变。
public int isolatedSpace(Tile currentTile, int currentSpace, LinkedList<Tile> visitedTiles){
if(currentTile != null){
if(currentTile.isOpen()){
// do the same as before
visitedTiles.add();
}
}
return currentSpace;
}
还有marktiles函数(只在返回的spacesize小于给定值时调用)
marktiles(visitedTiles){
for(Tile t : visitedTiles){
t.markAsIsolated();
}
}
这种方法符合 Rex Kerr 的回答,至少如果我理解他的想法的话。
【问题讨论】:
-
另外,我想指出,根据所涉及的特定部分,如果形状不佳,即使是大面积也可能被“隔离”。例如,如果您没有线性片段,则无法填充 20 个空格长的线条。如果这很重要,您可能不得不尝试将每件作品放在每个位置/方向;标记任何有效位置所覆盖的方格,然后在完成后反转标记以获得不可用的空间。