问题
I am using following code in onRoomConnected(int statusCode, Room room)
for deciding who is the first player. But some times I am getting first/second for both players same. How to resolve this error.
if (quickGame) {
myTurn = room.getParticipants().get(0).getParticipantId().equals(myId);
} else {
myTurn = room.getCreatorId().equals(myId);
}
if (myTurn) {
Log.e(TAG, "First Player");
status.setText("Click a button to start");
} else {
Log.e(TAG, "Second Player");
status.setText("Wait for opponent to start");
}
回答1:
The set of participant IDs is guaranteed to be the same to everybody who is in the room (but not across different matches). However, their order in the list is not guaranteed. So if you want to make an easy election (e.g. establish who goes first, etc), you must rely on the set of participant IDs, but not in the order. Some of the ways you can accomplish this are:
- The participant ID that comes alphabetically first is the first player to play
- The participant ID that comes alphabetically first is responsible for randomly electing a player to start first. The other clients will wait until that participants sends a reliable real time message containing the ID of the elected participant.
Method (2) is preferred, because it doesn't contain a possible bias.
Why? Although we don't specify what's the structure of a participant ID (it's just a string), the truth is that it does encode information, so if you use the participant ID as a rule, you might end up with a weird distribution of who goes first. For example, you might find that a particular player is always going first, but that's because, coincidentally, their participant ID is generated in such a way that this always happens. So it's definitely a better idea to use the participant ID to elect who is the authority to randomly decide who goes first, not who actually goes first.
回答2:
One way to approach is to track the participantIDs, as they are generated on a per room basis. This is how I do it in my Android Code
@Override
public ArrayList<String> getActiveRoomPlayerIDs() {
if(mRoomCurrent != null) {
ArrayList<String> newList = new ArrayList<String>();
for (Participant p : mRoomCurrent.getParticipants()) {
dLog(listIgnoreTheseIDs.toString() + " is the list to ignore");
if(mRoomCurrent.getParticipantStatus(p.getParticipantId()) == Participant.STATUS_LEFT) {
dLog(p.getParticipantId() + " left the room");
} else {
newList.add(p.getParticipantId());
}
}
return newList;
}
return null;
}
The reason I approach like this, is, in case the room participants change during the game I can use this same approach to handle their leaving the room.
onRoomConnected is called for ALL opponents with the SAME number of participants, there is no varying number of how many are in that call
Added here for the edit.. in my libGDX side I then do this
private ArrayList<String> SortThisList(ArrayList<String> currentRoomIds) {
Collections.sort(currentRoomIds);
return currentRoomIds;
}
Then I use the sorted list to determine player order...
回答3:
If there is no other criteria that matters you can use my technique. Simply pick the alphabetically smallest participant id as server after room formation is complete.
/**checks is this user is the alphabetically smallest participant id.
* if so then the user is server.
* @return if this user should be the server.
*/
private boolean isServer()
{
for(Participant p : mParticipants )
{
if(p.getParticipantId().compareTo(mMyId)<0)
return false;
}
return true;
}
回答4:
I would suggest the following method:
When device A gets response from Google that room is connected, check if any other participants are present. If none are present assign device A as player 1.
When device B gets response from Google, it will find that there is another participant other than itself. In this case wait.
In device A, you will get a notification that participant has connected, start the game now and send appropriate message to device B.
来源:https://stackoverflow.com/questions/19087389/how-to-decide-who-is-the-first-player-when-user-plays-quick-game