UIViewに生命を与えてみる

アプリ画面上のViewに生命があったら面白いだろうなとふと思いつき、UIViewに生命らしさを実装してみました。
<img width="343" alt="スクリーンショット 2016-02-21 21.20.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/35297/2397b8f6-63a5-d40e-fa7b-557552a4d79b.png">
（そもそもコンピュータ上のプログラムを生命と呼んでいいかどうかには異論があるかと思いますが）

生命の定義は生物学者によってもまちまちなのですが、今回は以下のように生命を定義してみました。
a. 自己複製ができる
b. 外部と代謝（物質のやりとり）ができる
c. 遺伝子が存在し、遺伝子が一定以上異なる個体は別種とみなされる

複雑な生命を実装するのは難しいので、今回はバクテリアやアメーバなどの無性の単細胞生物をイメージして、上記を以下のような方法でViewに実装してみました。
1. 個体がある一定以上の大きさになると分裂する。
2. 分裂の際に、個体の遺伝子が複製される。その際わずかな遺伝子の変異がランダムに起きる。
3. 遺伝子には、個体の動くスピード、個体の大きさ、個体の肉食性を決定する3つのものがある。
4. ある特定のエリアにおいて、個体にリソースが補給される。そのゾーン以外では補給されない。補給速度は肉食度が高くなると低下する。
5. 遺伝子が一定以上異なる個体が重なっていると、その個体を他種とみなし捕食行動が行われる。捕食速度は肉食度が高くなる、もしくは個体サイズが大きくなると向上する。捕食活動により被捕食者からはリソースが奪われ、捕食者に与えられる。
6. 個体は、体の大きさに応じた速度でリソースを消費する。
7. 個体は、移動速度に応じた速度でリソースを消費する。
8. 4.5.6.7.によって獲得、もしくは消費されたリソースの合計値が正であればその値に応じて個体のサイズが拡大し、合計値が負であればその値に応じて個体のサイズは縮小する。
9. サイズが一定の値以下になった個体は死亡したとみなされる。
10. 各個体はランダムウォークで移動するが、予め設定した境界より外に移動することはできない。

実行結果を動画にしました。
３時間程度ありますので、かいつまんで見ることをお勧めいたします。
https://youtu.be/TZHDfr969ZM

<img width="335" alt="スクリーンショット 2016-02-21 20.43.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/35297/cde5d470-f220-d73c-62b3-d546d4835257.png">
最初はたった一つのViewから始まります。
背景の灰色の箇所はリソースが補給されるエリア、背景の白色のエリアはリソースが補給されないエリアです。

<img width="335" alt="スクリーンショット 2016-02-21 20.50.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/35297/27848038-58d3-f87b-7c5f-056d70665435.png">
Viewは分裂を繰り返して増殖していきます。

<img width="336" alt="スクリーンショット 2016-02-21 20.55.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/35297/614db97b-6848-bbd4-6feb-39ed14b2910e.png">
遺伝に多様性が生じてくるとともに、Viewに色がついていきます。青が移動速度の遺伝子の強さ、緑が個体サイズの遺伝子の強さ、赤が肉食性の遺伝子の強さを表します。肉食性の遺伝子が強いほど、Viewの角が丸くなります。
また、種の概念が生じて捕食行動が始まるようになります。赤枠で囲まれているViewは捕食行動中のViewです。

<img width="343" alt="スクリーンショット 2016-02-21 21.20.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/35297/2397b8f6-63a5-d40e-fa7b-557552a4d79b.png">

やがて遺伝子に多様性が生じ、様々な色、大きさのViewが誕生します。種ごとにコロニーが形成される傾向も見えます。画像からは分かりませんが、種によって移動スピードも様々です。
以下に観察された現象の例を挙げます。
・肉食性の強い種が周囲のViewを食べつくて大増殖した結果、食料となるViewの欠乏により餓死してしまう。
・上記で空いたスペースに小さくて動きの早い種が瞬く間に入り込む。
・全エリアの半分を占めるほど支配的になった種が、種の内部分裂により自壊してしまう。
・周囲からの干渉を受けにくい画面端には、動くが遅くサイズが大きい種が育ちやすい。
単純な生命だけではなく人類の拡散や国家の盛衰など様々なスケールの現象のモデルになるかもしれませんね。

<img width="342" alt="スクリーンショット 2016-02-21 21.52.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/35297/ee740f80-8ac5-d9f5-00a8-957b36f88e71.png">
十分に時間が経過すると、やがて生命活動は収束に入ります。
動きの早い種、体の小さな種、肉食性の強い種は淘汰され、体が大きくてほとんど動かない大木のような個体のみが残ります。
不可逆的な変化で増加するのがエントロピーとするならば、エントロピーが最大の状態に到達してしまったのかもしれません。
ある意味各種がお互いの領域を侵さない平和な状態とも言えますが、ダイナミックさに欠けた面白味のない状態とも言えます。
この状態の是非はともかく、この状況に陥らないようにするためには、例えば以下のような対策が必要になるかと思います。
・閉じた系ではなく開放系にする。Viewの移動領域を制限しない。
→画面上下左右をループさせる擬似開放系ではだめでした。Viewの流入と流出が必要かもしれません。
・大陸移動のような環境変化。背景のリソース補給エリアを移動させる。
・スノーボールアースや巨大隕石の衝突のような大量絶滅イベントを意図的に起こす。
→肉食性の高いViewによってViewの総数が極端に減少させられた後、カンブリア紀のようにViewの多様性が増加することが確認できています。

閉じた系では生命の多様性が一旦広がった後、やがて収束に向かうというのは興味深いです。
人類が宇宙に進出したがるのも、ひょっとしたらこのような収束状態に向かうのに抵抗するためなのかもしれません。
今後、性の概念と知性の概念をViewに導入することも考えています。人工知能のロジックの開発において、いい実験対象になるでしょう。

今回の実験結果はあまりアプリ開発に直接役立つものではありませんが、生命のしくみを模する事はより深みのあるゲーム開発やUI/UXの開発につながる可能性があるかもしれませんね。

今回作成したコードをGitHubで共有したいと思います。
https://github.com/yukinaga/LivingView