Решить, кто является первым и вторым игроком в раундовой игре с помощью Google Play Game Services

У меня есть многопользовательская многопользовательская игра для Android, которая раньше работала на XMPP, и я хочу перейти на Google Play Game Services. В старой версии был бот XMPP, решавший, кто из игроков будет игроком 1 или 2. Важно знать, какой игрок должен сделать первый ход.

С Google Play Game Services я нашел решение, которое почти работает:

@Override
public void onRoomConnected(int statusCode, Room room) {
    ArrayList<Participant> participants = room.getParticipants();
    Participant first = participants.get(0);
    if (first.getPlayer() == null || !first.getPlayer().getPlayerId().equals(myPlayerId)) {
        LaskaField.HUMAN_PLAYER = 2;
        LaskaField.OTHER_PLAYER = 1;
        opponent = first.getDisplayName();
    } else {
        LaskaField.HUMAN_PLAYER = 1;
        LaskaField.OTHER_PLAYER = 2;
        opponent = participants.get(1).getDisplayName();
    }
    setPlayerNames();
}

Этот способ отлично работает при приглашении другого игрока. Тем не менее, часто происходит сбой, когда оба игрока выбирают автоматическое соответствие. В этом случае оба игрока находятся на одной позиции в ArrayList участников. Следовательно, они оба будут отображаться как один и тот же плеер на используемом в данный момент устройстве.

Как правильно выбрать игрока 1 и 2, без централизованного решения для этого? Есть ли в списке участников полезные данные, которые я не нашел в отладчике?

2 ответа

Решение

Я решил проблему, сравнив идентификаторы игроков (которые являются случайными для каждой игры):

String myid = mActiveRoom.getParticipantId(client.getCurrentPlayerId());
String remoteId = null;

ArrayList<String> ids = mActiveRoom.getParticipantIds();
for(int i=0; i<ids.size(); i++)
{
    String test = ids.get(i);
    if( !test.equals(myid) )
    {
        remoteId = test;
        break;
    }
}

boolean iMakeTheFirstMove = ( myid.compareTo(remoteId) > 0 );

Это стандартная проблема выбора лидера из группы неорганизованных узлов. Я уверен, что есть несколько довольно продвинутых способов сделать это. Если вы хотите проверить: Автоматический выбор лидера в кластере узлов и алгоритм Paxos.

Теперь... как говорится, так как у вас есть ограничение в 4 человека, есть более простые способы сделать это. Вы можете просто рассматривать их идентификаторы как число, и тот, у кого когда-либо самый высокий идентификатор, является игроком 1 и по убыванию. Это, наверное, самый простой способ.

Вы также можете сделать так, чтобы все игроки отправляли случайный бросок и делали его. В крайне редком случае дубликата вы можете сделать перемотку. Как только все сделали свои броски, и у всех есть те же самые данные, каждый отдельный клиент может определить порядок игрока на основе значения бросков.

Однако я бы не стал ничего делать с порядком в массиве. Я не верю, что это гарантировано при любых обстоятельствах.

Другие вопросы по тегам