Обучение: Руководство по комбинаторам
Руководство для продвинутых, предполагающее базовое понимание логических схем. Охватывает более сложные темы, такие как SR-триггеры, ячейки памяти и таймеры. Начинающим, прежде, необходимо изучить Обучение: Руководство по логической сети и Логическая сеть.
Введение
Комбинаторная логика реализуется путем перекрестного соединения выходов со входами устройств таким образом, чтобы достичь необходимой логической схемы. Хотя для продвинутой логики требуется много комбинаторов, базовая логика, но не менее полезная, может быть реализована с использованием лишь нескольких комбинаторов. Комбинаторная логика возможна благодаря тому, что Factorio обновляется 60 раз в секунду, что позволяет комбинаторам обрабатывать логику на одном такте, а результат, например суммирования и/или деления, выдавать на следующем.
Пока логическое значение вычисляется в комбинаторе, его выходы не определены до следующего такта. Поэтому сравнивающий комбинатор, используемый для проверки определенного условия на входе, не будет влиять на схему после него до следующего такта. Эту особенность работы комбинаторов необходимо запомнить, т.к. она может приводить к ошибкам и большим задержкам, в случае последовательного соединения множества комбинаторов.
Логические провода аналогичны шине в электронике; они передают информацию подключенным к ним проводам, а это означает, что если в проводе есть похожие сигналы, они автоматически просуммируются.
При перекрестном соединении комбинаторов, хорошей практикой для межсоединений считается применение проводов другого цвета, что разделяет входные и выходные сети и предотвращает случайное подключение нежелательных входов к более крупной сети.
Виртуальные сигналы
В дополнение к стандартным сигналам, в Factorio существуют дополнительные сигналы, не представляющие какие-либо предметы из игры. Вместо этого, они позиционируется как определяемые игроком сигналы — иначе говоря, их значение определяется тем смыслом, который заложил в него сам игрок. На текущий момент существует 48 виртуальных сигналов:
- 26 букв английского алфавита (A-Z) и 10 цифр (0-9);
- 9 цветов: красный, зеленый, синий, желтый, пурпурный, голубой, белый, серый и черный;
- 3 иконки: зеленая галочка, информационная буква 'i' и маленькая белая точка.
Логические сигналы
Помимо описанных, в игре есть три дополнительных виртуальных сигнала, известные как логические сигналы. Они отличны от других сигналов тем, что не могут отсылаться в сеть, вместо этого они дают дополнительные возможности комбинаторам. Иными словами, логические символы представляют собой метасимволы, которые являются специальными сигналами, представляющие собой "ноль и более" произвольных сигналов вместо представления одного дискретного сигнала.
Метасимвол "Все"
Метасимвол Все используется в сравнивающем комбинаторе. Его поведение зависит от того, используется ли он на входе или на выходе:
- Вход: возвращает "истина" если все входные сигналы удовлетворяют условию или если на входе нет сигналов, в противном случае возвращает "ложь".
- Выход: возвращает все ненулевые входные сигналы.
Когда метасимвол Все используется на входе, он может пониматься как логическое "И" или квантор всеобщности. На выходе, он подобен 'эхо' входного сигнала.
Примечание: может использоваться на выход только в том случае, если на входе не используется метасимвол Каждый.
Метасимвол "Любой"
Метасимвол Любой тоже используется в сравнивающем комбинаторе, но только на вход.
Представляет любой, хотя бы один входной сигнал и возвращает "истина", если он удовлетворяет условию. Если ни один из сигналов не удовлетворяет условию или на входе нет сигналов, возвращает "ложь". Метасимвол Любой может пониматься как логическое "ИЛИ" или как квантор существования.
Метасимвол "Каждый"
Метасимвол Каждый используется в сравнивающем и арифметическом комбинаторе. Поведение этого метасимвола несколько отлично от поведения предыдущих: он выполняет функцию комбинатора над каждым сигналом в отдельности. То, как он применяется, зависит от конкретной функции комбинатора и типа комбинатора. Применяется он на входе и на выходе, но только тогда, когда используется и на входе.
В сравнивающем комбинаторе, при использовании метасимвола на входе, возвращается каждый входной сигнал, удовлетворяющий условию комбинатора. В зависимости от того, используется ли метасимвол Каждый только на входе или на входе и выходе одновременно, результат на выходе комбинатора будет разным:
- Только вход: суммирует каждый входной сигнал, удовлетворяющий условию, и, в зависимости от настроек выхода, возвращает либо количество сигналов, либо сумму их значений.
- Вход и выход: возвращает каждый сигнал, удовлетворяющий условию.
В арифметическом комбинаторе, назначенная операция применяется для каждого входного сигнала и, аналогично сравнивающему комбинатору, возвращаемый сигнал зависит от, того, применяется ли метасимвол только на входе или на входе и выходе одновременно:
- Только вход: после применения арифметической операции к каждому сигналу, они суммируются, а результат возвращается на выход.
- Вход и выход: после применения арифметической операции к каждому сигналу, они возвращаются на выход.
Как видно, метасимвол Каждый более сложный чем два предыдущих, однако при этом он является более полезным.
Изолятор и устройство стробирования
Арифметический комбинатор с настройками — (вход: Каждый + 0; выход: Каждый) — представляет собой изолятор или устройство для развязки сетей. Оно может использоваться для замены одного цвета провода на другой, предотвращая проникновение в сеть нежелательных сигналов из схемы после комбинатора.
Сравнивающий комбинатор с настройками — (вход: сигнал с выхода > сигнала на входе; выход: Все) — действует как изолятор, пока верно заданное логическое условие. Таким образом, это устройство позволяет фильтровать и стробировать входные сигналы. С помощью стробирующего устройство можно последовательно опрашивать удаленные хранилища ж/д станций, что бы включать только нужные станции.
Установка/Сброс триггера
Допустим вы хотите, чтобы что-то установило триггер по достижению определенного количества каких-либо предметов, и оставался в этом состоянии, пока количество этих предметов не достигло другого значения, после чего бы триггер был сброшен. Для реализации подобной схемы, вам потребуется один сравнивающий и один арифметический комбинатор (для реализации мультиканальной схемы потребуется еще 2 сравнивающий и один постоянный комбинатор).
Установите первый сравнивающий комбинатор с условием, при выполнении которого на выход подается 1. В нашем примере, единица на канале B появляется при выполнении условия: "уран-235 > 40".
Затем соедините выход сравнивающего комбинатора со входом арифметического и умножте его на разницу между значениями устанавливающего и сбрасывающего триггер. В нашем примере, сбрасывающее значение равно 0, а устанавливающее — 40 (если бы мы хотели оставить, скажем, 4 предмета в сундуке, мы бы установили смещение на 36). Обратите внимание, что на выходе арифметического устройства выбран тот же канал (уран-235), что и на сравнивающем комбинаторе.
Теперь соедините выход арифметического комбинатора со входом сравнивающего. Это число будет добавлено к изначальному входу.
Вот как работает эта схема:
- Изначально B = 0; x единиц урана-235 меньше чем 40. Выход сравнивающего комбинатора — 0, арифметического — 0*40 = 0. Этот ноль возвращается назад на сравнивающий комбинатор и добавляется к x.
- Запускается производство урана-235 и x увеличивается достигая 41. Это запускает решающий комбинатор, и он посылает 1 по каналу B. Вы можете использовать этот сигнал для разгрузки урана-235.
- Арифметический комбинатор теперь выводит однократное смещение, равное 40. Число 40 добавляется к x на входе сравнивающего комбинатора, таким образом смещая его.
- Когда уран-235 выгружается, x уменьшается, а вход сравнивающего комбинатора по прежнему остается смещенным: x+40. До тех пор, пока x больше 0, сравнивающий комбинатор удерживает на своем выходе единицу и разгрузка продолжается.
- В один момент x достигает 0 и вход сравнивающего комбинатора становится равным 40, а на канал B подается 0. Разгрузка завершается и цикл повторяется.
Первый манипулятор включается, когда количество урана-235 в сундуке больше 40. Размер стака манипулятора переопределен и равен единице.
Второй манипулятор управляется сигналом по каналу B выведенные из триггера. Он запускает и удерживает процесс разгрузки сундука, до тех пор, пока он не станет пустым (когда B снова станет равным 0). 40 единиц урана-235 загружаются в центрифугу и процесс продолжается.
Аналогичная схема, но для резервирования пара детально описана здесь: Обучение: Руководство по логической сети.
- Decider.png
Сравнивающего комбинатора.
- Arithmetic.png
Арифметического комбинатора.
- Inserter1.png
Манипулятор, выгружающий излишки урана-235.
- Inserter2.png
Манипулятор, возвращающий уран-235 в центрифугу.
Продвинутый загрузчик поездов
Эта схема решает проблему равномерной загрузки предметов в сундуки на станциях погрузки, из-за которой погрузка предметов в вагоны поездов происходит медленнее.
Для установки этой схемы потребуется арифметический комбинатор и красный и зеленый провода. Все сундуки соединяются проводом, который заводится на вход комбинатора. В арифметическом комбинаторе введите: количество предметов / -количество сундуков — это дает среднее значение предметов в одном сундуке; результат деления передается по каналу тех предметов, что находятся в сундуке. Все используемые манипуляторы соединяются проводом, который заводится на выход комбинатора, причем его цвет отличен от цвета провода, соединяющего сундуки. Далее, в манипуляторах необходимо установить условие: предмет < 1.
Рисунок схемы можно найти на reddit: продвинутый загрузчик поездов от MadZuri.
Вот как работает эта схема:
в манипуляторах производится сравнение среднего значения количества предметов с количество предметов из сундука напротив манипулятора (суммируется отрицательное среднее с положительным числом предметов из сундука). Манипулятор включается, когда среднее значение больше количества в сундуке.
Память
Для сохранения некоторого числа для последующего использования, например, в таймере или более сложной схеме, необходимо соединить вход и выход сравнивающего комбинатора и для любого канала (или всех сразу) настроить условие "> 0". Т.о., передавая значение с выхода на вход, комбинатор сохраняет его до тех пор, пока на в входах не появится какой-либо сигнал.
Любой, ненулевой сигнал на входе, соответствующий условию в комбинаторе, создает простейший таймер. Сохраненное число инкрементируется на каждом такте на значение входного сигнала. Импульсный сигнал на входе, инкрементирует сохраненное значение один раз. Сброс до нуля происходит лишь в том случае, если не выполняется условие либо, когда на входе возникает импульсный сигнал с таким же, но отрицательным значением.
Базовый таймер
Для конструирования базового таймера необходимо соединить вход и выход комбинатора, что приводит к увеличению значения на каждом такте. Использовать можно как арифметический, так и сравнивающий комбинаторы.
Арифметический комбинатор просто заводится сам на себя, однако потребуется дополнительная схема для сброса таймера.
Для самосбрасывающегося таймера нужен всего лишь один сравнивающий комбинатор с соединенными входом и выходом и условием "меньше чем" (сигнал со входа передается на выход). Поставив на вход постоянный комбинатор, каждый такт таймер будет инкрементироваться на значение указанное в постоянном комбинаторе до тех пор, пока не достигнет значения в условии, после чего на выходе образуется 0 и цикл начнется заново.
Таймер всегда начинает свою работу не с нуля, а с предустановленного в постоянном комбинаторе числа. В арифметическом комбинаторе стартовое значение можно изменять, однако нужно помнить, что его выходы обрабатываются на такт позже.
Генератор импульсов
Подсоединяя дополнительный сравнивающий комбинатор на выход базового таймера можно сделать генератор импульсов, который будет генерировать один импульс по условию каждый цикл таймера. В качестве выходного сигнала генератора может выступать как выход с самого таймера, в том числе единичны, либо сигнал с внешней схемы.
Пояснения к рисунку:
- Вместо 1 с правой стороны, можно использовать любое другого число в диапазоне таймера.
- Если в качестве примера взять таймер описанный выше, то генератор импульсов будет генерировать импульс 1 раз в 30 тактов или 2 раза в секунду, т.к. Factorio обновляется с частотой 60 тактов в секунду.
Счетчик
Счетчик используется для подсчета количества входных событий. Он представляет собой сравнивающий комбинатор с соединенными входом и выходом и условием передающим значение со входа на выход. На его вход должны поступать только импульсы, иначе он превратится в таймер. Для этого обычно используется генератор импульсов.
Комбинирование стробирующего устройства, таймера и генератора импульсов позволит осуществлять удаленный опрос и подсчет содержимого содержимого удаленных структур.
Логические вентили
Некоторые логические элементы работают только с булевыми значениями, которые изменяются от 0 до 1. Другие — могут работать и с другими числами, например с 2.
Встроенные
В арифметическом комбинаторе есть операторы логических "И", "ИЛИ", "ИСКЛЮЧАЮЩЕЕ ИЛИ". Это побитовые операции, т.е. они работают с каждым битом значения представленного в двоичной системе исчисления.
Пример побитового логического "И":
Вход 1 | Вход 2 | Выход |
---|---|---|
0 | 1 | 0 |
1 | 1 | 1 |
1 | 4 | 0 |
1 | 3 | 1 |
10 | 30 | 10 |
10 | 40 | 8 |
Если на входах комбинатора булевы значения (от 0 до 1), то побитовые операции, могут использоваться как логические вентили.
Унарное НЕ
Таблица истинности:
Вход | Выход |
---|---|
0 | 1 |
1 | 0 |
Бинарное ИЛИ
Таблица истинности:
Вход 1 | Вход 2 | Выход |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
*Примечание: работает для любого количества входов. Работает как для логических входов, так и для других значений.
Бинарное ИЛИ-НЕ
Таблица истинности:
Вход 1 | Вход 2 | Выход |
---|---|---|
0 | 0 | 1 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 0 |
*Примечание: работает для любого количества входов. Работает как для логических входов, так и для других значений.
Бинарное ИСКЛЮЧАЮЩЕЕ ИЛИ
Таблица истинности:
Вход 1 | Вход 1 | Выход |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
*Примечание: работает только для булевых значений.
Бинарное И
Таблица истинности:
Вход 1 | Вход 2 | Выход |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
*Примечание: в примере на рисунке арифметический комбинатор работает с небулевыми значениями и будет возвращать небулевы значения, когда они заданы в качестве входных значений, но только если оба значения не равны 0.
*Примечание: в примере на рисунке сравнивающий комбинатор работает только с булевыми значениями. Его можно модифицировать, чтобы иметь любое количество входов, изменив «1» на число меньшее на 1 количества входов, или «2» на количество входов, как показано ниже для тернарного И.
Тернарный И
Таблица истинности:
Вход 1 | Вход 2 | Вход 3 | Выход |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 0 | 0 |
1 | 1 | 0 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 |
Бинарное И-НЕ
Таблица истинности:
Вход 1 | Вход 2 | Выход |
---|---|---|
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
*Примечание: работает только для булевых значений. Его можно изменить, чтобы иметь любое количество входов, изменив «2» на требуемое количество входов.
Бинарное ИСКЛЮЧАЮЩЕЕ ИЛИ-НЕ
Таблица истинности:
Вход 1 | Вход 2 | Выход |
---|---|---|
0 | 0 | 1 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
*Примечание: работает только для булевых значений.
Ячейки памяти
Простая защелка
Когда комбинатор заведен сам на себя, для основных входов/выходов используйте провода другого цвета.
Таблица истинности:
Выход 1 | Вход 1 | Вход 2 | Выход 1 (t+1) |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
0 | 0 | 1 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 |
1 | 1 | 0 | 1 (2) |
1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 (2) |
- Примечание: выход 1 - это обратная связь (зеленый провод на рисунке), по которой передается значения для сохранения.
- Примечание: вход 1 установлен пока вход 2 сброшен.
Ячейка для сохранения положительных чисел
На рисунке, число, которое требуется сохранить, передается на ячейку памяти посредством виртуального канала "3", сброс же происходит за счет передачи на ячейку отрицательного значения. Обратите внимание, что выход арифметического комбинатора должен быть направлен в противоположную сторону от сравнивающего комбинатора.
Представленная схема ячейки не работает при однократном вводе значения. Ввод должен удерживаться минимум 2 такта.
Ячейка для сохранения положительных и отрицательных чисел
Эта ячейка способна сохранять и положительные, и отрицательные значения. Сброс происходит по отдельной линии. Кроме того, запись значения происходит за 1 такт. Пост на форуме.
- На выходе M (memory) удерживается последнее ненулевое значение с входа I (input).
- Ненулевой сигнал R (reset) сбрасывает схему.
- Однотактовые сигналы I и R обрабатываются схемой правильно.
- Отрицательные значения тоже могут храниться.
Умножение и словари/массивы
Перемножение двух сигналов операция простая и требует всего один комбинатор, чего нельзя сказать о перемножении нескольких сигналов, схема которой представлена на рисунке. Ниже представлено доказательство, почему эта схема работает.
Словарь - это система, которая позволяет получить доступ к значению определенного сигнала из некоторого множества сигналов по ключу. К примеру, (см. на рисунок) A хранит некоторое множество сигналов (либо из постоянного комбинатора, либо из ячейки памяти), а B содержит один сигнал-ключ (например сигнал синего цвета). На выходе схемы, остается только значение из множества A соответствующее синему сигналу, т.к. остальные были умножены на 0.
Массивы похожи на словари, но вместо использования сигнала в качестве ключа, используется число. Постоянный комбинатор нумерует некоторое множество сигналов (например, значение сигнала конвейера равно 1, быстрого конвейера — 2, экспресс-конвейера — 3, твердотовливного манипулятора — 4 и т.д.). Затем используется сравнивающий комбинатор с условием (вход: каждый = индекс нужного сигнала; выход: каждый), выход которого заводится на схему чтения словаря.
Выражения доказывающие и объясняющие работу схемы:
((A+B)^2 - (A-B)^2)/4 = AB (A+B)^2 - (A-B)^2 = 4AB (A^2 + 2AB + B^2) - (A^2 - 2AB + B^2) = 4AB 4AB = 4AB