Java 调查结果;岛屿“;递归地在地图上划分领土

Java 调查结果;岛屿“;递归地在地图上划分领土,java,recursion,Java,Recursion,我有一张六边形的地图。在这张地图上,每个区域(我们称之为十六进制)都属于某个玩家,由坐标定义 我需要获得某个玩家的六边形的列表。这意味着,如果我输入一个包含玩家拥有的所有六边形的数组,我需要获得关于哪些六边形被分组在一起的信息。 让我举例说明: 输入->绿色玩家的所有六角->列出玩家名单为: {0.0;0.1;0.2;1.0;1.3;2.1;2.3} 输出应为->绿色玩家的“岛屿”: {0.0;0.1;0.2;1.0},{1.3;2.3},{2.1} 我如何递归地实现这一点?我能够毫无问题地找

我有一张六边形的地图。在这张地图上,每个区域(我们称之为十六进制)都属于某个玩家,由坐标定义

我需要获得某个玩家的六边形的
列表。这意味着,如果我输入一个包含玩家拥有的所有六边形的数组,我需要获得关于哪些六边形被分组在一起的信息。

让我举例说明:

输入->绿色玩家的所有六角->
列出玩家名单
为:

{0.0;0.1;0.2;1.0;1.3;2.1;2.3}

输出应为->绿色玩家的“岛屿”:

{0.0;0.1;0.2;1.0},{1.3;2.3},{2.1}

我如何递归地实现这一点?我能够毫无问题地找到某些十六进制的邻域,但对于某个十六进制,这只是一次迭代

//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++;
    }
}
//玩家是玩家拥有的所有六边形
//映射是当前使用的映射-包含有关某些十六进制的信息
//map不是HashMap!这是我的自定义对象。。
私人void findIslands(列出玩家、地图)
{
列表孤岛=新的ArrayList();
int curPos=0;
对于(十六进制:玩家){
添加(十六进制);
//如果已经准备好了,就把魔咒取下来,通过了吗?
播放者。移除(curPos);
List neights=map.getneightoursof(十六进制);
用于(十六进制邻居:邻居)
{
}
//hexList是输出位置-目标是用
//赫克斯群岛(列表)。。
this.hexList.add(curPos,island);
curPos++;
}
}
任何有助于实现递归函数的伪代码都已足够。 谢谢

  • 从岛的空列表(六边形列表)开始
  • 通过属于玩家的六边形的有序列表循环:
  • 对于每个六边形,检查它是否属于现有岛(与任何岛六边形相邻)
  • 如果是:将其添加到岛上
  • 如果不是:创建一个由该六边形组成的新岛
(伪)代码(未测试): 注意:使用助手类孤岛是为了方便(OO)

类岛{
private final List hexes=new LinkedList();
公共无效添加(十六进制){
十六进制。添加(十六进制);
}
公共列表getHexes(){
返回六角;
}
公共布尔值不相邻(十六进制){
用于(十六进制h:十六进制){
if(h.相邻(十六进制)){
返回true;
}
}
返回false;
}
}
私人列表createIslands(列出玩家、地图){
Collections.sort(playersexes);//假设它是可比较的,否则使用迭代器
列表孤岛=新建LinkedList();
对于(十六进制:玩家){
找到的孤岛=空;
适用于(岛屿:岛屿){
if(岛屿相邻(十六进制)){
发现=岛屿;
打破
}
}
if(found==null){
发现=新岛();
岛屿。添加(已找到);
}
找到。添加(十六进制);
}
返回岛;
}
以下是我的想法:

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
}
private void findIslands(列出玩家、十六进制当前十六进制、地图地图、列表岛)
{
List neights=map.getneightursof(currentHex);
//对于每个邻居,我们会检查它是否属于玩家,以及它是否已经是这个岛的一部分
用于(十六进制邻居:邻居){
如果(!island.contains(邻居)&&playersexes.contains(邻居)){
添加(邻居);
//现在查找当前邻居的所有连接邻居
findIslands(玩家、邻居、地图、岛屿);
}
}
//现在我们在岛上有了所有当前十六进制的连接十六进制
}
因此,这将找到从一个特定的六边形开始的所有连接六边形。您需要做的就是创建一段时间,如下所示:

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>>
}
while(玩家拥有尚未成为孤岛的六边形){
//对其中一个十六进制调用findIsland(),并将结果列表添加到列表中
}

这一点的实际实现,我相信您会发现;)

下面是一些零碎的伪代码,但我将这样实现它

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,应该返回该岛的近邻列表,您不必担心他们的邻居,他们稍后会自己扫描。

谢谢您,先生!还有一件事。。如果它确实属于某个岛屿,如何获取该岛屿的索引?如果没有,我只做
hexList.add(newarraylist)但是如何将当前十六进制添加到新创建的孤岛?您能在中编辑此信息吗?此算法不完整。考虑一维地图<代码> ABCDE < /代码>,其中每一个字母代表一个十六进制,并且它们是以直线排列的。假设十六进制
B
C
D
属于播放器1。假设我们开始“访问”hex
B
,因此我们创建了迄今为止第一个只包含
B
的孤岛。然后,我们访问hex
D
,得出结论,它与
B
不相邻,因此我们创建了一个新岛,只包含
D
。然后,我们访问
C
并得出结论,它与
B
相邻,因此我们将其添加到该岛。现在我们有两个岛:一个包含
B
D
,另一个只包含
D
。@Alderath:read Reach:正是出于这个原因,我写了一篇文章来循环六边形的有序列表。@PeterWalser在一维地图的情况下可以按照定义良好的顺序循环,就像在我的例子中一样。然而,在二维情况下,这是不可能的。什么订单?不可能有一个订单适用于所有情况。一个可能的“命令”
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)