ここでは第一回のコンテストで私が開発した草食動物であるShera11について解説します。
ソースはこちらからダウンロード出来ます。
Shera11はコンテスト序盤に投入し、それなりに繁殖しました。
それ程優秀な生物でもありませんが、参考になるところもあるかと思います。
ただし私の書いた初めてのC#プログラムということもあり、あまりきれいではありませんし、
公開するつもりは全くありませんでしたので、かなりいいかげんなところもあります。
ちなみにコンテストでは、Perlスクリプトに通して変数名や関数名を変え、
WriteTrace文を無効にしてからコンパイルしてリリースしました。
Shera11は普通の消極的な草食です。
ランダムに歩きまわり、肉食動物がいれば逃げ、草があれば食べに行きます。
サイズは最小の25であり、スキンはSpiderです。
パラメータは次のようになっています。
[MaximumEnergyPoints( 26 )] // 体力
[EatingSpeedPoints( 0 )] // 食べる速さ
[AttackDamagePoints( 0 )] // 攻撃力
[DefendDamagePoints( 20 )] // 防御力
[MaximumSpeedPoints( 14 )] // 移動の速度
[CamouflagePoints( 0 )] // 身を隠す能力
[EyesightPoints( 40 )] // 視野の広さ
現在の状態を次のように区別しています。
これはタスクの優先順位を簡単に扱うための実装です。
public enum TaskEnum
{
Nothing, //何もしてない
Eating, //食事中
ToFood, //エサに向かい中
Walking, //散歩中
WaitFood, //エサ場で待機中
RunAway, //逃走中
Attacked, //攻撃された
Blocked, //ぶつかった
};
ではポイントとなるところについてみていきます。
int [,] Map; //視界の世界 1:動物 2:植物
周囲のマップを作成し、Mapという2次元配列に格納します。
関数ScanAll()で、Scanの結果動物がいるところは1、植物のところは2を入れます。
0はなにもないということを示すことになります。
この配列をもとに移動出来る場所を探します。
関数IsCleanLineでは、自分が今から移動しようとしている場所までの間に、
障害物があるかないかを判定することが出来ます。
bool IsCleanLine( Point p1, Point p2 )
p1からp2まで移動する間に通ることになる全てのセルについて、
関数IsCleanを呼び出し、障害物がないかを調べます。
IsCleanでは2次元配列Mapを参照し、自分のサイズを考慮した上で、
その地点に行けるかどうかを判定します。
実際に移動する前にIsCleanLineを呼び出すことで、
障害物にぶつかるのを避けることが出来ます。
ただし、障害物が動物である場合には、相手が移動する可能性がありますので、
こまめにIsCleanLineを呼び出して、進路を微調整することが必要です。
IdleEventはターン毎に発生するイベントです。
Shera11ではここでほとんどの処理を決定しています。
まず、生殖が可能かどうかを調べ、可能であれば直ちに生殖を開始します。
次にScanAll()とMakeMap()を呼び出し、周囲の状況を把握します。
そして、TryDefend()を呼び出し、一番近くにいる敵に対し防御を行います。
その後、肉食がいれば逃げ、エサがあれば食べに行きます。
何もない場合には、適当に歩き回ります。
関数TryEat()でエサに関する処理を行っています。
逃げている途中はエサ探しは行わないようにしています。
すでにエサを食べられる位置にいるときは、植物が食べれる状態にあるかを判定します。
自分がおなかいっぱいのときと、
植物が食い尽くされてしまう場合にはエサを食べません。
エサを食べることの出来ない位置にいるときは、
エサに向かって歩き出します。
Shera11ではFoodChunksの多い順に植物を並べ替え、
さらに近い順に並べ替えて優先順位を付けています。
そのリストの中から、障害物にぶつかることなく到達出来る地点を探し、
そこに向かいます。
もし、視野の中に植物が見当たらないときは、
食料を探して歩き回ることになります。
Shera11では単純に乱数によって行き場所を決めています。
ここは一番に改良が必要なところだと思います。
関数TryRunAway()では、敵から逃げる処理を行っています。
近くに危険な敵がいる場合には、最も安全と思われる方向に逃げ出します。
Shera11では、その場所が安全かどうかは、単純に一番近い敵との距離で判断しています。
これも改良の余地があるところです。
Shera11.csの一番最後に、次のような関数があります。
//自分の仲間か? あまり信用できないかも
public bool IsMyFriend(OrganismState s){
return s.Species.Skin.StartsWith(" ");
}
これはsという生物が自分の仲間かどうかを判定するためのものです。
例えば、肉食動物を作り、特定の草食動物のみを仲間として攻撃しないようにすれば、
その草食は非常に有利になります。
これはテラリウムにおいてとても有効な戦略で、
実際に私が第一回コンテストに優勝することが出来たのも、
Lie005のみを攻撃しない肉食動物Lufasのおかげです。
しかし、自分で"あまり信用できない"とコメントしている通り、
この関数では簡単に偽装出来てしまいます。
つまりこの機能を搭載した肉食が繁栄しているのを見た他の人が、
Skinに空白を入れた草食を作れば、その草食は攻撃されることなく繁栄することが出来ます。
これを防ぐためには、IsMyFriendをもっと厳密にする必要があります。
例えば、パラメータに制限を決めて、チェックを厳しくすることが出来ます。
また、独特の動きを定義し、その動き方をしている生物のみを仲間と見なすことで、
より偽装されにくい仲間機能が実現出来ると思います。
私が第一回のコンテストでリリースした生物は、
です。
この人たちは茅田砂胡さんの小説"デルフィニア戦記"の登場人物たちです。
とても面白い物語ですので、興味のある方は是非読んでみてください。
ちなみにこの中で私が一番好きなのはシェラです。
Sheraで優勝できたらよかったのですが、
張り切って最初にリリースしたために、いまいち活躍出来ませんでした。
優勝したLieは主人公ですが、物語の中でもLufasによく助けられています。
この辺にはちょっとこだわってみました。
またリィとシェラの性格の違いなども考え、Sheraの方がおしとやかにしてあります。
[ テラリウム攻略法 ]
このページに対するご意見ご感想は (ara999 あっと gmail.com ) までお願いします