「砂」の仕組み
どういう規則で動いているか
「砂」は、砂一粒毎にまわりの様子を見て、どの方向に動くかを決めています。
正確には、粒の周囲4方向の障害物の有無をみて、左右上下に動くか、または、動かないかを決定します。
具体的には、
- 下に何もなければ下に動く
- 右と下に障害物があって左に何もなければ左に動く
- 左と下に障害物があって右に何もなければ右に動く
- 上のみがあいている場合は一定の確率で上に動く
- 左右に何もなくて下に障害物があるときは右か左か
それとも動かないかのどれかを適当に選ぶ
といった感じの規則で動いています。
普通の物理シミュレーションでは複数の物体を同時に動かすときは、
- 各物体がこれからどちらに動くかを計算する。
- 各物体を計算した方向にしたがって動かす。
といった手順で動かしますが、「砂」の場合、このようにすると
粒同士が重なってしまうので、単に砂粒を1つ1つ順番に動かしています。
これだと、厳密には左右対称になりません。実際、砂粒を画面上に
規則正しくならべると最初のうちは右か左に少し偏ったりします。
しかし、砂粒が十分に交ざっているとそれほど不自然な動きは見られません。
「砂」では、初期状態の砂粒をちゃんとシャッフルするようにしています。
という感じで、かなり簡単な方法ですが、やってみるとそれなりに
リアルな動きになるわけです。
プログラムは?
砂がどのような規則で動いているかは、上のとおりですが、
上の説明をそのままプログラムにすると、If-then-elseの
羅列になってしまいます。それでも、ちゃんと動くわけですが、
といった欠点があります。そこで、上に書いた規則を
テーブル化します。どのようなテーブルにするかというと、
- 周り4方向の状態の組み合16通に対してどの程度の確率で
どちらに動くかを記述する。
- 動く方向は、左,右,上,下,動かない の5つあるので、
この5つをコード化したものをいくつかならべる。
(「砂」では16個になっている)
各方向のコードの個数が多ければ多いほどその方向に行く確率が高くなる。
- これを配列変数に格納して、動かすときに周りの状況を読み取って
その方向に関するテーブルを参照して動く方向を決定する。
(方向コードをならべた個数の数までの乱数を発生させてその数を
配列のインデックスとすると、動くべき方向を取り出せる)