新歓ブログリレー2021 7日目の記事になります。
こんにちは、20Bの @dan_dan です。traPでは競技プログラミングとグラフィック系の活動をマイペースでやっています。
ところで、今日(記事の公開日)は Fizz/FizzBuzz ですね!
なんのこっちゃ・・・となる人も、なるほどね~という人もいるはずですが、これが今回のテーマになるので、まずは「FizzBuzz」の説明からしてみます。
FizzBuzzとは
海外生まれの、シンプルな言葉遊びゲームです。
1から順番に整数を言い合っていきます。ただし、それが3の倍数だったら「Fizz」、5の倍数だったら「Buzz」、両方に当てはまったら「FizzBuzz」と叫びます。間違えたり、詰まったりしたら敗退。一人ぼっちでも結構ですが、 多めの人数で楽しむのが推奨されています。
そんなFizzBuzzゲーム、プログラミングの業界では、「for文(線形探索)」と「if文(条件分岐)」という、基本にあたるアルゴリズムを試す目的で使われているんだそう。
こちらが、Pythonという言語で書いた、FizzBuzzの流れを表現するためのコード(コンピュータへの指示文)です。
プログラミングに興味のある皆さんのために、軽く解説を。
- 変数i
変数というのは数字や文字をぶちこむ箱のような概念です。その名前をiにしました。 - for文
後ろに書いてある操作を、何回か繰り返すように指示するものです。ここでは、1から始めて、変数iに入れる数字を31の手前まで増やしながら(つまり、30回)繰り返す旨が記されています。 - if文
「この数字は3の倍数かな、5の倍数かな」と判断してもらうための文。条件分岐と呼ばれる。
i % 3 == 0 というのは、iの数字が3で割り切れる事を意味します。
ここでは、3でも5でも割り切れる場合と、3だけで割り切れる場合、5だけで割り切れる場合を分類します。
さらに、いずれにも当てはまらない場合を「else文」で表現します。 - print文
カッコ内の文字か、変数に入っている数字を「叫び」ます。出力と呼ばれる。
3の倍数、5の倍数をさっきのif文で分類したので、ルールに従って出力させます。(3でも5でも割り切れない場合は、変数iの中の数字を叫ぶのでしたね。)
実際に試してみたい人は、paiza.ioというwebサイトにアクセス。コードをタイピングして実行してみましょう。文頭を下げるにはtabキーを使います。
Minecraftとは
説明するまでも無く、Mojang社が開発した大人気ゲーム。立方体のブロックでできた世界を冒険したり、あるいは建築・施設を思いのままに創ったりできます。
さて、マイクラには「レッドストーン」というアイテムがあり、繋げて信号を伝達したり、モノを動かしたりに使われます。付随する装置とうまく組み合わせれば、様々な目的を達成できることから、「RS回路」なる単語も登場しました。
先ほどはPythonを用い、コンピュータ上でFizzBuzzを実行してみましたが、
ではレッドストーン回路を用いて、マイクラで実行することは、どの程度可能なのでしょうか。
実装してみよう
マイクラの世界に降り立ちました。
まずはサバイバルするためにそこらへんの木を
素手で殴ります。およそ常人に成せる業ではありません。
次に、鉱石を探しに洞窟に潜りましょう。
回路をつくるためにどれだけレッドストーンを集めればいいかわからない?
まずは採掘範囲を・・・え?
グオオオオオオーーーーーー!!!!!!!(死んでしまった)
実装してみよう Take 2
サバイバルモードでやってるとあまりに時間がかかりすぎて、ブログの期限に間に合わず、偉い人に怒られてしまう のでアイテム無限のクリエイティブモードを使います。
草原に壁を生やしました。
Fizz・Buzzを、発言に応じて点灯させたいので、信号を受け取るときらびやかに光るランプを取り付けます。
グーグル先生にお世話になりつつ、ランプたちを一つのスイッチでONOFFにできるように、レッドストーンで繋ぎ合わせをしました。
マイクラで実装するときの課題の一つが、if i % 3 == 0 とたった数文字で表せた、倍数の判定をどうするか。
そこで再び先生に聞いたところ、このような回路を作るのが適しているらしい。
(レッドストーンリピーター、横から信号を貰うとロックされるなんて初めて知った)
これで、3回ごとに「Fizz」が、5回ごとに「Buzz」が点灯するようになりました。
次に、print文を再現。
3の倍数かつ5の倍数の時には、「Fizz」「Buzz」別々ではなく、同時に言ってもらう必要があるので、AND回路とXOR回路を組み合わせて必要十分な装置を形成しました。
コマンドブロックを召喚してこの様なコマンドを記入すると、信号を貰った際にチャットされます。
ここまでで、if i % 3 == 0 and i % 5 == 0 から print('Buzz') までの部分(即ち変数iが3の倍数・5の倍数だった時に、適切な単語に言い換える)がいちおう再現されました。
では、変数iの数字を増やしていくfor文を実装してみましょう。
何をもって変数を表したらいいのか悩みましたが
クロック回路(繰り返し回路)にディスペンサーをつなぎ、村人のスポーンエッグを配置。
彼らが出現するたびに感圧板が押されて、先述の倍数判定が行われる仕組みです。
出現した村人たちは直下の穴に押し込められます。密ですね。
この場所にいる村人の数=変数iの値と解釈すると、わりと違和感ないのでは。
for文は、やり直すと変数iの値がリセットされます。
焼却処分すれば値が0になるね、ヨシ!!!
妥協と完成
ある程度進みましたが、まだ「else」部分が残っています。
3の倍数でも5の倍数でもないときに、村人の数を叫ぶ部分です。
・・・結果、シングルプレイの環境では変数が用意されていませんでした。
Mobの数をカウントするmodがあれば別ですけれど、妥協せざるを得なかったことを報告しておきます。ごめん
最後に見た目を整えて。
左端に映っているのは、作業中に夜になったり雨が降ったりするのにイラついたため永遠に時間と天気を最適にする回路です。
物騒なことが書いてある看板
プログラムができたらコードテストを行います。
これを怠ると、AtCoderのコンテストではWAになってペナルティを食らう羽目になります。
マイクラでFizzBuzzを可能な限り再現する流れを整理すると
- プログラムの実行 = レバーを一瞬ONにする
- for文 = クロック回路
- 変数i = 村人の数
- if文 = 村人が増えるたびに感圧板が踏まれ、3回or5回ごとに信号が通じる
- print文(出力) = コマンドブロックを介したチャットと、ランプの点灯
当初ディスペンサーにある村人スポーンエッグの数だけ、変数iの増加が繰り返されます。
そして、3の倍数かつ5の倍数なら条件分岐で「FizzBuzz」、片方だけなら「Fizz」や「Buzz」を出力する(該当しない際、変数の値を出力するのは未実装)という事ですね。
プログラミングに手を出してみたけど、中で何が起こっているのかわかりづらい。
そんな時は、コードをゲームで再現してみるといいんじゃないかと思います。(・・・ほんまか?)
今回はマインクラフトを扱いましたが、traPにはいろんなゲームが好きな人が多く所属しています。
創作活動の傍ら、部内SNS「traQ」を使って、攻略の話をしたり、マルチプレイで遊んだり。また、他の部員と協力してプログラムを書き(もちろん絵や曲を作る人も)、まったく新しいゲームを製作するプロジェクトも複数存在しています。
traPで楽しいゲームライフを!
以上、 @dan_dan がお送りしました。
明日の担当者は @toruthi です。楽しみ~