生命,吉姆,但据我们所知


58

您可能知道Conway的“生命游戏”,这是数学家John Conway发明的著名的细胞自动机。生命是一组规则,这些规则可以使您一起模拟二维的细胞板。这些规则决定了板上的哪些单元生存,哪些单元死亡。凭空想像,您可以说Life是一个零玩家游戏:一种旨在发现有趣行为模式的游戏,例如著名的滑翔机。

滑翔机

零人游戏...直到今天。您将编写一个程序,玩人生游戏-并玩赢山丘之王。您的对手(单数)当然会尝试这样做。获胜者要么是拥有任何活细胞的最后一个机器人,要么是10000代后活细胞最多的玩家。

游戏规则

这些规则与正常(B3 / S23)寿命几乎相同:

  • 少于两个友好邻居的活细胞因饥饿而死亡。
  • 具有两个或三个友好邻居的活细胞可以存活。
  • 具有三个以上友好邻居的活细胞会因人口过多而死亡。
  • 如果没有敌方邻居,则死者牢房中只有一个同一个玩家的三个邻居,可以为该玩家战斗。

...但是每一代人之后,您和您的对手都有机会进行干预。您最多可以唤醒30个细胞为您而战。(谁先走是由服务器决定的。)

面板是一个(x,y)单元格正方形。所有方块最初都死了。边界不环绕(这不是圆环状的世界),并且永久死了。

这是本着BattlebotsCore Wars精神进行的竞赛。有一个将运行机器人的中央服务器,可以在这里找到

协议

竞技场服务器使用通过argv通信的简单JSON协议

其中Values是JSON编码的字符串

  • y_size:消失之前的最大y坐标
  • x_size:消失之前,瓦片的最大x坐标
  • tick_id:当前的刻度号
  • board:字典,键的形式为'(y,x)',值的形式为bot_id(int)
  • bot_id:具有此ID的木板中的瓷砖是您的

例:

 {"y_size":2000,"x_size":2000,"board":{},"bot_id":1,"tick_id":1}

告诉服务器您的选择:

  • 向服务器发送一个瓷砖列表以转换为您的颜色。
  • 只有那些空的将被更改
  • 嵌套坐标列表格式
    • [[0,0], [0,1], [100,22]...]

注意:您的机器人完全不需要更新磁贴-服务器会自行更新

比赛规则

  • 如果您的实现未能遵循该协议,那么该行为将被没收;服务器将保持状态不变
  • 不允许您故意利用竞技场服务器中的故障。
  • 让您的AI在合理的时间内决定动作。请尽快发送您的下一步行动。
  • 最后,请对服务器友好。它在那里供您享受。
  • 不遵守这些规则会导致失格。
  • 如果出现平局,则两名玩家的总胜利数为1

自己运行控制器

控制器的源代码可以在这里找到。有两种运行控制器的方式:

  • 竞赛模式(终端)
    • 设置 python3 get_answers.py
    • 每个机器人相互竞争,进行全面竞争。
  • 测试模式(GUI)
    • python3 nice_gui.py
    • 请点击 Pull Answers
    • 如果要添加自己的答案以在发布前进行尝试,请单击File -> Add manual answer并找到文件,然后选择其书写语言。
    • 如果您的语言不正确,请尝试在服务器上安装它,我将在其上运行(安装和运行说明也很不错!)
    • 选择2个机器人互相对抗
    • 请点击 Run
    • 看比赛...
  • 安装
    • 需要python3
    • get_answers需要bs4和html5lib
    • 控制器需要一种运行.sh文件的方式(Windows上的MinGW)

应用示例图片

计分

12/07/2016(7月12日) 14/07/2016(7月14日,无法解决如何运行机器人)获胜最多的机器人。


可以在此聊天室中询问控制器/ GUI的帮助


自2014年以来,这个问题一直在开发中,并且是沙盒中提出最多的问题。特别感谢Wander Nauta(原始作者和概念),PPCG Chat(评论和帮助)以及在沙盒帖子中发表评论的任何人(更多评论)。


25
thought,我以为这将永远不会超出沙盒。大!
Luis Mendo

错别字:2016年12月
路易斯·门多

4
+1。您应将这个伟大的问题带出沙盒,而获得AED大奖!
2016年

1
@ KevinLau-notKenny哦,好的。您可以在文件中运行命令吗?
Rɪᴋᴇʀ

1
@Magenta当我得到它们时(即使它一直处于不断打开的标签中,我也完全忘记了它),我现在正在运行它
Blue

Answers:


4

Python 3,爆炸程序

在周围放置小爆炸物,而不管那里是否已经有障碍物。

from random import randint
import sys,json,copy
q=json.loads(sys.argv[1])
x=q["x_size"];y=q["y_size"];F=[[0,1],[1,0],[1,1],[1,2],[2,0],[2,2]];D=[]
for g in [0]*5:
 X=randint(0,x);Y=randint(0,y);A=copy.deepcopy(F)
 for C in A:C[0]+=Y;C[1]+=X
 D+=A
print(D)

1
我不敢相信,在我为无限期增长设置了块状开关以及专门为破坏增长结构而建立的系统之后,一个简单的基于爆炸物的系统在战斗中胜过了我:o
Value Ink

我也不知道它怎么做,因为无论出于什么原因我都无法运行控制器。
洋红色

8

Ruby,InterruptingBlockMaker

它没有初始化像TrainingBot这样的滑翔机,而是尝试在迷宫中的任意位置创建一个5x5的制块开关机,如Wikipedia所述。然后,在剩余的激活下,它只是找到敌人的点,并尝试用您的细胞给附近的地方撒些胡椒,以试图阻止它们的生长并弄乱它们的模式。您的细胞将在下一代死亡,但也许它们也停止了某些生长,从而减慢了您的对手的速度!

v2:略有优化(?),以尽量减少超时。

v3:经过优化的中断代码,可以在拒绝我们自己的单元位置之前对活动块的子集进行预采样,以防止进一步超时,以牺牲一些有效的中断单元攻击为代价。

require 'json'

class Range
  def product range2
    self.to_a.product range2.to_a
  end
end

args = JSON.parse(ARGV[0])
bot_id = args["bot_id"]
width  = args["x_size"]
height = args["y_size"]
board  = args["board"]

generator = [[2,2], [2,3], [2,6], [3,2], [3,5], [4,2], [4,5], [4,6], [5,4], [6,2], [6,4], [6,5], [6,6]]

targets = []

iterations = 50
gen_location = nil
while !gen_location && iterations > 0
  y = rand height - 9
  x = rand width  - 9
  temp = (0...9).product(0...9).map{|_y, _x| [y + _y, x + _x]}
  if temp.all?{|_y,_x| !board["(#{y},#{x})"]}
    gen_location = temp
    targets += generator.map{|_y, _x| [y + _y, x + _x]}
  end

  iterations -= 1
end

enemies = board.keys.sample(100).reject {|k| board[k] == bot_id}
interrupts = []
enemies.each do |location|
  y, x = location.scan(/\d+/).map &:to_i
  interrupts |= ((y-1)..(y+1)).product((x-1)..(x+1)).reject{|y, x| gen_location.include?([y,x]) || board["(#{y},#{x})"]}
end

targets += interrupts.sample(30 - targets.size)

puts JSON.dump(targets)

@muddyfish谢谢,已经解决了!现在唯一的问题是Windows命令行命令的硬编码限制为8191,这意味着在仿真的某个时刻,僵尸程序将因无法解析截断的JSON字符串而崩溃。这是一个操作系统的问题,所以我想我必须要寻找到一个Linux的云盒子什么的,为了测试我的机器人〜
价值油墨

@muddyfish我已经提到Windows由于命令行限制而出现问题,最后一个错误是在Cloud9(表面上是Linux机器)上。我的机器人在您的Linux机器上的价格如何(因为您暗示自己拥有一个)?
Value Ink 2016年

原来我没有承诺,但是bot_score显示的数字显示每个机器人与其他机器人相比有多少胜利
Blue

好的,谢谢!不幸的是,Cloud9确实没有GUI,Windows最终仍未打破其命令限制就无法运行模拟,但是至少我简要地了解了这些机器人之间的竞争方式。此外,我有时会看到我的机器人与自己抗衡,因为它们不断互相攻击并阻止足够的增长以突破角色限制,尽管有时会超时...
Value Ink 2016年

4

Python 2,TrainingBot

因为每个人都需要其中之一!

import random, copy
import sys, json

args = json.loads(sys.argv[1])
bot_id = args["bot_id"]
x_size = args["x_size"]
y_size = args["y_size"]
cur_tick = args["tick_id"]
board = args["board"]

glider = [[1,2],[2,1],[0,0],[0,1],[0,2]]

x_add = random.randrange(x_size)
y_add = random.randrange(y_size)
new_glider = copy.deepcopy(glider)
for coord in new_glider:
    coord[0]+=y_add
    coord[1]+=x_add
move = new_glider
print json.dumps(move)

4

Java,巨魔机器人

特洛尔·博特(Troll Bot)考虑了一下,他意识到自己不在乎敌人。实际上,他只是向这些工厂发送垃圾邮件,从而在整个地图上随机产生更多的家伙。过了一会儿,他意识到任何其他细胞最好用于团块。这些由四个单元构成的块将粘在一起并阻止滑行在其轨道上!他不认为自己只是在打架。他还是冗长的面向对象编程的大力支持者。巨魔还假设坐标的格式为y,x,并且他要求进行测试。只要将他放在一个名为“ TrollBot.java”的文件中,他就会被设置!

package trollbot;

/**
 *
 * @author Rohans
 */
public class TrollBot{
public static class coord{
    public int x;
    public int y;
    public coord(int inX,int inY){
        x = inX;
        y = inY;
    }
    @Override
    public String toString(){
        return"["+x+","+y+"]";
    }
}
    /**
     * Input the JSON as the first cla
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       String JSON="{\"bot_id\":1,\"y_size\":1000,\"x_size\":1000,\"board\":{}}";
    String[] JArray=args[0].split(",");
       int botId=Integer.parseInt(JSON.charAt(10)+"");
    int xSize=Integer.parseInt(JArray[2].substring(JArray[2].indexOf(":")+1));
    int ySize=Integer.parseInt(JArray[1].substring(JArray[1].indexOf(":")+1));
    int[][] board = new int[xSize][ySize];//0 indexed
//todo: parse the board to get an idea of state
    String soldiers="[";    
//for now just ignore whats on the board and put some troll cells on
    //Attempts to create 3 10 cells factories of cells, hoping it does not place it on top of allies
    //Then puts random 2/2 blocks
  boolean[][] blockspam=new boolean[10][8];
  blockspam[7][1]=true;
  blockspam[5][2]=true;
  blockspam[7][2]=true;
  blockspam[8][2]=true;
  blockspam[5][3]=true;
  blockspam[7][3]=true;
  blockspam[5][4]=true;
  blockspam[3][5]=true;
  blockspam[1][6]=true;
  blockspam[3][6]=true;
  for(int z=0;z<3;z++){
     int xOffSet=(int) (Math.random()*(xSize-11));
     int yOffSet=(int) (Math.random()*(ySize-9));
     //stay away from edges to avoid odd interactions
     for(int i=0;i<blockspam.length;i++){
         for(int j=0;j<blockspam[i].length;j++){
             if(blockspam[i][j])
             soldiers+=new coord(j+yOffSet,i+xOffSet).toString()+",";
         }
     }
  }
  soldiers=soldiers.substring(0,soldiers.length()-1);
  for(int i=0;i<8;i++){
            int y=(int ) (Math.random()*(ySize-1));
            int x = (int) (Math.random()*(xSize-1));
      soldiers+=new coord(y,x).toString()+",";
                          soldiers+=new coord(y+1,x).toString()+",";
                          soldiers+=new coord(y,x+1).toString()+",";
                          soldiers+=new coord(y+1,x).toString()+",";

  }
  soldiers+="\b]";

  System.out.println(soldiers);
  //GO GO GO! Lets rule the board
    }

}

3

Python 3,RandomBot

该机器人很难做出明智的决策,但至少知道不尝试将事物置于其他事物之上。它将随机创建具有不同方向的滑翔机,船,C / 2正交和2x2块,以确保放置它们时不会与其他盟友或敌人重叠。

该漫游器未经测试,因为在尝试运行GUI时收到各种错误。另外,我使用TrainingBot作为基础并进行编辑,因此代码中的任何相似之处都可能是由于此。

import random, copy
import sys, json
args = json.loads(sys.argv[1])
bot_id = args["bot_id"]
x_size = args["x_size"]
y_size = args["y_size"]
board = args["board"]
occupied = [tuple(key) for key,value in iter(board.items())]
cellsleft=30
move=[]
choices = [[[1,2],[2,1],[0,0],[0,1],[0,2]],
           [[0,0],[0,1],[1,1],[1,0]],
           [[0,1],[1,0],[0,2],[0,3],[1,3],[2,3],[3,3],[4,3],[5,2],[5,0]],
           [[0,0],[1,0],[0,1],[2,1],[2,2]]]
while cellsleft>0:
    x_add = random.randrange(x_size)
    y_add = random.randrange(y_size)
    new_glider = copy.deepcopy(random.choice(choices))
    randomdirection = random.choice([[1,1],[1,-1],[-1,1],[-1,-1]])
    maxy=max([y[0] for y in new_glider])
    maxx=max([x[1] for x in new_glider])
    for coord in new_glider:
        coord[0]=coord[0]*randomdirection[0]+y_add
        coord[1]=coord[1]*randomdirection[1]+x_add
        cellsleft-=1
    set([tuple(x) for x in new_glider]) 
    if not set([tuple(x) for x in new_glider]) & (set(occupied)|set([tuple(x) for x in move])) and cellsleft>0:
        if min(y[0] for y in new_glider)<0: new_glider = [[y[0]+maxy,y[1]] for y in new_glider]
        if min(y[1] for y in new_glider)<0: new_glider = [[y[0],y[1]+maxx] for y in new_glider]
        move += new_glider
    elif set([tuple(x) for x in new_glider]) & (set(occupied)|set([tuple(x) for x in move])):
        cellsleft+=len(new_glider)

print(json.dumps(move))

1
GUI很可能由于print(sys.argv[1])第3行而失败,这使输出混乱(模拟器期望仅唤醒您想要的坐标字符串)。另外,程序的最后一行缺少结束括号。
Value Ink

@ KevinLau-notKenny GUI在训练机器人和Ruby机器人上也失败了。但是,我删除了该行,并添加回了结尾括号(我认为后者是一个复制粘贴错误)。
史蒂文·H.

您使用的是什么操作系统,并且在运行时在命令行中出现什么错误?当前,这是Windows不能正常运行sim卡的已知错误,因为当超过8000个命令行字符限制时,通过命令行传递的参数将被截断。–
Value Ink

@ KevinLau-notKenny我正在使用Windows 10,但是我得到了……好吧,很多错误。首先是BeautifulSoup不想找到html5lib,然后又找不到包含所有机器人的文件夹(我必须更改这两个机器人的代码),此后,任何一个Python机器人的运行都导致返回非零的返回代码1.
Steven H.

如果屏幕上的活动单元过多,Windows仍将无法运行代码。但是对于其他错误,可能是因为TrainingBot需要Python 2?
Value Ink

3

Python,GuyWithAGun

他是个男人,他有枪;他疯了。他只是到处扔滑翔机枪而无视其他人在做什么

import random, copy
import sys, json

args = json.loads(sys.argv[1])
bot_id = args["bot_id"]
x_size = args["x_size"]
y_size = args["y_size"]
tick_id = args["tick_id"]
board = args["board"]

start_squares = [[0,5],[2,5],[1,6],[2,6],
                 [35,3],[36,3],[35,4],[36,4]]
gun = [[11,5],[11,6],[11,7],
       [12,4],[12,8],
       [13,3],[13,9],
       [14,3],[14,9],
       [15,6],
       [16,4],[16,8],
       [17,5],[17,6],[17,7],
       [18,6],
       [21,3],[21,4],[21,5],
       [22,3],[22,4],[22,5],
       [23,2],[23,6],
       [25,1],[25,2],[25,6],[25,7]]

templates = [start_squares, gun]

def add_squares(pos, coords):
    new_squares = copy.deepcopy(coords)
    for coord in new_squares:
        coord[0]+=pos[0]
        coord[1]+=pos[1]
    return new_squares

def get_latest_pos():
    seed, template_id = divmod(tick_id, 2)
    random.seed(seed)
    cur_pos = [random.randrange(y_size),
               random.randrange(x_size)]
    cur_template = templates[template_id]
    try:
        return add_squares(cur_pos, cur_template)
    except IndexError:
        return []

move = get_latest_pos()

print json.dumps(move)

2

Python 3,SquareBot

到处都放正方形-也许

正方形是生命中的静态对象-它们不会移动。因此,如果我在周围放置足够的惰性物体,其他人造成的滑行和爆炸可能会被阻止,或至少被抑制。

-改编自TrainingBot

from random import randint
import sys,json,copy
args=json.loads(sys.argv[1])
x=args["x_size"];y=args["y_size"]
square=[[0,0],[0,1],[1,0],[1,1]];D=[]
for g in range(7):
 X=randint(0,x);Y=randint(0,y)
 A=copy.deepcopy(square)
 for C in A:C[0]+=Y;C[1]+=X
 D+=A
print(D)

虽然我在测试时遇到麻烦



我可以证实,这个僵尸程序实际上做什么它的意思是-它帮助我找到并修复在控制器中的错误
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.