В 40-е годы XX века работа Фон Неймана в области самовоспроизводящихся машин привела к появлению теории клеточных автоматов. Оттуда же берёт своё начало не безызвестная «Game of Life» — математическая модель примитивной жизни захватывающая умы простотой своего описании и сложностью порождаемых ею систем.
Футуристы тех лет считали, что эти исследования помогут в ближайшем будущем покорить Марс — где даже одного самореплицирующегося автомата хватит, чтобы он, скрупулёзно следуя алгоритму заложенному при его создании, смог основать целую колонию таких машин. Которые занялись бы терраформингом и приготовлением планеты к прибытию колонистов из плоти и крови.
Мы же предлагаем вам приобщиться к этому делу в игровой форме. Вы можете попробовать себя в роли разработчика таких машин в TorLand и положить начало новой искусственной жизни, более того всё это можно сделать в пределах окна вашего браузера.
Бот — модель примитивного организма
Боты населяют клетчатое квадратное поле с замкнутыми сторонами. Подобно почти всем живым существам они обладают:
-
Памятью;
-
Потребностью в энергии;
-
Ориентацией в пространстве;
-
Возрастом;
-
Органами чувств.
И самое главное они обладают генами. В TorLand’е геном — это результат компиляции Assembly-like кода, который описывает поведение бота. Язык описания генома бота называется BotC подробнее о деталях его синтаксиса можно почитать вот здесь.
Мы же рассмотрим пример простого генома — JXELCCIAIAEAGQH72HBF5RH545ZBQAYKDI4EEIWUBEYGASHJJ5U6H4GPP3JQK. Который был скомпилирован из следующего кода
start: // объявление метки eatsun // поглощение энергии солнца cmpv en 1500 // сравнение уровня энергии с константой jle start // переход на метку start, если En <= 1500 fork right start // деление с созданием новой колонии справо, // новый бот начинает выполнение кода с метки start mov front // пройти на 1 клетку вперёд относительно "лица" бота
Этот простой организм ждёт накопления достаточного уровня энергии, которую он получает из солнца. После чего размножается делением, порождая нового бота справа, а затем делает один шаг вперёд. Так как fork это довольно энергоёмкая операция, старый бот тут же погибает после передвижения в новую клетку. Создавая тем самым ощущение бегущей волны.

В симуляции первое время всё идёт согласно нашему замыслу элегантно описанному в коде. Но в конце один из ботов неожиданно покидает стройные ряды своих собратьев и отправляется на встречу с неизведанному.
Это не что иное как эволюция — случайное изменение генома нового бота, которое может произойти с некоторой вероятностью при каждом использовании команды fork.
Если же вам не по душе такая непредсказуемость вы всегда можете использовать аналогичную команду split, которая гарантирует отсутствие мутаций в новом организме. Или же вообще отключить возможность случайной мутации, установив её вероятность равной нулю в настройках мира.
NiLang
В романе «Мир-Кольцо» Ларри Нивен описывает массивную супер-структуру — кольцо опоясывающее звезду и являющееся домом для множества биологических видов собранных по всей галактики загадочными создателями этого чуда света.
С точки зрения топологии мир в котором существуют боты аналогичен Миру-кольцу. Квадрат с замкнутыми сторонами представляет из себя двухмерную проекцию поверхности Тора.

NiLang — это высокоуровневый язык программирования ботов TorLand’а, получивший своё название от первых слогов имени и фамилии автора «Мир-Кольцо» — Ларри Нивена.
Геном бота из нашего первого примера можно описать следующей программой на NiLang‘е.
Using bot Fun Charge$ energy Int: While GetEnergy < energy: ConsumeSunlight # function call without arguments Charge$1500 Fork$dir::right Move$dir::front
Как видите, синтаксически NiLang очень похож от Python, хотя в отличии от него является статически типизированным языком. Если вам интересно полное описание синтаксиса NiLang‘а и другая информация о нём, то вы можете найти её здесь.
А теперь давайте перейдём к примерам куда более комплексных организмов.
Примеры
Шахматная доска
Начнём с простого, заполним тор ботами в шахматном порядке. Алгоритм здесь довольно простой:
-
Зарядиться энергией;
-
Если клетка справа спереди свободна, породить нового бота там;
-
Повернуться на право;
-
Обойдя все четыре стороны перейти в режим «растения» — вечный цикл накопления энергии.

Using bot Fun Charge$ energy Int: While GetEnergy < energy: ConsumeSunlight Int i = 0 While i < 4: Using dir Charge$1500 If IsEmpty$frontRight: Fork$frontRight Face$right i = i + 1 While True: ConsumeSunlight
Поле цветов
Переходя к более сложным организмам, мы можем воспользоваться генетической памятью — возможностью бота передавать своему потомку информацию. Для создания цветка нам потребуется три роли:
-
Корень — основания от которого будут расти ветки нашего цветка;
-
Ветка — кусок цветка, который породит семечку;
-
Семечко — подвижная часть организма, которая отвечает за создание нового цветка.

Using bot Int _ENERGY = 1500 Int _BRANCH_LENGTH = 5 Int _SPREAD_DISTANCE = 45 Fun Charge$ energy Int: While GetEnergy < energy: ConsumeSunlight Fun PlantLoop: While True: ConsumeSunlight Fun Root: Int i = 0 While i < 4: Charge$_ENERGY Face$dir::left Fork$dir::front i = i + 1 Fun Seed: Int d = 0 While d < _SPREAD_DISTANCE: Charge$100 Move$dir::frontRight d = d + 1 WriteMemory$1 Root Fun Branch: Charge$_ENERGY Fork$dir::front Int stage = 0 If IsMemoryReady: stage = ReadMemory WriteMemory$stage+1 If stage < 1: Root Elif stage >= 1 And stage <= _BRANCH_LENGTH: Branch Elif stage > _BRANCH_LENGTH: Seed PlantLoop
Змейка
До сих пор наши боты существовали в мире с равномерным распределением ресурсов. Но в TorLand’е также можно создать мир разделённый на кластеры, где количество доступного солнечного света и минералов из которых бот получает энергию варьируется (жёлтые участки богаты солнцем, а синие минералами).
Змейка использует свои органы чувств, чтобы расти только в сторону участков карты богатых на солнечное излучение.

Using bot Using dir Int _ENERGY_PER_SPLIT = 1000 Int _INT_MIN = -2000 Fun Charge$ energy Int: While GetEnergy < energy: AbsorbMinerals ConsumeSunlight Fun GetEn::Int$dir Dir: If IsEmpty$dir: Return -GetLuminosity$dir Return _INT_MIN Int ft = GetEn$front Int fr = GetEn$frontRight Int rt = GetEn$right Int br = GetEn$backRight Int bt = GetEn$back Int bl = GetEn$backLeft Int lt = GetEn$left Int fl = GetEn$frontLeft Fun IsMax::Bool$x Int: Return x >= ft And x >= fr And x >= rt And x >= br And x >= bt And x >= bl And x >= lt And x >= fl Charge$_ENERGY_PER_SPLIT + _ENERGY_PER_SPLIT/2 If IsMax$ft: Split$front Elif IsMax$rt: Split$right Elif IsMax$bt: Split$back Elif IsMax$lt: Split$left Elif IsMax$bl: Split$backLeft Elif IsMax$br: Split$backRight Elif IsMax$fl: Split$frontLeft Elif IsMax$fr: Split$frontRight While True: ConsumeSunlight
Песок и платформа
Как ни странно, но при помощи ботов можно сделать простой симулятор частиц. Правда для этого понадобиться отключить старение (сделать очень большим параметр мира Штраф к энергии за возраст), а также понизить Расход энергия за деление и Расход энергии за шаг.
Код бота платформы
Using bot Using dir While True: If IsEmpty$back: Move$back Elif IsEmpty$backRight: Move$backRight Elif IsEmpty$backLeft: Move$backLeft Else: While True: ConsumeSunlight
Код бота частицы
Using bot Using dir While True: If IsEmpty$back: Move$back Elif IsEmpty$backRight: Move$backRight Elif IsEmpty$backLeft: Move$backLeft Else: While True: ConsumeSunlight
Ссылки
-
Страница TorLand на GitHub;
-
Документация к BotC;
-
Страница NiLang на GitHub;
-
Онлайн-Компилятор BotC и NiLang, а также онлайн версия TorLand’а.
ссылка на оригинал статьи https://habr.com/ru/articles/901454/
Добавить комментарий