[Avida-SVN] r1666 - in branches/dkdev/source: cpu main
dknoester at myxo.css.msu.edu
dknoester at myxo.css.msu.edu
Mon Jun 11 10:46:27 PDT 2007
Author: dknoester
Date: 2007-06-11 13:46:27 -0400 (Mon, 11 Jun 2007)
New Revision: 1666
Modified:
branches/dkdev/source/cpu/cHardwareCPU.cc
branches/dkdev/source/cpu/cHardwareCPU.h
branches/dkdev/source/main/cDeme.cc
Log:
New instructions for locating, determining altitude, and rotating to face the two cells selected per deme.
Modified: branches/dkdev/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/dkdev/source/cpu/cHardwareCPU.cc 2007-06-11 17:18:31 UTC (rev 1665)
+++ branches/dkdev/source/cpu/cHardwareCPU.cc 2007-06-11 17:46:27 UTC (rev 1666)
@@ -367,7 +367,10 @@
// Construction instructions
cInstEntryCPU("cr-link", &cHardwareCPU::Inst_CreateLink),
cInstEntryCPU("rd-links", &cHardwareCPU::Inst_ReadLinks),
- cInstEntryCPU("get-lpos", &cHardwareCPU::Inst_GetLocalPosition)
+ cInstEntryCPU("get-lpos", &cHardwareCPU::Inst_GetLocalPosition),
+ cInstEntryCPU("get-cpos", &cHardwareCPU::Inst_GetCellPosition),
+ cInstEntryCPU("get-altitude", &cHardwareCPU::Inst_GetAltitude),
+ cInstEntryCPU("rotate-cell", &cHardwareCPU::Inst_RotateCell)
};
const int n_size = sizeof(s_n_array)/sizeof(cNOPEntryCPU);
@@ -3627,3 +3630,97 @@
GetRegister(y) = pos.second;
return true;
}
+
+
+/*! Place the (x,y) coordinates of one of the two cells in ?BX? and !?BX?. The
+cell is specified by the numeric value of a label, mod 2.
+*/
+bool cHardwareCPU::Inst_GetCellPosition(cAvidaContext& ctx) {
+ if(organism->GetCellID()==-1) return false;
+ cPopulationCell& cell = m_world->GetPopulation().GetCell(organism->GetCellID());
+ cDeme& deme = m_world->GetPopulation().GetDeme(cell.GetDemeID());
+ std::pair<int,int> cells = deme.GetCellsToLink();
+ std::pair<int,int> pos(0,0);
+ const int x = FindModifiedRegister(REG_BX);
+ const int y = FindNextRegister(x);
+
+ ReadLabel();
+ int label = GetLabel().AsInt(NUM_NOPS);
+
+ if(label % 2) {
+ // Return position of second cell.
+ pos = deme.GetCellPosition(cells.second);
+ } else {
+ // Return position of first cell.
+ pos = deme.GetCellPosition(cells.first);
+ }
+
+ GetRegister(x) = pos.first;
+ GetRegister(y) = pos.second;
+ return true;
+}
+
+
+/*! Calculates the euclidean distance between two points. */
+double point_distance(const std::pair<int,int>& p1, const std::pair<int,int>& p2) {
+ return sqrt(pow(p1.first-p2.first,2) + pow(p1.second-p2.second,2));
+}
+
+
+/*! Calculates the euclidean distance of a point to a line (where the line is described by two points). */
+double altitude(const std::pair<int,int>& p, const std::pair<int,int>& b1, const std::pair<int,int>& b2) {
+ return ((b1.second-b2.second)*p.first + (b2.first-b1.first)*p.second + b1.first*b2.second - b2.first*b1.second) / point_distance(b1,b2);
+}
+
+/*! Places the altitude of the caller with respect to the two cells into ?BX?.*/
+bool cHardwareCPU::Inst_GetAltitude(cAvidaContext& ctx) {
+ if(organism->GetCellID()==-1) return false;
+ cPopulationCell& cell = m_world->GetPopulation().GetCell(organism->GetCellID());
+ cDeme& deme = m_world->GetPopulation().GetDeme(cell.GetDemeID());
+
+ std::pair<int,int> one = deme.GetCellPosition(deme.GetCellsToLink().first);
+ std::pair<int,int> two = deme.GetCellPosition(deme.GetCellsToLink().second);
+ std::pair<int,int> self = deme.GetCellPosition(cell.GetID());
+
+ GetRegister(FindModifiedRegister(REG_BX)) = (int)altitude(self, one, two);
+ return true;
+}
+
+
+/*! */
+bool cHardwareCPU::Inst_RotateCell(cAvidaContext& ctx) {
+ if(organism->GetCellID()==-1) return false;
+ cPopulationCell& cell = m_world->GetPopulation().GetCell(organism->GetCellID());
+ cDeme& deme = m_world->GetPopulation().GetDeme(cell.GetDemeID());
+ std::pair<int,int> cells = deme.GetCellsToLink();
+ std::pair<int,int> pos(0,0);
+ std::pair<int,int> self = deme.GetCellPosition(cell.GetID());
+
+ ReadLabel();
+ int label = GetLabel().AsInt(NUM_NOPS);
+
+ if(label % 2) {
+ // Return position of second cell.
+ pos = deme.GetCellPosition(cells.second);
+ } else {
+ // Return position of first cell.
+ pos = deme.GetCellPosition(cells.first);
+ }
+
+ if(pos == self) return true;
+
+ // For each cell that we face, calculate the distance to pos.
+ double d=point_distance(self, pos);
+ cPopulationCell* target=0;
+ for(int i=0; i<cell.ConnectionList().GetSize(); ++i,cell.ConnectionList().CircNext()) {
+ cPopulationCell* that = cell.ConnectionList().GetFirst();
+ double di=point_distance(deme.GetCellPosition(that->GetID()), pos);
+ if(di < d) {
+ d = di;
+ target = that;
+ }
+ }
+
+ cell.ConnectionList().FindPtr(target);
+ return true;
+}
Modified: branches/dkdev/source/cpu/cHardwareCPU.h
===================================================================
--- branches/dkdev/source/cpu/cHardwareCPU.h 2007-06-11 17:18:31 UTC (rev 1665)
+++ branches/dkdev/source/cpu/cHardwareCPU.h 2007-06-11 17:46:27 UTC (rev 1666)
@@ -485,6 +485,9 @@
bool Inst_CreateLink(cAvidaContext& ctx);
bool Inst_ReadLinks(cAvidaContext& ctx);
bool Inst_GetLocalPosition(cAvidaContext& ctx);
+ bool Inst_GetCellPosition(cAvidaContext& ctx); //!< Returns the (x,y) position of one of two cells.
+ bool Inst_GetAltitude(cAvidaContext& ctx); //!< Returns the distance of the caller from the line connecting two cells.
+ bool Inst_RotateCell(cAvidaContext& ctx); //!< Rotates the caller to face (as close as is possible) in the direction of one of twocells.
};
Modified: branches/dkdev/source/main/cDeme.cc
===================================================================
--- branches/dkdev/source/main/cDeme.cc 2007-06-11 17:18:31 UTC (rev 1665)
+++ branches/dkdev/source/main/cDeme.cc 2007-06-11 17:46:27 UTC (rev 1666)
@@ -28,10 +28,10 @@
{
_world = world;
cell_ids = in_cells;
- _cellsToLink = std::make_pair(_world->GetRandom().GetInt(cell_ids.GetSize()),
- _world->GetRandom().GetInt(cell_ids.GetSize()));
+ _cellsToLink = std::make_pair(cell_ids[_world->GetRandom().GetInt(cell_ids.GetSize())],
+ cell_ids[_world->GetRandom().GetInt(cell_ids.GetSize())]);
while(_cellsToLink.second == _cellsToLink.first) {
- _cellsToLink.second = _world->GetRandom().GetInt(cell_ids.GetSize());
+ _cellsToLink.second = cell_ids[_world->GetRandom().GetInt(cell_ids.GetSize())];
}
birth_count = 0;
org_count = 0;
More information about the Avida-cvs
mailing list