인생이야, 짐


58

수학자 John Conway가 발명 한 유명한 셀룰러 오토 마톤 인 Conway의 Game of Life를 알고있을 것입니다 . Life 는 함께 2 차원 셀 보드를 시뮬레이션 할 수있는 일련의 규칙입니다. 규칙은 보드의 어떤 셀이 살고 어떤 셀이 죽는 지 결정합니다. 약간의 상상력으로 Life 는 제로 플레이어 게임 이라고 할 수 있습니다. 유명한 글라이더와 같이 재미있는 행동을하는 패턴을 찾는 것을 목표로하는 게임입니다.

글라이더

제로 플레이어 게임 ... 오늘까지. 당신은 인생의 게임을하고 언덕 스타일의 왕으로 승리하는 프로그램을 작성해야합니다. 상대방 (단수)은 물론 똑같이하려고합니다. 우승자는 모든 라이브 셀을 보유한 마지막 봇이거나 10000 세대 후 가장 많은 라이브 셀을 보유한 플레이어입니다.

게임 규칙

규칙은 일반 (B3 / S23) 수명 과 거의 동일합니다.

  • 친근한 이웃이 2 명 미만인 살아있는 세포는 기아로 사망합니다.
  • 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 승을 거두게됩니다

컨트롤러를 직접 실행

컨트롤러의 소스는 여기 에서 찾을 수 있습니다 . 컨트롤러를 실행하는 방법은 두 가지가 있습니다 :

  • 경쟁 모드 (터미널)
    • 설정 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 년 이후 개발되어 왔으며 샌드 박스에서 가장 많이 제기 된 질문입니다. 특별 감사는 Wander Nauta (원저 작성자 및 개념), PPCG Chat (설명 및 도움말) 및 샌드 박스 게시물에 댓글을 남긴 사람 (추가 의견)에게 전달됩니다.


25
허, 나는 이것이 결코 샌드 박스에서 나오지 않을 것이라고 생각했다. 큰!
Luis Mendo 2016 년

오타 : 2016
Luis Mendo

4
+1. 샌드 박스에서이 위대한 질문을 가져 오면 AED 상을받을 자격이 있습니다!
agtoever

1
@ KevinLau-notKenny 아, 알았어. 파일에서 명령을 실행할 수 있습니까?
Rɪᴋᴇʀ

1
@Magenta 나는 (나는 완전히이 지속적으로 개방 탭에있었습니다에도 불구하고 이것에 대해 잊었다), 지금 그것을 실행하는거야 그들을 얻을 때
블루

답변:


4

파이썬 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

어떤 이유로 컨트롤러를 실행할 수 없기 때문에 어떻게 작동하는지 모르겠습니다.
Magenta

8

루비, 끼어 들기

TrainingBot과 같은 글라이더를 초기화하는 대신 Wikipedia언급 된 대로 미로의 임의 지점에서 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 클라우드 박스 나 무언가를 살펴 봐야 할 것 같아요
Value Ink

@muddyfish 이미 명령 줄 제한으로 인해 Windows에 문제가 있으며 마지막 오류는 Linux9 인 Cloud9에서 발생했습니다. Linux 박스에서 내 봇 요금은 어떻게됩니까?
Value Ink

내가 그것을 저지른 것은 아니지만 숫자는 bot_score각 봇이 다른 봇에 대해 얼마나 많은 승리를했는지 를 보여줍니다.
Blue

알았어, 고마워! 불행히도 Cloud9에는 실제로 GUI가 없으며 Windows는 결국 명령 제한을 위반하지 않고 시뮬레이션을 실행할 수 없지만 적어도 봇이 서로 어떻게 대응하는지 간략히 살펴 보았습니다. 또한, 가끔 시간이 초과 되기는하지만 서로를 공격하고 캐릭터 제한을 깨뜨리기에 충분한 성장을 방해하기 때문에 봇이 끝까지 싸우는 것을 보게됩니다.
Value Ink

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

자바, 트롤 봇

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

파이썬 3, 랜덤 봇

이 봇은 현명한 결정을 내리는 데 어려움을 겪지 만 적어도 다른 것들 위에 물건을 올리려고 시도하지는 않습니다. 다양한 방향으로 글라이더, 보트, C / 2 Orthagonal 및 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을 엉망으로 만드는 온라인 3 때문에 실패 할 가능성이 높습니다 (시뮬레이터는 깨우려는 좌표 열만 예상합니다). 또한 프로그램의 마지막 줄에는 닫는 패러가 없습니다.
Value Ink

@ KevinLau-notKenny GUI는 교육 봇과 루비 봇에서도 실패했습니다. 그래도 그 줄을 제거하고 닫는 괄호에 다시 추가했습니다 (후자는 복사 붙여 넣기 오류라고 생각합니다).
Steven H.

어떤 운영 체제를 사용하고 있으며 실행할 때 명령 줄에 어떤 오류가 표시됩니까? 현재 명령 줄 문자 제한이 약 8000자를 초과하면 명령 줄을 통해 전달 된 인수가 잘려서 Windows가 시뮬레이션을 제대로 실행할 수없는 것으로 알려진 버그입니다.
Value Ink

@ KevinLau-notKenny Windows 10을 사용하고 있으며 많은 오류가 발생했습니다. 첫 번째 것은 BeautifulSoup이 찾기를 원하지 html5lib않았고 모든 봇이 들어있는 폴더를 찾지 못했습니다 (둘 다 코드를 변경해야 함). 그 후 파이썬 봇을 실행하면 0이 아닌 리턴 코드가 발생했습니다. 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

파이썬 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)

테스트하는 데 문제가 있지만



이 봇이 실제로 의도 한대로 작동한다는 것을 확인할 수 있습니다. 컨트롤러에서 버그를 찾아 수정하는 데 도움이되었습니다.
Blue
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.