ヒルのチーム!


27

この課題は、@ HelkaHombaの優れた課題である赤対青ピクセルチームバトルボットに触発されました。このチャレンジは、おそらくこのサイトで見た中で最高のチャレンジでした。今まで。

私の挑戦はまだ大きく異なりますが、@ HelkaHombaはそのインスピレーションに感謝します。

概要

これは、すべてのプレイヤーがあなたのチームで生き残っていることによってあなたのチームが勝つチームです。つまり、最後のチームに立って勝ちます。抽選はやり直されます。

あなたはボードに乗っています。最初のラウンドでのポジション知っています(0にチェックマークを付けます)。また、あなたはあなたの周りの地域に誰がいるか知っています:

白いセルに囲まれた9x9グリッドの単一の赤い正方形。

この場合、あなたの周りには誰もいませんでした。ontickハンドラーの最初の引数で周囲のアイテムを見ることができます。APIについては後で詳しく説明します。

あなたのチーム

チームはユーザーIDによって決定されます。それを見つけるには、プロフィール画像をクリックしてください:

私のプロフィール写真

次に、アドレスバーでユーザーIDを見つけます。

/ users /と/ yourusernameの間です

奇妙な場合、あなたは青いチームにいます。

偶数の場合、あなたは赤チームです。

手描きのサークルを歓迎します。

あなたの(ボットの)名前

ボットの名前は、チームの最初の文字(「r」または「b」)で始まります。正規表現と一致する必要があり/^(r|b)[A-Za-z_-]$/ます。それ以外は、ボットの名前を選ぶことができます。既存のものを使用しないでください。

起動

赤いプレーヤーはマップの上部近くから始まり、青色のプレーヤーは下部近くから始まります。関数のenvironmentパラメーターの最初のティック(ターン)に関する特別な情報が提供されontickます。保管することをお勧めします。詳細については、APIをご覧ください。

あなたの番

順番は最初はランダム化されますが、その後は変わりません。

ターンアクション

ターンごとに1つのアクションしか行えません。

  • 移動する

    移動したい場合this.move(num)は、API を呼び出します。num移動したいセルです:

    0は左上、1は真上、2は右上、3は右中、4は左中、5は左下、6は中央下、7は右下です。

    移動できる数値の相対位置は、グローバル定数に保存されますthreeByThree

[
    [0, 1, 2],
    [3, undefined, 4],
    [5, 6, 7]
]

壁や他のプレイヤーに移動して何も起こりません。

  • 回転

    回転するには、を呼び出しますthis.rotate(num)。Numは、回転させる方向です。

    0が上、1が右、2が下、3が左

    回転は絶対です。

  • 殺します

    (別のチームの)他のプレイヤーが直面しているセルにいる場合、this.kill()それらを呼び出して殺すことができます。誰もいない場合、または彼らがあなたのチームにいる場合、これは何もしません。例:

    上記と同じ数字、0セルは緑、1は青、2はオレンジ、3は黄色

    になっている場合0、緑を殺すことができます。1になっている場合、青を殺すことができます。2になったら、オレンジを殺すことができます。3になったら、黄色を殺すことができます。

  • 爆弾

    爆撃は、あなたとあなたの周りの9マスのチームメイトを含むすべてのプレイヤー殺します。例:

    各セルに「x」が付いた9x9グリッドがあります。

    なぜあなたはこれをしたいのですか? 神風あなたの周りの9つのセルにあなたのチームいないプレイヤーがもっといるなら、あなたのチームにもいるので、爆撃を検討するかもしれません。(最初に仲間に通知することをお勧めします!)

  • 地雷を配置する

    これにより、チームにいない他の人の死の広場が作成されます。地雷を配置すると、その上に足を踏み入れないように移動します。あなたは呼んでthis.landMine(num)numは、あなたがに行きたいの正方形です。例:

    白いセルに囲まれた9x9グリッドの単一の赤い正方形。

    それからあなたは電話するthis.landMine(4)

    [中央に赤い「M」があり、右中央に赤いセルがある9x9グリッド。

    その「M」を参照してください?それは地雷です。他の人はそれを見ることができます...今のところ。あなたのチームにいない人も含め、誰でもそれが置かれたダニの地雷を見ることができます。しかし、そのダニが終わった後、誰も、あなたもそれを見ることできません。しかし、敵がその上を歩くとすぐに爆発します。例:

    2つの9x9グリッド、最初の中央の左の青いセル、最初の中央の赤い「M」、2番目の中央の赤い「x」、およびそれらの間の矢印。

    青が地雷の上を移動し、ブーム!新たに殺されました。

    (直接的な殺人または地雷から)2キルごとに、1発追加の地雷を獲得します。また、最初に取得します。

  • 掘る

    掘るとき、あなたはあなたの周りにある5x5のエリアで地雷を探します。これは、地雷を置いたボットのチームを示していません。(あなたのチームの誰かが設置した地雷で殺すことはできないことを思い出してください。)例えば、これがあなたの周りのグリッドだった場合:

    の戻り値は次のthis.dig()ようになります。

[undefined,undefined,undefined,true,undefined,
undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,true,undefined,undefined,
true,undefined,undefined,undefined,undefined]

配列のインデックスは、左上から始まり、右ではなく、下から始まります。自分自身は含まれません。

合計で23あり、それらの相対位置はグローバル定数に保存されfiveByFiveます:

[
    [0, 1, 2, 3, 4],
    [5, 6, 7, 8, 9],
    [10, 11, undefined, 12, 13],
    [14, 15, 16, 17, 18],
    [19, 20, 21, 22, 23]
]

digは、とは異なり、以前のティックに配置された地雷を明らかにすることに注意してくださいaroundMe

コミュニケーション

誰かと話したいときは、を呼び出しますthis.sendMessage(recipients, team, data)。データをすることができ、あなたが欲しいもの、あなたはそれを送ることができますあなたが望むだれでも、他のチームにも、選手たち。これは、プログラミングが不十分なボットをだますために使用できますが、すべてのプレイヤーは誰がメッセージを送信し、誰がチームに所属しているかを確認できます。

例:

「redisbest」という名前のボットに何かを送信します。

this.sendMessage("redisbest", undefined, "Hi!");

「redisbest」および「blueiscool」という名前のボットに何かを送信します。

this.sendMessage(["redisbest", "blueiscool"], undefined, {hello: "there"});

赤チーム全体に何かを送る

this.sendMessage(undefined, "red", {hello: "red"});

みんなに何かを送る

this.sendMessage(undefined, "*", {hello: "everyone"});

赤いチーム全体と「blueiscool」という名前のボットに何かを送信します。

this.sendMessage("blueiscool", "red", {hello: "bots"});

API

コードは、関数の1回の呼び出しで構成する必要がありますcreateBot。他に何もありません。サンプルコード:

createBot({
    ontick: function(environment) {
        return new Promise((resolve, reject)=>{
            this.move(0);//example
            resolve();//please call this when you are done
        });
    },
    onmessage: function(data, from, fromBot) {
        console.log("onMessage: " + this.name + " from " + this.team + " got message ", data, " from " + from + ", on team " + fromTeam);
        this.sendMessage(["bot", "otherbot"], "team", "some data");
    },
    team: "red",//your team
    name: "rmyteamname",//team name must begin with the first letter of your team's name
    onkill: function(){
        //say goodbye
    }
});

(これを自由にコピーして貼り付けます。チームなどに合わせて変更するだけです。)

方法

  • ontick(environment)

    あなたの番になったときに呼び出されます。Promise1秒以内に解決するを返す必要があります。そうしないと無視されます。これはパフォーマンス上の理由によるもので、タブがハングしないという素晴らしい副作用があります。

    this (オンティックの場合)

    • landMines 残っている地雷の数。キルが多いほど、地雷が多くなります。ボットを2つ倒すごとに、地雷が1つ増えます。また、1を開始します。
    • direction あなたが向いている方向。
    • storage ストレージへの呼び出しの間持続することonTickonMessage。開始時の空のオブジェクト。目的に合わせて変更しますが、正しく保持されるように、常に配列またはオブジェクトであることを確認してください。
    • move(num) 指定した位置に移動します。無効な場合は何もしません。詳細については上記を参照してください。
    • rotate(num) 指定した位置に回転します。無効な場合は何もしません。詳細については上記を参照してください。
    • kill() 直面しているプレイヤーが存在し、チームにいない場合、プレイヤーを殺します。詳細については上記を参照してください。
    • bomb() あなた自身を含む、あなたの周りの9つの正方形の誰でも殺します
    • landMine(num) 現在地に地雷を置き、指定された位置に移動します。無効な場合、numまたは何も残っていない場合は何もしません。詳細については上記を参照してください。
    • dig() 新しい! あなたを中心とした5x5のエリアの地雷に関する情報の配列を返します。詳細については上記を参照してください。
    • sendMessage(recipients, team, data) recipients単一のボット(文字列)、ボットの配列、またはundefined/のいずれかnullです。あなたがメッセージを送りたい人です。 teamメッセージを送信したいチームの文字列です。"*"全員にメッセージを送信するために使用します。 dataJS関数に渡すことができるものです。受信者に送信されます。オブジェクトまたは配列の場合、参照によって渡されるため、ユーザーと受信者はそれを自分storageやオブジェクトに保存でき、オブジェクトへの変更は両方のボットのコピーに影響します。ボットのリスト、文字列で指定された正確なボット、または指定したチームのボットのいずれかにいる受信者は、メッセージを取得することに注意してください。

environment

最初のティックで

  • x:プレーヤーのx位置
  • y:プレーヤーのYポジション
  • gridWidth:グリッドの幅(セル単位)
  • gridHeight:グリッドの高さ(セル単位)

    すべてのティックで

  • aroundMe:プレイヤーと地雷の配列。プレイヤーは似たオブジェクト{name: "bot name", team: "bot team"}であり、地雷はそう{team: "team of bot who placed mine"}です。配列のインデックス:

    0は左上、1は真上、2は右上、3は右中、4は左中、5は左下、6は中央下、7は右下です。

    現在のティック以外のティックに配置された地雷は表示されないことに注意してください。

    aroundMe 例:

    これがグリッドであるとしましょう(あなたは赤です):

    9x9グリッド。左上に水色、右上に灰色の「M」、中央に赤、左中央に黄色、左下に赤の「M」があります。

    次のaroundMeようになります。

[
    {name: "bexamplebluebot", team: "blue"},
    undefined,//sparse array, nothing in index 1
    undefined,//there is technically a landmine here, but it wasn't placed this tick, so it is not shown
    undefined,//nothing in 3
    {name: "yexampleyellowbot", team: "yellow"},
    {team: "red"},//this is a landmine, you can tell is not a bot because it has no name. mines have the team name of the player they were placed by. This mine was placed this tick, otherwise you couldn't see it
    //nothing else after index 5, so the array's length is 5.
]

配列のインデックスは次のとおりです。

0は左上、1は真上、2は右上、3は右中、4は左中、5は左下、6は中央下、7は右下です。

ボットはこれを効果的に確認します。

左上に黒の数字0が付いた水色のボックス、左の端に黒の数字4が付いた黄色のボックス、左下に黒の5が付いた赤の「M」。

  • onmessage(data, fromBot, fromTeam)

    this (onmessageの場合)

    • sendMessage(recipients, team, data) 標準メッセージ送信機能。
    • storage 標準ストレージ。

    data送信者から送信されたデータ。 fromPlayerメッセージの送信元のプレーヤー。 fromTeamメッセージの送信元のチーム。

  • onkill()

    this (オンキルのとき)

    • sendMessage(recipients, team, data) 標準メッセージ送信機能。

便利な(定数)グローバル配列:

threeByThree

[
    [0, 1, 2],
    [3, undefined, 4],
    [5, 6, 7]
]

データをmove関数に渡したり解釈したりするのに便利ですaroundMe。上記を参照。

fiveByFive

[
    [0, 1, 2, 3, 4],
    [5, 6, 7, 8, 9],
    [10, 11, undefined, 12, 13],
    [14, 15, 16, 17, 18],
    [19, 20, 21, 22, 23]
]

ハンドラーthis.dig()内の関数に役立ちontickます。

やってみて!

コントローラは、パフォーマンス上の理由からローカルホスト上の私のマシンから実行されますが、CodePenを使用てボットをテストできます。

Enter実行をクリックする前に、コードをコンソールに貼り付けて押す必要があることに注意してください。好きなだけボットを貼り付けることができます。「テストボット」は、テスト対象の例です。あなたがそれらのすべてを打ち負かすか、または結ぶことができるならば、あなたは少なくともまともなボットを持っています。

提出

ルール

ルール(コントローラーにより実施)

  • メインontickコードは1秒以上かかることはありません。ラウンドが永遠に続くことは望ましくありません。コードに1秒以上かかる場合、停止します。
  • ターンごとに複数のアクションを実行しようとした場合、または無効なアクション(this.move(-1)壁への移動など)を実行した場合、それは無視されます。
  • もっとすぐに来るかもしれません...

ルール(私によって実施され、DQになる可能性があります)

  • グローバル変数を書き込まないでください(読み取りは問題ありません)。
  • あなたのコードは、そう、(場合にコントローラがNodejsに移植される)Nodejsで作業しなければならないJSON.parse(...)細かいですが、alert()ではありません。
  • あなたは呼び出すことが許可されていないcreateBotかのコントローラに干渉する任意の方法
  • 他人のコードを許可なく使用したり、大幅な変更を加えたりしないでください。コピーボットはありません。
  • 抜け穴はありません!
  • もっとすぐに来るかもしれません...

私のボット

ボットは次のとおりです。

このボットは、アクションをランダムに選択します。まあ、それは加重ランダムですが、それでもかなりランダムです。少なくともまともなボットを持っているよりも、このボットを殺すことができれば(最終的には自殺しますが、カウントされません)。それを投稿して、何が起こるか見てください!

ボットの名前は「x」で始まり、チームは「none」です。このコードの一部を使用することはできますが、少なくともいくつかの変更を行ってください。少なくとも数字を微調整することに煩わされなければ、勝つことはできません。

提出物のフォーマット

次の形式を使用してください:

# rmyamazingbot

    createBot({
        ontick: function(environment) {
            return new Promise((resolve, reject)=>{
                this.move(0);//example
                resolve();//please call this when you are done
            });
        },
        onmessage: function(data, fromTeam, fromBot) {
            console.log("onMessage: " + this.name + " from " + this.team + " got message ", data, " from " + from + ", on team " + fromTeam);
            this.sendMessage(["bot", "otherbot"], "team", "some data");
        },
        team: "red",//your team
        name: "rmyteamname",//team name must begin with the first letter of your team's name
        onkill: function(){
            //say goodbye
        }
    });

Long, but cool explanation...

機能のリクエスト、バグ、質問など?

以下にコメントしてください!そのコメントが既にあるかどうかを確認してください。すでにある場合は、それを投票します。

チームと話をしたいですか?

青のチャットルームを使用します。

言語

現在、JSとJSにコンパイルされるもののみがサポートされていますが、Nodejsで他の言語を動作させる方法を知っている場合は、コントローラーをNodejsに移植できます。

最終ノート

戦略のアイデア

あなたのチームを助けてください!別のボットを支援し、連携するように設計されたボットを作成します。この戦略赤対青でうまく機能しました-Pixel Team Battlebots

担当者

優勝チームで最も高い投票数の回答を受け入れます。以前の回答はより多くの票を獲得する傾向がありますが、それらの弱点は発見され、悪用される可能性が高いことに留意してください。

また、すぐに答えると、+ 100の賞金がもらえるかもしれません。


1
コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
デニス

複数のボットを作成できますか?(申し訳ありませんが、会話が動いたことはわかっています。チャット禁止になっているのでそうです)
マシュー・ノ

@SIGSEGVはい、ただし他の誰かが投稿する必要があります。1つのボットを投稿し、チームの誰かに別のボットのコードを渡すことはできますが、2回投稿することはできません。
Programmer5000

配置について、[0、0]インデックス付きセルはどこですか、それは左上のセルですか?また、メッセージングは​​あなたのアクションを消費しますか(ターンごとに)?ありがとう。
スラックス

@Thraxはい、いいえ。メッセージへの応答としてメッセージを送ることもできます。
Programmer5000

回答:


7

xscared(非競合)

createBot({
    ontick: function(environment) {
        var reverse = [0, 1, 2, 3, 4, 5, 6, 7].reverse();
        return new Promise((resolve, reject)=>{
            (this.aroundMe || []).forEach((item,idx)=>{
                this.move(reverse[idx]);
                return resolve();
            });
            this.move(~~(Math.random() * 8));
            return resolve();
        });
    },
    onmessage: function() {
    },
    team: "none",
    name: "xscared",
    onkill: function(){
    }
});

人がとても怖い。最初に見た人(または地雷)から離れます。それ以外の場合は、ランダムに移動します。これは競合するものではなく、単なる例であることに注意してください。それを破ってみてください!


6

バックアップ、青いボット

チャットで警告されたように、私は私の人生でjavascriptに何も書いたことがないので、間違いを見つけたら教えてください!(すでに私を支援してくれた@ programmer5000に感謝します)
このボットのコンセプトは、同じチームの他のボットと通信し、見つかった地雷の地図とともに位置を送信することです。最も近い青色のボット([x、y]配列として与えられた位置データを送信する場合)に参加しようとし、近くにとどまり(可能な限り背中を向けて)、近づいてくる赤色のボットを殺すか、鉱山の先に。

createBot({
    team: 'blue',
    name: 'backup',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            //if (typeof this.x != "undefined") this.storage['position'] = [this.x, this.y];
            if (typeof environment.x != "undefined") this.storage['position'] = [environment.x, environment.y]; //Modified according to @WasteD
            if (typeof this.storage['map'] == "undefined") { //Create empty map
                var map = [[]];
                //for(i=0;i<this.gridHeight;i++) map[i]=[];
                for(i=0;i<environment.gridHeight;i++) map[i]=[]; //Modified according to @WasteD
                this.storage['map'] = map;
            }
            var blue = []
            var red = []
            var x = this.storage['position'][0];
            var y = this.storage['position'][1];
            var dx = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
            var dy = [1, 1, 1, 0, 0, 0, -1, -1, -1]
            (this.aroundMe || []).forEach((item, idx) => { // Update map and list positions of surrounding blues and reds
                if (item && item.team == 'red' && typeof item.name != "undefined") red += idx;
                if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx[idx]][y+dy[idx]] = 'M';
                if (item && item.team == 'blue' && typeof item.name != "undefined") blue += idx;
            });
            this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']}); //Send to buddies my position and the map
            if (red.indexOf([1, 4, 6, 3][this.direction]) > -1) this.kill() ; //If red guy is in front of
            else if (red.indexOf([1,4,6,3]) > -1) this.rotate(red.indexOf([1,4,6,3])); //If red guy is next but not in front of
            else if (blue.indexOf(3) > -1){ //If blue buddy on the left
                if (blue.indexOf(4) > -1){ //If another one is on the right
                    if (blue.indexOf(1) > -1 && this.direction != 2) this.rotate(2); //...and a third one at the top
                    else var digging = this.dig();
                    }
                else if (this.direction != 1) this.rotate(1);
                else var digging = this.dig();
            }
            else if (blue.indexOf(1) > -1){
                if (blue.indexOf(6) > -1 && this.direction != 3) this.rotate(3);
                else if (this.direction != 2) this.rotate(2);
                else var digging = this.dig();
            }
            else if (blue.indexOf(4) > -1){
                if (this.direction != 3) this.rotate(3);
                else var digging = this.dig();
            }
            else if (blue.indexOf(6) > -1 && this.direction != 0) this.rotate(0);
            else if (blue.indexOf([0,2]) > -1){ //If no blue next to me but one in diagonal, move next
                this.move(1);
                this.storage['position'][1] = y+1; //Update position
            }
            else if (blue.indexOf([5,7]) > -1){
                this.move(6);
                this.storage['position'][1] = y-1;
            }
            else if (typeof this.storage['other_blue'] != "undefined"){ //Check if buddies said where they were, try to go near the closest one
                var dmin = 99999;
                var pos = []
                (this.storage['other_blue'] || {}).forEach((item, idx) => {
                    var d = Math.sqrt(Math.pow(item['position'][0]-x,2) + Math.pow(item['position'][1]-y,2));
                    if (d < dmin){
                        dmin = d;
                        pos = item['position'];
                        }
                });
                if (pos[0]-x > 0){
                    this.move(4);
                    this.storage['position'][0] = x+1
                }
                else if (pos[0] < 0){
                    this.move(3);
                    this.storage['position'][0] = x-1
                }
                else if (pos[1] > 0){
                    this.move(1);
                    this.storage['position'][1] = y+1
                }
                else{
                    this.move(6);
                    this.storage['position'][1] = y-1
                }
            }
            else var digging = this.dig();
            if (typeof digging != "undefined"){ //Check out surroundings if dig() was played and update the map accordingly
                var dx2 = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2];
                var dy2 = [2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2];
                (digging || []).forEach((item, idx) => {
                    //if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M';
                    if (item) this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M'; //previously misread what dig() returned
                });
            }
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {
        if (typeof data['position'] != "undefined" && fromTeam == 'blue') { //If position sent by a blue bot
            if (typeof this.storage['other_blue'] == "undefined") this.storage['other_blue'] = [];
            for (i in this.storage['other_blue']){
                var found = false;
                if ('name' in i){
                    if (i['name'] == fromBot){
                        i['position'] = data['position'];
                        found = true; //Update if position already known from previous ticks
                        }
                }
            }
            if (!found) this.storage['other_blue'] += {'position':data['position'], 'name':fromBot}; //Add position if previously unknown
            this.sendMessage(fromBot, undefined, "roger.");
        }
    },
    onkill: function() {this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']});}
});

ちょっとあなたも私がこれを入力するかどうか気にしますが、(別の名前で)私も青です
クリストファー

@Christopherいいえ、気にしませんが、少なくとももう1つ異なる(少なくとも既存の2つのボットを補完する)場合は、あなたにとってもチームにとっても少し面白いでしょう。
-plannapus

それをします。変更します
クリストファー

codepenでボットを実行しようとしても、使用しているthis.xなどの理由で機能しませんが、environment.x間違っているのでしょうか?
-WasteD

@WasteDは私が言ったように、Javascriptをまったく知らないので、可能です。それはケースだ場合しかし、私はそれがまたあるべき推測するenvironment.gridHeightenvironment.aroundMe?その場合、他のボットはを使用するため、動作しませんthis.aroundMe
プランナパス

5

青、青、私の世界は青

createBot({
    team: 'blue',
    name: 'blue-blue-my-world-is-blue',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            var red = 0;
            // See who's around me
            (this.aroundMe || []).forEach((item, idx) => {
                if (item && item.team == 'red') red++;
            });
            // If surrounded, take one for the team
            if (red >= 6) this.bomb();
            else {
                // Translate direction into position
                var kill = [1, 4, 6, 3][this.direction];
                // Random values
                var move = Math.floor(Math.random() * 8);
                var nsew = Math.floor(Math.random() * 4);
                // Lay a landmine if possible
                if (this.landMines) this.landMine(move);
                // Kill if someone is in the way
                else if (this.aroundMe && this.aroundMe[kill] && this.aroundMe[kill].team == 'red' && this.aroundMe[kill].name) this.kill();
                else {
                    // Move somewhere if already in the requested direction
                    if (nsew == this.direction) this.move(move);
                    // Otherwise just rotate to the requested direction
                    else this.rotate(nsew);
                }
            }
            resolve();
        });
    },
    onmessage: function(data, from, fromBot) {},
    onkill: function() {}
});

ほぼランダムですが、囲まれていると爆撃され、移動よりも周囲を確認して殺すことを好みます。


スマート!良いですね。
Programmer5000

3
聞いてよ、これは青い世界に住んでいる小さな男についての話だ。
マシュー盧

3

リラックスした爆撃機

このボットは、両側に少なくとも1つの空きセルがあるスポットを検索し、地雷を植えます。敵が近付くまでキャンプします。誰かが近づくと、彼は自分の鉱山で前後に歩き、その上で他のボットを餌にします。また、必要に応じて回転させて殺します。鉱山が残っていない場合、左上隅を壁に背を向けて避難し、脅迫された場合は報復します。

ここでは、selfキーワードを使用して自分の位置をチームにブロードキャストする以外に、特別なチームプレイはありません。

createBot({
    team: 'red',
    name: 'relaxed-bomber',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            if (typeof this.storage['dropped'] == "undefined") {
                this.storage['dropped'] = false;
                this.storage['covered'] = false;
                this.storage['baited'] = false;
            }
            if (typeof environment.x != "undefined" && typeof environment.y != "undefined") {
                this.storage['pos'] = [environment.x, environment.y];
            }
            if (typeof environment.gridWidth != "undefined" && typeof environment.gridHeight != "undefined") {
                this.storage['grid'] = [environment.gridWidth, environment.gridHeight];
            }
            var x = this.storage['pos'][0];
            var y = this.storage['pos'][1];
            var x0 = this.storage['grid'][0];
            var y0 = this.storage['grid'][1];
            var source = [1, 4, 6, 3];
            var dest = [6, 3, 1, 4];
            var rot = [0, 1, 2, 3];
            var movex = [-1, 0, 1, -1, 1, -1, 0, 1];
            var movey = [-1, -1, -1, 0, 0, 1, 1, 1];
            var action = false;
            if (this.landMines > 0) { 
                var move = [false, false, false, false];
                var moveIndex = -1;
                if (x <= 0) { move[1] = true; }
                if (x >= x0 - 1) { move[3] = true; }
                if (y <= 0) { move[2] = true; }
                if (y >= y0 - 1) { move[0] = true; }    
                if (move[0] && !move[1] && !move[2] && move[3]) { moveIndex = 0; }
                if (move[0] && !move[1] && !move[2] && !move[3]) { moveIndex = 1; }
                if (move[0] && move[1] && !move[2] && !move[3]) { moveIndex = 2; }
                if (!move[0] && !move[1] && !move[2] && move[3]) { moveIndex = 3; }
                if (!move[0] && move[1] && !move[2] && !move[3]) { moveIndex = 4; }
                if (!move[0] && !move[1] && move[2] && move[3]) { moveIndex = 5; }
                if (!move[0] && !move[1] && move[2] && !move[3]) { moveIndex = 6; }
                if (!move[0] && move[1] && move[2] && !move[3]) { moveIndex = 7; }  
                if (moveIndex >= 0) {
                    this.storage['pos'] = [ x + movex[moveIndex], y + movey[moveIndex]];
                    this.move(moveIndex);
                } else {
                    this.storage['dropped'] = true;
                    this.storage['covered'] = false;
                    this.landMine(1);
                }
            } else {
                if (this.storage['dropped']) {
                    this.storage['dropped'] = false;
                    this.storage['covered'] = true;
                    this.storage['pos'] = [ x + movex[6], y + movey[6]];
                    this.move(6);
                } else if (this.storage['covered']) {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            this.storage['covered'] = false;
                            this.storage['baited'] = true;
                            this.storage['mine'] = this.storage['pos'].slice();
                            this.storage['reverse'] = source[dest[i]];
                            this.storage['pos'] = [ x + movex[dest[i]], y + movey[dest[i]]];
                            this.move(dest[i]);
                            action = true;
                        }
                    }
                    if (!action) {
                        this.dig();
                    }
                } else if (this.storage['baited']) {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            if (this.direction == rot[source[i]]) {
                                this.kill();
                                this.storage['baited'] = false;
                                action = true;
                            } else {
                                this.rotate(rot[source[i]]);
                                action = true;
                            }
                        }
                    }
                    if (!action) {
                        if (this.storage['mine'][0] == this.storage['pos'][0] && this.storage['mine'][1] == this.storage['pos'][1]) {
                            this.storage['pos'] = [ x + movex[this.storage['reverse']], y + movey[this.storage['reverse']]];
                            this.move(this.storage['reverse']);
                            this.storage['reverse'] = source[this.storage['reverse']];
                        } else {
                            this.storage['pos'] = [ x + movex[this.storage['reverse']], y + movey[this.storage['reverse']]];
                            this.move(this.storage['reverse']);
                            this.storage['reverse'] = dest[this.storage['reverse']];
                        }
                    }
                } else {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            if (this.direction == rot[source[i]]) {
                                this.kill();
                                this.storage['baited'] = false;
                                action = true;
                            } else {
                                this.rotate(rot[source[i]]);
                                action = true;
                            }
                        }
                    }
                    if (!action) {
                        if (x > 0 && y > 0) {
                            this.storage['pos'] = [ x + movex[0], y + movey[0]];
                            this.move(0);
                        } else if (x > 0 && y == 0) {
                            this.storage['pos'] = [ x + movex[3], y + movey[3]];
                            this.move(3);
                        } else if (x == 0 && y > 0) {
                            this.storage['pos'] = [ x + movex[1], y + movey[1]];
                            this.move(1);
                        } else {
                            this.rotate(1);
                        }
                    }
                }
            }
            this.sendMessage(undefined, "red", {'self': this.storage['pos'] });
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {},
    onkill: function() {}
});

あなたはどのチームにいますか?
Programmer5000

@ programmer5000ボットの名前はチームの文字で始まる必要があるため、私はチームレッドだと思います:)
Thrax

素敵なボット!私もあなたの周りにあるものをあなたのチームにブロードキャストすることをお勧めします。
Programmer5000

1

別の青いボットを1つバックアップします(以前にこれを行うのを忘れていました)

createBot({
    team: 'blue',
    name: 'backup1',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            //if (typeof this.x != "undefined") this.storage['position'] = [this.x, this.y];
            if (typeof environment.x != "undefined") this.storage['position'] = [environment.x, environment.y]; //Modified according to @WasteD
            if (typeof this.storage['map'] == "undefined") { //Create empty map
                var map = [[]];
                //for(i=0;i<this.gridHeight;i++) map[i]=[];
                for(i=0;i<environment.gridHeight;i++) map[i]=[]; //Modified according to @WasteD
                this.storage['map'] = map;
            }
            var blue = []
            var red = []
            var x = this.storage['position'][0];
            var y = this.storage['position'][1];
            var dx = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
            var dy = [1, 1, 1, 0, 0, 0, -1, -1, -1]
            (this.aroundMe || []).forEach((item, idx) => { // Update map and list positions of surrounding blues and reds
                if (item && item.team == 'red' && typeof item.name != "undefined") red += idx;
                if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx[idx]][y+dy[idx]] = 'M';
                if (item && item.team == 'blue' && typeof item.name != "undefined") blue += idx;
            });
            this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']}); //Send to buddies my position and the map
            if (red.indexOf([1, 4, 6, 3][this.direction]) > -1) this.kill() ; //If red guy is in front of
            else if (red.indexOf([1,4,6,3]) > -1) this.rotate(red.indexOf([1,4,6,3])); //If red guy is next but not in front of
            else if (blue.indexOf(3) > -1){ //If blue buddy on the left
                if (blue.indexOf(4) > -1){ //If another one is on the right
                    if (blue.indexOf(1) > -1 && this.direction != 2) this.rotate(2); //...and a third one at the top
                    else var digging = this.dig();
                    }
                else if (this.direction != 1) this.rotate(1);
                else var digging = this.dig();
            }
            else if (blue.indexOf(1) > -1){
                if (blue.indexOf(6) > -1 && this.direction != 3) this.rotate(3);
                else if (this.direction != 2) this.rotate(2);
                else var digging = this.dig();
            }
            else if (blue.indexOf(4) > -1){
                if (this.direction != 3) this.rotate(3);
                else var digging = this.dig();
            }
            else if (blue.indexOf(6) > -1 && this.direction != 0) this.rotate(0);
            else if (blue.indexOf([0,2]) > -1){ //If no blue next to me but one in diagonal, move next
                this.move(1);
                this.storage['position'][1] = y+1; //Update position
            }
            else if (blue.indexOf([5,7]) > -1){
                this.move(6);
                this.storage['position'][1] = y-1;
            }
            else if (typeof this.storage['other_blue'] != "undefined"){ //Check if buddies said where they were, try to go near the closest one
                var dmin = 99999;
                var pos = []
                (this.storage['other_blue'] || {}).forEach((item, idx) => {
                    var d = Math.sqrt(Math.pow(item['position'][0]-x,2) + Math.pow(item['position'][1]-y,2));
                    if (d < dmin){
                        dmin = d;
                        pos = item['position'];
                        }
                });
                if (pos[0]-x > 0){
                    this.move(4);
                    this.storage['position'][0] = x+1
                }
                else if (pos[0] < 0){
                    this.move(3);
                    this.storage['position'][0] = x-1
                }
                else if (pos[1] > 0){
                    this.move(1);
                    this.storage['position'][1] = y+1
                }
                else{
                    this.move(6);
                    this.storage['position'][1] = y-1
                }
            }
            else var digging = this.dig();
            if (typeof digging != "undefined"){ //Check out surroundings if dig() was played and update the map accordingly
                var dx2 = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2];
                var dy2 = [2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2];
                (digging || []).forEach((item, idx) => {
                    //if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M';
                    if (item) this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M'; //previously misread what dig() returned
                });
            }
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {
        if (typeof data['position'] != "undefined" && fromTeam == 'blue') { //If position sent by a blue bot
            if (typeof this.storage['other_blue'] == "undefined") this.storage['other_blue'] = [];
            for (i in this.storage['other_blue']){
                var found = false;
                if ('name' in i){
                    if (i['name'] == fromBot){
                        i['position'] = data['position'];
                        found = true; //Update if position already known from previous ticks
                        }
                }
            }
            if (!found) this.storage['other_blue'] += {'position':data['position'], 'name':fromBot}; //Add position if previously unknown
            this.sendMessage(fromBot, undefined, "roger.");
        }
    },
    onkill: function() {this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']});}
});

1

ブルーファイター

createBot({
  team: "blue",
  name: "blue-fighter",
  ontick: function(environment) {
    return new Promise((resolve, reject)=>{
      let map = environment.aroundMe;
      let sides = [1, 4, 6, 3];
      let facing = sides[this.direction];
      let isTeam = (team,a) => a && a.team === team;
      let isRed = (a)=>isTeam("red",a);
      let isBlue = (a)=>isTeam("blue",a);
      let randomSquare = ()=>Math.floor(Math.random()*8);
      let redNum = map.filter(isRed).length;
      let blueNum =  map.filter(isBlue).length;
      if(redNum > blueNum && redNum > 2){
        this.bomb();
      }else if(isRed(map[facing])){
        this.kill();
      }else if(sides.includes(map.findIndex(isRed))){
        this.rotate(sides.indexOf(map.findIndex(isRed)));
      }else if(Math.random() < 0.5 && this.landMines > 0){
        this.landMine(randomSquare());
      }else{            
        this.move(randomSquare());
      }
      resolve();
    });
  },
  onmessage: function(data, from, fromBot) {},
  onkill: function(){}
});

青い戦闘機はランダムに移動して地雷を発し、赤いプレイヤーに向かって回転します。周囲のブロックが青よりも赤である場合、爆撃します。赤いプレイヤーに直面している場合、それを殺します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.