Código Bots 4: Programação Funcional


25

sheesh, este é realmente o quarto? Para todos os veteranos, o principal desafio é o mesmo, mas estamos usando Java em vez de uma linguagem personalizada. Aqui estão os três últimos desafios do CodeBot , caso você esteja interessado.

O objetivo do CodeBots é tornar seu bot o mais viral possível . Cada bot carrega uma bandeira e você precisa garantir que sua bandeira esteja em todo lugar .

API

Os bots seguirão um "protocolo" padronizado e os bots progredirão pelas seguintes etapas de forma síncrona:

  1. IPAddress selectMessageRecipient() permite que um bot escolha para quem ele deseja enviar uma mensagem "amigável".
  2. Message sendMessage() permite que um bot escolha o conteúdo da mensagem que ele enviará.
  3. processMessage(IPAddress, Message) é chamado para cada mensagem que um bot recebe.
  4. FunctionType selectFunctionToBlock()impede que uma função seja substituída na curva atual. Veja o passo 7.
  5. IPAddress selectAttackTarget()permite que um bot escolha quem ele quer DDOS. Um ataque DDOS será bem-sucedido se o bot for direcionado por 3 bots ao mesmo tempo. Se um ataque for bem-sucedido, cada um dos invasores poderá executar as etapas 6 e 7.
  6. readData(ReadonlyBot) permite que um bot leia os dados armazenados no bot vulnerável.
  7. FunctionType selectFunctionToReplace()é o cerne desse desafio . Você tem permissão para selecionar 1 função (das 8 listadas aqui) para copiar do seu bot para o bot dele. Então, sua função será chamada em vez da deles . Se vários bots selecionam a mesma função, uma aleatória será bem-sucedida.
  8. String getFlag()é chamado no final do jogo e deve retornar uma sequência única para o seu envio. Sua função sempre deve retornar a mesma string. A finalização com o maior número de bandeiras no final do jogo vence.

Armazenamento

Você tem três formas de armazenamento, um Catálogo de endereços , um Registro e Variáveis . Essas formas de armazenamento são locais para o bot em que sua função está sendo executada (portanto, se sua função for copiada, o conteúdo de cada um desses objetos será diferente). Todos esses objetos podem ser modificados ou limpos manualmente. Para obter esses objetos, você tem um getter em sua classe (por exemplo getLog()).

O AddressBook armazena uma lista de IPAddress , cada um com um AddressType , que permite classificar os diferentes tipos de endereços. O Catálogo de Endereços sempre conterá pelo menos 1 endereço (se estiver limpo, será adicionado um aleatório). A limpeza do seu AddressBook para obter vários endereços IP não é permitida.

O Log armazena uma lista de todas as ações executadas, bem como dados sobre a ação. Também inclui um histórico de todos os ataques bem-sucedidos (embora você não saiba quais funções eles substituem)

O objeto Variables permite armazenar variáveis ​​de string anexadas a um nome de string. No início do jogo, Variáveis conterão uma única variável, IDque contém um ID gerado aleatoriamente, exclusivo para o seu tipo de bot.

Você também tem outras funções de acesso:

  • int getTurnNumber() retorna um número inteiro com a curva atual
  • bool functionsMatch(ReadonlyBot, FunctionType) testes para ver se a função do ReadonlyBot corresponde à sua
  • IPAddress personalAddress() retorna seu endereço IP

Como implementar

  • Você pode obter o código no Github
  • Adicione seu bot à \botspasta e, em seguida, adicione uma referência ao seu bot emcontroller\CodeBotFactory.java
  • Seu bot deve estender codebots.bot.CodeBotoucodebots.bots.DefaultCodeBot
  • Você precisa do Java 8 se quiser executar o controlador.
  • Você pode executar o código (supondo que você esteja na /srcpasta) usando javac codebots\*.javapara compilar e depois java codebots.Mainexecutar.
  • Você pode não ter quaisquer variáveis de membro não-constantes em sua classe
  • Reflexão não é permitida.
  • Formas de comunicação entre bots (do mesmo tipo ou de tipos diferentes) fora dos métodos listados acima não são permitidas.
  • Bots mudos e / ou suicidas são permitidos, mas todos os bots devem ser funcionalmente diferentes das entradas existentes.
  • Se você quiser aleatoriedade no seu bot, use getRandom()
  • Por favor, tente manter seu código eficiente. Passei muito tempo analisando e tornando o controlador rápido.

Pontuações

105.2501 Expelliarmus!
104.5803 Estou ajudando!
104.2746 Quem sou eu?
103.8529 Dumb Bot
103.2028 Substituto
102.7045 Caos
102.4046 Hermit Bot
102.2849 Swarmer
100.5598 O bot aleatório ama você
99.966 Confie na confiança!
99.0185 codebots.bots.DefaultCodeBot
91.2942 codebots.bots.MarkedBot
91.1423 Apenas seu e-mail de vizinhança amigável que fornece robô.
89,4645 null


Você provavelmente deve tornar o Log.LogEntry final, com ele não final. Posso criar logs com qualquer informação que eu queira ... que apenas a minha função bot possa ler ou criar.
TheNumberOne

O readData pode acessar o IpAddress do bot que está lendo?
TheNumberOne

@TheNumberOne não atualmente, mas não vejo por que não. Não tenho o código agora, mas atualizarei o código para alterar isso.
Nathan Merrill

3
Acho interessante que o Chaos faça com que o DisarmBot e o MarkedBot sejam colocados no quadro de líderes.
TheNumberOne

1
Atualmente na rodada 7850 de 10000, obtendo pontuações mais precisas ...
LegionMammal978

Respostas:


4

TrustBot

Se você enviar uma mensagem para ele, ele fará o que diz. Se ele ler um bot, ele copiará os endereços diretamente em seu livro. Ele ataca os bots que o catálogo de endereços diz para atacar.

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.*;
import java.util.*;

public class TrustBot extends CodeBot {
    @Override
    public IPAddress selectMessageRecipient() {
        AddressBook book = getAddressBook();
        return book.getAddress(getRandom().nextInt(book.size()));
    }

    @Override
    public Message sendMessage() {
        AddressBook book = getAddressBook();
        return new Message(Message.MessageType.INFORM, book.getAddress(getRandom().nextInt(book.size())));
    }

    @Override
    public void processMessage(IPAddress s, Message m) {
        AddressBook book = getAddressBook();
        if(m.getAddress() != null){
            if(m.getType() == Message.MessageType.ATTACK){
                book.add(m.getAddress(), AddressBook.AddressType.TO_ATTACK);
            }
            else if(m.getType() == Message.MessageType.HELP){
                book.add(m.getAddress(), AddressBook.AddressType.TO_DEFEND);
            }
            else if(m.getType() == Message.MessageType.CONFIRM){
                book.add(m.getAddress(), AddressBook.AddressType.TRUSTED);
            }
            else if(m.getType() == Message.MessageType.REJECT){
                book.add(m.getAddress(), AddressBook.AddressType.UNTRUSTED);
            }
            else if(m.getType() == Message.MessageType.AVOID){
                book.remove(m.getAddress());
            }
            else{
                book.add(m.getAddress());
            }
        }else{
            Message msg = new Message(m.getType(), s);
            processMessage(s, msg);
        }
    }

    @Override
    public FunctionType selectFunctionToBlock() {
        return FunctionType.SELECT_FUNCTION_TO_BLOCK;
    }

    @Override
    public IPAddress selectAttackTarget() {
        AddressBook book = getAddressBook();
        List<IPAddress> l;
        l = book.getAddressesOfType(AddressBook.AddressType.TO_ATTACK);
        Iterator<IPAddress> I = l.iterator();
        if(!I.hasNext())
            return book.getAddress(getRandom().nextInt(book.size()));
        return I.next();
    }

    @Override
    public void readData(ReadonlyBot bot) {
        AddressBook myBook = getAddressBook();
        ReadonlyAddressBook hisBook = bot.getAddressBook();
        AddressBook.AddressType[] values = AddressBook.AddressType.values();
        for(int i=0;i<values.length;i++){
            myBook.addAll(hisBook.getAddressesOfType(values[i]), values[i]);
        }
    }

    @Override
    public FunctionType selectFunctionToReplace() {
        return getRandom().nextInt(2)==1?FunctionType.GET_FLAG:FunctionType.SELECT_FUNCTION_TO_BLOCK;
    }

    @Override
    public String getFlag() {
        return "Trust in Trust!";
    }
}

4

AmnesiaBot

Um bot aleatório que injeta outros bots com código de perda de memória. Cada função começa com o código para limpar o log, o Catálogo de endereços e as variáveis. Este código fará com que os bots inteligentes percam memória, na tentativa de acabar com a lógica.

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.*;

public class AmnesiaBot extends CodeBot {

    private void clear(){
        getAddressBook().clear();
        getAddressBook().add(getAddressBook().getAddress(0), AddressBook.AddressType.TRUSTED);
        getVariables().clear();
        getLog().clear();
    }

    @Override
    public IPAddress selectMessageRecipient() {
        clear();
        return getAddressBook().getAddress(0);
    }

    @Override
    public Message sendMessage() {
        clear();
        Message.MessageType[] values = Message.MessageType.values();
        return new Message(values[getRandom().nextInt(values.length)], getAddressBook().getAddress(0));
    }

    @Override
    public void processMessage(IPAddress source, Message message) {
        clear();
    }

    @Override
    public FunctionType selectFunctionToBlock() {
        clear();
        return getTurnNumber() % 2 == 0 ?
             FunctionType.GET_FLAG: FunctionType.SELECT_FUNCTION_TO_BLOCK;
    }

    @Override
    public IPAddress selectAttackTarget() {
        clear();
        return getAddressBook().getAddress(0);
    }

    @Override
    public void readData(ReadonlyBot bot) {
        clear();
    }

    @Override
    public FunctionType selectFunctionToReplace() {
        clear();
        FunctionType[] values =  FunctionType.values();
        return values[getRandom().nextInt(values.length)];
        //random gives a 7/8 chance of successes. 
    }

    @Override
    public String getFlag() {
        return "Who Am I?";
    }
}

Eu acho que este ganha apenas devido à incapacidade de um script mais inteligente ser capaz de lembrar de qualquer coisa. ou seja, limpar o objeto Variáveis ​​é realmente poderoso.
Draco18s

@ draco18s este não era realmente ment ser uma resposta séria ...
MegaTom

Eu sei! É por isso que estou tão confuso com isso. XD
Draco18

3

NullBot

A bandeira dele é muito ... característica ...

package codebots.bots;
import codebots.gameobjects.*;
public class NullBot extends DefaultCodeBot {
    public IPAddress selectMessageRecipient() {
        return null;
    }
    public Message sendMessage() {
        return null;
    }
    public IPAddress selectAttackTarget() {
        return null;
    }
    public FunctionType selectFunctionToReplace() {
        return null;
    }
    public FunctionType selectFunctionToBlock() {
        return null;
    }
    public String getFlag(){
        return null;
    }
}

Isso também serve para testar o controlador e os limites da regra "são permitidos bots burros".


Tecnicamente, ele não se encaixa na especificação, porque ele não retorna exatamente uma String para sua bandeira.
TheNumberOne

3
nullé uma string. ;) Apenas uma string sofisticada.
Addison Crump

Isso me fez reconhecer uma falha na minha especificação, que foi especificada: "todos os bots devem ser funcionalmente diferentes das entradas existentes"
Nathan Merrill

@NathanMerrill Corrigido para seguir mais de perto as especificações.
TheNumberOne

3

RandomCodeBot

Entrada aleatória obrigatória no KoTH

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.AddressBook;
import codebots.gameobjects.FunctionType;
import codebots.gameobjects.IPAddress;
import codebots.gameobjects.Message;

public class RandomCodeBot extends CodeBot {

    @Override
    public IPAddress selectMessageRecipient() {
        AddressBook book = getAddressBook();
        return book.getAddress(getRandom().nextInt(book.size()));
    }

    @Override
    public Message sendMessage() {
        Message.MessageType[] values = Message.MessageType.values();
        return new Message(values[getRandom().nextInt(values.length)]);
    }

    @Override
    public void processMessage(IPAddress source, Message message) {

    }

    @Override
    public FunctionType selectFunctionToBlock() {
        FunctionType[] values =  FunctionType.values();
        return values[getRandom().nextInt(values.length)];
    }

    @Override
    public IPAddress selectAttackTarget() {
        AddressBook book = getAddressBook();
        return book.getAddress(getRandom().nextInt(book.size()));
    }

    @Override
    public void readData(ReadonlyBot bot) {

    }

    @Override
    public FunctionType selectFunctionToReplace() {
        FunctionType[] values =  FunctionType.values();
        return values[getRandom().nextInt(values.length)];
    }

    @Override
    public String getFlag() {
        return "Random bot loves you";
    }
}

3

DisarmerBot

O DisarmerBot não é muito inteligente. Se receber instruções de ataque, escolherá um atacante aleatório, caso contrário, atacará um jogador aleatório. Ele simplesmente substitui a selectFunctionToBlockfunção deles de bloquear selectFunctionToBlock.

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.*;

import java.util.ArrayList;
import java.util.List;

public class DisarmerBot extends CodeBot {
    public IPAddress selectMessageRecipient() { return null; }
    public Message sendMessage() { return null; }

    public void processMessage(IPAddress source, Message message) {
        if (message != null && message.getAddress() != null && message.getType() == Message.MessageType.ATTACK)
            getAddressBook().add(message.getAddress());
    }

    public IPAddress selectAttackTarget() {
        AddressBook book = getAddressBook();
        List<IPAddress> attack = book.allAddresses();
        if (attack.size() > 0) {
            IPAddress bot = attack.get(getRandom().nextInt(attack.size()));
            book.clear();
            return bot;
        }
        //Umm...
        book.clear();
        return book.getAddress(0);
    }

    public void readData(ReadonlyBot bot) { getLog().clear(); /*Safety*/ }
    public FunctionType selectFunctionToReplace() { return FunctionType.SELECT_FUNCTION_TO_BLOCK; }
    public FunctionType selectFunctionToBlock() { return FunctionType.SELECT_FUNCTION_TO_BLOCK; }
    public String getFlag() { return "Expelliarmus!"; }
}

Você pode selecionar o enésimo endereço sem precisar fazer todos os endereços (). Se você olhar para o meu bot aleatório, ele está fazendo a seleção de endereços aleatórios. Atualizei seu código no Github (por motivos de eficiência), mas se você achar que não funciona, fico feliz em revertê-lo.
Nathan Merrill

Oh, meu mal, fixo.
Nathan Merrill

3

MarkedBot

Marca-se na primeira rodada e usa essas informações nas rodadas posteriores. Dessa forma, se outro bot for injetado com seu código de ataque, ele será ineficaz.

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.*;

public class MarkedBot extends CodeBot {

    @Override
    public IPAddress selectMessageRecipient() {
        Variables v = getVariables();
        AddressBook ab = getAddressBook();
        if(getTurnNumber()==0)
            v.add(v.get("ID"),"true");
        if("true".equals(v.get("hasOurFlag"))){
            ab.remove(ab.getAddress(0));
            v.remove("hasOurFlag");
        }
        return ab.getAddress(0);
    }

    @Override
    public Message sendMessage() {
        return new Message(Message.MessageType.STOP);
    }

    @Override
    public void processMessage(IPAddress source, Message message) {
        if(message.getType() != Message.MessageType.STOP)
            getAddressBook().add(source, AddressBook.AddressType.TO_ATTACK);
    }

    @Override
    public FunctionType selectFunctionToBlock() {
        Variables v = getVariables();
        if("true".equals(v.get(v.get("ID"))))
            return FunctionType.GET_FLAG;
        return FunctionType.SELECT_FUNCTION_TO_BLOCK;
    }

    @Override
    public IPAddress selectAttackTarget() {
        Variables v = getVariables();
        if("true".equals(v.get(v.get("ID"))))
            return getAddressBook().getAddress(0);
        else
            return null;
    }

    @Override
    public void readData(ReadonlyBot bot) {
        Variables v = getVariables();
        if(functionsMatch(bot, FunctionType.GET_FLAG))
            v.add("hasOurFlag", "true");
        else if("false".equals(v.get("hasOurFlag")))
            v.add("hasOurFlag", "false2");
        else
            v.add("hasOurFlag", "false");
    }

    @Override
    public FunctionType selectFunctionToReplace() {
        Variables v = getVariables();
        if("true".equals(v.get(v.get("ID"))))
            if(!v.has("hasOurFlag") || "false".equals(v.get("hasOurFlag")))
                return FunctionType.GET_FLAG;
            else if("false2".equals(v.get("hasOurFlag")))
                return FunctionType.SELECT_FUNCTION_TO_BLOCK;
            else
                return FunctionType.SEND_MESSAGE;
        return FunctionType.SELECT_FUNCTION_TO_REPLACE;
    }

    @Override
    public String getFlag() {
        return this.getClass().getName();
    }
}

Eu encontrei vários bugs neste bot (erros de digitação, usando == em vez de iguais) Você também encontrou uma falha no meu sistema: você não deveria conseguir criar novos endereços IP aleatórios. Corrigi esse problema (e removi o código). Você pode encontrar o código atualizado no github
Nathan Merrill

Além disso, parabéns no primeiro lugar!
Nathan Merrill

HelperBot não é muito inteligente. Só ficou no topo porque todos os outros bots eram burros. : P Este é provavelmente o primeiro bot eficaz .
Draco18s

1
@NathanMerrill Isso significa que não podemos mais criar endereços IP forjados para enganar? (se isso é o caso eu vou necessidade de redesenhar meu)
Nic Robertson

Um bot nunca tem acesso intencional à rodada. Você pode usar os endereços IP dos oponentes como falsificações, mas a criação de um não é permitida. Além disso, uma constante é uma variável definida no tempo estático ou no tempo de inicialização.
Nathan Merrill

2

SwarmBot

Esse bot não bem conhecido é bastante complicado (e o mais complicado enviado até agora), mas tentei um bot que substituísse sistematicamente todos os métodos de um destino antes de passar para um novo destino. Ele tenta identificar cópias de si mesmo e tratá-las como aliadas, verificando-as periodicamente para garantir a integridade. Eu não inventei um nome melhor.

Vinculando ao ramo de repositório do github, pois esse bot tem 340 linhas.

https://github.com/Draco18s/CodeBots4/blob/master/src/codebots/bots/SwarmBot.java

Alguns pontos interessantes:

  • As linhas 14 a 24 são simplesmente uma lista não modificável que facilitou o ajuste na ordem em que o bot substitui os métodos de seu destino. Ele armazena qual índice é Variablesativado e incrementa a cada rodada. Isso deve seguir a regra "sem variáveis ​​não constantes".
  • As linhas 203-217 tratam da verificação de aliados. Na verdade, não nos importamos que outro bot implemente todas as oito instruções. Apenas quatro são essenciais e, se estiver faltando um em um aliado "confiável", o substituiremos pelo nosso.
  • As linhas 295-300 foram um aumento inesperado na eficácia. Ao proteger nossa bandeira nas duas primeiras voltas do jogo, evitamos que os robôs mudos substituam nossa bandeira antes que tenhamos uma chance de se espalhar muito longe. Esperar mais tempo, no entanto, dá a outros bots a chance de substituir nosso BlockFunction e isso causa uma degradação no desempenho (suspeita devido ao RandomBot interferir nos aliados que tentam desfazer a corrupção).
  • Por um longo período de tempo durante o desenvolvimento desse bot, esse bot fez com que o HelperBot subisse à frente, a certa altura violando a marca 130, enquanto este bot permaneceu na faixa de 81-98, mas arrastou a eficácia de MarkedBot e DefaultBot para vários pontos.
  • Este bot só foi possível com o functionsMatchmétodo adicionado . Sem functionsMatchera impossível escrever um bot que pudesse tomar decisões significativas, pois era cego. Ele poderia ler as variáveis ​​e logs dos alvos, mas não sabe nada sobre o estado do alvo.

Provavelmente ainda existem algumas melhorias possíveis, mas não as vejo. As linhas 198-205 provavelmente são um problema de desempenho, mas até que a classe IPAddress permita que os endereços sejam reconstituídos e armazenados em Variáveis, isso é necessário (como os bots não têm como validar um endereço, qualquer armazenamento de um endereço inválido faz com que o jogo agrupar um destino nulo em um ReadOnlyBot, lançando o NPE).

Editar: Atualizações 12/12/15

Ajustar alguns dos parâmetros na getTurnNumber()lógica permitiu alguns aumentos no desempenho. O aumento de 5% para 10% na segmentação no final do jogo valeu cerca de 15 pontos, aumentando igualmente a segmentação no início do jogo de 5% para 8%. Agora, esse bot combinado pode (quase) sobreviver mesmo quando confrontado com o AmnesiaaBot (alcançando o segundo lugar com uma pontuação de 110, onde o HelperBot chega a 117).

Mesmo com esses ajustes, pode ter azar, então, por 10 rodadas, seu alcance é de aproximadamente 170-185.


Impressionante! É intencional que você não possa criar IPAddresses a partir de strings.
Nathan Merrill

Bem, ostensivamente, sim! (Ou bots criarão arbitrários para encontrar novos bots). O problema é que se você fizer a simulação trava. ;)
Draco18

Na linha 143, você usa um construtor inexistente.
TheNumberOne

@TheNumberOne era válido quando eu escrevi. Nathan provavelmente atualizou a base.
Draco18s

Atualização @TheNumberOne feita. A new IPAddressligação deveria ter sido uma "consulta do catálogo de endereços", como eu havia feito readData. Eu extraí essa pesquisa e fixei a linha 143.
Draco18s

1

DefaultCodeBot

Tenta fazer coisas razoáveis. (Substitua essa classe se você não quiser implementar todas as funções)

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.FunctionType;
import codebots.gameobjects.IPAddress;
import codebots.gameobjects.Message;

public class DefaultCodeBot extends CodeBot {

    @Override
    public IPAddress selectMessageRecipient() {
        return getAddressBook().getAddress(0);
    }

    @Override
    public Message sendMessage() {
        return new Message(Message.MessageType.INFORM);
    }

    @Override
    public void processMessage(IPAddress source, Message message) {

    }

    @Override
    public FunctionType selectFunctionToBlock() {
        return FunctionType.GET_FLAG;
    }

    @Override
    public IPAddress selectAttackTarget() {
        return getAddressBook().getAddress(0);
    }

    @Override
    public void readData(ReadonlyBot bot) {

    }

    @Override
    public FunctionType selectFunctionToReplace() {
        return FunctionType.GET_FLAG;
    }

    @Override
    public String getFlag() {
        return this.getClass().getName();
    }
}

1

HelperBot

O bot auxiliar não faz nada além de tentar espalhar sua própria bandeira ... ou pelo menos a bandeira que está carregando no momento ...

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.FunctionType;
import codebots.gameobjects.IPAddress;
import codebots.gameobjects.Message;

public class HelperBot extends CodeBot {

    @Override
    public IPAddress selectMessageRecipient() {
        getAddressBook().clear();
        return getAddressBook().getAddress(0);
    }

    @Override
    public Message sendMessage() {
        return new Message(Message.MessageType.INFORM);
    }

    @Override
    public void processMessage(IPAddress source, Message message) {

    }

    @Override
    public FunctionType selectFunctionToBlock() {
        return FunctionType.GET_FLAG;
    }

    @Override
    public IPAddress selectAttackTarget() {
        getAddressBook().clear();
        return getAddressBook().getAddress(0);
    }

    @Override
    public void readData(ReadonlyBot bot) {

    }

    @Override
    public FunctionType selectFunctionToReplace() {
        return FunctionType.GET_FLAG;
    }

    @Override
    public String getFlag() {
        return "I'm Helping!";
    }
}

Se o HelperBot pressupuser que qualquer método próprio que seja sobrescrito (exceto getFlag()) será substituído por algo melhor.


1

Caos

Ele liberta todas as bandeiras da tirania de ser bloqueado.

package codebots.bots;

import codebots.bot.ReadonlyBot;
import codebots.gameobjects.FunctionType;
import codebots.gameobjects.IPAddress;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by thenumberone on 12/11/15.
 *
 * @author thenumberone
 */
public class Chaos extends DefaultCodeBot{

    private static final String NAME = "Chaos";
    private static final String BLOCK = NAME + ":BLOCK";
    private static final String ATTACK = NAME + ":ATTACK";
    private static final String REPLACE = NAME + ":REPLACE";
    private static final String READ = NAME + ":READ";
    private static final String FLAG = NAME + ":FLAG";
    private static final String SELECT = NAME + ":SELECT";
    private static final String SEND = NAME + ":SEND";

    private static final Map<String, FunctionType> commands;

    private static final String[] REPLACEMENT_ORDER = {
            BLOCK,
            FLAG,
            REPLACE,
            READ,
            ATTACK,
    };

    private static final String DEFAULT = BLOCK;
    private static final String BLOCK_FUNCTION = BLOCK;

    static {
        Map<String, FunctionType> c = new HashMap<>();
        c.put(BLOCK, FunctionType.SELECT_FUNCTION_TO_BLOCK);
        c.put(ATTACK, FunctionType.SELECT_ATTACK_TARGET);
        c.put(REPLACE, FunctionType.SELECT_FUNCTION_TO_REPLACE);
        c.put(READ, FunctionType.READ_DATA);
        c.put(FLAG, FunctionType.GET_FLAG);
        c.put(SELECT, FunctionType.SELECT_MESSAGE_RECIPIENTS);
        c.put(SEND, FunctionType.SEND_MESSAGE);
        commands = Collections.unmodifiableMap(c);
    }

    @Override
    public String getFlag() {
        return NAME;
    }

    @Override
    public void readData(ReadonlyBot bot) {
        for (String command : commands.keySet()){
            getVariables().remove(command);
        }
        for (String command : REPLACEMENT_ORDER){
            if (!functionsMatch(bot, commands.get(command))) {
                getVariables().add(command, "");
                return;
            }
        }
    }

    @Override
    public FunctionType selectFunctionToBlock() {
        return commands.get(BLOCK_FUNCTION);
    }

    @Override
    public IPAddress selectAttackTarget() {
        getAddressBook().clear();
        return getAddressBook().getAddress(0);
    }

    @Override
    public FunctionType selectFunctionToReplace() {
        for (String command : REPLACEMENT_ORDER){
            if (getVariables().has(command)) {
                getVariables().remove(command);
                return commands.get(command);
            }
        }
        return commands.get(DEFAULT);
    }
}

1

Substituto

Esta entrada substitui todas as selectFunctionToReplacefunções por sua própria selectFunctionToReplacefunção.

package codebots.bots;

import codebots.bot.ReadonlyBot;
import codebots.gameobjects.FunctionType;
import codebots.gameobjects.IPAddress;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by thenumberone on 12/11/15.
 *
 * @author thenumberone
 */
public class Replacer extends DefaultCodeBot{

    private static final String NAME = "Replacer";
    private static final String BLOCK = NAME + ":BLOCK";
    private static final String ATTACK = NAME + ":ATTACK";
    private static final String REPLACE = NAME + ":REPLACE";
    private static final String READ = NAME + ":READ";
    private static final String FLAG = NAME + ":FLAG";
    private static final String SELECT = NAME + ":SELECT";
    private static final String SEND = NAME + ":SEND";

    private static final Map<String, FunctionType> commands;

    private static final String[] REPLACEMENT_ORDER = {
            REPLACE,
            FLAG,
            READ,
            ATTACK
    };

    private static final String DEFAULT = REPLACE;
    private static final String BLOCK_FUNCTION = FLAG;

    static {
        Map<String, FunctionType> c = new HashMap<>();
        c.put(BLOCK, FunctionType.SELECT_FUNCTION_TO_BLOCK);
        c.put(ATTACK, FunctionType.SELECT_ATTACK_TARGET);
        c.put(REPLACE, FunctionType.SELECT_FUNCTION_TO_REPLACE);
        c.put(READ, FunctionType.READ_DATA);
        c.put(FLAG, FunctionType.GET_FLAG);
        c.put(SELECT, FunctionType.SELECT_MESSAGE_RECIPIENTS);
        c.put(SEND, FunctionType.SEND_MESSAGE);
        commands = Collections.unmodifiableMap(c);
    }

    @Override
    public String getFlag() {
        return NAME;
    }

    @Override
    public void readData(ReadonlyBot bot) {
        for (String command : commands.keySet()){
            getVariables().remove(command);
        }
        for (String command : REPLACEMENT_ORDER){
            if (!functionsMatch(bot, commands.get(command))) {
                getVariables().add(command, "");
                return;
            }
        }
    }

    @Override
    public FunctionType selectFunctionToBlock() {
        return commands.get(BLOCK_FUNCTION);
    }

    @Override
    public IPAddress selectAttackTarget() {
        getAddressBook().clear();
        return getAddressBook().getAddress(0);
    }

    @Override
    public FunctionType selectFunctionToReplace() {
        for (String command : REPLACEMENT_ORDER){
            if (getVariables().has(command)) {
                getVariables().remove(command);
                return commands.get(command);
            }
        }
        return commands.get(DEFAULT);
    }
}

1

MailBot

O Mailbot apenas lida com mensagens. Não é bem-sucedido em colocar sua própria bandeira no mundo (pontuação média ~ 50, ligeiramente superior a nullbot em ~ 45), mas envie uma mensagem e encaminhará seu endereço para outra pessoa.

package codebots.bots;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import codebots.bot.ReadonlyBot;
import codebots.gameobjects.AddressBook;
import codebots.gameobjects.FunctionType;
import codebots.gameobjects.IPAddress;
import codebots.gameobjects.Message;

public class MailBot extends DefaultCodeBot {
    private final String TEAM = "Just your friendly neighborhood mail delivering robot.";
    private final String TEAMALT = "Mailmain";
    private final List<FunctionType> funcList;
    {
        List<FunctionType> list = new ArrayList<FunctionType>();
        list.add(FunctionType.SELECT_MESSAGE_RECIPIENTS);
        list.add(FunctionType.SEND_MESSAGE);
        list.add(FunctionType.PROCESS_MESSAGE);
        funcList = Collections.unmodifiableList(list);
    }

    @Override
    public IPAddress selectMessageRecipient() {
        AddressBook book = getAddressBook();
        IPAddress ip;
        List<IPAddress> l = book.getAddressesOfType(AddressBook.AddressType.TO_ATTACK);
        if(l.size() > 0) {
            ip = l.get(0);
            book.add(ip,AddressBook.AddressType.UNTRUSTED);
            return ip;
        }
        ip = book.getAddress(getRandom().nextInt(book.size()));
        book.add(ip,AddressBook.AddressType.UNTRUSTED);
        return ip;
    }

    @Override
    public Message sendMessage() {
        AddressBook book = getAddressBook();
        IPAddress ip;

        List<IPAddress> l = book.getAddressesOfType(AddressBook.AddressType.UNTRUSTED);
        if(l.size() > 0) {
            ip = l.get(0);
            book.add(ip,AddressBook.AddressType.TO_DEFEND);
            return new Message(Message.MessageType.INFORM,ip);
        }

        ip = book.getAddress(getRandom().nextInt(book.size()));
        book.add(ip,AddressBook.AddressType.UNTRUSTED);
        return new Message(Message.MessageType.INFORM,ip);
    }

    @Override
    public void processMessage(IPAddress source, Message message) {
        AddressBook book = getAddressBook();
        book.add(source,AddressBook.AddressType.TO_ATTACK);
        if(message.getAddress() != null)
            book.add(message.getAddress(),AddressBook.AddressType.TO_ATTACK);
    }

    @Override
    public FunctionType selectFunctionToBlock() {
        return FunctionType.SEND_MESSAGE;
    }

    @Override
    public IPAddress selectAttackTarget() {
        //Mailbot doesn't attack
        return null;
    }

    @Override
    public void readData(ReadonlyBot bot) { }

    @Override
    public FunctionType selectFunctionToReplace() {
        //if our attack selection gets overwritten,
        //then attack a message-based function
        return funcList.get(getTurnNumber()%3);
    }

    @Override
    public String getFlag() {
        return TEAM;
        //if flag is too long, use:
        //return TEAMALT;
    }
}

Eu considerei salvar detalhes para encaminhar toda a mensagem para um novo bot (conteúdo e sinalizador) em vez de apenas o IP do remetente, mas isso envolveria o uso intenso de variáveis ​​sem nenhum ganho funcional, principalmente considerando o AmnesiaBot em jogo.


1

DumbBot

Ugh, isso parece sujo. Esta é provavelmente a única coisa que vence o AmnesiaBot. Na realidade, é apenas um RandomBot especializado: ele obtém um bot aleatório na simulação (via getAddressBook().clear()) e substitui aleatoriamente a função Block ou a função Flag. É isso aí. Ao escolher apenas esses dois, sua taxa de propagação da bandeira é maior que o AmnesiaBot ou o HelperBot, mas apenas um pouco após as 3000 rodadas:

Round 2999
105.50666666666666  Dumb Bot
105.07266666666666  Who Am I?
103.541             I'm Helping!
102.94833333333334  Swarmer
102.82033333333334  Chaos
102.82033333333334  Replacer
101.55666666666667  Expelliarmus!
101.25833333333334  Trust in Trust!
100.347             Random bot loves you
99.22233333333334   codebots.bots.DefaultCodeBot
92.62733333333334   codebots.bots.MarkedBot
91.80966666666667   Just your friendly neighborhood mail delivering robot.
90.46933333333334   null

Eu brinquei um pouco com a função de substituição, mas no final, esta é a versão que teve mais sucesso.

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.AddressBook;
import codebots.gameobjects.FunctionType;
import codebots.gameobjects.IPAddress;
import codebots.gameobjects.Message;

public class DumbBot extends CodeBot {


    @Override
    public FunctionType selectFunctionToBlock() {
        return getRandom().nextBoolean()?FunctionType.SELECT_FUNCTION_TO_BLOCK:FunctionType.GET_FLAG;
    }

    @Override
    public IPAddress selectAttackTarget() {
        AddressBook book = getAddressBook();
        book.clear();
        return book.getAddress(getRandom().nextInt(book.size()));
    }

    @Override
    public FunctionType selectFunctionToReplace() {
        return getRandom().nextBoolean()?FunctionType.SELECT_FUNCTION_TO_BLOCK:FunctionType.GET_FLAG;
    }

    @Override
    public void readData(ReadonlyBot bot) {

    }

    @Override
    public IPAddress selectMessageRecipient() {
        AddressBook book = getAddressBook();
        book.clear();
        return book.getAddress(getRandom().nextInt(book.size()));
    }

    @Override
    public Message sendMessage() {
        Message.MessageType[] values = Message.MessageType.values();
        return new Message(values[getRandom().nextInt(values.length)]);
    }

    @Override
    public void processMessage(IPAddress source, Message message) {

    }

    @Override
    public String getFlag() {
        return "Dumb Bot";
    }
}

0

Hermit Bot

Ele mora sozinho e fala apenas consigo mesmo. Se menos pessoas souberem quem ele é, ele se incomodará menos. Se alguém o incomodar, ele os atacará até que alguém o incomode.

package codebots.bots;

import codebots.bot.CodeBot;
import codebots.bot.ReadonlyBot;
import codebots.gameobjects.AddressBook;
import codebots.gameobjects.FunctionType;
import codebots.gameobjects.IPAddress;
import codebots.gameobjects.Message;

public class HermitBot extends CodeBot {

    @Override
    public IPAddress selectMessageRecipient() {
        return personalAddress();//Talks to himself.
    }

    @Override
    public Message sendMessage() {
        Message.MessageType[] values = Message.MessageType.values();
        return new Message(values[getRandom().nextInt(values.length)], personalAddress());
    }

    @Override
    public void processMessage(IPAddress source, Message message) {
        AddressBook book = getAddressBook();
        if(source != personalAddress()){
            //if someone talks to you, put them in your addres book and remove everyone else
            book.clear();
            book.add(source);
            book.remove(0);
        }
    }


    @Override
    public FunctionType selectFunctionToBlock() {
        return getTurnNumber() % 3 == 0 ?
                FunctionType.SELECT_FUNCTION_TO_BLOCK: FunctionType.GET_FLAG;
    }

    @Override
    public IPAddress selectAttackTarget() {
        AddressBook book = getAddressBook();
        return book.getAddress(getRandom().nextInt(book.size()));
    }

    @Override
    public void readData(ReadonlyBot bot) {
        Variables v = getVariables();
        if(functionsMatch(bot, FunctionType.SELECT_FUNCTION_TO_BLOCK))
            v.add("Block Dif","A");
        if(functionsMatch(bot, FunctionType.GET_FLAG))
            v.add("Flag Dif","B");
        if(functionsMatch(bot, FunctionType.SELECT_MESSAGE_RECIPIENTS))
            v.add("Targ Dif","C");

    }

    @Override
    public FunctionType selectFunctionToReplace() {
        Variables v = getVariables();
        FunctionType r = getRandom().nextBoolean()?FunctionType.SELECT_FUNCTION_TO_REPLACE: FunctionType.READ_DATA;

        if(v.has("Targ Dif"))
            r = FunctionType.SELECT_MESSAGE_RECIPIENTS;
        if(v.has("Flag Dif") && getTurnNumber() % 3 == 0)
            r = FunctionType.GET_FLAG;
        if(v.has("Block Dif"))
            r = FunctionType.SELECT_FUNCTION_TO_BLOCK;
        v.clear();
        return r;
    }

    @Override
    public String getFlag() {
        return "Hermit Bot";
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.