Ini Hidup, Jim, tapi tidak seperti yang kita tahu


58

Anda mungkin tahu Permainan Kehidupan Conway , robot seluler terkenal yang ditemukan oleh ahli matematika John Conway. Hidup adalah seperangkat aturan yang, bersama-sama, memungkinkan Anda untuk mensimulasikan papan sel dua dimensi. Aturan memutuskan sel mana di papan hidup dan mana yang mati. Dengan beberapa imajinasi, Anda dapat mengatakan bahwa Life adalah game tanpa pemain: permainan dengan tujuan untuk menemukan pola dengan perilaku yang menarik, seperti peluncur yang terkenal.

Pesawat peluncur

Gim nol pemain ... Hingga hari ini. Anda harus menulis sebuah program yang memainkan Game of Life - dan memainkannya untuk menang, gaya King of the Hill. Lawan Anda (tunggal) tentu saja mencoba melakukan hal yang sama. Pemenangnya adalah bot terakhir dengan sel hidup apa pun, atau pemain dengan sel terbanyak setelah 10.000 generasi.

Aturan gim

Aturannya hampir sama dengan kehidupan normal (B3 / S23):

  • Sel hidup dengan kurang dari dua tetangga yang ramah mati karena kelaparan.
  • Sel hidup dengan dua atau tiga tetangga yang ramah selamat.
  • Sel hidup dengan lebih dari tiga tetangga yang ramah mati karena kelebihan populasi.
  • Sel mati dengan tepat tiga tetangga dari pemain yang sama menjadi hidup untuk bertarung demi pemain itu asalkan tidak ada tetangga musuh .

... tetapi setelah setiap generasi, baik Anda dan lawan Anda mendapatkan kesempatan untuk campur tangan. Anda dapat bangun hingga maksimal 30 sel untuk memperjuangkan Anda. (Siapa yang duluan diputuskan oleh server.)

Papan adalah sel (x, y) sel. Semua kotak awalnya mati. Perbatasan tidak membungkus (ini bukan dunia yang berbentuk torus) dan mati secara permanen.

Ini adalah kontes dalam semangat Battlebots dan Core Wars . Ada server pusat yang akan menjalankan bot dan dapat ditemukan di sini

Protokol

Server arena berbicara protokol JSON sederhana yang dikomunikasikan melalui argv

Di mana Nilai adalah string yang dikodekan JSON

  • y_size: maksimum y tegel ubin sebelum hilang
  • x_size: maksimum x coords ubin sebelum hilang
  • tick_id: nomor centang saat ini
  • board: kamus dengan kunci dalam formulir '(y, x)' dan nilai-nilai dalam bentuk bot_id(int)
  • bot_id: ubin di papan dengan id ini adalah milikmu

Contoh:

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

Memberitahu server pilihan Anda:

  • Kirim server daftar ubin untuk beralih ke warna Anda.
  • Hanya yang kosong yang akan diubah
  • Format daftar koordinat bersarang
    • [[0,0], [0,1], [100,22]...]

CATATAN: Bot Anda tidak perlu memperbarui ubin sama sekali - server melakukan pembaruan itu sendiri

Aturan persaingan

  • Jika implementasi Anda gagal mengikuti protokol, gilirannya itu akan hangus; Server akan menganggap tidak ada perubahan dalam status
  • Anda tidak diizinkan mengambil keuntungan dari kesalahan di server arena.
  • Mintalah AI Anda memutuskan untuk bergerak dalam waktu yang waras. Silakan kirim langkah Anda berikutnya secepat mungkin.
  • Akhirnya, mohon bersikap baik pada server. Itu ada untuk kesenangan Anda.
  • Tidak mengikuti aturan-aturan ini dapat menyebabkan diskualifikasi.
  • Dalam hal seri, kedua pemain memiliki 1 kemenangan ditambahkan ke total mereka

Menjalankan pengontrol sendiri

Sumber untuk pengontrol dapat ditemukan di sini . Ada 2 cara menjalankan pengontrol:

  • Mode kompetisi (terminal)
    • Setup dengan python3 get_answers.py
    • Jalankan semua kompetisi semua dengan bot masing-masing mengadu domba satu sama lain.
  • Mode pengujian (GUI)
    • Lari python3 nice_gui.py
    • Klik Pull Answers
    • Jika Anda ingin menambahkan jawaban Anda sendiri untuk mencobanya sebelum memposting, klik File -> Add manual answerdan temukan file dan pilih bahasa yang digunakan untuk menuliskannya.
    • Jika bahasa Anda tidak hadir, ping saya dan saya akan mencoba untuk menginstalnya di server saya akan menjalankannya (instalasi dan menjalankan instruksi juga akan bagus!)
    • Pilih 2 bot untuk diadu satu sama lain
    • Klik Run
    • Tonton pertandingan ...
  • Instalasi
    • Membutuhkan python3
    • get_answers membutuhkan bs4 dan html5lib
    • controller memerlukan cara menjalankan file .sh (MinGW di windows)

Contoh gambar aplikasi

Mencetak gol

Bot dengan kemenangan terbanyak mulai dari 12/07/2016(12 Juli) 14/07/2016 (14 Juli, tidak bisa mengetahui cara menjalankan bot) menang.


Bantuan dengan controller / gui dapat ditanyakan di ruang obrolan ini


Pertanyaan ini telah dikembangkan sejak 2014 dan merupakan pertanyaan yang paling banyak dipilih di kotak pasir. Terima kasih khusus kepada Wander Nauta (penulis asli dan konsep), Obrolan PPCG (komentar dan bantuan) dan siapa saja yang berkomentar di posting sandbox (lebih banyak komentar).


25
Huh, saya pikir ini tidak akan pernah bisa keluar dari kotak pasir. Bagus!
Luis Mendo

Typo: 12/06/2016 (12 Juli)
Luis Mendo

4
+1. Anda layak mendapatkan penghargaan AED karena telah mengajukan pertanyaan hebat ini dari kotak pasir!
agtoever

1
@ KevinLau-notKenny oh, oke. Bisakah Anda menjalankan perintah dalam file?
Rɪᴋᴇʀ

1
@ Magenta Ketika saya mendapatkannya (saya benar-benar lupa tentang ini meskipun sudah berada di tab yang selalu terbuka), saya menjalankannya sekarang
Biru

Jawaban:


4

Python 3, Exploder

Letakkan peledak kecil di sekitar tempat itu, tanpa memperhatikan apakah sudah ada blok di sana.

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
Saya tidak dapat percaya bahwa setelah semua pekerjaan saya mengatur sakelar pembuatan blok untuk pertumbuhan yang tidak terbatas dan sistem yang secara khusus dibangun untuk menghancurkan struktur pertumbuhan, sebuah sistem sederhana berbasis exploder berhasil menambang dalam pertempuran: o
Value Ink

Saya tidak tahu bagaimana caranya, karena saya tidak dapat menjalankan controller untuk alasan apa pun.
Magenta

8

Ruby, InterruptingBlockMaker

Alih-alih menginisialisasi glider seperti TrainingBot, ia mencoba untuk membuat mesin saklar blok 5x5 seperti yang disebutkan di Wikipedia pada titik acak di labirin. Kemudian, dengan aktivasi yang tersisa, itu hanya menemukan titik musuh dan mencoba untuk membumbui area terdekat dengan sel-sel Anda dalam upaya untuk mengganggu mereka dari tumbuh dan mungkin mengacaukan pola mereka. Sel-sel Anda akan mati pada generasi berikutnya, tetapi mungkin mereka juga menghentikan pertumbuhan untuk memperlambat lawan Anda!

v2: Dioptimalkan sedikit (?) untuk mencoba meminimalkan waktu habis.

v3: Dioptimalkan kode gangguan untuk pra-sampel sekelompok blok aktif sebelum menolak lokasi sel kita sendiri, untuk mencegah timeout lebih lanjut dengan biaya beberapa efektivitas dalam serangan sel interupsi.

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 terima kasih, sudah memperbaikinya! Sekarang satu-satunya masalah adalah bahwa perintah baris perintah Windows memiliki batas hardcoded 8191, yang berarti bahwa pada titik tertentu dalam simulasi bot akan crash karena tidak dapat mengurai string JSON terpotong. Ini masalah OS, jadi saya rasa saya harus melihat ke kotak cloud Linux atau sesuatu untuk menguji bot saya ~
Value Ink

@muddyfish Saya sudah menyebutkan bahwa Windows memiliki masalah karena batas baris perintah, kesalahan terakhir adalah pada Cloud9 yang seolah-olah kotak Linux. Bagaimana tarif bot saya di kotak Linux Anda (karena Anda tersirat memilikinya)?
Value Ink

Ternyata saya tidak melakukan itu tetapi angka-angka dalam bot_scoremenunjukkan berapa banyak kemenangan masing-masing bot terhadap bot lainnya
Biru

Baiklah terima kasih! Sayangnya, Cloud9 memang tidak memiliki GUI dan Windows masih tidak dapat menjalankan simulasi tanpa melanggar batas perintahnya pada akhirnya, tapi setidaknya saya mendapatkan pandangan singkat tentang bagaimana tarif bot terhadap satu sama lain. Juga, saya bisa melihat bot saya bertarung melawan dirinya sendiri sampai akhir beberapa kali karena mereka terus menyerang satu sama lain dan mencegah pertumbuhan yang cukup untuk menembus batas karakter, meskipun kadang-kadang waktu habis ...
Value Ink

4

Python 2, TrainingBot

Karena semua orang membutuhkan ini!

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

Troll Bot telah memikirkannya, dan dia menyadari bahwa dia TIDAK peduli dengan musuh. Bahkan dia hanya membohongi pabrik-pabrik ini untuk menghasilkan lebih banyak anak buahnya secara acak di seluruh peta. Setelah beberapa saat ia menyadari bahwa sel tambahan apa pun paling baik digunakan dalam rumpun. Blok empat sel ini akan bersatu dan menghentikan glider di jalurnya! Dia tidak berpikir dia hanya berkelahi. Juga dia adalah pendukung besar pemrograman berorientasi objek verbose. Troll itu juga berasumsi bahwa coords berada dalam format y, x, dan dia meminta untuk diuji. Masukkan saja dia ke dalam file bernama "TrollBot.java", dan dia akan siap!

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

Bot ini kesulitan membuat keputusan yang cerdas, tetapi setidaknya tahu untuk tidak mencoba menempatkan hal-hal di atas hal-hal lain. Itu akan secara acak membuat glider, kapal, C / 2 Orthagonal , dan blok 2x2 dengan berbagai orientasi, memastikan bahwa ketika mereka ditempatkan mereka tidak tumpang tindih dengan sesuatu yang lain, sekutu atau musuh.

Bot ini tidak diuji, karena saya menerima semua jenis kesalahan ketika saya mencoba menjalankan GUI. Juga, saya menggunakan TrainingBot sebagai basis dan hanya mengedit, jadi ada kesamaan dalam kode mungkin karena itu.

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 kemungkinan besar gagal karena print(sys.argv[1])jalur 3 Anda, yang mengacaukan output (simulator hanya mengharapkan deretan koordinat yang ingin Anda bangun). Juga, baris terakhir program Anda tidak memiliki paren penutup.
Value Ink

@ KevinLau-notKenny GUI gagal pada bot pelatihan dan bot Ruby juga. Saya menghapus baris itu, dan menambahkan kembali pada paren penutup (saya pikir yang terakhir adalah kesalahan copy-paste).
Steven H.

Sistem operasi apa yang Anda gunakan, dan kesalahan apa yang muncul di baris perintah saat Anda menjalankannya? Saat ini merupakan bug yang diketahui bahwa Windows tidak dapat menjalankan sim dengan benar karena argumen yang dilewatkan melalui baris perintah terpotong ketika mereka melebihi batas karakter baris perintah sekitar 8000.
Nilai Tinta

@ KevinLau-notKenny Saya menggunakan Windows 10, dan saya mendapatkan ... yah, banyak kesalahan. Hal pertama adalah BeautifulSoup tidak ingin menemukan html5lib, kemudian tidak menemukan folder yang berisi semua bot (saya harus mengubah kode untuk kedua hal ini), dan sejak saat itu pengoperasian kedua bot Python telah menghasilkan kode pengembalian non-0 1.
Steven H.

Windows masih tidak dapat menjalankan kode jika ada terlalu banyak sel aktif di layar ... Tetapi untuk kesalahan Anda yang lain, mungkin karena TrainingBot menginginkan Python 2?
Value Ink

3

Python, GuyWithAGun

Dia seorang pria, dia punya pistol; dia marah. Dia hanya melemparkan senjata glider ke mana-mana tanpa memperhatikan apa yang dilakukan orang lain

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

Menempatkan kotak di mana-mana - mungkin

Kotak adalah objek statis di Life - mereka tidak bergerak. Jadi jika saya menempatkan cukup objek lembam di sekitar tempat itu, glider dan ledakan yang dibuat orang lain mungkin akan diblokir, atau setidaknya dibasahi.

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

Meskipun saya mengalami kesulitan mengujinya



Saya dapat mengonfirmasi bahwa bot ini memang melakukan apa yang dimaksudkan - dan itu membantu saya menemukan dan memperbaiki bug di controller
Biru
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.