火箭机器人KOTH


11

火箭机器人

那一年是3024年。人们已经变得资源稀缺,无法在战争中冒险,因此战斗已经转移到了机器人身上。您的任务是构造一个与众不同的机器人,该机器人的火箭将摧毁敌人的敌人,击落所有即将到来的威胁。

游戏玩法

机器人

游戏玩法在10x15的网格上进行。您的机器人位于底部边缘之外,并且在网格的位置6,7和8处具有三个插槽。您的对手位于网格的顶部,在您的对面有三个插槽。

火箭队

从任何一个插槽中,您都可以发射火箭,前提是该插槽尚未销毁。火箭由创建时给出的方向列表组成,一旦发射,这些方向就无法更改。每转一圈,火箭将消耗列表的顶部,并朝该方向移动。火箭同时移动。如果两枚火箭以相同的砖块结尾,它们都会爆炸。如果火箭用完了命令,它将爆炸。如果火箭用尽燃料,则在移动100次后会爆炸。火箭爆炸时,它将在该磁贴中保留5圈,从而导致其他任何在那里移动的火箭也爆炸。

注意: 由于同时运动,两个火箭可以彼此通过而不会爆炸,只要它们不都在相同的瓦片中结束转弯即可。

目标

每场比赛的目的都是在保持对手生存的同时消灭对手的位置。可以从您拥有的任何活动插槽中发射火箭,并在发射前为其指定路径。您每转一圈发射一枚火箭,这意味着火箭将移动两次,然后再发射另一枚。决斗持续200回合,或者直到一个机器人插槽全部被破坏。

计分

比赛结束时,您每拥有一个实时角子机就获得1分,而您摧毁的每个对手角子机则得到1分。这意味着这是一场零和游戏,每场比赛将获得6分。

轮循将运行,以便每个机器人都彼此面对一次。如果有任何机器人使用RNG,则每个对决将是1000次对决。

实作

比赛代码可以在这里找到:https : //github.com/Cain93/RocketBots

每次提交都应扩大Bot班级。您必须重写该fireRocket方法。此方法接收Rocket[][]代表游戏板的Rockets的网格数组。你总是位于网格的底部,与斑点插槽[-1][6][-1][7][-1][8]。在网格上,未占用的地点将用表示null。如果磁贴中存在火箭,则可以通过访问该dis字段来识别它属于谁。“ ^”是您的火箭,“ v”是您的对手。

您必须返回一个给出了火箭说明的整数链接列表。要向上移动,请使用0。要向上和向右移动,请使用1,就在右边,使用2,依此类推,一直到7向上和向左。火箭将按您推动整数的顺序移动。例如,以下代码将使火箭向上旋转几圈,使之弯曲几圈,然后爆炸。

LinkedList<Integer> moves = new LinkedList<Integer>();

moves.push(0);
moves.push(0);
moves.push(0);
moves.push(1);
moves.push(7);
moves.push(1);
moves.push(7);

要更改从哪个插槽发射火箭,请更改curSlot字段。0是您最左边的插槽,2是您最右边的插槽。要检查插槽是否已损坏,请使用getSlot(int slotNumber)

如果火箭在插槽上结束转弯,则该插槽将被销毁。您无需手动引爆火箭。

注意:火箭在发射出的插槽位置生成,但在评估碰撞之前会移动一次。因此,如果您从插槽0发射火箭,而第一步是正确的(2),那么您将摧毁自己的中间插槽。但是,向上和向右(1)是安全的举动。

如果要命名您的机器人,请覆盖该name()方法。

机器人将为每个决斗重新构建,因此所有静态变量都将被重置。

祝好运!

愿您的火箭真实飞行,而您的对手不过是闷烧的金属碎片。

暗示:

与试图击落对手的火箭相比,有目的地引爆火箭以产生爆炸是一种更容易防御的防御方法。

机器人例子

package bots;

import java.util.LinkedList;

import mechanics.*;




public class SimpleBot extends Bot {

    public String name(){
        return "Simple";
    }

    public LinkedList<Integer> fireRocket(Rocket[][] g){

        LinkedList<Integer> l = new LinkedList<Integer>();
        for(int i = 0; i < 12; i++){
            l.push(0);
        }
        return l;
    }

}

分数

分数从6-24

Simple: 900
Zigzagoon: 3654
Wall-E: 3606
Tortoise: 2248
3 Shot: 2334
HatTrickBot: 4287
Sniper: 2973
SideShooter: 2491
Terminator: 4835
StraightShot: 3378
Defender: 4570
MoreDakka: 4324

已修正,因此顺序无关紧要,如果有任何机器人使用RNG,那么我将每场比赛的跑步次数增加到1000次
该隐

1
有没有办法检查对手的插槽是否被破坏?getSlot(int)仅适用于我们的插槽,对吗?
Katenkyo 2015年

1
@Cain可能无法将任何火箭发射到被摧毁的插槽上可能很有趣:3
Katenkyo

1
@Manu这不是一个错误,您正在从侧面看板,因此左侧插槽是相对的
Katenkyo

1
很抱歉,已经修复了该错误,我只是忘了推它了!
该隐2015年

Answers:


3

后卫

Defender使用一种新型的防御方式:火箭在插槽前巡逻。这具有巨大的优势,因为火箭的寿命是100转而不是5转(例如爆炸)。

package bots;

import java.util.LinkedList;
import mechanics.*;

public class Defender extends Bot {
    int turn = 0;

    @Override
    public String name() {
        return "Defender";
    }

    @Override
    public LinkedList<Integer> fireRocket(Rocket[][] grid) {
        LinkedList<Integer> command = new LinkedList<Integer>();
        for (int i = 0; i < 3; i++) {
            if ((grid[0][6+i] == null || grid[0][6+i].getDis().equals("v")) && (grid[1][6+i] == null || grid[1][6+i].getDis().equals("v")) && getSlot(i)) {
                curSlot = i;
                command.push(0);
                for (int j = 0; j < 50; j++) {
                    command.push(0);
                    command.push(4);
                }
                break;
            }
        }

        if (command.isEmpty()) {
            if ((grid[0][9] == null || grid[0][9].getDis().equals("v")) && (grid[0][10] == null || grid[0][10].getDis().equals("v")) && (grid[1][10] == null || grid[1][10].getDis().equals("v")) && getSlot(2)) {
                curSlot = 2;
                command.push(1);
                command.push(1);
                command.push(4);
                for (int i = 0; i < 50; i++) {
                    command.push(6);
                    command.push(2);
                }
            } else if ((grid[0][5] == null || grid[0][5].getDis().equals("v")) && (grid[0][4] == null || grid[0][4].getDis().equals("v")) && (grid[1][4] == null || grid[1][4].getDis().equals("v")) && getSlot(0)) {
                curSlot = 0;
                command.push(7);
                command.push(7);
                command.push(4);
                for (int i = 0; i < 50; i++) {
                    command.push(2);
                    command.push(6);
                }
            }

        }

        if (command.isEmpty()) {
            if (turn % 2 == 0 && getSlot(0)){
                curSlot = 0;
                command.push(7);
                command.push(7);
                for (int i = 0; i < 7; i++) {
                    command.push(0);
                }
                command.push(2);
                for (int i = 0; i < 2; i++) {
                    if (Math.random() < 0.2) command.push(2);
                }
                command.push(1);
            } else {
                curSlot = 2;
                command.push(1);
                command.push(1);
                for (int i = 0; i < 7; i++) {
                    command.push(0);
                }
                command.push(6);
                for (int i = 0; i < 2; i++) {
                    if (Math.random() < 0.5) command.push(6);
                }
                command.push(7);
            }
        }

        turn++;
        return command;
    }
}

哇+1。很棒的机器人。但是正如您所说,当机器人在另一侧时,无法发挥出色。
Spikatrix

1
非常完美的比赛,恭喜您
该隐2015年

6

Zigzagoon

外部插槽变宽(略),然后向前移动并朝敌方插槽返回。中间插槽在中间向上呈锯齿形。

每隔一轮(3回合),它将进入防御模式,并在我自己的插槽附近爆炸一些火箭。攻击模式火箭然后绕过它们。没什么特别的,只是让比赛开始并进行的东西。

package bots;import java.util.*;import mechanics.*;

public class Zigzagoon extends Bot{
    String[] evenMoves = {"7000000001","0170710170","1000000007"};
    String[] oddMoves = {"0","00","0"};
    boolean even = true;
    public String name(){return "Zigzagoon";}

    public LinkedList<Integer> fireRocket(Rocket[][] g){
        curSlot = (curSlot+1)%3;
        if(curSlot<1)even=!even;
        String[] moves = even?evenMoves:oddMoves;
        LinkedList<Integer> command = new LinkedList<Integer>();
        for(int i=0;i<moves[curSlot].length();i++)
            command.push(moves[curSlot].charAt(i)-'0');
        return command;
    }
}

已修正,大部分差异来自于什至是真还是假。机器人现在在每次比赛前都会重建。
该隐2015年

嗯,那很有道理。我什至没有想到变量不会重置。谢谢:)
Geobits

5

终结者

我很自豪地介绍《终结者》!

每个火箭都从中间向左/向右移动,然后返回敌人的插槽。每两转,防御火箭就会直射并在槽口附近爆炸以保护它。

package bots;

import java.util.LinkedList;
import mechanics.Bot;
import mechanics.Rocket;

public class Terminator extends Bot {

    int n = 0;
    String[] moves = {"000", "0111107777", "00", "0077700111", "00", "0777701111"};

    public String name() {
        return "Terminator";
    }

    @Override
    public LinkedList<Integer> fireRocket(Rocket[][] g) {
        curSlot = (n+1) % 3;

        LinkedList<Integer> commands = loadCommands(moves[n % moves.length]);
        n++;

        return commands;
    }

    protected LinkedList<Integer> loadCommands(String commands) {
        LinkedList<Integer> linkedList = new LinkedList<Integer>();

        for (int i = 0; i < commands.length(); i++) {
            linkedList.push(commands.charAt(i) - 48);
        }

        return linkedList;
    }

}

3

帽子戏法

我有CodeBot 3的DoubleTapBot,他在一个回合中两次击中,这里出现了HatTrickBot:同时击中所有三个点!

如果您知道火箭将下落的位置,总是可以防止火箭击中。但是我认为没有很多机器人能够保护自己的插槽不受3枚火箭弹的攻击。

顺便说一句,是的,看到这样的elseif反复切换很恐怖。我本可以创建一个var,以便为插槽状态和turnConter的每种组合使用唯一值打开。但这很难理解(我必须将值的含义保留在注释中……很无聊!):)

package bots;
import java.util.LinkedList;
import mechanics.*;
/*
 * HatTrickBot always tries to destroy all the enemy slots at once
 * In order to achieve this, each slot needs extrem concentration and coordination
 * It explain why they need some turns to re-synchronized the rockets after one of them dies.
 */
public class HatTrickBot extends Bot
{
    // Default moves are at [0]
    // moves at [1] are used when there's only 2 slots remaining
    // moves  [2-4] are here for when there's only 1 slot remaining
    // it panicks, and can't establish how to fire to do a hat trick.
    // So he will just spamm every ennemy position, one at a time
    String[] rightSlot = {  "770002000020",
                            "0000000001",
                            "0000000000",
                            "0000000001",
                            "0000000011"};
    String[] midSlot   = {  "0000000000",
                            "11000060000",
                            "0000000000",
                            "0000000010",
                            "0000000700"};
    String[] leftSlot  = {  "11000060007",
                            "777702000020",
                            "0000000000",
                            "0000007000",
                            "0000077000"};
    int turnCounter=-1;
    public String name(){return "HatTrickBot";}
    public LinkedList<Integer> fireRocket(Rocket[][] g)
    {
        turnCounter=(turnCounter+1)%3;
        String[][] moves = {rightSlot,midSlot,leftSlot};
        LinkedList<Integer> ll = new LinkedList<Integer>();
        boolean slotL=getSlot(0),slotM=getSlot(1),slotR=getSlot(2);
        int movePoint=0;
        if(slotL&&slotM&&slotR)
        {
            switch(turnCounter)
            {
            case 0: curSlot=0;
                break;
            case 1: curSlot=2;
                break;
            case 2: curSlot=1;
                break;
                default:break;
            }
            movePoint=0;

        }
        else if(!slotM&&slotL&&slotR)
        {
            switch(turnCounter)
            {
            case 0: curSlot=0;
                    movePoint=0;
                break;
            case 1: curSlot=2;
                    movePoint=0;
                break;
            case 2: curSlot=0;
                    movePoint=1;
                break;
                default:break;
            }
        }
        else if(!slotL&&slotM&&slotR)
        {
            switch(turnCounter)
            {
            case 0: curSlot=0;
                    movePoint=0;
                break;
            case 1: curSlot=1;
                    movePoint=1;
                break;
            case 2: curSlot=0;
                    movePoint=1;
                break;
                default:break;
            }
        }
        else if(!slotR&&slotM&&slotL)
        {

            switch(turnCounter)
            {
            case 0: curSlot=2;
                    movePoint=1;
                break;
            case 1: curSlot=1;
                    movePoint=1;
                break;
            case 2: curSlot=1;
                    movePoint=0;
                break;
                default:break;
            }
        }
        else
        {
            if(slotR)curSlot=0;
            if(slotM)curSlot=1;
            if(slotL)curSlot=2;
            movePoint = 2+turnCounter;
        }
        for(int i=0;i<moves[curSlot][movePoint].length();i++)
            ll.push(Integer.parseInt(moves[curSlot][movePoint].charAt(i)+""));
        return ll;
    }
}

火箭每隔一回合就开火,所以这并不能完全击中帽子戏法。虽然仍然非常有效
该隐2015年

@Cain Ho,很难过的是每2圈:/。无论如何,我会看到第一轮的结果,然后修改一下做一个真正的HatTrick,如果我认为它可以改善的话:)
Katenkyo 2015年

每次调用fireRocket()时,火箭都会两次移动。因此,现在,它们都彼此偏移了一个转弯。您可以在控制器中使用测试文件来查看匹配项的直观表示。
该隐2015年

@Cain当我写这些机器人的时候我还在工作,所以我只基于它们的规范:)
Katenkyo 2015年

哇,恭喜,您在没有任何测试的情况下就成功地写下了这一点。我更新了规格以使其更加清晰
该隐2015年

2

乌龟

如果我保护所有基地,我会得到3分。如果我的网格很好,只能从5个位置攻击基地。火箭持续5转身...

该机器人使用了所有这些功能来实现其目标:口袋中至少有50%的点可以生存。它发射3枚火箭,然后掩盖自身

package bots;

import java.util.LinkedList;

public class Tortoise extends Bot
{
    int turnCounter=-1;
    boolean attacked=false;
    int[] moves={7,0,0,0,1};
    public String name(){return "Tortoise";}
    public LinkedList<Integer> fireRocket(Rocket[][] g)
    {
         LinkedList<Integer> rocket = new LinkedList<Integer>();
         turnCounter++;
         if(!attacked)
         {
             curSlot=turnCounter;
             for(int i=0;i<11;i++)
                 rocket.push(0);
             if(turnCounter==2)
                 attacked=true;
             return rocket;
         }
         turnCounter%=5;
         switch(turnCounter)
         {
         case 0:
         case 1:curSlot=0;break;
         case 2:curSlot=1;break;
         case 3:
         case 4:curSlot=2;break;
            default:break;
         }
         rocket.push(moves[turnCounter]);
         return rocket;
    }
}

火箭每隔一回合就开火,所以您实际上只能维持两
该隐2015年

@Cain哦,所以我将其修改为一个真正的庇护所:)
Katenkyo 2015年

2

SideShooter

首先以两种不同方式之一通过第一个(最右边的)炮塔射击。然后,它以两种不同方式之一通过最后一个(最左侧)炮塔射击。然后,通过在每个转塔前面爆炸火箭,形成带有第二个(中间)转塔的“墙”。重复此过程。

如果游戏持续超过30回合,SideShooter就会变得无聊,并且变化很小。它没有直射第二(中间)炮塔的“墙”,而是直射。其余炮塔的行为相同。

import java.util.LinkedList;

public class SideShooter extends Bot {

    int[] launcher = new int[]{1, 3, 2, 2, 2};
    String[] right = {"1100000077", "100000007"};
    String[] left  = {"7700000011", "700000001"}; 
    int position = -1;
    int turns = 0;

    public String name(){
        return "SideShooter";
    }

    public LinkedList<Integer> fireRocket(Rocket[][] g){
      LinkedList<Integer> directions = new LinkedList<Integer>();

      if(getSlot(0) || getSlot(1) || getSlot(2))      
          do{
              position = (position + 1) % 5;
              curSlot = launcher[position] - 1;
          }while(!getSlot(curSlot));

      if(position == 0)
      {
          String shoot = left[((int) (Math.random() * left.length))];
          for(int i=0; i < shoot.length(); i++)
              directions.push(shoot.charAt(i)-'0');
      }else if(position == 1)
      {
          String shoot = right[((int) (Math.random() * right.length))];
          for(int i=0; i < shoot.length(); i++)
              directions.push(shoot.charAt(i)-'0');
      }else
      {
          if(turns < 30)
          {
            if(position == 2 )
                directions.push(0);
            else if(position == 3)
                directions.push(1);
            else if(position == 4)
                directions.push(7);
          }else
              for(int i=0; i < 10; i++)
                  directions.push(0); 
      }
      turns ++;
      return directions;
    }

}

do...while声明中做一个无限循环......
guy777

@ guy777,不,不是。一直循环直到找到未损坏的转塔。
Spikatrix

好 !这是我第一次与所有机器人,SideShooter和其他机器人(我不知道是哪个机器人)一起启动代码!
guy777

有些游戏无法完成。控制器应有转弯限制。
guy777

1
@CoolGuy我投票批准他的编辑。确保自己检查/测试。
mbomb007

2

狙击手

狙击手首先挡住其两侧,然后开始直线射击。

import java.util.LinkedList;

public class Sniper extends Bot {

    int[] launcher = new int[]{1, 3, 1, 2, 3};
    String[] moves = {"7", "1", "0000000000", "0000000000", "0000000000"}; 
    int position = -1, move = 0;

    public String name(){
        return "Sniper";
    }

    public LinkedList<Integer> fireRocket(Rocket[][] g){
        LinkedList<Integer> directions = new LinkedList<Integer>();

        if(getSlot(0) || getSlot(1) || getSlot(2))
        do{
            position = (position + 1) % launcher.length;
            curSlot = launcher[position] - 1;
        }while(!getSlot(curSlot));

        for(int i=0; i < moves[move].length(); i++)
            directions.push(moves[move].charAt(i)-'0');

        move = (move + 1) % moves.length;

        return directions;
    }

}

在此处查看有关SideShooter的评论,同一个问题。
该隐

2

三枪

我们拍了一些奇怪的镜头。没有真正的防御,但是这种模式使得很难摆脱这种奇怪的冰雹。(或者就是这个主意。它很可能行不通。)

package bots;import java.util.*;import mechanics.*;

public class ThreeShot extends Bot{
    public String name(){state = 0;return "3 Shot";}
    private int state;

    public LinkedList<Integer> fireRocket(Rocket[][] g){
        LinkedList<Integer> command = new LinkedList<Integer>();
        if(state < 2){
           state++;
           return fireLeft();
        }
        if(state < 4){
           state++;
           return fireCenter();
        }
        state=(state+1)%6;
        return fireRight();
    }
    LinkedList<Integer> fireCenter(){
        LinkedList<Integer> command = new LinkedList<Integer>();
        curSlot = 1;
        while(command.size()<90){
            command.push(1);
            command.push(7);
            command.push(6);
            command.push(1);
        }
        return command;
    }
    LinkedList<Integer> fireRight(){
        LinkedList<Integer> command = new LinkedList<Integer>();
        curSlot = 2;
        command.push(1);
        for(int i=0;i<8;i++){
            command.push(0);
        }
        command.push(7);
        return command;
    }
    LinkedList<Integer> fireLeft(){
        LinkedList<Integer> command = new LinkedList<Integer>();
        curSlot = 0;
        command.push(7);
        for(int i=0;i<8;i++){
            command.push(6);
            command.push(1);
        }
        command.push(1);
        return command;
    }
}

注意


2

更多达喀尔

达卡不停地向五个方向射击(直到炮塔被其他导弹击毁)。

import java.util.LinkedList;

public class MoreDakka extends Bot
{
    String[] moves={"70000000001", "0000000000", "0000000000", "0000000000", "1000000007"};
    int[] launcher = new int[]{0, 0, 1, 2, 2};
    int position = -1;

    public String name(){
        return "MoreDakka";
    }

    public LinkedList<Integer> fireRocket(Rocket[][] g)
    {
         LinkedList<Integer> directions = new LinkedList<Integer>();

         if(getSlot(0) || getSlot(1) || getSlot(2))
            do{
                position = (position + 1) % launcher.length;
                curSlot = launcher[position];
            }while(!getSlot(curSlot));

         for(int i=0; i < moves[position].length(); i++)
            directions.push(moves[position].charAt(i)-'0');

         return directions;
    }
}

1

直射

只是向他们开枪。

package bots;import java.util.*;import mechanics.*;

public class StraightShot extends Bot{
    public String name(){return "StraightShot";}

    public LinkedList<Integer> fireRocket(Rocket[][] g){
        LinkedList<Integer> command = new LinkedList<Integer>();
        curSlot = (curSlot+1)%3;
        for(int i=0;i<100;i++)
            command.push(0);
        return command;
    }
}

1
如果您不知道,这基本上与WaveBot相同,WaveBot是控制器随附的示例机器人之一。
Geobits,2015年

@Geobits我不知道示例机器人已经存在。
MegaTom 2015年

我的缺点是无法将Sample Bots放在更容易看到的地方。我要删除WaveBot并保留该条目
该隐

1

这是我自己的条目

瓦力

射击一些偏心火箭,并在他的边缘和中心建立墙壁。100转后,开始瞄准中间插槽。

package bots;

import java.util.LinkedList;
import java.util.Random;

import mechanics.*;


public class WallE extends Bot {

    int turn = 2;

    public String name(){
        return "Wall-E";
    }

    public LinkedList<Integer> fireRocket(Rocket[][] g){
        turn++;
        LinkedList<Integer> moves = new LinkedList<Integer>();
        curSlot = 1;
        switch(turn%4){
        case 0: 
            //Check the right wall
            if(getSlot(2)){
                curSlot = 2;
                moves.push(1);
                return moves;
            }
        case 1:
            //Check the left wall
            if(getSlot(0)){
                curSlot = 0;
                moves.push(7);
                return moves;
            }
        case 2:
            //Check the center wall
            if(getSlot(1)){
                curSlot = 1;
                moves.push(0);
                return moves;
            }
            break;
        default:
            //Fire a sneaky rocket
            Random rand = new Random();
            int direction = rand.nextInt(2);
            int back = 0;
            if(direction == 0 && getSlot(2)){ direction = 1; back = 7; curSlot = 2;}
            else{ direction = 7; back = 1; curSlot = 0; }
            moves.push(0);
            moves.push(direction);
            moves.push(direction);
            for(int i = 0; i < 5; i++){
                moves.push(0);
            }

            //Go for the center after turn 100
            if(turn > 104){
                moves.pop();
                moves.push(back);
            }
            moves.push(back);
            moves.push(back);


        }

        return moves;










    }

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