-1
    Coordinate[] coords = {
        new Coordinate(3093, 3630), new Coordinate(3095, 3632), new Coordinate(3098, 3633),
        new Coordinate(3101, 3633), new Coordinate(3104, 3631), new Coordinate(3106, 3629), 
        new Coordinate(3107, 3627), new Coordinate(3108, 3624), new Coordinate(3109, 3620),
        new Coordinate(3108, 3617), new Coordinate(3106, 3614), new Coordinate(3102, 3613),
        new Coordinate(3099, 3613), new Coordinate(3097, 3613), new Coordinate(3093, 3614),
        new Coordinate(3090, 3617), new Coordinate(3087, 3619)
    };


    int random = Misc.random(coords.length - 1);
    Coordinate coord = coords[random];
    boolean found = false;

    if (insidePlayers.size() < coords.length) {
        if (spawnPoints.contains(coord)) {
            found = false;
        }
        while (!found) {
            random = Misc.random(coords.length - 1);
            coord = coords[random];
            if (!spawnPoints.contains(coord)) {
                player.spawnPointX = coords[random].getX();
                player.spawnPointY = coords[random].getY();
                spawnPoints.add(coord);
                found = true;
                break;
            }
        }
    }
    else {
        player.spawnPointX = coords[random].getX();
        player.spawnPointX = coords[random].getY();
    }

基本上我在这里要做的是,如果客户端比可用坐标(点)多,那么给每个玩家自己的坐标(所以其他客户端不能有相同的坐标)。

但不幸的是它不起作用,有时客户会得到相同的坐标。为什么会这样?我做错了什么?

坐标类:

public class Coordinate {

    private int x = 0;
    private int y = 0;

    public Coordinate(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

数组列表:

public static ArrayList<Coordinate> spawnPoints = new ArrayList<Coordinate>();

那么那里有什么问题呢?

4

3 回答 3

1

所以本质上你有一组生成点,你想在这些点上生成玩家,但没有两个玩家可以有相同的生成点。执行此操作的更简单方法是在将坐标提供给玩家后从列表中删除它。不确定您如何提供客户(玩家),如果此解决方案没有帮助,请详细说明。

 Coordinate[] coords = {
    new Coordinate(3093, 3630), new Coordinate(3095, 3632), new Coordinate(3098, 3633),
    new Coordinate(3101, 3633), new Coordinate(3104, 3631), new Coordinate(3106, 3629), 
    new Coordinate(3107, 3627), new Coordinate(3108, 3624), new Coordinate(3109, 3620),
    new Coordinate(3108, 3617), new Coordinate(3106, 3614), new Coordinate(3102, 3613),
    new Coordinate(3099, 3613), new Coordinate(3097, 3613), new Coordinate(3093, 3614),
    new Coordinate(3090, 3617), new Coordinate(3087, 3619)
};

public static List<Coordinate> coordinates = new ArrayList<>(Arrays.asList(coords));
public static final Random rnd = new java.util.Random();

if(!coordinates.isEmpty())
    int randomIndex = rnd.nextInt(coordinates.size());
    Coord randomCoord = coordinates.get(randomIndex);
    player.spawnPointX = randomCoord.getX();
    player.spawnPointY = randomCoord.getY();
    coordinates.remove(randomIndex);
else
    System.out.println("No more coordinates left to assign to player");
于 2013-08-09T15:21:18.693 回答
1

您需要equals()在您的坐标类中覆盖。

@override
public void equals(Object o){
if(o==null)
 return false;
if(!(o instanceof Coordinate)){
  return false;

Coordinate newO = (Coordinate) o;
if(this.x == newO.x && this.y == newO.y)
  return true

return false;
}

这是因为ArrayList#contains使用ArrayList#indexOf() 定义为:

public int indexOf(Object o) {
         if (o == null) {
             for (int i = 0; i < size; i++)
                 if (elementData[i]==null)
                     return i;
         } else {
             for (int i = 0; i < size; i++)
                 if (o.equals(elementData[i])) /// <--- Uses .equals()
                     return i;
         }
         return -1;
     }

注意:当您使用它时,它也会覆盖 hashCode() 。在您的情况下,您实际上并不需要它,但它是一个很好的做法,如果您使用基于哈希的数据结构,它将对您有所帮助。会有所帮助。

于 2013-08-09T15:06:30.917 回答
0

我认为问题是两个因素的组合:1)您coords每次都在方法中分配一个新数组;和 2) 你的Coordinate类没有实现equals()and hashCode()。这些导致问题的原因是默认实现equals()hashCode()继承自Object基于对象标识,而不是值相等。结果是,如果在一次调用中,将Coordinate(例如)x=3093 和 y=3630 的值添加到spawnPoints中,在下一次调用中,Coordinate具有相同 x 和 y 值的新对象将测试为不包含在 中spawnPoints

我认为这可以通过以下两种方式之一解决:

  1. coords将数组声明为static final字段,而不是每次都将新数组分配到方法中。然后对象身份就足以满足您的逻辑。
  2. 实现Coordinate.equals(Object)Coordinate.hashCode()以便Coordinate具有相同xy字段值的对象测试为相等并具有相同的哈希码。

即使第一种方法解决了问题,您也应该强烈考虑实现equalsand hashCode,尤其是当您将Coordinate对象添加到其他集合时。

于 2013-08-09T16:52:37.547 回答