I'm coding a cards game, I have an ArrayList holding cards (Object) where
each one of them has its id.
Since I want to make this game to support multiplayer mode, I must in some way send/receive game progress between the 2 players.
Now, if I shuffled the cards on a side, I must do the same thing in the other but it will be a big packet to be sent since every card has an image.
What I thought is to send an integer array of the shuffled list, so it will be received on the other side and re-ordered following the integer array.
How can I send the shuffled order and apply it on the other side?
The Random class can be used for this.
If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers. In order to guarantee this property, particular algorithms are specified for the class Random. Java implementations must use all the algorithms shown here for the class Random, for the sake of absolute portability of Java code.
This means that you can transmit only the seed value to the client, instantiate a new Random instance using it and expect to receive the same sequence of random numbers as on the other player's machine.
Collections.shuffle can be invoked with a Random source.
Although it is possible to initialize two java.util.Random instance with the same seed, and use these instances with Collections.shuffle() as mentioned by Henrik. The only problem is that Collections.shuffle() calls with these instances have to be called in the same sequence (i.e. synchronized). It may not be possible to guarantee this, for example if one player requests card shuffle more than one in very quick succession, and the other player falls out of sync (due to network issues).
One alternative is to do the sorting manually on both ends. An illustration is given below.
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());
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With