テラリウム徹底攻略ガイド(改訂版)

KAnimalクラスで処理しているイベント(1)

泉 祐介+デジタルアドバンテージ
2003/05/10
Page1 Page2 Page3 Page4 Page5 Page6 Page7

KAnimalクラスで処理しているイベント

 冒頭にも述べたが、KAnimalクラスには動物としての基本的な行動があらかじめ記述してある。ここまではKAnimalクラスを利用した動物の実装に直接関係のあるメソッドについて解説してきたが、この項では、動物の基本的な行動を実装している部分であるKAnimalクラスのイベント・ハンドラについて説明していく。

LoadEventイベント・ハンドラ

 Loadイベントは、各ターンの最初に必ず発生するイベントだ。従って、Loadイベントのイベント・ハンドラであるこのメソッドも、各ターンの最初に必ず呼び出されることになる。

 まずは、コードを示すことにしよう。

protected virtual void LoadEvent(object sender, LoadEventArgs e) {
  try {
    moveCount--;
    for(int i = 0 ; i < 10 ; i++) {
      UpdateViewState();
    }
    UpdateTarget();
    if(CanReproduce) {
      BeginReproduction(null);
    }
  } catch(Exception exc) {
    WriteTrace(exc);
  }
}
KAnimalクラスのLoadEventイベント・ハンドラ

 Brunt、Food、Threatの各プロパティの値を変更するために、KAnimalクラスの内部ではScanメソッドなどによって得られた動物の情報を、適当に更新しながら保持するようにしている。UpdateViewStateはこれらの情報を更新するためのメソッドだ。情報をより確かにするために、forループを使って10回このメソッドを呼び出している。これは、偽装により隠れている動物を、可能な限り発見できるようにするためだ。ただ、tabataのような単純な生物なら、たいていの場合10回呼び出しても処理は1ターンに収まるようである(これはテラリウム・アプリケーションを実行しているマシンの性能による)。しかしUpdateViewState内で呼び出しているScanメソッドは、比較的処理時間を必要とするので、IdelEventなどでより複雑な行動を行うような場合には、この値を小さくする必要があるだろう。次のUpdateTargetは、Brunt、Food、Threatの各プロパティの値を設定するためのメソッドである。

 CanReproduceは、生物が生殖できる状態にあるかを調べるAnimalクラスのプロパティである。生殖活動を行うには、生物が成熟している、エネルギー状態が通常の状態以上になっている、前の生殖活動から一定期間がたっている(これは先にも書いたとおり)などの諸条件が満たされる必要があるが、このプロパティを使えば簡単にこれらの条件がそろっているかどうかを調べることができる。続くBeginReproductionはAnimalクラスのメソッドで、実際に生殖活動を始めるメソッドだ。

生物リストを更新するUpdateViewStateメソッド

 LoadEventメソッドで呼び出しているUpdateViewStateメソッドについても簡単に解説しておこう。

protected void UpdateViewState() {
  ArrayList newfoundCreatures = base.Scan();
  foreach(OrganismState oos in foundCreatures) {
    bool exist = false;
    foreach(OrganismState nos in newfoundCreatures) {
      if(oos.ID == nos.ID) {
        exist = true;
        break;
      }
    }
    if(!exist) {
      OrganismState os = LookFor(oos);
      if(os != null) {
        newfoundCreatures.Add(os);
      } else {
        if((oos is PlantState  && !WithinViewRange(oos)) ||
           (oos is AnimalState && oos.IsAlive          )) {
          newfoundCreatures.Add(oos);
        }
      }
    }
  }
  foundCreatures = newfoundCreatures;
}
保持している生物リストを更新するUpdateViewStateメソッド

 ここではまず、Scanメソッドを使って、その時点で動物の視界に含まれている生物リスト(newfoundCreatures)を得る。次に、前ターンで見つかった生物を保持している生物のリスト(foundCreatures)と照らし合わせて、見つからないときはLookForメソッドを使って、その生物に関する新しい情報を獲得しようとする。このメソッドは指定された生物に関する新しい情報を返すもので、Animalクラスで定義されている。ただし、偽装などによって新しい情報を得られない場合や、死んでしまったために生物が消滅した場合などにはnullが返ってくる。このような場合にはさらに生物の状態を確認し、存在するのであればリストに加える。

3つの主要プロパティを更新するUpdateTargetメソッド

 UpdateTargetメソッドでは、Brunt、Food、Threatの各プロパティの値を設定する。

protected void UpdateTarget() {
  food = null;
  threat = null;
  brunt = null;

  double minDistanceF = Double.MaxValue;
  double minDistanceT = Double.MaxValue;
  double minDistanceB = Double.MaxValue;
  foreach(OrganismState organismState in foundCreatures) {
    if(organismState == null || RefreshState(organismState.ID) == null)
      continue;
    double r = DistanceTo(organismState);
    if(r < minDistanceF && IsFood(organismState)) {
      minDistanceF = r;
      food = organismState;
    }
    if(r < minDistanceT && IsThreat(organismState)) {
      minDistanceT = r;
      threat = organismState as AnimalState;
    }
    if(r < minDistanceB && IsBrunt(organismState)) {
      minDistanceB = r;
      brunt = organismState as AnimalState;
    }
  }
}
Brunt、Food、Threatの各プロパティ値を更新するUpdateTargetメソッド

 このメソッドの処理はいたって単純だ。あらかじめ、Food、Threat、Bruntの各プロパティの値をnullで消去しておく。実際には、それらのプロパティの値を実際に格納しているfood、threat、bruntの各フィールドにnullを格納することになる。次に、先のUpdateViewStateで見つけた生物の一覧に含まれる生物1つ1つをIsFood、IsThreat、IsBruntの各メソッドにかけ、それに当てはまる生物であれば該当するフィールド(food、threat、brunt)にその生物を格納している。また、すでにそのフィールドに何らかの生物が格納されていた場合は、より距離の近い方を格納するようにする(これはFood、Threat、Bruntの各プロパティのところで解説したとおり)。


 INDEX
  テラリウム徹底攻略ガイド(改訂版)
  第4回 KAnimalクラスを使った草食動物の作成
     KAnimalクラスとは
     草食動物を作成する(1)
     草食動物を作成する(2)
     草食動物を作成する(3)
     KAnimalクラスのプロパティとメソッド
   KAnimalクラスで処理しているイベント(1)
     KAnimalクラスで処理しているイベント(2)
 
インデックス・ページヘ  「テラリウム徹底攻略ガイド(改訂版)」


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 記事ランキング

本日 月間