Đó là cuộc sống, Jim, nhưng không như chúng ta biết


58

Bạn có thể biết Trò chơi cuộc sống của Conway , máy tự động di động nổi tiếng được phát minh bởi nhà toán học John Conway. Cuộc sống là một tập hợp các quy tắc, cùng nhau, cho phép bạn mô phỏng một bảng tế bào hai chiều. Các quy tắc quyết định các tế bào trên bảng sống và những tế bào nào chết. Với một số trí tưởng tượng, bạn có thể nói rằng Life là một trò chơi không có người chơi: một trò chơi với mục tiêu tìm ra các mô hình với hành vi thú vị, giống như tàu lượn nổi tiếng.

Tàu lượn

Một trò chơi không có người chơi ... Cho đến hôm nay. Bạn phải viết một chương trình chơi Trò chơi cuộc sống - và chơi nó để giành chiến thắng, theo phong cách Vua của Đồi. Đối thủ của bạn (số ít) tất nhiên cố gắng làm điều tương tự. Người chiến thắng là bot cuối cùng với bất kỳ ô sống nào hoặc người chơi có nhiều ô sống nhất sau 10000 thế hệ.

Luật chơi

Các quy tắc gần giống như Cuộc sống bình thường (B3 / S23):

  • Một tế bào sống có ít hơn hai người hàng xóm thân thiện chết vì đói.
  • Một tế bào sống với hai hoặc ba người hàng xóm thân thiện sống sót.
  • Một tế bào sống với hơn ba người hàng xóm thân thiện chết vì quá đông dân.
  • Một tế bào chết với chính xác ba người hàng xóm của cùng một người chơi trở nên sống động để chiến đấu cho người chơi đó với điều kiện không có hàng xóm của kẻ thù .

... nhưng sau mỗi thế hệ, cả bạn và đối thủ đều có cơ hội can thiệp. Bạn có thể thức tối đa 30 ô để chiến đấu cho bạn. (Ai đi trước được quyết định bởi máy chủ.)

Bảng là một ô vuông (x, y). Tất cả các hình vuông ban đầu đã chết. Các biên giới không bao quanh (đây không phải là một thế giới hình xuyến) và đã chết vĩnh viễn.

Đây là một cuộc thi theo tinh thần của BattlebotsCore Wars . Có một máy chủ trung tâm sẽ chạy bot và nó có thể được tìm thấy ở đây

Giao thức

Máy chủ đấu trường nói một giao thức JSON đơn giản được truyền đạt thông qua argv

Trong đó Giá trị là một chuỗi được mã hóa JSON

  • y_size: các chuỗi y tối đa của gạch trước khi chúng biến mất
  • x_size: x x tối đa của gạch trước khi chúng biến mất
  • tick_id: số đánh dấu hiện tại
  • board: một từ điển với các khóa ở dạng '(y, x)' và các giá trị ở dạng bot_id(int)
  • bot_id: gạch trong bảng với id này là của bạn

Thí dụ:

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

Nói với máy chủ sự lựa chọn của bạn:

  • Gửi cho máy chủ một danh sách các ô để chuyển sang màu của bạn.
  • Chỉ những người trống sẽ được thay đổi
  • Định dạng danh sách coords lồng nhau
    • [[0,0], [0,1], [100,22]...]

LƯU Ý: Bot của bạn hoàn toàn không phải cập nhật các ô - máy chủ tự cập nhật

Thể lệ cuộc thi

  • Nếu việc triển khai của bạn không tuân theo giao thức, đến lượt nó sẽ bị hủy bỏ; Máy chủ sẽ cho rằng không có thay đổi về trạng thái
  • Bạn không được phép cố tình lợi dụng lỗi trong máy chủ đấu trường.
  • Có AI của bạn quyết định di chuyển trong một thời gian lành mạnh. Vui lòng gửi bước tiếp theo của bạn nhanh nhất có thể.
  • Cuối cùng, xin vui lòng đến máy chủ. Đó là để bạn tận hưởng.
  • Không tuân theo các quy tắc này có thể dẫn đến việc không đủ tiêu chuẩn.
  • Trong trường hợp hòa, cả hai người chơi có 1 chiến thắng được thêm vào tổng số của họ

Tự chạy bộ điều khiển

Nguồn cho bộ điều khiển có thể được tìm thấy ở đây . Có 2 cách để chạy bộ điều khiển:

  • Chế độ thi đấu (thiết bị đầu cuối)
    • Thiết lập với python3 get_answers.py
    • Chạy tất cả các v cạnh tranh với mỗi bot đọ sức với nhau.
  • Chế độ kiểm tra (GUI)
    • Chạy python3 nice_gui.py
    • Nhấp chuột Pull Answers
    • Nếu bạn muốn thêm câu trả lời của riêng mình để thử trước khi đăng, hãy nhấp File -> Add manual answervà tìm tệp và chọn ngôn ngữ được viết.
    • Nếu ngôn ngữ của bạn không xuất hiện ping tôi và tôi sẽ cố gắng cài đặt nó trên máy chủ, tôi sẽ chạy nó (hướng dẫn cài đặt và chạy cũng sẽ rất tuyệt!)
    • Chọn 2 bot để đối đầu với nhau
    • Nhấp chuột Run
    • Xem trò chơi ...
  • Cài đặt
    • Yêu cầu python3
    • get_answers yêu cầu bs4 và html5lib
    • bộ điều khiển yêu cầu cách chạy các tệp .sh (MinGW trên windows)

Hình ảnh ví dụ của ứng dụng

Chấm điểm

Bot có nhiều chiến thắng nhất bắt đầu từ 12/07/2016(ngày 12 tháng 7) 14/07/2016 (ngày 14 tháng 7, không thể tìm ra cách chạy bot) sẽ giành chiến thắng.


Có thể yêu cầu trợ giúp với bộ điều khiển / gui trong phòng chat này


Câu hỏi này đã được phát triển từ năm 2014 và là câu hỏi được đánh giá cao nhất trong hộp cát. Cảm ơn đặc biệt đến Wander Nauta (tác giả và khái niệm ban đầu), Trò chuyện PPCG (bình luận và trợ giúp) và bất kỳ ai đã bình luận trong bài đăng trên hộp cát (thêm bình luận).


25
Huh, tôi nghĩ rằng điều này sẽ không bao giờ làm cho nó ra khỏi hộp cát. Tuyệt quá!
Luis Mendo

Typo: 12/06/2016 (ngày 12 tháng 7)
Luis Mendo

4
+1. Bạn xứng đáng nhận giải thưởng AED vì đã đưa câu hỏi tuyệt vời này ra khỏi hộp cát!
bất cứ lúc nào

1
@ KevinLau-notKenny ồ, được thôi. Bạn có thể chạy một lệnh trong một tập tin?
Rɪᴋᴇʀ

1
@Magenta Khi tôi nhận được chúng (Tôi hoàn toàn quên mất điều này mặc dù nó đã ở trong một tab liên tục mở), tôi đang chạy nó ngay bây giờ
Blue

Câu trả lời:


4

Python 3, Trình giải thích

Đặt các nhà thám hiểm nhỏ xung quanh nơi này, không liên quan đến việc đã có một khối ở đó chưa.

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
Tôi không thể tin rằng sau tất cả công việc của mình là thiết lập các công tắc tạo khối để tăng trưởng vô thời hạn và một hệ thống được xây dựng đặc biệt để phá hủy các cấu trúc tăng trưởng, một hệ thống dựa trên trình thám hiểm đơn giản đã khai thác tốt nhất trong chiến đấu: o
Value Ink

Tôi cũng không biết nó hoạt động thế nào, vì tôi không thể chạy bộ điều khiển vì bất kỳ lý do gì.
Magenta

8

Ruby, InterruptingBlockMaker

Thay vì khởi tạo các tàu lượn như TrainingBot, nó cố gắng tạo ra một máy chuyển đổi chế tạo khối 5x5 như được đề cập trên Wikipedia tại một điểm ngẫu nhiên trong mê cung. Sau đó, với các kích hoạt còn lại của nó, nó chỉ tìm thấy các điểm của kẻ thù và cố gắng tiêu diệt khu vực gần đó bằng các tế bào của bạn để ngăn chúng phát triển và có thể làm rối tung mô hình của chúng. Các tế bào của bạn sẽ chết trong thế hệ tiếp theo, nhưng có lẽ chúng cũng ngừng một số tăng trưởng để làm chậm đối thủ của bạn!

v2: Tối ưu hóa một chút (?) để cố gắng giảm thiểu thời gian chờ.

v3: Mã gián đoạn được tối ưu hóa để lấy mẫu trước một tập hợp con của các khối hoạt động trước khi từ chối vị trí ô của chúng ta, để ngăn chặn thời gian chờ thêm với chi phí hiệu quả trong các cuộc tấn công tế bào bị gián đoạn.

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 cảm ơn, đã sửa nó! Bây giờ vấn đề duy nhất là các lệnh dòng lệnh Windows có giới hạn mã hóa là 8191, điều đó có nghĩa là tại một thời điểm nhất định trong mô phỏng, các bot sẽ gặp sự cố do không thể phân tích chuỗi JSON bị cắt. Đó là một sự cố hệ điều hành, vì vậy tôi đoán rằng tôi phải xem xét một hộp đám mây Linux hoặc thứ gì đó để kiểm tra bot của mình ~
Value Ink

@muddyfish Tôi đã đề cập rằng Windows có vấn đề do giới hạn dòng lệnh, lỗi cuối cùng là trên Cloud9, có vẻ như là một hộp Linux. Làm thế nào để bot của tôi giá trên hộp Linux của bạn (vì bạn ngụ ý rằng bạn đã có một cái)?
Mực giá trị

Hóa ra tôi đã không cam kết nhưng các con số bot_scorecho thấy mỗi bot có bao nhiêu chiến thắng trước các bot khác
Blue

Được rồi, cảm ơn! Thật không may, Cloud9 thực sự không có GUI và Windows vẫn không thể chạy mô phỏng mà không phá vỡ giới hạn lệnh của nó, nhưng ít nhất tôi đã có một cái nhìn ngắn gọn về cách các bot đối đầu với nhau. Ngoài ra, tôi có thể thấy bot của mình chiến đấu chống lại nó đến cùng một lúc vì chúng liên tục tấn công lẫn nhau và ngăn cản sự phát triển đủ để phá vỡ giới hạn nhân vật, mặc dù thỉnh thoảng hết giờ ...
Value Ink

4

Python 2, TrainingBot

Bởi vì ai cũng cần một trong những thứ này!

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 đã nghĩ về điều đó, và anh nhận ra mình KHÔNG quan tâm đến kẻ thù. Trên thực tế, anh ta chỉ spam các nhà máy này để sản xuất thêm nhiều kẻ của mình một cách ngẫu nhiên trên khắp bản đồ. Sau một thời gian, anh nhận ra rằng bất kỳ tế bào bổ sung nào được sử dụng tốt nhất trong các cụm. Những khối bốn ô này sẽ dính vào nhau và dừng tàu lượn trong đường ray của chúng! Anh ta không nghĩ rằng anh ta chỉ chiến đấu. Ngoài ra, ông là một người ủng hộ lớn của lập trình hướng đối tượng dài dòng. Troll cũng cho rằng các coords có định dạng y, x và anh ta yêu cầu được kiểm tra. Chỉ cần đặt anh ta vào một tệp có tên "TrollBot.java", và anh ta sẽ được thiết lập!

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 này gặp khó khăn khi đưa ra quyết định thông minh, nhưng ít nhất nó cũng không biết cố gắng đặt mọi thứ lên trên những thứ khác. Nó sẽ tạo ngẫu nhiên các tàu lượn, thuyền, C / 2 hình khối và các khối 2x2 với nhiều hướng khác nhau, đảm bảo rằng khi chúng được đặt, chúng không bị chồng chéo với thứ gì khác, đồng minh hoặc kẻ thù.

Bot này chưa được kiểm tra, vì tôi nhận được tất cả các loại lỗi khi tôi cố chạy GUI. Ngoài ra, tôi đã sử dụng TrainingBot làm cơ sở và chỉ chỉnh sửa, vì vậy bất kỳ sự tương đồng nào trong mã có lẽ là do điều đó.

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 rất có thể không thành công do print(sys.argv[1])dòng 3 của bạn làm rối đầu ra (trình giả lập chỉ mong đợi chuỗi tọa độ bạn muốn đánh thức). Ngoài ra, dòng cuối cùng của chương trình của bạn đang thiếu một paren đóng.
Mực giá trị

@ KevinLau-notKenny GUI cũng bị lỗi trên bot đào tạo và bot Ruby. Mặc dù vậy, tôi đã xóa dòng đó và thêm lại vào phần đóng (tôi nghĩ rằng cái sau là lỗi sao chép-dán).
Steven H.

Bạn đang sử dụng hệ điều hành nào và lỗi nào xuất hiện trong dòng lệnh khi bạn chạy nó? Hiện tại, đó là một lỗi đã biết rằng Windows không thể chạy sim một cách chính xác do các đối số được truyền qua dòng lệnh bị cắt bớt khi chúng vượt quá giới hạn ký tự dòng lệnh khoảng 8000.
Giá trị Ink

@ KevinLau-notKenny Tôi đang sử dụng Windows 10 và tôi đã nhận được ... rất nhiều lỗi. Điều đầu tiên là BeautifulSoup không muốn tìm html5lib, sau đó không tìm thấy thư mục chứa tất cả các bot (tôi phải thay đổi mã cho cả hai), và từ đó việc chạy bot Python đã dẫn đến mã trả về không 0 1.
Steven H.

Windows vẫn không thể chạy mã nếu có quá nhiều ô đang hoạt động trên màn hình ... Nhưng đối với các lỗi khác của bạn, có thể là do TrainingBot muốn Python 2?
Mực giá trị

3

Con trăn, GuyWithAGun

Anh ta là một chàng trai, anh ta có một khẩu súng; cậu ây bị điên. Anh ta chỉ vứt súng lượn khắp mọi nơi mà không quan tâm đến những gì người khác đang làm

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

Đặt hình vuông ở khắp mọi nơi- có thể

Hình vuông là đối tượng tĩnh trong Cuộc sống- chúng không di chuyển. Vì vậy, nếu tôi đặt đủ các vật thể trơ xung quanh nơi đó, các tàu lượn và vụ nổ mà người khác tạo ra sẽ có thể bị chặn, hoặc ít nhất là bị ẩm.

-Được chấp nhận từ 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)

Mặc dù tôi gặp khó khăn khi thử nghiệm nó



Tôi có thể xác nhận rằng bot này thực tế làm theo ý nghĩa của nó - và nó đã giúp tôi tìm và sửa một lỗi trong bộ điều khiển
Blue
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.