昨日は何を作るか長々と書いた末にブロック崩しを作った。Pongのコードの大部分がそのまま使えて楽ができた。今はまだ、とにかく動作するものを作るということに意識が持っていかれて、他のことにまで配慮ができていない。他のことってなんなのかと言うと、2つ無視できないことがある。
1つ目は、コードの質について妥協していることだ。昨日書いたブロック崩しでは、明らかに問題なところがあったのを認識した上で、とりあえず動作するからこれでいいかと完了にした。練習だしRustに不慣れだからこんなもんでいいだろうという気持ちもあった。何が問題だったかと言うと、ひどく重複したコードがあって、本当なら共通の処理なので関数にまとめ上げるべきだったのを、そのままにしておいた。同じことを繰り返さないというのはプログラミングにおいて大切な姿勢だ。その姿勢はコードの中にも現れる。重複するコードが出現するというのは、典型的な改善するべきポイントとなる。Rustに不慣れだからだめなコードを書いてしまうのではなく、手持ちの能力でも改善できると認識していながら放置していってしまうと、良いプログラミングの習慣を身につけるチャンスをわざわざ逃していってしまうことになる。コードを良いものに作り変えるプロセスには、リファクタリングと呼ばれる名称がついている。リファクタリングについて学んだり練習したりしたことはないのだけど、おそらく今回のコードの重複を取り除くという改善作業は、リファクタリングに該当するのではないかと思う。せっかくプログラムを作ってリファクタリングを適用できる、訓練できる機会があったのに、むざむざとそれを手放してしまうというのはなんとももったいない話だ。コードの質の妥協についてはだいたいこんなところだ。
2つ目は、ゲームが面白いかどうかを気にかけていないということだ。既存のゲームのクローンを作るのだから、それが面白いかどうかなんて関係ないと思っていた。練習のために作ったゲームなので、誰も、自分自身ですらもそれで遊ぶことはないと割り切っている。ゲームプログラミングそのものを訓練しいるのであって、ゲームのデザインは自分の仕事ではないと思いこんでいる。確かに、ゲームデザインは自分の本業ではないかもしれない。将来的には、何かしらこういうのを作りたいという要求がどこからか湧いてきて、それを忠実にプログラムすれば面白いゲームができるのではないかという、夢の世界に生きている。現実ではそんなことはありえない。要求のとおりにプログラムするだけで面白いゲームになるわけでもない。これはゲームでないプログラミングについても同じで、要求のとおりにプログラムしたら使い勝手の良くないものが出来上がるというのはよく知られた悲劇で、プログラミングの失敗例だ。
既存のゲームのクローンを作るというのは、ある意味、要求の分析を行う訓練を行うことを放棄していることでもある。プログラミングそのものを訓練しているのだから、それでいいというのはちょっと違う気がする。プログラミングと要求の分析というのは完全に切り離されたステージではない。プログラミングをどう定義するのかは置いておいて、もし完全に切り離してしまったら場合のコードを書くステージは、プログラミングと呼ぶより、コーディングと呼ぶほうがより適切になる。そう考えた場合、既存ゲームのクローンをとりあえず動作させるというだけの行為も同様に、プログラミングではなく、コーディングというのが適切だ。将来的に、忠実にコーディングだけを行うようなことを生業としたいかというとそんなことはない。面白いゲームをプログラミングすることを生業としたい。
要求というのは安定しないものだ。特にゲームに置いては、ある程度形になってきてから、ここはこうした方がいいと分かって、コーディングよりも前の段階に戻ってやり直すなど日常茶飯事となる。前に戻るのがコストが高いから妥協するとなったりすると、つまらないゲームがになってしまう。つまらないゲームは、研究対象として興味があるかもしれないというのを置いておくと、使いにくいアプリケーションのような役に立たないプログラムと同じだ。アプリケーションの最大の存在価値化は、便利かどうかというところにある。ゲームの最大の存在価値は、面白いかどうかというところにある。だから、必ずしも実践できなくてもよいのだけど、今作っているゲームは面白いかどうか、というのは常に頭の片隅にでも置いて置かなければいけない。クローンの元となるゲームが面白くないのなら、どうやったらこれを面白くできるかということも検討するべきだ。どうやっても面白くならないのなら、そんなことはあまりないはずだけど、それはクローンする価値がない。そもそもの要求が間違っていたということだ。
常に面白いゲームを作らなければいけないというのは、ちょっと理想が高すぎるかもしれない。 Rustの使い方がままならず、練習をしている段階でさえもゲームデザインについても考えながらやらないといけないとなると、前も書いたかもしれないけど、二兎を負うものは一兎も得ずの状態になってしまう。そんなたいしたことではない。ちょっとした意識の配分の仕方による。例えば、今回のブロック崩しを例に取ると、ボールの軌道にXとYが反転するだけ以外に変化がないのはいかにも退屈だ。パドルの当たり具合によってボールの軌道や速度に変化があるようにすると、ずっと良くなる。こんな感じで、気がついたことを直していく習慣をつけていくのが良い。その分プログラムはごちゃごちゃしてきて、見通しが悪くなる。これは必ずしも悪いことではない。現実の問題を解決するには、そういう状況に耐えうるようにプログラムを設計しなければいけない。ちょっとした変化をつけるだけで、何がなんだかわからなくなるようなのは、設計が不十分である、複雑さに耐えうるだけのしっかりしたものになっていないからだと考えられる。
だんだんハードルが高くなってきている気がする。まだやっとこさブロック崩しを作った、という段階で要求やら設計やら考える必要があるだろうか。文字数を稼ぎたかったので、少し話を膨らませて書いたところが多い。本当の話は単純だ。面白いゲームにしたいという気持ちを持ち続けること、それだけ。プログラミングしながらそれを覚えておけば、あとはついて回るだろう。ここはこうした方が面白くなる、だからコードを書き換える、そうするとコードが煩雑になる、だから基本から設計をやり直す、と自然にそういう流れになるだろう。この練習を繰り返すことは、Rustの習得という点においても、そんなに効率が悪いとは思わない。
そういう方向でやっていこう。