関数をもっと呼び出す前回、ゲームを作ってみます、と言ったのですが、「shi3z式ゲームプログラミング」が始まってしまったのでこの連載では引き続き粛々とプログラミングの楽しさを紹介していきたいと思います。今回のテーマは「再帰(さいき)」です。再帰・・・再び帰ってくる。宇宙探査機はやぶさのようです。今回のテーマを学ぶとこんな図形を描けるようになりますよさあやってみましょう(続きは以下のリンクから)前々回、関数というものを学びました。ところで関数の中からさらに関数を呼んでみるとどうなるでしょう?・・・というのは説明するまでもないかもしれませんね。いままでonLoadという主たる処理を書いていた関数から、さらに自分で定義したcircleやrandという関数を呼び出して使っていた訳です。関数の中から関数を呼び出すことも簡単にできるんです。実は・・・大変なことになります。下のコードはサンプルですが、決して実行しないで下さい。ブラウザが壊れることがあります。したらどうなる?}Safariなどの賢いブラウザは、こんなふうに警告を発してくれます。実は、ここに関数呼び出しの秘密があります。関数は自由に呼び出せるが、無限に呼び出せる訳ではないのです。「最大」の呼び出し数が決まっているということで、それが「コールスタックサイズ」なのです。onLoad関数のなかで無条件にonLoad関数を呼ぶと、それは無限に新しいonLoad関数を呼び出してしまいます。すると、最大コールスタックサイズがどれだけ大きく設定されていたとしても、確実に最大コールスタックサイズを超えてしまうのです。通常は十分なだけのコールスタックサイズが設定されているのですが、どれだけ大きなコールスタックサイズを確保したとしても、無限にあるわけではないので必ずエラーになります。こんな危険な機能・・・つまり自分自身を呼び出す関数という機能はなぜ実装されているのでしょうか?実は関数が自分自身を呼び出す機能、というのは、上手く使えば非常に有効な道具になってくれるのです。それが「再帰」というテクニックです。以下のコードを見て下さい。logo.penUp();}実行すると下のようになります。今度はブラウザもおかしくならずにうまく動作しました。これはなにが起きているのでしょう?ご覧のようにprocが何回も呼び出されていますね。このプログラムの動きを知るには、alertを使うと簡単です。logo.penUp();}すると、procが呼び出される度にalertでtの値が表示されます。最初はtの値は3です。次は「t=2.4000000000000004」となりますが、ほぼ2.4、そして1.92、1.536、1.2288、0.98304となってtが1未満になったので再帰は終わります。右側の画像にも注目してください。再帰が繰り返されるほどより半径の小さい円が描かれていきます。このように、自分自身を呼び出しながらも、呼び出し回数にわざと制限を設けて呼び出すのが再帰です。使いこなすのが難しいと思いましたか?実際、再帰は慣れるまで非常に理解するのが大変な考え方のひとつです。逆に再帰を使いこなせるようになれば、プログラマとして一人前になった、と言えるかもしれません。最後に、再帰を使って美しい木のグラフィックを出す方法をご紹介して今回は終わりにしたいと思います。logo.penUp();}なにが起きているかわかりましたか?こういうプログラムを理解するコツは、適当に数字を変えてみたり、moveやturnの順番を変えてみたりすることです。なあに、よほどのことが起きなければ驚くほどのことはありません。相手にしているのは再帰です。無限の再帰に気をつけて。