Це життя, Джиме, але не так, як ми його знаємо


58

Напевно, ви знаєте «Гра життя» Конвея , знаменитий стільниковий автомат, винайдений математиком Джоном Конуей. Життя - це набір правил, які разом дозволяють імітувати двовимірну дошку комірок. Правила визначають, які клітини на дошці живуть, а які вмирають. Маючи трохи уяви, ви можете сказати, що Life - гра з нульовим гравцем: гра з метою знайти зразки з цікавою поведінкою, як у відомого планера.

Планер

Гра з нульовим гравцем ... До сьогодні. Ви маєте написати програму, яка грає в «Гра життя» - і грає її, щоб виграти, Король гори. Ваш противник (сингулярний), звичайно, намагається зробити те саме. Переможець або останній бот з будь-якими живими клітинами, або гравець з найбільш живими клітинами після 10000 поколінь.

Правила гри

Правила майже такі ж, як і звичайні (B3 / S23) Життя:

  • Жива клітина з менш ніж двома доброзичливими сусідами помирає від голоду.
  • Виживає жива клітина з двома-трьома дружніми сусідами.
  • Жива клітина з більш ніж трьома доброзичливими сусідами гине від перенаселення.
  • Мертва клітина з рівно трьома сусідами того ж гравця оживає, щоб боротися за цього гравця за умови, що ворогів немає .

... але після кожного покоління ви і ваш противник отримуєте можливість втручатися. Ви можете розбудити до 30 клітинок, щоб боротися за вас. (Хто перший йде, вирішує сервер.)

Дошка - квадрат (x, y) комірок. Усі квадрати спочатку мертві. Кордони не обертаються (це не світ у формі тору) і назавжди мертві.

Це змагання в дусі Battlebots та Core Wars . Є центральний сервер, який запускає ботів, і його можна знайти тут

Протокол

Сервер арени говорить простий протокол JSON, переданий через argv

Де Значення - це кодований рядок JSON

  • y_size: максимум y координати плиток, перш ніж вони зникнуть
  • x_size: максимальна кількість х плиток плит, перш ніж вони зникнуть
  • tick_id: поточний номер галочки
  • board: словник з ключами у формі '(y, x)' та значеннями у формі bot_id(int)
  • bot_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
    • Запустіть змагання all v all з кожним ботом, протиставляючи його один одному.
  • Режим тестування (GUI)
    • Біжи python3 nice_gui.py
    • Клацніть Pull Answers
    • Якщо ви хочете додати власну відповідь, щоб спробувати її перед публікацією, натисніть File -> Add manual answerі знайдіть файл та виберіть мову, на якій він написаний.
    • Якщо вашої мови немає, пінг мені, і я спробую встановити його на сервер, я запустити його (інструкції з встановлення та запуску було б непогано!)
    • Виберіть 2 боти, щоб піднятися один проти одного
    • Клацніть Run
    • Дивитися гру ...
  • Установка
    • Потрібен python3
    • get_answers вимагає bs4 та html5lib
    • контролер вимагає способу запуску .sh файлів (MinGW у Windows)

Приклад зображення програми

Оцінка балів

Бот з найбільшою кількістю виграшів починаючи з 12/07/2016(12 липня) 14/07/2016 (14 липня не зміг розібратися, як запустити бота).


Довідку з контролером / gui можна попросити в цій кімнаті чату


Це питання розробляється з 2014 року і було найбільш актуальним питанням у пісочниці. Особлива подяка Прогуляйтеся NAUTA (автор оригіналу і концепція), PPCG чат (коментарі та допомогу) і всім , хто коментував в пісочниці повідомленням (більше коментарів).


25
Так, я думав, що це ніколи не вийде з пісочниці. Чудово!
Луїс Мендо

Друкарня: 12.06.2016 (12 липня)
Луїс Мендо

4
+1. Ви заслужили нагороду AED за те, що вивели це чудове питання з пісочниці!
agtoever

1
@ KevinLau-notKenny о, добре. Чи можете ви запустити команду у файлі?
Rɪᴋᴇʀ

1
@Magenta Коли я їх отримую (я зовсім забув про це, хоча він був у постійно відкритій вкладці), я запускаю його зараз
Blue

Відповіді:


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
Чорнило з

Я не знаю, як це відбувається, тому що я не можу запустити контролер з будь-якої причини.
Маджента

8

Рубі, перериваючиBlockMaker

Замість того, щоб ініціалізувати планери, як TrainingBot, він намагається створити блок перемикання блоку 5х5, як згадується у Вікіпедії, у випадковій точці лабіринту. Потім, залишившись активаціями, він просто знаходить ворожі точки і намагається переправити сусідню зону з вашими клітинами, намагаючись перешкодити їм зростати і, можливо, зіпсувати їхні зразки. Ваші клітини загинуть у наступному поколінні, але, можливо, вони також зупинили деякий ріст, щоб уповільнити опонента!

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 або щось таке, щоб перевірити мого бота ~
Value Ink

@muddyfish Я вже згадував, що Windows має проблеми через обмеження в командному рядку, що остання помилка була в Cloud9, який нібито є вікном Linux. Як мій бот тарифікується на вашу скриньку Linux (оскільки ви припустили, що у вас є)?
Значення чорнила

Виявляється, я цього не робив, але цифри bot_scoreпоказують, скільки виграшів у кожного бота проти інших ботів
Blue

Гаразд, дякую! На жаль, у Cloud9 дійсно немає графічного інтерфейсу, і 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

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 та 2х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"]
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
Графічний інтерфейс, швидше за все, виходить з ладу через ваш print(sys.argv[1])рядок 3, який псує результат (тренажер очікує лише рядка координат, які ви хочете прокинути). Крім того, в останньому рядку вашої програми відсутнє батьківство закриття.
Значення чорнила

@ KevinLau-notKenny Графічний інтерфейс не працював і на тренувальному боті, і на боті Ruby. Однак я видалив цей рядок і додав його знову до закритого батька (я думаю, що останній був помилкою копіювання та вставки).
Стівен Х.

На якій операційній системі ви входите, і які помилки з’являються в командному рядку під час її запуску? Наразі відома помилка, що Windows не може належним чином запустити сим через аргументи, передані через командний рядок, усічений, коли вони перевищують ліміт символів командного рядка близько 8000.
Значення чорнила

@ KevinLau-notKenny Я використовую Windows 10, і я отримав ... ну, багато помилок. Перше, що BeautifulSoup не хотів знайти html5lib, потім не знаходив папку, що містила всіх ботів (мені довелося змінити код для обох цих), і з тих пір запуск будь-якого бота Python призвів до повернення коду не 0 1.
Стівен Х.

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

Розставляє сквери скрізь - можливо

Квадрати - це статичні об’єкти в Житті - вони не рухаються. Тож якщо я розміщую навколо себе достатньо інертних предметів, планери та вибухи, які створюють інші, можливо будуть заблоковані або принаймні заглушені.

-Додано з 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.