SVX日記
2023-05-05(Fri) 割合生産するFactorio
Factorioを始めて、しばらくして気づいたのが「ベルトに複数のアイテムを混在させて運ぶと詰まってしまう」ということだ。それを防ぐには「ベルトに複数のアイテムを混在させない」ことだ。そうすれば「消費が遅く、生産能力が過剰」か「消費が早く、生産能力が不足」のどちらかにはなるものの、詰まってしまうことはなくなり、人手を介入する必要はなくなる。ここ数日はそれを目指して、赤色、緑色、灰色のサイエンスパックの量産ラインを完成させてきた。
ちょうど近くまで鉄鉱石を運ぶベルトが延びており、その片側が空いていたため、それを活用し、プラスチック棒と硫黄を混在して運ぶことにした。しかし、それをすると、どうしても詰まってしまうのだ。新たにベルトを敷けば済むのだが、どうにかする方法はないものなのかと。
両アイテムが常にチェストに補充される状態にして、何らかの方法で必要な割合で取り出せるようにしたら? と思ったが、チェストの容量は有限なので、生産を抑制しない限りどちらかが余り、いつかはチェストの容量の上限に達してしまう。つまり、必要な量しか、組立機や化学プラントから取り出さないようにしなければならないことになる。今回の目標は、プラスチック棒と硫黄を6:1で取り出し、供給することだ。
そうなるとインサータの制御は必須なので、回路を組むのが必須になる。ループするベルトの上に取り出したいアイテムを見本として置き、それをベルトに検知させて、インサータに取り出させてはどうか? と思ったが、これもダメ。ベルト上をアイテムが通過するのには一定時間を要するし「消費が遅く、生産能力が過剰」な場合、ベルト上にアイテムが滞留し、インサータの動作回数が制御できない。パルスで動作をトリガする必要がある。
やり方を思いついては、試してうまく動作せず、の繰り返し。数十時間を費やしても実現できない。回路も組めるプログラマとして、プライドはズタズタだ。どうやら、変数がなかったり、論理演算にクセがあったり、コンデンサのようなタイマがなかったりと、Factorioの回路を、既存の概念の範疇で捉えようとすることが誤りのように思えてきた。
そして気づいたのが「赤い*」のAND動作のクセだ。%演算子でループするカウンタを作ったまではいいのだが、それを「赤い*」に食わせると意図しない動作になってしまう。散々アレコレやっているうちにようやく気づいた。「ゼロは偽ではなく、無信号だ」ということ。別の言い方をすると「ゼロは、ANDに偽の信号を入力するのでなく、信号線そのものを外す動作となる」ということだ。
これに気づいたらだいぶ進捗した。ゼロを使わないようにすればいい。定数回路を使って、ゲタを履かせてやればいい。真偽はn>9で判定するようにし、ループするカウンタは10〜15で常に真、パルスは9と10を発生させて一瞬だけ真を発生させる。そのANDを取れば、10〜15の値がパルス出力される。それをインサータに入力し、動作条件をn>9とすれば6/6動作。n>14とすれば1/6動作となる。そいつを合流させれば6:1でアイテムを流せる。
パルスの発生にはループ状のベルトの上に載せた石炭と石を使う。アイテムの消費が遅くベルトの先が詰まった場合には、ベルトに検知させてループ状のベルトの回転を止め、パルスの発生自体を遅延させる。これでようやく期待する回路を組むことができた。そこそこシンプルな形で。