KOTH assimétrico: pegue o gato
ATUALIZAÇÃO : Os arquivos gist são atualizados (incluindo novas submissões), pois o Controller.java não capturou Exceções (apenas erros). Agora ele captura erros e exceções e também os imprime.
Este desafio consiste em duas linhas, esta é a linha de captura, a linha de gato pode ser encontrada aqui .
O controlador pode ser baixado aqui .
Este é um KOTH assimétrico: Cada envio é um gato ou um coletor . Existem jogos entre cada par de gato e apanhador. Os gatos e os coletores têm classificações separadas.
Apanhador
Há um gato em uma grade hexagonal. Sua tarefa é capturá-lo o mais rápido possível. A cada turno, você pode colocar um balde de água em uma célula da grade para impedir que o gato possa ir para lá. Mas o gato não é (talvez) tão burro, e sempre que você coloca um balde, ele se move para outra célula da grade. Como a grade é hexagonal, o gato pode ir em 6 direções diferentes. Seu objetivo é cercar o gato com baldes de água, quanto mais rápido, melhor.
Gato
Você sabe que o apanhador quer pegá-lo colocando baldes de água ao seu redor. Claro que você tenta fugir, mas como você é um gato preguiçoso (como os gatos), você dá exatamente um passo de cada vez. Isso significa que você não pode ficar no mesmo lugar que você, mas você precisa se mudar para um dos seis pontos circundantes. Sempre que vir que o apanhador colocou um novo balde de água, você vai para outra célula. Claro que você tenta fugir o maior tempo possível.
Rede
A grade é hexagonal, mas como não temos estruturas de dados hexagonais, pegamos uma 11 x 11
matriz quadrada em 2d e imitamos o 'comportamento' hexagonal de que o gato só pode se mover em 6 direções:
A topologia é toroidal, ou seja, se você pisar em uma célula 'fora' da matriz, você será transferido para a célula correspondente do outro lado da matriz.
jogos
O gato começa em uma determinada posição na grade. O apanhador pode fazer o primeiro movimento, depois o gato e seu apanhador se movem alternadamente até o gato ser pego. O número de etapas é a pontuação para esse jogo. O gato tenta obter uma pontuação o melhor possível, o apanhador tenta obter uma pontuação o mais baixa possível. A soma média de todos os jogos em que você participou será a pontuação do seu envio. Existem dois rankings separados, um para o gato e outro para os coletores.
Controlador
O controlador fornecido é escrito em Java. Como apanhador ou gato, cada um de vocês precisa implementar uma classe Java (já existem alguns exemplos primitivos) e colocá-la no players
pacote (e atualizar a lista de gatos / apanhadores na classe Controller), mas você também pode escrever funções adicionais dentro dessa classe. O controlador vem com cada dois exemplos de trabalho de classes simples de gatos / coletores.
O campo é uma matriz 11 x 11
2D int
que armazena os valores dos estados atuais das células. Se uma célula estiver vazia, ela terá valor 0
, se houver um gato, ela terá valor -1
e, se houver um balde, haverá a 1
.
Existem algumas funções que você pode usar: isValidMove()
/ serve isValidPosition()
para verificar se a sua jogada (gato) / posição (apanhador) é válida.
Cada vez que é a sua vez, sua função takeTurn()
é chamada. O argumento contém uma cópia da grade atual e métodos como read(i,j)
para ler a célula em (i,j)
, além de isValidMove()/ isValidPosition()
verificar a validade de sua resposta. Isso também gerencia o encapsulamento da topologia toroidal, ou seja, mesmo que a grade seja apenas 11 x 11, você ainda pode acessar a célula (-5,13).
O método deve retornar uma int
matriz de dois elementos, que representam possíveis movimentos. Para os gatos, estes são os {-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}
que representam a posição relativa de onde o gato quer ir, e os coletores retornam as coordenadas absolutas de onde querem colocar um balde {i,j}
.
Se seu método produzir uma movimentação inválida, seu envio será desqualificado. A movimentação é considerada inválida, se o seu destino já for um depósito ou a movimentação não for permitida / destino já ocupado (como um gato) ou se já houver um depósito / gato (como um coletor). Você pode verificar isso antes com as funções fornecidas.
Seu envio deve funcionar razoavelmente rápido. Se o seu método demorar mais de 200 ms para cada etapa, ele também será desqualificado. (De preferência muito menos ...)
Os programas têm permissão para armazenar informações entre as etapas.
Submissões
- Você pode fazer quantos envios quiser.
- Não altere significativamente os envios que você já enviou.
- Por favor, cada envio em uma nova resposta.
- Cada envio deve preferencialmente ter seu nome exclusivo.
- O envio deve consistir no código da sua turma, bem como uma descrição que nos diga como o seu envio funciona.
- Você pode escrever a linha
<!-- language: lang-java -->
antes do código fonte para obter o realce automático da sintaxe.
Pontuação
Todos os gatos competirão contra todos os coletores no mesmo número de vezes. Vou tentar atualizar as pontuações atuais com frequência, os vencedores serão determinados quando a atividade diminuir.
Este desafio é inspirado neste jogo flash antigo
Agradecemos à @PhiNotPi por testar e fornecer alguns comentários construtivos.
Pontuações atuais (100 jogos por emparelhamento)
Name Score Rank Author
RandCatcher 191674 8 flawr
StupidFill 214246 9 flawr
Achilles 76820 6 The E
Agamemnon 74844 5 The E
CloseCatcher 54920 4 randomra
ForwordCatcher 94246 7 MegaTom
Dijkstra 46500 2 TheNumberOne
HexCatcher 48832 3 randomra
ChoiceCatcher 43828 1 randomra
RandCat 77928 7 flawr
StupidRightCat 81794 6 flawr
SpiralCat 93868 5 CoolGuy
StraightCat 82452 9 CoolGuy
FreeCat 106304 3 randomra
RabidCat 77770 8 cain
Dijkstra's Cat 114670 1 TheNumberOne
MaxCat 97768 4 Manu
ChoiceCat 113356 2 randomra
PRINT_STEPS = true
mais detalhadas no arquivoMyFrame.java
). Então gravei isso no LICEcap e editei no GIMP . Se você tiver mais perguntas, basta perguntar!Respostas:
Aquiles
Aquiles não é muito inteligente, mas ele é implacavelmente eficiente. Primeiro, ele impede que o gato use o envoltório do tabuleiro e depois divide o tabuleiro em dois. Então ele continua dividindo a parte do tabuleiro em que o gato está dividido ao meio até que ele fique preso.
Demonstração RandCat vs Achilles
fonte
Agamenon
Agamenon divide a área dos gatos ao meio com uma linha vertical até que o gato tenha apenas uma faixa de largura 2 para se mover, e nesse ponto ele prende o gato.
Agamemnon vs RandCat:
Esse apanhador é consistentemente melhor que Aquiles e acho que ele é diferente o suficiente para justificar uma nova resposta.
fonte
HexCatcher
Se o apanhador conseguir colocar o gato dentro de um grande hexágono com 3 unidades laterais, onde os cantos do hexágono já estão ocupados por baldes, o apanhador pode manter o gato nessa área e pegá-lo. O hexágono fica assim:
É isso que o HexCatcher tenta alcançar. Ele mentalmente ladrilha o campo com esses grandes hexágonos de maneira que cada célula de canto faça parte de três grandes hexágonos.
Se houver uma chance de manter o gato na área atual conectando dois cantos ao lado do gato, o bot fará isso. (Por exemplo, na imagem, se o gato estiver em 7,5, escolhemos 7,6, mesmo que apenas as células 6,6 e 8,5 ainda estejam ocupadas.)
Se o anterior não for uma opção, escolhemos tocar um canto que faz parte da área onde o gato está. Se todos esses cantos já tiverem sido escolhidos (como na imagem), escolhemos uma célula ao lado do gato.
São possíveis vários pequenos aprimoramentos, como lidar melhor com o acondicionamento (o lado a lado é quebrado) ou fazer o último par de movimentos otimizados. Eu posso fazer algumas delas. Se não for permitido, apenas o anexarei (fora de competição) aos interessados.
DijkstrasCat vs HexCatcher:
fonte
CloseCatcher
Escolhe uma das posições em que o gato pode pisar na próxima etapa. Ele escolhe aquele que daria os caminhos mais possíveis após 3 etapas para o gato se ele se mudasse para lá e o campo não mudasse.
O código é quase idêntico à minha entrada Cat, FreeCat , que escolhe a direção de uma maneira muito semelhante.
SpiralCat vs CloseCatcher:
fonte
Dijkstra
Ele não gosta muito de gatos (:
v{ >
FreeCat vs Dijkstra
(necessidades atualizadas):Como ele tenta pegar o gato:
Ele analisa todos os quadrados do quadro e tenta encontrar o quadrado que minimiza a abertura do quadro e maximiza o quanto o quadro é esticado; em relação ao gato. A abertura e rigidez de uma placa são calculadas usando uma modificação de seu famoso algoritmo .
Abertura:
A abertura de uma placa em relação a uma posição é o número de posições alcançáveis a partir dessa posição.
Rigidez:
A rigidez de uma placa em relação a uma posição é a soma das distâncias entre as posições alcançáveis e a posição.
Com a última atualização:
Agora, ele é muito melhor em pegar o
FreeCat e seu próprio gato,todos os gatos.Infelizmente, ele também é muito pior em capturar os gatos loucos que não cooperam. Ele poderia ser melhorado, detectando se o gato é um dos loucos e depois atuando como CloseCatcher.Erro corrigido.
fonte
error: cannot infer type arguments for PriorityQueue<>
nesta linhaPriorityQueue<int[]> open = new PriorityQueue<>(new Comparator<int[]>() {
.int[]
entre os dois diamantes vazios depoisPriorityQueue
.ForwordCatcher
Coloca um balde na frente do gato, ou, se for levado, coloca atrás.
RabidCat vs ForwordCatcher:
fonte
ChoiceCatcher
Usa o mesmo mecanismo de pontuação da minha entrada ChoiceCat . Há uma pequena modificação que ajuda a escolher células relevantes nas primeiras etapas, pois o ChoiceCat não se importa com os primeiros baldes, pois não os vê como ameaça.
O ChoiceCatcher parece ter uma pontuação consideravelmente melhor do que os atuais coletores.
ChoiceCat vs ChoiceCatcher:
fonte
RandCatcher
Isso foi feito apenas para testar o controlador e coloca os baldes aleatoriamente (de maneira muito ineficiente).
fonte
StupidFillCatcher
Isso foi feito apenas para testar o controlador. Apenas preenche coluna por coluna até o gato ser pego.
fonte