とりあえず触ってみる所から始める、『SHENZHEN I/O』

実際にアセンブリを書く『SHENZHEN I/O』というパズルゲームがあります。
自分の回りでは非エンジニアのプレイヤーも日々増えていて、スコア画面が賑っていて大変嬉しいです。
![header.jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/fea2d1aa-7ec8-6a23-75c1-b1c6ed4cc455.jpeg)
[Steam：SHENZHEN I/O](http://store.steampowered.com/app/504210/)

しかし、プログラムに触れた経験が無い場合、ゲーム開始のとっかかりを得れなくて1問目に立ち向かう前に頓挫してしまう事もあるようです。
特に英語の PDF 資料にまず目を通さねばならない点は非情に高い障壁である為、
「 pdf 資料とかいいからとりあえず最初の問題を触ってみよう！」という主旨で このような記事を執筆しています。
※この記事は非エンジニアの方に向けたものなので、エンジニアの方には簡単すぎるかもしれません。
※また 英語版 pdf にはストーリー部もあり面白いので、余裕が出たら一度読んでみる事もお勧めします。


###まずは1問目
[ゲームサイトのレビュー](http://www.famitsu.com/news/201609/13115488.html)にて
>30ページ長のマニュアル（PDF）を読みこなしてデータシートやリファレンスガイドを把握し

というような事が記載されているのもあり、まずゲームを開始して資料に目を通してみる事になるかと思うのですが
書かれているものが何を意味するのか、何を目的としているのか、が分からなければ眠くなってしまうだけです。

なのでまずゲーム画面内のメーラーを起動して、最初の仕事にとりかかってみましょう。

![20161023154531_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/2da5c96a-1398-f97f-69cf-d2da2b533343.jpeg)
頭に！マークのついたメールが、攻略対象となるメールである事を表しています。
最初の問題は『SECURITY CAMERA(FAKE)』というものですね。

メール本文を読む事でどんな依頼かが詳しく分かりますが、クリアに必要な条件だけなら先の画面でも確認可能な為、
英語が読めない人は右下の『OPEN IN CONCEPT CAD』をクリックしてさらっと先に進んでしまいましょう。[^0]
[^0]: 僕も英語が読めませんが、せっかくなので機械翻訳サイトに入力して読んでいます。 背景のストーリーも知れるとより楽しいですね。
&nbsp;


『OPEN IN CONCEPT CAD』をクリックすると設計ソフトウェアが起動します。
CAD とは computer-aided design の略で、コンピュータで設計図などを作る場合に使われるソフトの事です。
どちらかというと、建築や航空機、車など他分野で使われているものの方が有名かと思います。

このゲーム内で利用する CAD ソフトウェアは電子回路を設計する為に特化したもので、プレイヤーが一番見る画面が この CAD の設計画面という事になります。
さて、デフォルトで空のデザインが1つ作られているので、そちらを開いてみましょう。
画面右側の『NEW DESIGN 1』(新規デザインファイル1)をダブルクリックしてください。

### サンプルコードを読み解く

![20161023154551_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/44123ec9-433a-caa7-f6c3-29c8e2ca5296.jpeg)

なにやらプログラムのようなものの書かれた回路が中央に配置された画面に遷移しました。
これが設計画面です。

画面下部には何やら英文が書かれていますが、これが先程のメールで求められていたもの要約したものとなります。
機械翻訳に頼りつつ整理してみると。

![20161023154551_1 - コピー.jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/07f5d0f6-6b69-6e30-3f36-8b7258b16df2.jpeg)
>○偽の監視カメラ
・active と network は LED に接続された、単純(simple)な出力です。
・active と network の出力を制御します。　検証(VERIFICATION)タブに示されているように信号を繰り返します。

となります。
すぐ左に検証(VERIFICATION)タブがあるので開いてみましょう。
なにやらよく分からない線が描かれていますが、これがお題にある実現すべき信号を示しています。
線にマウスを重ねてみると、マウスで指した部分の予想(Expected)される信号が0であったり100であったりするのが分かります。
![20161023163939_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/cb30838a-f8b4-22c6-ba23-e21e05fe1f46.jpeg)


とはいえ、この段階では何もとっかかりがなく、何から手をつけていいか分からないと思いますが、
この1つ目の依頼には、サンプルとして1つの回路が既に配置されています。
![20161023154551_1 - コピー (2).jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/1988793d-9014-44a8-9c68-9b41fbadc08c.jpeg)


これですね。
プログラムが書かれた箱から線が伸びており、active と書かれた丸に繋がっています。

メールを見ると分かりますが、自分の前にこの仕事に当たったエンジニアが途中まで作ったもののようです。
>why is this so hard? :(

「何でこれこんな難しいの？(-_-)」とコメントが残されている所から察するに、彼はアセンブリ言語を使いこなすには至らないまま退職したようです:([^comment]
[^comment]: プログラムの中で冒頭に # が付いたものをコメントと言い、プログラム的に意味を無さないメモとして利用できます。
&nbsp;

このサンプルを動かしてみましょう。
記述されたコードは、画面左下の再生ボタンのようなものを押せば動かす事ができます。
![20161023154551_1 - コピー (3).jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/e573b109-6391-97ff-26d9-7a6fe9e38076.jpeg)

まずは一番下の黒い三角形が3つ描かれた SIMULATE というボタンを押してみましょう。[^1]
[^1]: 再生後は下のスライドで速度を調整したり、最初に戻すリセット(RESET)、途中で止めるポーズ(PAUSE)が利用できるので 速すぎて見逃した場合は何度か再生してみてください。

[![https://gyazo.com/bdb8d30219e87e78f0a7d32c17d88f7b](https://i.gyazo.com/bdb8d30219e87e78f0a7d32c17d88f7b.gif)](https://gyazo.com/bdb8d30219e87e78f0a7d32c17d88f7b)

active 欄の上下する信号が動作し、右のカメラの赤い LED が点滅している事が分かります。
しかし下の network 欄の信号は ずっとまっすぐ動いている為、お題の薄い橙色の信号とズレた所は赤で「間違い」を示されており、右のカメラの青い LED も点滅しません。
なぜならば中央の回路図において、下段の network には何も信号が繋げられていないので、ずっと出力が変更されないままだからです。


次に中央の回路と信号に注目しながら、黒い三角形が1つ描かれた ADVANCE というものを何度か繰り返し押してみましょう。
押す度に信号が少しずつ進み、それと同時にプログラムの特定の行が選択されたかのように明るくなるのが分かるかと思います。
これは現在実行している行を表しています。
プログラムは最後の行に達すると最初の行に戻り、繰り返し実行されていきます。


では実際にプログラムが何をしているのか見てみましょう。
```
mov 0 p0
  slp 6
  mov 100 p0
  slp 6
```

この4行のプログラムコードのうち、各行の左端に書かれている mov,slp が動作を指示する為のプログラム命令文です。
つまり、サンプルで使われているプログラム命令の種類はたった2つです。

30ページのマニュアルを読み通さなくても、この2つの命令を知る事ができれば何をしているのか理解する事ができそうです。
このタイミングになって始めてマニュアルを開いてみましょう。
pdf マニュアルの15ページ『Basic Instructions』(基本的な命令)の項にこの2つの命令が記載されています。

やはり英語はちょっと……という方は、steam コミュニティのガイドページに有志の方が翻訳版を公開してくださっているので、そちらを読む事をお勧めします。
※くどいようですが、マニュアルにはストーリーテキスト等も載っている為、余裕があればそちらも読まれる事をお勧めします。

[Shenzhen I/O 日本語リファレンス・マニュアル](http://steamcommunity.com/sharedfiles/filedetails/?id=779368889)


原文と併記して抜粋すると

>・mov R/I R
第1オペランドから値をコピーして第2オペランドへと格納します。
Copy the value of the first operand into the second operand.

「オペランド」が何なのかは、翻訳された方が冒頭でも解説されていますが
命令文の後に半角スペースで空白を開けて書かれている各項目の事で、
その命令を実行する対象や、その命令に渡す数字などが入ると思っておいてください。


このマニュアルの記載を元に、サンプルプログラムの1行目と3行目の意図を読み解くと
> mov 0 p0
mov 100 p0

第1オペランドで指定された数字(0,100)の値を第2オペランド(p0)へとコピーする。
と読み替える事ができます。
mov とは move(移動) の略称であり、指定した値を指定した先に移動させる というような意味なのですね。


ここで回路をもう一度見てみると、p0 とはプログラムの書かれた箱の外側、左下に書かれており、
その p0 と active が線で繋がれている事が分かります。

一度リセットしてから、再び ADVANCE ボタンを押して進めてみましょう。
プログラムが mov 命令に差し掛かった時、信号の値が0から100に変わっているのが分かるでしょうか。
つまりこの命令で繋がった p0 を経由して信号の値を書き換えているのです。


では次にもう1つの slp 命令について見てみましょう。

>・slp R/I
オペランドで指定されたTUだけスリープ状態にします。
Sleep for the number of time units specified by the operand.

TU とは time units の略で、ADVANCE ボタンを押した時に進む1回分の時間の事です。
実際のプログラム環境ではこれが 何万分の1秒とかだったりするのですが、
このゲームをプレイする上では実際の時間は気にせず、slp 1 で信号が 1 ステップ進む と考えてしまって構いません。[^2]
[^2]: ゲームを進めていくと もうちょっと複雑になっていきますが、今はこの考え方で十分です。
&nbsp;
さてでは一度リセットして命令文にさしかかった時の信号の動きを見てみましょう。
今度は自身が ADVANCE をクリックする回数にも注意してみてください。

自身が6度クリックする間、プログラムが進んでいないのが分かるでしょうか？
slp とはすなわち Sleep(眠り) の事であり、プログラムを指定した間眠らせる為の命令文なのですね。


### 自分で書いてみる
さて、ここまででサンプルプログラムに書かれているものが、どうやって信号を実現しているかが理解できました。
では今度は、自分の手で network LED の信号を作り出してみましょう。

前身のエンジニアは network LED の出力に繋がる回路を作ってくれていない為、まずはプログラムを書く前に回路を完成させる必要があります。
ただし難しく考える事はないです。
目の前に調度いいサンプルがあるので、右のメニューからパーツを選び、ドラッグアンドドロップで回路上に配置して、p0 と network を線で結ぶだけです。
![20161023171949_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/a0cb5bf0-9a61-ff92-a73c-31e8b1787577.jpeg)
まったく同じですね。

さて、次に再現しなければならない信号を見てみましょう。
![20161023154642_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/78375/841e650c-4163-5c32-2aff-d738bd31322a.jpeg)

録画中を示す赤い LED と違い、ネットワーク通信を偽装する為 ランダムに点滅する とメールには記載されていましたが、
実際には2つの長さの点滅が繰り返されているだけです。

つまり slp で指定する待ち時間の長さが 6 ではないだけで、0 と 100 を mov で設定する事に違いはないのです。


さて、この記事は答えを教える為のものではありません。
しかし、ここまでで覚えた2つのプログラム命令を使えばこの信号を再現できる事が分かるはずです。

ここからはあなたが自らがエンジニアとなって仕事を完了させる時間です。

さぁともに深センで楽しい労働に勤しみましょう！

[![https://gyazo.com/bc9960953b3171ef08a98e03c9c47c8c](https://i.gyazo.com/bc9960953b3171ef08a98e03c9c47c8c.gif)](https://gyazo.com/bc9960953b3171ef08a98e03c9c47c8c)

※SIMULATE ボタンでテストを開始し、8つ連続でテストをクリアすると、1問目をクリアとなります。


##最後に
ここまで読んでいただきありがとうございました。
非エンジニア向けの入門記事として書きましたが、自分自身がエンジニアな為十分な解説が出来ているか判断ができません。
もし「この部分が何の事だか分からない」等があれば、コメントなり twitter にてご指摘頂けると助かります。

余力があればチュートリアルの範囲だと思うので、3問目くらいまでは解説したいと思っています。
(がライバルプレイヤーが私の作った回路より低消費電力での回路を実現してきた為、しばらく深センでの缶詰が続くかもしれません……


どーゆー風に遊ぶのか、というとっかかりを与える事が目的であった為、簡略化して伝えてはいますが
ここから先に進む前に、日本語訳されたものでいいので、一度マニュアルの「基本的な命令」「算術命令」「Test命令」の3ページに目を通す事をお勧めします。[^xbus]
[^xbus]: 6問目「RUBBISH AUDIO THING」あたりから マニュアルの冒頭にある simple I/O と xBus の違いについても理解が必要になってくるかもしれません。
&nbsp;
現段階で理解する必要も、全てを覚える必要もありません。
ただ「どーゆー事が出来る命令が存在するのか」をふわっとでも認識しておく事は、この先の問いに進んでいく上で役立ちます。
他のゲームの説明書だって、最初に読んだ全ての情報がいきなり求められるという事はないのですから。[^3]
[^3]: え、説明書なんて読まない？
&nbsp;
この記事内で示したプログラム命令セットは mov slp の2つですが、マニュアルに記載された命令セット全てでも15個しかありません。
また、「～以上」か「～以下か」 といった似た機能の命令も多い為、実際に指示できる命令の種類は恐ろしく少ないのです。

しかし、その少ない命令文を組合せる事で、どんな信号だって作り出せる、それがプログラミングの面白い所であり
このゲームのよくできている所だと思います。


※執筆段階で『SHENZHEN I/O』は早期アクセスゲームでのリリースである為、今後解説内容とは異なる内容に変更される可能性があります。