人生だよ、ジム


58

数学者のジョン・コンウェイが発明した有名なセルラーオートマトンであるコンウェイのゲーム・オブ・ライフをご存知でしょう。ライフとは、2次元のセルのボードをシミュレートできる一連のルールです。ルールは、ボード上のどのセルが生き、どのセルが死ぬかを決定します。想像力を働かせると、Lifeはゼロプレーヤーゲームであると言えます。有名なグライダーのように、興味深い動作を伴うパターンを見つけることを目的としたゲームです。

グライダー

ゼロプレイヤーゲーム...今日まで。ゲームオブライフをプレイし、勝つためにプレイするキングオブザヒルスタイルのプログラムを作成します。対戦相手(単数形)はもちろん同じことを試みます。勝者は、生きているセルがある最後のボットか、10000世代後に最も生きているセルを持つプレイヤーのいずれかです。

ゲームのルール

ルールは通常の(B3 / S23)ライフとほぼ同じです。

  • 友好的な隣人が2人未満の生細胞は、飢fromで死にます。
  • 2〜3人の友好的な隣人がいる生細胞は生き残ります。
  • 3人以上の友好的な隣人がいる生細胞は、過密により死にます。
  • 同じプレイヤーの正確に3人の隣人がいる死んだ細胞は、敵の隣人がいなければ、そのプレイヤーのために戦うために生きてきます。

...しかし、各世代の後、あなたとあなたの対戦相手の両方が介入する機会を得ます。あなたはあなたのために戦うために最大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勝が加算されます

コントローラーを自分で実行する

コントローラのソースはここにあります。コントローラーを実行するには2つの方法があります。

  • 競争モード(端末)
    • でセットアップ python3 get_answers.py
    • 各ボットが他のすべてに対してボットする、すべて対すべての競争を実行します。
  • テストモード(GUI)
    • 走る python3 nice_gui.py
    • クリック Pull Answers
    • 投稿する前に独自の回答を追加して試してみたい場合File -> Add manual answerは、ファイルをクリックして検索し、書かれている言語を選択します。
    • あなたの言語が存在しない場合、pingを実行し、サーバーにインストールしようとします(インストールと実行の手順も素晴らしいでしょう!)
    • 2つのボットを選択して、互いに対戦します
    • クリック Run
    • ゲームを見る...
  • 設置
    • python3が必要
    • get_answersにはbs4とhtml5libが必要です
    • コントローラーには、.shファイル(Windows上のMinGW)を実行する方法が必要です

アプリの画像例

得点

12/07/2016(7月12日) 14/07/2016(7月14日、ボットの実行方法がわからなかったから最も多く勝ったボットが勝ちました。


このチャットルームでコントローラー/ GUIのサポートを依頼できます。


この質問は2014年から開発中であり、サンドボックスで最も支持された質問でした。特別な感謝はして行くナウターワンダ(原作者とのコンセプト)、PPCGチャットにコメント(コメントやヘルプ)と誰サンドボックスポスト(もっとコメント)。


25
ええと、これはサンドボックスから出ることはないだろうと思いました。すばらしいです!
ルイスメンドー

タイプミス:2016
ルイスメンドー

4
+1。この素晴らしい質問をサンドボックスから引き出したことで、AED賞に値します!
-agtoever

1
@ KevinLau-notKennyああ、大丈夫。ファイルでコマンドを実行できますか?
Rɪᴋᴇʀ

1
@Magenta私は(私は完全にそれが常に開いているタブにされていていても、このことについて忘れて)、私は今それを実行しているそれらを取得する場合
ブルー

回答:


4

Python 3、Exploder

既にブロックが存在するかどうかに関係なく、小さな爆発物をその場所の周りに配置します。

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ブロック作成スイッチマシンを作成しようとします。次に、残りのアクティベーションを使用して、敵のポイントを見つけ、細胞の成長を妨げ、パターンを台無しにすることを妨害するために、セルで近くのエリアをペッパーにしようとします。あなたの細胞は次世代で死ぬでしょうが、おそらく彼らはあなたの対戦相手を遅くするためにいくらかの成長を止めました!

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文字列を解析できないためにクラッシュすることを意味します。これは、OSの問題ですので、私は、私は〜私のボットをテストするために、Linuxのクラウドボックスまたは何かに見ている必要があり推測
バリューインク

@muddyfishコマンドラインの制限のためにWindowsに問題があることは既に述べましたが、その最後のエラーは表面上はLinuxボックスであるCloud9にありました。私のボットはあなたのLinuxボックスでどのように動きますか(あなたが持っていることを暗示しているので)?
バリューインク

私はそれをコミットしていませんでしたが、数字はbot_score各ボットが他のボットに対してどれだけ勝ったかを示しています
ブルー

了解、ありがとう!残念ながら、Cloud9には実際にはGUIがなく、Windowsは最終的にコマンドの制限を壊さずにシミュレーションを実行できませんが、少なくともボットが互いにどのように機能するかについて簡単に見てきました。彼らはお互いを攻撃し、文字の制限を破るために十分な成長を防止し続けるのでまた、私はそれが時折時間をんが...、最後に自分自身に対する私のボットの戦いを見るためにいくつかの時間を取得
バリューインク

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

トロールボットはそれについて考え、彼は敵を気にかけないことに気付きます。実際、彼はこれらの工場をスパムして、マップ全体にランダムにさらに多くの仲間を生み出しています。しばらくして、彼は、追加のセルは塊で使用するのが最適であることに気付きました。これらの4つのセルのブロックは互いにくっつき、グライダーをトラックに止めます!彼はただ戦うとは思わない。また、彼は冗長オブジェクト指向プログラミングの大きな支持者でもあります。トロールは、座標が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 Orthogonal s、および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行目が出力を台無しにしているためです(シミュレータは、起動したい座標の文字列のみを想定しています)。また、プログラムの最後の行には閉じ括弧がありません。
バリューインク

@ KevinLau-notKenny GUIはトレーニングボットとRubyボットでも失敗していました。ただし、その行を削除し、閉じ括弧に追加し直しました(後者はコピーアンドペーストエラーだと思います)。
スティーブンH.

現在使用しているオペレーティングシステム、および実行時にコマンドラインに表示されるエラー 現在のところ、Windowsが正常にため、彼らは周りの8000のコマンドライン文字制限を超えたときに切り捨てられているコマンドラインから渡される引数のシムを実行することはできません既知のバグです
バリューインク

@ KevinLau-notKenny私はWindows 10を使用していますが、よくわかりました...多くのエラーが発生しました。BeautifulSoupは最初に見つけたくhtml5libない、すべてのボットを含むフォルダを見つけられなかった(これらの両方のコードを変更する必要がありました)、それ以来、いずれかのPythonボットの実行は0以外のリターンコードになりました1.
スティーブンH.

画面上にアクティブなセルが多すぎると、Windowsはまだコードを実行できません...しかし、他のエラーについては、TrainingBotがPython 2を必要としている可能性がありますか?
バリューインク

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

どこにでも正方形を置く-多分

四角はLifeの静的オブジェクトであり、移動しません。そのため、その場所の周りに十分な不活性オブジェクトを配置すると、他の人が作成するグライダーと爆発がブロックされるか、少なくとも減衰されます。

-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)

テストに問題がありますが



私は、このボットは、実際にそれが意味何やるんことを確認することができます-そしてそれは私が、コントローラのバグを見つけて修正助け
ブルー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.