/// <summary> /// Clones the current plant state while resetting the immutability attribute /// so that the new state can be updated with new information. /// </summary> /// <returns>An newly mutable OrganismState that can be casted to a PlantState.</returns> /// <internal/> public override OrganismState CloneMutable() { var newInstance = new PlantState(ID, Species, Generation, EnergyState, Radius); CopyStateInto(newInstance); return(newInstance); }
// First event fired on an organism each turn void LoadEvent(object sender, LoadEventArgs e) { try { if(targetPlant != null) { // See if our target plant still exists (it may have died) // LookFor returns null if it isn't found targetPlant = (PlantState) LookFor(targetPlant); } } catch(Exception exc) { // WriteTrace is useful in debugging creatures WriteTrace(exc.ToString()); } }
// First event fired on an organism each turn private void MyAnimal_Load(object sender, LoadEventArgs e) { try { if (targetPlant != null) { // See if our target plant still exists (it may have died) // LookFor returns null if it isn't found targetPlant = (PlantState) LookFor(targetPlant); if (targetPlant == null) // WriteTrace is the best way to debug your creatures. WriteTrace("Target plant disappeared."); } } catch (Exception exc) { WriteTrace(exc.ToString()); } }
/// <summary> /// Clones the current plant state while resetting the immutability attribute /// so that the new state can be updated with new information. /// </summary> /// <returns>An newly mutable OrganismState that can be casted to a PlantState.</returns> /// <internal/> public override OrganismState CloneMutable() { var newInstance = new PlantState(ID, Species, Generation, EnergyState, Radius); CopyStateInto(newInstance); return newInstance; }
// Looks for target plants, and starts moving towards the first one it finds private bool ScanForTargetPlant() { try { ArrayList foundCreatures = Scan(); if (foundCreatures.Count > 0) { // Always move after closest plant or defend closest creature if there is one foreach (OrganismState organismState in foundCreatures) { if (organismState is PlantState) { targetPlant = (PlantState) organismState; BeginMoving(new MovementVector(organismState.Position, 2)); return true; } } } } catch (Exception exc) { WriteTrace(exc.ToString()); } return false; }
/// <summary> /// Initializes a new state object with the given position and family generation /// </summary> /// <param name="position">The position of the new PlantState</param> /// <param name="generation">The family generation of the new Plant</param> /// <returns>A state object initialized to the given position and generation.</returns> public override OrganismState InitializeNewState(Point position, int generation) { // Need to start out hungry so they can't reproduce immediately and just populate the world var initialEnergy = EnergyState.Hungry; var newState = new PlantState(Guid.NewGuid().ToString(), this, generation, initialEnergy, InitialRadius) { Position = position }; newState.ResetGrowthWait(); return newState; }
// Looks for target plants, and starts moving towards the first one it finds private bool ScanForTargetPlant() { try { // Find all Plants/Animals in range ArrayList foundAnimals = Scan(); // If we found some Plants/Animals lets try // to weed out the plants. if (foundAnimals.Count > 0) { foreach (OrganismState organismState in foundAnimals) { // If we found a plant, set it as our target // then begin moving towards it. Tell the // caller we have a target. if (!(organismState is PlantState)) continue; targetPlant = (PlantState) organismState; BeginMoving(new MovementVector(organismState.Position, 2)); return true; } } } catch (Exception exc) { WriteTrace(exc.ToString()); } // Tell the caller we couldn't find a target return false; }
/// <summary> /// Percentage of light reaching this plant. /// We assume the sun moves from east to west directly overhead /// /// We get a rough estimation like this: /// Get all plants with a certain radius whose radius blocks any East-West vector that intersects /// any part of the radius of the plant in question -- assume they block it completely /// Figure out which blocks it at the highest angle. /// Discount the amount of light the plant sees by angle / 180 /// </summary> /// <param name="plant">The plant to get light for.</param> /// <returns>The amount of available light for the plant.</returns> public int GetAvailableLight(PlantState plant) { var maxX = plant.GridX + plant.CellRadius + 25; if (maxX > _gridWidth - 1) { maxX = _gridWidth - 1; } var overlappingPlantsEast = FindOrganismsInCells(plant.GridX + plant.CellRadius, maxX, plant.GridY - plant.CellRadius, plant.GridY + plant.CellRadius); var minX = plant.GridX - plant.CellRadius - 25; if (minX < 0) { minX = 0; } var overlappingPlantsWest = FindOrganismsInCells(minX, plant.GridX - plant.CellRadius, plant.GridY - plant.CellRadius, plant.GridY + plant.CellRadius); double maxAngleEast = 0; foreach (OrganismState targetPlant in overlappingPlantsEast) { if (!(targetPlant is PlantState)) continue; var currentAngle = Math.Atan2(((PlantState) targetPlant).Height, targetPlant.Position.X - plant.Position.X); if (currentAngle > maxAngleEast) { maxAngleEast = currentAngle; } } double maxAngleWest = 0; foreach (OrganismState targetPlant in overlappingPlantsWest) { if (!(targetPlant is PlantState)) continue; var currentAngle = Math.Atan2(((PlantState) targetPlant).Height, plant.Position.X - targetPlant.Position.X); if (currentAngle > maxAngleWest) { maxAngleWest = currentAngle; } } return (int) (((Math.PI - maxAngleEast + maxAngleWest)/Math.PI)*100); }
/// <summary> /// Initializes a new state object with the given position and family generation /// </summary> /// <param name="position">The position of the new PlantState</param> /// <param name="generation">The family generation of the new Plant</param> /// <returns>A state object initialized to the given position and generation.</returns> public override OrganismState InitializeNewState(Point position, int generation) { PlantState newState = new PlantState(Guid.NewGuid().ToString(), this, generation); newState.Position = position; newState.IncreaseRadiusTo(InitialRadius); // Need to start out hungry so they can't reproduce immediately and just populate the world newState.StoredEnergy = newState.UpperBoundaryForEnergyState(EnergyState.Hungry); newState.ResetGrowthWait(); return newState; }