[Avida-SVN] r2346 - in branches/energy/source: actions cpu main
connel42 at myxo.css.msu.edu
connel42 at myxo.css.msu.edu
Tue Feb 19 10:54:46 PST 2008
Author: connel42
Date: 2008-02-19 13:54:46 -0500 (Tue, 19 Feb 2008)
New Revision: 2346
Modified:
branches/energy/source/actions/PopulationActions.cc
branches/energy/source/cpu/cHardwareCPU.cc
branches/energy/source/cpu/cHardwareCPU.h
branches/energy/source/cpu/cTestCPUInterface.h
branches/energy/source/main/cAvidaConfig.h
branches/energy/source/main/cDeme.cc
branches/energy/source/main/cDeme.h
branches/energy/source/main/cDemeCellEvent.cc
branches/energy/source/main/cOrgInterface.h
branches/energy/source/main/cOrgMovementPredicate.h
branches/energy/source/main/cOrganism.cc
branches/energy/source/main/cOrganism.h
branches/energy/source/main/cPopulation.cc
branches/energy/source/main/cPopulationCell.cc
branches/energy/source/main/cPopulationInterface.h
branches/energy/source/main/cTaskLib.cc
branches/energy/source/main/cTaskLib.h
Log:
BDC - merged in my movement-related tasks and predicates. Updated GERMLINE_INJECT_ORGS
use to only inject into unoccupied cells.
New config options:
PHEROMONE_ENABLED (0/1) - whether or not to allow pheromone dropping
PHEROMONE_AMOUNT (float) - amount of pheromone resource to drop per move
PHEROMONE_DROP_MODE - how to distribute the dropped pheromone
0 = 1/2 at source 1/2 at dest cell
1 = all at source cell
2 = all at dest cell
LOG_PHEROMONE (0/1) - whether or not to write movement/pheromone data to data/pheromones.dat
Modified: branches/energy/source/actions/PopulationActions.cc
===================================================================
--- branches/energy/source/actions/PopulationActions.cc 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/actions/PopulationActions.cc 2008-02-19 18:54:46 UTC (rev 2346)
@@ -454,15 +454,13 @@
-/*! Injects an organism into all demes in the population.
+/*! Injects GERMLINE_INJECT_ORGS organisms into all demes in the population.
Parameters:
filename (string):
The filename of the genotype to load. If this is left empty, or the keyword
"START_CREATURE" is given, than the genotype specified in the genesis
file under "START_CREATURE" is used.
-cell ID (integer) default: 0
- The grid-point into which the organism should be placed.
merit (double) default: -1
The initial merit of the organism. If set to -1, this is ignored.
lineage label (integer) default: 0
@@ -470,6 +468,7 @@
neutral metric (double) default: 0
A double value that randomly drifts over time.
*/
+
class cActionInjectDemes : public cAction
{
private:
@@ -494,6 +493,14 @@
{
cGenome genome = cGenomeUtil::LoadGenome(m_filename, m_world->GetHardwareManager().GetInstSet());
if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1) {
+
+ // Insert N-1 more orgs into deme 0
+ for(int j=1; j < m_world->GetConfig().GERMLINE_INJECT_ORGS.Get(); j++) {
+ m_world->GetPopulation().Inject(genome,
+ m_world->GetPopulation().GetDeme(0).GetCellID(j),
+ m_merit, m_lineage_label, m_neutral_metric);
+ }
+
for(int i=1; i<m_world->GetPopulation().GetNumDemes(); ++i) { // first org has already been injected
for(int j = 0 ; j < m_world->GetConfig().GERMLINE_INJECT_ORGS.Get(); j++) {
m_world->GetPopulation().Inject(genome,
@@ -501,24 +508,20 @@
m_merit, m_lineage_label, m_neutral_metric);
}
}
- for(int j = 1 ; j < m_world->GetConfig().GERMLINE_INJECT_ORGS.Get(); j++) { // other orgs in first deme
- m_world->GetPopulation().Inject(genome,
- m_world->GetPopulation().GetDeme(0).GetCellID(j),
- m_merit, m_lineage_label, m_neutral_metric);
- }
} else {
for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
// WARNING: initial ancestor has already be injected into the population
// calling this will overwrite it.
- m_world->GetPopulation().Inject(genome,
- m_world->GetPopulation().GetDeme(i).GetCellID(0),
- m_merit, m_lineage_label, m_neutral_metric);
+ for(int j=0; j < m_world->GetPopulation().GetNumDemes(); j++) {
+ m_world->GetPopulation().Inject(genome,
+ m_world->GetPopulation().GetDeme(i).GetCellID(j),
+ m_merit, m_lineage_label, m_neutral_metric);
+ }
}
}
}
};
-
/*
Randomly removes a certain proportion of the population.
@@ -1140,7 +1143,54 @@
}
};
+
/*
+ Added predicate to all demes that is satisified when an organism reaches a target cell
+ modified cActionPred_DemeEventMoveCenter
+*/
+class cActionPred_DemeEventMoveBetweenTargets : public cAction
+{
+private:
+ int m_times;
+
+public:
+ cActionPred_DemeEventMoveBetweenTargets(cWorld* world, const cString& args) : cAction(world, args), m_times(1) {
+ cString largs(args);
+ if (largs.GetSize()) m_times = largs.PopWord().AsInt();
+ }
+
+ static const cString GetDescription() { return "Arguments: [int times=1]"; }
+
+ void Process(cAvidaContext& ctx)
+ {
+ m_world->GetPopulation().AddDemePred("EventMovedBetweenTargets", m_times);
+ }
+};
+
+/*
+ Added predicate to all demes that is satisified when a number of organisms
+ reach a target cell
+*/
+class cActionPred_DemeEventMigrateToTargets : public cAction
+{
+private:
+ int m_numorgs;
+
+public:
+ cActionPred_DemeEventMigrateToTargets(cWorld* world, const cString& args) : cAction(world, args), m_numorgs(1) {
+ cString largs(args);
+ if (largs.GetSize()) m_numorgs = largs.PopWord().AsInt();
+ }
+
+ static const cString GetDescription() { return "Arguments: [int numorgs=1]"; }
+
+ void Process(cAvidaContext& ctx)
+ {
+ m_world->GetPopulation().AddDemePred("EventMigrateToTargets", m_numorgs);
+ }
+};
+
+/*
Designed to serve as a control for the compete_demes. Each deme is
copied into itself and the parameters reset.
*/
@@ -1635,6 +1685,8 @@
action_lib->Register<cActionPred_DemeEventReceivedCenter>("Pred_DemeEventReceivedCenter");
action_lib->Register<cActionPred_DemeEventReceivedLeftSide>("Pred_DemeEventReceivedLeftSide");
action_lib->Register<cActionPred_DemeEventMoveCenter>("Pred_DemeEventMoveCenter");
+ action_lib->Register<cActionPred_DemeEventMoveBetweenTargets>("Pred_DemeEventMoveBetweenTargets");
+ action_lib->Register<cActionPred_DemeEventMigrateToTargets>("Pred_DemeEventMigrateToTargets");
action_lib->Register<cActionNewTrial>("NewTrial");
action_lib->Register<cActionCompeteOrganisms>("CompeteOrganisms");
Modified: branches/energy/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/energy/source/cpu/cHardwareCPU.cc 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/cpu/cHardwareCPU.cc 2008-02-19 18:54:46 UTC (rev 2346)
@@ -203,6 +203,9 @@
tInstLibEntry<tMethod>("sense", &cHardwareCPU::Inst_SenseLog2), // If you add more sense instructions
tInstLibEntry<tMethod>("sense-unit", &cHardwareCPU::Inst_SenseUnit), // and want to keep stats, also add
tInstLibEntry<tMethod>("sense-m100", &cHardwareCPU::Inst_SenseMult100), // the names to cStats::cStats() @JEB
+
+
+
// Data collection
tInstLibEntry<tMethod>("collect-cell-data", &cHardwareCPU::Inst_CollectCellData),
@@ -238,6 +241,18 @@
// Addition for follow-the-leader
tInstLibEntry<tMethod>("sense3-and-rotate", &cHardwareCPU::Inst_Sense3andRotate),
tInstLibEntry<tMethod>("sense-cell-data", &cHardwareCPU::Inst_SenseCellData),
+
+ // @BDC additions for pheromones
+ tInstLibEntry<tMethod>("phero-on", &cHardwareCPU::Inst_PheroOn),
+ tInstLibEntry<tMethod>("phero-off", &cHardwareCPU::Inst_PheroOff),
+ tInstLibEntry<tMethod>("pherotoggle", &cHardwareCPU::Inst_PheroToggle),
+ tInstLibEntry<tMethod>("sense-target", &cHardwareCPU::Inst_SenseTarget),
+ tInstLibEntry<tMethod>("sensef", &cHardwareCPU::Inst_SenseLog2Facing),
+ tInstLibEntry<tMethod>("sensef-unit", &cHardwareCPU::Inst_SenseUnitFacing),
+ tInstLibEntry<tMethod>("sensef-m100", &cHardwareCPU::Inst_SenseMult100Facing),
+ tInstLibEntry<tMethod>("sense-pheromone", &cHardwareCPU::Inst_SensePheromone),
+ tInstLibEntry<tMethod>("sense-pheromone-faced", &cHardwareCPU::Inst_SensePheromoneFaced),
+
// Threading instructions
tInstLibEntry<tMethod>("fork-th", &cHardwareCPU::Inst_ForkThread),
@@ -3116,6 +3131,214 @@
// Note that we are converting <double> resources to <int> register values
}
+
+bool cHardwareCPU::Inst_SensePheromoneFaced(cAvidaContext& ctx)
+{
+ cPopulation& pop = m_world->GetPopulation();
+ cPopulationCell& mycell = pop.GetCell(organism->GetCellID());
+
+ int cellid = mycell.GetCellFaced().GetID(); //absolute id of faced cell
+
+ return DoSensePheromone(ctx, cellid);
+} //End Inst_SensePheromoneFacing()
+
+
+bool cHardwareCPU::Inst_SensePheromone(cAvidaContext& ctx)
+{
+ int cellid = organism->GetCellID(); //absolute id of current cell
+
+ return DoSensePheromone(ctx, cellid);
+} //End Inst_SensePheromone()
+
+
+// DoSensePheromone -- modified version of DoSense to only sense from
+// pheromone resource in given cell
+bool cHardwareCPU::DoSensePheromone(cAvidaContext& ctx, int cellid)
+{
+ int reg_to_set = FindModifiedRegister(REG_BX);
+
+ cPopulation& pop = m_world->GetPopulation();
+ cDeme &deme = pop.GetDeme(pop.GetCell(cellid).GetDemeID());
+ int relative_cell_id = deme.GetRelativeCellID(cellid);
+
+ cResourceCount deme_resource_count = deme.GetDemeResourceCount();
+ tArray<double> cell_resources = deme_resource_count.GetCellResources(relative_cell_id);
+
+ if(deme_resource_count.GetSize() == 0) return false;
+
+ for (int i = 0; i < deme_resource_count.GetSize(); i++) {
+ if(strcmp(deme_resource_count.GetResName(i), "pheromone") == 0) {
+ GetRegister(reg_to_set) = (int)round(cell_resources[i]);
+
+/*
+ ofstream pslog;
+ pslog.open("data/sensedpheromones.dat", ios::app);
+ pslog << m_world->GetStats().GetUpdate() << " " << organism->GetID() << " " << relative_cell_id << " " << cell_resources[i] << endl;
+ pslog.close();
+*/
+
+ return true;
+ }
+ }
+
+ return false;
+
+} //End DoSensePheromone()
+
+
+bool cHardwareCPU::Inst_SenseLog2Facing(cAvidaContext& ctx)
+{
+ return DoSenseFacing(ctx, 0, 2);
+}
+
+bool cHardwareCPU::Inst_SenseUnitFacing(cAvidaContext& ctx)
+{
+ return DoSenseFacing(ctx, 1, 1);
+}
+
+bool cHardwareCPU::Inst_SenseMult100Facing(cAvidaContext& ctx)
+{
+ return DoSenseFacing(ctx, 1, 100);
+}
+
+// BDC: same as DoSense, but uses senses from cell that org is facing
+bool cHardwareCPU::DoSenseFacing(cAvidaContext& ctx, int conversion_method, double base)
+{
+ cPopulationCell& mycell = m_world->GetPopulation().GetCell(organism->GetCellID());
+
+ int faced_id = mycell.GetCellFaced().GetID();
+
+ // Returns the amount of a resource or resources
+ // specified by modifying NOPs into register BX
+ const tArray<double> & res_count = m_world->GetPopulation().GetCellResources(faced_id);
+
+ // Arbitrarily set to BX since the conditional instructions use this directly.
+ int reg_to_set = REG_BX;
+
+ // There are no resources, return
+ if (res_count.GetSize() == 0) return false;
+
+ // Only recalculate logs if these values have changed
+ static int last_num_resources = 0;
+ static int max_label_length = 0;
+ int num_nops = GetInstSet().GetNumNops();
+
+ if ((last_num_resources != res_count.GetSize()))
+ {
+ max_label_length = (int) ceil(log((double)res_count.GetSize())/log((double)num_nops));
+ last_num_resources = res_count.GetSize();
+ }
+
+ // Convert modifying NOPs to the index of the resource.
+ // If there are fewer than the number of NOPs required
+ // to uniquely specify a resource, then add together
+ // a subset of resources (motivation: regulation can evolve
+ // to be more specific if there is an advantage)
+
+ // Find the maximum number of NOPs needed to specify this number of resources
+ // Note: It's a bit wasteful to recalculate this every time and organisms will
+ // definitely be confused if the number of resources changes during a run
+ // because their mapping to resources will be disrupted
+
+ // Attempt to read a label with this maximum length
+ ReadLabel(max_label_length);
+
+ // Find the length of the label that we actually obtained (max is max_reg_needed)
+ int real_label_length = GetLabel().GetSize();
+
+ // Start and end labels to define the start and end indices of
+ // resources that we need to add together
+ cCodeLabel start_label = cCodeLabel(GetLabel());
+ cCodeLabel end_label = cCodeLabel(GetLabel());
+
+ for (int i = 0; i < max_label_length - real_label_length; i++)
+ {
+ start_label.AddNop(0);
+ end_label.AddNop(num_nops-1);
+ }
+
+ int start_index = start_label.AsInt(num_nops);
+ int end_index = end_label.AsInt(num_nops);
+
+ // If the label refers to ONLY resources that
+ // do not exist, then the operation fails
+ if (start_index >= res_count.GetSize()) return false;
+
+ // Otherwise sum all valid resources that it might refer to
+ // (this will only be ONE if the label was of the maximum length).
+ int resource_result = 0;
+ double dresource_result = 0;
+ for (int i = start_index; i <= end_index; i++)
+ {
+ // if it's a valid resource
+ if (i < res_count.GetSize())
+ {
+ if (conversion_method == 0) // Log
+ {
+ // for log, add together and then take log
+ dresource_result += (double) res_count[i];
+ }
+ else if (conversion_method == 1) // Addition of multiplied resource amount
+ {
+ int add_amount = (int) (res_count[i] * base);
+ // Do some range checking to make sure we don't overflow
+ resource_result = (INT_MAX - resource_result <= add_amount) ? INT_MAX : resource_result + add_amount;
+ }
+ }
+ }
+
+ // Take the log after adding resource amounts together! This way a zero can be assigned to INT_MIN
+ if (conversion_method == 0) // Log2
+ {
+ // You really shouldn't be using the log method if you can get to zero resources
+ if(dresource_result == 0.0)
+ {
+ resource_result = INT_MIN;
+ }
+ else
+ {
+ resource_result = (int)(log(dresource_result)/log(base));
+ }
+ }
+
+ //Dump this value into an arbitrary register: BX
+ GetRegister(reg_to_set) = resource_result;
+
+ //We have to convert this to a different index that includes all degenerate labels possible: shortest to longest
+ int sensed_index = 0;
+ int on = 1;
+ for (int i = 0; i < real_label_length; i++)
+ {
+ sensed_index += on;
+ on *= num_nops;
+ }
+ sensed_index+= GetLabel().AsInt(num_nops);
+ organism->GetPhenotype().IncSenseCount(sensed_index);
+
+ return true;
+
+ // Note that we are converting <double> resources to <int> register values
+}
+
+
+bool cHardwareCPU::Inst_SenseTarget(cAvidaContext& ctx) {
+ int reg_to_set = FindModifiedRegister(REG_CX);
+
+ cPopulation& pop = m_world->GetPopulation();
+ cDeme &deme = pop.GetDeme(pop.GetCell(organism->GetCellID()).GetDemeID());
+
+ int cellID = deme.GetRelativeCellID(organism->GetCellID());
+ int val = 0;
+
+ if( (cellID == 23) || (cellID == 77) ) {
+ val = 1;
+ }
+
+ GetRegister(reg_to_set) = val;
+
+} //End Inst_SenseTarget()
+
+
bool cHardwareCPU::Inst_CollectCellData(cAvidaContext& ctx) {
int cellID = organism->GetCellID();
const int out_reg = FindModifiedRegister(REG_BX);
@@ -3876,6 +4099,26 @@
return true;
}
+
+
+// @BDC Pheromone-related instructions
+bool cHardwareCPU::Inst_PheroOn(cAvidaContext& ctx)
+{
+ organism->SetPheromone(true);
+} //End Inst_PheroOn()
+
+bool cHardwareCPU::Inst_PheroOff(cAvidaContext& ctx)
+{
+ organism->SetPheromone(false);
+} //End Inst_PheroOff()
+
+bool cHardwareCPU::Inst_PheroToggle(cAvidaContext& ctx)
+{
+ organism->TogglePheromone();
+} //End Inst_PheroToggle()
+
+
+
// @WRE addition for movement
// Tumble sets the organism and cell to a new random facing
//
@@ -3897,14 +4140,14 @@
{
// Declarations
int fromcellID, destcellID; //, actualNeighborhoodSize, fromFacing, destFacing, currentFacing;
-
+
// Get population
cPopulation& pop = m_world->GetPopulation();
// Get stepsize. Currently, all moves are one cell regardless of stepsize.
// This could be changed in the future.
const int stepsize = m_world->GetConfig().BIOMIMETIC_MOVEMENT_STEP.Get();
-
+
// Code
if (0 < stepsize) {
// Current cell
@@ -3933,9 +4176,65 @@
// updates movement predicates
m_world->GetStats().Move(*organism);
-
+
+ // BDC
+ // If organism is dropping pheromones, mark the destination cell
+ if( (m_world->GetConfig().PHEROMONE_ENABLED.Get() == 1) &&
+ (organism->GetPheromoneStatus() == true) ) {
+
+ const double pher_amount = m_world->GetConfig().PHEROMONE_AMOUNT.Get();
+ const int drop_mode = m_world->GetConfig().PHEROMONE_DROP_MODE.Get();
+
+ cDeme &deme = pop.GetDeme(pop.GetCell(organism->GetCellID()).GetDemeID());
+
+ if(drop_mode == 0) {
+ deme.AddPheromone(fromcellID, pher_amount/2);
+ deme.AddPheromone(destcellID, pher_amount/2);
+ } else if(drop_mode == 1) {
+ deme.AddPheromone(fromcellID, pher_amount);
+ }
+ else if(drop_mode == 2) {
+ deme.AddPheromone(destcellID, pher_amount);
+ }
+
+ // Old CellData-based version
+ //const int newval = pop.GetCell(destcellID).GetCellData() + 1;
+ //pop.GetCell(destcellID).SetCellData(newval);
+
+ } //End laying pheromone
+
+ // Write some logging information if LOG_PHEROMONE is set. This is done
+ // out here so that non-pheromone moves are recorded.
+ if(m_world->GetConfig().LOG_PHEROMONE.Get() == 1) {
+ ofstream pherolog;
+ cDeme &deme = pop.GetDeme(pop.GetCell(organism->GetCellID()).GetDemeID());
+
+//TODO: would be nice to use the DATA_DIR from the config file
+ //pherolog.open("data/pheromones.dat", ios::app);
+ int rel_srcid = deme.GetRelativeCellID(fromcellID);
+ int rel_destid = deme.GetRelativeCellID(destcellID);
+ double pher_amount;
+ const int drop_mode = m_world->GetConfig().PHEROMONE_DROP_MODE.Get();
+
+ // By columns: update ID, org ID, source cell (relative), destination cell (relative), amount dropped, drop mode
+ if( (m_world->GetConfig().PHEROMONE_ENABLED.Get() == 1) &&
+ (organism->GetPheromoneStatus() == true) ) {
+ pher_amount = m_world->GetConfig().PHEROMONE_AMOUNT.Get();
+ } else {
+ pher_amount = 0;
+ }
+
+ //pherolog << m_world->GetStats().GetUpdate() << " " << organism->GetID() << " " << rel_srcid << " " << rel_destid << " " << pher_amount << " " << drop_mode << endl;
+
+ //pherolog.close();
+ }
+
// check tasks. general movement tasks are not yet supported.
- organism->DoOutput(ctx);
+ //organism->DoOutput(ctx);
+
+ // Brian movement
+ organism->Move(ctx);
+
return true;
} else {
return false;
Modified: branches/energy/source/cpu/cHardwareCPU.h
===================================================================
--- branches/energy/source/cpu/cHardwareCPU.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/cpu/cHardwareCPU.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -446,6 +446,7 @@
bool DoSense(cAvidaContext& ctx, int conversion_method, double base);
bool Inst_CollectCellData(cAvidaContext& ctx);
+
void DoDonate(cOrganism * to_org);
void DoEnergyDonate(cOrganism* to_org);
bool Inst_DonateRandom(cAvidaContext& ctx);
@@ -484,6 +485,21 @@
// Additions for follow-the-leader
bool Inst_Sense3andRotate(cAvidaContext& ctx);
bool Inst_SenseCellData(cAvidaContext& ctx); // @ LMG, more follow-the-leader
+
+ // @BDC Additions for pheromones
+ bool Inst_PheroOn(cAvidaContext& ctx);
+ bool Inst_PheroOff(cAvidaContext& ctx);
+ bool Inst_PheroToggle(cAvidaContext& ctx);
+ bool DoSenseFacing(cAvidaContext& ctx, int conversion_method, double base);
+ bool Inst_SenseLog2Facing(cAvidaContext& ctx);
+ bool Inst_SenseUnitFacing(cAvidaContext& ctx);
+ bool Inst_SenseMult100Facing(cAvidaContext& ctx);
+ bool Inst_SenseTarget(cAvidaContext& ctx);
+ bool DoSensePheromone(cAvidaContext& ctx, int cellid);
+ bool Inst_SensePheromone(cAvidaContext& ctx);
+ bool Inst_SensePheromoneFaced(cAvidaContext& ctx);
+
+
// Multi-threading...
bool Inst_ForkThread(cAvidaContext& ctx);
Modified: branches/energy/source/cpu/cTestCPUInterface.h
===================================================================
--- branches/energy/source/cpu/cTestCPUInterface.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/cpu/cTestCPUInterface.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -45,8 +45,14 @@
virtual ~cTestCPUInterface() { ; }
int GetCellID() { return 0; }
+ int GetBirthCellID() { return 0; }
+ int GetPrevTaskCellID() { return 0; }
+ void AddReachedTaskCell() { }
+ int GetNumTaskCellsReached() { return 0; }
int GetDemeID() const { return 0; }
void SetCellID(int in_id) { ; }
+ void SetBirthCellID(int in_id) { ; }
+ void SetPrevTaskCellID(int in_id) { ; }
void SetDemeID(int in_id) { ; }
bool Divide(cAvidaContext& ctx, cOrganism* parent, cGenome& child_genome);
Modified: branches/energy/source/main/cAvidaConfig.h
===================================================================
--- branches/energy/source/main/cAvidaConfig.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cAvidaConfig.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -506,7 +506,15 @@
CONFIG_ADD_CUSTOM_FORMAT(INST_SET_NEW, "Instruction Set Definition");
CONFIG_ADD_FORMAT_VAR(INST, "Instruction entry in the instruction set");
-
+
+
+ // BDC: Additions for pheromones
+ CONFIG_ADD_GROUP(PHEROMONE_GROUP, "Pheromone Settings");
+ CONFIG_ADD_VAR(PHEROMONE_ENABLED, bool, 0, "Enable pheromone usage. 0/1 (off/on)");
+ CONFIG_ADD_VAR(PHEROMONE_AMOUNT, double, 1.0, "Amount of pheromone to add per drop");
+ CONFIG_ADD_VAR(PHEROMONE_DROP_MODE, int, 0, "Where to drop pheromone\n0 = Half amount at src, half at dest\n1=All at source\n2 = All at dest");
+ CONFIG_ADD_VAR(LOG_PHEROMONE, bool, 0, "Log pheromone drops. 0/1 (off/on)");
+
#endif
void Load(const cString& filename, const bool& crash_if_not_found);
Modified: branches/energy/source/main/cDeme.cc
===================================================================
--- branches/energy/source/main/cDeme.cc 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cDeme.cc 2008-02-19 18:54:46 UTC (rev 2346)
@@ -220,6 +220,40 @@
deme_resource_count.ModifyCell(cell_resources, relative_cell_id);
}
+
+// ------------------------
+// Pheromone-related functions (BDC)
+
+void cDeme::AddPheromone(int absolute_cell_id, double value)
+{
+ assert(cell_ids[0] <= absolute_cell_id);
+ assert(absolute_cell_id <= cell_ids[cell_ids.GetSize()-1]);
+
+ int relative_cell_id = GetRelativeCellID(absolute_cell_id);
+ tArray<double> cell_resources = deme_resource_count.GetCellResources(relative_cell_id);
+
+ for (int i = 0; i < deme_resource_count.GetSize(); i++) {
+ if(strcmp(deme_resource_count.GetResName(i), "pheromone") == 0) {
+ // There should only be one "pheromone" resource, so no need to divvy value up
+ cell_resources[i] = value;
+ //cout << "BDC-DEBUG: Adding " << value << " to pheromone resource " << deme_resource_count.GetResName(i) << "\n";
+ }
+ else {
+ cell_resources[i] = 0;
+ //cout << "BDC-DEBUG: Looking at non-pheromone resource " << deme_resource_count.GetResName(i) << "\n";
+ }
+ }
+
+//It appears that ModifyCell adds the amount of resources specified in the cell_resources array, so I'm just
+//settign the element to the value I want to add instead of setting the element to the current value plus the amount to add
+// Ask Ben why he does it differently in GiveBackCellEnergy()
+
+ deme_resource_count.ModifyCell(cell_resources, relative_cell_id);
+
+} //End AddPheromone()
+
+
+
void cDeme::SetCellEvent(int x1, int y1, int x2, int y2, int delay, int duration, bool static_pos, int time_to_live, int ID) {
cDemeCellEvent demeEvent = cDemeCellEvent(x1, y1, x2, y2, delay, duration, width, GetHeight(), static_pos, time_to_live, this);
if(ID != -1)
@@ -319,6 +353,49 @@
}
}
+
+void cDeme::AddEventMoveBetweenTargetsPred(int times) {
+ if(cell_events.Size() == 0) {
+ cerr<<"Error: An EventMoveBetweenTargets cannot be created until at least one CellEvent is added.\n";
+ exit(1);
+ }
+
+ tVector<cDemeCellEvent *> alive_events;
+
+ for(int i = 0; i < cell_events.Size(); i++) {
+cout << "BDCDEBUG: Looking at cell event " << i << " Is Dead??: " << cell_events[i].IsDead() << " Is Active??: " << cell_events[i].IsActive() << endl;
+ if(!cell_events[i].IsDead()) {
+ alive_events.Add(&cell_events[i]);
+ }
+ }
+
+ cOrgMovementPred_EventMovedBetweenTargets* pred = new cOrgMovementPred_EventMovedBetweenTargets(alive_events, m_world->GetPopulation(), times);
+ m_world->GetStats().AddMovementPredicate(pred);
+ movement_pred_list.Add(pred);
+}
+
+
+void cDeme::AddEventMigrateToTargetsPred(int times) {
+ if(cell_events.Size() == 0) {
+ cerr<<"Error: An EventMigrateToTargets cannot be created until at least one CellEvent is added.\n";
+ exit(1);
+ }
+
+ tVector<cDemeCellEvent *> alive_events;
+
+ for(int i = 0; i < cell_events.Size(); i++) {
+cout << "BDCDEBUG: Looking at cell event " << i << " Is Dead??: " << cell_events[i].IsDead() << " Is Active??: " << cell_events[i].IsActive() << endl;
+ if(!cell_events[i].IsDead()) {
+ alive_events.Add(&cell_events[i]);
+ }
+ }
+
+ cOrgMovementPred_EventMigrateToTargets* pred = new cOrgMovementPred_EventMigrateToTargets(alive_events, m_world->GetPopulation(), times);
+ m_world->GetStats().AddMovementPredicate(pred);
+ movement_pred_list.Add(pred);
+}
+
+
int cDeme::GetNumMessagePredicates() {
return message_pred_list.Size();
}
Modified: branches/energy/source/main/cDeme.h
===================================================================
--- branches/energy/source/main/cDeme.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cDeme.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -116,6 +116,7 @@
void ModifyDemeResCount(const tArray<double> & res_change, const int absolute_cell_id);
double GetAndClearCellEnergy(int absolute_cell_id);
void GiveBackCellEnergy(int absolute_cell_id, double value);
+ void AddPheromone(int absolute_cell_id, double value);
void SetupDemeRes(int id, cResource * res, int verbosity);
void UpdateDemeRes() { deme_resource_count.GetResources(); }
void Update(double time_step) { deme_resource_count.Update(time_step); }
@@ -133,6 +134,8 @@
void AddEventReceivedCenterPred(int times);
void AddEventReceivedLeftSidePred(int times);
void AddEventMoveCenterPred(int times);
+ void AddEventMoveBetweenTargetsPred(int times);
+ void AddEventMigrateToTargetsPred(int times);
int GetNumMessagePredicates();
int GetNumMovementPredicates();
bool PredicatePreviouslySatisfied(int pred_id);
Modified: branches/energy/source/main/cDemeCellEvent.cc
===================================================================
--- branches/energy/source/main/cDemeCellEvent.cc 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cDemeCellEvent.cc 2008-02-19 18:54:46 UTC (rev 2346)
@@ -50,6 +50,7 @@
}
void cDemeCellEvent::ActivateEvent(cWorld* m_world) {
+
if(m_dead) {
return;
}
Modified: branches/energy/source/main/cOrgInterface.h
===================================================================
--- branches/energy/source/main/cOrgInterface.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cOrgInterface.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -54,8 +54,14 @@
virtual ~cOrgInterface() { ; }
virtual int GetCellID() = 0;
+ virtual int GetBirthCellID() = 0;
+ virtual int GetPrevTaskCellID() = 0;
+ virtual int GetNumTaskCellsReached() = 0;
+ virtual void AddReachedTaskCell() = 0;
virtual int GetDemeID() const = 0;
virtual void SetCellID(int in_id) = 0;
+ virtual void SetBirthCellID(int in_id) = 0;
+ virtual void SetPrevTaskCellID(int in_id) = 0;
virtual void SetDemeID(int in_id) = 0;
virtual bool Divide(cAvidaContext& ctx, cOrganism* parent, cGenome& child_genome) = 0;
Modified: branches/energy/source/main/cOrgMovementPredicate.h
===================================================================
--- branches/energy/source/main/cOrgMovementPredicate.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cOrgMovementPredicate.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -136,4 +136,252 @@
int m_current_times;
};
+
+
+/*! A predicate that returns true if an organism has made it to a target cell.
+ * Modified from cOrgMovementPred_EventMovedIntoCenter
+*/
+struct cOrgMovementPred_EventMovedBetweenTargets : public cOrgMovementPredicate {
+ cOrgMovementPred_EventMovedBetweenTargets(tVector<cDemeCellEvent *> events, cPopulation& population, int times) :
+ pop(population)
+ , m_event_received(false)
+ , m_stats_updated(false)
+ , m_events(events)
+ , m_total_times(times)
+ , m_current_times(0)
+ , m_prev_target_event(-1) {}
+
+ ~cOrgMovementPred_EventMovedBetweenTargets() { }
+
+ virtual bool operator()(const cOrganism& org) {
+ int deme_id = org.GetOrgInterface().GetDemeID();
+
+ for(int i = 0; i < m_events.Size(); i++) {
+ cDemeCellEvent *event = m_events[i];
+
+ if(deme_id != event->GetDeme()->GetDemeID() || event->IsDead()) {
+ m_event_received = false;
+ }
+ else {
+ if(event->IsActive()) {
+ int absolute_cell_ID = org.GetCellID();
+ std::pair<int, int> pos = pop.GetDeme(deme_id).GetRelativeCellPosition(absolute_cell_ID);
+
+ if( (event->InCenter(pos)) &&
+ (event->GetEventID() != m_prev_target_event) ) {
+
+ m_current_times++;
+ m_prev_target_event = event->GetEventID();
+
+ if(m_current_times >= m_total_times) {
+
+/*
+ofstream predlog;
+predlog.open("data/predlog.dat", ios::app);
+predlog << "BDCDEBUG organism in deme " << deme_id << " at center for event ";
+predlog << i << " and satisfied the counter" << endl;
+predlog.close();
+*/
+
+ m_event_received = true;
+
+ return m_event_received;
+ }
+
+ } //End if org is in center of event area
+
+ } //End if event is active
+
+ } //End if this event matches the predicate
+
+ } //End going through events
+
+ return m_event_received;
+
+ } //End operator()
+
+ virtual void Print(std::ostream& out) {
+ // WHAT TO PRINT
+ }
+
+ virtual void Reset() {
+ m_event_received = false;
+ m_stats_updated = false;
+ m_current_times = 0;
+ m_prev_target_event = -1;
+ }
+
+ virtual bool PreviouslySatisfied() {
+ return m_event_received;
+ }
+
+ virtual cString GetName() {
+ return "EventMovedBetweenTargets";
+ }
+
+ virtual void UpdateStats(cStats& stats) {
+ if(m_event_received && !m_stats_updated) {
+/* int eventCell = m_event->GetNextEventCellID();
+ while(eventCell != -1) {
+ stats.IncPredSat(eventCell);
+ eventCell = m_event->GetNextEventCellID();
+ }*/
+ m_stats_updated = true;
+ }
+ }
+
+ tVector<cDemeCellEvent *> GetEvents() { return m_events; }
+
+ cPopulation& pop;
+ bool m_event_received;
+ bool m_stats_updated;
+ tVector<cDemeCellEvent *> m_events;
+ int m_total_times;
+ int m_current_times;
+ int m_prev_target_event;
+};
+
+
+
+
+/*! A predicate that returns true if the appropriate number of organisms touch
+ * target cells
+*/
+
+struct cOrgMovementPred_EventMigrateToTargets : public cOrgMovementPredicate {
+ cOrgMovementPred_EventMigrateToTargets(tVector<cDemeCellEvent *> events, cPopulation& population, int numorgs) :
+ pop(population)
+ , m_event_received(false)
+ , m_stats_updated(false)
+ , m_events(events)
+ , m_total_orgs(numorgs)
+ , m_current_orgs(0)
+ , m_prev_target_event(-1) {
+
+//TODO: m_event_orgs needs to be a tVector of pointers to tVectors so that the appropriate
+//values can be updated later. but how do you allocate a new tVector??
+ for(int i = 0; i < m_events.Size(); i++) {
+ tVector<bool> x;
+
+ for(int j = 0; j < population.GetSize(); j++) {
+ x.Add(false);
+ }
+
+ m_event_orgs.Add(x);
+ }
+
+ } //End constructor()
+
+ ~cOrgMovementPred_EventMigrateToTargets() { }
+
+ virtual bool operator()(const cOrganism& org) {
+ int deme_id = org.GetOrgInterface().GetDemeID();
+
+ for(int i = 0; i < m_events.Size(); i++) {
+ cDemeCellEvent *event = m_events[i];
+
+ if(deme_id != event->GetDeme()->GetDemeID() || event->IsDead()) {
+ m_event_received = false;
+ }
+ else {
+ if(event->IsActive()) {
+ int absolute_cell_ID = org.GetCellID();
+ std::pair<int, int> pos = pop.GetDeme(deme_id).GetRelativeCellPosition(absolute_cell_ID);
+
+ if( (event->InCenter(pos)) &&
+ (event->GetEventID() != m_prev_target_event) ) {
+
+//TODO: check to see if current organism (orgid) has been to this target yet
+// - if so, do nothing
+// - otherwise, set its field to true, increment m_current_orgs, and check to see if we've reached our goal
+
+ m_current_orgs++;
+ m_prev_target_event = event->GetEventID();
+
+ if(m_current_orgs >= m_total_orgs) {
+
+/*
+ofstream predlog;
+predlog.open("data/predlog.dat", ios::app);
+predlog << "BDCDEBUG migratetotargets organism in deme " << deme_id << " at center for event ";
+predlog << i << " and satisfied the counter" << endl;
+predlog.close();
+*/
+
+ m_event_received = true;
+
+ return m_event_received;
+ }
+
+ } //End if org is in center of event area
+
+ } //End if event is active
+
+ } //End if this event matches the predicate
+
+ } //End going through events
+
+ return m_event_received;
+
+ } //End operator()
+
+ virtual void Print(std::ostream& out) {
+ // WHAT TO PRINT
+ }
+
+ virtual void Reset() {
+ m_event_received = false;
+ m_stats_updated = false;
+ m_current_orgs = 0;
+ m_prev_target_event = -1;
+
+ m_event_orgs.Clear();
+ for(int i = 0; i < m_events.Size(); i++) {
+ tVector<bool> x;
+
+ for(int j = 0; j < m_pop_size; j++) {
+ x.Add(false);
+ }
+
+ //m_event_orgs.Add(&x);
+ }
+
+
+ }
+
+ virtual bool PreviouslySatisfied() {
+ return m_event_received;
+ }
+
+ virtual cString GetName() {
+ return "EventMovedBetweenTargets";
+ }
+
+ virtual void UpdateStats(cStats& stats) {
+ if(m_event_received && !m_stats_updated) {
+/* int eventCell = m_event->GetNextEventCellID();
+ while(eventCell != -1) {
+ stats.IncPredSat(eventCell);
+ eventCell = m_event->GetNextEventCellID();
+ }*/
+ m_stats_updated = true;
+ }
+ }
+
+ tVector<cDemeCellEvent *> GetEvents() { return m_events; }
+
+ cPopulation& pop;
+ bool m_event_received;
+ bool m_stats_updated;
+ tVector<cDemeCellEvent *> m_events;
+ int m_total_orgs;
+ int m_current_orgs;
+ int m_prev_target_event;
+ tVector< tVector<bool> > m_event_orgs;
+ int m_pop_size;
+
+};
+
+
+
#endif
Modified: branches/energy/source/main/cOrganism.cc
===================================================================
--- branches/energy/source/main/cOrganism.cc 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cOrganism.cc 2008-02-19 18:54:46 UTC (rev 2346)
@@ -746,3 +746,11 @@
}
return 0;
}
+
+// Brian Movement
+void cOrganism::Move(cAvidaContext& ctx)
+{
+ assert(m_interface);
+ DoOutput(ctx);
+} //End cOrganism::Move()
+
Modified: branches/energy/source/main/cOrganism.h
===================================================================
--- branches/energy/source/main/cOrganism.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cOrganism.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -124,6 +124,8 @@
bool m_is_running; // Does this organism have the CPU?
bool m_is_sleeping; // Is this organisms sleeping?
bool m_is_dead; // Is this organism dead?
+
+ bool m_pher_drop; // Is the organism dropping pheromone?
class cNetSupport
{
@@ -185,6 +187,10 @@
bool IsSleeping() { return m_is_sleeping; }
bool IsDead() { return m_is_dead; }
+
+ bool GetPheromoneStatus() { return m_pher_drop; }
+ void TogglePheromone() { m_pher_drop = (m_pher_drop == true) ? false : true; }
+ void SetPheromone(bool newval) { m_pher_drop = newval; }
// -------- cOrgInterface Methods --------
cHardwareBase& GetHardware() { return *m_hardware; }
@@ -201,6 +207,11 @@
void Kaboom(int dist) { m_interface->Kaboom(dist);}
void SpawnDeme() { m_interface->SpawnDeme(); }
int GetCellID() const { return m_interface->GetCellID(); }
+ int GetBirthCellID() const { return m_interface->GetBirthCellID(); }
+ int GetPrevTaskCellID() const { return m_interface->GetPrevTaskCellID(); }
+ void SetPrevTaskCellID(int id) const { m_interface->SetPrevTaskCellID(id); }
+ int GetNumTaskCellsReached() const { m_interface->GetNumTaskCellsReached(); }
+ void AddReachedTaskCell() { m_interface->AddReachedTaskCell(); }
int GetDebugInfo() { return m_interface->Debug(); }
int GetID() { return m_id; }
bool GetSentActive() { return m_sent_active; }
@@ -368,6 +379,10 @@
void SetGradientMovement(const double value) {
m_gradient_movement = value;
}
+
+ // -------- Brian Movement ---------
+public:
+ void Move(cAvidaContext& ctx);
};
Modified: branches/energy/source/main/cPopulation.cc
===================================================================
--- branches/energy/source/main/cPopulation.cc 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cPopulation.cc 2008-02-19 18:54:46 UTC (rev 2346)
@@ -807,8 +807,10 @@
if (cell1.GetID() == cell2.GetID()) return;
// Clear current contents of cells
//cout << "SwapCells: clearing cell contents" << endl;
+
cOrganism * org1 = cell1.RemoveOrganism();
cOrganism * org2 = cell2.RemoveOrganism();
+
// @WRE additions for movement logging
/* int x = 0;
int y = 0;
@@ -1093,7 +1095,7 @@
void cPopulation::ReplicateDemes(int rep_trigger)
{
assert(GetNumDemes()>1); // Sanity check.
-
+
// Determine which demes should be replicated.
const int num_demes = GetNumDemes();
@@ -1297,14 +1299,16 @@
}
}
} else { // GERMLINE_INJECT_ORGS organisms (all identical)
- int source_deme_inject_cell;
- int target_deme_inject_cell;
+ int source_deme_inject_cell = 0;
+ int target_deme_inject_cell = 0;
if(m_world->GetConfig().GERMLINE_RANDOM_PLACEMENT.Get() == 2) {
// inject GERMLINE_INJECT_ORGS organisms in source deme
while(source_deme.GetOrgCount() < m_world->GetConfig().GERMLINE_INJECT_ORGS.Get()) {
// organism is randomly placed in deme
- source_deme_inject_cell = source_deme.GetCellID(m_world->GetRandom().GetInt(0, source_deme.GetSize()-1));
+ do {
+ source_deme_inject_cell = source_deme.GetCellID(m_world->GetRandom().GetInt(0, source_deme.GetSize()-1));
+ } while (cell_array[source_deme_inject_cell].IsOccupied() == true); //ZOOZ
// Lineage label is wrong here; fix.
InjectGenome(source_deme_inject_cell, source_germline.GetLatest(), 0); // source deme
}
@@ -1312,7 +1316,10 @@
// inject GERMLINE_INJECT_ORGS organisms in target deme
while(target_deme.GetOrgCount() < m_world->GetConfig().GERMLINE_INJECT_ORGS.Get()) {
// organism is randomly placed in deme
- target_deme_inject_cell = target_deme.GetCellID(m_world->GetRandom().GetInt(0, target_deme.GetSize()-1));
+ do {
+ target_deme_inject_cell = target_deme.GetCellID(m_world->GetRandom().GetInt(0, target_deme.GetSize()-1));
+ } while (cell_array[target_deme_inject_cell].IsOccupied() == true); //ZOOZ
+
// Lineage label is wrong here; fix.
InjectGenome(target_deme_inject_cell, target_germline.GetLatest(), 0); // target deme
}
@@ -1524,6 +1531,14 @@
for (int deme_id = 0; deme_id < deme_array.GetSize(); deme_id++) {
deme_array[deme_id].AddEventMoveCenterPred(times);
}
+ } else if(type == "EventMovedBetweenTargets") {
+ for (int deme_id = 0; deme_id < deme_array.GetSize(); deme_id++) {
+ deme_array[deme_id].AddEventMoveBetweenTargetsPred(times);
+ }
+ } else if(type == "EventMigrateToTargets") {
+ for (int deme_id = 0; deme_id < deme_array.GetSize(); deme_id++) {
+ deme_array[deme_id].AddEventMigrateToTargetsPred(times);
+ }
} else {
cout << "Unknown Predicate\n";
exit(1);
Modified: branches/energy/source/main/cPopulationCell.cc
===================================================================
--- branches/energy/source/main/cPopulationCell.cc 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cPopulationCell.cc 2008-02-19 18:54:46 UTC (rev 2346)
@@ -180,6 +180,12 @@
// Adjust the organism's attributes to match this cell.
m_organism->GetOrgInterface().SetCellID(m_cell_id);
+
+ // If this organism is new, set the birth cell id
+ if(m_organism->GetOrgInterface().GetBirthCellID() == -1) {
+ m_organism->GetOrgInterface().SetBirthCellID(m_cell_id);
+ }
+
m_organism->GetOrgInterface().SetDemeID(m_deme_id);
if(m_world->GetConfig().ENERGY_ENABLED.Get() == 1 && m_world->GetConfig().FRAC_ENERGY_TRANSFER.Get() > 0.0) {
Modified: branches/energy/source/main/cPopulationInterface.h
===================================================================
--- branches/energy/source/main/cPopulationInterface.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cPopulationInterface.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -45,6 +45,9 @@
private:
cWorld* m_world;
int m_cell_id;
+ int m_birth_cell_id;
+ int m_prev_task_cell;
+ int m_num_task_cells;
int m_deme_id;
cPopulationInterface(); // @not_implemented
@@ -52,12 +55,18 @@
cPopulationInterface operator=(const cPopulationInterface&); // @not_implemented
public:
- cPopulationInterface(cWorld* world) : m_world(world), m_cell_id(-1), m_deme_id(-1) { ; }
+ cPopulationInterface(cWorld* world) : m_world(world), m_cell_id(-1), m_birth_cell_id(-1), m_prev_task_cell(-1), m_num_task_cells(0), m_deme_id(-1) { ; }
virtual ~cPopulationInterface() { ; }
int GetCellID() { return m_cell_id; }
+ int GetBirthCellID() { return m_birth_cell_id; }
+ int GetPrevTaskCellID() { return m_prev_task_cell; }
+ int GetNumTaskCellsReached() { return m_num_task_cells; }
+ void AddReachedTaskCell() { m_num_task_cells++; }
int GetDemeID() const { return m_deme_id; }
void SetCellID(int in_id) { m_cell_id = in_id; }
+ void SetBirthCellID(int in_id) { m_birth_cell_id = in_id; }
+ void SetPrevTaskCellID(int in_id) { m_prev_task_cell = in_id; }
void SetDemeID(int in_id) { m_deme_id = in_id; }
bool Divide(cAvidaContext& ctx, cOrganism* parent, cGenome& child_genome);
Modified: branches/energy/source/main/cTaskLib.cc
===================================================================
--- branches/energy/source/main/cTaskLib.cc 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cTaskLib.cc 2008-02-19 18:54:46 UTC (rev 2346)
@@ -403,9 +403,27 @@
else if (name == "move_to_event")
NewTask(name, "Move to event", &cTaskLib::Task_MoveToEvent);
+ // BDC Movement Tasks
+ if (name == "move")
+ NewTask(name, "Successfully Moved", &cTaskLib::Task_Move);
+ //else if (name == "movesides")
+ // NewTask(name, "Successfully Moved to a Side", &cTaskLib::Task_MoveSides);
+ else if (name == "moveleft")
+ NewTask(name, "Successfully Moved to Left Side", &cTaskLib::Task_MoveLeftSide);
+ else if (name == "moveright")
+ NewTask(name, "Successfully Moved to Right Side", &cTaskLib::Task_MoveRightSide);
+ else if (name == "moveleftmid")
+ NewTask(name, "Successfully Moved to Middle of Left Side", &cTaskLib::Task_MoveLeftMiddle);
+ else if (name == "moverightmid")
+ NewTask(name, "Successfully Moved to Middle of Right Side", &cTaskLib::Task_MoveRightMiddle);
+ else if (name == "movecell23")
+ NewTask(name, "Successfully Moved to cell 23", &cTaskLib::Task_MoveCell23);
+ else if (name == "movecell77")
+ NewTask(name, "Successfully Moved to cell 77", &cTaskLib::Task_MoveCell77);
+ else if (name == "movebetweentwo")
+ NewTask(name, "Move between two pre-defined cells", &cTaskLib::Task_MoveBetweenTwo);
-
// Make sure we have actually found a task
if (task_array.GetSize() == start_size) {
if (errors != NULL && errors->GetSize() == 0) {
@@ -2801,6 +2819,179 @@
return 1.0;
}
+double cTaskLib::Task_Move(cTaskContext& ctx) const
+{
+ if(ctx.GetOrganism()->GetCellID() != ctx.GetOrganism()->GetBirthCellID()) {
+ return 1.0;
+ }
+
+ return 0.0;
+
+} //End cTaskLib::Task_Move()
+
+
+/*
+double cTaskLib::Task_MoveSides(cTaskContext& ctx) const
+{
+ cOrgInterface* iface = ctx.GetOrgInterface();
+ cPopulation pop = m_world->GetPopulation();
+
+ int current_cell = iface->GetCellID();
+ int xsize = m_world->GetPopulation().GetWorldX();
+ int ysize = m_world->GetPopulation().GetWorldY();
+
+ // 0.......99
+ // 100....199
+ // ..........
+ // 9900..9999
+
+ //If we're currently on a side and we weren't here last, success
+ if((current_cell % xsize) == 0) {
+ if(last_movement_task != 0) {
+ last_movement_task = 0;
+ return 1.0;
+ }
+ } else if((current_cell % xsize) == (xsize - 1)) {
+ if(last_movement_task != 1) {
+ last_movement_task = 1;
+ return 1.0;
+ }
+ }
+
+ return 0;
+
+} //End cTaskLib::TaskMoveSides()
+*/
+
+double cTaskLib::Task_MoveLeftSide(cTaskContext& ctx) const
+{
+ cOrgInterface* iface = ctx.GetOrgInterface();
+
+ int current_cell = iface->GetCellID();
+ int xsize = m_world->GetPopulation().GetWorldX();
+ int ysize = m_world->GetPopulation().GetWorldY();
+
+ if((current_cell % xsize) == 0) {
+ return 1.0;
+ }
+
+ return 0;
+
+} //End cTaskLib::TaskMoveLeftSide()
+
+double cTaskLib::Task_MoveRightSide(cTaskContext& ctx) const
+{
+ cOrgInterface* iface = ctx.GetOrgInterface();
+
+ int current_cell = iface->GetCellID();
+ int xsize = m_world->GetPopulation().GetWorldX();
+ int ysize = m_world->GetPopulation().GetWorldY();
+
+ if((current_cell % xsize) == (xsize - 1)) {
+ return 1.0;
+ }
+
+ return 0;
+
+} //End cTaskLib::TaskMoveLeftSide()
+
+
+double cTaskLib::Task_MoveLeftMiddle(cTaskContext& ctx) const
+{
+ cOrgInterface* iface = ctx.GetOrgInterface();
+
+ int current_cell = iface->GetCellID();
+ int xsize = m_world->GetPopulation().GetWorldX();
+ int ysize = m_world->GetPopulation().GetWorldY();
+
+ if( ((current_cell % xsize) == 0) &&
+ (floor(current_cell/xsize) == floor(ysize/2)) ) {
+ return 1.0;
+ }
+
+ return 0;
+
+} //End cTaskLib::TaskMoveLeftMiddle()
+
+
+double cTaskLib::Task_MoveRightMiddle(cTaskContext& ctx) const
+{
+ cOrgInterface* iface = ctx.GetOrgInterface();
+
+ int current_cell = iface->GetCellID();
+ int xsize = m_world->GetPopulation().GetWorldX();
+ int ysize = m_world->GetPopulation().GetWorldY();
+
+ if( ((current_cell % xsize) == (xsize - 1)) &&
+ (floor(current_cell/xsize) == floor(ysize/2)) ) {
+ return 1.0;
+ }
+
+ return 0;
+
+} //End cTaskLib::TaskMoveLeftMiddle()
+
+double cTaskLib::Task_MoveCell23(cTaskContext& ctx) const
+{
+ cOrgInterface* iface = ctx.GetOrgInterface();
+ cDeme& deme = m_world->GetPopulation().GetDeme(ctx.GetOrgInterface()->GetDemeID());
+
+ int current_cell = deme.GetRelativeCellID(iface->GetCellID());
+
+ if(current_cell == 23) {
+ return 1.0;
+ }
+
+ return 0;
+
+} //End cTaskLib::TaskMoveCell23()
+
+double cTaskLib::Task_MoveCell77(cTaskContext& ctx) const
+{
+ cOrgInterface* iface = ctx.GetOrgInterface();
+ cDeme& deme = m_world->GetPopulation().GetDeme(ctx.GetOrgInterface()->GetDemeID());
+
+ int current_cell = deme.GetRelativeCellID(iface->GetCellID());
+
+ if(current_cell == 77) {
+ return 1.0;
+ }
+
+ return 0;
+
+} //End cTaskLib::TaskMoveCell77()
+
+
+double cTaskLib::Task_MoveBetweenTwo(cTaskContext& ctx) const
+{
+ int target1 = 23;
+ int target2 = 77;
+
+ cOrgInterface* iface = ctx.GetOrgInterface();
+
+ cDeme& deme = m_world->GetPopulation().GetDeme(ctx.GetOrgInterface()->GetDemeID());
+
+ int current_cell = deme.GetRelativeCellID(iface->GetCellID());
+ int prev_target = deme.GetRelativeCellID(iface->GetPrevTaskCellID());
+
+ // If the organism is currently on a target cell, see which target cell it previously
+ // visited. Since we want them to move back and forth, only reward if we are on
+ // a different target cell.
+
+ if( (current_cell == target1) || (current_cell == target2) )
+ {
+ if (current_cell == prev_target) {
+ // At some point, we may want to return a fraction
+ return 0;
+ } else {
+ iface->AddReachedTaskCell();
+ return 1.0;
+ }
+ }
+
+} //End cTaskLib::Task_MoveBetweenTwo()
+
+
double cTaskLib::Task_MoveToRightSide(cTaskContext& ctx) const {
cDeme& deme = m_world->GetPopulation().GetDeme(ctx.GetOrgInterface()->GetDemeID());
std::pair<int, int> location = deme.GetRelativeCellPosition(ctx.GetOrgInterface()->GetCellID());
Modified: branches/energy/source/main/cTaskLib.h
===================================================================
--- branches/energy/source/main/cTaskLib.h 2008-02-19 18:33:44 UTC (rev 2345)
+++ branches/energy/source/main/cTaskLib.h 2008-02-19 18:54:46 UTC (rev 2346)
@@ -282,6 +282,19 @@
double Task_MoveNeutralGradient(cTaskContext& ctx) const;
double Task_MoveDownGradient(cTaskContext& ctx) const;
double Task_MoveNotUpGradient(cTaskContext& ctx) const;
+
+ // BDC Movement tasks
+ double Task_Move(cTaskContext& ctx) const;
+ //double Task_MoveSides(cTaskContext& ctx) const;
+ double Task_MoveLeftSide(cTaskContext& ctx) const;
+ double Task_MoveRightSide(cTaskContext& ctx) const;
+ double Task_MoveLeftMiddle(cTaskContext& ctx) const;
+ double Task_MoveRightMiddle(cTaskContext& ctx) const;
+ double Task_MoveCell23(cTaskContext& ctx) const;
+ double Task_MoveCell77(cTaskContext& ctx) const;
+ double Task_MoveBetweenTwo(cTaskContext& ctx) const;
+
+
double Task_MoveToRightSide(cTaskContext& ctx) const;
double Task_MoveToLeftSide(cTaskContext& ctx) const;
double Task_MoveToEvent(cTaskContext& ctx) const;
More information about the Avida-cvs
mailing list