Concurso concluído! Leia os comentários nos blobs para ver a pontuação deles.
Este KoTH é inspirado livremente pela simulação de seleção natural da Primer . Seu bot é um blob. Para sobreviver, você deve comer pellets para recuperar a energia, que é usada para se mover. Com energia extra, os blobs podem se dividir em dois.
Energia e Movimento
Seu blob começa a cada rodada com 100 de energia e não tem limite na quantidade de energia que pode coletar. Cada rodada é executada em turnos, com cada blob tendo a opção de mover para o norte, leste, sul ou oeste em qualquer turno ou ficar parada. Mover usa 1 energia e ficar parado usa 0,25 energia. O comprimento lateral do mapa éceil(0.25 * blobCount) * 2 - 1
unidades, com um mínimo de 9 unidades. Todos os blobs começam na borda do mapa, com um colocado em cada canto e cada blob subseqüente sendo colocado a 2 unidades de qualquer outro. A cada 30 turnos, uma onda de pellets é colocada em pontos aleatórios ao redor do mapa, a pelo menos 1 unidade de qualquer borda. Cada vez que uma onda de pellets aparece, a quantidade de pellets (originalmente duas vezes o número de blobs ou a largura do mapa, o que for maior) na próxima onda é reduzida em 1, forçando o número de blobs a diminuir ao longo do tempo. Cada pellet restaura entre 5 e 15 energia. Quando a energia de um blob é menor ou igual a 0, ela morre.
Comendo
Se dois ou mais blobs tentarem ocupar o mesmo local, aquele com mais energia consumirá os outros, recebendo sua energia. Se ambos têm energia igual, ambos desaparecem.
Detecção e Informação
Os blobs podem ver pellets ou outros blobs a uma distância de 4 unidades. Quando suas funções são chamadas, os blobs são fornecidos com:
- O comprimento lateral do mapa
- A posição do blob no mapa
- As posições de todos os pellets dentro do raio de pesquisa e os valores
- As posições de todos os blobs dentro do raio de pesquisa, assim como a energia e os UIDs
- A energia, o UID e os locais do blob cuja função está sendo executada
- Um objeto de armazenamento exclusivo para o blob
- Um objeto de armazenamento compartilhado por todos os blobs relacionados ao blob através da divisão
Divisão
Se um blob tiver mais de 50 de energia, poderá optar por dividir. A divisão custa 50 de energia e a energia restante é dividida igualmente entre os dois blobs. Todos os blobs são originais ou cópias divididas, com cada cópia retornando a um original. Todos esses juntos são "parentes". Todos os parentes têm um objeto de armazenamento comum. Os parentes ainda podem comer um ao outro e podem se dividir, usar seu próprio objeto de armazenamento ou coletar energia sem afetar os outros.
Transferencia de energia
Se dois blobs estiverem próximos um do outro (após o movimento), um dos bots pode transferir energia para o outro. Isto é feito através da devolução SendNorth(amt)
, SendEast(amt)
, SendSouth(amt)
, ou SendWest(amt)
, com amt
sendo um número que representa a quantidade enviada. Pode ser qualquer quantia que o remetente possa pagar, incluindo toda a sua energia. Recomenda-se que o blob que está recebendo energia fique parado durante o armazenamento comunitário, para que ele não se afaste quando a energia estiver sendo transferida (embora a energia não seja deduzida do total do remetente nesse caso).
Funções, armazenamento e UIDs
Para permitir comportamentos de aprendizado mais complexos, todos os blobs receberão um UID inteiro (Identificador Único). Esses UIDs serão gerados aleatoriamente a cada mapa, impedindo estratégias baseadas em destinos individuais. Quando a função de um blob é chamada, são transmitidos quatro argumentos:
- O comprimento lateral do mapa como um número inteiro
- Um objeto com duas matrizes:,
pellets
eblobs
. Ambas as matrizes contêm objetos, ambos com umapos
propriedade contendo a posição do pellet ou blob formatada como[x,y]
. Os pellets terão umaenergy
propriedade, enquanto os blobs terão umauid
propriedade e umaenergy
propriedade - Um objecto contendo várias propriedades da gota que é passado para:
energy
,uid
, epos
. Apos
matriz está formatada como[x,y]
- Um objeto que contém os dois objetos de armazenamento do blob. Uma
self
propriedade contém um objeto de armazenamento individual que pode ser modificado da maneira que o blob considerar adequado (manipulando propriedades do objeto que é passado) e umacommunal
propriedade que pode ser modificada por qualquer parente.
Os blobs não são movidos imediatamente para evitar que as curvas anteriores / posteriores tenham uma vantagem. Todos os movimentos são processados em grupos. energia independente de se isso traria sua energia total acima de 0.
Para que os blobs relativos se reconheçam, o armazenamento comum deve ser usado para que cada blob registre seu UID em uma matriz ou através de algum outro sistema.
Retornar valores
Para mover ou dividir, o valor de retorno da função é usado. Primeiro, o significado das direções cardinais em termos de coordenadas:
- Norte = -Y
- Leste = + X
- Sul = + Y
- Oeste = -X
Observe que [0,0]
é o canto superior esquerdo e Y aumenta à medida que você desce. O valor de retorno da função deve seguir estas regras:
- Para não fazer nada: não retorne nada, 0, nulo, indefinido, falso ou qualquer outro valor que seja igual a falso
- Para mover: retorne uma das quatro variáveis globais: norte, leste, sul ou oeste, que equivale a "norte", "leste", "sul" ou "oeste" (que também pode ser usado como valor de retorno)
- Para dividir: retorne a variável global SplitNorth, SplitEast, SplitSouth ou SplitWest, a direção que indica onde colocar o novo blob
Se um comando de divisão for retornado e a quantidade de energia necessária for maior ou igual à energia do blob, nada acontecerá. Os blobs não poderão sair do mapa.
Funções de biblioteca predefinidas
Existem algumas funções básicas disponíveis por padrão, para economizar tempo:
taxiDist (pt1, pt2)
Retorna a distância do táxi entre dois pontos (distância X mais distância Y).
taxiDist([0, 0], [2, 2]) //4
taxiDist([3, 4], [1, 5]) //3
taxiDist([1.25, 1.3], [1.3, 1.4]) //0.15
taxiDist([0, 0], [5, 2.5], 2.5) //3
taxiDist([0, 0], [2, 4], 2.5) //2.4
hypotDist (pt1, pt2)
Retorna a distância entre dois pontos de acordo com o teorema de Pitágoras
hypotDist([0, 0], [5, 12]) //13
hypotDist([4, 6], [8, 9]) //5
hypotDist([0, 1], [2, 1]) //2
hypotDist([1, 1], [2, 2]) //sqrt(2)
modDir (dir, amt)
Toma a direção inserida, gira 90 graus no sentido amt
horário e retorna o novo valor.
modDist(North, 1) //East
modDist(East, 2) //West
modDist(West, 3) //South
modDist(South, 4) //South
Blob de exemplo
Este blob não se moverá até encontrar um pellet próximo. Então, ele se moverá na direção que achar mais provável de recompensá-lo. Se sua energia estiver sempre acima de 150, ela se dividirá.
function(map, near, me, storage) {
if (me.energy > 150)
return SplitNorth;
if (!near.pellets.length)
return null;
var dirs = [0, 0, 0, 0];
for (let p, i = 0; i < near.pellets.length; i++) {
p = near.pellets[i];
dirs[0] += me.pos[1] - p.pos[1];
dirs[1] += p.pos[0] - me.pos[0];
dirs[2] += p.pos[1] - me.pos[1];
dirs[3] += me.pos[0] - p.pos[0];
}
return [North, East, South, West][dirs.indexOf(Math.max(...dirs))];
}
Regras
- As brechas padrão são proibidas. Além disso, não há brechas incomuns.
- Nenhum blob pode tentar modificar ou ler quaisquer dados que não foram passados para ele através de seus parâmetros
- Nenhum blob pode tentar modificar uma variável de valor de retorno para sabotar outros blobs
- Uma rodada dura até que os únicos blobs restantes sejam parentes
- Nenhum blob pode modificar dados injetando funções em seus parâmetros que modificam valores usando a
this
palavra - chave - Todos os envios devem estar em Javascript ou em um idioma que não seja muito diferente do Javascript (Python, por exemplo). Todas as respostas serão convertidas em Javascript para a competição.
- O vencedor é o blob que coletou a maior quantidade de energia no total em todas as rodadas (de bolinhas ou consumindo blobs menores que não são parentes)
Controlador: https://gist.github.com/RedwolfPrograms/1facc0afe24c5dfd3ada8b8a2c493242
Chatroom: https://chat.stackexchange.com/rooms/93370/hungry-blobs-koth
fonte
Respostas:
Introvertido
O Introvertido não gosta de outras bolhas. Quando vê um borrão não relacionado, come-o, se puder, e, relutantemente, aceita sua presença, se não pode, embora foge se vê sinais de agressão. Quando vê um blob relacionado , ele se distancia. No entanto, não pode deixar de dividir muito.
Detalhes técnicos
O principal recurso desse blob é separar e espalhar para maximizar a visão combinada dos blobs. Também emprega um sistema para impedir que dois deles competam por um pellet.
fonte
Refeição Animada
Um bot simples, apenas para começar a competição. Encontra a moeda mais próxima e vai em sua direção. Baseado no bot de exemplo.
fonte
testador de bloblib
O bot real é bastante simples, mas isso é mais projetado como uma prova de conceito
bloblib
, uma coleção de funções e funcionalidades que planejo usar e desenvolver em outros bots (fique à vontade para usar / expandir também)Em resumo, este bot faz o seguinte:
fonte
Covarde ganancioso
Ou, em JavaScript,
Este bot não é muito interessante. Ele atua de acordo com duas prioridades:
Ele nunca cospe para maximizar sua capacidade de comer outras coisas.
fonte
SafetyBlob
Este bot usa algumas das mesmas lógicas do Safetycoin do KOTH anterior.
Como funciona
Esse bot seguirá em direção a comida que pode ser alcançada antes de qualquer robô maior ou ao mesmo tempo / antes de um robô menor. Se não conseguir ver nenhum alimento que atenda a esses critérios, ele se moverá em uma direção aleatória (inclinado em direção ao centro). Se atingir 150 de energia e não conseguir ver alimentos seguros, ele se dividirá em uma das direções que rotulou como seguras de se mover.
Este bot não controla seus próprios filhos, mas eles não devem colidir de qualquer maneira devido aos mecanismos de segurança.
fonte