コードボット4:関数型プログラミング


25

sheesh、これは本当に4番目ですか?昔からのすべての人にとって、中心的な課題は同じですが、カスタム言語の代わりにJavaを使用しています。興味のある方のために、過去3つの CodeBot チャレンジをご紹介ます。

CodeBotsの目標は、ボットをできるだけバイラルにすることです。各ボットには旗があり、旗がどこにでもあることを確認する必要があります。

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つのうち)を選択して、ボットからボットにコピーできます。その後、関数はtheirsの代わりに呼び出されます。複数のボットが同じ機能を選択した場合、ランダムなボットが成功します。
  8. String getFlag()はゲームの終了時に呼び出され、送信に固有の文字列を返す必要があります。関数は常に同じ文字列を返す必要があります。ゲームの最後に最も多くのフラグが付いた提出が勝ちです。

ストレージ

ストレージには、AddressBookLogVariablesの 3つの形式があります。 これらの形式のストレージは、関数が実行されているボットに対してローカルです(関数がコピーされた場合、これらの各オブジェクトの内容は異なります)。これらのオブジェクトはすべて、手動で変更または消去できます。これらのオブジェクトを取得するには、クラスにゲッターがあります(例:)getLog()

アドレス帳は、リストに格納たIPAddressと、各AddressTypeにあなたがアドレスの種類を分類することができます。 AddressBookには常に少なくとも1つのアドレスが含まれます(クリアされた場合、ランダムなアドレスが追加されます)。アドレス帳をクリアして複数のIPアドレスを取得するは許可されていません。

ログはすべて実行されたアクションだけでなく、行動に関するデータのリストを格納します。また、成功したすべての攻撃の履歴も含まれます(ただし、どの機能が上書きされたかはわかりません)

変数オブジェクトを使用すると、文字列の名前に接続文字列変数を格納することができます。ゲームの開始時に、変数には単一の変数が含まれますID。これには、ボットタイプに固有のランダムに生成された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 null


Log.LogEntryを最終的なものにする必要があります。最終的なものではなく、必要な情報を使用してログを作成できます...ボット関数のみが読み取りまたは作成できるようにします。
TheNumberOne

readDataは、読み取り中のボットのIpAddressにアクセスできますか?
TheNumberOne

@TheNumberOneは現在ありませんが、なぜそうなのかわかりません。現時点ではコードはありませんが、コードを更新して変更します。
ネイサンメリル

3
ChaosがDisarmBotとMarkedBotをリーダーボードのトレードプレースにするのは興味深いことです。
TheNumberOne

1
現在、10000ラウンド中の7850で、より正確なスコアを取得しています...
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?";
    }
}

これは、よりスマートなスクリプトが何も記憶することができないためにのみ勝つと思います。すなわち、Variablesオブジェクトをクリアすることは本当に強力です。
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;
    }
}

これは、コントローラーと「ダムボットを許可する」ルールの制限をテストすることも目的としています。


技術的に彼は仕様に適合していません。なぜなら、彼はフラグに対して文字列を正確に返さないからです。
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!"; }
}

allAddresses()を実行する必要なく、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();
    }
}

このボットでいくつかのバグを発見しました(タイプミス、等しいではなく==を使用)また、私のシステムに欠陥を発見しました。新しいランダムなIPAddressesを作成できないはずです。私はその問題を修正しました(そしてそれを行うコードを削除しました)。更新されたコードはgithubで
ネイサンメリル

また、トップスポットにおめでとうございます!
ネイサンメリル

HelperBotはあまりスマートではありません。他のすべてのボットが愚かだったので、トップになりました。:Pこれはおそらく最初の効果的なボットです。
Draco18s

1
@NathanMerrillそれは、詐欺のために偽造IPAdressを作成することをもはや許可されないということですか?(もしそうなら、私は私のものを再設計する必要があります)
ニックロバートソン

ボットがラウンドに意図的にアクセスすることはありません。相手のIPアドレスを偽造として使用できますが、作成することは許可されていません。また、定数は静的時または初期化時に設定される変数です。
ネイサンメリル

2

SwarmBot

この名前のよくないボットはかなり複雑です(そしてこれまでで最も複雑なサブミットです)が、新しいターゲットに進む前に、ターゲットのすべてのメソッドを体系的に置き換えるボットを試みました。自身のコピーを特定して同盟国として扱い、定期的にチェックして整合性を保証しようとします。私はより良い名前を思いつきませんでした。

このボットの長さは340行なので、githubリポジトリブランチにリンクします。

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

いくつかの興味深い点:

  • 14〜24行目は、ボットがターゲットのメソッドを置換する順序を簡単に調整できる変更不可能なリストです。どのインデックスがオンになっているかを保存しVariables、各ラウンドでインクリメントします。これは、「非定数変数なし」ルールに従う必要があります。
  • 203〜217行目は味方の検証を扱っています。別のボットが8つの命令すべてを実装することは実際には気にしません。不可欠なのは4つだけです。「信頼できる」同盟国で1つが不足している場合は、それを自分のものに置き換えます。
  • 295〜300行目は、予想外の効果の向上でした。ゲームの最初の2ターンでFlagを保護することにより、非常に遠くに広がる前に、フラッグの代わりにダムボットを使用しないようにします。ただし、長く待つと、他のボットがBlockFunctionを置き換える機会が与えられ、パフォーマンスが低下します(ランダムボットが、破損を取り消そうとする同盟国に干渉するためと思われます)。
  • このボットの開発中に最も長い間、このボットは130マークを突破し、一時的に130マークを突破しましたが、このボットは81-98の範囲で衰退しましたが、MarkedBotとDefaultBotの有効性をいくつかのポイントに引き下げました。
  • このボットは、追加されたfunctionsMatchメソッドでのみ可能でした。なければfunctionsMatch、それは盲目だったので、意味のある意思決定を行うことができボットを書くことは不可能でした。ターゲットの変数とログを読み取ることはできますが、ターゲットの状態は何も知りません。

おそらくいくつかの改善が可能ですが、私はそれらを見ることができません。198行目から205行目はおそらくパフォーマンスを独占しますが、IPAddressクラスがアドレスを変数に格納することから再構成できるようになるまで、これが必要です(ボットにはアドレスを検証する手段がないため、無効なアドレスを格納するとゲームがNPEをスローして、ReadOnlyBotでnullターゲットをラップします)。

編集:アップデート12/12/15

getTurnNumber()ロジックのパラメーターの一部を調整することで、パフォーマンスをある程度向上させることができました。ゲーム終了時のターゲティングの5%から10%への増加は約15ポイントの価値があり、同様にゲーム初期のターゲティングを5%から8%に増加しました。このボットを組み合わせると、AmnesiaaBotに直面した場合でも(ほぼ)生き残ることができます(スコア110で2位に達し、HelperBotは約117に達します)。

これらの調整を行っても、不運になる可能性があるため、10ラウンドのスコア範囲は約170〜185です。


驚くばかり!文字列からIPAddressesを作成することはできません。
ネイサンメリル

表面的にはそうです!(または、ボットは新しいボットを見つけるために任意のボットを作成します)。問題は、シミュレーションを行うとクラッシュすることです。;)
Draco18s

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

DumbBot

うーん、これは汚い感じです。これは、おそらくAmnesiaBotを打ち負かす唯一のものです。実際には、その特殊なRandomBotだけです。シミュレーションでランダムボットを取得し(経由でgetAddressBook().clear())、ブロック関数またはフラグ関数のいずれかをランダムに置き換えます。 それでおしまい。 これらの2つだけを選択することにより、フラグ拡散率は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";
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.