Code Bots 4: Programmazione funzionale


25

sheesh, è davvero il 4? Per tutti voi vecchietti, la sfida principale è la stessa, ma stiamo usando Java invece di un linguaggio personalizzato. Ecco le tre ultime sfide di CodeBot , nel caso tu sia interessato.

L'obiettivo di CodeBots è rendere il tuo bot il più virale possibile . Ogni bot porta una bandiera e devi assicurarti che la tua bandiera sia ovunque .

API

I robot seguiranno un "protocollo" standardizzato e procederanno in modo sincrono attraverso i seguenti passaggi:

  1. IPAddress selectMessageRecipient() consente a un bot di scegliere a chi desidera inviare un messaggio "amichevole".
  2. Message sendMessage() consente a un bot di scegliere il contenuto del messaggio che invierà.
  3. processMessage(IPAddress, Message) viene chiamato per ogni messaggio ricevuto da un bot.
  4. FunctionType selectFunctionToBlock()impedisce a una funzione di essere sovrascritta per il turno corrente. Vedi il passaggio 7.
  5. IPAddress selectAttackTarget()consente a un bot di scegliere chi desidera DDOS. Un attacco DDOS ha esito positivo se il bot viene preso di mira da 3 bot contemporaneamente. Se un attacco ha esito positivo, ciascuno degli attaccanti può eseguire i passaggi 6 e 7.
  6. readData(ReadonlyBot) consente a un bot di leggere i dati memorizzati nel bot vulnerabile.
  7. FunctionType selectFunctionToReplace()è il nocciolo di questa sfida . Puoi selezionare 1 funzione (delle 8 elencate qui) per copiare dal tuo bot al loro bot. Quindi, la tua funzione verrà chiamata al posto della loro . Se più robot selezionano la stessa funzione, una casuale avrà esito positivo.
  8. String getFlag()viene chiamato alla fine del gioco e dovrebbe restituire una stringa unica alla tua presentazione. La tua funzione dovrebbe sempre restituire la stessa stringa. La presentazione con il maggior numero di bandiere alla fine del gioco vince.

Conservazione

Hai 3 forme di archiviazione, una rubrica , un registro e una variabile . Queste forme di archiviazione sono locali al bot su cui è in esecuzione la funzione (quindi se la funzione viene copiata, il contenuto di ciascuno di questi oggetti sarà diverso). Tutti questi oggetti possono essere modificati o cancellati manualmente. Per ottenere questi oggetti, hai un getter nella tua classe (ad es getLog().).

L'AddressBook memorizza un elenco di IndirizzoIP , ciascuno con un'AddressType , che permette di classificare i diversi tipi di indirizzi. La Rubrica conterrà sempre almeno 1 indirizzo (se viene cancellato, ne verrà aggiunto uno casuale). Non è possibile cancellare la Rubrica per ottenere più indirizzi IP .

Il registro memorizza un elenco di tutte le azioni intraprese, nonché i dati relativi all'azione. Include anche una cronologia di tutti gli attacchi riusciti (anche se non sai quali funzioni hanno sovrascritto)

L' oggetto Variabili consente di memorizzare variabili stringa associate a un nome stringa. All'inizio del gioco, le variabili conterranno una singola variabile, IDche contiene un ID generato casualmente che è unico per il tuo tipo di bot.

Hai anche altre funzioni di accesso:

  • int getTurnNumber() restituisce un numero intero con il turno corrente
  • bool functionsMatch(ReadonlyBot, FunctionType) verifica se la funzione di ReadonlyBot corrisponde alla tua
  • IPAddress personalAddress() restituisce il tuo indirizzo IP

Come implementare

  • È possibile ottenere il codice da Github
  • Aggiungi il tuo bot alla \botscartella, quindi aggiungi un riferimento al tuo bot incontroller\CodeBotFactory.java
  • Il tuo bot deve estendere codebots.bot.CodeBotocodebots.bots.DefaultCodeBot
  • È necessario Java 8 se si desidera eseguire il controller.
  • Puoi eseguire il codice (supponendo che tu sia nella /srccartella) usando javac codebots\*.javaper compilare, quindi java codebots.Mainper eseguire.
  • Si può non avere alcun variabili membro non costanti nella classe
  • La riflessione non è consentita.
  • Non sono consentite forme di comunicazione tra bot (di tipo uguale o diverso) al di fuori dei metodi sopra elencati.
  • Sono ammessi bot stupidi e / o suicidi, ma tutti i robot dovrebbero essere funzionalmente diversi dalle voci esistenti.
  • Se vuoi casualità nel tuo bot, usa getRandom()
  • Prova a mantenere il tuo codice efficiente. Ho trascorso molto tempo a profilare e velocizzare il controller.

I punteggi

105.2501 Expelliarmus!
104.5803 Sto aiutando!
104.2746 Chi sono io?
103.8529 Bot
stupido
103.2028 Sostituitore 102.7045 Caos
102.4046 Bot eremita 102.2849
Swarmer
100.5598 Bot casuale ti ama
99.966 Trust in Trust!
99.0185 codebots.bots.DefaultCodeBot
91.2942 codebots.bots.MarkedBot
91.1423 Solo il tuo amichevole robot di consegna della posta di quartiere.
89.4645 null


Probabilmente dovresti rendere Log.LogEntry definitivo, con esso non posso creare registri con tutte le informazioni che voglio ... che solo la mia funzione bot sarebbe in grado di leggere o creare.
TheNumberOne

ReadData può accedere a IpAddress del bot che sta leggendo?
TheNumberOne l'

@TheNumberOne non è attualmente, ma non vedo perché no. Non ho il codice su di me in questo momento, ma aggiornerò il codice per cambiarlo.
Nathan Merrill,

3
Trovo interessante il fatto che Chaos porti DisarmBot e MarkedBot nella classifica.
TheNumberOne l'

1
Attualmente al round 7850 su 10000, ottenendo punteggi più accurati ...
LegionMammal978

Risposte:


4

TrustBot

Se gli invii un messaggio, farà quello che dice. Se legge un robot, copia gli indirizzi direttamente nel suo libro. Attacca i robot che la rubrica dice di attaccare.

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

Un bot casuale che inietta altri bot con codice di perdita di memoria. Ogni funzione inizia con il codice per cancellare il registro, la Rubrica e le variabili. Questo codice farà perdere memoria ai robot intelligenti, nel tentativo di eliminare la logica.

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?";
    }
}

Penso che questo vince solo a causa dell'incapacità di una sceneggiatura più intelligente di essere in grado di ricordare qualsiasi cosa. cioè cancellare l'oggetto Variabili è davvero dannatamente potente.
Draco18s,

@ draco18s questa non era davvero una risposta seria ...
MegaTom

Lo so! Ecco perché ne sono così confuso. XD
Draco18s

3

NullBot

La sua bandiera è molto ... caratteristica ...

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;
    }
}

Questo ha anche lo scopo di testare il controller e i limiti della regola "Sono ammessi robot stupidi".


Tecnicamente non si adatta alle specifiche, perché non restituisce esattamente una stringa per la sua bandiera.
TheNumberOne

3
nullè una stringa. ;) Solo una stringa di fantasia.
Addison Crump,

Questo mi ha fatto riconoscere un difetto nelle mie specifiche, che è stato specificato: "tutti i bot dovrebbero essere funzionalmente diversi dalle voci esistenti"
Nathan Merrill,

@NathanMerrill Risolto per seguire più da vicino le specifiche.
TheNumberOne

3

RandomCodeBot

Inserimento casuale obbligatorio di 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

DisarmerBot non è troppo intelligente. Se riceve istruzioni di attacco, sceglierà un attaccante a caso, altrimenti attaccherà un giocatore a caso. Sostituisce semplicemente la loro selectFunctionToBlockfunzione da bloccare 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!"; }
}

È possibile selezionare l'ennesimo indirizzo senza la necessità di eseguire allAddresses (). Se guardi il mio bot casuale, sta facendo la selezione casuale dell'indirizzo. Ho aggiornato il tuo codice su Github (per motivi di efficienza), ma se ritieni che non funzioni, sono felice di ripristinarlo.
Nathan Merrill,

Oh, mio ​​cattivo, risolto.
Nathan Merrill,

3

MarkedBot

Si segna al primo turno e usa queste informazioni nei round successivi. In questo modo, se un altro bot viene iniettato con il suo codice di attacco, sarà inefficace.

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();
    }
}

Ho trovato diversi bug in questo bot (errori di battitura, usando == anziché uguale a) Hai anche trovato un difetto nel mio sistema: non dovresti essere in grado di creare nuovi indirizzi IP casuali. Ho risolto quel problema (e rimosso il codice facendolo). Puoi trovare il codice aggiornato su github
Nathan Merrill il

Inoltre, congratulazioni per il primo posto!
Nathan Merrill,

HelperBot non è molto intelligente. Ha ottenuto il massimo solo perché tutti gli altri robot erano stupidi. : P Questo è probabilmente il primo bot efficace .
Draco18s,

1
@NathanMerrill Significa che non ci è più permesso di creare indirizzi IP falsi per inganno? (se è così dovrò ridisegnare il mio)
Nic Robertson,

Un bot non ha mai accesso al round intenzionalmente. Puoi usare gli indirizzi IP degli avversari come falsi, ma crearne uno non è permesso. Inoltre, una costante è una variabile impostata in tempo statico o tempo di inizializzazione.
Nathan Merrill l'

2

SwarmBot

Questo bot non ben definito è piuttosto complicato (e il più complicato presentato finora), ma ho fatto un tentativo con un bot che sostituisce sistematicamente tutti i metodi di un target prima di passare a un nuovo target. Tenta di identificare copie di se stesso e di trattarle come alleate, controllandole periodicamente per assicurarne l'integrità. Non ho trovato un nome migliore.

Collegamento al ramo repo github, poiché questo bot è lungo 340 linee.

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

Alcuni punti interessanti:

  • Le righe 14-24 sono semplicemente un elenco non modificabile che ha reso facile modificare l'ordine in cui il bot sostituisce i metodi del suo target. Memorizza quale indice è attivoVariables attivo e aumenta ogni round. Questo dovrebbe seguire la regola "nessuna variabile non costante".
  • Le righe 203-217 trattano della verifica degli alleati. In realtà non ci importa che un altro bot implementi tutte e otto le nostre istruzioni. Solo quattro sono essenziali, e se ci manca uno su un alleato "fidato", lo sostituiamo con il nostro.
  • Le linee 295-300 sono state un aumento inaspettato in termini di efficacia. Proteggendo la nostra bandiera nei primi due turni del gioco, evitiamo che i muti robot sostituiscano la nostra bandiera prima di avere la possibilità di diffonderci molto lontano. L'attesa più a lungo, tuttavia, offre agli altri robot la possibilità di sostituire la nostra BlockFunction e ciò causa il degrado delle prestazioni (sospettato a causa di RandomBot che interferisce con gli alleati che tentano di annullare la corruzione).
  • Per il tempo più lungo durante lo sviluppo di questo bot, questo bot ha fatto avanzare HelperBot, superando a un certo punto il segno 130, mentre questo bot ha languito nell'intervallo 81-98, ma dopo aver trascinato l'efficacia di MarkedBot e DefaultBot su diversi punti.
  • Questo bot era possibile solo con il functionsMatchmetodo aggiunto . Senza functionsMatchera impossibile scrivere un robot che potesse prendere decisioni significative, poiché era cieco. Poteva leggere le variabili e i log dei target, ma non sapeva nulla dello stato del target.

Probabilmente ci sono ancora alcuni miglioramenti possibili, ma non riesco a vederli. Le righe 198-205 sono probabilmente un ostacolo alle prestazioni, ma fino a quando la classe IPAddress non consente la ricostituzione degli indirizzi dalle variabili, ciò è necessario (poiché i bot non hanno alcun mezzo per convalidare un indirizzo, qualsiasi memorizzazione di un indirizzo non valido provoca il gioco a avvolgere un target null in un ReadOnlyBot, lanciando NPE).

Modifica: aggiornamenti 12/12/15

La modifica di alcuni parametri sulla getTurnNumber()logica ha consentito di aumentare le prestazioni. L'aumento dal 5% al ​​10% nel targeting per fine gioco valeva circa 15 punti, allo stesso modo aumentando il targeting per inizio gioco dal 5% all'8%. Combinato questo bot ora può (quasi) sopravvivere anche di fronte ad AmnesiaaBot (raggiungendo il 2 ° con un punteggio di 110, dove HelperBot arriva a circa 117).

Anche con queste modifiche, può essere sfortunato, quindi per 10 round il suo intervallo di punteggio è di circa 170-185.


Eccezionale! È intenzionale che non è possibile creare indirizzi IP dalle stringhe.
Nathan Merrill,

Beh, apparentemente sì! (O i robot ne creeranno di arbitrari per trovare nuovi robot). Il problema è che se si esegue il crash della simulazione. ;)
Draco18s

Urm, sulla linea 143 usi un costruttore inesistente.
TheNumberOne l'

@TheNumberOne era valido quando l'ho scritto. Nathan probabilmente ha aggiornato la base.
Draco18s,

@TheNumberOne aggiornamento effettuato. La new IPAddresschiamata avrebbe dovuto essere un "sguardo dalla rubrica" ​​come avevo fatto io readData. Ho estratto quella ricerca e la linea fissa 143.
Draco18s

1

DefaultCodeBot

Cerca di fare cose ragionevoli. (Sostituisci questa classe se non vuoi implementare tutte le funzioni)

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

Il robot helper non fa altro che cercare di diffondere la propria bandiera ... o almeno la bandiera che sta trasportando ...

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 HelperBot presuppone che qualsiasi suo metodo sovrascritto (diverso da getFlag()) verrà sovrascritto con qualcosa di meglio.


1

Caos

Libera tutte le bandiere dalla tirannia di essere bloccato.

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

Replacer

Questa voce sostituisce tutte le selectFunctionToReplacefunzioni con una propria selectFunctionToReplacefunzione.

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

Mailbot gestisce solo i messaggi. Non ha successo nel portare la propria bandiera nel mondo (punteggio medio ~ 50, leggermente superiore a nullbot a ~ 45), ma invia un messaggio e inoltrerà il tuo indirizzo a qualcun altro.

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;
    }
}

Ho pensato di salvare i dettagli in modo da inoltrare l'intero messaggio a un nuovo bot (contenuto e flag) anziché solo all'IP del mittente, ma ciò avrebbe comportato un uso intenso delle variabili senza alcun guadagno funzionale, soprattutto considerando che AmnesiaBot era in gioco.


1

DumbBot

Ugh, sembra sporco. Questa è probabilmente l'unica cosa che batte AmnesiaBot. In realtà, è solo un RandomBot specializzato: ottiene un bot casuale nella simulazione (tramite getAddressBook().clear()) e sostituisce in modo casuale la funzione Block o Flag. Questo è tutto. Selezionando solo quei due, il suo tasso di diffusione della bandiera è superiore a quello di AmnesiaBot o HelperBot, ma solo leggermente dopo 3000 colpi:

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

Ho smanettato un po 'con la funzione di sostituzione, ma alla fine, questa è la versione che ha avuto più successo.

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

Eremita Bot

Vive da solo e parla solo con se stesso. Se meno persone sanno chi è, allora sarà disturbato meno. Se qualcuno lo disturba, li attaccherà fino a quando qualcun altro lo disturberà.

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";
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.