Skip to content

Commit

Permalink
Implemented conditional exchange.
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewanderson committed Oct 8, 2010
1 parent 7c6eefc commit bf3b83f
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 19 deletions.
6 changes: 6 additions & 0 deletions Cas/Core/Interfaces/ISimulation.cs
Expand Up @@ -135,6 +135,12 @@ public interface ISimulation : IDisposable
/// </summary>
double RandomDeathChance { get; }

/// <summary>
/// The total number of times, per interaction, that an agent will try to locate
/// an acceptable target.
/// </summary>
int MaximumAttemptsToFindSuitableTarget { get; }

#endregion

}
Expand Down
83 changes: 73 additions & 10 deletions Cas/Core/SimulationBase.cs
Expand Up @@ -21,10 +21,11 @@ public abstract class SimulationBase : ISimulation
#endregion

protected SimulationBase()
: this(1.5, 4, 0.25, 1.75, 0.2, 0.005, 0.02, 0.005) { }
: this(1.5, 4, 0.25, 1.75, 0.2, 0.005, 0.02, 0.005, 5) { }

protected SimulationBase(double interactionsPerGenerationFactor, int maximumUpkeepCostPerLocation, double upkeepChance,
double reproductionThreshold, double reproductionInheritance, double migrationBaseChance, double maxMigrationBonus, double randomDeathChance)
double reproductionThreshold, double reproductionInheritance, double migrationBaseChance, double maxMigrationBonus,
double randomDeathChance, int maximumAttemptsToFindSuitableTarget)
{
// Set some defaults
InteractionsPerGenerationFactor = interactionsPerGenerationFactor;
Expand All @@ -38,6 +39,8 @@ protected SimulationBase()
MaximumMigrationBonus = maxMigrationBonus;

RandomDeathChance = randomDeathChance;

MaximumAttemptsToFindSuitableTarget = maximumAttemptsToFindSuitableTarget;
}

#region ISimulation Members
Expand Down Expand Up @@ -240,6 +243,8 @@ public void Reset()

public double RandomDeathChance { get; set; }

public int MaximumAttemptsToFindSuitableTarget { get; set; }

#endregion

#region RunGeneration
Expand Down Expand Up @@ -359,19 +364,15 @@ private void DoInteractions(ILocation location, int interactionsToPerform)
actor.SetInteractionContactPoint();

// Pick a target
var target = SelectRandomTarget(allTargets, actor);
if (target is IAgent)
var target = SelectTarget(allTargets, actor);
if (target != null)
{
(target as IAgent).SetInteractionContactPoint();
InnerDoInteraction(location, actor, target);
}

// TODO: Check that we should interact (via tags)

InnerDoInteraction(location, actor, target);
}

// TODO: We need to do interactions within multi-agents here
}
}

protected abstract void InnerDoInteraction(ILocation location, IAgent actor, IInteractable target);

Expand Down Expand Up @@ -443,6 +444,26 @@ public void AddEventToAgent(IAgent agent, IEvent newEvent)
if (this.LogHistory) agent.History.Add(newEvent);
}

/// <summary>
/// Selects a target for the actor to interact with, taking into account
/// the conditional exchange tags.
/// </summary>
protected IInteractable SelectTarget(List<IInteractable> allTargets, IAgent actor)
{
if (allTargets == null) throw new ArgumentNullException("allTargets");
if (allTargets == null) throw new ArgumentNullException("actor");

IInteractable target = null;
for (int i = 0; i < MaximumAttemptsToFindSuitableTarget; i++)
{
target = SelectRandomTarget(allTargets, actor);
if (target != null && target is IAgent) (target as IAgent).SetInteractionContactPoint();
if (target == null || !ShouldExchangeOccur(actor, target)) continue;
}

return target;
}

/// <summary>
/// Retrieves a random target from the supplied list, ensuring that it
/// does not match the supplied actor.
Expand Down Expand Up @@ -471,6 +492,48 @@ public void AddEventToAgent(IAgent agent, IEvent newEvent)
return target;
}

/// <summary>
/// Test to see whether or not an exchange interaction should take place.
/// </summary>
/// <remarks>
/// See Holland pg. 111-113, 148 for details and explanations on this.
/// </remarks>
protected static bool ShouldExchangeOccur(IAgent actor, IInteractable target)
{
if (actor == null) throw new ArgumentNullException("actor");
if (target == null) throw new ArgumentNullException("target");

return CalculateConditionalExchangeMatch(actor.Exchange, target.Offense);

// NOTE:
// Holland suggests also checking if the target matches the actor, and
// if not then giving it a chance to flee. I have not included this since
// I believe that Holland's model has agents encountering each other and
// attacking simultaneously, not a one way attack like I currently have
// implemented.
}

/// <summary>
/// Determine whether or not the exchange tag of one individual is well matched
/// to the offense tag of another individual.
///
/// If the exchange tag matches the start of the offense tag then it is considered a match.
/// </summary>
protected static bool CalculateConditionalExchangeMatch(Tag exchange, Tag offense)
{
if (exchange == null) throw new ArgumentNullException("exchange");
if (offense == null) throw new ArgumentNullException("offense");

for (int i = 0; i < exchange.Data.Count; i++)
{
if (i >= offense.Data.Count) return false;
if (exchange.Data[i] == Resource.WildcardResource) continue;
if (exchange.Data[i] != offense.Data[i]) return false;
}

return true;
}

#endregion

#region IDisposable Members
Expand Down
10 changes: 5 additions & 5 deletions Cas/TestCas/GridSimulation.cs
Expand Up @@ -31,14 +31,14 @@ public class GridSimulation : SimulationBase
public GridSimulation(int length, int width, int minResourceNodes, int maxResourceNodes, int minResourcesPerNode, int maxResourcesPerNode,
int minResourceNodeDefense, int maxResourceNodeDefense, int tagComplexity)
: this(length, width, minResourceNodes, maxResourceNodes, minResourcesPerNode, maxResourcesPerNode, minResourceNodeDefense, maxResourceNodeDefense, tagComplexity,
100, 4, 0.25, 1.5, 1.75, 0.2, 0.005, 0.02, 0.005) { }
100, 4, 0.25, 1.5, 1.75, 0.2, 0.005, 0.02, 0.005, 5) { }

public GridSimulation(int length, int width, int minResourceNodes, int maxResourceNodes, int minResourcesPerNode, int maxResourcesPerNode,
int minResourceNodeDefense, int maxResourceNodeDefense, int tagComplexity, int uniqueResourceCount, int maximumUpkeepCostPerLocation,
double upkeepChance, double interactionsPerGeneration, double reproductionThreshold, double reproductionInheritance,
double migrationBaseChance, double maxMigrationBonus, double randomDeathChance)
: base(interactionsPerGeneration, maximumUpkeepCostPerLocation, upkeepChance, reproductionThreshold, reproductionInheritance,
migrationBaseChance, maxMigrationBonus, randomDeathChance)
double upkeepChance, double interactionsPerGeneration, double reproductionThreshold, double reproductionInheritance,
double migrationBaseChance, double maxMigrationBonus, double randomDeathChance, int maximumAttemptsToFindSuitableTarget)
: base(interactionsPerGeneration, maximumUpkeepCostPerLocation, upkeepChance, reproductionThreshold, reproductionInheritance,
migrationBaseChance, maxMigrationBonus, randomDeathChance, maximumAttemptsToFindSuitableTarget)
{
Length = length;
Width = width;
Expand Down
6 changes: 3 additions & 3 deletions Cas/WebCritters/WebCrittersForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cas/WebCritters/WebCrittersForm.cs
Expand Up @@ -62,7 +62,9 @@ private void CreateSimulationFromLoadControls()
int.Parse(reproductionInheritancePercent.Text) / 100.0,
double.Parse(migrationBaseChance.Text) / 100.0,
double.Parse(maxMigrationBonus.Text) / 100.0,
double.Parse(randomDeathPercent.Text) / 100.0);
double.Parse(randomDeathPercent.Text) / 100.0,
5 // TODO: Config me in form
);

CasSimulation.GenerationFinished += new EventHandler(CasSimulation_GenerationFinished);
CasSimulation.LogHistory = this.trackAgentHistory.Checked;
Expand Down

0 comments on commit bf3b83f

Please sign in to comment.