[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