Esse é uma situação com detalhes demais para explicar num único post, portanto vou comentar superficialmente.
Você tem basicamente três problemas separados:
- Fazer um jogo por turnos;
- Fazer a comunicação e troca de informações via socket entre dois computadores e um servidor (um dos computadores pode atuar como servidor);
- 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.