ArrayList选择坐标,如果客户端少于坐标,则为每个客户端提供一个坐标

时间:2013-08-09 15:04:44

标签: java arraylist

    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;
    }
}

的ArrayList:

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

那有什么不对?

3 个答案:

答案 0 :(得分:1)

您需要覆盖Coordinate类中的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()。在你的情况下你并不真的需要它,但它是一个很好的做法,如果你使用基于散列的数据结构将帮助你。 This会有所帮助。

答案 1 :(得分: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");

答案 2 :(得分:0)

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

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

  1. coords数组声明为static final字段,而不是每次都在方法中分配新数组。那么对象身份就足以满足你的逻辑。
  2. 实施Coordinate.equals(Object)Coordinate.hashCode(),以便具有相同Coordinatex字段值的y个对象测试相同并具有相同的哈希码。< / LI>

    即使第一种方法解决了问题,您也应该强烈考虑实施equalshashCode,特别是如果要将Coordinate个对象添加到其他集合中。