Slime
Last-modified: 2019-01-27 (日) 01:45:32 (1518d)
StarLogoの配布に含まれているサンプルプログラム「Slime」 プロジェクトのプログラム説明です。 なお、このサンプルの解説は、MITのStarLogoページにもありますから そちらも参照してください。 目次 プロジェクト概要 †このプロジェクトの実行は「粘菌細胞:slime-mold cell」の動きを思わせる動きをします。 それは、生物がいかにして、「リーダ無し」で、クラスタ(かたまり) を形成するのかを見せてくれます。 これらの生き物は単純な(分散的な)規則に従い、行動します。
生物の個体数がある一定以上になると、いくつかのクラスタに集約していくのが観察 できます。 ユーザインターフェース †2つのボタンと1つのスライダがあります。
実行 †numberスライダで生物(タートル)の数を適当に設定して、goボタンを押します。 変数 †このプログラムでは、パッチの変数としてchemicalがあります。 chemicalは「化学物質(pheromone)」をあらわすもので、時間が経つと 拡散、蒸発してゆきます。宣言は、Observer Proceduresのエリアで patches-own [chemical] の様に記述しています。 ローカル変数については、各手続き内で説明します。 手続き †このプロジェクト内の手続きは次の様なものです。
オブザーバ手続き †setup †このプロジェクトの初期設定をします。生成タートルの数を表すnumberは、 スライダGUIで宣言されています。 to setup ca ;;パッチ・タートルを全てクリア crt number ;;タートルをnumber匹生成 ask-patches [setchemical 0] ;;全てのパッチの化学物質を0に ask-turtles [setup] end go †プロジェクト(シミュレーション)全体の実行を進めます。 タートルのgo手続きを1回実行し、そのタートルの状態に対して、 パッチの状態(chemical変数の値)を変更しています。 これによって、タートル <---> パッチ の相互作用が進行します。 to go ask-turtles [go] diffuse chemical 1 ;disperse the chemical to surrounding patches ask-patches [set chemical chemical * 0.9 scale-pc green chemical 0.1 3] end 「diffuse」という命令はパッチ全体の指定した変数の値(ここではchemical)に 大して、拡散(diffusion)を行うというものです。そのためには、ある パッチの値をそのパッチとそのパッチに隣接したパッチの値で平均をとる 事によって行います。最後のパラメータは「それを何回やるか」です。 chemical変数の値をセットしたところで、「scale-pc」という命令で、その 値を色分けによって表示しています。この場合は、chemical変数の値が0.1から 3の間を緑色で、真っ黒から、白まで明るさを割り当てて表示しています (0.1以下は全て黒、3以上は全て白)。 タートル手続き †setup †タートルの初期位置(画面上の適当な場所)、色(赤)、そのタートルがいる位置の パッチの変数chemicalの値を設定(現状に+2)します。 to setup setxy random screen-width random screen-height setc red set chemical chemical + 2 end go †タートルの動作のための手続きです。「foreverチェックボックス」をONにした ボタンを作成し、デーモンとして実行します。 to go uphill rt random 40 lt random 40 grid-step setchemical chemical + 2 end ここでは、まず、uphill(あとで説明します)によって、化学物質の濃度勾配(薄いほうから濃い方への方向)にそってタートルの方向を定めています。次に続く3行でランダムウォーク(非対称)しています。最後に動いたあとの場所へ化学物質を2だけ落としています。 grid-step †現在の方向へ1進み、その座標を四捨五入しています。 to grid-step fd 1 setxy round xcor round ycor ;round your coordinates to the nearest whole number end uphill †その位置の化学物質の濃度の濃い方向を嗅ぎ(sniff)分け、uphill(丘登り)します。 to uphill let [:dir sniff] if :dir >= -45 [seth heading + :dir] end sniff手続きから返される値がその方向をあらわす角度です。その角度が45度より も大きい場合、方向をその角度へ向けます。 sniff †自分の位置の濃度との左45度、前、右45度の一歩前に自分の位置の濃度を比較し、 もっとも濃度が高い方向を返します。 to sniff let [:dir -45 :best-val chemical :best-dir -100] let [:current chemical-towards :dir 1] if :current > :best-val [set :best-val :current set :best-dir :dir] set :dir :dir + 45 set :current chemical-towards :dir 1 if :current > :best-val [set :best-val :current set :best-dir :dir] set :dir :dir + 45 set :current chemical-towards :dir 1 if :current > :best-val [set :best-val :current set :best-dir :dir] output :best-dir end 補足・感想 † |