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