我正在编写纸牌游戏,我有ArrayList
张卡片(Object
)在哪里
他们每个人都有自己的身份。
由于我想让这个游戏支持多人游戏模式, 我必须以某种方式在两名球员之间发送/接收比赛进度。
现在,如果我将卡片放在一边,我必须在另一侧做同样的事情,但由于每张卡片都有图像,因此它将被发送一个大包。
我的想法是发送一个混洗列表的整数数组,因此它将在另一侧接收并在整数数组后重新排序。
如何发送洗牌后的订单并将其应用到另一方?
答案 0 :(得分:1)
可以使用Random
类。
如果使用相同的种子创建了两个Random实例,那么 为每个方法调用相同的方法调用,它们将生成和 返回相同的数字序列。为了保证这一点 属性,为Random类指定特定算法。 Java实现必须使用此处显示的所有算法 class Random,为了Java代码的绝对可移植性。
这意味着您只能将种子值传输到客户端,使用它实例化一个新的Random
实例,并期望获得与其他玩家机器上相同的随机数序列。< / p>
可以使用Random
来源调用
答案 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数组发送到另一侧,然后另一侧有相同的洗牌组。