アリの餌集めのシミュレーション

友人と、子どもにコンピュータや数学に興味をもってもらうには、という話をしていて、
アリの餌集めなら、子どもに身近だし、群知能ランダムウォークに繋がるし面白いんじゃないか、となった。
Processingでもいいけど、ブラウザのJavascriptCanvasを使うほうが簡単かな。

目標

  • 子どもに、電子アリのプログラミングを楽しんでもらうこと。
  • 子どもの創意工夫を邪魔しないこと。
  • 結果を現実のアリでも説明できること。

で、こんなモデルはどうだろう。

電子アリのモデル

  • 秒速1ドットで動ける。
  • 周囲1ドットの色(RGBA)を読める。
  • 描画できる。画面全体に渡って。全く好きなように。(現実のアリがフェロモンを出すことのモデル。)
  • 周囲1ドットの砂糖の数がわかる。
  • 砂糖を1つ運べる。
  • GPSを持っていて、常に現在の自分の位置がわかる。
  • すごい記憶力と、すごい計算力がある。(三角関数でも遺伝的アルゴリズムでも使い放題)
  • 他の電子アリのことは全くわからない。

出題方法

  • processという関数の中身をプログラムしてもらう。
  • グローバル変数などで、他の電子アリと直接に値をやりとりするのは禁止。
    • (グローバル変数を使うこと自体はOKだけど。とにかく、情報交換にはフェロモン描画を使ってください。)
  • process関数は1秒間に1回、各電子アリごとに呼ばれる。
function process(aAntData, aProbedImageData, aFoundSugarsCount) {
 //この中身を書いてね
 //描画にはCanvas要素を使ってね。グローバル変数ctxに Canvas.getContext("2d")が入ってるよ。
}

//引数aAntDataは以下のようなオブジェクト
{
    id:    2,    //ID
    x:     127,  //現在の x 座標
    y:     127,  //現在の y 座標
    carry: false //砂糖を運んでいるか
};

//引数aProbedImageDataは以下のような配列
aProbedImageData[-1][-1] == [0,0,0,0]      //左上の色。RGBA。これは黒。
aProbedImageData[ 0][-1] == [255,0,0,0]    //上の色。これは赤。
...
aProbedImageData[ 1][ 1] == [255,0,0,127]  //右下の色。これは半透明の赤。

//引数aFoundSugarsCountは周囲の砂糖の数。

//process関数は以下の値のいずれかを返すこと。
[-1,-1] //左上に動く
[ 0,-1] //上
[ 1,-1] //右上
[-1, 0] //左
[ 0, 0] //動かない
[ 1, 0] //右
[-1, 1] //左下
[ 0, 1] //下
[ 1, 1] //右下
"carry" //砂糖を拾う

実際に作ってみた

とりあえずランダムウォークする。
砂糖を見つけたら、まるで「あったぞーっ」て大声で叫ぶように、赤いフェロモンを出す。
それが赤のグラデーションになっているので、みんなで濃い赤に向かって進む。
ある程度濃い赤まで来たらランダムウォークで周りを歩いて他の砂糖を探す。

感想

  • ちょっと子どもにはプログラムが難しすぎるし、アリの行列をなかなか拝めない。
  • 好きに描画していいぞってのは面白いんだけどなー。
  • 現実のアリには、こういう大声で叫んで仲間を集めるのはいないのかな?
    • あ、天敵に見つかっちゃうか。