きっかけは妻だった。
フラクタル構造にちょっと興味があるのだけど、あまり詳しくないからいい本ないかね、と相談された。
僕はフラクタルにはそれなりに興味があってかじった程度の知識はあるけど、体系だった知識は無い。
これは良い機会なので、いろいろ調べてみる。
「フラクタルって何だろう―新しい科学が自然を見る目を変えた」
1988 年の出版なので、すでに古本でしか手に入らないのだけど、この本が良さそうだ。
購入してみる。
…届いた本は、まさに疑問に答える良書だった。
著者はマンデルブロの元で学んだ、日本のフラクタル研究の第1人者で、その人が「誰にでもわかるように、平易に」フラクタルを解説したもの。
図版も多く、巻頭にはカラーページもある。
さて、妻に渡す前に届いた本をざっと読んでいたら、子供が表紙の絵やカラーページに興味を持った。
実は、少し前に子供と話をしていて「フラクタル構造」について雑多な話をしたことはある。
良い機会なので、図版を見せながら、以前話したことの再確認をする。
特に「シェルピンスキ―のギャスケット」が長女(7歳)のツボだったようで、お絵かきし始めた。
最初はうまく描けなかったが、「三角形の辺の中心を結ぶ」ことをコツとして教えたら、6段階くらいまで描いていた。
6段も描くと、ちゃんとフラクタルに見える。
面白がって別の紙にも描いて量産しながら「描くの大変~」とか笑ってる。
じゃぁ、ここはパソコンで描けるのを見せるところか。
子供がお絵かきして楽しんだのが水曜日の話で、木曜日に「パソコンで見せるなら適切な言語は何か」と調査した。
タートルグラフィックが使いたいが、案外気軽な言語が無い。
…とおもったら、Scratch がタートルグラフィックを扱えた。
ずっと以前に Scratch でゲーム作ったりして見たけど、タートル扱えるのなんて忘れてた。
(もう一つ忘れていた理由があるのだけど、これは後で解説する)
昼の間に、コッホ雪片を描くプログラムを自作してみる。
うん。簡単に実演できそうだ。
夜、子供が風呂に入っている間に準備をして、風呂上がりの子供にコッホ雪片を描く過程を実演。
まず、「猫」に命令する形で、三角形を描くプログラムを作る。
次に、長さを与えると、その長さの「1段階のコッホ曲線」を描くサブルーチンを作る。
三角形の「直線」部分を「コッホ曲線」に変えると、六芒星が描かれる。
最後に、コッホ曲線を描くサブルーチンを改造し、その内部で使っている「直線」の定義を、「コッホ曲線」に置き変える。
すると、コッホ曲線は1段階ではなく、無限に細かくなり、「三角形」が「コッホ雪片」に変わる。
#実際には、直線の定義を変えるだけでなく、「ある程度短い線なら実際に描いてしまう」という条件分岐も必要。
非常に簡単なプログラムで、美しい図形が描き出されるのは面白かったようだ。
もっといろいろ描いて! というので、とりあえず猫がランダムウォークしながら、虹色の線を描くプログラムを作った。
猫以外出せないの? というから、新たなキャラクターの絵を選ばせ(長女がスケート靴を選んだ)、同じようにランダムウォークさせる。
次女(5歳)も「絵を選びたかった」と拗ねるので、さらに選ばせると、プレゼントの箱にした。
ランダムウォークではつまらないので、スケート靴がぶつかったら音を出すプログラムを仕込む。
音のライブラリから音を選ぶと、「ヒヒーン」という馬のいななきが選ばれた。
これで、スケート靴がプレゼントにぶつかるたびに「ヒヒーン」となくようになった。
ついでに、プレゼントの箱から「ひひーん」と吹き出しが出るようにした。
猫がぶつかった時も何かしたい、というので、ジングルベルが流れ出すことになった。
この際、プレゼントは「おめでとう」と喋る。
そして、猫とスケート靴がぶつかったときは、猫が1秒間巨大化することになった。
なにがなんだかわからないカオスな世界。
しかし、子供たちはゲラゲラ笑いながらこの作成過程を楽しんだ。
いつも寝る時間は8時半なのに、10時になっていた。
「今日はおしまい。明日も学校あるから早く寝ないと」と終了。
子供たちが寝た後、「小学生からはじめるわくわくプログラミング」を Amazon に注文。
この様子だと、長男(10歳)にはそろそろプログラムを教えても楽しいだろう。
翌日金曜日は特に何もなく、その次の土曜日。
いじっていて気になる機能があったので、ちょっと自分の方で実験してみる。
「クローン」という機能ブロックがあったのが気になっていた。
これはもしや、インスタンスを作る機能では?
…まさにその通りだった。
Scratch は、オブジェクト指向に作られているのだけど、以前に 1.4 を使ったときはインスタンスが作れなかった。
厳密に言えば、作ったオブジェクトを「コピー」して増やすことはできる。
ただし、それはプログラム作成時点で手動でコピーするのであり、プログラム内でインスタンス生成することはできなかった。
また、コピーしたプログラムは新たな別プログラムになるので、ゲームを作る際に「20匹の敵が出るようにする」ために20のコピーを作ると、同じ内容のプログラムが20個に増えることになる。
その後プログラムの改造をすると、「少しづつ違うプログラム」が出来てしまう。
そのため、実行前に20個のコピーを一旦削除し、再び20個のコピーを作り、それから実行…と余計な手間が増える。
クローン機能はこの手間を無くすもので、非常に強力だ。
早速小さなゲームを作ってみる。
このゲームに子供たちが反応した。
お絵かきが出来るんだと思っていたら、ゲームも作れる!
#この機能は、強力だけど難しい概念でもあります。
オブジェクト指向に作りながらインスタンス生成が無かった、というのは、判りにくい概念を避けるために「あえて」入れなかった、ということでしょう。
長女が、動かす絵は選ぶだけで自分で描けないの? と聞いてきた。
描けるよ、と教えると、ピクミンを描きたいという。
(うちの子は結構ピクミンが好き。ゲームが、というよりは、あの世界観が好き)
Scratch では、お絵かきのための簡単なツールもついている。
ビットマップとベクターの両形式で描けるが、ここは子供にわかりやすくビットマップで描かせてみる。
あえて何もヒントを出さずに筆だけで描かせたら、最初は「うまく描けない」と言っていたのが、「筆を太くして円を描く」というテクニックを見つけ出した。
(筆を太くすると、「点」が大きさを持った円になる)
これで、雪だるまのように頭と体を描き、そこに小さめの黒丸で目を入れる。
…手足を描く段階で「うまくまっすぐ描けない」とまた言い出したので、助け舟を出す。
実は、直線を描くための機能がある、ということと、 Undo 機能が存在することを教えた。
これでずっと絵が描きやすくなった。やがて赤ピクミン完成。
青と黄色も描きたい、というので、赤をコピーして、ペイントバケツで色を変えるテクニックを教える。
後はキャラごとの顔の違いをちょっと変更して、三色のピクミンが完成した。
さて、これをどうする?
長女にはまだプログラムは難しい。
ピクミンだから 100匹動かしたい! という要望。
早速、クローンを使う時が来た。
赤ピクミンをクローンして100匹に増やす。
オリマーの後ろにぞろぞろ歩くようにしたい、と言われる。
マウスカーソルの方に「向かせる」ことは簡単なので、マウスカーソルに向かって歩くようにする。
ところが、これだとやがて皆が重なり合い、ぞろぞろ感が出ない。
各ピクミンごとの「足の速さ」パラメータをランダムに決め、バラつきを演出する。
ところが、これでもまとまりすぎてぞろぞろ感が出ない。
マウスカーソルに追随しすぎるのだ。「マウスカーソルに向く」タイミングを、ランダムで 1/5 にしてみた。
平均すれば5歩歩くたびに方向を変えるわけだ。
これでやっと「ぞろぞろ」感が出た。
ついでに、クローン時にランダムに赤・青・黄色を切り替えるようにもした。
(3種類は「コスチューム」の違い…同じプログラムで動くが、見た目だけの違いとなっていて、クローン時にランダムに切り替える)
ぞろぞろとピクミンを連れて歩けるようになったら「敵を置いて攻撃したい」と言われた。
画像ライブラリにはカエルの絵があった。
じゃぁ、コイツがマロガエルってことで。(ピクミンには、そういう名前の敵キャラがいる)
マロガエルを置き、ピクミンに触れたら「体力」が減少するようにする。
…マロガエル側でチェックしたら、ピクミンが1人触れていても、100人触れていても同じ速度で体力が減少した。
これはつまらないので、ピクミン側でチェックするように変更。
これで、集団攻撃するとあっという間に倒せるようになった。
マロガエルは攻撃されるとゲコゲコと啼き、倒されると断末魔を上げて消える。
「敵が止まってたらつまらない」と言われたので、ランダムウォークも追加した。
逃げ回るカエルを追いかけるゲーム。
これでも「攻撃してこないと緊張感が無い」と言われたので、舌を長く伸ばしたカエルの絵を追加。
スペースキーを押すと、1秒間の間舌を伸ばすようにした。
この舌にピクミンが当たると、ピクミンは消えてしまう。
…意図せず、謎のゲームが出来上がった。
スペースキーをタイミングよく押して、ピクミンを食べつくすカエルと、全滅前にカエルを倒すピクミンの戦い。
ここまで完成した時点で、僕は関与するのを辞めた。
作る過程を全部隣で見ていた長男が、ある程度理解している。
ピクミンの強さを定めるパラメータ位置と、カエルの強さを定めるパラメータ位置を教え、好きなように調整して「ゲーム」を面白くしてごらん、と任せてみる。
長男に任せたのは、そろそろ昼ご飯作らないとな…と思ったからだったのだけど、その時丁度郵便屋さんが来た。
一昨日ポチった Scratch の本が届いた。
中身をざっと確認してから、長男に見せてみる。
長男もざっと中身を確認してから…あまり興味を示さず、パソコンに戻る。
というのも、すでに本で紹介している学習レベルを超えてしまっていたから!
本に書いてあるのは、いくつかのサンプル程度のレベルを超えないプログラムを作るまでの過程で、簡単なゲームも含まれていた。
しかし、すでに簡単なゲームのレベルを超えたものを作りはじめ、長男はゲームバランスをどうやったらとれるか考え始めている。
プログラムの学習はじめてから、合計で6時間程度しかたっていないのに!
後で長男がパソコンに向かえない時間(大人気になってしまい、長男・長女・次女が1時間交代で使うようになった)に、Scratch 本を眺めたりはしている。
でも、基本的に知識を再学習し、体系づけているだけで「新発見」することは何もないようだ。
さて、ここで Scratch 本を僕も読み、Scratch にタートルグラフィックがある、ということを忘れていた理由がわかった。
以前使った 1.4 では、サブルーチン定義ができなかったのだ。
僕がタートルグラフィックを使いたい理由は、「再帰」による描画が簡単にできるからだ。
しかし、Scratch 1.4 ではサブルーチン定義ができず、再帰も行えなかった。
「ローカル変数を持った、再帰可能な関数」である必要はない。
僕は大学1年の時まで BASIC (と機械語)しか使えなかったが、三角関数と LINE でタートルグラフィック相当の描画を行えるようにしたうえで、コッホ曲線とかを描いていた。
再帰可能なC言語のような関数であれば描くのはより楽だが、そうでなくても配列が使えれば自前でスタックを組んでローカル変数を確保できる。
しかし、そもそも「サブルーチン」が定義できない 1.4 では、フラクタルを描く方法はなかった。
これが僕にとって「タートルグラフィックがあっても魅力を感じなかった」理由で、そのために存在自体を覚えていなかったのだった。
そして、2.0 ではいきなりコッホ曲線を描いていたように、強力なサブルーチン定義がある。
以前に、1.4 を使ったときに書いた日記では、Scratch は初心者向けには良いが、将来の保証が何もない、と書いた。
すぐに限界にぶつかるし、別の言語への乗り換え易さも考慮されていなかったためだ。
しかし、先に書いた「インスタンス生成」と、「サブルーチン定義」の2つが追加されたことで、Scratch に対する不満はかなり解消されたと思う。
別の言語への乗り換えは、相変わらず考慮されていない。しかし、「乗り換えなくてはならない」と思うほどに言語の壁に突き当たるのは、かなり熟練してからだろう。
多くの子供は、そこまで熟練しないだろうし、する必要もない。
Scratch は大人の使用に耐えるほどの機能を持っていて、サンデープログラマならこれで十分。
サンデープログラマの枠に収まらないレベルになったら乗り換えるべきだけど、そのレベルに行きつける人なら乗り換えは難しくない、むしろ楽しいチャレンジだろう。
#あえて難を言えば、配列の機能が弱い。
一次元配列は持てるし、その操作機能は十分なのだけど、2次元配列にはできない。
もっとも、1次元を2次元に拡張することは「不可能ではない」ので、十分な知識があれば乗り越えられる。
(でも、乗り越えられる技量があるなら、別の言語に乗り換えたほうが良いかも)
さて、長女の絵に始まった「ピクミン」プログラムは、長男が大きく改造を開始したことで、2つのプロジェクトにフォークした。
長男は、ランダムウォークしかできないカエルに不満を持ち、キー操作で様々な「技」を出せるように改造した。
代わりに、ピクミンはランダムウォークとなり、対戦ゲームではなくなった。
元々、ピクミンもカエルも、横から見た絵だった。
だから、カエルはほおっておくと下に落ちる。ピクミンはランダムウォークだが、基本的に下方向に集まっており、黄色だけが高くジャンプできる。
(ゲームでも黄色はジャンプ力が高い)
下キーを押すと、カエルは向いている方向に舌を出し、同時に少しその方向に進む。
上を押すと「昇竜拳」で、カエルが舌を出して左右に激しく向きを変えながら一番上まで上昇する。
(その後落ちてくる)
左右キーは、舌を出しながら押された向きに画面端まで一気に進む。
下キーの「舌を出すだけ」と言うのがあまりにも地味だが、この技は連続して出せる。
しかし、それ以外の技は、出した後に長い硬直時間があり、連続して出せない。
「強い技にはデメリットもある」という、バランスを考慮したものになっている。
土曜日のプログラムはここまで。
日曜日。
長男はさらに大改造を試みる。
紫ピクミンと白ピクミンを追加し、カエルの技に「プレス」を追加した。
昇竜拳で空中に上がった後、下キーを押すとカエルが一気に落ち、その間に当たったピクミンを「プレス」で倒せる。
(ちなみに、下にいるときの下キーは、今まで通り舌を出す)
白ピクミンには毒があるので、プレスで倒さないといけない。間違えて食べると、カエルの体力が大きく削られる。
しかし、紫ピクミンにぶつかると、カエルはしばらく操作不能となる。
画面内を大きく移動する「昇竜拳&プレス」は、紫にぶつかる確率を上げてしまうので、使いどころを考えなくてはならない。
長男から構想を聞かされた時に、これはまだ長男の手に余るのではないかな、と思って「まだ難しいかもしれないけど、頑張ってごらん」と言っておいた。
実際、思ったより難しかったようで、時々弱音を吐きながら作っていた。
しかし、日曜日の間に大体完成。
時々バグが出て、上手く動かないと言って自分でじっくりとロジックを考え「あー、ここが悪かった」と修正したりしている。
中には、どうしても原因がわからずに「お父さんわかる?」と聞いてくる。
たとえば、ピクミンの「残り数」を表示しているだが、これをピクミンの処理ルーチン内でこなしていた。
すると、最後の一匹を倒した瞬間に「ピクミン処理ルーチン」は全て停止してしまい、「残り1匹」の表示のままになってしまう。
最後の1匹を倒したとき「以外」は正常に動いているので、何が悪いのかなかなか気づきにくい。
いわゆる「端の処理」というやつで、経験則上もっともバグの出やすい部分で、僕は症状を聞いただけで原因が推察できた。
でも、経験が浅いとどこが悪いのかわかりにくい。
しかし、逆に言えば、経験の必要な個所以外は、自分で工夫して「やりたいこと」を実現していってしまう。
まさか、たった2日でこのレベルまでプログラムが組めるようになるとは思わなかった。
ちなみに、妻もフラクタルの描き方とかを勉強してます。
こちらは、いきなり「再帰処理」を学ぼうとしているわけで、ちょっと混乱気味。
でも、描きたかった画像を大体作るプログラムは完成していて、残すはパラメーター調整のみ。
妻はちょっと Javascript と PHP を使った経験はあるけど、再帰処理するようなプログラムは初体験。
上達は十分速いと感じる。
妻も長男も、上達が早いように感じるのは、それだけ Scratch が使いやすいからだ。
長女の方の「ピクミン」プロジェクトはまた別の方向に進んでいる。
「ペレット」にピクミンが触れると少し「オニヨン」の方向に動き、オニヨンにペレットを運び込むとピクミンが10匹増える。
(ペレットはまたランダムな個所に現れる)
戦いとはまた別の、「協力して物を運ぶピクミン」という方向に伸びているのが面白い。
次女もピクミンの絵を描きたいというのでさらに別プロジェクト。
こちらは、たくさんのピクミンが「ひっこぬかれて あなただけに ついていく」などと歌いながらお散歩している。
同じ題材で作り始めても、これだけの多様性が出る。
子供の考えることって面白い。
Scratch の「初心者に対する」使いやすさはかなり良くできていて、誰でもプログラムを始められると思う。
(これは、誰にとっても使いやすい、という意味ではない。あくまでも初心者にとってのハードルの低さの話)
プログラムをやってみたい人に薦められる言語が無い、と20年くらい思っていたのだけど、いまなら間違いなく Scratch がお勧め。
最初に何をやっていいかわからない、という人は、簡単なお絵かきから始めるのがお勧めかな。
「ペンを下ろす」を指示してから「~歩動かす」をすると、線を描くことができます。
~歩、の数字を大きくすれば長い線になります。
そして、「~度回す」を使うと、進む方向が変えられる。
ブロックをダブルクリックすればそのコマンドを実行できるし、隣のエリアに持っていけばブロックを繋げて手順を示せる。
繋がった手順ブロックをダブルクリックすれば、まとめて実行されます。
まずは、三角形描いてみましょう。
それができたら、次は星型。(5つ腕がある奴ね)
1個星がかけたら、ランダムなサイズでランダムな位置に描くことにチャレンジしてみましょう。
このチャレンジは、結構難しい。教師無しでやっていると、投げ出したくなるくらいの難問かも。
(適切な教師がいれば簡単に作れると思うのですが)
さらに、星、三角、四角など、いろんな図形をランダムにちりばめてみましょう。
ここまで自力で作れたらたいしたもの。
もっといろんな絵を描いてみたり、線は引かないでも「キャラクターを自由に動かす」ことでアニメを作ってみたり、ゲームにしてみたり…
多分、思いついたことを手当たり次第にやっていれば上達できるだろう。
プログラムに興味のある方は、是非どうぞ。
同じテーマの日記(最近の一覧)
関連ページ
BASIC言語 初稼働日(1964)【日記 15/05/01】
別年同日の日記
申し訳ありませんが、現在意見投稿をできない状態にしています。 |