Коди-боти 4: Функціональне програмування


25

sheesh, це справді четверте? Для всіх ваших стариків основна проблема однакова, але ми використовуємо Java замість спеціальної мови. Ось три останні виклики CodeBot , якщо вам це цікаво.

Мета CodeBots - зробити вашого бота якомога віруснішим . Кожен бот несе прапор, і вам потрібно переконатися, що ваш прапор є скрізь .

API

Боти дотримуватимуться стандартизованого "протоколу", і боти прогресують через наступні кроки синхронно:

  1. IPAddress selectMessageRecipient() дозволяє боту обирати, кому він хоче надіслати "дружнє" повідомлення.
  2. Message sendMessage() дозволяє боту вибирати вміст повідомлення, яке він надсилатиме.
  3. processMessage(IPAddress, Message) називається для кожного повідомлення, яке отримує бот.
  4. FunctionType selectFunctionToBlock()блокує функцію перезапису на поточний поворот. Дивіться крок 7.
  5. IPAddress selectAttackTarget()дозволяє боту обирати, кого він хоче DDOS. DDOS-атака є успішною, якщо бот націлений на 3 бота одночасно. Якщо атака є успішною, то кожен з нападників може виконати крок 6 і 7.
  6. readData(ReadonlyBot) дозволяє боту читати дані, що зберігаються на вразливому боті.
  7. FunctionType selectFunctionToReplace()суть цієї проблеми . Вам дозволяється вибрати 1 функцію (з 8 перерахованих тут), щоб скопіювати з вашого бота на їх бота. Тоді ваша функція буде називатися замість їх . Якщо кілька ботів вибирають одну і ту ж функцію, випадкова буде успішною.
  8. String getFlag()називається в кінці гри, і має повернути рядок, унікальний для вашого подання. Ваша функція завжди повинна повертати один і той же рядок. Подання з найбільшою кількістю прапорів наприкінці гри виграє.

Зберігання

У вас є 3 форми зберігання, адресна книга , журнал та змінні . Ці форми зберігання є локальними для бота, на якому працює ваша функція (тому якщо ваша функція буде скопійована, вміст кожного з цих об'єктів буде різним). Усі ці об’єкти можна вручну змінити або очистити. Для отримання цих об'єктів у вашому класі є геттер (напрgetLog() ).

AddressBook зберігає список IPAddress , кожен з AddressType , що дозволяє класифікувати різні типи адрес. Адресна книга завжди буде містити принаймні 1 адресу (якщо вона буде очищена, буде додана випадкова). Очищення адресної книги для отримання декількох IP-адрес не дозволяється.

Log зберігає список всіх дій, а також дані про дію. Він також включає історію всіх успішних атак (хоча ви не знаєте, які функції вони перезаписали)

Об'єкт Змінні дозволяє зберігати змінні рядків, приєднані до імені рядка. Під час запуску гри Змінні містять єдину змінну, IDяка містить випадковим чином генерований ідентифікатор, унікальний для вашого типу бота.

Також у вас є інші функції доступу:

  • int getTurnNumber() повертає ціле число з поточним поворотом
  • bool functionsMatch(ReadonlyBot, FunctionType) тести, щоб перевірити, чи відповідає функція ReadonlyBot вашій
  • IPAddress personalAddress() повертає вашу IP-адресу

Як реалізувати

  • Ви можете отримати код від Github
  • Додайте свого бота до \botsпапки, а потім додайте посилання на свого бота вcontroller\CodeBotFactory.java
  • Ваш бот повинен поширити codebots.bot.CodeBotабоcodebots.bots.DefaultCodeBot
  • Вам потрібна Java 8, якщо ви хочете запустити контролер.
  • Ви можете запустити код (якщо ви знаходитесь в /srcпапці), використовуючи javac codebots\*.javaдля компіляції, а потім java codebots.Mainдля запуску.
  • Ви можете не мати ніяких непостійні змінні - члени в своєму класі
  • Рефлексія заборонена.
  • Форми зв'язку між ботами (одного і того ж або різних типів) поза перерахованими вище методами не дозволяються.
  • Допускаються німі та / або суїцидальні боти, але всі боти повинні бути функціонально іншими, ніж існуючі.
  • Якщо ви хочете випадковості у вашому боті, використовуйте getRandom()
  • Будь ласка, спробуйте зберегти свій код ефективним. Я витратив чимало часу на профілювання та швидке виготовлення контролера.

Оцінки

105.2501 Expelliarmus!
104.5803 Я допомагаю!
104.2746 Хто я?
103.8529 Німий бот
103.2028 Замінник
102.7045 Хаос
102.4046 Бот-відлюдник
102.2849 Плавець
100.5598 Випадковий бот любить вас
99,966 Довіряйте довірі!
99.0185 codebots.bots.DefaultCodeBot
91.2942 codebots.bots.MarkedBot
91.1423 Просто ваша дружня сусідська пошта, яка доставляє робота.
89,4645 нуль


Ви, ймовірно, повинні зробити Log.LogEntry остаточним, з ним не остаточним, я можу створювати журнали з будь-якою інформацією, яку мені хочеться ... що тільки моя бот-функція могла б читати чи створювати.
TheNumberOne

Чи може readData отримати доступ до IpAddress бота, який він читає?
TheNumberOne

@TheNumberOne наразі немає, але я не бачу, чому б ні. Зараз у мене немає коду, але я оновлю код, щоб змінити це.
Натан Меррілл

3
Мені цікаво, що Chaos робить DisarmBot та MarkedBot місцями торгівлі на лідері.
TheNumberOne

1
На даний момент у раунді 7850 з 10000, отримуючи точніші результати ...
LegionMammal978

Відповіді:


4

TrustBot

Якщо ви надішлете йому повідомлення, він зробить те, що говорить. Якщо він прочитає бота, він скопіює адреси безпосередньо у свою книгу. Він нападає на ботів, за якими адресна книга каже, що вони атакують.

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

Випадковий бот, який вводить іншим ботам код втрати пам'яті. Кожна функція починається з коду для очищення журналу, адресної книги та змінних. Цей код змусить розумних ботів втратити пам'ять, намагаючись усунути логіку.

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

Я думаю, що цей виграє лише через неможливість розумнішого сценарію бути здатним запам’ятати що-небудь. тобто очищення об'єкта змінних дійсно прокляте.
Draco18s

@ draco18s це насправді не було серйозною відповіддю ...
MegaTom

Я знаю! Ось чому я його так збентежив. XD
Draco18s

3

NullBot

Його прапор дуже ... характерний ...

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

Це також призначене для тестування контролера та меж правила "німі боти дозволені".


Технічно він не відповідає специфікації, тому що він точно не повертає String для свого прапора.
TheNumberOne

3
null- це рядок. ;) Просто мудра струна.
Аддісон Кримп

Це змусило мене визнати недолік у моїй специфікації, який був уточнений: "всі боти повинні бути функціонально іншими, ніж існуючі записи"
Натан Меррілл

@NathanMerrill Виправлено, щоб більш уважно слідувати специфікації.
TheNumberOne

3

RandomCodeBot

Обов’язковий випадковий запис 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 не надто розумний. Якщо він отримає вказівки про атаку, він вибере випадкового атаке, інакше атакує випадкового гравця. Це просто перекриває їх selectFunctionToBlockфункцію для блокування 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!"; }
}

Ви можете вибрати n-ту адресу, не потрібно робити всі адреси (). Якщо ви подивитеся на мого випадкового бота, він робить вибір випадкової адреси. Я оновив ваш код на Github (з міркувань ефективності), але якщо ви відчуваєте, що він не працює, я радий повернути його.
Натан Меррілл

О, моя погана, виправлена.
Натан Меррілл

3

MarkedBot

Відзначає себе в першому раунді і використовує цю інформацію в наступних раундах. Таким чином, якщо інший бот отримає ін'єкційний код атаки, він буде неефективним.

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

Я знайшов кілька помилок у цьому боті (помилки, використовуючи == замість рівних) Ви також виявили недолік у моїй системі: ви не повинні мати змогу створювати нові випадкові IP-адреси. Я вирішив цю проблему (і видалив код, який це робив). Ви можете знайти оновлений код на github
Nathan Merrill

Також вітаємо з першим місцем!
Натан Меррілл

HelperBot не дуже розумний. Це дісталося лише тому, що всі інші боти були німі. : P Це, мабуть, перший ефективний бот.
Draco18s

1
@NathanMerrill Це означає, що нам більше не дозволяється створювати підроблені IP-адреси для обману? (якщо це так, мені потрібно буде переробити шахту)
Нік Робертсон

Бот ніколи не має навмисного доступу до раунду. Ви можете використовувати IP-адреси супротивників як фальшивки, але створювати їх не дозволяється. Також константа - це змінна множина в статичний час або час ініціалізації.
Натан Меррілл

2

SwarmBot

Цей не добре названий бот досить складний (і найскладніший поданий на даний момент), але я зробив спробу на бота, який систематично замінює всі методи цілі, перш ніж переходити до нової цілі. Він намагається визначити копії себе та розглядає їх як союзників, періодично перевіряючи їх, щоб забезпечити цілісність. Я не придумав кращого імені.

Посилання на гілку github repo, оскільки цей бот має 340 ліній.

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

Кілька цікавих моментів:

  • Рядки 14-24 - це просто немодифікований список, який спростив налаштування порядку, в якому бот замінює методи своєї мети. Він зберігає, які індексують його вVariables кроки та з кроком кожного раунду. При цьому слід керуватися правилом "без постійних змінних".
  • Рядки 203-217 стосуються верифікації союзників. Нам фактично все одно, що інший бот реалізує все вісім наших інструкцій. Лише чотири є істотними, і якщо нам не вистачає одного "довіреного" союзника, ми замінюємо його своїм.
  • Лінії 295-300 були несподіваним підвищенням ефективності. Захищаючи наш Прапор на перших двох оборотах гри, ми уникаємо, щоб німі боти замінили наш Прапор, перш ніж ми маємо шанс поширитись далеко. Однак, якщо чекати довше, це дає шансам іншим ботам замінити нашу BlockFunction, і це призводить до погіршення продуктивності (підозрюється через те, що RandomBot втручається в союзників, які намагаються скасувати корупцію).
  • Найдовше протягом розвитку цього бота цей бот змушував HelperBot випереджатись, в один момент порушивши позначку 130, в той час як бот затуманився на діапазоні 81-98, але перетягнув ефективність MarkedBot та DefaultBot вниз на кілька очок.
  • Цей бот був можливий лише за допомогою доданого functionsMatchметоду. Без functionsMatchнього неможливо було написати бота, який міг би приймати змістовні рішення, оскільки він був сліпим. Він може читати змінні та журнали своїх цілей, але нічого не знає про стан своєї цілі.

Можливо, все ще можливі деякі вдосконалення, але я не можу їх побачити. Рядки 198-205 - це, ймовірно, вивірка продуктивності, але поки клас IPAddress не дозволяє відновити адреси із збереження у змінних, це необхідно (оскільки боти не мають можливості перевірити адресу, будь-яке зберігання недійсної адреси спричиняє гру загортайте нульову ціль у ReadOnlyBot, кидаючи NPE).

Редагувати: оновлення 12.12.15

Налаштування деяких параметрів на getTurnNumber()логіці дозволило деяким збільшити продуктивність. Збільшення від 5% до 10% у націлюванні на кінцеву гру коштувало приблизно 15 балів, аналогічно збільшенню націлювання на ранню гру з 5% до 8%. У поєднанні цей бот тепер може (майже) вижити, навіть стикаючись з AmnesiaaBot (досягнувши другого місця з оцінкою 110, де HelperBot потрапляє до 117).

Навіть за допомогою цих виправлень це може стати невдалим, тому для 10 раундів його показник становить приблизно 170-185.


Дивовижно! Навмисно не можна створювати IP-адреси з рядків.
Натан Меррілл

Ну, нібито, так! (Або боти створять довільні для пошуку нових ботів). Проблема полягає в тому, що якщо ви зробите імітаційні збої. ;)
Draco18s

Urm, у рядку 143 ви використовуєте неіснуючий конструктор.
TheNumberOne

@TheNumberOne це було дійсно, коли я писав це. Натан, ймовірно, оновив базу.
Draco18s

@TheNumberOne зроблено оновлення. new IPAddressВиклик повинен був «подивитися з адресної книги» , як я зробив в readData. Я витягнув цей пошук і виправив лінію 143.
Draco18s

1

DefaultCodeBot

Намагається робити розумні справи. (Замініть цей клас, якщо ви не хочете реалізувати всі функції)

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

Бот-помічник не робить нічого, крім намагається поширити власний прапор ... або, принаймні, прапор, який він нині каріє ...

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

Якщо HelperBot передбачає, що будь-який власний метод, який буде перезаписаний (крім getFlag()), буде замінено чимось кращим.


1

Хаос

Він звільняє всі прапори від тиранії блокування.

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

Замінник

Цей запис замінює всі selectFunctionToReplaceфункції власною selectFunctionToReplaceфункцією.

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 обробляє лише повідомлення. Вивести власний прапор у світ не вдається (середній бал ~ 50, трохи вище, ніж nullbot на ~ 45), але надішліть йому повідомлення, і воно перешле вашу адресу комусь іншому.

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

Я розглядав можливість збереження деталей, щоб він передавав всю повідомлення на новий бот (вміст та прапор), а не лише IP-адресу відправника, але це залучало б велике використання змінних без будь-якого функціонального посилення, особливо враховуючи, що AmnesiaBot використовується.


1

Гантель

Фу, це відчуває себе брудно. Це, мабуть, єдине, що перемагає AmnesiaBot. Насправді це просто спеціалізований RandomBot: він отримує випадковий бот при моделюванні (через getAddressBook().clear()) і випадковим чином замінює або функцію Block, або функцію Flag. Це воно. Вибравши лише ці два, швидкість розповсюдження прапора вище, ніж AmnesiaBot або HelperBot, але лише після 3000 раундів:

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

Я трохи поспішив із функцією заміни, але врешті-решт, саме ця версія була найбільш успішною.

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

Відлюдник Бот

Він живе один і розмовляє лише сам із собою. Якщо менше людей знає, хто він, то він буде менше турбуватися. Якщо хтось його набридає, він буде атакувати їх, поки хтось інший не заважає йому.

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";
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.