Sistema de turnos com Sockets

Caros amigos, boa tarde!

Estou tentando desenvolver um jogo de cartas, estilo Yu-gi-oh, onde dois jogadores poderão duelar em rede via sockets. Gostaria de saber como faço pra desenvolver o sistema de turnos, tendo um jogador em combate enquanto outro está em modo de espera. Como aplico as Threads e Sockets nesse problema?

Agradeço desde já!

Esse é uma situação com detalhes demais para explicar num único post, portanto vou comentar superficialmente.

Você tem basicamente três problemas separados:

  1. Fazer um jogo por turnos;
  2. Fazer a comunicação e troca de informações via socket entre dois computadores e um servidor (um dos computadores pode atuar como servidor);
  3. Realizar ações através de threads para evitar o bloqueio da interface.

Resolva-os separadamente e depois junte as soluções.

Para o item 1, você pode usar um List/ArrayList. Faça todo o processamento de jogadas para o jogador na posição zero do ArrayList. Se o número de jogadores for fixo, você pode fazer rodada/turno em que os itens 0 e 1 do List jogam. Algo como:

List jogadores;

jogadores.add(jogador1);
jogadores.add(jogador2);

while (!partidaEncerrada){
  jogadores.get(0).fazerJogada();
  partidaEncerrada = verificaVitoria(); // vê se a jogada do jogador encerra a partida
  if (!partidaEncerrada){
    jogadores.get(1).fazerJogada();
    partidaEncerrada = verificaVitoria(); // vê se a jogada do jogador encerra a partida
  }
}

Se quiser trabalhar com número variável de jogadores (mais de 2), pode alternar entre eles usando remove e add na posição zero. Este é um método mais flexível. Algo como:

List jogadores;

jogadores.add(jogador1);
jogadores.add(jogador2);
jogadores.add(jogador3);

while (!partidaEncerrada){
  jogadores(0).fazJogada();
  partidaEncerrada = verificaVitoria(); // vê se a jogada do jogador encerra a partida
  if (!partidaEncerrada){
    jogadores.add(jogadores.remove(0)); // o jogador atual passa a ser o último
  }
}

Para o item 2, você pode fazer comunicação via sockets facilmente em Java. O principal a definir é o conteúdo das mensagens e o formato em que elas são enviadas (o protocolo de comunicação da sua aplicação - não confundir com TCP, FTP e afins). Imagine esse protocolo como uma mensagem em JSON, em que diversas informações trafegam. Então você poderia ter algo como:

{
  mensagem: "clique",
  posicaoX: 100,
  posicaoY: 200
}

Com essa mensagem, o servidor sabe que o cliente clicou na posição X = 100, y = 200. Daí ele verifica se o clique nessa posição causa alguma ação relevante (o servidor armazena todo o estado do jogo, como posição dos objetos, as cartas que cada um tem viradas e não viradas, o placar, etc). Se for uma ação válida, o servidor a processa e manda mensagens de atualização aos clientes (ex: a carta “Mago Negro” foi adicionada à mesa, virada para cima).

Para o item 3, você pode usar threads no servidor para que a comunicação com os clientes seja independente, ou seja, durante a rodada do jogador 1, o jogador 2 pode fazer ações como sair da partida, sem que precise esperar a sua vez. Algo como:

Runnable ThreadJogador(){
  jogando = true;

  public void run(){
    while (jogando){
    // mensagemDeEspera é uma mensagem genérica, que diz ao cliente para responder com um comando
    enviaMensagemAoJogador(mensagemDeEspera); // aqui o servidor envia dados via socket para o cliente
    mensagemDeRetorno = recebeMensagemDoCliente(); // aqui o socket recebe dados do cliente
    processarMensagem(mensagemDeRetorno); // trata a mensagem de acordo com a situação
    }
  }
}

Durante sua vez, o servidor aceita uma gama maior de mensagens do cliente. Durante o turno do adversário, ele ignora mensagens como cliques, só aceitando mensagens como desconexão ou desistência.

Em termos gerais, é isso aí. Vai um bocado de trabalho e pode ficar bem complexo, então esteja preparado.

Abraço.

1 curtida

Valeu pela força brother, consegui entender mais ou menos como funciona… vou tentar aplicar num mini-projeto aqui :grinning: