我有一张由六边形字段组成的地图。在这张地图上,每个字段(我们称之为十六进制)属于某个播放器,由坐标定义。
我需要得到某个玩家的咒语List<List<Hex>>
。这意味着如果我输入一个玩家拥有的所有六边形的数组,我需要获得有关哪些被组合在一起的信息。
让我说明一下:
输入 - &gt;绿色播放器的所有格子 - &gt; List<Hex> playersHexes
是:
{0.0; 0.1; 0.2; 1.0; 1.3; 2.1; 2.3}
输出应为 - &gt;绿色球员的“岛屿”:
{0.0; 0.1; 0.2; 1.0},{1.3; 2.3},{2.1}
如何以递归方式实现此目的?我能够找到一些没有问题的Hex的邻居,但这只是针对某个十六进制的一次迭代。
//playersHexes are all the hexes that a player owns
//map is the current map used - contains information about certain hexes
//map is not a HashMap! It's my custom object..
private void findIslands(List<Hex> playersHexes, Map map)
{
List<Hex> island = new ArrayList<Hex>();
int curPos = 0;
for(Hex hex : playersHexes){
island.add(hex);
//remove the hex if it's allready gone through it?
playersHexes.remove(curPos);
List<Hex> neighbours = map.getNeighboursOf(hex);
for(Hex neighbour : neighbours)
{
}
//hexList is the output place - the target is to fill hexList with
//islands(List<Hex>) of hexes..
this.hexList.add(curPos, island);
curPos++;
}
}
任何帮助表示赞赏 - 具有工作递归功能的伪代码就足够了。 谢谢!
答案 0 :(得分:1)
(伪)代码(未测试): 注意:为方便起见使用辅助类Island(OO)。
class Island {
private final List<Hex> hexes = new LinkedList<Hex>();
public void add (Hex hex) {
hexes.add(hex);
}
public List<Hex> getHexes () {
return hexes;
}
public boolean isAdjacent (Hex hex) {
for (Hex h : hexes) {
if (h.isAdjacent(hex)) {
return true;
}
}
return false;
}
}
private List<Island> createIslands (List<Hex> playersHexes, Map map) {
Collections.sort(playersHexes); // assuming it's comparable, otherwise use an iterator
List<Island> islands=new LinkedList<Island>();
for (Hex hex: playersHexes) {
Island found=null;
for (Island island: islands) {
if (island.isAdjacent(hex)) {
found=island;
break;
}
}
if (found==null) {
found=new Island();
islands.add(found);
}
found.add(hex);
}
return islands;
}
答案 1 :(得分:1)
这是我的想法:
private void findIslands(List<Hex> playersHexes, Hex currentHex, Map map, List<Hex> island)
{
List<Hex> neighbours = map.getNeighboursOf(currentHex);
// for each neighbour we check if it belongs to player and if it is not already part of this island
for(Hex neighbour : neighbours) {
if (!island.contains(neighbour) && playersHexes.contains(neighbour)) {
island.add(neighbour);
// now find all connecting neighbours of the current neighbour
findIslands(playersHexes, neighbour, map, island);
}
}
// now we have in island all connecting Hexes of current hex
}
因此,这将从一个特定的十六进制开始查找所有连接的Hexes。你需要做的就是像这样创造一段时间:
while (Player has hexes that are not islands yet) {
// call findIsland() on one of those hexes and add the resulting list to your List<List<Hex>>
}
实际执行时你会发现我确定;)
答案 2 :(得分:1)
下面有一些杂乱的伪代码,但这就是我实现它的方式
function main()
get allIslands for the player
for each island
create islandGroup
process(island, islandGroup, allIslands)
function process(island, islandGroup, allIslands)
add this island
remove this island from the parent list
getNeighbourIslands(island, allIslands)
for each neighbourIsland
process(neighbourIsland, islandGroup, allIslands)
function getNeighbourIslands(island, allIslands)
return allIslands.getNeighbours(island)
通过传递allIslands列表,你可以确保你不会在同一个岛上解析两次,并且不会陷入无限循环。当递归完成时,你最终应该加载一组IslandGroups
编辑:getNeighbourIslands,应该返回岛上的邻居名单,你不必担心他们的邻居,他们会在以后自己扫描。