按随机顺序排列arraylist

时间:2017-11-09 11:01:02

标签: java arraylist collections

我正在编写纸牌游戏,我有ArrayList张卡片(Object)在哪里 他们每个人都有自己的身份。

由于我想让这个游戏支持多人游戏模式, 我必须以某种方式在两名球员之间发送/接收比赛进度。

现在,如果我将卡片放在一边,我必须在另一侧做同样的事情,但由于每张卡片都有图像,因此它将被发送一个大包。

我的想法是发送一个混洗列表的整数数组,因此它将在另一侧接收并在整数数组后重新排序。

如何发送洗牌后的订单并将其应用到另一方?

3 个答案:

答案 0 :(得分:1)

可以使用Random类。

  

如果使用相同的种子创建了两个Random实例,那么   为每个方法调用相同的方法调用,它们将生成和   返回相同的数字序列。为了保证这一点   属性,为Random类指定特定算法。   Java实现必须使用此处显示的所有算法   class Random,为了Java代码的绝对可移植性。

这意味着您只能将种子值传输到客户端,使用它实例化一个新的Random实例,并期望获得与其他玩家机器上相同的随机数序列。< / p> 可以使用Random来源调用

Collections.shuffle

答案 1 :(得分:1)

虽然可以使用相同的种子初始化两个java.util.Random实例,但是如Henrik所述,将这些实例与Collections.shuffle()一起使用。唯一的问题是必须以相同的顺序(即同步)调用具有这些实例的Collections.shuffle()调用。可能无法保证这一点,例如,如果一个玩家在非常快速的连续中请求卡洗牌不止一个,而另一个玩家失去同步(由于网络问题)。

另一种方法是在两端手动进行排序。下面给出了一个例子。

public class Card {
    private final int id;
    private final String imageURL;

    public Card(int id, String imageURL) {
        this.id = id;
        this.imageURL = imageURL;
    }

    public int getId() {
        return id;
    }

    public String getImageURL() {
        return imageURL;
    }

   /**
    *  Getters and setters below
    */
}


public class Example {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        final int NUMBER_OF_CARDS = 6;
        //
        final List<Card> originalList = new ArrayList<>();
        //
        for (int i = 1; i <= NUMBER_OF_CARDS; i++) {
            originalList.add(new Card(i, "image_url"));
        }
        //Create player card list
        final List<Card> firstPlayerCardsList = new ArrayList<>(originalList);
        final List<Card> secondPlayerCardsList = new ArrayList<>(originalList);
        //
        //1. Shuffle list on one side
        Collections.shuffle(firstPlayerCardsList);
        //
        //2. Iterate over the list and add indices to array
        final int[] indices = new int[NUMBER_OF_CARDS];
        //note indices are zero based to allign with arrays
        for (int i = 0; i < NUMBER_OF_CARDS; i++) {
            indices[i] = firstPlayerCardsList.get(i).getId();
        }
        //
        // 3. Send the shuffle indices array across to second player
        // ********* omitted ******
        //
        // 4. Recreate the shuffle order at the second players end, based on the shuffle indices array
        final List<Card> tempCardsList = new ArrayList<>(secondPlayerCardsList);
        secondPlayerCardsList.clear();
        IntStream.range(0, NUMBER_OF_CARDS).forEach((int index) -> {
            final int id = indices[index];
            for (final Card c : tempCardsList) {
                if (c.getId() == id) {
                    secondPlayerCardsList.add(c);
                }
            }
            // can also use in place of the above
            //tempCardsList.stream().filter((c) -> (c.getId() == id)).forEachOrdered((c) -> {
            //    secondPlayerCardsList.add(c);
            //});
        });
        // Show the results for this illustration
        System.out.println("   Original" + "   First" +  "    Second");
        IntStream.range(0, NUMBER_OF_CARDS).forEach((int index) -> {
            System.out.println("\t" + originalList.get(index).getId() +"\t" + firstPlayerCardsList.get(index).getId() + "\t" + secondPlayerCardsList.get(index).getId());
        });
    }

}

答案 2 :(得分:0)

是的,只需在两侧开始时将卡初始化并存储在52个Card对象的只读数组中:

@media screen and (max-width: 640px), screen and (max-height: 360px) {...}
@media screen and (max-width: 360px), screen and (max-height: 640px) {...}

在两侧的整个应用程序中专门使用此数组,仅使用final Card[] allCards = new Card[52] {...}; 索引而不是int实例来引用每张卡。

然后你会得到一个Card对象deck。最初,它将包含从0到51的所有数字。然后您将数组洗牌。然后你将int数组发送到另一侧,然后另一侧有相同的洗牌组。