31 октября, 2016

Factorio, Комбинаторы, описание, примеры (старое)

Статья про комбинаторы со старого форума mtgm.ru

Комбинаторы были детально описаны в пятничных фактах 88 . Но что мы имеем по факту на момент версии 0.12.1. А имеем мы то что они сейчас нафиг не нужны, потому что не хватает множества вещей, для того чтобы их реально где-то применить. Но игра не стоит на месте и я думаю уже через несколько месяцев большинство претензий потеряет актуальность.

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




А вот так выглядит схема полностью:


1.
А теперь по порядку. Схема задается в константном комбинаторе. Мы в нем выбрали пластины и указали сигнал мощностью 2 и шестеренки с мощностью сигнала 1. Эти цифры можно менять свободно, половина схемы построена специально, чтобы упростить настройку, поэтому она сама высчитывает интервалы и прочее.


Дальше из него провода уходят в 2 направления. Запоминаем что провод одного цвета, присоединенный последовательно к нескольким входам спокойно передает сигнал. Именно это тут и исопльзуется. Стрелочками помечено как именно идут провода с сигналом от комбинатора.


2.
Блок решающих комбинаторов из 4 штук слева нужен чтобы сравнить количество ресурсов в рецепте (в константном комбинаторе) и реально в наличии в сундуках. Потому что другой возможности проверить, достаточно ли ресурсов у нас нет.

Для начала мы получаем данные о ресурсах в наличии по красному проводу. Сундуки соединенные проводом между собой посылают информацию о количестве ресурсов единым сигналом. Причем если в нескольких сундуках объединенных одним проводом будет одинаковый тип ресурсов, то сигналы сложатся и мы получим количество ресурсов во всех сундуках группы.


2а.
Нижние два решающих комбинатора имеют простенькое условие. Если есть ресурс в сундуке, то отдаем синий сигнал. Галочка input count значит, что сила сигнала на выходе будет равна силе сигнала на входе. То есть на картинке мы проверяем, количество пластин в сундуке больше нуля? Если больше то синий сигнал будет иметь силу равную количеству пластин. По факту мы конвертировали сигнал от количества пластин в абстрактный сигнал синего цвета той же мощности. Это нужно, потому что мы не можем напрямую сравнить количество пластин в сундуке с тем количеством пластин которое написано в решающем комбинаторе.



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

2б.
Выходы нижних решающих комбинаторов подсоединены к соответствующим входам верхних комбинаторов. Конкретно верхние комбинаторы сравнивают конвертированный абстрактный сигнал от сундуков с реальными пластинами указанными в константном комбинаторе. Если ластин в сундуке больше, то мы отдаем синий сигнал мощностью в 1. В качестве наглядного сигнала у нас сверху, над соответствующим комбинатором, зажигается лампочка. На соседнем комбинаторе, который отвечает за шестеренки мы зажигаем зеленую лампочку, это нам понадобится для следующего сравнения.



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

Вот эта желтая звездочка в условиях комбинатора - Each (каждый), считает количество сигналов и отдает на выход число сигналов. В нашем случае если есть ресурсы в сундуках, то это даст 2 единицы мощности, если ресурсов достаточно, то комбинаторы слева выдадут еще два сигнала - еще 2 единицы мощности, и еще 1 единица мощности дает рыбка, наличие которой в сундуке сигнализирует об окончании последовательности. Итого на выходе у нас сумма единичных синих сигналов и она равна 5 когда цикл окончен и 4 в нормальном процессе работы.


4.
Следующий комбинатор делает простейшую штуку, Если на предыдущем шаге мощность сигнала равна 5, то мы генерируем сигнал F мощностью 1.



5.
Теперь вернемся к нижней группе арифметических комбинаторов. Первый и третий со знаком умножения выставляют задержки для манипуляторов. Мы выяснили что 30 тиков (примерно полсекунды), это как раз время выгрузки 1 предмета. Поэтому мы берем количество предметов определенного типа в константном комбинаторе и умножаем его на 30. Выходной сигнал имеет маркировку 0 (или 1 для шестеренок) и мощность равную получившемуся произведению.



6.
Следующие два арифметических комбинатора делают простую вещь. Берут сигнал получившийся на прошлых комбинаторах и вычитают из него единицу. Это будет нужно в дальнейшем.



7.
Самый нижний комбинатор высчитывает длину цикла в тиках в зависимости от рецепта выставленного в константном комбинаторе. Он складывает выходные сигналы с арифметических комбинаторов со знаком умножения и добавляет к ним константу. После чего выводит это число под маркировкой E.

Тут нужно отметить что конкретно нашем примере у нас две пластины занимают время 60 тиков и шестеренка занимает время еще 30 тиков. То есть теоретически на полный цикл работы достаточно 90 тиков. На практике там выходит на 6 тиков больше, поэтому практическую длительность мы устанавливаем в 100 тиков (90+10 дополнительных). Но из-за особенностей работы арифметического комбинатора и конкретно режима Each, у нас к каждому сигналу прибавляется константа, после чего складываются все сигналы. Поскольку у нас два сигнала, поэтому мы и дополнительную задержку в 10 тиков поделили пополам. Именно так получилась константа 5. Если делать аналогичную схему на 3 разных типа предметов, то при подсчете задержки нужно будет указывать меньшую константу.



8.
Возвращаемся к тому решающему комбинатору на котором мы остановились. Он работает как таймер для цикла. Фиолетовой стрелочкой указано, что красным проводом нужно соединить выход и вход. Зеленый провод приводит нам сигнал F мощностью 1. Этот сигнал запускает цикл и выдается только тогда, когда ресурсы в наличии и рыбка в сундуке. Если этого сигнала не будет - таймер не будет прибавлять +1 к F сигналу каждый тик. То есть он остановится. Красный же провод подводит сюда сигнал E, который мы получили на арифметических комбинаторах и который является длиной цикла.

Цикл по шагам работает так: Когда рыбка в сундуке - таймер запускается. Он работает с 96 до 99 единиц. После этого перестает выполняться условие комбинатора и счетчик таймера сбрасывается. Рыбка все еще на месте. Таймер начинает работу заново с нуля и в момент 1 запускает выгрузку ресурсов. Последней на конвеер выгружается рыбка и когда это происходит, условие в комбинаторе выше(синий сигнал = 5) перестает выполняться, сигнал который крутит таймер перестает поступать и таймер останавливается.



9.
Следующее условие довольно простое. Из таймера (предыдущий комбинатор) ловится момент когда таймер равен 1, и в это время подается короткий импульс синего сигнала с силой также 1.



10.
Теперь начинаются решающие комбинаторы, отвечающие непосредственно за выгрузку предметов на конвеер. Первый комбинатор является типовой ячейкой памяти. Синий сигнал запоминается, зеленый используется для сброса. Фиолетовой стрелкой помечено что выход нужно соединить со входом. Зеленая стрелка - провод с предыдущего шага, который запускает ячейку памяти. Желтой стрелкой указан провод сбрасывающий ячейку памяти.



Именно этот комбинатор подсоединен к умному манипулятору и подает сигнал для его работы.


А еще он зажигает лампочку во время своей работы:


11.
Дальше идет таймер. Фиолетовой стрелкой выход соединен со входом. Он сравнивает, если синий сигнал от ячейки памяти все еще идет, и его мощность меньше чем задержка посчитанная арифметическим комбинатором, то тогда нужно прибавить единичку к мощности синего сигнала. Звучит довольно сложно, но таймер наиболее простая штука. Он каждый тик прибавляет единичку к входному сигналу и этот входной сигнал накапливается до тех пор пока условие не нарушится, после чего он сбрасывается. В данном конкретном случае он отсчитывает 30 тиков пока манипулятор передаст шестеренку на конвеер.



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



13.
Та же самая фиговина, что и в разделе 10. Это ячейка памяти. Фиолетовая стрелка показывает что нужно соединить выход и вход. Запускается зеленым сигналом, который сбрасывал предыдущую. (Зеленый провод). Сигналом сброса здесь является синий (желтая стрелка). Этот комбинатор активирует манипулятор для выгрузки предметов на конвеер (красная стрелка) и включает лампочку на время своей работы (еще одна зеленая стрелка).


14.
Тот же самый таймер. Фиолетовая стрелка - соединить выход и вход. Пока входной сигнал активированный ячейкой памяти меньше чем время на выгрузку предметов (посчитанное арифметическим комбинатором), мы прибавляем единичку к мощности сигнала на входе.

15.
Сброс ячейки памяти. Срабатывает в определенный момент (посчитанный арифметическим комбинатором в разделе 6) ячейку памяти, таким образом останавливает манипулятор. Также дает сигнал для следующего комбинатора.


16.
Последняя ячейка памяти. Выход и вход соединить. Активируется сигналом сброса от предыдущей. Запускает манипулятор который выгружает на конвеер рыбку, тем самым завершая последовательность выгрузки. Сбрасывается снова зеленым сигналом (желтая стрелка).

17.
Последний комбинатор и очень простое условие. Мы проверяем наличие рыбки в сундуке, где она должна лежать. Если ее там нет ( = 0), тогда посылаем сигнал на сброс ячейки памяти. На этом цикл завершается и начинается все заново, когда рыбка вернется обратно в сундук.

Комментариев нет:

Отправить комментарий