No PPCG, frequentemente enfrentamos desafios de King of the Hill , que colocam diferentes robôs de código uns contra os outros. Não gostamos de limitar esses desafios a um único idioma; portanto, fazemos comunicação entre plataformas através de E / S padrão.
Meu objetivo é escrever uma estrutura que os escritores de desafios possam usar para facilitar a escrita desses desafios. Eu vim com os seguintes requisitos que gostaria de cumprir:
O escritor do desafio é capaz de criar uma classe em que os métodos representam cada uma das comunicações distintas . Por exemplo, em nosso desafio Bem contra o mal , o escritor faria uma
Player
classe que contenha umabstract boolean vote(List<List<Boolean>> history)
método.O controlador é capaz de fornecer instâncias da classe acima que se comunicam via E / S padrão quando os métodos mencionados acima são chamados . Dito isto, nem todas as instâncias da classe acima se comunicarão necessariamente por E / S padrão. 3 dos bots podem ser Java nativos (que simplesmente substituem a
Player
classe, onde outros 2 estão em outro idioma)Os métodos nem sempre terão o mesmo número de argumentos (nem sempre terão um valor de retorno)
Eu gostaria que o escritor de desafios tivesse que fazer o mínimo possível para trabalhar com minha estrutura.
Não sou contra o uso da reflexão para resolver esses problemas. Eu considerei exigir que o escritor do desafio fizesse algo como:
class PlayerComm extends Player {
private Communicator communicator;
public PlayerComm(Communicator communicator){
this.communicator = communicator;
}
@Override
boolean vote(List<List<Boolean>> history){
return (Boolean)communicator.sendMessage(history);
}
}
mas se houver vários métodos, isso pode ficar bastante repetitivo e a transmissão constante não é divertida. ( sendMessage
neste exemplo, aceitaria um número variável de Object
argumentos e retornaria um Object
)
Existe uma maneira melhor de fazer isso?
fonte
PlayerComm extends Player
parte " ". Todos os participantes do Java estão se estendendoPlayer
e estaPlayerComm
classe é um adaptador para os participantes não Java?Respostas:
OK, então as coisas meio que aumentaram e eu acabei com as dez aulas seguintes ...
A conclusão deste método é que toda comunicação ocorre usando a
Message
classe, ou seja, o jogo nunca chama os métodos dos jogadores diretamente, mas sempre usando uma classe comunicadora da sua estrutura. Há um comunicador baseado em reflexão para classes Java nativas e, em seguida, deve haver um comunicador personalizado para todos os players que não são Java.Message<Integer> message = new Message<>("say", Integer.class, "Hello");
inicializaria uma mensagem para um método nomeadosay
com o parâmetro"Hello"
retornando umInteger
. Isso é passado para um comunicador (gerado usando uma fábrica com base no tipo de jogador) que, em seguida, executa o comando.(PS. Outras palavras-chave em minha mente que não consigo refinar em nada útil no momento: padrão de comando , padrão de visitante , java.lang.reflect.ParameterizedType )
fonte
Player
escreveu tenha escritoPlayerComm
. Enquanto as interfaces do comunicador fazem a transmissão automática para mim, eu continuaria com o mesmo problema de ter que escrever a mesmasendRequest()
função em cada método.