MinecraftのRD回路で加算器作ってみた

## 挨拶
オッス、メッス。

この記事は [SLP KBIT Advent Calendar 2022](https://adventar.org/calendars/7569) 19日目の記事です。今回はタイトルの通り、Minecraftに実装されているレッドストーン(RD)回路を使って計算機（4bit加算器）を作りました。プログラミングとは関係ありませんが、たまにはいいでしょうという事で、ネタ枠として読んでいただければ幸いです（ちなみに論理回路を履修している１年生は必見やぞ！読め！）
## 2進数の足し算（半加算器）
（ページの都合上）詳しくは解説しませんが、ざっくりと説明すると
```
0 + 0 = 00
0 + 1 = 01
1 + 0 = 01
1 + 1 = 10
```
が2進数の足し算（繰り上げ無し）です。ここで、1の位に注目してみましょう。
```
入力値A   入力値B   1の位
   0        0        0
   0        1        1
   1        0        1
   1        1        0
```
ちなみにこのような表を真理値表といいます。

さあ、この表を見て何を思い浮かぶでしょうか。
そう、「XOR演算」ですね。
つまり
「1の位は入力値のXOR演算で表現できる」
ということです。

次に、2の位に注目してみましょう。
```
入力値A   入力値B   2の位
   0        0        0
   0        1        0
   1        0        0
   1        1        1
```
さあ、この表を見て、何を思い浮かぶでしょうか。
そう、「AND演算」ですね。
つまり
「2の位は入力値のAND演算で表現できる」
ということです。

↓半加算器の回路図
![01_hankasan2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/07bdf816-0560-4af0-13ec-3f0affa6f3f9.png)

## 2進数の足し算（全加算器）
上記のXOR回路とAND回路を組み合わせることで事実上計算機（半加算器）を作ることは可能ですが、半加算器だと桁上がりを行うことが出来ません。

なので今度は桁上がりが出来る「全加算器」を考えましょう。
```
0 + 0 + 0 = 00
0 + 0 + 1 = 01
0 + 1 + 0 = 01
0 + 1 + 1 = 10
1 + 0 + 0 = 01
1 + 0 + 1 = 10
1 + 1 + 0 = 10
1 + 1 + 1 = 11
```
長々と書きましたが、簡単に考えると入力の結果は
```
00
01
10
11
```
の4つを取ります。
```
入力値の1の個数が
合計0個 => 00
合計1個 => 01
合計2個 => 10
合計3個 => 11
```
と受け取ることもできます。
この全加算器を実現するには、筆算を考えると楽ちんです。

まず、入力値の変数をそれぞれ
```
入力値
X + Y + C = ???
```
とし、先に
X + Y
演算を行います。

これは先ほどの半加算器で演算できますね。

次に、X + Y から得た値と C の加算を行います。

これも結局、半加算器を使って実現します。

つまり、全加算器は半加算器を2つ用いることで作成可能であるのです。

また、X + Y の取り得る値は
```
00
01
10
```
の三つです。

このとき、このX+Yの1の位と C の値を次の半加算器の入力値とします。
その加算も
```
00
01
10
```
の三つの結果を返します。 C の入力値は0か1であるので、X + Y の出力個数が3個（00、01、10）であることより、最終的な結果の個数は 2 × 3 = 6 個です。以下にその結果をまとめます。
```
「」の中だけを演算する。その演算結果は「」の中に表現する
(X+Y) +  C  = 左辺の「」の演算結果を右辺の「」の中に表現
左辺の X+Y の1の位は「」で囲んでいる。
（1の位のみを演算するから）

0「0」+「0」= 0「00」 -> 全体的に00になればうれしい
0「0」+「1」= 0「01」 -> 全体的に01になればうれしい

0「1」+「0」= 0「01」 -> 全体的に01になればうれしい
0「1」+「1」= 0「10」 -> 全体的に10になればうれしい

1「0」+「0」= 1「00」 -> 全体的に10になればうれしい
1「0」+「1」= 1「10」 -> 全体的に11になればうれしい
```
右辺の値にて、2の位と「」の中の2の位を比べて、最終的な値を出力します。
まさに筆算の時の桁上がりの考え方と一緒ですね。
上の演算結果を真理値表に直してみると
```
X+Yの2の位   (X+Y)+Cの2の位   最終的な2の位
    0                0             0
    0                1             1
    1                0             1
    1                1             1
```
さあ、この表を見て、何を思い浮かぶでしょうか。
そう、「OR演算」ですね。
つまり
「最終的な2の位は、それぞれの2の位のOR演算で表現できる」
ということです。

↓全加算器の図
画像では最初の入力値はXとYとC'ですが、上記の説明ではXとYとCであることに注意
![02_fulladder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/9a88cbb1-8e05-2375-0ad5-c6d3f93cf077.png)
## もっと項を増やす（全加算器の組み合わせ）
もちろん、全加算器を複数組み合わせることでさらに項を増やした演算を行うことが出来ます。
先ほど全加算器の解説にて「筆算を考えると楽ちん」と述べましたが、新しく半加算器を追加する際も桁が一つずれた場所に全加算器をどんどん設置することによって表現することが可能です。
![03_fulladder2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/553cf527-9561-066a-75a3-da91e1d792d2.png)
以上で論理的な説明を終了します。
ではお待ちかねのMinecraftを起動しましょう。
## Minecraft上での回路の動作
まずON・OFF機能のみのもっとも単純な回路です。
![01_onoff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/68c54a11-4086-bdd0-a429-4d495fb369c2.png)
上の状態ではレバーはOFFです。ONにしてみましょう。
![02_on.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/a6fe6bb7-e8d4-5343-821a-463e70d5ce99.png)
明かりがつきました。スイッチをONにすることで、赤色の導線に動力が渡されます。そしてその動力はランプに伝わり、明かりがつきました。赤色の導線は複数に分岐させることもできます（OR回路の実現）。赤色の導線をRDといいます。RDはON、OFFの二つの状態があり、動力に流れは存在しません。

次にNOT回路の紹介です。
![03notoff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/bb9b3c37-0fcd-2f77-8741-b4c2b60d5de5.png)
赤色のたいまつはRDトーチといい、常に動力を発しています。逆にRDトーチに動力を渡すと、RDトーチは動力を発しなくなります。つまり、スイッチによってRDトーチに動力を渡すことでNOT回路を実現しています。スイッチをONにしてみましょう。
![04noton.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/5db69e2c-5eb9-5511-976e-31ffb7752082.png)
手前のランプがついたのでスイッチのONが確認されましたが、奥のランプは消えました（トーチに動力が伝わり、常にONであるトーチがOFFになった）。

次にOR回路です。
![05or.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/dcaf36c2-ef49-423c-cb73-5a7d5b960f9d.png)
RDをつなげることで簡単にOR回路を実現することが出来ます。
入力値
0   1
![0501.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/b89de784-d298-489e-cfad-a8c92911082e.png)
入力値
1   0
![0510.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/7a755dba-33ad-135e-1fe3-97b6bf21ce16.png)
入力値
1   1
![0511.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/8251266d-9a43-c2ce-0341-7fa5402976cb.png)
次にAND回路です。

OR回路とNOT回路を組み合わせて実現しています。

入力値
0   0
![0610.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/8d075444-a9c7-858d-2095-066019f33b1d.png)
入力値
0   1![0601.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/88af7570-b7d2-78b7-2542-112565974b36.png)
入力値
1   0![0600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/78c76f40-12f2-c6cb-422a-4fd3b3aed537.png)
入力値
1   1
![0511.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/df645adb-df77-ea21-a99f-24dad75169bd.png)
次にXOR回路を紹介します。

XOR回路はAND回路とNOT回路を組み合わせて実現しています。
入力値の例は省略。
![07xor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/3af06a2c-3d9a-b08a-8c1a-85d0cdf81697.png)
そしてXOR回路とAND回路を組み合わせた半加算器がこちらです。
```
↓ 0 + 0 = 00
```
![08halfadder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/487399a0-a345-d7b9-e8c4-eff12cea9bdb.png)
```
↓ 0 + 1 = 01
```
![0801.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/661e28a7-3a97-f001-677c-becf57cb6c3b.png)
```
↓ 1 + 0 = 01
```
![0810.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/c8562dd8-4809-3e99-c670-a6b62025f631.png)
```
↓ 1 + 1 = 10
```
![0811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/7122c2a0-3300-91ce-3f9d-0576481d290a.png)
更に半加算器を二つ組み合わせた全加算器がこちらです。
```
↓ 0 + 0 + 0 = 00 （XOR回路が違うのは触れないでっ）
```
![09full000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/dee29d57-eac3-9805-6af9-a1317a78bfe9.png)
```
↓ 0 + 0 + 1 = 01
```
![09001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/844af599-32d9-a888-5eb2-55a5ebcfa2ae.png)
```
↓ 0 + 1 + 0 = 01
```
![09010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/5fee4505-9498-af1b-b591-fb55628f143d.png)
```
↓ 1 + 1 + 1 = 11
```
![09111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/d1438576-7f5d-60bd-05a2-6f88dad174c8.png)
## アホみたいに時間かけて作った4bit加算器がこちらです！！！！！！
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/56db58c0-11a5-dbf0-c383-7c0db31e05fb.png)
緑が半加算器、青が全加算器になっています。
さっそく演算してみるぞ！！！！
```
5 + 9 = 14
つまり
0101 + 1001 = 01110
```
![1014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/9c034e14-4cdf-0232-6271-657bf0dab451.png)
```
8 + 2 = 10
つまり
0100 + 0010 = 00110
```
![1010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/b2c06168-e4ea-6e45-5c8b-ad2d949b9fb0.png)
### できたああああああああああああああああ！！！！！
（つかれた）

## エンコーダとデコーダ
ええっと、無理です。つかれた。計算機を無事作ることが出来ました。
ので、もういいでしょ。
一応その頑張った努力の証だけ残しておきます。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2384147/5d83866b-f54a-fd4f-4215-6371564eaf15.png)
ちなみに
エンコーダとは10進数を2進数に変換する回路のことで、
デコーダ  とは2進数を10進数に変換する回路のことです。
## 感想
本当はね、加算だけでなく減算とか乗算除算もやりたかったんです。でも、これは無理や。気が狂いそうになる。ディスプレイも作ってコンピュータっぽくしたかったけど、そんな鋼の心を持ち合わせてはいません。

あと入力箇所にもランプを設置してどの数字が入力されたか見やすくすればよかったなぁ。

ちなみにyoutubeに投稿されている動画では、RD回路で疑似量子コンピュータを実現させているニキもいます。すごいですよねぇ。
## おわりに
マイクラでコンピュータを作るのはお勧めしません。
強靭な精神を持ち合わせていない限り、心が壊れます。
是非皆さんは健全なゲームライフを送ってください。

皆さんは年末どのようにお過ごしになるでしょうか。
自分はAbemaで12/30に一挙放送されるゆるキャン△2期がとても楽しみです。この作品の一挙放送は毎年しているので、毎年見てます。みんな見ようね。ちなみに1期の放送は終了しました。

それでは良いお年を～～～～～。

ps. ギリギリ記事が25日に間に合わなかった、悔しぃいいいいい！！！！