連載

テラリウム徹底攻略ガイド

第5回 KAnimalクラスを使った肉食動物の作成

大石 晃裕+デジタルアドバンテージ
2002/06/06
改訂版はこちら(2003/05/10)

テラリウムサロン
テラリウムに関するご質問やご意見はこちらへ

 前回は、テラリウムで提供されているAnimalクラスから派生したKAnimalクラスを作成し、このクラスを継承した草食動物“Tabata”を作成してみた。KAnimalクラスは、動物の基本的な行動や、汎用的に利用できるであろういくつかのメソッドを実装したクラスである。KAnimalクラスを利用することにより、実際の動物プログラムの方では、その動物独自の戦略のみを記述すればよいようになっている。

 連載5回目となる今回は、このKAnimalクラスを利用して、今度は肉食動物をプログラミングしてみる。作成する肉食動物の名前は、前回の“Tabata(田端)”に続き、山手線の次の駅名として“Komagome(駒込)”と命名した。今回作成したプログラムは次のリンクからダウンロードすることができる。前回同様、C#版に加え、Visual Basic .NET(VB.NET)版も用意した。

KAnimalクラス(C#版)をダウンロードする(kanimal.cs
KAnimalクラス(VB.NET版)をダウンロードする(kanimal.vb)
肉食動物Komagome(C#版)をダウンロードする(komagome.cs)
肉食動物Komagome(VB.NET版)をダウンロードする(komagome.vb)

 なお、今回使用しているKAnimalクラスは、前回のものと比べて多少チューンアップを施している。これについて本稿の後半で触れている。

 さて、肉食動物komagomeのプログラムkomagome.csでは、いつものようにプログラムの先頭部分で各種属性を設定し、それに続いてKAnimalクラスを継承したKomagomeクラスを記述している。さっそくこのプログラムを解説していこう。

肉食動物Komagomeの基本能力属性

 まずは、肉食動物Komagomeの基本能力を決定する属性を見てみる。

[MatureSize(25)]

[MaximumEnergyPoints(14)]   // 体力
[EatingSpeedPoints(2)]      // 動物を食べる速さ
[AttackDamagePoints(16)]    // 攻撃力
[DefendDamagePoints(8)]     // 防御力
[MaximumSpeedPoints(18)]    // 移動の速度
[CamouflagePoints(20)]      // 偽装(身を隠す)能力
[EyesightPoints(20)]        // 視野の広さ
肉食動物Komagomeで設定している基本能力

 各パラメータの意味についてはここまでの連載で何度か解説しているのでそちらを参考にしていただきたい。

 さて、見ていただくと分かるが、かなりばらばらに配分されている。これは、肉食動物に必要とされるスキルが多いということだ。視野はある程度広くないと、もともと食料を確保しにくい肉食動物にとって致命的であるし、偽装能力が高くなければ、草食動物は早々と逃げ出してしまい、移動のスピードが遅ければ草食動物に追いつくこともできない。また攻撃力が高ければより早く相手を殺すことをできるし、防御力が低ければほかの肉食動物やどう猛な草食動物に負けることもあるだろう。

 それでいろいろと調整していった結果、結局このようにばらばらな数字になってしまった。

 生物が成熟したときの最大サイズを指定するMatureSize属性については、最小の値である25にしている。前回書いたとおり、大きくなるとそれに比例して攻撃力などが増加するのだが、デメリットとして成長する時間が長くかかるようになる。生物は完全に成長していないと繁殖できないので、この値が大きいと繁殖に時間がかかるようになる。つまり今回の設定では、なるべく繁殖の間隔を短くしようとしているわけだ。テラリウムの世界では、草食か肉食かにかかわらず、その繁殖数だけが結果として評価されるため、これを優先させた。

周りの生物を判定する3つのメソッド

 次に、IsFood、IsThreat、IsBruntの3つのメソッドを見ていこう。これらのオーバーライド・メソッドについて簡単に復習すると、KAnimalクラスには、自分の周囲にいる生物の状況について、自動的に取得するコードが組み込まれているのだが、発見した生物が自分にとって食料となるか(IsFood)、脅威となるか(IsThreat)、あるいは餌食となるか(IsBrunt)の判断に利用されるのがこれらのメソッドである。

 KAnimalクラスを利用するプログラムでは、IsFoodメソッドは引数で与えられた生物が食料ならばtrue、そうでなければfalseを返せばよい。同じように、IsThreatメソッドでは、その生物が脅威になるのならばtrueを、そうでないのならばfalseを返し、IsBruntメソッドでは、その生物が獲物となりそうであればtrueを、そうでなければfalseを返せばよい。KAnimalクラスでは、これらの判断メソッドを抽象メソッドにすることによって、継承したクラス側で記述できるようにしている。詳しくは前回の記事を参照してほしい。

 それでは実際にコードを見ていく。まずは引数で与えられた生物が自分の食料となり得るかを判定するIsFoodメソッドだ。

protected override bool IsFood(OrganismState target) {
  if(IsRetire) return false;
  AnimalState a = target as AnimalState;
  if(a == null) return false;
  return !a.IsAlive;
}
肉食動物KomagomeのIsFoodメソッド

 このメソッドの処理は単純である。まずリタイア(IsRetireメソッドについては前回を参照。今回も同じメソッドをKomagomeクラスで用意している)してしまった、つまりもはや子供を産むことができない状態の動物にはエサは食べさせない。この場合、メソッドはfalseを返し、KAnimalクラスに対象となる生物(target)が食料ではないことを教えるのだ。これによってKAnimalクラスでは、その生物が食料ではないと判断する。リタイアしていない場合、その生物が動物で、かつ死んでいるならばすべて食料とするような実装となっている。

 ここで少し“as”演算子について説明しよう。これはキャストに非常によく似た演算子なのだが、as演算子は、キャストに失敗したときに例外を発生するのではなくnullを返すようになっている。つまりこのコードで、参照“a”がnullではないかどうかを判定しているのは、キャストに成功したかどうかを判定していることになる。ここでキャストに失敗する場合というのは、OrganismStateオブジェクトであるtargetをAnimalStateオブジェクトにキャストして失敗した場合、つまりtargetがAnimalStateクラスのオブジェクトではない場合であるから、このオブジェクトは植物であるということが分かる。肉食動物は植物を食べることはできない。肉食動物が食べられるのは死んでいる動物のみだ。

 次は引数で与えられた生物が脅威となるかを判定するIsThreatメソッドである。

protected override bool IsThreat(OrganismState target) {
  AnimalState a = target as AnimalState;
  if(a == null) return false;
  return
    a.IsAlive &&
    !IsMySpecies(a) &&
    !CanWin(a);
}
肉食動物KomagomeのIsThreatメソッド

 このメソッドでは、まず生物が動物かどうかを確認している。植物に攻撃される心配はないので、動物ではない場合はfalseを返す。自分が作った同じ種類の生物ならば攻撃される心配はないので(次のIsBruntの実装を参照)、falseを返し、次にその生物に勝てるかどうかを調べるKAnimalクラスのメソッドCanWinの戻り値を反転して返すようにしている(つまり戦ってみて負けそうな生物ではtrueを、勝てそうな生物ではfalseを返す)。

 そして最後に餌食となりそうな生物を判定するためのIsBruntメソッドである。

protected override bool IsBrunt(OrganismState target) {
  AnimalState a = target as AnimalState;
  if(a == null) return false;
  return
    a.IsAlive &&
    !IsMySpecies(a) &&
    CanWin(a);
}
肉食動物KomagomeのIsBruntメソッド

 これは、「動物である」「生きている」「同じ種族ではない」という条件がIsThreatメソッドと同じ実装なのだが、最後の行だけ異なっていて、CanWinメソッドの戻り値を反転させていない。IsBruntメソッドの方は、動物を獲物とするにはその生物に勝てなければならないからだ。よってCanWinメソッドの値をそのままメソッドの戻り値に反映している。

 

 INDEX
  [連載]テラリウム徹底攻略ガイド
  第5回 KAnimalクラスを使った肉食動物の作成
   肉食動物を作成する
     肉食動物の行動パターン
     KAnimalクラスのBeginChaseメソッド
     KAnimalクラスのGetBypassメソッド
 
インデックス・ページヘ  「連載  テラリウム徹底攻略ガイド」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間