[Avida-SVN] r2479 - in branches/energy/source: actions cpu main

connel42 at myxo.css.msu.edu connel42 at myxo.css.msu.edu
Thu Mar 20 12:30:33 PDT 2008


Author: connel42
Date: 2008-03-20 15:30:32 -0400 (Thu, 20 Mar 2008)
New Revision: 2479

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/cOrgInterface.h
   branches/energy/source/main/cOrgMovementPredicate.h
   branches/energy/source/main/cOrganism.h
   branches/energy/source/main/cPopulation.cc
   branches/energy/source/main/cPopulationInterface.h
   branches/energy/source/main/cTaskLib.cc
   branches/energy/source/main/cTaskLib.h
Log:
added explore and exploit commands, updated sense-target, probably other things as well



Modified: branches/energy/source/actions/PopulationActions.cc
===================================================================
--- branches/energy/source/actions/PopulationActions.cc	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/actions/PopulationActions.cc	2008-03-20 19:30:32 UTC (rev 2479)
@@ -1167,29 +1167,7 @@
   }
 };
 
-/*
- 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);
-  }
-};
-
 /*
  Added predicate to all demes that is satisified when a number of organisms
  reach a target cell
@@ -1709,7 +1687,6 @@
   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<cActionPred_DemeEventEventNUniqueIndividualsMovedIntoTarget>("Pred_DemeEventNUniqueIndividualsMovedIntoTarget");
   
   action_lib->Register<cActionNewTrial>("NewTrial");

Modified: branches/energy/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/energy/source/cpu/cHardwareCPU.cc	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/cpu/cHardwareCPU.cc	2008-03-20 19:30:32 UTC (rev 2479)
@@ -252,6 +252,8 @@
     tInstLibEntry<tMethod>("sensef-m100", &cHardwareCPU::Inst_SenseMult100Facing),
     tInstLibEntry<tMethod>("sense-pheromone", &cHardwareCPU::Inst_SensePheromone),
     tInstLibEntry<tMethod>("sense-pheromone-faced", &cHardwareCPU::Inst_SensePheromoneFaced),
+    tInstLibEntry<tMethod>("exploit", &cHardwareCPU::Inst_Exploit),
+    tInstLibEntry<tMethod>("explore", &cHardwareCPU::Inst_Explore),
 
     
     // Threading instructions
@@ -3151,6 +3153,261 @@
 } //End Inst_SensePheromone()
 
 
+
+// This command should move the organism to the neighbor cell that is a
+// target.  If more than one target exists, it moves towards the last-seen
+// one.  If no target exists, the organism moves forward in its original
+// facing.
+bool cHardwareCPU::Inst_Explore(cAvidaContext& ctx)
+{
+  int num_rotations = 0;
+
+  cPopulation& pop = m_world->GetPopulation();
+  int cellid = organism->GetCellID();
+  cPopulationCell& mycell = pop.GetCell(cellid);
+  cDeme &deme = pop.GetDeme(pop.GetCell(cellid).GetDemeID());
+  cResourceCount deme_resource_count = deme.GetDemeResourceCount();
+
+  int fromcellID, destcellID;
+  int cell_data;
+  
+  // 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();
+
+  // Find if any neighbor is a target
+  for(int i = 0; i < 8; i++) {
+    cell_data = m_world->GetPopulation().GetCell(organism->GetCellID()).GetCellData();
+
+    if(cell_data > 0) {
+      num_rotations = i;
+    }
+
+    mycell.ConnectionList().CircNext();
+  }
+
+  // Rotate until we face the neighbor with a target.
+  // If there was no winner, just move forward.
+  for(int i = 0; i < num_rotations; i++) {
+    mycell.ConnectionList().CircNext();
+  }
+
+  // Move to the faced cell
+  if(stepsize > 0) {
+    fromcellID = organism->GetCellID();
+
+    if(fromcellID == -1) {
+      return false;
+    }
+
+    destcellID = pop.GetCell(fromcellID).GetCellFaced().GetID();
+
+    /*********************/
+    // TEMP.  Remove once movement tasks are implemented.
+    if(pop.GetCell(fromcellID).GetCellData() < pop.GetCell(destcellID).GetCellData()) { // move up gradient
+      organism->SetGradientMovement(1.0);
+    } else if(pop.GetCell(fromcellID).GetCellData() == pop.GetCell(destcellID).GetCellData()) {
+      organism->SetGradientMovement(0.0);
+    } else { // move down gradient
+      organism->SetGradientMovement(-1.0);    
+    }
+    /*********************/ 
+
+    pop.SwapCells(pop.GetCell(fromcellID),pop.GetCell(destcellID));
+    pop.MoveOrganisms(ctx, pop.GetCell(fromcellID), pop.GetCell(destcellID));
+    
+    m_world->GetStats().Move(*organism);
+
+    // If organism is dropping pheromones, mark the appropriate 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);
+	}
+
+    } //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) &&
+        (m_world->GetStats().GetUpdate() >= m_world->GetConfig().EXPLORE_LOG_START.Get()) ) {
+      cString tmpfilename = cStringUtil::Stringf("explore_movelog.dat");
+      cDataFile& df = m_world->GetDataFile(tmpfilename);
+
+      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;
+      }
+
+      cString UpdateStr = cStringUtil::Stringf("%d %d %d %d %f %d",  m_world->GetStats().GetUpdate(), organism->GetID(), rel_srcid, rel_destid, pher_amount, drop_mode);
+      df.WriteRaw(UpdateStr);
+    }
+
+    organism->Move(ctx);
+
+    return true;
+  } else {
+    return false;
+  }
+
+  return true;
+
+} // End Inst_Explore()
+
+
+
+bool cHardwareCPU::Inst_Exploit(cAvidaContext& ctx)
+{
+  int num_rotations = 0;
+  float phero_amount = 0;
+  float max_pheromone = 0;
+
+  cPopulation& pop = m_world->GetPopulation();
+  int cellid = organism->GetCellID();
+  cPopulationCell& mycell = pop.GetCell(cellid);
+  cDeme &deme = pop.GetDeme(pop.GetCell(cellid).GetDemeID());
+  cResourceCount deme_resource_count = deme.GetDemeResourceCount();
+  int relative_cell_id = deme.GetRelativeCellID(cellid);
+  tArray<double> cell_resources = deme_resource_count.GetCellResources(relative_cell_id);
+
+  int fromcellID, destcellID;
+  
+  // 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();
+
+
+  // Find which neighbor has the strongest pheromone
+  for(int i = 0; i < 8; i++) {
+
+    phero_amount = 0;
+
+    for (int j = 0; j < deme_resource_count.GetSize(); j++) {
+      if(strcmp(deme_resource_count.GetResName(j), "pheromone") == 0) {
+        phero_amount = cell_resources[j];
+      }
+    }
+
+    if(phero_amount > max_pheromone) {
+      num_rotations = i;
+      max_pheromone = phero_amount;
+    }
+
+    mycell.ConnectionList().CircNext();
+  }
+
+  // Rotate until we face the neighbor with the strongest pheromone.
+  // If there was no winner, just move forward.
+  for(int i = 0; i < num_rotations; i++) {
+    mycell.ConnectionList().CircNext();
+  }
+
+  // Move to the faced cell
+  if(stepsize > 0) {
+    fromcellID = organism->GetCellID();
+
+    if(fromcellID == -1) {
+      return false;
+    }
+
+    destcellID = pop.GetCell(fromcellID).GetCellFaced().GetID();
+
+    /*********************/
+    // TEMP.  Remove once movement tasks are implemented.
+    if(pop.GetCell(fromcellID).GetCellData() < pop.GetCell(destcellID).GetCellData()) { // move up gradient
+      organism->SetGradientMovement(1.0);
+    } else if(pop.GetCell(fromcellID).GetCellData() == pop.GetCell(destcellID).GetCellData()) {
+      organism->SetGradientMovement(0.0);
+    } else { // move down gradient
+      organism->SetGradientMovement(-1.0);    
+    }
+    /*********************/ 
+
+    pop.SwapCells(pop.GetCell(fromcellID),pop.GetCell(destcellID));
+    pop.MoveOrganisms(ctx, pop.GetCell(fromcellID), pop.GetCell(destcellID));
+    
+    m_world->GetStats().Move(*organism);
+
+    // If organism is dropping pheromones, mark the appropriate 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);
+	}
+
+    } //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) &&
+        (m_world->GetStats().GetUpdate() >= m_world->GetConfig().EXPLOIT_LOG_START.Get()) ) {
+      cString tmpfilename = cStringUtil::Stringf("exploit_movelog.dat");
+      cDataFile& df = m_world->GetDataFile(tmpfilename);
+
+      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;
+      }
+
+      cString UpdateStr = cStringUtil::Stringf("%d %d %d %d %f %d",  m_world->GetStats().GetUpdate(), organism->GetID(), rel_srcid, rel_destid, pher_amount, drop_mode);
+      df.WriteRaw(UpdateStr);
+    }
+
+    organism->Move(ctx);
+
+    return true;
+  } else {
+    return false;
+  }
+
+  return true;
+
+} //End Inst_Exploit()
+
+
+
 // DoSensePheromone -- modified version of DoSense to only sense from
 // pheromone resource in given cell
 bool cHardwareCPU::DoSensePheromone(cAvidaContext& ctx, int cellid)
@@ -3169,14 +3426,6 @@
   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;
     }
   }
@@ -3323,14 +3572,10 @@
 
 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 cell_data = m_world->GetPopulation().GetCell(organism->GetCellID()).GetCellData();
   int val = 0;
 
-  if( (cellID == 23) || (cellID == 77) ) {
+  if(cell_data > 0) {
     val = 1;
   }
 

Modified: branches/energy/source/cpu/cHardwareCPU.h
===================================================================
--- branches/energy/source/cpu/cHardwareCPU.h	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/cpu/cHardwareCPU.h	2008-03-20 19:30:32 UTC (rev 2479)
@@ -498,6 +498,8 @@
   bool DoSensePheromone(cAvidaContext& ctx, int cellid);
   bool Inst_SensePheromone(cAvidaContext& ctx);
   bool Inst_SensePheromoneFaced(cAvidaContext& ctx);
+  bool Inst_Exploit(cAvidaContext& ctx);
+  bool Inst_Explore(cAvidaContext& ctx);
 
 
   // Multi-threading...

Modified: branches/energy/source/cpu/cTestCPUInterface.h
===================================================================
--- branches/energy/source/cpu/cTestCPUInterface.h	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/cpu/cTestCPUInterface.h	2008-03-20 19:30:32 UTC (rev 2479)
@@ -48,7 +48,7 @@
   int GetBirthCellID() { return 0; }
   int GetPrevTaskCellID() { return 0; }
   void AddReachedTaskCell() { }
-  //int GetNumTaskCellsReached() { return 0; }
+  int GetNumTaskCellsReached() { return 0; }
   int GetDemeID() const { return 0; }
   void SetCellID(int in_id) { ; }
   void SetBirthCellID(int in_id) { ; }

Modified: branches/energy/source/main/cAvidaConfig.h
===================================================================
--- branches/energy/source/main/cAvidaConfig.h	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cAvidaConfig.h	2008-03-20 19:30:32 UTC (rev 2479)
@@ -515,6 +515,8 @@
   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)");
+  CONFIG_ADD_VAR(EXPLOIT_LOG_START, int, 0, "Update at which to start logging exploit moves");
+  CONFIG_ADD_VAR(EXPLORE_LOG_START, int, 0, "Update at which to start logging explore moves");
 
 #endif
   

Modified: branches/energy/source/main/cDeme.cc
===================================================================
--- branches/energy/source/main/cDeme.cc	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cDeme.cc	2008-03-20 19:30:32 UTC (rev 2479)
@@ -363,7 +363,6 @@
   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]);
     }
@@ -375,26 +374,6 @@
 }
 
 
-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);
-}
-
 void cDeme::AddEventEventNUniqueIndividualsMovedIntoTargetPred(int times) {
   if(cell_events.Size() == 0) {
     cerr<<"Error: An EventMovedIntoCenter cannot be created until a CellEvent is added.\n";

Modified: branches/energy/source/main/cOrgInterface.h
===================================================================
--- branches/energy/source/main/cOrgInterface.h	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cOrgInterface.h	2008-03-20 19:30:32 UTC (rev 2479)
@@ -56,7 +56,7 @@
   virtual int GetCellID() = 0;
   virtual int GetBirthCellID() = 0;
   virtual int GetPrevTaskCellID() = 0;
-  //virtual int GetNumTaskCellsReached() = 0;
+  virtual int GetNumTaskCellsReached() = 0;
   virtual void AddReachedTaskCell() = 0;
   virtual int GetDemeID() const = 0;
   virtual void SetCellID(int in_id) = 0;

Modified: branches/energy/source/main/cOrgMovementPredicate.h
===================================================================
--- branches/energy/source/main/cOrgMovementPredicate.h	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cOrgMovementPredicate.h	2008-03-20 19:30:32 UTC (rev 2479)
@@ -56,7 +56,8 @@
   virtual bool PreviouslySatisfied() = 0;
   virtual cString GetName() = 0;
   virtual void UpdateStats(cStats& stats) {}
-  virtual cDemeCellEvent* GetEvent() { return NULL; }
+  virtual cDemeCellEvent* GetEvent(int i) { return NULL; }
+  virtual int GetNumEvents() { return 1; }
 };
 
 /*! A predicate that returns true if an organism has made it to the center of the gradient event
@@ -71,7 +72,7 @@
   , m_current_times(0){ }
   
   ~cOrgMovementPred_EventMovedIntoCenter() { }
-  
+
   virtual bool operator()(const cOrganism& org) {
     int deme_id = org.GetOrgInterface().GetDemeID();
     
@@ -127,7 +128,7 @@
     }
   }
   
-  cDemeCellEvent* GetEvent() { return m_event; }
+  cDemeCellEvent* GetEvent(int i) { return m_event; }
   
   cPopulation& pop;
   bool m_event_received;
@@ -148,176 +149,86 @@
   , m_event_received(false)
   , m_stats_updated(false)
   , m_events(events)
-  , m_total_times(times)
-  , m_current_times(0)
-  , m_prev_target_event(-1) {}
+  , m_total_orgs(1)   // TODO: eventually, want to make this a parameter.  problem is cPopulation::AddDemePred takes only 1 arg
+  , m_total_times(times) {
 
+    m_event_success.clear();
+    for(int i = 0; i < m_events.Size(); i++) {
+      set<int> p;
+      p.clear();
+      m_event_success.push_back(p);
+    }
+    m_successful_orgs.clear();
+  } //End constructor
+
   ~cOrgMovementPred_EventMovedBetweenTargets() { }
-  
+
   virtual bool operator()(const cOrganism& org) {
     int deme_id = org.GetOrgInterface().GetDemeID();
+    set<int>::iterator it;
+    int other_event;    // Index of the other event
 
-    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;
+      cDemeCellEvent *event = m_events[i];
+      other_event = (i+1) % 2;
+ 
+      if( (event->IsDead() == false) && (event->IsActive()) &&
+          (deme_id == event->GetDeme()->GetDemeID()) ) {
 
-      for(int j = 0; j < population.GetSize(); j++) {
-        x.Add(false);
-      }
+        int absolute_cell_ID = org.GetCellID();
+        int relative_cell_ID = pop.GetDeme(deme_id).GetRelativeCellID(absolute_cell_ID);  
 
-      m_event_orgs.Add(x);
-    }
 
-  } //End constructor()
+        if(event->OnEventCell(relative_cell_ID)) {
 
-  ~cOrgMovementPred_EventMigrateToTargets() { }
-  
-  virtual bool operator()(const cOrganism& org) {
-    int deme_id = org.GetOrgInterface().GetDemeID();
+          int org_id = -1;
+          org_id = ((cOrganism&) org).GetID();
+	  
+	  m_event_success[i].insert(org_id);
 
-    for(int i = 0; i < m_events.Size(); i++) {
-      cDemeCellEvent *event = m_events[i];
+          it = m_event_success[other_event].find(org_id);
 
-      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(it != m_event_success[other_event].end())
+          {
+             // See how many times this org has gone back and forth.  If it has
+             // done it enough times, it is considered successful
+             int num_backforth = (int) floor(org.GetNumTaskCellsReached()/2);
 
-          if( (event->InCenter(pos)) &&
-              (event->GetEventID() != m_prev_target_event) ) {
+             if(num_backforth >= m_total_times) {
+               m_successful_orgs.insert(org_id);
 
-//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
+               //---- do some logging ----------------------------------------------------------------------
+               ofstream predlog;
+               predlog.open("data/predlog.dat", ios::app);
+               predlog << "BDCDEBUG organism " << org_id << " in deme " << deme_id ;
+               predlog << " has touched both targets " << num_backforth << " times. " << m_successful_orgs.size();
+               predlog << " orgs have done this out of " << m_total_orgs << endl;
 
-            m_current_orgs++;
-            m_prev_target_event = event->GetEventID();
+               set<int>::iterator it;
+               for(int q = 0; q < m_event_success.size(); q++) {
+                 predlog << "ORGS FOR EVENT " << q;
+                   for ( it=m_event_success[q].begin() ; it != m_event_success[q].end(); it++ )
+                     predlog << " " << *it;
+                 predlog << endl;
+               }
 
-            if(m_current_orgs >= m_total_orgs) {
+               predlog.close();
+               //---- end of logging -----------------------------------------------------------------------
 
-/*
-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();
-*/
+               // If enough organisms have touched both targets, predicate is satisfied.
+               if(m_successful_orgs.size() >= m_total_orgs) {
+                 m_event_received = true;
+                 return m_event_received;
+               }
+             }
 
-              m_event_received = true;
 
-	      return m_event_received;
-            }
+          } //End if this organism has gone to the other target as well
 
-          } //End if org is in center of event area
+        } //End if org is in event area
 
-        } //End if event is active
-
       } //End if this event matches the predicate
 
     } //End going through events 
@@ -329,25 +240,18 @@
   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();
+    m_event_success.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);
+      set<int> p;
+      p.clear();
+      m_event_success.push_back(p);
     }
-
-
+    m_successful_orgs.clear();
   }
 
   virtual bool PreviouslySatisfied() {
@@ -369,22 +273,32 @@
     }
   }
   
-  tVector<cDemeCellEvent *> GetEvents() { return m_events; }
+  cDemeCellEvent * GetEvent(int i) {
+    return m_events[i];
+  }
+
+  virtual int GetNumEvents() {
+    return m_events.Size();
+  }
   
   cPopulation& pop;
   bool m_event_received;
   bool m_stats_updated;
   tVector<cDemeCellEvent *> m_events;
+  int m_total_times;
   int m_total_orgs;
-  int m_current_orgs;
-  int m_prev_target_event;
-  tVector< tVector<bool> > m_event_orgs;
-  int m_pop_size;
 
+  vector< set<int> > m_event_success;
+  set<int> m_successful_orgs;
 };
 
 
 
+
+/*! A predicate that returns true if the appropriate number of organisms touch
+ *  target cells
+*/
+
 struct cOrgMovementPred_EventNUniqueIndividualsMovedIntoTarget : public cOrgMovementPredicate {
   cOrgMovementPred_EventNUniqueIndividualsMovedIntoTarget(cDemeCellEvent* event, cPopulation& population, int unique_individuals) :
   pop(population)
@@ -449,7 +363,7 @@
     }
   }
   
-  virtual cDemeCellEvent* GetEvent() {
+  virtual cDemeCellEvent* GetEvent(int i) {
     return m_event;
   }
   

Modified: branches/energy/source/main/cOrganism.h
===================================================================
--- branches/energy/source/main/cOrganism.h	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cOrganism.h	2008-03-20 19:30:32 UTC (rev 2479)
@@ -210,7 +210,7 @@
   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(); }
+  int GetNumTaskCellsReached() const { m_interface->GetNumTaskCellsReached(); }
   void AddReachedTaskCell() { m_interface->AddReachedTaskCell(); }
   int GetDebugInfo() { return m_interface->Debug(); }
   int GetID() const { return m_id; }

Modified: branches/energy/source/main/cPopulation.cc
===================================================================
--- branches/energy/source/main/cPopulation.cc	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cPopulation.cc	2008-03-20 19:30:32 UTC (rev 2479)
@@ -1540,10 +1540,6 @@
     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 if(type == "EventNUniqueIndividualsMovedIntoTarget") {
     for (int deme_id = 0; deme_id < deme_array.GetSize(); deme_id++) {
       deme_array[deme_id].AddEventEventNUniqueIndividualsMovedIntoTargetPred(times);

Modified: branches/energy/source/main/cPopulationInterface.h
===================================================================
--- branches/energy/source/main/cPopulationInterface.h	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cPopulationInterface.h	2008-03-20 19:30:32 UTC (rev 2479)
@@ -61,7 +61,7 @@
   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; }
+  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; }

Modified: branches/energy/source/main/cTaskLib.cc
===================================================================
--- branches/energy/source/main/cTaskLib.cc	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cTaskLib.cc	2008-03-20 19:30:32 UTC (rev 2479)
@@ -30,6 +30,7 @@
 #include "cDeme.h"
 #include "cEnvReqs.h"
 #include "cOrgMessagePredicate.h"
+#include "cOrgMovementPredicate.h"
 #include "cPopulation.h"
 #include "cPopulationCell.h"
 #include "tHashTable.h"
@@ -422,8 +423,13 @@
     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);
+  else if (name == "movetotarget")
+    NewTask(name, "Move to a target area", &cTaskLib::Task_MoveToTarget);
+  else if (name == "movetoevent")
+    NewTask(name, "Move to a target area", &cTaskLib::Task_MoveToMovementEvent);
+  else if (name == "movebetweenevent")
+    NewTask(name, "Move to a target area", &cTaskLib::Task_MoveBetweenMovementEvent);
   
-  
   // Make sure we have actually found a task  
   if (task_array.GetSize() == start_size) {
     if (errors != NULL && errors->GetSize() == 0) {
@@ -2962,6 +2968,37 @@
 } //End cTaskLib::TaskMoveCell77()
 
 
+double cTaskLib::Task_MoveToTarget(cTaskContext& ctx) const
+//Note - a generic version of this is now at - Task_MoveToMovementEvent
+{
+  cOrgInterface* iface = ctx.GetOrgInterface();
+  cDeme& deme = m_world->GetPopulation().GetDeme(ctx.GetOrgInterface()->GetDemeID());
+  int celldata = m_world->GetPopulation().GetCell(iface->GetCellID()).GetCellData();
+
+  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(celldata > 1) 
+  {
+    if (current_cell == prev_target) {
+      // At some point, we may want to return a fraction
+      return 0;
+    } else {
+      iface->AddReachedTaskCell();
+      iface->SetPrevTaskCellID(current_cell);
+      return 1.0;
+    }
+  }
+
+  return 0;
+
+} //End cTaskLib::TaskMoveToTarget()
+
+
 double cTaskLib::Task_MoveBetweenTwo(cTaskContext& ctx) const
 {
   int target1 = 23;
@@ -2985,6 +3022,7 @@
       return 0;
     } else {
       iface->AddReachedTaskCell();
+      iface->SetPrevTaskCellID(current_cell);
       return 1.0;
     }
   }
@@ -3022,3 +3060,65 @@
   }
   return 0.0;
 }
+
+double cTaskLib::Task_MoveToMovementEvent(cTaskContext& ctx) const {
+  cDeme& deme = m_world->GetPopulation().GetDeme(ctx.GetOrgInterface()->GetDemeID());
+  int cell_data = m_world->GetPopulation().GetCell(ctx.GetOrgInterface()->GetCellID()).GetCellData();
+  cOrgInterface* iface = ctx.GetOrgInterface();
+
+  if(cell_data <= 0)
+    return 0.0;
+    
+  for(int i = 0; i < deme.GetNumMovementPredicates(); i++) {
+      if(deme.GetMovPredicate(i)->GetEvent(0)->GetEventID() == cell_data) {
+        iface->AddReachedTaskCell();
+        iface->SetPrevTaskCellID(cell_data);
+        return 1.0;
+      }
+  }
+  return 0.0;
+}
+
+
+double cTaskLib::Task_MoveBetweenMovementEvent(cTaskContext& ctx) const {
+  cDeme& deme = m_world->GetPopulation().GetDeme(ctx.GetOrgInterface()->GetDemeID());
+  int cell_data = m_world->GetPopulation().GetCell(ctx.GetOrgInterface()->GetCellID()).GetCellData();
+  cOrgInterface* iface = ctx.GetOrgInterface();
+  int prev_target = deme.GetRelativeCellID(iface->GetPrevTaskCellID());
+
+  int cellid = ctx.GetOrgInterface()->GetCellID();
+
+  // NOTE: as of now, orgs aren't rewarded if they touch a target more than
+  //   once in a row.  Could be useful in the future to have fractional reward
+  //   or something.
+  if( (cell_data <= 0) || (cell_data == prev_target) )
+    return 0.0;
+    
+  for(int i = 0; i < deme.GetNumMovementPredicates(); i++) {
+      // NOTE: having problems with calling the GetNumEvents function for some reason.  FIXME
+      //int num_events = deme.GetMovPredicate(i)->GetNumEvents;
+      int num_events = 2;
+
+      if(num_events == 1) {
+        if( (deme.GetMovPredicate(i)->GetEvent(0)->IsActive()) &&
+            (deme.GetMovPredicate(i)->GetEvent(0)->GetEventID() == cell_data) ) {
+          iface->AddReachedTaskCell();
+          iface->SetPrevTaskCellID(cell_data);
+          return 1.0;
+        }
+      } else {
+        for(int j = 0; j < num_events; j++) {
+          cDemeCellEvent *event = deme.GetMovPredicate(i)->GetEvent(j);
+          if( (event != NULL) && (event->IsActive()) &&
+              (event->GetEventID() == cell_data) ) {
+            iface->AddReachedTaskCell();
+            iface->SetPrevTaskCellID(cell_data);
+            return 1.0;
+          }
+        }
+      }
+
+  }
+  return 0.0;
+}
+

Modified: branches/energy/source/main/cTaskLib.h
===================================================================
--- branches/energy/source/main/cTaskLib.h	2008-03-20 03:24:37 UTC (rev 2478)
+++ branches/energy/source/main/cTaskLib.h	2008-03-20 19:30:32 UTC (rev 2479)
@@ -292,7 +292,10 @@
   double Task_MoveRightMiddle(cTaskContext& ctx) const;
   double Task_MoveCell23(cTaskContext& ctx) const;
   double Task_MoveCell77(cTaskContext& ctx) const;
+  double Task_MoveToTarget(cTaskContext& ctx) const;
   double Task_MoveBetweenTwo(cTaskContext& ctx) const;
+  double Task_MoveToMovementEvent(cTaskContext& ctx) const;
+  double Task_MoveBetweenMovementEvent(cTaskContext& ctx) const;
 
 
   double Task_MoveToRightSide(cTaskContext& ctx) const;




More information about the Avida-cvs mailing list