Este é um desafio do tipo rei da colina para Dots and Boxes (também conhecido como Pen the Pig). O jogo é simples, por sua vez, basta desenhar uma linha em uma cerca vazia. Toda vez que você completar um quadrado, você ganha um ponto. Além disso, como jogamos de acordo com as regras do campeonato , se você completar pelo menos um quadrado no seu turno, terá um turno extra. Este é um torneio round robin, em que cada bot joga um com o outro duas vezes 12 vezes em uma grade 9x9. Confira esta partida entre dois titãs pesados, onde o ChainCollector faz carne picada do co-campeão Asdf:
Regras
- 0,5 segundo limite de tempo por movimento.
- Não interfere com outros bots.
- Use PigPen.random () e PigPen.random (int) para aleatoriedade.
- Nenhuma gravação em arquivos.
- O Bot e todos os seus dados persistentes serão redefinidos toda vez que o oponente mudar (a cada 12 rodadas).
Bots
Cada bot estende o Player.java:
package pigpen;
public abstract class Player {
public abstract int[] pick(Board board, int id, int round);
}
Board
é o tabuleiro de jogo, que serve principalmente para dar acesso às Pen
classes, e id
é o seu ID do jogador (informa se você é o primeiro ou o segundo), round
informa qual rodada você joga contra o mesmo oponente (1 ou 2). O valor de retorno é um int[]
, onde o primeiro elemento é o penID (indexado a 1) e o segundo elemento é o fenceID (indexado a 0). VejoPen.pick(int)
uma maneira fácil de gerar esse valor de retorno. Veja a página do Github para exemplo de players e JavaDoc. Como estamos usando apenas uma grade quadrada, ignore quaisquer funções e campos relacionados aos hexágonos.
Como executar
- Faça o download do Source do Github.
- Escreva o bot do seu controlador (certifique-se de incluir
package pigpen.players
) e coloque-o nosrc/
pasta; - Compile com
javac -cp src/* -d . src/*.java
. Executar comjava pigpen.Tournament 4 9 9 false
(os dois últimos números podem ser alterados para ajustar o tamanho da grade. A última variável deve ser configurada apenastrue
se você desejar usar o software pp_record.)
Pontuações
- Coletor de Corrente: 72
- Asdf: 57
- Lazybones: 51
- Finalizador: 36
- = Jogador linear: 18
- = Jogador para trás: 18
- RandomPlayer: 0
Veja também:
Nota : este jogo é um desafio competitivo e não é facilmente solucionável, devido a dar aos jogadores um turno extra para completar uma caixa.
Agradecemos a Nathan Merrill e Darrel Hoffman pela consultoria sobre este desafio!
Atualizações :
- Adicionado um
moves(int player)
método à classe Board para obter uma lista de todos os movimentos que um jogador fez.
Recompensa indefinida (100 Rep) :
Primeira pessoa a postar uma solução que vence todas as rodadas e usa estratégia (ajustando o jogo com base na observação de como o adversário joga).
fonte
Respostas:
Lazybones
Este bot é preguiçoso. Ele escolhe um ponto e direção aleatórios e continua a construir nessa direção sem se mover muito. Existem apenas 2 casos em que ele faz algo diferente:
fonte
pen.n(Pen.LEFT)
(função vizinha).pick()
método agora tem umint round
parâmetro no final, portanto, se você puder adicioná-lo.ChainCollector
Este bot gosta de cadeias 1 . Ele quer o máximo deles possível. Às vezes ele até sacrifica uma pequena parte de uma corrente para ganhar uma maior.
[1] Uma corrente consiste em canetas conectadas por cercas abertas, onde cada caneta possui 1 ou 2 cercas abertas. Se uma única caneta pertencente à cadeia puder ser finalizada, por causa da regra do campeonato, toda a cadeia também poderá ser finalizada.
fonte
Finalizador
Usa um comparador para escolher a caneta com as cercas mais disponíveis, mas prioriza as caneta com apenas 1 vedação disponível. (7 é usado em vez de 5 para permitir que esse código funcione também no modo hexagonal)
fonte
Asdf
Atribui uma pontuação a cada cerca e, em seguida, escolhe o melhor deles. Por exemplo: Uma caneta com uma cerca aberta tem uma pontuação de 10, enquanto uma caneta com 2 cercas abertas tem uma pontuação de -8.
Parece que Lazybones usa uma estratégia semelhante, porque está ligada a esse bot.
fonte
LinearPlayer
A maneira mais fácil de escrever esse bot é na verdade
return null
, porque uma entrada inválida selecionará automaticamente a primeira cerca disponível. Este código não usa métodos de atalho e gera manualmente o valor de retorno.fonte
BackwardPlayer
Este código usa o método de atalho
Pen.pick(int)
para gerar o valor de retorno. Se a cerca superior não estiver disponível, ela escolherá a cerca disponível mais próxima no sentido horário.fonte
RandomPlayer
Mesma idéia que o BackwardPlayer, mas seleciona aleatoriamente uma caneta. Observe que as
+1
Canetas são indexadas em 1.fonte