石橋を叩いて壊すページ

ゼロから始めるFactorioの回路構築(累積回路編)

前回の記事では回路から「現在の」状態を取得していろいろな判断をする回路をご紹介した。
この記事では、「過去に」入力された信号を全て累積する累積回路を使った回路をご紹介する。
ちなみに「累積回路」という名前は今決めた。軽く調べたが、適当な名前がなさそうだったからこう呼ぶことにする。

基本編 > 入力・出力・混合編 > 定数・算術回路編 > 条件回路編 > 実践例編 > 累積回路編

累積回路とは

累積回路には、今までに入力された信号を累積(合計)する機能がある。
例えばインサータには「掴んだアイテムの個数」の信号を出力する機能があるが、その信号を累積回路に入力することで、 「今までに掴んだアイテムの累積個数」がわかるようになる。
これにより、例えば「今までに100個のアイテムを取り出した」という情報を得たり、 「アイテムを100個入れるごとに列車を1回発車させる」といった回路が組めるようになる。

累積回路を作るのは簡単である。
① 算術回路を1つ設置し、その入力と出力をレッドケーブルでつなぐ。
② 算術回路に「それぞれ+0をそれぞれ出力」という式を設定する。
これで終わりである。


完成した累積回路。算術回路1個とレッドワイヤー1本で簡単に作れる。
ちなみに算術回路には電気が要るので、別途電柱を置いて電力を供給してほしい。

それでは実際に「今までに掴んだアイテムの累積個数」を数えてみよう。
インサータと累積回路を設置し、レッドワイヤーでつないでおく。
インサータの回路設定を開き「動作モード:なし、掴んでいるアイテムを取得する:✅、読み取りモード:パルス」と設定する。
インサータの周りにベルトを配置し、アイテムがぐるぐる回るようにしておく。

あとは、ベルトに適当なアイテムを載せれば実験はスタートだ。
インサータがアイテムを掴むたびに掴んだアイテムの個数が回路に流れ、 それを累積回路が累積して「今までに掴んだアイテムの累積個数」として記憶し続ける様子が確認できるだろう。


インサータがアイテムを掴むと信号が回路に出力され、累積回路に累積されていく。
算術回路にマウスを当てると、画像右上のように算術回路が累積している情報を表示できる。
この画像では、このインサータは今までに鉄板を69枚、銅板を48枚、鋼鉄を24本掴んでいることがわかる。
累積回路が正しく動いていれば、インサータがアイテムを掴むたびに掴んだ分だけ信号が増えていくはずである。
なお、もし掴んだアイテムの数と信号の増え方が一致しない場合は、インサータの読み取りモードが「パルス」になっているか確認しよう。
読み取りモード「パルス」ではインサータはアイテムを掴んだ瞬間に1度だけ信号を出力するので、 足し算も1度だけとなり、掴んだアイテムの数が正しく累積回路に累積される。
読み取りモード「ホールド」ではインサータはアイテムを掴んでいる間ずっと信号を出し続けるため、 累積回路はその間ずっと足し算を繰り返してしまい、実際に掴んだアイテム数の数十倍の数を記憶してしまう。

累積回路の仕組みは実に簡単である。
算術回路には「それぞれ+ゼロをそれぞれ出力」という式が設定されているから、 算術回路に入力された信号は元の数字+0、つまり元の数字のまま算術回路から出力される。
そして算術回路の出力がレッドワイヤーを介して算術回路の入力に繋がっているから、出力された信号は結局算術回路に戻ってくる。 これにより同じ信号がループし続けるので、信号が維持されるわけである。
そして以前の記事で説明した通り、ひとつの回路に複数の出力があると信号は足し算されるので、 算術回路とそれ以外の出力が混ざると信号が足し算され、その結果が算術回路に入力されるので、 算術回路以外から入力された値が算術回路にどんどん累積されていくという仕組みである。

ちなみに式にそれぞれが使われているので、 複数のアイテムの信号が流れてきた場合はアイテムごとにそれぞれ累積が行われる。
式にそれぞれを使わず、例えば「鉄板+ゼロを鉄板として出力」のように具体的なアイテムを指定することで、 鉄板の枚数だけを累積しそれ以外を無視する累積回路を作ることもできる。
累積をゼロに戻したい場合は、いったん算術回路を撤去し、直後に「元に戻す」(キーボードの場合CTRL+Z)で再設置すると楽である。
停電が発生しても累積値は維持されるので、ある日いきなり記憶喪失といった心配は必要ないが、 停電中は信号が入力されても累積されず無視されるので注意しよう。

以上が、累積回路の基本的な説明である。
以下では、この回路を便利に使うテクニックをご紹介したい。

これまでに打ち上げたロケットの数を数える

ある程度ゲームに慣れてきた工場長は、ロケットを1発打ち上げただけでは満足せず、2発も3発も打ち上げるはずである。
ただ、これが100発、1000発となってくると、だんだん数え切れなくなってくる。
そんなときこそ累積回路の出番である。早速、いままでに打ち上げたロケットの数を数える回路を作ってみよう。

残念ながらロケット発射台には「ロケットを発射したとき信号を出す」ような機能は存在しないので、 ここでは代わりに組立機から衛星を取り出すインサータにワイヤーを繋ぎ、「今までに組み立てた衛星の数」を数えることにする。
人工衛星はロケットに積んで発射する以外に用途がないので、あとは道端にポイ捨てでもしない限り、 「今までに組立機から取り出した衛星の数」を数えることは「今までに打ち上げたロケットの数」を数えることに等しいという理屈である。

やることは簡単で、既に上記でお見せした通り累積回路とインサータを繋ぐだけである。


人工衛星を作る組立機の取り出し用インサータにレッドワイヤーを繋ぎ、累積回路に繋ぐ。
インサータには「動作モード:なし、掴んでいるアイテムを取得する:✅、読み取りモード:パルス」を設定する。
そうすれば、組立機から衛星が出てくるたびにインサータから「人工衛星が1」という信号が出力され、 それが累積回路で合計されることで、今までに組み立てられた人工衛星の数がわかる。
数を知りたい時は累積回路にマウスを合わせれば、回路に記憶された衛星の数が画面右の情報ウィンドウに表示される。
上記画像の場合は、今までに37発の人工衛星を作ったことがわかる。

数を数えるだけなら、たったこれだけでOKである。

数字を7セグで表示する

上記で数を数えることができたが、これだけだと味気ないので、せっかくだから7セグ表示も追加してみよう。
7セグというのは「日」の字の形で0から9までの数字を表示する、いわゆる「デジタル数字」のことである。
点いたり消えたりする棒部分(セグメント)が7本あるので7セグと呼ばれている。


実際の工場での運用風景と、その簡略図。いままでに約5万発のロケットを打ち上げたことがわかる。
これだけ打ち上げたら、そろそろ地球から救助船が来てもいいころだと思うのだが…。もしかして地球滅んでる?
簡略図に合わせた建設計画はこちら

数値を7セグで表示するには、まず数値をそれぞれの位ごとに分ける必要がある。
例えば「52586」を表示したいなら、万の位は5、千の位は2、百の位は5、十の位は8、一の位は6、という具合である。

数値の位分けは、算術回路の「%」(割り算の余り)の出番である。
例えば「52586」という数字の一の位は「6」だが、これは52586を10で割った答えの「余り6」として算出できる。
よって算術回路としては、「衛星の数%10」を計算すれば一の位を得ることができる。
十の位の8は、52586をいったん10で割って「5258」とし、これを10で割ると「余り8」が得られるから、算術回路を2台使えば計算できるとわかる。
百の位の5は、同様に52586をいったん100で割って「525」とし、これを10で割ると「余り5」が得られる。千、万の位も同様である。
ちなみに、算術回路による割り算は小数点以下切り捨てなので、端数が出る心配はない。


簡略図を再掲。この図の左半分には、6台の算術回路が書かれている。
一番左の1台は累積回路で、これまでに製造された衛星の数を数えるためのもの。
その右の最上段の算術回路は、「衛星の数÷10000をという特殊アイテム信号として出力」している。
その下の算術回路は「衛星の数÷1000をという特殊アイテム信号として出力」している。 以下、も同様である。
(ちなみに一の位は1で割る必要はない。1で割っても元のままだから、累積回路の衛星の数をそのまま使えばいい。)
そして最下段の算術回路は「それぞれ」を使い、上記した信号を全部ひっくるめて10で割った余りに変換している。
こうすれば、例えば衛星の数が「52586」であったなら、は5、は2、は5、は8、衛星は6、という位ごとの数値が得られることになる。

次は、これをセグメント(直線)ごとの点灯/消灯信号に変換してみよう。これには定数回路を使う。
説明の前に、まず7セグのそれぞれのセグメントに名前を付けておこう。
ここでは、「 日 」の形の一番上の横線「  ̄ 」をセグメントAと呼ぶ。そこから時計周りに外周の各直線をセグメントB~Fと呼ぶ。
(デジタル数字の縦棒は上半分と下半分の2セグメントに分かれていることに注意。)
真ん中の横線「 ― 」はセグメントGと呼ぶ。

簡略図中央の定数回路には、からまでそれぞれ以下表のとおり信号を出力させる。

定数回路の設定
-1,212,153,856
-104,857,600
-541,065,216
-1,228,931,072
-1,568,669,696
-1,900,019,712
1,052,770,304

まるで暗号のようだが、これらの数字はなんだろうか。
電気に詳しくない人でも、「コンピューターの中では、すべてが1か0かで表される」という話は聞いたことがあると思う。
上記の値は、セグメントAからセグメントGまでの各部品を「光らせる」ときは「1」、「光らせない」ときは「0」で表したデータを、 7セグに表示させたい0から9までの10文字分つなげた数字である。
これ以上詳しい説明は省くが、重要なのはこれらの数字を「7セグに表示させたい数字」の分だけ左ビットシフトすると、 その値がマイナス値かどうかで各セグメントを「光らせるか、光らせないか」がわかる点である。
例えば「5」を表示させたい場合、の「-1,212,153,856」を左に5ビットシフトすると「-134,217,728」になるのだが、 これはマイナス値なので、「5を表示する場合、セグメントA(一番上の横棒)は光らせる」という具合である。
B~Gまでのセグメントも同様に、それぞれの信号を表示したい数字の分だけビットシフトした結果がマイナスかどうかで、光らせる/光らせないを判断できる。
ちなみに「0」を表示させたい場合は各数値を左に0ビットシフトする。 その場合各数値は何も変動しないのだが、 上記表を見るとまではマイナス値でだけがマイナスではないから、 よってセグメントA~F(=外周全部)を光らせ、セグメントG(真ん中の横線)は光らせなければよいとわかる。 7セグで外周だけが光ったらどんな数字が表示されるかを考えれば、仕組みにご納得いただけるだろう。
なお左ビットシフトは算術回路の「<<」演算子で計算できる。


再び簡略図。
万の位の各セグメント点灯計算では「それぞれ」を使い、からまでの各信号をそれぞれ万の位に表示させたいの値で左ビットシフトしている。
「日」の字に配置された各ランプは、それぞれ自身のセグメントの信号がマイナスなら光るよう点灯条件を設定しているので、計算結果に基づいてランプが光る。
ちなみにランプに色を付けたい場合は、定数回路に色信号を追加し、各ランプの「色の使用」に✅を入れておこう。

これで、今までに打ち上げたロケットの数をデカデカと表示することが可能になる。
もちろんロケット以外の数字も表示できるので、例えば蓄電池の電池残量を1%刻みで表示し、20%を切ったら数字が赤くなるようにしたりすると、 最高にドキドキする夜を過ごすことができるだろう。


せっかく思いついたので実際やってみた。電池残量50%以下で黄色、20%以下で赤になる。
色の切り替え方法は前回の記事に書いた一灯式残量表示器の応用。
ちなみに百の位は電池残量が100の時だけ光ればいいので条件回路で「電池残量=100」を判定させて手抜きした。
10%未満の時は十の位が光らないおまけつき。建設計画

寿司ベルトでアイテムを混在させて送る

累積回路の有用な使い方のもうひとつが通称“寿司ベルト”。 これは回転寿司の要領で、1本のベルトに複数のアイテムを混在させて送る技術である。

ベルトにアイテムを流すとき、量が多すぎると詰まって流れが悪くなり、少なすぎると途中で消費されて、 どちらにしてもうまく行き渡らない、といった現象は熟練の工場長なら容易に想像がつくだろう。
ではどうすればよいか。ちょうどいい数のアイテムを流せばいい。そんな時に役立つのが累積回路である。

例えば、ベルトにアイテムを3個載せたときは「+3」、ベルトからアイテムを1個取ったときは「-1」という信号を出力させる。
累積回路は今までに入力された信号をすべて累積するので、3個載せた、1個取ったという今までの増減履歴を全部累積していくことで、 現在のベルト上のアイテム数は(+3)+(-1)、つまり2個である、というような在庫把握ができるようになる。
あとはその数が「ちょうどいい数」より少ないときだけアイテムをベルトに補充する、要するに在庫管理をしてやれば、 ちょうどいい在庫状態を自動で保てるというのが寿司ベルトの考え方である。

実際の例を見てみよう。以下の図は、研究所に寿司ベルトを使った場合の例である。


ここでは1本の寿司ベルトに7種類のサイエンスパックを混載している。
寿司ベルトにパックを載せる際は、たとえば「赤パックが+3」のような信号をインサータが出力するので、 これを累積回路(画像の算術回路2)に足し算する。
寿司ベルトからパックを降ろす際は、インサータは「赤パックが+1」のような信号を出力するが、 これは画像左の算術回路1にて-1を掛けられて符号反転されるため、 「赤パックが-1」というマイナス値に変換されたうえで累積回路に足し算されることで在庫の減少が把握され、 寿司ベルト上の現在のパック数がリアルタイムで把握可能になる。
補充側のインサータには作動条件として「現在のパック数<ちょうどいいパック数」が設定されているので、 この条件がYESになったときだけ補充が行われることで寿司ベルト上のパックがちょうどいい量に保たれる。
ビーコンをなくして小さめにした寿司ベルトサンプルの建設計画はこちら

研究所は最大7種類のサイエンスパックを消費するので、通常であればベルトが4本必要になるのだが、 寿司ベルトなら1本のベルト上に7種類のパックを同時に送れるのでベルトを節約でき、見た目もシンプルにできる。
ちなみに上図で補充側のインサータが横一列ではなくジグザグに並んでいるのは、ベルトの左右にアイテムを分散させるためである。
インサータはベルトの自分から遠い側にアイテムを置くため、補充用インサータを横一列に並べてしまうとベルトの片側に7種全部のパックが載ってしまう。ジグザグに配置することでベルトの両側をバランスよく使うことが可能になる。
またこの仕組みなら同じ色のパックは常にベルトの同じ側に並ぶので、ベルトの両側に7色のパックがぐちゃぐちゃに混ざって流れる場合に比べれば見た目のカオス度が多少和らぐ効果もある。

なお寿司ベルトにおける「ちょうどいい数」は、ベルトの速さや長さ、そしてアイテムの消費速度が影響するので一概には言い難い。
実際に寿司ベルトを運用してみて、補充したアイテムの一部がベルトを1周して戻ってくる量を見極めよう。
全く戻ってこないなら足りていないし、ほとんど戻ってくるようなら多すぎる。
どんどん補充してもほとんど戻ってこないようなら、ベルトの速度を上げるかプラントの規模を小さくすることを考えよう。
いずれにせよ、プラントの稼働開始直後は大量にアイテムを消費するし、安定稼働に入れば消費速度は低下するし、 プラントが一斉に動き出した場合はあるタイミングでアイテムが一斉に消費されるなど減り方にムラがあるかもしれないので、 短期的な見た目ではなく様子を見ながらゆっくり寄せていく感じで調整するのがよいだろう。

注意点として、工場長は寿司ベルトから直接アイテムを取りあげないようにしよう。
インサータと違って工場長はレッドワイヤーに繋がれていないので、 工場長がアイテムを拾ってもそのことが回路に伝わらず、取り上げたアイテムの数はそのまま在庫誤差として残り続けてしまう。


ちなみにこの画像の左側のように、インサータを使わずベルトだけで寿司ベルトを作ることもできる。
ただしこれには、停電時に正しく動作しなくなるという欠点がある。
停電が起きると算術回路が計算をしなくなるので、たまたま補充中(ベルトが稼働中)に停電が起きると復電までベルトが動きつづけて補充が続いてしまい、ベルトにアイテムが溢れかえってしまう。
インサータでアイテムを補充する場合は停電するとインサータ自体が止まるので、アイテムが溢れることはない
ちなみにベルトを使う場合、アイテムを補充するベルト(動く/止まるを切り替えるベルト)と、補充されたアイテムの数を数えるベルトを共用ないし隣接させるとカウントが正しく行われないようで、 時間と共にだんだん数字がずれていってやはりアイテムが溢れかえるため、上記画像ではこれらを1マス開けた別のベルトで行う対応を取っている。

基本編 > 入力・出力・混合編 > 定数・算術回路編 > 条件回路編 > 実践例編 > 累積回路編

この記事を評価

この記事にコメント

  1. ...

【この記事にコメント】
お名前:
コメント:

Menu