using System;
using System.Drawing;
using System.Collections;
using System.IO;
[assembly: OrganismClass("highlander")]
[assembly: AuthorInformation("barbie_j", "barbie_j@epitech.net")]
[CarnivoreAttribute(false)]
[MatureSize(25)]
[AnimalSkin(AnimalSkinFamilyEnum.Ant)]
[MarkingColor(KnownColor.Yellow)]
[MaximumEnergyPoints(8)]
[EatingSpeedPoints(0)]
[AttackDamagePoints(20)] // multiple de 4
[DefendDamagePoints(8)] // multiple de 4
[MaximumSpeedPoints(24)]
[CamouflagePoints(0)]
[EyesightPoints(40)] // multiple de 10
public class highlander: Animal
{
PlantState food = null;
AnimalState challenger = null;
AnimalState satanas = null;
AnimalState last_satanas = null;
int dist_warning = 60000; // todo
double limit_eating = 0.92;
double better_go_there = 20; // todo
int random_speed = 5;
/* int escape_speed = 16; */
int nb_childs = 0;
int limit_child_attack = 1;
bool hold_on = false;
AnimalState blocking = null;
bool randoming = false;
double limit_injured_attack = 0.5;
double limit_injured_defend = 0.9;
bool contourning = false;
protected override void Initialize()
{
Antennas.AntennaValue = 3;
ReproduceCompleted += new ReproduceCompletedEventHandler(ReproduceCompletedEvent);
Load += new LoadEventHandler(LoadEvent);
Idle += new IdleEventHandler(IdleEvent);
MoveCompleted += new MoveCompletedEventHandler(MoveCompletedEvent);
Teleported += new TeleportedEventHandler(TeleportedEvent);
Attacked += new AttackedEventHandler(AttackedEvent);
AttackCompleted += new AttackCompletedEventHandler(AttackCompletedEvent);
}
/* ---------------------------------------------------------------------------------- */
void MoveCompletedEvent(object sender, MoveCompletedEventArgs e)
{
try
{
contourning = false;
randoming = false;
hold_on = false;
if(e.Reason == ReasonForStop.Blocked)
{
WriteTrace("*** Who s blocking me ? ***");
gere_blocked(e);
}
else
WriteTrace("*** arrived at destination ***");
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void gere_blocked(MoveCompletedEventArgs e)
{
try
{
if (e.BlockingOrganism is AnimalState)
{
AnimalState blockingAnimal = (AnimalState) e.BlockingOrganism;
if (blockingAnimal == blocking)
{
if (IsMoving)
StopMoving();
my_attack(blocking, false);
hold_on = true;
return;
}
if (blockingAnimal.IsAlive &&
!IsMySpecies(e.BlockingOrganism) &&
nb_childs >= limit_child_attack &&
last_satanas == null &&
State.PercentInjured < limit_injured_attack)
{
blocking = blockingAnimal;
IAnimalSpecies spe = (IAnimalSpecies) blocking.Species;
if (!spe.IsCarnivore)
{
if (State.EnergyState <= EnergyState.Hungry)
{
if (IsMoving)
StopMoving();
hold_on = true;
my_attack(blocking, false);
return;
}
else
{
contourne(e);
return;
}
}
else
{
hold_on = false;
return;
}
}
else
{
contourne(e);
return;
}
}
else
if (e.BlockingOrganism is PlantState)
{
if (IsMoving)
StopMoving();
if (last_satanas == null)
hold_on = false;
else
contourne(e);
return;
}
contourne(e);
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void contourne(MoveCompletedEventArgs e)
{
try
{
WriteTrace("*** contourning ***");
Point originalDestination = e.MoveToAction.MovementVector.Destination;
Vector originalVector = Vector.Subtract(originalDestination, Position);
Vector newVector = originalVector.Rotate(Math.PI / 4);
Vector unitVector = newVector.GetUnitVector();
Vector newPositionVector = unitVector.Scale(20);
Point newPosition = Vector.Add(Position, newPositionVector);
contourning = true;
hold_on = true;
if (last_satanas == null)
BeginMoving(new MovementVector(newPosition, random_speed));
else
BeginMoving(new MovementVector(newPosition, Species.MaximumSpeed));
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void IdleEvent(object sender, IdleEventArgs e)
{
WriteTrace("*** IdleEvent ***");
try
{
bool escaping;
escaping = false;
if(CanReproduce)
gere_reproduction();
analyse_world();
if (contourning == false)
if (satanas != null)
if (gere_satanas() == true)
{
randoming = false;
escaping = true;
}
if (food != null)
{
gere_food(escaping);
randoming = false;
return;
}
if (hold_on || escaping == true)
return;
WriteTrace("*** hold_on = false ***");
if (challenger != null &&
nb_childs >= limit_child_attack &&
State.PercentInjured < limit_injured_attack &&
State.EnergyState <= EnergyState.Hungry) // stupid !
{
gere_challenger();
randoming = false;
return;
}
if (randoming == false)
move_to_a_random_place();
randoming = true;
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void gere_challenger()
{
try
{
WriteTrace("*** go killing a challenger ***");
if (WithinAttackingRange(challenger))
{
WriteTrace("*** eyes of the tiger ***");
if (IsMoving)
StopMoving();
hold_on = true;
my_attack(challenger, false);
}
else
{
move_to_challenger();
my_attack(challenger, false);
}
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void gere_blocking_annimal()
{
try
{
WriteTrace("*** what about my blocking friend ? ***");
if (WithinAttackingRange(blocking) &&
blocking.IsAlive)
{
WriteTrace("*** still here ? U want a die ? ***");
if (IsMoving)
StopMoving();
hold_on = true;
my_attack(blocking, false);
}
else
{
if (blocking.IsAlive)
{
challenger = blocking;
move_to_challenger();
my_attack(challenger, false);
}
else
{
hold_on = false;
blocking = null;
}
}
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
bool gere_satanas()
{
try
{
WriteTrace("*** is the satanas near me ? ***");
if (DistanceTo(satanas) < dist_warning)
{
WriteTrace("*** yes ***");
escape_from_satanas();
return true;
}
WriteTrace("*** no ***");
return false;
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
return false;
}
/* ---------------------------------------------------------------------------------- */
void gere_food(bool escaping)
{
try
{
WriteTrace("*** oh, I can see food ! ***");
if(WithinEatingRange(food))
{
WriteTrace("*** hum, food near me ***");
if (hold_on == true || escaping == true)
{
if (CanEat)
BeginEating(food);
return;
}
if ((food.PercentInjured < limit_eating || State.EnergyState == EnergyState.Deterioration) &&
CanEat)
{
WriteTrace("*** let s eat it ***");
if(IsMoving)
StopMoving();
if (challenger != null && State.EnergyState >= EnergyState.Normal)
BeginDefending(challenger);
BeginEating(food);
}
else
{
WriteTrace("*** to injured for me ***");
if (challenger != null && State.EnergyState >= EnergyState.Normal)
BeginDefending(challenger);
}
return;
}
else
{
if (hold_on == false && escaping == false)
{
WriteTrace("*** move to food ***");
move_to_food();
}
}
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void gere_reproduction()
{
try
{
WriteTrace("*** soon, we ll be more ***");
BeginReproduction(null);
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void move_to_challenger()
{
// todo: ne pas se deplacer vers le centre mais seulement vers le bord
try
{
/* int speed = CalculateSpeed(challenger, Species.MaximumSpeed); */
/* MovementVector moveto = new MovementVector(challenger.Position, speed); */
double speed = 0;
switch(State.EnergyState)
{
case EnergyState.Full:
speed = Species.MaximumSpeed;
break;
case EnergyState.Normal:
speed = Species.MaximumSpeed * .7;
break;
case EnergyState.Hungry:
speed = Species.MaximumSpeed * .4;
break;
default:
speed = Species.MaximumSpeed * .2;
break;
}
BeginMoving(new MovementVector(challenger.Position, (int) speed));
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void move_to_food()
{
// todo: ne pas se deplacer vers le centre mais seulement vers le bord
try
{
/* int speed = CalculateSpeed(food, Species.MaximumSpeed); */
BeginMoving(new MovementVector(food.Position, Species.MaximumSpeed));
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void move_to_a_random_place()
{
try
{
WriteTrace("*** let s go for a walk ***");
int X = OrganismRandom.Next(0, WorldWidth - 1);
int Y = OrganismRandom.Next(0, WorldHeight - 1);
BeginMoving(new MovementVector(new Point(X,Y), random_speed));
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void escape_from_satanas()
{
try
{
WriteTrace("*** hoho, g cru voir un ro minet... ***");
Vector newVector = Vector.Subtract(satanas.Position, Position);
Vector newPositionVector = newVector.Scale(10);
Point newPosition = Vector.Add(Position, newPositionVector);
challenger = null;
blocking = null;
if (newPosition.X > WorldWidth - 1)
newPosition.X = WorldWidth - 1;
if (newPosition.Y > WorldHeight - 1)
newPosition.Y = WorldHeight - 1;
if (newPosition.X < 1)
newPosition.X = 1;
if (newPosition.Y < 1)
newPosition.Y = 1;
BeginMoving(new MovementVector(newPosition, Species.MaximumSpeed));
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void analyse_world()
{
WriteTrace("*** analysing_world ***");
ArrayList creatures = Scan();
ArrayList plants = new ArrayList();
ArrayList animals = new ArrayList();
ArrayList herbivors = new ArrayList();
ArrayList carnivors = new ArrayList();
try
{
foreach (OrganismState orgState in creatures)
if (orgState is PlantState)
plants.Add(orgState);
else
animals.Add(orgState);
foreach (OrganismState aniState in animals)
{
IAnimalSpecies spe = (IAnimalSpecies) aniState.Species;
if (!spe.IsCarnivore)
{
if (!IsMySpecies(aniState))
herbivors.Add(aniState);
}
else
carnivors.Add(aniState);
}
select_carnivor(carnivors);
select_plant(plants);
select_herbivor(herbivors);
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void select_carnivor(ArrayList carnivors)
{
// todo: essayer avec tracer de rayon sur les autres...
double minDistance = double.MaxValue;
try
{
if (carnivors.Count > 0)
{
foreach(AnimalState carn in carnivors)
{
if (carn.IsAlive &&
DistanceTo(carn) < minDistance)
{
satanas = carn;
minDistance = DistanceTo(carn);
}
}
}
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void select_herbivor(ArrayList herbivors)
{
double minDistance = double.MaxValue;
double injured = 0;
try
{
if (herbivors.Count > 0)
{
foreach(AnimalState herb in herbivors)
{
if (herb.IsAlive &&
(DistanceTo(herb) < minDistance ||
(herb.PercentInjured > injured && DistanceTo(herb) < better_go_there)))
{
challenger = herb;
minDistance = DistanceTo(herb);
injured = herb.PercentInjured;
}
}
}
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void select_plant(ArrayList plants)
{
double minDistance = double.MaxValue;
try
{
if (plants.Count > 0)
{
foreach(PlantState plant in plants)
{
if (DistanceTo(plant) < minDistance)
{
food = plant;
minDistance = DistanceTo(plant);
}
}
}
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void AttackedEvent(object sender, AttackedEventArgs e)
{
WriteTrace("*** we re being attaked ! ***");
try
{
AnimalState TheAttacker = e.Attacker;
IAnimalSpecies spe = (IAnimalSpecies) TheAttacker.Species;
if (!spe.IsCarnivore)
blocking = TheAttacker;
if(e.Attacker.IsAlive)
{
hold_on = true;
if (IsMoving)
StopMoving();
if (WithinAttackingRange(TheAttacker))
my_attack(TheAttacker, true);
else
{
if (State.PercentInjured < limit_injured_defend)
{
// turning bad
// would be good to escape
}
WriteTrace("*** ce con m attaque mais n est pas a ma portee !!! catch it ***");
my_attack(TheAttacker, true);
BeginMoving(new MovementVector(TheAttacker.Position, Species.MaximumSpeed));
}
}
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void ReproduceCompletedEvent(object sender, ReproduceCompletedEventArgs e)
{
WriteTrace("*** a hero is born ***");
nb_childs++;
}
/* ---------------------------------------------------------------------------------- */
void TeleportedEvent(object sender, TeleportedEventArgs e)
{
WriteTrace("*** new world for me ***");
try
{
food = null;
satanas = null;
challenger = null;
last_satanas = null;
nb_childs = 0;
if (IsMoving)
StopMoving();
randoming = false;
hold_on = false;
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void LoadEvent(object sender, LoadEventArgs e)
{
WriteTrace("*** il n en restera qu un ! ***");
try
{
food = null;
last_satanas = satanas; // for blocked event
satanas = null;
challenger = null;
if (hold_on == true && blocking != null)
{
blocking = (AnimalState) LookFor(blocking);
if (blocking != null)
gere_blocking_annimal();
else
hold_on = false;
}
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void AttackCompletedEvent(object sender, AttackCompletedEventArgs ee)
{
try
{
if (ee.Killed)
{
WriteTrace("*** enemy down ***");
challenger = null;
blocking = null;
hold_on = false;
}
else
WriteTrace("*** enemy still alive ***");
}
catch(Exception exc)
{
WriteTrace(exc.ToString());
}
}
/* ---------------------------------------------------------------------------------- */
void my_attack(AnimalState target, bool force_attack)
{
BeginDefending(target);
if (!force_attack)
{
if (State.EnergyState <= EnergyState.Hungry)
BeginAttacking(target);
}
else
BeginAttacking(target);
}
/* ---------------------------------------------------------------------------------- */
int CalculateSpeed(OrganismState target, double max)
{
int PossibleSpeed;
if (target == null)
return 2;
PossibleSpeed = Species.MaximumSpeed;
while (PossibleSpeed > 2 &&
State.EnergyRequiredToMove(DistanceTo(target), PossibleSpeed) > max)
PossibleSpeed /= 2;
PossibleSpeed /= 2;
if (PossibleSpeed < 2)
PossibleSpeed = 2;
return PossibleSpeed;
}
/* ---------------------------------------------------------------------------------- */
public override void SerializeAnimal(MemoryStream m)
{
;
}
public override void DeserializeAnimal(MemoryStream m)
{
;
}
}