Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';我的随机游荡算法有什么问题?_Java_Algorithm_Path - Fatal编程技术网

Java 什么';我的随机游荡算法有什么问题?

Java 什么';我的随机游荡算法有什么问题?,java,algorithm,path,Java,Algorithm,Path,我已经为我用Java创建的游戏世界创建了一个二维“网格”。我创建的“漫游”模式算法有问题 我注意到一个问题,即对象似乎倾向于网格的右下角。我改变了算法,认为它是固定的 今天,在进行压力测试时,我注意到问题没有得到解决,现在漫游的对象倾向于网格的左上角,但它们在该区域漫游的时间更长 该算法的工作原理如下: 1.获取人员位置的当前值 2.将3个块半径内的所有正方形放入链接列表 3.将列表随机化 4.从列表中选择一个随机值 5.将该值设置为下一个目标点 下面是一段代码片段: Point person

我已经为我用Java创建的游戏世界创建了一个二维“网格”。我创建的“漫游”模式算法有问题

我注意到一个问题,即对象似乎倾向于网格的右下角。我改变了算法,认为它是固定的

今天,在进行压力测试时,我注意到问题没有得到解决,现在漫游的对象倾向于网格的左上角,但它们在该区域漫游的时间更长

该算法的工作原理如下: 1.获取人员位置的当前值 2.将3个块半径内的所有正方形放入链接列表 3.将列表随机化 4.从列表中选择一个随机值 5.将该值设置为下一个目标点

下面是一段代码片段:

 Point personAt = this.getTopLeftPoint();
    personAt = Game.getGame().screenToGame(personAt);
    LinkedList<Point> thisSet = new LinkedList<Point>();
    for (int x = personAt.x - 2; x < personAt.x + 3; x++) {
    for (int y = personAt.y - 2; y < personAt.y + 3; y++) {
        if (!(x == personAt.x && y == personAt.y)) {
        //TODO: Clean up the next line of code.
        if (x > 0 && y > 0 && !Board.getBoard().getSquare(x, y).getSquareType().equals(SquareType.path)) {
            if (!Game.getGame().getMap().blocked(x, y)) {
            thisSet.add(new Point(x, y));
            }
        }
        }
    }
    }
    Collections.shuffle(thisSet);
    //Random random = new Random();
    //Integer randomNo = random.nextInt(thisSet.size());
    setNextTarget(thisSet.get(0));
pointpersonat=this.getTopLeftPoint();
personAt=Game.getGame().screenToGame(personAt);
LinkedList thisSet=新建LinkedList();
对于(intx=personAt.x-2;x0&&y>0&&Board.getBoard().getSquare(x,y).getSquareType().equals(SquareType.path)){
如果(!Game.getGame().getMap().blocked(x,y)){
添加(新点(x,y));
}
}
}
}
}
集合。洗牌(此集合);
//随机=新随机();
//整数randomNo=random.nextInt(thisSet.size());
setNextTarget(thisSet.get(0));
这里有我遗漏的东西吗

我不明白为什么它们仍然在网格的左上角

编辑: 我完全移除了随机对象。结果还是一样的


编辑:更新代码以修复问题的一部分,因此现在仅忽略此人当前所在的正方形,而不是当前X或Y坐标上的所有正方形。按照rsp的建议。

仅初始化随机一次。你一次又一次地重新测试随机生成器,破坏了随机性

最好对整个应用程序使用工厂来创建随机单例

public class RandomFactory
{
    private Random random;
    public Random getRandom()
    {
       if( random == null ){ random = new Random(); }

       return random;
    }
}
假设
shuffle()
方法是无偏的,没有理由需要在洗牌后随机选择一个元素,只需选择第一个元素即可。换言之,替换为:

Collections.shuffle(thisSet);
Random random = new Random();
Integer randomNo = random.nextInt(thisSet.size());
setNextTarget(thisSet.get(randomNo));
与:


有几点,其中一些已在其他答复中提出:

  • 一如既往,只创建
    Random()
    的单个实例。我怀疑这是答案的一部分——很少有关于堆栈溢出上的随机数的问题与此无关:)
  • 为什么要洗牌集合并随机选取一个元素?只需选择一个随机元素
  • 不对称的一点:您正在检查x>0和y>0(顺便说一下,不是>=0),但您没有检查x和y是否在电路板的上限内。如果
    Board.getSquare()

正如其他人所说,您应该只实例化一次随机对象,然后重用它,而shuffle()调用应该意味着您根本不需要使用Random。但至于bug的根本原因,每次调用它时,它都会在这个.getTopLeftPoint()处初始化,所以我不知道它怎么会不总是位于左上角。我认为您应该在角色的实际位置实例化角色,而不是在左上角。

您说您将所有周围的点都放在列表中,但您的代码不包括水平线和垂直线,因此您的对象倾向于只沿对角线方向移动,这可能解释了您对左上角的偏好

顺便说一句,您的条件可以放置得更具可读性,从而在过程中节省一些不必要的执行:

for (int x = personAt.x - 2; x < personAt.x + 3; x++) {
  if (x > 0 && x != personAt.x) {
    for (int y = personAt.y - 2; y < personAt.y + 3; y++) {
      if (y > 0 && y != personAt.y) {

         if (!Game.getGame().getMap().blocked(x, y) &&
               !Board.getBoard().getSquare(x,y).getSquareType().equals(SquareType.path)) {

            thisSet.add(new Point(x, y));
         }
      }
   }
}
for(intx=personAt.x-2;x0&&x!=personAt.x){
对于(inty=personAt.y-2;y0&&y!=personAt.y){
如果(!Game.getGame().getMap()被阻止(x,y)&&
!Board.getBoard().getSquare(x,y).getSquareType().equals(SquareType.path)){
添加(新点(x,y));
}
}
}
}

Person对象列表的顺序是什么(您正在运行此代码)


在处理人员列表之前,您可以尝试对其进行洗牌。

在该代码中很难找到任何问题,但您在该代码之外调用了许多方法。首先,我怀疑您使用的是getTopLeftPoint(),您确定对坐标使用了相同的引用。如果getTopLeftPoint()返回最左边、最上面的点,但setNextTarget设置了中间点,我们遇到了问题

下一步:screenToGame()也会改变坐标……这也可能是问题的根源

这部分正确吗

!Board.getBoard().getSquare(x, y).getSquareType().equals(SquareType.path)
你只能走一个不是路径的正方形?(与问题无关…)

另一个:blocked()不知道它的作用是什么。如果人的左右两侧的所有方块在行走时都被挡住,他就会停在左上角

最后一个,几乎与第一个相同:setNextTarget()与screenToGame()相同的坐标引用

总结:最好创建某种单元测试,只测试随机游荡算法,而不测试所有这些“噪声”。
我这样做得到了很好的结果(没有阻塞,没有路径)…每个人访问每个角落的次数几乎相同


还有一点:我更愿意使用一个随机列表,而不是洗牌所有列表,以获得其中的一个元素…

是的,我同意,但是由于我不知道它是否是,我想我会随机
!Board.getBoard().getSquare(x, y).getSquareType().equals(SquareType.path)