[Avida-SVN] r2749 - in branches/movement/source: actions cpu main

grabow38 at myxo.css.msu.edu grabow38 at myxo.css.msu.edu
Fri Aug 8 07:37:04 PDT 2008


Author: grabow38
Date: 2008-08-08 10:37:04 -0400 (Fri, 08 Aug 2008)
New Revision: 2749

Modified:
   branches/movement/source/actions/PrintActions.cc
   branches/movement/source/cpu/cHardwareCPU.cc
   branches/movement/source/cpu/cHardwareCPU.h
   branches/movement/source/main/cAvidaConfig.h
   branches/movement/source/main/cOrganism.cc
   branches/movement/source/main/cOrganism.h
   branches/movement/source/main/cPhenotype.cc
   branches/movement/source/main/cPhenotype.h
   branches/movement/source/main/cPopulation.cc
   branches/movement/source/main/cPopulationCell.cc
   branches/movement/source/main/cStats.cc
   branches/movement/source/main/cStats.h
Log:
Committing code related to idealized gradient and movement tracking to movement branch.

Modified: branches/movement/source/actions/PrintActions.cc
===================================================================
--- branches/movement/source/actions/PrintActions.cc	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/actions/PrintActions.cc	2008-08-08 14:37:04 UTC (rev 2749)
@@ -111,8 +111,9 @@
 // @WRE: Added output event for collected visit counts
 STATS_OUT_FILE(PrintCellVisitsData,         visits.dat			);
 STATS_OUT_FILE(PrintFlowRateTuples,         flow_rate_tuples.dat);
+// @ LMG, movement data stats
+STATS_OUT_FILE(PrintMovementData,           move.dat            );
 
-
 #define POP_OUT_FILE(METHOD, DEFAULT)                                                     /*  1 */ \
 class cAction ## METHOD : public cAction {                                                /*  2 */ \
 private:                                                                                  /*  3 */ \
@@ -2679,7 +2680,10 @@
   
   // @WRE: Added printing of visit data
   action_lib->Register<cActionPrintCellVisitsData>("PrintCellVisitsData");
+  // @ LMG, register print movement data
+  action_lib->Register<cActionPrintMovementData>("PrintMovementData");
 
+
   // Population Out Files
   action_lib->Register<cActionPrintPhenotypeData>("PrintPhenotypeData");
   action_lib->Register<cActionPrintPhenotypeStatus>("PrintPhenotypeStatus");

Modified: branches/movement/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/movement/source/cpu/cHardwareCPU.cc	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/cpu/cHardwareCPU.cc	2008-08-08 14:37:04 UTC (rev 2749)
@@ -225,6 +225,14 @@
     tInstLibEntry<tMethod>("donate-NUL", &cHardwareCPU::Inst_DonateNULL, nInstFlag::STALL),
     tInstLibEntry<tMethod>("donate-facing", &cHardwareCPU::Inst_DonateFacing, nInstFlag::STALL),
     
+	tInstLibEntry<tMethod>("sense-and-remem", &cHardwareCPU::Inst_SenseAndRemember), // @LMG
+	tInstLibEntry<tMethod>("sense-now", &cHardwareCPU::Inst_SenseNow), // @LMG
+	tInstLibEntry<tMethod>("sense-and-remem-noisy", &cHardwareCPU::Inst_SenseAndRememberNoisy), // @LMG
+	tInstLibEntry<tMethod>("sense-random-dist", &cHardwareCPU::Inst_SenseRandomDist), // @LMG
+	tInstLibEntry<tMethod>("sense-now-noisy", &cHardwareCPU::Inst_SenseNowNoisy), // @LMG
+	tInstLibEntry<tMethod>("sense-and-remem-m-curr", &cHardwareCPU::Inst_SenseAndRememberMCurr), // @LMG
+	tInstLibEntry<tMethod>("sense-now-m-curr", &cHardwareCPU::Inst_SenseNowMCurr), // @LMG
+	
     tInstLibEntry<tMethod>("IObuf-add1", &cHardwareCPU::Inst_IOBufAdd1, nInstFlag::STALL),
     tInstLibEntry<tMethod>("IObuf-add0", &cHardwareCPU::Inst_IOBufAdd0, nInstFlag::STALL),
 
@@ -248,6 +256,14 @@
     // @WRE additions for movement
     tInstLibEntry<tMethod>("tumble", &cHardwareCPU::Inst_Tumble, nInstFlag::STALL),
     tInstLibEntry<tMethod>("move", &cHardwareCPU::Inst_Move, nInstFlag::STALL),
+	// @ LMG specialized rotate plus move
+    tInstLibEntry<tMethod>("rotate-right-one-and-move", &cHardwareCPU::Inst_RotateRightOneAndMove),
+    tInstLibEntry<tMethod>("rotate-label-one-and-move", &cHardwareCPU::Inst_RotateLabelAndMove),
+    tInstLibEntry<tMethod>("tumble-and-move", &cHardwareCPU::Inst_TumbleAndMove),
+    tInstLibEntry<tMethod>("rotate-random-one-and-move", &cHardwareCPU::Inst_RotateRandomOneAndMove),
+	// @ LMG, random walk
+	tInstLibEntry<tMethod>("random-walk", &cHardwareCPU::Inst_RandomWalk),
+
     tInstLibEntry<tMethod>("move-to-event", &cHardwareCPU::Inst_MoveToEvent, nInstFlag::STALL),
     tInstLibEntry<tMethod>("if-event-in-unoccupied-neighbor-cell", &cHardwareCPU::Inst_IfNeighborEventInUnoccupiedCell),
     tInstLibEntry<tMethod>("if-event-in-faced-cell", &cHardwareCPU::Inst_IfFacingEventCell),
@@ -3881,7 +3897,596 @@
   return true;
 }
 
+// @ LMG helper function to calculate Euclidean distance between two input grid locations.
+// Note: Currently implemented only for bounded grid
+int cHardwareCPU::CalcDist(int in_cell1, int in_cell2)
+{
+	// Get the size of the world
+	const int world_x = m_world->GetConfig().WORLD_X.Get();
+	
+	// Get the two (x, y) coords from input IDs
+	int cell1_x_coord = in_cell1 % world_x;
+	int cell1_y_coord = in_cell1 / world_x;
+	int cell2_x_coord = in_cell2 % world_x;
+	int cell2_y_coord = in_cell2 / world_x;
+	
+	// Calculate current squared distance and return it
+	return( (cell1_x_coord -  cell2_x_coord) * (cell1_x_coord - cell2_x_coord) + 
+			(cell1_y_coord - cell2_y_coord) * (cell1_y_coord - cell2_y_coord) );
+}
 
+// Sense distance to target cell @LMG
+bool cHardwareCPU::Inst_SenseAndRemember(cAvidaContext& ctx)
+{
+  //double r = 0;  // Reward factor, eventually will be configurable
+  double r = m_world->GetConfig().REWARD_FACTOR.Get();
+  
+  // Get the size of the world, organism and target cell IDs, calculate (x, y)s
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+
+  int target_id = organism->GetTargetCellID();
+  // Check for a good target cell ID
+  if (target_id == -1) {
+   // cout << "Target ID not initialized for this cell." << endl;
+    return true;
+  }
+
+  if (target_id < 0 || target_id > world_x * world_x ) {
+    //cout << "Invalid target initialization for this cell." << endl;
+	return true;
+  }
+	
+  // Get the target and organism (x, y)
+  int target_x_coord = target_id % world_x;
+  int target_y_coord = target_id / world_x;
+
+  int org_id = organism->GetCellID();
+  if (org_id < 0) {
+   // cout << "Invalid cell id." << endl;
+	return true;
+  }
+  
+  int org_x_coord = org_id % world_x;
+  int org_y_coord = org_id / world_x;
+
+  // Calculate current squared distance
+  int cur_dist = (org_x_coord - target_x_coord) * (org_x_coord - target_x_coord) + 
+				 (org_y_coord - target_y_coord) * (org_y_coord - target_y_coord);
+
+  // Get initial, best, last distances
+  int init_dist = organism->GetPhenotype().GetInitDistance();
+  int best_dist = organism->GetPhenotype().GetBestDistance();
+  int last_dist = organism->GetPhenotype().GetLastDistance();
+
+  // Check for valid best distance value, just return if invalid
+  if (best_dist > world_x * world_x * 2) { return true; }
+	
+  // Update phenotype info
+  int x_diff = abs(org_x_coord - target_x_coord);
+  int y_diff = abs(org_y_coord - target_y_coord);
+  organism->GetPhenotype().SetCurNumStepsTarget(x_diff, y_diff);
+   // cout << "X diff, Y diff: " << x_diff << "  " << y_diff << " Current steps from target: " << organism->GetPhenotype().GetCurNumStepsTarget() << endl;
+  
+  // Calculate best and current distance ratios
+  double best_ratio = 1 - (double)best_dist/(double)init_dist;
+  double current_ratio = 1 - (double)cur_dist/(double)init_dist;
+  //cout << "Best %: " << best_ratio << " Current %: " << current_ratio << endl;
+  //cout << "Last best ratio: " << organism->GetPhenotype().GetLastBestDistanceRatio() << endl;
+
+  // Update current distance ratio
+  organism->GetPhenotype().SetCurDistanceRatio(current_ratio);
+  
+  if (cur_dist < best_dist) {
+    //r = 10;
+    organism->GetPhenotype().SetBestDistance(cur_dist);
+	organism->GetPhenotype().SetCurBestDistanceRatio(current_ratio);
+	//cout << " New best dist: " << organism->GetPhenotype().GetBestDistance() << endl;
+	
+	// Get current bonus, calculate new bonus and update
+    double cur_bonus = organism->GetPhenotype().GetCurBonus();
+    //cout << "Old bonus: " << cur_bonus;
+  
+    cur_bonus *= exp2((current_ratio - best_ratio) * r);
+    organism->GetPhenotype().SetCurBonus(cur_bonus);
+    //cout << " New bonus: " << cur_bonus << endl;
+	//cout << " Reward = " << r << endl;
+  }
+
+  
+  // Put current and last distances into registers for future use
+  const int reg1_used = FindModifiedRegister(REG_CX);
+  GetRegister(reg1_used) = cur_dist;
+  const int reg2_used = FindModifiedRegister(REG_BX);
+  GetRegister(reg2_used) = last_dist;
+
+  // Set current distance as new value for last distance to target
+  organism->GetPhenotype().SetLastDistance(cur_dist);
+  
+  return true;
+}
+
+// Sense distance to target cell @LMG
+// Puts only the current distance value into register
+bool cHardwareCPU::Inst_SenseNow(cAvidaContext& ctx)
+{
+  double r = m_world->GetConfig().REWARD_FACTOR.Get();
+  
+  // Get the size of the world, organism and target cell IDs, calculate (x, y)s
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+
+  int target_id = organism->GetTargetCellID();
+  // Check for a good target cell ID
+  if (target_id == -1) {
+   // cout << "Target ID not initialized for this cell." << endl;
+    return true;
+  }
+
+  if (target_id < 0 || target_id > world_x * world_x ) {
+    //cout << "Invalid target initialization for this cell." << endl;
+	return true;
+  }
+	
+  // Get the target and organism (x, y)
+  int target_x_coord = target_id % world_x;
+  int target_y_coord = target_id / world_x;
+
+  int org_id = organism->GetCellID();
+  if (org_id < 0) {
+   // cout << "Invalid cell id." << endl;
+	return true;
+  }
+  
+  int org_x_coord = org_id % world_x;
+  int org_y_coord = org_id / world_x;
+
+  // Calculate current squared distance
+  int cur_dist = (org_x_coord - target_x_coord) * (org_x_coord - target_x_coord) + 
+				 (org_y_coord - target_y_coord) * (org_y_coord - target_y_coord);
+
+  // Get initial, best, last distances
+  int init_dist = organism->GetPhenotype().GetInitDistance();
+  int best_dist = organism->GetPhenotype().GetBestDistance();
+  //int last_dist = organism->GetPhenotype().GetLastDistance();
+
+  // Check for valid best distance value, just return if invalid
+  if (best_dist > world_x * world_x * 2) { return true; }
+	
+  // Update phenotype info
+  int x_diff = abs(org_x_coord - target_x_coord);
+  int y_diff = abs(org_y_coord - target_y_coord);
+  organism->GetPhenotype().SetCurNumStepsTarget(x_diff, y_diff);
+   // cout << "X diff, Y diff: " << x_diff << "  " << y_diff << " Current steps from target: " << organism->GetPhenotype().GetCurNumStepsTarget() << endl;
+  
+  // Calculate best and current distance ratios
+  double best_ratio = 1 - (double)best_dist/(double)init_dist;
+  double current_ratio = 1 - (double)cur_dist/(double)init_dist;
+  //cout << "Best %: " << best_ratio << " Current %: " << current_ratio << endl;
+  //cout << "Last best ratio: " << organism->GetPhenotype().GetLastBestDistanceRatio() << endl;
+
+  // Update current distance ratio
+  organism->GetPhenotype().SetCurDistanceRatio(current_ratio);
+  
+  if (cur_dist < best_dist) {
+    //r = 10;
+    organism->GetPhenotype().SetBestDistance(cur_dist);
+	organism->GetPhenotype().SetCurBestDistanceRatio(current_ratio);
+	//cout << " New best dist: " << organism->GetPhenotype().GetBestDistance() << endl;
+	
+	// Get current bonus, calculate new bonus and update
+    double cur_bonus = organism->GetPhenotype().GetCurBonus();
+    //cout << "Old bonus: " << cur_bonus;
+  
+    cur_bonus *= exp2((current_ratio - best_ratio) * r);
+    organism->GetPhenotype().SetCurBonus(cur_bonus);
+    //cout << " New bonus: " << cur_bonus << endl;
+	//cout << " Reward = " << r << endl;
+  }
+  
+  // Put current distance into register for future use
+  const int reg1_used = FindModifiedRegister(REG_CX);
+  GetRegister(reg1_used) = cur_dist;
+  //const int reg2_used = FindModifiedRegister(REG_BX);
+  //GetRegister(reg2_used) = last_dist;
+
+  // Set current distance as new value for last distance to target
+  organism->GetPhenotype().SetLastDistance(cur_dist);
+  
+  return true;
+}
+
+// Sense distance to target cell, with noise @LMG 7 Feb 08
+bool cHardwareCPU::Inst_SenseAndRememberNoisy(cAvidaContext& ctx)
+{
+  double r = m_world->GetConfig().REWARD_FACTOR.Get();
+  double noise_level = m_world->GetConfig().DIST_NOISE_LEVEL.Get();
+  
+  // Get the size of the world, organism and target cell IDs, calculate (x, y)s
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+
+  int target_id = organism->GetTargetCellID();
+  // Check for a good target cell ID
+  if (target_id == -1) {
+   // cout << "Target ID not initialized for this cell." << endl;
+    return true;
+  }
+
+  if (target_id < 0 || target_id > world_x * world_x ) {
+    //cout << "Invalid target initialization for this cell." << endl;
+	return true;
+  }
+	
+  // Get the target and organism (x, y)
+  int target_x_coord = target_id % world_x;
+  int target_y_coord = target_id / world_x;
+
+  int org_id = organism->GetCellID();
+  if (org_id < 0) {
+   // cout << "Invalid cell id." << endl;
+	return true;
+  }
+  
+  int org_x_coord = org_id % world_x;
+  int org_y_coord = org_id / world_x;
+ 
+  // Calculate current squared distance
+  int cur_dist = int((org_x_coord - target_x_coord) * (org_x_coord - target_x_coord) + 
+				 (org_y_coord - target_y_coord) * (org_y_coord - target_y_coord));
+
+  // Get initial, best, last distances
+  int init_dist = organism->GetPhenotype().GetInitDistance();
+  int best_dist = organism->GetPhenotype().GetBestDistance();
+  int last_dist = organism->GetPhenotype().GetLastDistance();
+
+  // Check for valid best distance value
+  if (best_dist > world_x * world_x * 2) { 
+	return true;
+  }
+	  
+  // Update phenotype info
+  int x_diff = abs(org_x_coord - target_x_coord);
+  int y_diff = abs(org_y_coord - target_y_coord);
+  organism->GetPhenotype().SetCurNumStepsTarget(x_diff, y_diff);
+  
+  // Calculate best and current distance ratios
+  double best_ratio = 1 - (double)best_dist/(double)init_dist;
+  double current_ratio = 1 - (double)cur_dist/(double)init_dist;
+  
+  if (cur_dist < best_dist) {
+    organism->GetPhenotype().SetBestDistance(cur_dist);
+	organism->GetPhenotype().SetCurBestDistanceRatio(current_ratio);
+	
+	// Get current bonus, calculate new bonus and update
+    double cur_bonus = organism->GetPhenotype().GetCurBonus();
+  
+    cur_bonus *= exp2((current_ratio - best_ratio) * r);
+    organism->GetPhenotype().SetCurBonus(cur_bonus);
+  }
+  
+  // Give the organism a sensed distance with noise
+  double noise = ctx.GetRandom().GetDouble(1 - noise_level, 1 + noise_level); // Generate a multiplier in the given range
+  int sensed_dist = int(cur_dist * noise);
+				 
+  // Put current and last distances into registers for future use
+  const int reg1_used = FindModifiedRegister(REG_CX);
+  GetRegister(reg1_used) = sensed_dist;
+  const int reg2_used = FindModifiedRegister(REG_BX);
+  GetRegister(reg2_used) = last_dist;
+
+  // Set current distance as new value for last distance to target
+  organism->GetPhenotype().SetLastDistance(sensed_dist);
+  
+  return true;
+}
+
+// Sense random value as distance to target @LMG 15 Feb 08
+bool cHardwareCPU::Inst_SenseRandomDist(cAvidaContext& ctx)
+{
+  double r = m_world->GetConfig().REWARD_FACTOR.Get();
+  
+  // Get the size of the world, organism and target cell IDs, calculate (x, y)s
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+  
+  int target_id = organism->GetTargetCellID();
+  // Check for a good target cell ID
+  if (target_id == -1) {
+   // cout << "Target ID not initialized for this cell." << endl;
+    return true;
+  }
+
+  if (target_id < 0 || target_id > world_x * world_x ) {
+    //cout << "Invalid target initialization for this cell." << endl;
+	return true;
+  }
+	
+  // Get the target and organism (x, y)
+  int target_x_coord = target_id % world_x;
+  int target_y_coord = target_id / world_x;
+
+  int org_id = organism->GetCellID();
+  if (org_id < 0) {
+   // cout << "Invalid cell id." << endl;
+	return true;
+  }
+  
+  int org_x_coord = org_id % world_x;
+  int org_y_coord = org_id / world_x;
+ 
+  // Calculate current squared distance
+  int cur_dist = int((org_x_coord - target_x_coord) * (org_x_coord - target_x_coord) + 
+				 (org_y_coord - target_y_coord) * (org_y_coord - target_y_coord));  
+
+  // Get initial, best, last distances
+  int init_dist = organism->GetPhenotype().GetInitDistance();
+  int best_dist = organism->GetPhenotype().GetBestDistance();
+  int last_dist = organism->GetPhenotype().GetLastDistance();
+
+  // Check for valid best distance value
+  if (best_dist > world_x * world_x * 2) { 
+	return true;
+  }
+  
+  // Update phenotype info
+  int x_diff = abs(org_x_coord - target_x_coord);
+  int y_diff = abs(org_y_coord - target_y_coord);
+  organism->GetPhenotype().SetCurNumStepsTarget(x_diff, y_diff);
+  
+  // Calculate best and current distance ratios
+  double best_ratio = 1 - (double)best_dist/(double)init_dist;
+  double current_ratio = 1 - (double)cur_dist/(double)init_dist;
+
+  if (cur_dist < best_dist) {
+    organism->GetPhenotype().SetBestDistance(cur_dist);
+	organism->GetPhenotype().SetCurBestDistanceRatio(current_ratio);
+	
+	// Get current bonus, calculate new bonus and update
+    double cur_bonus = organism->GetPhenotype().GetCurBonus();
+	  
+    cur_bonus *= exp2((current_ratio - best_ratio) * r);
+    organism->GetPhenotype().SetCurBonus(cur_bonus);
+  }
+  
+  // Generate a random int value and give it as the current sensed distance
+  int sensed_dist = m_world->GetRandom().GetUInt(world_x * world_x);
+  
+  // Put current and last distances into registers for future use
+  const int reg1_used = FindModifiedRegister(REG_CX);
+  GetRegister(reg1_used) = sensed_dist;
+  const int reg2_used = FindModifiedRegister(REG_BX);
+  GetRegister(reg2_used) = last_dist;
+
+  // Set current distance as new value for last distance to target
+  organism->GetPhenotype().SetLastDistance(sensed_dist);
+  
+  return true;
+}
+
+// Inst_SenseTargetDistInstNoisy
+// Sense distance to target cell, with noise, no hand-coded memory @LMG 4 Apr 2008
+bool cHardwareCPU::Inst_SenseNowNoisy(cAvidaContext& ctx)
+{
+  double r = m_world->GetConfig().REWARD_FACTOR.Get();
+  double noise_level = m_world->GetConfig().DIST_NOISE_LEVEL.Get();
+  
+  // Get the size of the world, organism and target cell IDs, calculate (x, y)s
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+
+  int target_id = organism->GetTargetCellID();
+  // Check for a good target cell ID
+  if (target_id == -1) {
+   // cout << "Target ID not initialized for this cell." << endl;
+    return true;
+  }
+
+  if (target_id < 0 || target_id > world_x * world_x ) {
+    //cout << "Invalid target initialization for this cell." << endl;
+	return true;
+  }
+	
+  // Get the target and organism (x, y)
+  int target_x_coord = target_id % world_x;
+  int target_y_coord = target_id / world_x;
+
+  int org_id = organism->GetCellID();
+  if (org_id < 0) {
+   // cout << "Invalid cell id." << endl;
+	return true;
+  }
+  
+  int org_x_coord = org_id % world_x;
+  int org_y_coord = org_id / world_x;
+ 
+  // Calculate current squared distance
+  int cur_dist = int((org_x_coord - target_x_coord) * (org_x_coord - target_x_coord) + 
+				 (org_y_coord - target_y_coord) * (org_y_coord - target_y_coord));
+
+  // Get initial, best, distances
+  int init_dist = organism->GetPhenotype().GetInitDistance();
+  int best_dist = organism->GetPhenotype().GetBestDistance();
+  
+  // Check for valid best distance value
+  if (best_dist > world_x * world_x * 2) { 
+	return true;
+  }
+	  
+  // Update phenotype info
+  int x_diff = abs(org_x_coord - target_x_coord);
+  int y_diff = abs(org_y_coord - target_y_coord);
+  organism->GetPhenotype().SetCurNumStepsTarget(x_diff, y_diff);
+  
+  // Calculate best and current distance ratios
+  double best_ratio = 1 - (double)best_dist/(double)init_dist;
+  double current_ratio = 1 - (double)cur_dist/(double)init_dist;
+  
+  if (cur_dist < best_dist) {
+    organism->GetPhenotype().SetBestDistance(cur_dist);
+	organism->GetPhenotype().SetCurBestDistanceRatio(current_ratio);
+	
+	// Get current bonus, calculate new bonus and update
+    double cur_bonus = organism->GetPhenotype().GetCurBonus();
+  
+    cur_bonus *= exp2((current_ratio - best_ratio) * r);
+    organism->GetPhenotype().SetCurBonus(cur_bonus);
+  }
+  
+  // Give the organism a sensed distance with noise
+  double noise = ctx.GetRandom().GetDouble(1 - noise_level, 1 + noise_level); // Generate a multiplier in the given range
+  int sensed_dist = int(cur_dist * noise);
+				 
+  // Put current distance into registers for future use
+  const int reg1_used = FindModifiedRegister(REG_CX);
+  GetRegister(reg1_used) = sensed_dist;
+
+  // Set current distance as new value for last distance to target
+  organism->GetPhenotype().SetLastDistance(sensed_dist);
+  
+  return true;
+}
+
+// ************
+// Sense distance to target cell @LMG
+// Merit bonus is based on current distance to target instead of best distance
+bool cHardwareCPU::Inst_SenseAndRememberMCurr(cAvidaContext& ctx)
+{
+  // Get the size of the world, organism and target cell IDs, calculate (x, y)s
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+
+  int target_id = organism->GetTargetCellID();
+  // Check for a good target cell ID
+  if (target_id == -1) {
+   // cout << "Target ID not initialized for this cell." << endl;
+    return true;
+  }
+
+  if (target_id < 0 || target_id > world_x * world_x ) {
+    //cout << "Invalid target initialization for this cell." << endl;
+	return true;
+  }
+	
+  // Get the target and organism (x, y)
+  int target_x_coord = target_id % world_x;
+  int target_y_coord = target_id / world_x;
+
+  int org_id = organism->GetCellID();
+  if (org_id < 0) {
+   // cout << "Invalid cell id." << endl;
+	return true;
+  }
+  
+  int org_x_coord = org_id % world_x;
+  int org_y_coord = org_id / world_x;
+
+  // Calculate current squared distance
+  int cur_dist = (org_x_coord - target_x_coord) * (org_x_coord - target_x_coord) + 
+				 (org_y_coord - target_y_coord) * (org_y_coord - target_y_coord);
+
+  // Get initial, best, last distances
+  int init_dist = organism->GetPhenotype().GetInitDistance();
+  int best_dist = organism->GetPhenotype().GetBestDistance();
+  int last_dist = organism->GetPhenotype().GetLastDistance();
+
+  // Check for valid best distance value
+  if (best_dist > world_x * world_x * 2) { 
+  	return true;
+  }
+	 
+  // Calculate current distance ratio
+  double current_ratio = 1 - (double)cur_dist/(double)init_dist;
+  
+  if (cur_dist < best_dist) {
+    organism->GetPhenotype().SetBestDistance(cur_dist);
+	organism->GetPhenotype().SetCurBestDistanceRatio(current_ratio);
+  }
+  
+  // Update phenotype info
+  int x_diff = abs(org_x_coord - target_x_coord);
+  int y_diff = abs(org_y_coord - target_y_coord);
+  organism->GetPhenotype().SetCurNumStepsTarget(x_diff, y_diff);
+  organism->GetPhenotype().SetCurDistanceRatio(current_ratio);
+  organism->GetPhenotype().SetEndCellID(org_id);
+
+  // Put current and last distances into registers for future use
+  const int reg1_used = FindModifiedRegister(REG_CX);
+  GetRegister(reg1_used) = cur_dist;
+  const int reg2_used = FindModifiedRegister(REG_BX);
+  GetRegister(reg2_used) = last_dist;
+
+  // Set current distance as new value for last distance to target
+  organism->GetPhenotype().SetLastDistance(cur_dist);
+  
+  return true;
+}
+
+// Sense distance to target cell @LMG
+// Puts only the current distance value into register
+// Merit bonus is based on current distance to target instead of best distance
+bool cHardwareCPU::Inst_SenseNowMCurr(cAvidaContext& ctx)
+{
+  // Get the size of the world, organism and target cell IDs, calculate (x, y)s
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+
+  int target_id = organism->GetTargetCellID();
+  // Check for a good target cell ID
+  if (target_id == -1) {
+   // cout << "Target ID not initialized for this cell." << endl;
+    return true;
+  }
+
+  if (target_id < 0 || target_id > world_x * world_x ) {
+    //cout << "Invalid target initialization for this cell." << endl;
+	return true;
+  }
+	
+  // Get the target and organism (x, y)
+  int target_x_coord = target_id % world_x;
+  int target_y_coord = target_id / world_x;
+
+  int org_id = organism->GetCellID();
+  if (org_id < 0) {
+   // cout << "Invalid cell id." << endl;
+	return true;
+  }
+  
+  int org_x_coord = org_id % world_x;
+  int org_y_coord = org_id / world_x;
+
+  // Calculate current squared distance
+  int cur_dist = (org_x_coord - target_x_coord) * (org_x_coord - target_x_coord) + 
+				 (org_y_coord - target_y_coord) * (org_y_coord - target_y_coord);
+
+  // Get initial, best distances
+  int init_dist = organism->GetPhenotype().GetInitDistance();
+  int best_dist = organism->GetPhenotype().GetBestDistance();
+  
+  // Check for valid best distance value
+  if (best_dist > world_x * world_x * 2) { 
+  	return true;
+  }
+	 
+  // Calculate current distance ratio
+  double current_ratio = 1 - (double)cur_dist/(double)init_dist;
+  
+  if (cur_dist < best_dist) {
+    organism->GetPhenotype().SetBestDistance(cur_dist);
+	organism->GetPhenotype().SetCurBestDistanceRatio(current_ratio);
+  }
+  
+  // Update phenotype info
+  int x_diff = abs(org_x_coord - target_x_coord);
+  int y_diff = abs(org_y_coord - target_y_coord);
+  organism->GetPhenotype().SetCurNumStepsTarget(x_diff, y_diff);
+  organism->GetPhenotype().SetCurDistanceRatio(current_ratio);
+  organism->GetPhenotype().SetEndCellID(org_id);
+
+  // Put current and last distances into registers for future use
+  const int reg1_used = FindModifiedRegister(REG_CX);
+  GetRegister(reg1_used) = cur_dist;
+  
+  // Set current distance as new value for last distance to target
+  organism->GetPhenotype().SetLastDistance(cur_dist);
+  
+  return true;
+}
+
 bool cHardwareCPU::Inst_SearchF(cAvidaContext& ctx)
 {
   ReadLabel();
@@ -4143,6 +4748,11 @@
     // Swap inputs and facings between cells using helper function
     pop.MoveOrganisms(ctx, pop.GetCell(fromcellID), pop.GetCell(destcellID));
     
+	// @LMG, to save current cell ID in phenotype for merit bonus on divide with movement
+	if (m_world->GetConfig().MOVT_MERIT_DIV.Get()) {
+	  organism->GetPhenotype().SetEndCellID(destcellID);
+	}
+	
     // updates movement predicates
     m_world->GetStats().Move(*organism);
 
@@ -4196,6 +4806,51 @@
   }
 }
 
+// @ LMG, rotations plus move one cell in a single instruction
+// This set of instructions calls existing instructions in order to use a given rotation
+// strategy and move immediately afterwards.
+bool cHardwareCPU::Inst_RotateRightOneAndMove(cAvidaContext& ctx)
+{
+	bool result = Inst_RotateRightOne(ctx);
+	result = Inst_Move(ctx);
+	return true;
+}
+
+bool cHardwareCPU::Inst_RotateLabelAndMove(cAvidaContext& ctx)
+{
+	bool result = Inst_RotateLabel(ctx);
+	result = Inst_Move(ctx);
+	return true;
+}
+
+bool cHardwareCPU::Inst_TumbleAndMove(cAvidaContext& ctx)
+{
+	bool result = Inst_Tumble(ctx);
+	result = Inst_Move(ctx);
+	return true;
+}
+
+bool cHardwareCPU::Inst_RotateRandomOneAndMove(cAvidaContext& ctx)
+{
+	bool result;
+    double value = ctx.GetRandom().GetDouble(0, 1);
+	
+	if (value < 0.5) result = Inst_RotateRightOne(ctx);
+	else result = Inst_RotateLeftOne(ctx);
+	
+	return true;
+}
+
+// @ LMG, random walk instruction 13 March 2008
+bool cHardwareCPU::Inst_RandomWalk(cAvidaContext& ctx)
+{
+	double value = ctx.GetRandom().GetDouble(0, 1);
+	bool result;
+	if (value < 0.5) result = Inst_Tumble(ctx);
+	else  result = Inst_Move(ctx);
+	return true;
+}
+
 bool cHardwareCPU::Inst_MoveToEvent(cAvidaContext& ctx) {
   const int reg_used = FindModifiedRegister(REG_BX);
   int orginalFacing = organism->GetFacing();

Modified: branches/movement/source/cpu/cHardwareCPU.h
===================================================================
--- branches/movement/source/cpu/cHardwareCPU.h	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/cpu/cHardwareCPU.h	2008-08-08 14:37:04 UTC (rev 2749)
@@ -483,6 +483,15 @@
   bool Inst_DonateNULL(cAvidaContext& ctx);
   bool Inst_DonateFacing(cAvidaContext& ctx);
 
+  int CalcDist(int in_cell1, int in_cell2); // @LMG helper function to calculate distance
+  bool Inst_SenseAndRemember(cAvidaContext& ctx); // @LMG
+  bool Inst_SenseNow(cAvidaContext& ctx); // @LMG
+  bool Inst_SenseAndRememberNoisy(cAvidaContext& ctx); // @LMG
+  bool Inst_SenseRandomDist(cAvidaContext& ctx); // @LMG
+  bool Inst_SenseNowNoisy(cAvidaContext& ctx); // @LMG
+  bool Inst_SenseAndRememberMCurr(cAvidaContext& ctx);
+  bool Inst_SenseNowMCurr(cAvidaContext& ctx);
+
   bool Inst_SearchF(cAvidaContext& ctx);
   bool Inst_SearchB(cAvidaContext& ctx);
   bool Inst_MemSize(cAvidaContext& ctx);
@@ -510,6 +519,14 @@
   // @WRE additions for movement
   bool Inst_Tumble(cAvidaContext& ctx);
   bool Inst_Move(cAvidaContext& ctx);
+  // @ LMG, rotations plus move one cell in a single instruction
+  bool Inst_RotateRightOneAndMove(cAvidaContext& ctx);
+  bool Inst_RotateLabelAndMove(cAvidaContext& ctx);
+  bool Inst_TumbleAndMove(cAvidaContext& ctx);
+  bool Inst_RotateRandomOneAndMove(cAvidaContext& ctx);
+  // @ LMG, random walk
+  bool Inst_RandomWalk(cAvidaContext& ctx);
+  
   bool Inst_MoveToEvent(cAvidaContext& ctx);
   bool Inst_IfNeighborEventInUnoccupiedCell(cAvidaContext& ctx);
   bool Inst_IfFacingEventCell(cAvidaContext& ctx);

Modified: branches/movement/source/main/cAvidaConfig.h
===================================================================
--- branches/movement/source/main/cAvidaConfig.h	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cAvidaConfig.h	2008-08-08 14:37:04 UTC (rev 2749)
@@ -539,6 +539,14 @@
   CONFIG_ADD_VAR(BIOMIMETIC_EVAL_ON_MOVEMENT, int, 0, "Force task evaluation on each movement step");
   CONFIG_ADD_VAR(BIOMIMETIC_K, int, 0, "Carrying capacity in number of organisms");
 
+  // @ LMG, config options related to target cell
+  CONFIG_ADD_VAR(REWARD_FACTOR, double, 0, "Value used for reward in sense-target instruction");
+  CONFIG_ADD_VAR(TARGET_DIST_THRESH, int, 50, "Minimum squared distance of target cell from organism");
+  CONFIG_ADD_VAR(DIST_NOISE_LEVEL, double, 0, "Amount of noise (+/_ %) to add to target distance measurement");
+  CONFIG_ADD_VAR(MOVT_TRACK_ON, int, 0, "Movement tracking on [1 = on, 0 = off]");
+  CONFIG_ADD_VAR(MOVT_MERIT_DIV, int, 0, "Calculate merit bonus only on divide [1 = yes, 0 = no]");
+  CONFIG_ADD_VAR(MOVT_DEBUG_OUT, int, 0, "Show movement debugging output [1 = yes, 0 = no]");
+
   // 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)");

Modified: branches/movement/source/main/cOrganism.cc
===================================================================
--- branches/movement/source/main/cOrganism.cc	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cOrganism.cc	2008-08-08 14:37:04 UTC (rev 2749)
@@ -277,6 +277,71 @@
   }
 }
 
+void cOrganism::SetTargetCell()
+{
+  // @LMG
+  //const int threshold = 50; // Distance threshold for target cell, right now totally arbitrary 
+  int threshold = m_world->GetConfig().TARGET_DIST_THRESH.Get();
+  
+  // Check the world geometry, return if not a grid
+  int geometry = m_world->GetConfig().WORLD_GEOMETRY.Get();
+  if (geometry != nGeometry::GRID) { cout << "Not a grid, cannot make target cell" << endl; return; }
+  //SetOrgInterface(m_interface);
+
+  bool good = false; // Just a loop flag
+
+  // Get organism's cell ID, find the (x, y)
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+  const int world_y = m_world->GetConfig().WORLD_Y.Get();
+  int id = m_interface->GetCellID();
+  int x_coord = id % world_x;
+  int y_coord = id / world_x;
+  int size = world_x * world_y;
+  
+  while (good == false) {
+    // Pick a random target cell
+    target_cell_id = m_world->GetRandom().GetUInt(size);
+    // target_cell_id = 5050;
+	
+    // Make sure target different from current cell
+    if (id == target_cell_id) continue;
+  
+    // Get the target (x, y)
+    int target_x_coord =  target_cell_id % world_x;
+    int target_y_coord =  target_cell_id / world_x;
+
+    // Calculate distance; use distance squared to keep value integer
+    int temp_dist = (x_coord - target_x_coord) * (x_coord - target_x_coord) + 
+	                (y_coord - target_y_coord) * (y_coord - target_y_coord);
+  
+    if (temp_dist > size * 2) { cout << "Distance bigger than world: " << temp_dist << endl; continue; }
+	
+	//m_phenotype.SetInitialDistance(temp_dist);
+	//m_phenotype.SetLastDistance(temp_dist);
+    //m_phenotype.SetBestDistance(temp_dist);
+	  
+    if (temp_dist > threshold) {
+	  good = true;
+	  
+	  m_phenotype.SetInitialDistance(temp_dist);
+	  m_phenotype.SetLastDistance(temp_dist);
+	  m_phenotype.SetBestDistance(temp_dist);
+	  m_phenotype.SetTargetCellID(target_cell_id);
+	  m_phenotype.SetEndCellID(id);
+	  
+	  // Find and set the number of steps to the target
+	  int x_diff = abs(x_coord - target_x_coord);
+	  int y_diff = abs(y_coord - target_y_coord);
+	  //int bigger = (x_diff >= y_diff) ? x_diff : y_diff;	  
+	  m_phenotype.SetCurNumStepsTarget(x_diff, y_diff);
+	}
+  }	
+  // cout << "Cell ID " << id << ", org. ID " << m_id <<" Target cell: " << target_cell_id << endl;
+  
+  // cout << "Org. ID " << m_id <<" Target cell: " << target_cell_id << endl;
+
+}
+
 void cOrganism::NetGet(cAvidaContext& ctx, int& value, int& seq)
 {
   assert(m_net);

Modified: branches/movement/source/main/cOrganism.h
===================================================================
--- branches/movement/source/main/cOrganism.h	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cOrganism.h	2008-08-08 14:37:04 UTC (rev 2749)
@@ -127,6 +127,9 @@
   bool m_is_sleeping;      // Is this organisms sleeping?
   bool m_is_dead;          // Is this organism dead?
 
+  // Target (destination) cell info @LMG
+  int target_cell_id;		// Cell ID of target cell
+
   bool killed_event;
   
   class cNetSupport
@@ -262,6 +265,10 @@
   bool Divide_CheckViable();
   bool ActivateDivide(cAvidaContext& ctx);
   
+  // --------  Target (destination) Cell Methods  @LMG --------
+  void SetTargetCell();  // Sets the target cell ID for this organism
+  int GetTargetCellID() { return target_cell_id; }   // Returns the target cell ID
+    
   
   // --------  Networking Support  --------
   void NetGet(cAvidaContext& ctx, int& value, int& seq);

Modified: branches/movement/source/main/cPhenotype.cc
===================================================================
--- branches/movement/source/main/cPhenotype.cc	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cPhenotype.cc	2008-08-08 14:37:04 UTC (rev 2749)
@@ -60,6 +60,7 @@
   , last_reaction_add_reward(m_world->GetEnvironment().GetReactionLib().GetSize())  
   , last_inst_count(world->GetHardwareManager().GetInstSet().GetSize())
   , last_sense_count(m_world->GetStats().GetSenseSize())
+  , target_best_dist(100000)  // @LMG for movement tracking
 {
 }
 
@@ -117,7 +118,12 @@
   sensed_resources         = in_phen.sensed_resources;            
   cur_task_time            = in_phen.cur_task_time;   
   cur_child_germline_propensity = in_phen.cur_child_germline_propensity;
+  cur_best_dist_ratio	   = in_phen.cur_best_dist_ratio;  // @ LMG
+  cur_num_steps_target	   = in_phen.cur_num_steps_target;
+  cur_steps_away		   = in_phen.cur_steps_away;
+  cur_dist_ratio		   = in_phen.cur_dist_ratio;
 
+
   // Dynamically allocated m_task_states requires special handling
   tList<cTaskState*> hash_values;
   tList<void*>       hash_keys;
@@ -145,6 +151,10 @@
   last_sense_count         = in_phen.last_sense_count;   
   last_fitness             = in_phen.last_fitness;            
   last_child_germline_propensity = in_phen.last_child_germline_propensity;
+  last_best_dist_ratio	   = in_phen.last_best_dist_ratio; // @ LMG
+  last_num_steps_target	   = in_phen.last_num_steps_target;
+  last_steps_away		   = in_phen.last_steps_away;		  
+  last_dist_ratio	       = in_phen.last_dist_ratio;
 
   // 4. Records from this organisms life...
   num_divides              = in_phen.num_divides;      
@@ -154,8 +164,10 @@
   age                      = in_phen.age;               
   fault_desc               = in_phen.fault_desc;    
   neutral_metric           = in_phen.neutral_metric; 
-  life_fitness             = in_phen.life_fitness; 	
-                        
+  life_fitness             = in_phen.life_fitness;
+  target_best_dist		   = in_phen.target_best_dist; // @ LMG
+  target_last_dist		   = in_phen.target_last_dist;
+  target_init_dist		   = in_phen.target_init_dist; 	 	
   
   // 5. Status Flags...  (updated at each divide)
   to_die                  = in_phen.to_die;		 
@@ -307,6 +319,10 @@
   trial_time_used = 0;
   trial_cpu_cycles_used = 0;
   cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
+  cur_best_dist_ratio	   = 0.0;  // @ LMG 09/19/07
+  cur_num_steps_target	   = 0;
+  cur_steps_away		   = 0;
+  cur_dist_ratio		   = 0.0;
 
   // Copy last values from parent
   last_merit_base           = parent_phenotype.last_merit_base;
@@ -323,6 +339,10 @@
   last_sense_count          = parent_phenotype.last_sense_count;
   last_fitness              = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
   last_child_germline_propensity = parent_phenotype.last_child_germline_propensity;   // chance of child being a germline cell; @JEB
+  last_best_dist_ratio      = parent_phenotype.last_best_dist_ratio; // @ LMG for movement tracking
+  last_num_steps_target     = parent_phenotype.last_num_steps_target;
+  last_steps_away           = parent_phenotype.last_steps_away;
+  last_dist_ratio			= parent_phenotype.cur_dist_ratio;
 
   // Setup other miscellaneous values...
   num_divides     = 0;
@@ -447,6 +467,10 @@
   trial_time_used = 0;
   trial_cpu_cycles_used = 0;
   cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
+  cur_best_dist_ratio  = 0.0; // @ LMG
+  cur_num_steps_target = 0;
+  cur_steps_away	   = 0;
+  cur_dist_ratio	   = 0.0;
 
   // Copy last values from parent
   last_merit_base = genome_length;
@@ -462,7 +486,11 @@
   last_inst_count.SetAll(0);
   last_sense_count.SetAll(0);
   last_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
-
+  last_best_dist_ratio = 0.0;  // Added for movement tracking @ LMG
+  last_num_steps_target = 0;
+  last_steps_away = 100000;
+  last_dist_ratio = 0.0;
+  
   // Setup other miscellaneous values...
   num_divides     = 0;
   generation      = 0;
@@ -478,6 +506,8 @@
   num_quanta_thresh_gb_donations = 0;
   num_quanta_thresh_gb_donations_last = 0;
 
+  target_best_dist = 100000; // Added for movement tracking @LMG
+
   // Setup flags...
   is_injected   = true;
   is_donor_last = false;
@@ -556,6 +586,29 @@
   if (merit_default_bonus) {
     cur_bonus = merit_default_bonus;
   }
+  
+  // @LMG, for merit bonus only on divide for sense-target instructions
+  int movt_merit_on_divide = m_world->GetConfig().MOVT_MERIT_DIV.Get();
+  if(movt_merit_on_divide) {
+  double reward = m_world->GetConfig().REWARD_FACTOR.Get();
+  const int world_x = m_world->GetConfig().WORLD_X.Get();
+  int target_x_coord = target_id % world_x;
+  int target_y_coord = target_id / world_x;
+  int org_x_coord = end_cell_id % world_x;
+  int org_y_coord = end_cell_id / world_x;
+  if ( m_world->GetConfig().MOVT_DEBUG_OUT.Get() ) {
+    cout << " Org. cell id: " << end_cell_id << " Target id: " << target_id
+		 << " Target x, y: " << target_x_coord << ", " << target_y_coord
+		 << " Org. x, y: "  << org_x_coord << ", " << org_y_coord << endl;
+  }
+		 
+	int cur_dist = (org_x_coord - target_x_coord) * (org_x_coord - target_x_coord) + 
+				 (org_y_coord - target_y_coord) * (org_y_coord - target_y_coord);
+	double current_ratio = 1 - (double)cur_dist/(double)target_init_dist;
+	if (current_ratio > 0) { cur_bonus *= exp2(current_ratio * reward); }
+	cur_dist_ratio = current_ratio;
+  }
+  
   merit = cur_merit_base * cur_bonus;
   
   SetEnergy(energy_store + cur_energy_bonus);
@@ -585,6 +638,10 @@
   last_inst_count           = cur_inst_count;
   last_sense_count          = cur_sense_count;
   last_child_germline_propensity = cur_child_germline_propensity;
+  last_best_dist_ratio      = cur_best_dist_ratio; // @LMG for movement tracking
+  last_num_steps_target     = cur_num_steps_target;
+  last_steps_away           = cur_steps_away;
+  last_dist_ratio			= cur_dist_ratio;
 
   // Reset cur values.
   cur_bonus       = m_world->GetConfig().DEFAULT_BONUS.Get();
@@ -602,6 +659,10 @@
   cur_sense_count.SetAll(0);
   cur_task_time.SetAll(0.0);
   cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
+  cur_best_dist_ratio = 0.0;  // @LMG for movement tracking
+  cur_num_steps_target = 0; 
+  cur_steps_away = 0;
+  cur_dist_ratio = 0.0;
 
   // Setup other miscellaneous values...
   num_divides++;
@@ -1731,3 +1792,9 @@
   
   return false;
 }
+
+void cPhenotype::SetCurNumStepsTarget(int deltax, int deltay) // @ LMG
+{
+  assert(initialized == true);
+  cur_num_steps_target = (deltax >= deltay) ? deltax : deltay;
+}

Modified: branches/movement/source/main/cPhenotype.h
===================================================================
--- branches/movement/source/main/cPhenotype.h	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cPhenotype.h	2008-08-08 14:37:04 UTC (rev 2749)
@@ -128,7 +128,11 @@
   int trial_time_used;                        // like time_used, but reset every trial; @JEB
   int trial_cpu_cycles_used;                  // like cpu_cycles_used, but reset every trial; @JEB
   double last_child_germline_propensity;   // chance of child being a germline cell; @JEB
-
+  double cur_best_dist_ratio;  // Best proportion of distance to target traveled @ LMG
+  int cur_num_steps_target;    // Current distance from target in steps @LMG
+  int cur_steps_away;		   // Current number of steps away from target @LMG
+  double cur_dist_ratio;	   // Current proportion of distance to target traveled @LMG
+  
   // 3. These mark the status of "in progess" variables at the last divide.
   double last_merit_base;         // Either constant or based on genome length.
   double last_bonus;
@@ -145,6 +149,10 @@
   double last_fitness;            // Used to determine sterilization.
   int last_cpu_cycles_used;
   double cur_child_germline_propensity;   // chance of child being a germline cell; @JEB
+  double last_best_dist_ratio; // Best proportion of distance to target traveled as of last update @LMG
+  int last_num_steps_target;   // Last distance from target in steps @LMG
+  int last_steps_away;		   // Last steps away from target @LMG
+  double last_dist_ratio;	   // Last proportion of distance to target traveled
 
   // 4. Records from this organisms life...
   int num_divides;       // Total successful divides organism has produced.
@@ -156,6 +164,11 @@
   double neutral_metric; // Undergoes drift (gausian 0,1) per generation
   double life_fitness; 	 // Organism fitness during its lifetime, 
 		         // calculated based on merit just before the divide
+  int target_best_dist;  // Closest approach to target cell so far @LMG
+  int target_last_dist;  // Distance to target at last sense @LMG
+  int target_init_dist;  // Initial distance to target cell @LMG
+  int target_id;	     // Cell ID of target cell @LMG
+  int end_cell_id;		 // Cell ID of location at divide @LMG
 
   // 5. Status Flags...  (updated at each divide)
   bool to_die;		 // Has organism has triggered something fatal?
@@ -386,6 +399,18 @@
   bool ChildFertile() const { assert(initialized == true); return child_fertile;}
   int GetChildCopiedSize() const { assert(initialized == true); return child_copied_size; }
 
+  // @LMG, target distance accessors
+  int GetInitDistance() { assert(initialized == true); return target_init_dist; }
+  int GetLastDistance() { assert(initialized == true); return target_last_dist; }
+  int GetBestDistance() { assert(initialized == true); return target_best_dist; }
+  double GetCurBestDistanceRatio() { assert(initialized == true); return cur_best_dist_ratio; }
+  double GetLastBestDistanceRatio() { assert(initialized == true); return last_best_dist_ratio; }
+  int GetCurNumStepsTarget() { assert(initialized == true); return cur_num_steps_target; }
+  int GetLastNumStepsTarget() { assert(initialized == true); return last_num_steps_target; } 
+  int GetCurStepsAway() { assert(initialized == true); return cur_steps_away; }
+  int GetLastStepsAway() { assert(initialized == true); return last_steps_away; }
+  double GetCurDistanceRatio() { assert(initialized == true); return cur_dist_ratio; }
+  double GetLastDistanceRatio() { assert(initialized == true); return last_dist_ratio; }
 
   ////////////////////  Accessors -- Modifying  ///////////////////
   void SetMerit(const cMerit& in_merit) { merit = in_merit; }
@@ -468,6 +493,21 @@
   void EnergyTestament(const double value); //! external energy given to organism
   double ExtractParentEnergy();
   
+  // @ LMG, modifiers for distances to target cell
+  void SetBestDistance(int in_target_dist) { assert(initialized == true); target_best_dist = in_target_dist; }
+  void SetLastDistance(int in_target_dist) { assert(initialized == true); target_last_dist = in_target_dist; }
+  void SetInitialDistance(int in_target_dist) { assert(initialized == true); target_init_dist = in_target_dist; }
+  void SetCurBestDistanceRatio(double in_cur_best) { assert(initialized == true); cur_best_dist_ratio = in_cur_best; }
+  void SetLastBestDistanceRatio(double in_last_best) { assert(initialized == true); last_best_dist_ratio = in_last_best; }
+  void SetCurNumStepsTarget(int deltax, int deltay);
+  void SetLastNumStepsTarget(int num_steps) { assert(initialized == true); last_num_steps_target = num_steps; }
+  void SetLastStepsAway(int num_steps) { assert(initialized == true); last_steps_away = num_steps; }
+  void SetCurStepsAway(int num_steps) { assert(initialized == true); cur_steps_away = num_steps; }
+  void SetCurDistanceRatio(double in_cur_dist) { assert(initialized == true); cur_dist_ratio = in_cur_dist; }
+  void SetLastDistanceRatio(double in_last_dist) { assert(initialized == true); last_dist_ratio = in_last_dist; }
+  void SetTargetCellID(int in_target_id) { assert(initialized == true); target_id = in_target_id; }
+  void SetEndCellID(int in_end_id) { assert(initialized == true); end_cell_id = in_end_id; }
+
   bool operator<(const cPhenotype& rhs) const;
   bool operator>(const cPhenotype& rhs) const;
   bool operator==(const cPhenotype& rhs) const;

Modified: branches/movement/source/main/cPopulation.cc
===================================================================
--- branches/movement/source/main/cPopulation.cc	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cPopulation.cc	2008-08-08 14:37:04 UTC (rev 2749)
@@ -358,6 +358,10 @@
   
   // If we're not about to kill the parent, do some extra work on it.
   if (parent_alive == true) {
+  
+    // Reset parent target cell @LMG 
+	parent_organism.SetTargetCell();
+
     // Reset inputs and re-calculate merit if required
     if (m_world->GetConfig().RESET_INPUTS_ON_DIVIDE.Get() > 0){
       environment.SetupInputs(ctx, parent_cell.m_inputs);
@@ -557,6 +561,9 @@
     } 
     in_organism->GetPhenotype().SetCurBonusInstCount(num_rewarded_instructions);
   }
+  
+  // @LMG for moving to target 
+  in_organism->SetTargetCell();
 }
 
 // @WRE 2007/07/05 Helper function to take care of side effects of Avidian 
@@ -836,37 +843,64 @@
 
 void cPopulation::SwapCells(cPopulationCell & cell1, cPopulationCell & cell2)
 {
-  // Sanity checks: Don't process if the cells are the same and 
-  // don't bother trying to move when given a cell that isn't there
-  if ((&cell1 == NULL) || (&cell2 == NULL)) return;
-  if (cell1.GetID() == cell2.GetID()) return;
-  // Clear current contents of cells
-  cOrganism * org1 = cell1.RemoveOrganism();
-  cOrganism * org2 = cell2.RemoveOrganism();
-  if (org2 != NULL) {
-    cell1.InsertOrganism(org2);
-    AdjustSchedule(cell1, org2->GetPhenotype().GetMerit());
-  } else {
-    AdjustSchedule(cell1, cMerit(0));
-  }
-  if (org1 != NULL) {
-    cell2.InsertOrganism(org1);
-    // Increment visit count
-    cell2.IncVisits();
-    // Adjust for movement factor if needed
-    if (1.0 != m_world->GetConfig().BIOMIMETIC_MOVEMENT_FACTOR.Get()) {
-      double afterfit = org1->GetPhenotype().GetCurBonus() * m_world->GetConfig().BIOMIMETIC_MOVEMENT_FACTOR.Get();
-      org1->GetPhenotype().SetCurBonus(afterfit); //Update fitness
+    // Sanity checks: Don't process if the cells are the same and 
+    // don't bother trying to move when given a cell that isn't there
+    //cout << "SwapCells: testing if cell1 and cell2 are non-null" << endl;
+    //if (!(NULL != cell1) || !(NULL != cell2)) return;
+    if ((&cell1 == NULL) || (&cell2 == NULL)) return;
+    //cout << "SwapCells: testing if cell1 and cell2 are different" << endl;  
+    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;
+    int x1 = 0;
+    int y1 = 0;
+    int cid = 0;
+
+    //cout << "SwapCells: organism 2 is non-null, fix up source cell" << endl;
+    if (org2 != NULL) {
+	cell1.InsertOrganism(org2);
+	schedule->Adjust(cell1.GetID(), org2->GetPhenotype().GetMerit());
+    } else {
+	schedule->Adjust(cell1.GetID(), cMerit(0));
     }
-    // Trigger evaluation for task completion
-    if (0 < m_world->GetConfig().BIOMIMETIC_EVAL_ON_MOVEMENT.Get()) {
-      cAvidaContext& ctx = m_world->GetDefaultContext();
-      org1->DoOutput(ctx,0);
+    //cout << "SwapCells: organism 1 is non-null, fix up dest cell" << endl;
+    if (org1 != NULL) {
+	cell2.InsertOrganism(org1);
+	schedule->Adjust(cell2.GetID(), org1->GetPhenotype().GetMerit());
+	// @WRE additions for movement logging
+	cell1.GetPosition(x1,y1);
+	cell2.GetPosition(x,y);
+	cid = org1->GetID();
+
+	// @LMG, config option for movement tracking, using movement logging above
+	// Output some information
+	if( m_world->GetConfig().MOVT_TRACK_ON.Get() ) {
+		const int world_x = m_world->GetConfig().WORLD_X.Get();
+		int target_cell_id = org1->GetTargetCellID();
+		int target_x = target_cell_id % world_x;
+		int target_y = target_cell_id / world_x;
+		
+	    ofstream movelog;
+	    movelog.open("data/movelog.txt",ios::app);
+	    // By columns: org ID, from cell xy, to cell xy
+	    movelog << cid << " " <<
+		x1 << " " <<
+		y1 << " " <<
+		x << " " <<
+		y << " " <<
+		target_x << " " <<
+		target_y << " " << endl;
+	    movelog.close();
+	}
+    } else {
+	schedule->Adjust(cell2.GetID(), cMerit(0));
     }
-    AdjustSchedule(cell2, org1->GetPhenotype().GetMerit());
-  } else {
-    AdjustSchedule(cell2, cMerit(0));
-  }
+    //cout << "SwapCells: Done." << endl;
 }
 
 // CompeteDemes  probabilistically copies demes into the next generation
@@ -3532,7 +3566,11 @@
   stats.SumCopySize().Clear();
   stats.SumExeSize().Clear();
   stats.SumMemSize().Clear();
-  
+  stats.SumBestDistance().Clear();   // @LMG
+  stats.SumNumStepsTarget().Clear();
+  stats.SumStepsAway().Clear();
+  stats.SumEndDistance().Clear();
+
   stats.ZeroTasks();
   stats.ZeroRewards();
   
@@ -3549,6 +3587,13 @@
   int num_threads = 0;
   int num_modified = 0;
   
+  stats.SetNumHalfwayToTarget(0);	// @LMG counts for movement stats
+  stats.SetNumStepsLessthan10(0);
+  stats.SetNumStepsLessthan5(0);
+  stats.SetNumLessthanHalfway(0);
+  stats.SetNumLessthan10Percent(0);
+  stats.SetNumNoMovement(0);
+
   // Maximums...
   cMerit max_merit(0);
   double max_fitness = 0;
@@ -3593,6 +3638,19 @@
     stats.SumExeSize().Add(phenotype.GetExecutedSize());
     stats.SetGenoMapElement(i, organism->GetGenotype()->GetID());
     
+	stats.SumBestDistance().Add(organism->GetPhenotype().GetLastBestDistanceRatio()); // @LMG
+	stats.SumNumStepsTarget().Add(organism->GetPhenotype().GetLastNumStepsTarget());
+	stats.SumStepsAway().Add(organism->GetPhenotype().GetLastStepsAway());
+	stats.SumEndDistance().Add(organism->GetPhenotype().GetLastDistanceRatio()); // @LMG
+	
+	if (organism->GetPhenotype().GetLastBestDistanceRatio() >= 0.5) stats.IncNumHalfwayToTarget(); // @LMG
+	else stats.IncNumLessthanHalfway();
+	
+	if (organism->GetPhenotype().GetLastBestDistanceRatio() < 0.1 ) stats.IncNumLessthan10Percent();
+	if (organism->GetPhenotype().GetLastBestDistanceRatio() == 0.0 ) stats.IncNumNoMovement();
+	if (organism->GetPhenotype().GetLastNumStepsTarget() <= 10) stats.IncNumStepsLessthan10();
+	if (organism->GetPhenotype().GetLastNumStepsTarget() <= 5) stats.IncNumStepsLessthan5();
+
 #if INSTRUCTION_COUNT
     for (int j = 0; j < m_world->GetNumInstructions(); j++) {
       stats.SumExeInst()[j].Add(organism->GetPhenotype().GetLastInstCount()[j]);

Modified: branches/movement/source/main/cPopulationCell.cc
===================================================================
--- branches/movement/source/main/cPopulationCell.cc	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cPopulationCell.cc	2008-08-08 14:37:04 UTC (rev 2749)
@@ -111,7 +111,9 @@
   while (m_connections.GetFirst() != &new_facing) {
     m_connections.CircNext();
 #ifdef DEBUG
-    assert(++scan_count < m_connections.GetSize());
+	// assert(++scan_count < m_connections.GetSize());
+	// Changed by LMG 3/25/08
+	 assert(++scan_count <= m_connections.GetSize());
 #endif
   }
 }

Modified: branches/movement/source/main/cStats.cc
===================================================================
--- branches/movement/source/main/cStats.cc	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cStats.cc	2008-08-08 14:37:04 UTC (rev 2749)
@@ -507,6 +507,16 @@
   num_resamplings = 0;
   num_failedResamplings = 0;
 
+  //sum_best_distance.Clear();	// @LMG, movement stats
+  sum_num_steps_target.Clear();
+  sum_steps_away.Clear();
+  num_halfway_to_target = 0;
+  num_steps_lessthan_10 = 0;
+  num_steps_lessthan_5 = 0;
+  num_lessthan_halfway = 0;
+  num_lessthan_10_percent = 0;
+  num_no_movement = 0;
+
   m_spec_total = 0;
   m_spec_num = 0;
   m_spec_waste = 0;
@@ -1203,6 +1213,26 @@
   df.Endl();
 }
 
+void cStats::PrintMovementData(const cString& filename) // @ LMG
+ {
+  cDataFile& df = m_world->GetDataFile(filename);
+   
+  df.WriteComment("Avida movement information\n");
+  df.WriteTimeStamp();
+  df.Write(m_update, "Update");
+  df.Write(sum_end_distance.Average(), "Average distance to target at divide");
+  df.Write(sum_best_distance.Average(), "Average best distance to target");
+  df.Write(sum_num_steps_target.Average(), "Average num. of steps to target");
+  //df.Write(sum_steps_away.Average(), "Average num. of steps moved away from target");
+  df.Write(num_no_movement, "Num. organisms at 0% distance to target");
+  df.Write(num_lessthan_10_percent, "Num. organisms < 10% distance to target");
+  df.Write(num_halfway_to_target, "Num. organisms >= 50% distance to target");
+  df.Write(num_steps_lessthan_10, "Num. organisms <= 10 steps from target");
+  df.Write(num_steps_lessthan_5, "Num. organisms <= 5 steps from target");
+  df.Endl();
+ }
+
+
 void cStats::PrintCompetitionData(const cString& filename){
   cDataFile& df = m_world->GetDataFile(filename);
 

Modified: branches/movement/source/main/cStats.h
===================================================================
--- branches/movement/source/main/cStats.h	2008-08-08 13:56:25 UTC (rev 2748)
+++ branches/movement/source/main/cStats.h	2008-08-08 14:37:04 UTC (rev 2749)
@@ -268,6 +268,18 @@
   tArray<int> sense_last_exe_count;
   tArray<cString> sense_names;
 
+  // Stats for movement @LMG
+  cDoubleSum sum_best_distance;
+  cDoubleSum sum_num_steps_target;
+  cDoubleSum sum_steps_away;
+  cDoubleSum sum_end_distance;
+  int num_halfway_to_target;
+  int num_steps_lessthan_10;
+  int num_steps_lessthan_5;
+  int num_lessthan_halfway;
+  int num_lessthan_10_percent;
+  int num_no_movement;
+
   // Stats for competitions
   tArray<double> avg_trial_fitnesses;
   double avg_competition_fitness;
@@ -444,6 +456,11 @@
   cDoubleSum& SumExeSize()       { return sum_exe_size; }
   cDoubleSum& SumMemSize()       { return sum_mem_size; }
 
+  cDoubleSum& SumBestDistance()  { return sum_best_distance; } // @LMG
+  cDoubleSum& SumNumStepsTarget()  { return sum_num_steps_target; } // @LMG
+  cDoubleSum& SumStepsAway()     { return sum_steps_away; } // @LMG
+  cDoubleSum& SumEndDistance()	 { return sum_end_distance;} //@LMG
+
   //deme
   cIntSum& SumDemeAge()          { return sum_deme_age; }
   cIntSum& SumDemeBirthCount()   { return sum_deme_birth_count; }
@@ -568,7 +585,21 @@
   void AddLastSense(int res_comb_index) { sense_last_count[res_comb_index]++; }
   void IncLastSenseExeCount(int res_comb_index, int count) 
     { sense_last_exe_count[res_comb_index]+= count; }
-    
+
+  void SetNumHalfwayToTarget(int in_val) { num_halfway_to_target = in_val; }  //@LMG
+  void SetNumStepsLessthan10(int in_val) { num_steps_lessthan_10 = in_val; }
+  void SetNumStepsLessthan5(int in_val) { num_steps_lessthan_5 = in_val; }
+  void SetNumLessthanHalfway(int in_val) { num_lessthan_halfway = in_val; }
+  void SetNumLessthan10Percent(int in_val) { num_lessthan_10_percent = in_val; }
+  void SetNumNoMovement(int in_val) { num_no_movement = in_val; }
+  void IncNumHalfwayToTarget() { num_halfway_to_target++; }
+  void IncNumStepsLessthan10() { num_steps_lessthan_10++; }
+  void IncNumStepsLessthan5() { num_steps_lessthan_5++; }
+  void IncNumLessthanHalfway() { num_lessthan_halfway++; }
+  void IncNumLessthan10Percent() { num_lessthan_10_percent++;}
+  void IncNumNoMovement() { num_no_movement++; }
+
+
   void SetReactions(const tArray<double> &_in) { reaction_count = _in; }
   void AddLastReactionAddReward(int _id, double _reward) { reaction_add_reward[_id] += _reward; }
   void ZeroRewards();
@@ -736,6 +767,7 @@
   void PrintMarketData(const cString& filename);
   void PrintSenseData(const cString& filename);
   void PrintSenseExeData(const cString& filename);
+  void PrintMovementData(const cString& filename); // @ LMG
   void PrintSleepData(const cString& filename);
   void PrintCompetitionData(const cString& filename);
   // @WRE: Added event for printing visit counts




More information about the Avida-cvs mailing list