希尔团队!


27

这项挑战的灵感来自@HelkaHomba出色的挑战,即Red vs. Blue-Pixel Team Battlebots。这一挑战可能是我在本网站上看到的最好的挑战。曾经

我的挑战仍然很大,但是@HelkaHomba的灵感值得称赞。

总览

这是一个团队之,您的团队通过让所有玩家都存活在团队中而获胜。换句话说,最后一支球队获胜。抽奖将被重做。

您在董事会上。您知道自己在第一轮的位置(打勾0)。您还知道周围的人是谁:

9x9网格中的单个红色正方形,周围是白色单元格。

在这种情况下,您一个人(或者您认为)独自一人,周围没有人。您可以在ontick处理程序的第一个参数中看到周围的项目。稍后会更多有关API的信息。

你的团队

您的团队由您的用户ID决定。要找出答案,请单击您的个人资料图片:

我的个人资料图片

然后在地址栏中找到您的用户ID:

在/ users /和/ yourusername之间

如果很奇怪,那么您就是蓝队。

如果是偶数,则说明您是红色团队。

手绘圈欢迎您。

您(机器人的)名字

您的漫游器名称以团队的第一个字母(“ r”或“ b”)开头。它必须匹配正则表达式/^(r|b)[A-Za-z_-]$/。除此之外,您还可以选择机器人的名称。请不要使用已经存在的一个。

开始

红色玩家将从地图顶部附近开始,蓝色玩家将从底部附近开始。environmentontick函数的参数的第一个刻度(转弯)上会给您特殊信息。我建议将其存储。有关详细信息,请参见API。

轮到你了

回合顺序最初是随机的,但随后保持不变。

转身动作

您每回合只能做一个动作。

  • 移动

    当您想移动时,可以调用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个方格中的所有玩家,包括您和队友。例:

    每个单元格中都有一个9x9的网格,其中带有“ x”。

    您为什么要这样做? 神风。如果周围的9个单元中没有更多的球员在您的团队中,那么您的团队中就有更多的球员,那么您可以考虑轰炸。(我建议你先通知你的同志们!)

  • 放置地雷

    这为不在您团队中的其他人创建了死亡广场。放置地雷时,您也要移动,以免踩到它。您调用this.landMine(num)num是要去的平方。例:

    9x9网格中的单个红色正方形,周围是白色单元格。

    然后您致电this.landMine(4)

    [9x9网格,中间有一个红色的“ M”,右中间有一个红色的单元格。

    看到那个“ M”?这是地雷。其他人现在可以看到它。任何人,甚至是不在您团队中的人,都可以在放置的滴答声中看到地雷。但是在那滴答滴答结束后,没人能看到它。但是一旦敌人越过它就会爆炸。例:

    两个9x9网格,第一个网格中间的蓝色单元格,第一个网格中间的红色“ M”,第二个网格中间的红色“ 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]
]

请注意,与挖掘不同,挖掘揭示了位于先前刻度上的地雷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

您的代码必须包含对该函数的单个调用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)

    轮到您时调用。必须返回Promise在1秒或更短时间内解决的,否则它将被忽略。这是出于性能原因,并且具有没有挂起标签的良好副作用。

    this (在提示时)

    • landMines 您还剩下多少个地雷。杀死的人越多,获得的地雷就越多。每杀死2个机器人,您就会获得1个地雷。您还将获得1开始。
    • direction 您所面对的方向。
    • storage 在对onTick和的调用之间持续存在的存储onMessage。开始时为空对象。出于任何目的进行修改,但请确保始终是数组或对象,以确保其正确存在。
    • move(num) 移动到指定位置。如果无效,则不执行任何操作。有关详情,请参见上文。
    • rotate(num) 旋转到指定位置。如果无效,则不执行任何操作。有关详情,请参见上文。
    • kill() 杀死您面对的玩家(如果存在且不在您团队中)。有关详情,请参见上文。
    • bomb() 杀死您周围9个方格中的任何人,包括您自己。
    • landMine(num) 将地雷放置在您所在的位置,然后移动到指定位置。如果无效num或您什么都没有,则什么也不做。有关详情,请参见上文。
    • dig() 新! 返回有关以您为中心的5x5区域中的地雷的信息的数组。有关详情,请参见上文。
    • sendMessage(recipients, team, data) recipients可以是单个bot(字符串),bot数组或undefined/ null。您想发送信息的人是谁。 team是您要发送消息的团队的字符串。用于"*"向所有人发送消息。 data是可以传递给JS函数的任何东西。它被发送给收件人。如果它是对象或数组,则通过引用传递,因此您和接收者可以将其保存到对象或数组中,并且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,左下角有一个红色“ M”,其中有一个黑色5。

  • onmessage(data, fromBot, fromTeam)

    this (当出现消息时)

    • sendMessage(recipients, team, data) 标准消息发送功能。
    • storage 标准存储。

    data从发送方发送的数据。 fromPlayer发送消息的播放器。 fromTeam发送消息的团队。

  • onkill()

    this (当被杀死时)

    • sendMessage(recipients, team, data) 标准消息发送功能。

方便的(恒定的)全局数组:

threeByThree

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

对于将数据传递到移动功能以及解释很有用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来测试bot。

请注意,您必须将代码粘贴到控制台中,并Enter在单击运行之前按。您可以根据需要粘贴任意数量的机器人。“测试机器人”是供您测试的示例。如果您能击败或打败所有人,那么您至少拥有一个不错的机器人。

意见书

规则

规则(由控制器强制执行)

  • 您的主ontick代码不得超过1秒。我们不希望回合永远持续下去。如果您的代码花费> 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是的,但其他人必须将其发布。您可以发布一个机器人,然后将另一个机器人的代码提供给团队中的某人,但是您不能发布两次。
程序员

关于定位,[0,0]索引的单元格在哪里,它是左上角的单元格吗?另外,消息传递是否会消耗您的动作(每回合)?谢谢。
Thrax

@Thrax是的,不是。您甚至可以响应消息。
程序员

Answers:


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不,我不介意,但是如果您使两者至少有所不同(至少是对已经存在的2个机器人的补充),那对您和团队来说会更有趣。
plannapus

会做到的。我将对其进行更改
Christopher

如果我尝试在Codepen中运行您的机器人,则由于您正在使用this.x等原因而无法正常工作,但这是正确的environment.x还是我错了?
WasteD '17年

就像我说的@WasteD我根本不懂Javascript,所以有可能。但如果是的话,那么我想这也应该是environment.gridHeightenvironment.aroundMe?在这种情况下,其他bot都不会使用,因为它们都使用this.aroundMe
plannapus '17

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

大多数情况下是随机的,但如果被包围,则会炸弹,并倾向于四处检查并杀死而不是移动。


聪明!好东西。
程序员

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由于机器人的名字必须以团队的字母开头,我想我是Red Team :)
Thrax(美国),2017年

不错的机器人!我建议您也向您的团队广播您周围的事情。
程序员

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

蓝斗士随机移动并扫雷,并向红斗士旋转。如果周围的方块红色多于蓝色,则会炸弹。如果它面对红色玩家,则将其杀死。

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.