[C# Source Code]Terrarium Farm.

本文介绍了一个复杂的生物模拟程序,该程序模拟了一种名为'MyCreature'的生物的行为逻辑,包括其移动、攻击、防御和觅食策略等。通过定义各种属性如最大能量点数、成熟尺寸等,并使用特定算法来实现生物间的互动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

using System; 
using System.Drawing;
using System.Collections; 
using System.IO; 
  [assembly: OrganismClass("MyCreature")]        
  [assembly: AuthorInformation("naka", "")]
  [AnimalSkin(AnimalSkinFamilyEnum.Beetle,"mari")]  
  [CarnivoreAttribute(true)]
  [MatureSize(26)]                            
  [MaximumEnergyPoints( 15 )]
  [EatingSpeedPoints( 5 )]
  [AttackDamagePoints( 0 )]
  [DefendDamagePoints( 0 )]
  [MaximumSpeedPoints( 20 )]
  [CamouflagePoints( 0 )]
  [EyesightPoints( 60 )]
/* NOX 
  [AnimalSkin(AnimalSkinFamilyEnum.Beetle,"XXE40240805")]
  [MatureSize(32)]                            
  [MaximumEnergyPoints( 18 )]
  [EatingSpeedPoints( 5 )]
  [AttackDamagePoints( 20 )]
  [DefendDamagePoints( 0 )]
  [MaximumSpeedPoints( 17 )]
  [CamouflagePoints( 0 )]
  [EyesightPoints( 40 )]
*/



  public class MyCreature : Animal
  {
      private class DistComparer3 : IComparer {
          MyCreature my;
          public DistComparer3(MyCreature my) {
              this.my = my;
          }
          public int Compare(object a,object b) {
              if(a==null || b ==null)
                  return 0;
              int d = my.CellDistanceTo(((OrganismState)a))
              - my.CellDistanceTo(((OrganismState) b));
              if(d == 0 && a is AnimalState && b is AnimalState){
                  d=Power((AnimalState)b)-Power((AnimalState)a);
              }
              if(d == 0 && a is AnimalState && b is AnimalState){
                  d=((AnimalState)a).Damage-((AnimalState)b).Damage;
              }
              return d;
          }
          int Power (AnimalState a){
              return a.AnimalSpecies.MaximumAttackDamagePerUnitRadius * a.Radius
              +a.AnimalSpecies.MaximumDefendDamagePerUnitRadius * a.Radius;
          }
      }
      /*
      private class SortableOrganism: IComparable
      {
          public OrganismState organism;
          public double score;
          public SortableOrganism(OrganismState organism, double score)
          {
              this.organism = organism;
              this.score = score;
          }
          public virtual int CompareTo(object obj)
          {
              if (((SortableOrganism) obj).score < score)
                  return (-1);
              if (((SortableOrganism) obj).score == score)
                  return 0;
              else
                  return 1;
          }
      }
      */
      Hashtable       Creatures       = new Hashtable();      
      public ArrayList    kyoi        = new ArrayList();    
      public ArrayList    kamo        = new ArrayList();    
      public ArrayList    animal        = new ArrayList();    
      public ArrayList    esa        = new ArrayList();    
      public ArrayList    esa2        = new ArrayList();    
      public ArrayList    Plants        = new ArrayList();    
      public ArrayList    Friends        = new ArrayList();    
      public ArrayList    Dead        = new ArrayList();    
      public ArrayList    AttackAS    = new ArrayList();    
      public ArrayList    FoundAS        = new ArrayList();    
      public ArrayList    AS             = new ArrayList();    
      public Vector lastRunaway;
      public    bool isBlocked;
      Hashtable SeenCreatures = new Hashtable();
      public ArrayList Seenkyoi =new ArrayList();
      private ArrayList RetiredFriends = new ArrayList(); 
      public ArrayList SeenCarnivores = new ArrayList();
      private bool isCarnivoreNear = false;
      ArrayList    Attackers    = new ArrayList();
      bool isclose;
      bool isfood;
      UtilMap     map;
      private class SeenCreature
      {
          public SeenCreature(OrganismState creature, int tick)
          {
              this.creature = creature;
              this.tick = tick;
          }
          public OrganismState creature;
          public int tick;
      }
      protected override void Initialize()
      {
          map = new UtilMap(this);
          Load += new LoadEventHandler(LoadEvent);             
          Idle += new IdleEventHandler(IdleEvent);             
          Attacked += new AttackedEventHandler(AttackedEvent); 
      }
      void LoadEvent(object sender, LoadEventArgs e)
      {
          kyoi.Clear();
          kamo.Clear();
          esa.Clear();
          esa2.Clear();
          Attackers.Clear();
          animal.Clear();
          Plants.Clear();
          Friends.Clear();
          Dead.Clear();
          SeenCarnivores.Clear();
          RetiredFriends.Clear();
          isBlocked=false;
          FoundAS.Clear();
          AS.Clear();
          AttackAS.Clear();
          isclose = false;
          isfood = false;
          isCarnivoreNear = false;
          if(OldAge())
              MyAntenna = Antenna.OldAge;
          else
              MyAntenna = Antenna.None;
/*NOX              
if (State.Generation > 300)
{
 if (((State.TickAge + 1) % 2) == 0)
{
 Antennas.RightAntenna = (AntennaPosition)(((State.TickAge + 1) * 83) % 10); 
}
else
 Antennas.RightAntenna = (AntennaPosition)(((State.TickAge + 1) * 58) % 10);
}
else
 Antennas.RightAntenna = (AntennaPosition)(((State.TickAge + 1) * 83) % 10);
NOX */
      }
   Point GetBypass(OrganismState target) {
    int dx = target.GridX - State.GridX;
    int dy = target.GridY - State.GridY;
    int size = State.CellRadius + target.CellRadius + 1;
    if(Math.Abs(dx) > Math.Abs(dy)) {
      if(OrganismRandom.Next(2) == 1) {
        return new Point(Position.X,(target.GridY + size) * 8);
      } else {
        return new Point(Position.X,(target.GridY - size) * 8);
      }
    } else {
      if(OrganismRandom.Next(2) == 1) {
        return new Point((target.GridX + size) * 8,Position.Y);
      } else {
        return new Point((target.GridX - size) * 8,Position.Y);
      }
    }
  }
      void IdleEvent(object sender, IdleEventArgs e)
      {
          if(CanReproduce){
              BeginReproduction(null);
          }
          ScanAll();
          MakeMap();
          if(OldAge()&&Friends.Count > 0)
          {
              Attack();
              Defend();
            if(AS.Count>0)
                      map.findingFood(AS);
              else
              if(AttackAS.Count>0)
              {
                  if(!isclose)
                  map.findingFood(AttackAS);
                  else 
                      StopMoving();
              }
              else if(FoundAS.Count>0){
                if(!isclose)
                          map.findingFood(FoundAS);
                  else
                      StopMoving();
              }else               if(!map.chaseenemy(Friends,Species.MaximumSpeed))
              {
                  map.ResetCost();
              }
          }
          else{
              Eat();
              Attack();
              Defend();
              if(Dead.Count > 0 && !isCarnivoreNear && !isfood){
                  MyAntenna = Antenna.None;
                  if(!map.findingFood(Dead))
                  {
                      map.ResetCost();
                  }
              }
              else if (State.StoredEnergy<50)
              {
                  TryWalk();
                  MyAntenna = Antenna.None;
              }
              else if((kamo.Count==0||kyoi.Count>0)&&AS.Count>0)
                  map.chaseenemy(AS,Species.MaximumSpeed);
            else if((kamo.Count==0||kyoi.Count>0)&&AttackAS.Count>0)
              {
                  if(!isclose)
                      map.chaseenemy(AttackAS,8);
                  else
                      StopMoving();
              }
              else if((kamo.Count==0||kyoi.Count>0)&&FoundAS.Count>0){
                 if(!isclose)
                      map.chaseenemy(FoundAS,8);
                  else
                      StopMoving();
              }
              else if(kyoi.Count>0 || SeenCarnivores.Count > 0){
                if(Friends.Count>0&&CellDistanceTo((OrganismState)Friends[0])<4)
                          StopMoving();
                 else
                      map.runawayFromEnemy(kyoi);
              }
              else if(kamo.Count>0){
                  MyAntenna = Antenna.None;
                  AnimalState best = (AnimalState) kamo[0];
                  int dist=CellDistanceTo(best);
                  int speed = 12;
                  if(dist<4)
                      speed=Species.MaximumSpeed;
                  else if(best.CurrentMoveToAction != null)
                      speed = Math.Max(12,Math.Min(Species.MaximumSpeed,best.CurrentMoveToAction.MovementVector.Speed+1));
                  else
                      speed=12;
                  if(!map.chaseenemy(kamo,speed))
                  {
                      map.ResetCost();
                  }
              }
              else if(esa2.Count>0){
                  AnimalState best = (AnimalState) esa2[0];                  
                  int dist=CellDistanceTo(best);
                  int speed = 3;
                  if(dist<2)
                   speed = Species.MaximumSpeed;
                   if(State.PercentInjured <0.5&&(State.PercentEnergy<0.4||dist<3))
                   map.chaseenemy(esa2,speed);
              }
              else if(esa.Count > 0){
                  AnimalState best = esa[0] as AnimalState;
                  int dist=CellDistanceTo(best);
                    StopMoving();
/*
                  if(Friends.Count ==0)
                  {
                          StopMoving();
                  }
                  else {
                      int speed = 3;
                      if(!map.chaseenemy(esa,speed))
                      {
                          map.ResetCost();
                      }
                  }
                  */
              }
              else
                  TryWalk();
          }
          if(OldAge())
              MyAntenna = Antenna.OldAge;
      }
      void Attack(){
          if(kyoi.Count>0){
              AnimalState closestCarni =(AnimalState)kyoi[0];
              if(WithinAttackingRange(closestCarni))
              {
                  try
                  {
                      BeginAttacking(closestCarni);
                      return;
                  }
                  catch(Exception ex)
                  {
                      WriteTrace(ex.ToString());
                  }
              }
          }
          if(animal.Count>0){
              AnimalState a = (AnimalState)animal[0];
                                                if (CellDistanceTo(a)<5)
                                                if (a.AnimalSpecies.IsCarnivore|| a.EnergyState == EnergyState.Hungry
                                                     || a.EnergyState == EnergyState.Deterioration||CanWin(a,1))
                                                    try{
                                                        BeginAttacking(a);
                                                        return;
                                                    }
                                                    catch {};
          }
          if(RetiredFriends.Count>0){
              AnimalState a = (AnimalState)RetiredFriends[0];
              if (CellDistanceTo(a)<5)
                  try{
                      BeginAttacking(a);
                      return;
                  }
                  catch {};
          }
      }
      void Defend(){
          if(kyoi.Count>0){
              AnimalState closestCarni =(AnimalState)kyoi[0];
              if(WithinAttackingRange(closestCarni))
              {
                  try
                  {
                      BeginDefending(closestCarni);
                      return;
                  }
                  catch(Exception ex)
                  {
                      WriteTrace(ex.ToString());
                  }
              }
          }
          try{
              AnimalState a = (AnimalState)animal[0];
              BeginDefending(a);
          }
          catch{};
      }
     public bool IsMyFriend(AnimalState animalState){
/*
        if (animalState.Species.Skin ==null)
            return false;
        bool ret = false;
        ret=!animalState.AnimalSpecies.IsCarnivore &&
        (animalState.Species.Skin.StartsWith("mary"));
        ret = ret && animalState.AnimalSpecies.SkinFamily == AnimalSkinFamilyEnum.Beetle;
        return ret;
*/
/*        if (animalState.Species.Skin ==null)
            return false;
        bool ret = false;
        ret=!animalState.AnimalSpecies.IsCarnivore &&
        ( animalState.AnimalSpecies.LifeSpan == 600 ) &&
        ( animalState.AnimalSpecies.MaximumEnergyPerUnitRadius == 443 ) &&
        ( animalState.AnimalSpecies.EatingSpeedPerUnitRadius == 2 ) &&
        ( animalState.AnimalSpecies.MaximumAttackDamagePerUnitRadius == 50 ) &&
        ( animalState.AnimalSpecies.MaximumDefendDamagePerUnitRadius == 52 ) &&
        ( animalState.AnimalSpecies.MaximumSpeed == 45 ) &&
        ( animalState.AnimalSpecies.EyesightRadius == 6 )
        &&(animalState.Species.Skin.StartsWith("mary"));
        ret = ret && animalState.AnimalSpecies.SkinFamily == AnimalSkinFamilyEnum.Spider;
        return ret;
*/
/*
        bool ret = false;
        ret=!animalState.AnimalSpecies.IsCarnivore &&
        ret = ret && animalState.AnimalSpecies.SkinFamily == AnimalSkinFamilyEnum.Spider;
        return ret;
        */
          if (animalState.Species.Skin ==null||!animalState.Species.Skin.StartsWith("mari"))
              return false;
          if(!animalState.AnimalSpecies.IsCarnivore &&animalState.AnimalSpecies.MatureRadius == 24&&animalState.Antennas.LeftAntenna==(AntennaPosition)(((animalState.TickAge) * 33 ) % 10))
              return true;
        return false;
    }
/*     public bool IsMyFriend(AnimalState animalState){
        if (animalState.Species.Skin ==null)
            return false;
        bool ret = false;
        ret=!animalState.AnimalSpecies.IsCarnivore &&
        ( animalState.AnimalSpecies.LifeSpan == 600 ) &&
        ( animalState.AnimalSpecies.EatingSpeedPerUnitRadius == 4 ) &&
        ( animalState.AnimalSpecies.MaximumAttackDamagePerUnitRadius == 52 ) &&
        ( animalState.AnimalSpecies.MaximumDefendDamagePerUnitRadius == 57 ) &&
        ( animalState.AnimalSpecies.MaximumSpeed == 30 ) &&
        ( animalState.AnimalSpecies.EyesightRadius == 6 )
        &&(animalState.Species.Skin.StartsWith("mary"));
        ret = ret && animalState.AnimalSpecies.SkinFamily == AnimalSkinFamilyEnum.Ant;
        return ret;
    }
*/
      public Point GetRandPos(){
          Point p;
          do
          {
              int d = (State.CellRadius+1)<<3;
              int x = OrganismRandom.Next(d, WorldWidth-d-1);
              int y = OrganismRandom.Next(d, WorldHeight-d-1);
              p = new Point(x,y);
          }while( p==Position );
          return p;
      }
      void MoveCompletedEvent(object o, MoveCompletedEventArgs e)
      {
          if( e.Reason == ReasonForStop.Blocked &&e.BlockingOrganism !=null&&e.BlockingOrganism is PlantState)
              isBlocked=true;
      }
      void TryWalk()
      {
          if(lastRunaway == null)
          {
              lastRunaway =Vector.Subtract(Position,GetRandPos());
          }
          map.randomwalk(lastRunaway);
      }
      void Eat()
      {
          if( CanEat )
          {
              foreach( OrganismState o in Dead )
              {
                  try{
                      BeginEating( o );
                      return;
                  }catch{};
              }
          }
      }
      public int CellDistanceTo(OrganismState creature)
      {
          return Math.Max(Math.Abs(State.GridX - creature.GridX),
                          Math.Abs(State.GridY - creature.GridY)) -     State.CellRadius - creature.CellRadius - 1;
      }
      public int CellDistanceTo(OrganismState creature1,OrganismState creature2)
      {
          return Math.Max(Math.Abs(creature1.GridX - creature2.GridX),
                          Math.Abs(creature1.GridY - creature2.GridY)) -     creature1.CellRadius - creature2.CellRadius - 1;
      }
      Point GetGrid( Point p ){
          return new Point( p.X>>3 , p.Y>>3 );
      }
      bool OldAge()
      {
          if(State.ReproductionWait > Species.LifeSpan - State.TickAge)
           return true;
        if(State.Species.GrowthWait*(State.Species.MatureRadius - State.Radius)> Species.LifeSpan - State.TickAge)
         return true;
         return false;
      }
      bool OldAge(AnimalState a)
      {
              if(a.ReproductionWait > a.Species.LifeSpan - a.TickAge)
           return true;
        if(a.Species.GrowthWait*(a.Species.MatureRadius - a.Radius)> a.Species.LifeSpan - a.TickAge)
         return true;
         return false;    
    }
      void AttackedEvent (object sender, AttackedEventArgs e)
      {
          Attackers.Add(e.Attacker);
      }
      private void ScanAll()
      {
          Hashtable tmp1 = new Hashtable() ;
          for( int i = 0 ; i < 3 ; i++ ){
              ArrayList tmp = Scan();
              foreach (OrganismState creature in tmp)
              {
                  if(tmp1.ContainsKey(creature.ID))
                      tmp1.Remove(creature.ID);
                  tmp1.Add(creature.ID,creature);
              }
          }
          ArrayList tmp2= new ArrayList();
          foreach(OrganismState creature in Creatures.Values) {
            if(creature == null )
                continue;
              if(tmp1.ContainsKey(creature.ID))
                  tmp2.Add(creature.ID);
              else
                  {
                      int j = 1;
                      AnimalState an = creature as AnimalState;
                      if(an != null &&an.AnimalSpecies.InvisibleOdds >0)
                          j = 10;
                      OrganismState org = null ;
                      int i = 0;
                      do{
                          org = RefreshState(creature.ID);
                          if(org != null && !tmp1.ContainsKey(creature.ID))
                              tmp1.Add(creature.ID,org);
                          i++;
                      }
                      while( i < j && org == null);
                      if(org ==null && !tmp2.Contains(creature.ID))
                          tmp2.Add(creature.ID);
                  }
          }
          foreach(String str in tmp2){
              if(SeenCreatures.ContainsKey(str))
                  SeenCreatures.Remove(str);
              if(Creatures[str] != null&&((OrganismState)Creatures[str]).IsAlive)
                  SeenCreatures.Add(str,new SeenCreature((OrganismState) Creatures[str], State.TickAge));
          }
          Creatures = tmp1;
          foreach(OrganismState org in Attackers)
              if(!Creatures.ContainsKey(org.ID))
                  Creatures.Add(org.ID,org);
          foreach(OrganismState org in Creatures.Values) {
            if(org == null )
                    continue;
              if(SeenCreatures.ContainsKey(org.ID))
                  SeenCreatures.Remove(org.ID);
              if(org is PlantState){
                  Plants.Add(org);
                  if(CellDistanceTo(org)<=Species.MaximumSpeed>>3+1)
                      isBlocked=true;
              }
              else {
                  if(!((AnimalState)org).IsAlive)
                      Dead.Add(org);
                  else
                      if(IsMySpecies((AnimalState)org)){
                          if(AnimalAntenna((AnimalState)org)==Antenna.FoundAS){
                              if(CellDistanceTo(org)==0)
                                  isclose=true;
                              FoundAS.Add(org);
                          }
                          if(AnimalAntenna((AnimalState)org)==Antenna.AttackAS){
                              if(CellDistanceTo(org)==0)
                                  isclose=true;
                              AttackAS.Add(org);
                          }
                          if(AnimalAntenna((AnimalState)org)==Antenna.OldAge)
                              RetiredFriends.Add(org);
                          else {
                              if(CellDistanceTo(org)<=Species.MaximumSpeed>>3+1)
                                  isBlocked=true;
                              Friends.Add(org);
                          }
                      }
                      else {
                          animal.Add(org);
                          if(((AnimalState)org).AnimalSpecies.IsCarnivore){
                              if(CanWin((AnimalState) org,0.8 ))
                                  kamo.Add(org);
                              else {
                                if(CellDistanceTo(org)<2 )
                                      MyAntenna = Antenna.AttackAS;
                                  else
                                    MyAntenna = Antenna.FoundAS;
                                  if(!CanWin((AnimalState) org,1.1)){
                                AS.Add(org);
                                      kyoi.Add(org);
                                      if(CellDistanceTo(org)<5)
                                          isCarnivoreNear=true;
                                  }
                              }
                          }
                          else if(IsMyFriend((AnimalState)org))
                          {
                            if(!OldAge((AnimalState)org))
                                animal.Remove(org);
                              esa.Add(org);
                          }
                          else {
                                if(!CanWin((AnimalState) org,1.1))
                                {                            
                                  }
                                  else 
                                      esa2.Add(org);
                          }
                      }
              }
          }
/*          if(AttackAS.Count>0 && AS.Count == 0){
              if(OldAge())
                  MyAntenna = Antenna.OldAge;
              else
                  MyAntenna = Antenna.None;
          }
*/
          ArrayList keys = new ArrayList();
          foreach(String str in SeenCreatures.Keys){
            if(SeenCreatures[str] == null)
                continue;
              int tick = 7;
              AnimalState an2 = Creatures[str] as AnimalState;
              if(an2 != null &&an2.AnimalSpecies.InvisibleOdds >0)
                  tick = 15;
              if (this.State.TickAge - ((SeenCreature) SeenCreatures[str]).tick > tick)
                  keys.Add(str);
              else
                  {
                      AnimalState an = ((SeenCreature) SeenCreatures[str]).creature as AnimalState;
                      if(an != null
                         &&an.IsAlive
                         &&an.AnimalSpecies.IsCarnivore
                         &&!CanWin(an,1.1))
                         SeenCarnivores.Add(an.Position);
                  }
          }
          foreach(String str in keys)
              SeenCreatures.Remove(str);
          DistComparer3 dc =new DistComparer3(this);
        if(Attackers.Count>1)
          foreach(OrganismState os in Attackers){
              if(!kyoi.Contains(os))
                  kyoi.Add(os); 
              if(!SeenCarnivores.Contains(os.Position))
               SeenCarnivores.Add(os.Position);
          }
          kyoi.Sort(dc);
          kamo.Sort(dc);
          esa.Sort(dc);
          esa2.Sort(dc);
          animal.Sort(dc);
          RetiredFriends.Sort(dc);
          Plants.Sort(dc);
          Friends.Sort(dc);
          Dead.Sort(dc);
          ArrayList tmp3 = new ArrayList();
          AS.Sort(dc);
          foreach(AnimalState as1 in AS)
          {
            int best = CellDistanceTo((OrganismState)AS[0]);
              foreach(AnimalState as2 in AttackAS)
              {
                int dist = CellDistanceTo(as1,as2);
                  if(    dist<5&&dist<=best&&!tmp3.Contains(as1))
                      tmp3.Add(as1);
              }
              foreach(AnimalState as2 in FoundAS)
              {
                int dist = CellDistanceTo(as1,as2);
                  if(    dist<5&&dist<=best&&!tmp3.Contains(as1))
                      tmp3.Add(as1);
              }
          }
          AS = tmp3;
          if(Dead.Count>0 && kyoi.Count>0)
          foreach(AnimalState as1 in Dead)
        {
            int best = 100;
              foreach(AnimalState as2 in kyoi)
            {
            if(!as2.AnimalSpecies.IsCarnivore)
                continue;
                int dist = CellDistanceTo(as1,as2);        
                if(best > dist)
                    best = dist;
            }
            if(best < CellDistanceTo(as1))
                isfood = true;    
        }
      }
      private double LeftTicks(AnimalState d,AnimalState a) {
          double dHitpoint = EngineSettings.DamageToKillPerUnitOfRadius * d.Radius - d.Damage;
          double aAttackpoint = a.AnimalSpecies.MaximumAttackDamagePerUnitRadius * a.Radius;
          double dDefendpoint = d.AnimalSpecies.MaximumDefendDamagePerUnitRadius * d.Radius;
          return dHitpoint / Math.Max(1,aAttackpoint - dDefendpoint + 500);
      }
      private bool CanWin(AnimalState target,double canWinAlpha) {
          if(target == null) return false;
          return canWinAlpha*LeftTicks(State,target) > LeftTicks(target,State);
      }
      /*
      private bool CanWin(AnimalState defender,double canWinAlpha) {
          double attackerAttackDefend  = (State.AnimalSpecies.MaximumAttackDamagePerUnitRadius+State.AnimalSpecies.MaximumDefendDamagePerUnitRadius)*State.Radius;
          double defenderAttackDefend  = (defender.AnimalSpecies.MaximumAttackDamagePerUnitRadius+defender.AnimalSpecies.MaximumDefendDamagePerUnitRadius)*defender.Radius;
          double attackerCanLoose = EngineSettings.DamageToKillPerUnitOfRadius*State.Radius-State.Damage;
          double defenderCanLoose = EngineSettings.DamageToKillPerUnitOfRadius*defender.Radius-defender.Damage;
          if(defenderCanLoose<0) defenderCanLoose=0.01;
          if(attackerCanLoose<0) attackerCanLoose=0.01;
          return  ((attackerCanLoose*attackerAttackDefend) / (defenderCanLoose*defenderAttackDefend) > canWinAlpha);
      }
      public double CanWin(AnimalState defender)
      {
          double attackerCanLoose = EngineSettings.DamageToKillPerUnitOfRadius*State.Radius-State.Damage;
          double defenderCanLoose = EngineSettings.DamageToKillPerUnitOfRadius*defender.Radius-defender.Damage;
          if(defenderCanLoose<0) defenderCanLoose=0.01;
          if(attackerCanLoose<0) attackerCanLoose=0.01;
          double attackerAttackDefend  = (State.AnimalSpecies.MaximumAttackDamagePerUnitRadius+State.AnimalSpecies.MaximumDefendDamagePerUnitRadius)*State.Radius;
          double defenderAttackDefend  = (defender.AnimalSpecies.MaximumAttackDamagePerUnitRadius+defender.AnimalSpecies.MaximumDefendDamagePerUnitRadius)*defender.Radius;
          return  ((attackerCanLoose*attackerAttackDefend) / (defenderCanLoose*defenderAttackDefend));
      }
      */
      private void MakeMap()
      {
          map.Update();
      }
      public OrganismState ClosestCreature(ArrayList array)
      {
          if ((array == null) || (array.Count == 0))
              return null;
          OrganismState bestCreature = (OrganismState) array[0];
          foreach (OrganismState creature in array)
              if (DistanceTo(creature) < DistanceTo(bestCreature))
                  bestCreature = creature;
          return bestCreature;
      }
      private Antenna MyAntenna
      {
          get
          {
              return (Antenna) this.Antennas.LeftAntenna;
          }
          set
          {
              this.Antennas.LeftAntenna = (AntennaPosition) value;
          }
      }
      private Antenna AnimalAntenna(AnimalState animal)
      {
          return (Antenna) animal.Antennas.LeftAntenna;
      }
      private enum Antenna
      {
          None = AntennaPosition.Bottom,
          OldAge = AntennaPosition.Backward,
          FoundAS = AntennaPosition.Left,
          AttackAS = AntennaPosition.BottomLeft
      }
      public override void SerializeAnimal(MemoryStream m)
      {
      }
      public override void DeserializeAnimal(MemoryStream m)
      {
      }
  }
  public class UtilMap
  {
      private class DistComparer : IComparer {
          Vector v;
          public DistComparer(Vector v) {
              this.v =v;
          }
          public int Compare(object a,object b) {
              if(a==null || b ==null)
                  return 0;
              Vector va = Vector.Subtract(new Point(0,0),(Point)a);
              Vector vb = Vector.Subtract(new Point(0,0),(Point)b);
              va = va.GetUnitVector();
              vb = vb.GetUnitVector();
              double da = v.X*va.X+v.Y*va.Y;
              double db = v.X*vb.X+v.Y*vb.Y;
              return((int)(db - da));
          }
      }
      private class DistComparer2 : IComparer {
          ArrayList enemies;
          Point myPoint;
          Animal my;
          public DistComparer2(ArrayList enemies,Point myPoint,Animal my) {
              this.enemies = enemies;
              this.myPoint = myPoint;
              this.my      = my;
          }
          public int Compare(object a,object b) {
              if(a==null || b ==null)
                  return 0;
              int ax = ((Point)a).X;
              int ay = ((Point)a).Y;
              int bx = ((Point)b).X;
              int by = ((Point)b).Y;
              double besta = -1;
              double bestb = -1;
              foreach(Point enemy in enemies)
              {
                  double tmpa =((enemy.X-myPoint.X)*ax+(enemy.Y-myPoint.Y)*ay)
                  /(Math.Sqrt((enemy.X-myPoint.X)*(enemy.X-myPoint.X)+(enemy.Y-myPoint.Y)*(enemy.Y-myPoint.Y))
                    *Math.Sqrt(ax*ax+ay*ay));
                  double tmpb =((enemy.X-myPoint.X)*bx+(enemy.Y-myPoint.Y)*by)
                  /(Math.Sqrt((enemy.X-myPoint.X)*(enemy.X-myPoint.X)+(enemy.Y-myPoint.Y)*(enemy.Y-myPoint.Y))
                    *Math.Sqrt(bx*bx+by*by));
                  if(besta < tmpa)
                      besta = tmpa;
                  if(bestb < tmpb)
                      bestb = tmpb;
              }
              if(my.State.CurrentMoveToAction != null) {
                  MovementVector mv = my.State.CurrentMoveToAction.MovementVector;
                  Point D = mv.Destination;
                  double tmpa =((myPoint.X-D.X)*ax+(myPoint.Y-D.Y)*ay)
                  /(Math.Sqrt((D.X-myPoint.X)*(D.X-myPoint.X)+(D.Y-myPoint.Y)*(D.Y-myPoint.Y))
                    *Math.Sqrt(ax*ax+ay*ay));
                  double tmpb =((myPoint.X-D.X)*bx+(myPoint.Y-D.Y)*by)
                  /(Math.Sqrt((D.X-myPoint.X)*(D.X-myPoint.X)+(D.Y-myPoint.Y)*(D.Y-myPoint.Y))
                    *Math.Sqrt(bx*bx+by*by));
                  if(besta < tmpa)
                      besta = tmpa;
                  if(bestb < tmpb)
                      bestb = tmpb;
              }
              return (Math.Sign(besta - bestb));
          }
          private int CellDistance(Point P1 , Point P2)
          {
              return Math.Max(Math.Abs(P1.X>>3 - P2.X>>3 ),
                              Math.Abs(P1.Y>>3 - P2.Y>>3 )) - 5;
          }
      }
      /*      private class DistComparer2 : IComparer {
          ArrayList enemies;
          Point myPoint;
          public DistComparer2(ArrayList enemies,Point myPoint) {
              this.enemies = enemies;
              this.myPoint = myPoint;
          }
          public int Compare(object a,object b) {
              if(a==null || b ==null)
                  return 0;
              int  da = 0;
              int  db = 0;
              int dax = 0;
              int day = 0;
              int dbx = 0;
              int dby = 0;
              int ax = ((Point)a).X<<3;
              int ay = ((Point)a).Y<<3;
              int bx = ((Point)b).X<<3;
              int by = ((Point)b).Y<<3;
              foreach(Point enemy in enemies)
              {
                  dax +=enemy.X-(ax+myPoint.X);
                  day +=enemy.Y-(ay+myPoint.Y);
                  dbx +=enemy.X-(bx+myPoint.X);
                  dby +=enemy.Y-(by+myPoint.Y);
              }
              da=dax*dax+day*day;
              db=dbx*dbx+dby*dby;
              return((int)(db - da));
          }
          */
          /*    public int Compare(object a,object b) {
              if(a==null || b ==null)
                  return 0;
              double da = 0;
              double db = 0;
              int ax = ((Point)a).X<<3;
              int ay = ((Point)a).Y<<3;
              int bx = ((Point)b).X<<3;
              int by = ((Point)b).Y<<3;
              foreach(Point enemy in enemies)
              {
                  int tmp;
                  tmp =( (enemy.X-(ax+myPoint.X))*(enemy.X-(ax+myPoint.X))
                        +(enemy.Y-(ay+myPoint.Y))*(enemy.Y-(ay+myPoint.Y)));
                  if(tmp == 0)
                      da = int.MaxValue;
                  else
                      da +=100000000/tmp;
                  tmp = ((enemy.X-(bx+myPoint.X))*(enemy.X-(bx+myPoint.X))
                         +(enemy.Y-(by+myPoint.Y))*(enemy.Y-(by+myPoint.Y))) ;
                  if(tmp == 0)
                      db = int.MaxValue;
                  else
                      db += 100000000/tmp;
              }
              return((int)(da - db));
          }
          */
          private MyCreature my;
      private int XSize, YSize;
      private int MapPosX, MapPosY;
      private int MaxX;
      private int MaxY;
      private bool[,] blocked ;
      private bool[,] creatures ;
      public int [,] costs;
      private Queue queue ;
      Point   foundPoint;
      Point   beginPoint;
      ArrayList Direction4;
      ArrayList Direction8;
      int d,e;
      public UtilMap(MyCreature my)
      {
          this.my=my;
          MaxX = my.WorldWidth >> EngineSettings.GridWidthPowerOfTwo;
          MaxY = my.WorldHeight>> EngineSettings.GridHeightPowerOfTwo;
          XSize = my.Species.EyesightRadius;
          YSize = my.Species.EyesightRadius;
          Direction4 = new ArrayList(4);
          Direction8 = new ArrayList(8);
          blocked = new bool[XSize<<1+1,YSize<<1+1];
          creatures = new bool[XSize<<1+1,YSize<<1+1];
          costs = new int[XSize<<1+1,YSize<<1+1];
          queue = new Queue();
          /*        direction = new Point[2,2,2,4];
          for(int i=0;i<2;i++)
              for(int j=0;j<2;j++)
                  for(int k=0;k<2;k++)
                  {
                      direction[i,j,k,0]=new Point((i==0?0:1)*(j==0?1:-1),(i==0?1:0)*(k==0?1:-1));
                      direction[i,j,k,1]=new Point((i==0?1:0)*(j==0?1:-1),(i==0?0:1)*(k==0?1:-1));
                      direction[i,j,k,2]=new Point((i==0?1:0)*(j==0?-1:1),(i==0?0:1)*(k==0?-1:1));
                      direction[i,j,k,3]=new Point((i==0?0:1)*(j==0?-1:1),(i==0?1:0)*(k==0?-1:1));
                  }
                  */
                  for(int x=-1;x<=1;x++)
                      for(int y=-1;y<=1;y++)
                      {
                          if(Math.Abs(x)!=Math.Abs(y))
                              Direction4.Add(new Point(x,y));
                          if(x!=0||y!=0)
                              Direction8.Add(new Point(x,y));
                      }
      }
      public void Update()
      {
          Reset();
          foreach(OrganismState creature in my.Plants) {
              addBlocker(creature);
          }
          foreach(OrganismState creature in my.Friends) {
              addBlocker(creature);
          }
          foreach(OrganismState creature in my.kyoi) {
              addBlocker(creature);
          }
          foreach(OrganismState creature in my.esa) {
              addBlocker(creature);
          }          
          foreach(OrganismState creature in my.Dead) {
              addBlocker(creature);
          }
      }
      public void ResetCost()
      {
          for(int i=0;i<=XSize<<1;i++)
              for(int ii=0;ii<=YSize<<1;ii++)
                  costs[i,ii] =int.MaxValue;
          queue.Clear();
      }
      private void Reset()
      {
          d = ((Int32)Math.Round( Math.Cos( (double)my.State.ActualDirection / 180 * Math.PI ) * my.State.Speed ));
          e = ((Int32)Math.Round( Math.Sin( (double)my.State.ActualDirection / 180 * Math.PI ) * my.State.Speed ));
          MapPosX = my.Position.X >> EngineSettings.GridWidthPowerOfTwo;
          MapPosY = my.Position.Y >> EngineSettings.GridHeightPowerOfTwo;
          int a = my.State.CellRadius;
          int b = MaxX-a;
          int c = MaxY-a;
          for(int i=0;i<=XSize<<1;i++) {
              for(int ii=0;ii<=YSize<<1;ii++)
              {
                  creatures[i,ii] = false;
                  costs[i,ii] =int.MaxValue;
                  int x = i+MapPosX-XSize;
                  int y = ii+MapPosY-YSize;
                  if(x<=a || x>=b||y<=a || y>=c)
                  {
                      blocked[i,ii]= true;
                  }
                  else
                      {
                          blocked[i,ii]= false;
                      }
              }
          }
          queue.Clear();
      }
      private Point GetRealPoint(Point m)
      {
          Point p = new Point((int)((m.X+MapPosX-XSize)*EngineSettings.GridCellWidth),
                              (int)((m.Y+MapPosY-YSize)*EngineSettings.GridCellHeight));
          return p;
      }
      public bool findingFood(ArrayList foods)
      {
          foundPoint = new Point(XSize,YSize);
          beginPoint = foundPoint;
          foreach(OrganismState food in foods) {
              if(my.State.IsAdjacentOrOverlapping(food))
              {
                  return true;
              }
              addCreature(food);
          }
          if(creatures[XSize,YSize])
              return false;
          queue.Enqueue(new Point(XSize,YSize));
          costs[XSize,YSize]=0;
          while(queue.Count>0&&(foundPoint.X == XSize&&foundPoint.Y == YSize))
              calcPath();
          if(foundPoint.X!=XSize||foundPoint.Y!=YSize)
          {
              try{
                  int speed = 12;
                  if(my.AS.Count>0)
                      speed = my.Species.MaximumSpeed;
                  my.BeginMoving(GetMovementVector2(backTrace2(foundPoint),speed));
                  return true;
              }catch{};
          }
          return false;
      }
      public bool chaseenemy(ArrayList foods,int speed)
      {
              foundPoint = new Point(XSize,YSize);
          beginPoint = foundPoint;
          costs[beginPoint.X,beginPoint.Y]=0;
              if(!my.isBlocked )
              {
                  OrganismState food = (OrganismState) foods[0];
                  double dist = my.DistanceTo(food);
                  Point p = food.Position;
                  if(food.CurrentMoveToAction != null) {
                      MovementVector mv = food.CurrentMoveToAction.MovementVector;
                      Point D = mv.Destination;
                      Vector vector = Vector.Subtract(food.Position,D);
                      vector = vector.GetUnitVector().Scale(dist * 0.03 * mv.Speed);
                      p = RangeCheck(Vector.Add(p,vector));
                  }
                  /*
                  if(my.CellDistanceTo(food) < 2){
                      Point myp = new Point(my.Position.X-d,my.Position.Y-e);
                      p =RangeCheck(Vector.Add(myp,Vector.Subtract(myp,p).Scale(100)));
                      speed = my.Species.MaximumSpeed;
                  }
                  */
                  if(p != Point.Empty)
                      my.BeginMoving(new MovementVector(p,MinSpeedToReachPointInTick(p,speed)));
                  /*                  if(!my.IsMySpecies(food)){
                      try{
                          my.BeginAttacking(food as AnimalState);
                          my.BeginDefending(food as AnimalState);
                      }
                      catch{};
                  }
                  */
                  return true;
              }
              foreach(OrganismState food in foods) {
                  addCreature(food);
              }
              if(creatures[beginPoint.X,beginPoint.Y])
                  return true;
          queue.Enqueue(beginPoint);
          Vector v = Vector.Subtract(my.Position,((OrganismState)foods[0]).Position);
          Direction4.Sort(new DistComparer(v));
          Direction8.Sort(new DistComparer(v));
          while(queue.Count>0&&foundPoint == beginPoint)
          {
              if(my.isBlocked)
              {
                  calcPath();
              }
              else
                  {
                      calcPath2();
                  }
          }
          if(foundPoint!=beginPoint)
          {
              try{
                  if(my.isBlocked)
                      my.BeginMoving(GetMovementVector2(backTrace2(foundPoint),speed));
                  else
                      my.BeginMoving(GetMovementVector(backTrace(foundPoint),speed));
                  return true;
              }catch{
              }
          }
          return false;
      }
      private void calcPath()
      {
          Point p = (Point)(queue.Dequeue());
          foreach(Point q in Direction4){
              int X = q.X+p.X;
              int Y = q.Y+p.Y;
              if(X>=0&&Y>=0&&X<=(XSize<<1)&&Y<=(YSize<<1)&&!blocked[X,Y] &&costs[X,Y]>costs[p.X,p.Y]+1)
              {
                  costs[X,Y]=costs[p.X,p.Y]+1;
                  Point tmp = new Point(X,Y);
                  if(!queue.Contains(tmp))
                      queue.Enqueue(tmp);
                  if(creatures[X,Y] == true)
                  {
                      foundPoint= tmp;
                      return;
                  }
              }
          }
      }
      private void calcPath2()
      {
          Point p = (Point)(queue.Dequeue());
          foreach(Point q in Direction8){
              int X = q.X+p.X;
              int Y = q.Y+p.Y;
              int cost = 0;
              if((q.X==-1||q.X==1)&&(q.Y==-1||q.Y==1))
                  cost = 3;
              else
                  cost = 2;
              if(X>=0&&Y>=0&&X<=(XSize<<1)&&Y<=(YSize<<1)&&!blocked[X,Y] &&costs[X,Y]>costs[p.X,p.Y]+cost)
              {
                  costs[X,Y] = costs[p.X,p.Y]+cost;
                  Point tmp = new Point(X,Y);
                  if(!queue.Contains(tmp))
                      queue.Enqueue(tmp);
                  if(creatures[X,Y] == true)
                  {
                      foundPoint= tmp;
                      return;
                  }
              }
          }
      }
      public void runawayFromEnemy(ArrayList enemies)
      {
          ArrayList distance=new ArrayList();
              foundPoint = new Point(XSize,YSize);
          beginPoint = foundPoint;
          /*        foreach(OrganismState enemy in enemies) {
              int xpos = (enemy.Position.X >> EngineSettings.GridWidthPowerOfTwo)-MapPosX+XSize;
              int ypos = (enemy.Position.Y >> EngineSettings.GridHeightPowerOfTwo)-MapPosY+YSize;
              beginX += xpos;
              beginY += ypos;
              addCreature(enemy);
          }
          beginPoint = new Point ((int)(beginX/enemies.Count),(int)(beginY/enemies.Count));
          */
          costs[beginPoint.X,beginPoint.Y]=0;
          foreach(OrganismState enemy in enemies)
          {
              distance.Add(enemy.Position);
          }
          foreach(Point F in my.SeenCarnivores)
              distance.Add(F);
          Point P = my.Position;
              Direction4.Sort(new DistComparer2(distance,P,my));
          Direction8.Sort(new DistComparer2(distance,P,my));
          if(my.isBlocked)
          {
              calcPath4(beginPoint.X,beginPoint.Y,Point.Empty);
          }
          else
              {
                  calcPath5(beginPoint.X,beginPoint.Y,Point.Empty);
              }
              if(foundPoint!=beginPoint){
                  AnimalState an;
                  int speed;
                  if(enemies.Count>0)
                  {
                      an =(AnimalState)enemies[0];
                      /*
                      int xpos = (an.Position.X >> EngineSettings.GridWidthPowerOfTwo)-MapPosX;
                      int ypos = (an.Position.Y >> EngineSettings.GridHeightPowerOfTwo)-MapPosY;
                      if((foundPoint.X-XSize)*xpos*(foundPoint.Y-YSize)*ypos>0)
                          a=Math.Abs(an.Position.X-my.Position.X) < Math.Abs(an.Position.Y-my.Position.Y)?0:1;
                      else
                          a=(foundPoint.X-XSize)*xpos>0?0:1;
                      b=an.Position.X<0?0:1;
                      c=an.Position.Y<0?0:1;
                      */
                      double h = (Vector.Subtract(my.Position,an.Position)).Magnitude;
                      speed = h>80 ? Math.Min(Math.Max(an.Speed+2 ,3),my.Species.MaximumSpeed) :  my.Species.MaximumSpeed;
                    }
                  else
                      speed = 3;
                  try{
                      if(my.isBlocked)
                          my.BeginMoving(GetMovementVector2(backTrace2(foundPoint),speed));
                      else
                          my.BeginMoving(GetMovementVector(backTrace(foundPoint),speed));
                  }catch{
                  }
              }
      }
      public void randomwalk(Vector v)
      {
              foundPoint = new Point(XSize,YSize);
          beginPoint = foundPoint;
          /*        foreach(OrganismState enemy in enemies) {
              int xpos = (enemy.Position.X >> EngineSettings.GridWidthPowerOfTwo)-MapPosX+XSize;
              int ypos = (enemy.Position.Y >> EngineSettings.GridHeightPowerOfTwo)-MapPosY+YSize;
              beginX += xpos;
              beginY += ypos;
              addCreature(enemy);
          }
          beginPoint = new Point ((int)(beginX/enemies.Count),(int)(beginY/enemies.Count));
          */
          costs[beginPoint.X,beginPoint.Y]=0;
              if(v != null){
                  Direction4.Sort(new DistComparer(v));
                  Direction8.Sort(new DistComparer(v));
              }
              if(my.isBlocked)
              {
                  calcPath4(beginPoint.X,beginPoint.Y,Point.Empty);
              }
              else
                  {
                      calcPath5(beginPoint.X,beginPoint.Y,Point.Empty);
                  }
                  if(foundPoint!=beginPoint){
                      try{
                          if(my.isBlocked)
                              my.BeginMoving(GetMovementVector2(backTrace2(foundPoint),3));
                          else
                              my.BeginMoving(GetMovementVector(backTrace(foundPoint),3));
                      }catch{
                      }
                  }
      }
      private bool calcPath4(int x,int y , Point P)
      {
          if(x==0||y==0||x==(XSize<<1)||y==(YSize<<1))
          {
              foundPoint = new Point(x,y);
              return true;
          }
          if(P != Point.Empty ){
              if(x+P.X>=0&&y+P.Y>=0&&x+P.X<=(XSize<<1)&&y+P.Y<=(YSize<<1)&&!blocked[x+P.X,y+P.Y] )
              {
                  int cost=costs[x,y]+2;
                  if(costs[x+P.X,y+P.Y]>cost)
                  {
                      costs[x+P.X,y+P.Y]=cost;
                      if(calcPath4(x+P.X,y+P.Y,P))
                          return true;
                  }
              }
          }
          foreach(Point p in Direction4)
              if(x+p.X>=0&&y+p.Y>=0&&x+p.X<=(XSize<<1)&&y+p.Y<=(YSize<<1)&&!blocked[x+p.X,y+p.Y] )
              {
                  int cost=costs[x,y]+2;
                  if(costs[x+p.X,y+p.Y]>cost)
                  {
                      costs[x+p.X,y+p.Y]=cost;
                      if(calcPath4(x+p.X,y+p.Y,p))
                          return true;
                  }
              }
              return false;
      }
      private bool calcPath5(int x,int y,Point P)
      {
          if(x==0||y==0||x==(XSize<<1)||y==(YSize<<1))
          {
              foundPoint = new Point(x,y);
              return true;
          }
          if(P != Point.Empty)
              if(x+P.X>=0&&y+P.Y>=0&&x+P.X<=(XSize<<1)&&y+P.Y<=(YSize<<1)&&!blocked[x+P.X,y+P.Y] )
              {
                  int cost;
                  if((P.X==-1||P.X==1)&&(P.Y==-1||P.Y==1))
                      cost=costs[x,y]+3;
                  else
                      cost=costs[x,y]+2;
                  if(costs[x+P.X,y+P.Y]>cost)
                  {
                      costs[x+P.X,y+P.Y]=cost;
                      if(calcPath5(x+P.X,y+P.Y,P))
                          return true;
                  }
              }
              foreach(Point p in Direction8)
                  if(x+p.X>=0&&y+p.Y>=0&&x+p.X<=(XSize<<1)&&y+p.Y<=(YSize<<1)&&!blocked[x+p.X,y+p.Y] )
                  {
                      int cost;
                      if((p.X==-1||p.X==1)&&(p.Y==-1||p.Y==1))
                          cost=costs[x,y]+3;
                      else
                          cost=costs[x,y]+2;
                      if(costs[x+p.X,y+p.Y]>cost)
                      {
                          costs[x+p.X,y+p.Y]=cost;
                          if(calcPath5(x+p.X,y+p.Y,p))
                              return true;
                      }
                  }
                  return false;
      }
      private ArrayList backTrace(Point target)
      {
          ArrayList ret = new ArrayList();
          Point last = target;
          int dx = target.X-XSize;
          int dy = target.Y-YSize;
          ret.Add(target);
          while(last!=beginPoint)
          {
              Point best = last;
                  foreach(Point p in Direction8)
                  {
                      int X=last.X+p.X;
                      int Y=last.Y+p.Y;
                      if(X>=0&&X<=XSize<<1&&Y>=0&&Y<=YSize<<1&&costs[X,Y]=0&&X<=XSize<<1&&Y>=0&&Y<=YSize<<1&&costs[X,Y]0)
          {
              moveTo = (Point) path[1];
              moveFrom = (Point) path[0];
          }
          else
              {
                  return null;;
              }
              int pos=1;
          Point next = (Point)path[0];
          Point last;
          do
          {
              last = next;
              if(pos0)
          {
              moveTo = (Point) path[1];
              moveFrom = (Point) path[0];
          }
          else
              {
                  return null;;
              }
              int pos=1;
          Point next = (Point)path[0];
          Point last;
          do
          {
              last = next;
              if(pos> EngineSettings.GridWidthPowerOfTwo)-MapPosX+XSize;
          int ypos = (o.Position.Y >> EngineSettings.GridHeightPowerOfTwo)-MapPosY+YSize;
          int size = o.CellRadius+my.State.CellRadius;
          for (int i=Math.Max(xpos-size,0); i<=Math.Min(xpos+size,XSize<<1); i++)
              for (int ii=Math.Max(ypos-size,0); ii<=Math.Min(ypos+size,YSize<<1); ii++)
              {
                  blocked[i,ii] = true;
              }
      }
      private void addCreature(OrganismState o)
      {
          int xpos = (o.Position.X >> EngineSettings.GridWidthPowerOfTwo)-MapPosX+XSize;
          int ypos = (o.Position.Y >> EngineSettings.GridHeightPowerOfTwo)-MapPosY+YSize;
          int size = o.CellRadius+my.State.CellRadius+1;
          for (int i=xpos-size; i<=xpos+size; i++)
              for (int ii=ypos-size; ii<=ypos+size; ii++)
              {
                  creatures[Math.Max(Math.Min(i,XSize<<1),0),Math.Max(0,Math.Min(ii,YSize<<1))] = true;
              }
      }
      private void addCreature(ArrayList a)
      {
          foreach(OrganismState o in a)
        {
              int xpos = (o.Position.X >> EngineSettings.GridWidthPowerOfTwo)-MapPosX+XSize;
              int ypos = (o.Position.Y >> EngineSettings.GridHeightPowerOfTwo)-MapPosY+YSize;
              int size = o.CellRadius+my.State.CellRadius+1;
              for (int i=xpos-size; i<=xpos+size; i++)
                  for (int ii=ypos-size; ii<=ypos+size; ii++)
                  {
                    int x = Math.Max(Math.Min(i,XSize<<1),0);
                    int y = Math.Max(0,Math.Min(ii,YSize<<1));
                    bool flag = false;
                      foreach(OrganismState o2 in a)
                      {
                          if(o2 != o && CellDistanceTo( o2 , x + MapPosX - XSize , y + MapPosY - YSize , o.CellRadius)> EngineSettings.GridWidthPowerOfTwo)-MapPosX+XSize;
          int ypos = (o.Position.Y >> EngineSettings.GridHeightPowerOfTwo)-MapPosY+YSize;
          creatures[Math.Max(Math.Min(xpos,XSize<<1),0),Math.Max(0,Math.Min(ypos,YSize<<1))] = true;
      }
      protected Point RangeCheck(Point point) {
          int x = point.X;
          int y = point.Y;
          x = (x < 0) ? 0 : (my.WorldWidth <= x) ? my.WorldWidth-1 : x;
          y = (y < 0) ? 0 : (my.WorldWidth <= y) ? my.WorldWidth-1 : y;
          return new Point(x,y);
      }
  }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值