代码机器人4:函数式编程


25

嘘,这真的是第四吗?对于所有老用户来说,核心挑战是相同的,但是我们使用Java而不是自定义语言。如果您有兴趣,这里是过去三个 CodeBot 挑战

CodeBots的目标是使您的机器人尽可能地具有病毒性。每个漫游器都带有一个Flag,并且您需要确保您的Flag 到处都是

API

漫游器将遵循标准化的“协议”,而漫游器将同步执行以下步骤:

  1. IPAddress selectMessageRecipient() 允许机器人选择他想向其发送“友好”消息的对象。
  2. Message sendMessage() 允许漫游器选择他将发送的消息的内容。
  3. processMessage(IPAddress, Message) 机器人收到的每条消息都会被调用。
  4. FunctionType selectFunctionToBlock()阻止当前回合中的函数被覆盖。请参阅步骤7。
  5. IPAddress selectAttackTarget()允许漫游器选择他想要DDOS的对象。如果该机器人同时被3个机器人作为目标,则DDOS攻击成功。如果攻击成功,则每个攻击者都可以执行步骤6和7。
  6. readData(ReadonlyBot) 允许机器人读取易受攻击的机器人上存储的数据。
  7. FunctionType selectFunctionToReplace()是挑战的关键。您可以选择1个功能(在此列出的8个功能中)从您的机器人复制到他们的机器人。然后,将调用您的函数而不是它们的函数。如果多个机器人选择了相同的功能,则随机将成功。
  8. String getFlag()在游戏结束时被调用,并且应返回您提交的唯一字符串。您的函数应始终返回相同的字符串。游戏结束时带有最多标记的提交将获胜。

存储

您有3种存储形式,一个AddressBook,一个Log和一个Variables这些存储形式是函数运行所在的bot的本地存储(因此,如果函数被复制,则每个对象的内容将有所不同)。所有这些对象都可以手动修改或清除。要获取这些对象,您的班级中有一个吸气剂(例如getLog())。

通讯录存储列表ip地址,每一个地址类型,它可以让你在不同类型的地址进行分类。 AddressBook将始终至少包含1个地址(如果清除该地址,则会添加一个随机的地址)。不允许清除地址簿以获取多个IPAddress

日志存储有关的行动采取的所有行动,以及数据的列表。它还包括所有成功攻击的历史记录(尽管您不知道它们重写了哪些功能)

变量对象允许你存储连接到一个字符串名称字符串变量。在游戏开始时,变量将包含一个变量,ID其中包含一个随机生成的ID,该ID对于您的机器人类型是唯一的。

您还具有其他访问功能:

  • int getTurnNumber() 返回当前转弯的整数
  • bool functionsMatch(ReadonlyBot, FunctionType) 测试以查看ReadonlyBot的函数是否与您的函数匹配
  • IPAddress personalAddress() 返回您的IPAddress

如何实施

  • 您可以从Github获取代码
  • 将您的漫游器添加到该\bots文件夹,然后在其中添加对您的漫游器的引用controller\CodeBotFactory.java
  • 您的漫游器必须扩展codebots.bot.CodeBotcodebots.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 Swarmer
100.5598随机机器人爱你
99.966信任信任!
99.0185 codebots.bots.DefaultCodeBot
91.2942 codebots.bots.MarkedBot
91.1423只是您友好的邻居邮件传递机器人。
89.4645无


您可能应该使Log.LogEntry成为最终版本,而不是最终版本。我可以使用任何我想创建的信息来创建日志...只有我的bot函数才可以读取或创建。
TheNumberOne 2015年

readData可以访问正在读取的机器人的IpAddress吗?
TheNumberOne

@TheNumberOne当前不是,但是我不明白为什么不这样做。我现在没有代码,但是我将更新代码以进行更改。
弥敦道·美林

3
我感到很有趣的是,Chaos在排行榜上获得了DisarmBot和MarkedBot交易场所。
TheNumberOne 2015年

1
目前在第7850轮(共10000轮)中获得更准确的分数...
LegionMammal978

Answers:


4

信托宝

如果您给他发消息,他会按照说的去做。如果他读了一个机器人,他会将地址直接复制到他的书中。他攻击通讯录说要攻击的机器人。

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

失忆症

一个随机机器人,向其他机器人注入内存丢失代码。每个功能均以清除日志,地址簿和变量的代码开头。该代码将使智能机器人失去内存,以消除逻辑。

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 2015年

@ draco18s这不是真正要认真回答的问题……
MegaTom,2015年

我知道!这就是为什么我对此感到困惑。XD
Draco18s 2015年

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

这也意味着测试控制器和“允许哑机器人”规则的限制。


从技术上讲,他不符合规范,因为他没有为标志正确返回字符串。
TheNumberOne 2015年

3
null是一个字符串。;)只是一个花哨的字符串。
艾迪生·克伦普

这使我认识到我的规范存在一个缺陷,该缺陷已被指定:“所有漫游器的功能都应与现有条目不同”
Nathan Merrill

@NathanMerrill已修复,可以更严格地遵循规范。
TheNumberOne 2015年

3

随机码

强制性随机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不太聪明。如果收到攻击指令,它将选择一个随机的被攻击者,否则它将攻击一个随机的玩家。它只是覆盖其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个地址,而无需执行allAddresses()。如果您看看我的随机漫游器,它是在进行随机地址选择。我已经在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();
    }
}

我在该机器人中发现了几个错误(打字机,使用==而不是equals),您还发现了我的系统中的一个缺陷:您不应该能够创建新的随机IPAddress。我已经解决了这个问题(并删除了执行此操作的代码)。您可以在github
Nathan Merrill

此外,恭喜您!
弥敦道·美林

HelperBot不是很聪明。它之所以获得最高排名,是因为其他所有机器人都是愚蠢的。:P这可能是第一个有效的机器人。
Draco18s 2015年

1
@NathanMerrill这是否意味着我们不再被允许创建伪造的IPAdresses进行欺骗?(如果是这样的话,我需要重新设计我的)
Nic Robertson

机器人永远不会有意进入该回合。您可以将对手的IP地址用作伪造品,但不允许创建一个。另外,常数是在静态时间或初始化时间设置的变量。
弥敦道·美林

2

虫群

这个名称不明确的机器人非常复杂(是迄今为止提交的最复杂的机器人),但是我尝试了一个机器人,该机器人可以系统地替换目标的所有方法,然后再转移到新目标。它试图识别自己的副本并将其视为盟友,并定期检查它们以确保完整性。我还没有一个更好的名字。

链接到github repo分支,因为该机器人长340行。

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

一些有趣的观点:

  • 第14至24行只是不可修改的列表,可轻松调整bot替换其目标方法的顺序。它存储哪个索引在其上Variables并在每一轮增加。这应遵循“没有非恒定变量”规则。
  • 第203-217行处理盟友验证。我们实际上并不在乎另一个机器人实现了我们所有的八条指令。只有四个是必不可少的,如果我们在一个“受信任”的盟友中缺少一个,我们将用我们自己的盟友代替它。
  • 295-300行有效地提高了效率。通过在游戏的前两个回合中保护我们的旗帜,我们可以避免笨拙的机器人取代我们的旗帜,然后我们才有机会传播到很远。但是,等待更长的时间使其他机器人有机会替换我们的BlockFunction,这会导致性能下降(由于RandomBot干扰试图撤消破坏的盟友而引起的怀疑)。
  • 在该机器人的开发过程中,最长的时间是,该机器人使HelperBot突飞猛进,一度突破了130分,而该机器人则在81-98范围内徘徊,但将MarkedBot和DefaultBot的有效性降低了几个点。
  • 该机器人只能通过添加的functionsMatch方法来实现。没有functionsMatch它,就不可能写出可以做出有意义决定的机器人,因为它是盲目的。它可以读取其目标变量和日志,但不了解其目标状态。

仍有可能进行一些改进,但我看不到它们。第198-205行可能是性能问题,但是直到IPAddress类允许将地址重新构造为不存储在Variables中之前,这是必需的(因为漫游器无法验证地址,任何无效地址的存储都会导致游戏将空目标包装在ReadOnlyBot中,并抛出NPE)。

编辑:更新12/12/15

调整getTurnNumber()逻辑上的某些参数可以提高性能。最终游戏目标从5%提高到10%大约价值15分,同样,早期游戏目标也从5%提高到8%。现在,即使遇到AmnesiaaBot,该机器人也可以(几乎)存活下来(得分110分排名第二,HelperBot达到117分)。

即使进行了这些调整,它也会变得不走运,因此对于10局来说,其得分范围约为170-185。


太棒了!故意不能从字符串创建IPAddress。
弥敦道·美林

好吧,表面上是,是的!(或者,机器人会创建任意机器人以寻找新的机器人)。问题是,如果执行此操作,则会崩溃。;)
Draco18s 2015年

Urm,在第143行上,您使用了不存在的构造函数。
TheNumberOne

@TheNumberOne当我写的时候是有效的。内森可能会更新基地。
Draco18s 2015年

@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

帮手

助手机器人什么也不做,只能尝试传播自己的标志……或者至少是它当前正在运行的标志……

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,但这将涉及大量使用Variables而没有任何功能收益,尤其是考虑到AmnesiaBot正在发挥作用。


1

笨蛋

gh,这感觉很脏。这可能是唯一击败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";
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.