mikecat が 2022年12月11日23時54分18秒 に編集
初版
タイトルの変更
【CalicoCPU】爆弾ゲーム
タグの変更
CalicoCPU
ゲーム
メイン画像の変更
記事種類の変更
製作品
ライセンスの変更
(CC BY 4+) Creative Commons Attribution CC BY version 4.0 or later
本文の変更
++[自作CPU Advent Calendar 2022](https://qiita.com/advent-calendar/2022/diycpu) 11日目++ [CalicoCPU](https://elchika.com/article/f38275fc-1f46-4e77-bc30-c172971ecf0f/) で動作する爆弾ゲームを作った。 # 爆弾ゲーム 爆弾の前にスイッチが何個か並んでいる。 そのうち1個だけ、押すと爆弾が爆発するスイッチがある。 * 複数人で遊ぶ場合 * まだ押されていないスイッチを順番に1個ずつ押していく。 * 爆弾を爆発させた人が負け。 * 1人で遊ぶ場合 * スイッチを押していく。 * 爆弾を爆発させたらゲームオーバー。 * 爆弾を爆発させずに押していないスイッチを1個だけにできたらクリア。 # Octet Switch Board |![Octet Switch Board](https://camo.elchika.com/40a48b4d29d79c23a9e03dd94cf2d155742784f2/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f34323336376365652d363839362d346364612d396134612d3433343133383638326635342f35343134616634332d376561662d343434372d623365312d623964623563313664666562/)|![Octet Switch Board 回路図](https://camo.elchika.com/1b74a08cd70e9802a7c5e2d0b7a8036fe021d6da/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f34323336376365652d363839362d346364612d396134612d3433343133383638326635342f34313631306165332d623035332d343461652d616531392d343431306565653865333363/)| |---|---| [基板設計データ](https://github.com/mikecat/hardware_cpu/releases/tag/20220310-boards-v1.0) 8回路のディップスイッチで8桁の入力をする。 2進数を入力しやすいよう、ビットの対応は右から左になっている。 # 爆弾ゲーム ## 使い方 1. レジスタを見ると爆破スイッチの位置がわかってしまうので、レジスタの表示を隠す。 2. PORT0の下位ビットに [2-way Buzzer Board](https://elchika.com/article/c55891ed-5a5f-4355-bf36-8a9f5ca6cd37/#h_2-way%20Buzzer%20Board) を、PORT1に Octet Switch Board を接続する。 3. プログラムを実行する。「初期化中」を表すled1が点灯する。 4. PORT1の入力を非0にする。爆破スイッチの位置の抽選が行われる。 5. PORT1の入力を0にする。爆破スイッチの位置が決定し、ゲーム開始となる。 6. PORT1に接続したスイッチを1個ずつONにしていく。 7. 爆破スイッチをONにすると、「爆発」を表すled2が点灯し、ブザーが鳴る。 ## プログラム [MikeAssembler](https://mikecat.github.io/mike_assembler/) でアセンブルできる。 ``` target calico ; PORT0 の0ビット目(ブザー)、2ビット目(初期化中)、3ビット目(爆発)を出力にする MOVI A, 0xD DRIVE 0, A ; 初期化中をHIGHにする MOVI A, 4 OUT 0, A ; PORT1 の入力がゼロでなくなるまで待つ MOVI C, init_wait_nonzero MOVI D, init_wait_zero init_wait_nonzero: IN B, 1 JNZ B, D JNZ C, C ; PORT1 の入力がゼロになるまで、爆破スイッチの位置をルーレットする init_wait_zero: ADDI A, 1 IN B, 1 JNZ B, D ; ルーレットの結果(Aレジスタ)を爆破スイッチの位置(Bレジスタ)に変換する MOVI B, 1 MOVI D, init_no_shift_1 MOVI C, 1 AND C, A JNZ C, D SHL B, 1 init_no_shift_1: MOVI3 D, init_no_shift_2 MOVI C, 2 AND C, A JNZ C, D SHL B, 2 init_no_shift_2: MOVI3 D, init_no_shift_4 MOVI C, 4 AND C, A JNZ C, D SHL B, 4 init_no_shift_4: ; 初期化中表示をLOWにする MOVI A, 0 OUT 0, A ; PORT1の爆破スイッチの位置がHIGHになるまで待機する MOVI C, explode MOVI D, game_loop game_loop: IN A, 1 AND A, B JNZ A, C JNZ D, D explode: ; ブザーと爆発表示をHIGHにする MOVI A, 9 OUT 0, A MOVI C, explode_end explode_end: JNZ C, C ``` 以下は、アセンブル結果のHEXデータである。 ``` :100000002D162412A6E9585F9B31585F61E5C3A104 :10001000828A9F45E7C300A2828A9F43E9C300A466 :10002000828A9F472012A387E3C7FB1806021BDFC3 :060030002912A387B59B15 :00000001FF ``` ## 実行結果 @[youtube](https://www.youtube.com/watch?v=nAE9cI5ERMI) ## 反省点 ディップスイッチは人間の手による操作がしにくく、中途半端に一旦ONになるなどの誤操作が発生した。 トグルスイッチなどの操作しやすいUIを用意したほうがいいかもしれない。