Giter Club home page Giter Club logo

tmptrash / construct Goto Github PK

View Code? Open in Web Editor NEW
22.0 7.0 3.0 2.03 MB

JavaScript Digital Organisms simulator

License: MIT License

JavaScript 100.00%
genetic-algorithm digital-organisms javascript distributed-computing distributed-systems es6 opensource evolution-simulation nodejs research websockets bytecode virtual-machine ai canvas2d programming-language artificial-intelligence machine-learning genetic-programming linear-genetic-programming

construct's Introduction

construct

Build Status Codacy Badge

construct is a native JavaScript/ES6 based, digital organisms evolution simulator. It's used for study the evolutionary biology of self-replicating and evolving computer programs (digital organisms). This project similar to Avida, but works with more abstract language (Digital Organism Script - DOS) instead of assembler. It uses special DOSVM for running DOS byte code and distributed computing to speed up the calculations. Generally, it consists of servers, which just a proxies between clients. All calculations are made on a client side only. It's possible to run the system in a "serverless" mode. For this, you have to run index.html (just drop it into the browser) in Chrome without server. More details for russian speaking people on blog and youtube channel. See video presentation here.

Requirements

  • Last version of Chrome browser
  • Last stable version of Node.js

Installation

  • Install Chome browser
  • Install Node.js
  • Clone this repo to your local machine
  • Go to the root folder of cloned repo
  • Run npm install to install all dependencies
  • Run npm run build to build client part
  • Run tests using npm run test command if you need

Run

  • To run construct in a "serverless" mode, just open ./client/dist/index.html in Chrome
  • To run construct in a "distributed" mode, you have to:
    • Choose some host in your local netwok for server
    • Clone construct repo to this host
    • Go to configuration ./client/src/share/Config.js, find serverHost option and change it to the IP, of your server host. You may use ipconfig under windows to get server's IP
    • Run npm run build command in a terminal from the root folder
    • Run server npm run server on chosen host
    • Copy ./client/dist/index.html and ./client/dist/app.js on all your remote machines and run it there under Chrome

Main commands

As an administrator, you may affect the system by command line API. For instance, you may obtain amount of organisms in current population or set new configuration in real time. For this, you have to open Chrome console (press F12) and type man.api[.namespace].xxx(). Where namespace is an optional unit or module and xxx() is supported command of this module. It's possible to use desc property to get command description. Example: man.api.getConfig.desc. Here are all available commands separated by namespace:

  • global namespace - man.api:
    • man.api.visualize(show:Boolean = true) - Turns on/off visualization in browser for current instance (world). Turning visualization off, increases application speed.
    • man.api.formatCode(code:Array) - Converts byte code array into human readable JavaScript based code. This function is low level. For using it you have to get organism's virtual machine reference and then use it's code property. For example: man.api.formatCode(man.api.organisms.getOrganism('128').vm.code). This example will find organism with id 128 and shows his byte code.
    • man.api.version - Returns current app version
    • man.api.getConfig(path:String) - Returns specified config value. First parameter is a namespace (optional) and config name. For example, to get maximum amount of organisms in current instance/world type: man.api.getConfig('organisms.orgMaxOrgs'). Example of organism related configs you may find here. Other configuration parameters are located in files with name Config.js.
    • man.api.setConfig(path:String, value:Any) - Sets configuration value in real time. Opposite to getConfig().
  • charts namespace - man.api.charts. This namespace is related to statistics in charts. There are many parameters like average code size, organisms amount, amount of picked energy and so on. See details here in charts property. You may show and hide different charts on a canvas, locate them and reset any time you need:
    • man.api.charts.on([[name:String = undefined[, show:Boolean = true]]) - shows chart(s) by name. List of all available names you may find here. Example: man.api.charts.on('energy') - will show chart of average organism energy at the moment. Calling this method without parameters shows all available charts. Calling this method with only one string parameter shows specified chart. Calling this method with two parameters shows/hides specified chart depending on second Boolean parameter. Example: man.api.charts.on() - shows all charts. man.api.charts.on('energy') - shows energy chart only. man.api.charts.on('energy', false) - hides energy chart only.
    • man.api.charts.off(name:String = undefined) - opposite to on(). Hides specified or all charts (without parameters) from the canvas.
    • man.api.charts.pos(name:String, pos:String) - Locates chart according to specified position. Available positions are: full, top, down, left, right, topleft, downleft, topright, downright. Example: man.api.charts.pos('code', 'full') - shows code trend chart on full screen. All available chart names are here.
    • man.api.charts.pos9(name:String, x:Number, y:Number) - The same like pos(), but with chart coordinates in 3x3 grid. For example: man.api.charts.pos9('energy', 0, 2) - will positioning energy chart at the location x:0, y:2.
    • man.api.charts.pos16(name:String, x:Number, y:Number) - The same like pos9(), but for grid 4x4.
    • man.api.charts.transparent(name:String, val:Number) - Sets chart transparency. val should be between 0..1. val parameter is optional. In this case all charts will have same transparency. Note: to improve speed, type man.api.visualize(false) in Chrome's devtool console during application run

P.S. If you are a ES6 js developer | Canvas 2D developer | Node.js developer | you just a - join us!

construct's People

Contributors

mekhovov avatar roman-kryvun avatar tarasrng avatar tmptrash avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

construct's Issues

Status plugin energy wrong calculation

Выглядит так, что количество энергии, которое вычисляет status плагин неправильное. Оно резко увеличивается, если включать визуальный режим man.api.visualize().

Add open directions for the world

  • Нужно добавить 4 стрелочки (вверх, вправо, вниз, влево) которые будут светиться зеленым, если организмы могут выходить за экран в этом направлении. По сути, это будет отображение массива Manager._activeAround.
  • Так же добавить функцию отключения\включения их отображения в man.api.showArrows(show = true)

Revert bin to native js converter

Сейчас конвертация байт кода в псевдо JS происходит с использованием goto из за сложностей с расстановкой закрывающихся скобок '{' в операторе цикла. Нужно сделать чтобы при конвертации использовался тот же корректирующий механизм, который сейчас используется в JSVM сейчас (внутренние блоки не могут выходить за внешние). Так, можно будет вернуть конвертацию в нативный JS. Сейчас за это отвечает класс Code2StringXXX.js

Black organisms issue

Проблема не только в том, что они могут быть черными, но и еще во всех темных цветах. Может вообще сделать только определенный набор цветов и менять их по кругу?

Add support of distributed servers/managers

Поддержка нескольких инстансов/процессов. Они должны общаться между собой с помощью Client/Server модулей в "быстром" режиме. Можно ли это сделать вообще без сервера? Или может иметь только один координационный сервер.

Update:

  • При подключении клиента, сервер должен выдавать уникальный в пределах этого сервера id

  • Выданный id должен отправляться со всеми реквестами к серверу

  • Идентификатор региона (коондинаты X,Y клиента) должен знать только сервер

  • Каждый реквест к серверу имеет определенный формат и может быть односторонний или с ответом:
    -> [id, param1, param2,...] request
    <- [*] response

  • Реквесты от клиента к серверу (id params desc):
    -> [0, clientId] run world on client
    <- [Boolean|String] true or error message

    -> [1, direction, org] organism is moving outside of the world
    <- [Boolean|String] true or error message

  • Реквесты от сервера к клиенту:
    -> [100, direction] siblling map is active
    <- [] no

  • добавить логику отправки сервером всем клиентам флажков о том, что сервера со всех сторон активны или наоборот перестали быть активными, чтобы клиенты знали можно ли отправлять организмов в соседнюю карту или работать с ними локально

  • добавить расширение за счет увеличения серверов "вокруг". Сервера должны хранить сокеты всех 4-рех серверов вокруг. это должно работать так:

    • каждый сервер может быть подключен к 4 серверам вокруг (верх, право, низ, лево)
    • новый сервер может появится с любой стороны
    • новый сервер должен создать от 1го до 4х клиентов для связи с серверами вокруг и постараться к ним подключиться. сервера в свою очередь, отреагируют и сохранят сокеты этих клиентов в такой же структуре (верх,...лево) в соотве-их направлениях
    • каждый сервер содержит ссылки на 4 серверов вокруг в виде сокетов

20170923_162950

Add turn off/on IPS title command

Нужно добавить команду в man.api.showIps(show = true) для показа, скрытия IPS в левом верхнем углу экрана.

Связано с #65, #106

Frozen organisms Refactoring

если организм frozen нужно вообще не передавать ему управление еще в главном цикле ManagerOrganism._updateOrganisms(). То есть, не вызывать на нем yieldto(). Везде в коде нужно убрать проверки на haskey(man.cons.frozen,... еще нужно: в _moveOrganism() вместо error() нужно вызывать yieldto(man.task)

Add organisms time analog

Ввести абсолютное количество итераций, которое будет заменять организмам время. Так же ввести совокупное время, которое прошло с момента запуска популяции. Еще, должно быть время и ips с момента последней смерти популяции. Всего будет 4 параметра.

Comments and project documentation

Переписать комменты на jsdoc. Нужно разобраться где это может использоваться. Может нам нужна обычная документация? документация должна быть на подобии вики со ссылками на свои другие разделы.
Концепции, которые нужно описать в документации:

  • что делает construct? (общее описание программы, что в ней происходит, жизненный цикл популяции и организма)
  • распределенная система
  • инсталляция и запуск (настройка клиентов и сервера)
  • основные понятия:
    • организм (из чего состоит, аналог организма в природе, что значит цвет, смерть, клонирование (когда оно возможно), продолжительность жизни, память и ее размер, итерации и наступление событий)
    • борьба за существование и ресурсы (борьба за ресурсы, когда их мало и тем самым те, кому они не достались умирают; охота на другие организмы, чтобы освободить свободное место в очереди организмов Organisms.organisms и дать потомство)
    • код организма (язык DOS, расширение языка, мутагенез кода, вероятности мутаций, рандомные вставки кода Config.orgRandomOrgPeriod, VM, веса операций, количество переменных, максимальное кол-во кода)
    • кроссовер
    • турниры
    • фитнесс
    • энергия (как организм тратит энергию в зависимости от того, сколько ее в нем и от размера его кода, что означает цвет энергии, умная энергия, периоды умной энергии, простая энергия)
    • популяция (в одном мире, макс. размер, автоматическое создание популяции)
    • мир (точки и их типы, размеры, 2D, навигация по миру (зум, скролл, fullscreen кнопка), в одной точке что-то одно, отключение визуализации (ускорение), )
    • соседние миры (клиенты, сервер, переходы из одного мира в другой, наказание за переход, лимит при переходе)
    • консоль (основные команды, данные консоли, расшифровка сокращений: age, kil, org, con,...)
      • полный список всех команд в консоли
    • графики (команды, описание каждого)
  • технические детали (однопоточная модель JS и эмуляция многопоточности, конфигурация и ее разделение по плагинам (Helper.override()), главный бесконечный цикл, на чем написан и какие библиотеки использует, архитектура и плагины, тесты)

One standart for imports (require(...))

Сейчас в UI части используется import XXX from XXX, а в BE части используется require(xxx). Нужно везде использовать require()

OperatorsDos andOperatorsGarmin should be moved outside of the core logic

Нужно вынести эти классы куда-то за пределы основного функционала. В конфиге нужно прописывать путь и имя класса чтобы можно было писать свои имплементации языков. То же самое с классами Code2StringDos, Code2StringGarmin. Это достаточно сырая идея. Нужно додумать стоит ли это делать...

Organisms speaking

Добавить примитивы для общения: say(var::Int8), listen(pos)::Int8. say() должен ложить число в свой локальный буфер. listen() забирать из этого буфера. При забирании число остается в буфере. Буфер должен быть цикличным.

Server command line parameters

Добавить возможность брать параметры для конфига из командной строки для сервера

  • Server should obtain it's port from command line parameter
  • Server should obtain it's max connections value from command line parameter

Связано с #69

Log system for manager

It's good to have some log system for server. All remote commands, connections/disconnections, organisms transfering, manager status, population status and so on should be in this log. It also, should support quite mode (termSetQuite() RPC) and storing them into file. It also should show them in terminal, supporting quite mode as well.

Merge codeVarAmount and codeBitsPerVar configs

  • По сути, это одно и то же. Нужно юзать только codeBitsPerVar.
  • Так же, нужно сделать этот параметр рабочим. Сейчас кроме значения 2 (4 переменные) ничего не работает.

Add version for all components

Добавить версии для сервера, визуализатора, терминала,... Думаю это же актуально для плагинов

Think about different sub populations at the time

Проблема состоит в том, что все организмы влияют друг на друга в том смысле, что клонирование затрагивает всю популяцию. Это значит, что внутри популяции невозможно одновременное развитие разных поведений. Если бы была возможность создавать сабпопуляции и делать клонирование или кроссовер внутри этих сабпопуляций, то, возможно эволюция шла бы в совсем в другие стороны. С другой стороны, возможно, это решится когда будет реализована распределенная система, где под популяции будут популяции разных машин\процессоров.

Organisms code access for other organisms

Подумать про доступ к коду организма другими организмами, но только находясь рядом.
Под вопросом

Add separate options for small mutations

Сейчас есть только одна вероятность того, что small mutation произойдет. На самом деле - это не одна мутация, а несколько. Нужно сделать чтобы все они были отдельными опциями\вероятностями.

Statistics server

По аналогии с админкой, нужно сделать сервер статистики. Он будет собирать статистику со всех клиентов и показывать общий либо индивидуальный тренд.

Add backup support

Добавить возможность сохранять популяцию текущего клиента в бекап.

  • В идеале оно должно сохраняться в файловую систему
  • Возможно сохранение в localStorage (продумать оптимизированный формат)
  • Добавить сохранение конфигурации в бэкап. Сейчас конфигурация берется из модуля Config в том виде, в котором она есть при запуске. То есть, можно менять её между запусками программы.

Add codeVarAmount config

Вынести кол-во локальных переменных в конфигурации. Сейчас 5.
Update: настройка уже вынесена, но она не работает. Нужно ее зафиксать, вместе с количеством бит на переменную

Use JS profiler to find slow places in a code

Почитать, как работает профайлер и как он показыват числи напротив каждой строки. Они какие-то нелогичные (например зачем число на закрывающейся скобке функции?)

Add copy mutation

Добавить функцию мутирования: 'копирование' помимо add/change/del...

Add different world object types (stones, holes,...)

  • Добавить разные типы объектов мира: стены, ямы, подумать что еще. Возможно какие-то динамические штуки вроде дня и ночи, холода и жары, двигающейся энергии и т.д.
  • Подумать о том, чтобы для определенного экрана (карты/менеджера) работал маленький скрипт, который бы по какому-то принципу создавал динамику объектов. Например приливы и отливы, рост скал, увеличение количества энергии и ее позиция и т.д. В каждой карте этот скрипт будет свой. Вполне возможно - это будет плагин.

Operators map should be an Array

Нужно переписать объект Operators._OPERATORS_CB на массив. Потому что это будет быстрее, чем объект, а это самое сердце JSVM.

Phylogenetic tree creation

Нужно сделать филогенетическое дерево на основе, например json или какой-нибудь технологии. Это даст нам понимание почему одни мутации поддерживают мягкая отборочный, а другие нет.

update: нужно использовать json но в формате данные и связи отдельно. Смотри этот линк. Мне нравится либа sigma.js. Суть следующая:

  • при первом старте системы мы создаем пустой массив типа Creature.Organism и массив связей типа Int
  • в первый массив добавляется каждый созданный организм
  • во время бекапа оба массива конвертируется в json и сохраняется в файлы по времени. При этом массивы в системе очищаются
  • во время клонирования в первый массив добавляется новый организм. Так же, во второй массив добавляется новая связь между родителем и ребенком

что должен уметь плагин:

  • нужно иметь возможность иметь полное филогенетическое дерево за определенный период времени. для этой задачи нужно ввести параметр времени или итераций из которых будет выбираться период
    пример дерева: https://www.dropbox.com/s/if22s1e7wncck60/phylo.png?dl=0
  • дерево должно содержать организмы с родительскими связями между ними. по сути, по этим связям можно подняться до самого "первого" предка (на рисунке выше - это движение снизу вверх)
  • при выборе организма нужно видеть его мета информацию такую как:
    • имя (id)
    • все свойства (энергия, количество мутаций, цвет, код и т.д). полный список свойств смотри здесь: https://github.com/tmptrash/jevo/blob/v1.1/src/organism/Creature.jl. строка "type Creature"
    • список измененных организмов, которые получили порции мутаций от текущего. это не то же самое, что получить (родить) наследника так как мутации получаются в течении жизни

Smart system parameters

Подумать о динамическом изменении параметров системы, если она не эволюционирует (если совокупное кол-во энергии у организмов не увеличивается или уменьшается). Например, можно увеличить число мутаций или изменить вероятностные коэфициенты.

update: По данным на 23.01.2018 - система не эволюционирует, если она застряла в локальном оптимуме. Чтобы выйти из него, нужно увеличивать мутагинез. А именно - уменьшать шаг кроссовера (organisms.orgCrossoverPeriod) и шаг рандомных организмов (organisms.orgRandomOrgPeriod).

Config properties should be real time changable

Сейчас они присваиваются константам (например в Num.js) это значит, что при изменении этого параметра во время работы программы, он не повлияет на ее работу. Нужно отказаться от такого подхода и везде использовать Config.xxxx

Add charts for analitycs

Добавить графики реального времени об изменении разных параметров: енергии, размера кода, частоте мутаций, всех параметров Organism типа, количество поломок (exceptions), общее кол-во энергии популяции

  • общее кол-во энергии в популяции (min,max,cur)
  • общая адаптация (мутации*енергию)
  • общее кол-во мутаций
  • общая вероятность добавл/изм/удал мутаций
  • сколько определенных кодовых конструкций сейчас в популяции (смотри CodePart тип)
  • отчего умирают организмы: старость, съедение, уменьшение энергии, альструизм
  • количество неудавшихся мутаций
  • Пройтись по всем свойствам организма и системы
  • Добавить график wenergy

Ideas

  • подумать про веса операций
  • подумать про диагонали
  • попробовать дать возможность организму самому делиться
  • подумать про "выброс" элементов в окружающую среду, как общение...
  • use elasticsearch for statistic module

Speed optimization of Organisms._onAfterMove() method

Выглядит так, что этот метод съедает существенную часть скорости CPU во время работы системы. Все из за этих двух строк:

    delete this._positions[Helper.posId(x1, y1)];
    this._positions[Helper.posId(x2, y2)] = org;

Проблема в том, что мы постоянно добавляем и удаляем ключи. Нужно придумать чем заменить работу с хеш мапой. Было бы неплохо использовать массив фиксированной длины, если это возможно. Но по сути, его размер будет такой же, как и размер мира в точках. Исходя из этого вторая идея - использовать сам мир, как этот массив. Для этого нужно проверить не будет ли медленным хранить в массиве мира ссылки на организмы, либо значения энергии. Так же, нужно учесть тот факт, что мир можно оптимизировать используя типизированные массивы типа UInt32Array. Нужно так же проверить будут ли они быстрее обычного массива, который используется сейчас.

Add unit tests

  • Для всех модулей
  • Прикрутить code caverage

Admin server

Добавить админку - сервер с http интерфейсом, который сможет:

  • связываться со всеми работающими серверами и показывать их конфигурацию (сетку серверов)
  • перемещать позиции серверов
  • включать\выключать сервера
  • регистрировать новые сервера (возвращать им их позицию, id, кто сверху, снизу, слева, справа)
  • регистрировать новые клиенты (возвращать их id и родительский сервер)
  • думаю можно еще менять конфигурацию определенного клиента удаленно
  • ...

Связано с #45, #13

Distributed system issues

  • При разрыве соединения с клиентом нужно очищать запросы этого клиента в Request._requests
  • Нужно проверять, что в соседнем клиенте существует максимальное кол-во организмов
  • Нужно чтобы организм не возвращался назад более 2 раз. Иначе возможен бесконечное перекидывание его между двумя соседними клиентами

Связано с #13

Add "termFollowOrganism" remote command

Добавить команду termFollow(orgId, color). Она будет переключаться между менеджерами и "следить" за одним организмом. Возможно нужно будет временно менять его цвет или как-то выделять среди других.

Update Statistics module

Модуль статистики сейчас устарел. Нужно переписать его с учетом полного филогенетического дерева, а текущий стереть.

Optimize random organism getting

Сейчас метод Organisms._tournament() использует такой код для получения случайного организма:

... = this._orgs.get(Helper.rand(orgAmount)).val;

этот код медленный, так как нам нужно крутить всреднем orgAmount / 2 итераций цикла для поиска случайного организма. Более простой путь использовать curPosInOrgsQueue + rand(4). Все равно все организмы перемешаны и нет никакой закономерности в их позиции (индексе) в очереди Organisms._orgs. Это будет в orgAmount / 2 / 2 быстрее, чем текущее решение.

Plugins should set in Config

Сейчас плагины просто хардкодятся в мапе PLUGINS. Нужно сделать чтобы пользователь мог изменить плагины которые добавляются к определенным классам.

  • Нужно сделать это с помощью конфигов plugIncluded, plugExcluded (как было в Julia/Jevo). Возможно это будет структура типа
{ClassName: [Plugin1, Plugins2,...],...}
  • Так же, нужно сделать систему разбора параметров задаваемых в командной строке для сервера и в URL для клиента. Эти параметры должны перекрывать собой параметры указанные в Config.js по умолчанию.

Config should affect only client

Нужно убрать из Config.js все опции сервера (все, что начинается на ser) и вернуть его в папку client.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.