[Avida-SVN] r2887 - in development/source: cpu main
connel42 at myxo.css.msu.edu
connel42 at myxo.css.msu.edu
Mon Oct 27 10:07:01 PDT 2008
Author: connel42
Date: 2008-10-27 13:07:01 -0400 (Mon, 27 Oct 2008)
New Revision: 2887
Modified:
development/source/cpu/cCPUTestInfo.h
development/source/cpu/cHardwareCPU.cc
development/source/cpu/cHardwareCPU.h
development/source/cpu/cTestCPUInterface.h
development/source/main/cAvidaConfig.h
development/source/main/cDeme.cc
development/source/main/cDeme.h
development/source/main/cOrgInterface.h
development/source/main/cOrganism.cc
development/source/main/cOrganism.h
development/source/main/cPhenotype.cc
development/source/main/cPhenotype.h
development/source/main/cPopulationInterface.cc
development/source/main/cPopulationInterface.h
Log:
Added code for energy level detection, energy sharing, and broadcast messaging
Modified: development/source/cpu/cCPUTestInfo.h
===================================================================
--- development/source/cpu/cCPUTestInfo.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/cpu/cCPUTestInfo.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -93,8 +93,8 @@
// Input Setup
void TraceTaskOrder(bool _trace=true) { trace_task_order = _trace; }
void UseRandomInputs(bool _rand=true) { use_random_inputs = _rand; use_manual_inputs = false; }
- void UseManualInputs(tArray<int> inputs) {use_manual_inputs = true; use_random_inputs = false; manual_inputs = inputs;}
- void ResetInputMode() {use_manual_inputs = false; use_random_inputs = false;}
+ void UseManualInputs(tArray<int> inputs) {use_manual_inputs = true; use_random_inputs = false; manual_inputs = inputs;}
+ void ResetInputMode() {use_manual_inputs = false; use_random_inputs = false;}
void SetTraceExecution(cHardwareTracer* tracer = NULL) { m_tracer = tracer; }
void SetInstSet(cInstSet* inst_set = NULL) { m_inst_set = inst_set; }
void SetResourceOptions(int res_method = RES_INITIAL, std::vector<std::pair<int, std::vector<double> > > * res = NULL, int update = 0, int cpu_cycle_offset = 0)
Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/cpu/cHardwareCPU.cc 2008-10-27 17:07:01 UTC (rev 2887)
@@ -219,6 +219,8 @@
tInstLibEntry<tMethod>("donate-quantagb", &cHardwareCPU::Inst_DonateQuantaThreshGreenBeard, nInstFlag::STALL),
tInstLibEntry<tMethod>("donate-NUL", &cHardwareCPU::Inst_DonateNULL, nInstFlag::STALL),
tInstLibEntry<tMethod>("donate-facing", &cHardwareCPU::Inst_DonateFacing, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("receive-donated-energy", &cHardwareCPU::Inst_ReceiveDonatedEnergy, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("donate-energy", &cHardwareCPU::Inst_DonateEnergy, nInstFlag::STALL),
tInstLibEntry<tMethod>("IObuf-add1", &cHardwareCPU::Inst_IOBufAdd1, nInstFlag::STALL),
tInstLibEntry<tMethod>("IObuf-add0", &cHardwareCPU::Inst_IOBufAdd0, nInstFlag::STALL),
@@ -232,7 +234,6 @@
tInstLibEntry<tMethod>("rotate-to-occupied-cell", &cHardwareCPU::Inst_RotateOccupiedCell, nInstFlag::STALL),
tInstLibEntry<tMethod>("rotate-to-event-cell", &cHardwareCPU::Inst_RotateEventCell, nInstFlag::STALL),
-
tInstLibEntry<tMethod>("set-cmut", &cHardwareCPU::Inst_SetCopyMut),
tInstLibEntry<tMethod>("mod-cmut", &cHardwareCPU::Inst_ModCopyMut),
tInstLibEntry<tMethod>("get-cell-xy", &cHardwareCPU::Inst_GetCellPosition),
@@ -366,7 +367,15 @@
tInstLibEntry<tMethod>("relinquishEnergyToNeighborOrganisms", &cHardwareCPU::Inst_RelinquishEnergyToNeighborOrganisms, nInstFlag::STALL),
tInstLibEntry<tMethod>("relinquishEnergyToOrganismsInDeme", &cHardwareCPU::Inst_RelinquishEnergyToOrganismsInDeme, nInstFlag::STALL),
-
+ // Energy level detection
+ tInstLibEntry<tMethod>("if-energy-low", &cHardwareCPU::Inst_IfEnergyLow, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("if-energy-not-low", &cHardwareCPU::Inst_IfEnergyNotLow, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("if-energy-high", &cHardwareCPU::Inst_IfEnergyHigh, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("if-energy-not-high", &cHardwareCPU::Inst_IfEnergyNotHigh, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("if-energy-med", &cHardwareCPU::Inst_IfEnergyMed, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("if-energy-in-buffer", &cHardwareCPU::Inst_IfEnergyInBuffer, nInstFlag::STALL),
+ tInstLibEntry<tMethod>("if-energy-not-in-buffer", &cHardwareCPU::Inst_IfEnergyNotInBuffer, nInstFlag::STALL),
+
// Sleep and time
tInstLibEntry<tMethod>("sleep", &cHardwareCPU::Inst_Sleep, nInstFlag::STALL),
tInstLibEntry<tMethod>("sleep1", &cHardwareCPU::Inst_Sleep, nInstFlag::STALL),
@@ -3327,11 +3336,14 @@
// Plug the current merit back into this organism and notify the scheduler.
organism->UpdateMerit(cur_merit);
+ organism->GetPhenotype().SetIsEnergyDonor();
// Update the merit of the organism being donated to...
double other_merit = to_org->GetPhenotype().GetMerit().GetDouble();
other_merit += merit_received;
to_org->UpdateMerit(other_merit);
+ to_org->GetPhenotype().SetIsEnergyReceiver();
+
}
void cHardwareCPU::DoEnergyDonate(cOrganism* to_org)
@@ -3345,15 +3357,59 @@
//update energy store and merit of donor
organism->GetPhenotype().ReduceEnergy(energy_given);
+ organism->GetPhenotype().IncreaseEnergyDonated(energy_given);
double senderMerit = cMerit::EnergyToMerit(organism->GetPhenotype().GetStoredEnergy() * organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
organism->UpdateMerit(senderMerit);
+ organism->GetPhenotype().SetIsEnergyDonor();
// update energy store and merit of donee
to_org->GetPhenotype().ReduceEnergy(-1.0*energy_given);
+ to_org->GetPhenotype().IncreaseEnergyReceived(energy_given);
double receiverMerit = cMerit::EnergyToMerit(to_org->GetPhenotype().GetStoredEnergy() * to_org->GetPhenotype().GetEnergyUsageRatio(), m_world);
to_org->UpdateMerit(receiverMerit);
+ to_org->GetPhenotype().SetIsEnergyReceiver();
}
+
+// The difference between this version and the previous is that this one allows energy to be placed
+// into the recipient's incoming energy buffer and not be applied immediately. Also, some of the
+// energy may be lost in transfer
+void cHardwareCPU::DoEnergyDonatePercent(cOrganism* to_org, const double frac_energy_given)
+{
+ double losspct = m_world->GetConfig().ENERGY_SHARING_LOSS.Get();
+
+ assert(to_org != NULL);
+ assert(frac_energy_given >= 0);
+ assert(frac_energy_given <= 1);
+ assert(losspct >= 0);
+ assert(losspct <= 1);
+
+ double cur_energy = organism->GetPhenotype().GetStoredEnergy();
+ double energy_given = cur_energy * frac_energy_given;
+
+ //update energy store and merit of donor
+ organism->GetPhenotype().ReduceEnergy(energy_given);
+ organism->GetPhenotype().IncreaseEnergyDonated(energy_given);
+ double senderMerit = cMerit::EnergyToMerit(organism->GetPhenotype().GetStoredEnergy() * organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+ organism->UpdateMerit(senderMerit);
+
+ //apply loss in transfer
+ energy_given *= (1 - losspct);
+
+ //place energy into receiver's incoming energy buffer
+ to_org->GetPhenotype().ReceiveDonatedEnergy(energy_given);
+ to_org->GetPhenotype().IncreaseEnergyReceived(energy_given);
+
+ //if we are using the push energy method, pass the new energy into the receiver's energy store and recalculate merit
+ if(m_world->GetConfig().ENERGY_SHARING_METHOD.Get() == 1) {
+ to_org->GetPhenotype().ApplyDonatedEnergy();
+ double receiverMerit = cMerit::EnergyToMerit(to_org->GetPhenotype().GetStoredEnergy() * to_org->GetPhenotype().GetEnergyUsageRatio(), m_world);
+ to_org->UpdateMerit(receiverMerit);
+ }
+
+} //End DoEnergyDonatePercent()
+
+
bool cHardwareCPU::Inst_DonateFacing(cAvidaContext& ctx) {
if (organism->GetPhenotype().GetCurNumDonates() > m_world->GetConfig().MAX_DONATES.Get()) {
return false;
@@ -3854,6 +3910,72 @@
}
+//Move energy from an organism's received energy buffer into their energy store, recalculate merit
+bool cHardwareCPU::Inst_ReceiveDonatedEnergy(cAvidaContext& ctx)
+{
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ if(organism->GetPhenotype().GetEnergyInBufferAmount() > 0) {
+ organism->GetPhenotype().ApplyDonatedEnergy();
+ organism->GetPhenotype().SetHasUsedDonatedEnergy();
+ double receiverMerit = cMerit::EnergyToMerit(organism->GetPhenotype().GetStoredEnergy() * organism->GetPhenotype().GetEnergyUsageRatio(), m_world);
+ organism->UpdateMerit(receiverMerit);
+ }
+
+ return true;
+
+} //End Inst_ReceiveDonatedEnergy()
+
+
+//Donate a fraction of organism's energy to the organism that last requested it.
+bool cHardwareCPU::Inst_DonateEnergy(cAvidaContext& ctx)
+{
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ const cOrgMessage* msg = organism->RetrieveMessage();
+ if(msg == 0) {
+ return false;
+ }
+
+ cOrganism* receiver = msg->GetSender();
+
+ // If the requestor no longer exists, should the donor still lose energy???
+ if( (receiver == NULL) && (receiver->IsDead()) ) {
+ return false;
+ }
+
+ //Note: could get fancier about fraction of energy to send
+ DoEnergyDonatePercent(receiver, m_world->GetConfig().MERIT_GIVEN.Get());
+ organism->GetPhenotype().IncDonates();
+
+ return true;
+
+} //End Inst_DonateEnergy()
+
+
+//Broadcast a request for energy
+bool cHardwareCPU::Inst_RequestEnergy(cAvidaContext& ctx)
+{
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ //TODO: BDC: somehow use nop modifiers to pick a multiplier for the amount of energy to request
+
+ cOrgMessage msg = cOrgMessage(organism);
+ // Could set the data field of the message to be the multiplier
+
+ organism->BroadcastMessage(ctx, msg);
+
+ return true;
+
+} //End Inst_RequestEnergy()
+
+
bool cHardwareCPU::Inst_SearchF(cAvidaContext& ctx)
{
ReadLabel();
@@ -4620,6 +4742,120 @@
return true;
}
+
+/* Execute the next instruction if the organism's energy level is low */
+bool cHardwareCPU::Inst_IfEnergyLow(cAvidaContext& ctx) {
+
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ // Note: these instructions should probably also make sure the returned energy level is not -1.
+ if(organism->GetPhenotype().GetDiscreteEnergyLevel() != cPhenotype::ENERGY_LEVEL_LOW) {
+ IP().Advance();
+ }
+
+ return true;
+
+} //End Inst_IfEnergyLow()
+
+
+/* Execute the next instruction if the organism's energy level is not low */
+bool cHardwareCPU::Inst_IfEnergyNotLow(cAvidaContext& ctx) {
+
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ if(organism->GetPhenotype().GetDiscreteEnergyLevel() == cPhenotype::ENERGY_LEVEL_LOW) {
+ IP().Advance();
+ }
+
+ return true;
+
+} //End Inst_IfEnergyNotLow()
+
+
+/* Execute the next instruction if the organism's energy level is high */
+bool cHardwareCPU::Inst_IfEnergyHigh(cAvidaContext& ctx) {
+
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ if(organism->GetPhenotype().GetDiscreteEnergyLevel() != cPhenotype::ENERGY_LEVEL_HIGH) {
+ IP().Advance();
+ }
+
+ return true;
+
+} //End Inst_IfEnergyHigh()
+
+
+/* Execute the next instruction if the organism's energy level is not high */
+bool cHardwareCPU::Inst_IfEnergyNotHigh(cAvidaContext& ctx) {
+
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ if(organism->GetPhenotype().GetDiscreteEnergyLevel() == cPhenotype::ENERGY_LEVEL_HIGH) {
+ IP().Advance();
+ }
+
+ return true;
+
+} //End Inst_IfEnergyNotHigh()
+
+
+/* Execute the next instruction if the organism's energy level is medium */
+bool cHardwareCPU::Inst_IfEnergyMed(cAvidaContext& ctx) {
+
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ if(organism->GetPhenotype().GetDiscreteEnergyLevel() != cPhenotype::ENERGY_LEVEL_MEDIUM) {
+ IP().Advance();
+ }
+
+ return true;
+
+} //End Inst_IfEnergyMed()
+
+
+/* Execute the next instruction if the organism has received energy */
+bool cHardwareCPU::Inst_IfEnergyInBuffer(cAvidaContext& ctx) {
+
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ if(organism->GetPhenotype().GetEnergyInBufferAmount() == 0) {
+ IP().Advance();
+ }
+
+ return true;
+
+} //End Inst_IfEnergyInBuffer()
+
+
+/* Execute the next instruction if the organism has not received energy */
+bool cHardwareCPU::Inst_IfEnergyNotInBuffer(cAvidaContext& ctx) {
+
+ if(organism->GetCellID() < 0) {
+ return false;
+ }
+
+ if(organism->GetPhenotype().GetEnergyInBufferAmount() > 0) {
+ IP().Advance();
+ }
+
+ return true;
+
+} //End Inst_IfEnergyNotInBuffer()
+
+
bool cHardwareCPU::Inst_Sleep(cAvidaContext& ctx) {
cPopulation& pop = m_world->GetPopulation();
int cellID = organism->GetCellID();
@@ -5315,7 +5551,7 @@
int cellid = organism->GetCellID();
if(cellid == -1) {
- return true;
+ return false;
}
cPopulationCell& mycell = pop.GetCell(cellid);
@@ -5371,7 +5607,7 @@
int cellid = organism->GetCellID(); //absolute id of current cell
if(cellid == -1) {
- return true;
+ return false;
}
return DoSensePheromone(ctx, cellid);
@@ -5382,7 +5618,7 @@
int cellid = organism->GetCellID(); //absolute id of current cell
if(cellid == -1) {
- return true;
+ return false;
}
cPopulation& pop = m_world->GetPopulation();
@@ -5403,7 +5639,7 @@
int cellid = organism->GetCellID();
if(cellid == -1) {
- return true;
+ return false;
}
cPopulationCell& mycell = pop.GetCell(cellid);
@@ -5541,7 +5777,7 @@
int cellid = organism->GetCellID();
if(cellid == -1) {
- return true;
+ return false;
}
cPopulationCell& mycell = pop.GetCell(cellid);
@@ -5685,7 +5921,7 @@
int cellid = organism->GetCellID();
if(cellid == -1) {
- return true;
+ return false;
}
cPopulationCell& mycell = pop.GetCell(cellid);
@@ -6053,7 +6289,7 @@
int cellid = organism->GetCellID();
if(cellid == -1) {
- return true;
+ return false;
}
cPopulationCell& mycell = pop.GetCell(cellid);
@@ -6185,7 +6421,7 @@
int cellid = organism->GetCellID();
if(cellid == -1) {
- return true;
+ return false;
}
cPopulationCell& mycell = pop.GetCell(cellid);
@@ -6313,7 +6549,7 @@
int cellid = organism->GetCellID();
if(cellid == -1) {
- return true;
+ return false;
}
cPopulationCell& mycell = pop.GetCell(cellid);
Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/cpu/cHardwareCPU.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -469,6 +469,7 @@
void DoDonate(cOrganism * to_org);
void DoEnergyDonate(cOrganism* to_org);
+ void DoEnergyDonatePercent(cOrganism* to_org, const double frac_energy_given);
bool Inst_DonateRandom(cAvidaContext& ctx);
bool Inst_DonateKin(cAvidaContext& ctx);
bool Inst_DonateEditDist(cAvidaContext& ctx);
@@ -478,7 +479,11 @@
bool Inst_DonateQuantaThreshGreenBeard(cAvidaContext& ctx);
bool Inst_DonateNULL(cAvidaContext& ctx);
bool Inst_DonateFacing(cAvidaContext& ctx);
+ bool Inst_ReceiveDonatedEnergy(cAvidaContext& ctx);
+ bool Inst_DonateEnergy(cAvidaContext& ctx);
+ bool Inst_RequestEnergy(cAvidaContext& ctx);
+
bool Inst_SearchF(cAvidaContext& ctx);
bool Inst_SearchB(cAvidaContext& ctx);
bool Inst_MemSize(cAvidaContext& ctx);
@@ -579,6 +584,14 @@
bool Inst_HeadDivide0_01(cAvidaContext& ctx);
bool Inst_HeadDivide0_001(cAvidaContext& ctx);
+ bool Inst_IfEnergyLow(cAvidaContext& ctx);
+ bool Inst_IfEnergyNotLow(cAvidaContext& ctx);
+ bool Inst_IfEnergyHigh(cAvidaContext& ctx);
+ bool Inst_IfEnergyNotHigh(cAvidaContext& ctx);
+ bool Inst_IfEnergyMed(cAvidaContext& ctx);
+ bool Inst_IfEnergyInBuffer(cAvidaContext& ctx);
+ bool Inst_IfEnergyNotInBuffer(cAvidaContext& ctx);
+
bool Inst_Sleep(cAvidaContext& ctx);
bool Inst_GetUpdate(cAvidaContext& ctx);
Modified: development/source/cpu/cTestCPUInterface.h
===================================================================
--- development/source/cpu/cTestCPUInterface.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/cpu/cTestCPUInterface.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -88,6 +88,8 @@
bool TestOnDivide() { return false; }
int GetFacing() { return 0; }
bool SendMessage(cOrgMessage& msg) { return false; }
+ bool SendMessage(cOrganism* recvr, cOrgMessage& msg) { return false; }
+ bool BroadcastMessage(cOrgMessage& msg) { return false; }
bool BcastAlarm(int jump_label, int bcast_range) { return false; }
void DivideOrgTestamentAmongDeme(double value) {;}
void SendFlash() { }
Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cAvidaConfig.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -462,6 +462,10 @@
CONFIG_ADD_VAR(NET_MUT_PROB, double, 0.0, "Message corruption probability");
CONFIG_ADD_VAR(NET_MUT_TYPE, int, 0, "Type of message corruption. 0 = Random Single Bit, 1 = Always Flip Last");
CONFIG_ADD_VAR(NET_STYLE, int, 0, "Communication Style. 0 = Random Next, 1 = Receiver Facing");
+
+ CONFIG_ADD_GROUP(ORGANISM_MESSAGING_GROUP, "Organism Message-Based Communication");
+ CONFIG_ADD_VAR(MESSAGE_TYPE, int, 0, "Messaging Stle. 0=Receiver Facing, 1=Broadcast");
+ CONFIG_ADD_VAR(MESSAGE_BCAST_RADIUS, int, 1, "Broadcast message radius (cells)");
CONFIG_ADD_GROUP(BUY_SELL_GROUP, "Buying and Selling Parameters");
CONFIG_ADD_VAR(SAVE_RECEIVED, bool, 0, "Enable storage of all inputs bought from other orgs");
@@ -490,7 +494,13 @@
CONFIG_ADD_VAR(ENERGY_PASSED_ON_DEME_REPLICATION_METHOD, int, 0, "Who get energy passed from a parent deme\n0 = Energy divided among organisms injected to offspring deme\n1 = Energy divided among cells in offspring deme");
CONFIG_ADD_VAR(INHERIT_EXE_RATE, int, 0, "Inherit energy rate from parent? 0=no 1=yes");
CONFIG_ADD_VAR(ATTACK_DECAY_RATE, double, 0.0, "Percent of cell's energy decayed by attack");
-
+ CONFIG_ADD_VAR(ENERGY_THRESH_LOW, double, .33, "Threshold percent below which energy level is considered low. Requires ENERGY_CAP.");
+ CONFIG_ADD_VAR(ENERGY_THRESH_HIGH, double, .75, "Threshold percent above which energy level is considered high. Requires ENERGY_CAP.");
+
+ CONFIG_ADD_GROUP(ENERGY_SHARING_GROUP, "Energy Sharing Settings");
+ CONFIG_ADD_VAR(ENERGY_SHARING_METHOD, int, 0, "Method for sharing energy. 0=receiver must actively receive, 1=energy pushed on receiver");
+ CONFIG_ADD_VAR(ENERGY_SHARING_LOSS, double, 0.0, "Percent of shared energy lost in transfer");
+
CONFIG_ADD_GROUP(SECOND_PASS_GROUP, "Tracking metrics known after the running experiment previously");
CONFIG_ADD_VAR(TRACK_CCLADES, int, 0, "Enable tracking of coalescence clades");
CONFIG_ADD_VAR(TRACK_CCLADES_IDS, cString, "coalescence.ids", "File storing coalescence IDs");
Modified: development/source/main/cDeme.cc
===================================================================
--- development/source/main/cDeme.cc 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cDeme.cc 2008-10-27 17:07:01 UTC (rev 2887)
@@ -795,3 +795,62 @@
// assert(false); // slots must be of equal size and fit perfectally in deme lifetime
return 0;
}
+
+/* Place the absolute IDs of all cells surrounding the given cell id within the given radius into vector cells */
+void cDeme::GetSurroundingCellIds(tVector<int> &cells, const int absolute_cell_id, const int radius) {
+ assert(cell_ids[0] <= absolute_cell_id);
+ assert(absolute_cell_id <= cell_ids[cell_ids.GetSize()-1]);
+ assert(radius >= 0);
+
+ const int relative_cell_id = GetRelativeCellID(absolute_cell_id);
+ const int geometry = m_world->GetConfig().WORLD_GEOMETRY.Get();
+ const int width = GetWidth();
+ const int height = GetHeight();
+ const std::pair<int, int> coords = GetCellPosition(absolute_cell_id);
+ const int curr_x = coords.first;
+ const int curr_y = coords.second;
+ int cid, acid;
+ int x2, y2;
+
+ //Note: this code currently supports a grid or torus
+ assert(geometry == nGeometry::GRID || geometry == nGeometry::TORUS);
+
+ if(geometry == nGeometry::GRID) {
+ for(int y = curr_y - radius; y <= curr_y + radius; y++) {
+ for(int x = curr_x - radius; x <= curr_x + radius; x++) {
+ cid = y * width + x;
+ acid = GetAbsoluteCellID(cid);
+ if(y >= 0 && y < height && x >= 0 && x < width && cid != relative_cell_id) {
+ cells.Add(acid);
+ }
+ }
+ }
+ } //End if world is a grid
+ else if(geometry == nGeometry::TORUS) {
+ for(int y = curr_y - radius; y <= curr_y + radius; y++) {
+ for(int x = curr_x - radius; x <= curr_x + radius; x++) {
+ x2 = x; y2 = y;
+
+ if(x2 < 0) {
+ x2 = x2 + width;
+ } else if(x2 >= width) {
+ x2 = x2 - width;
+ }
+
+ if(y2 < 0) {
+ y2 = y2 + height;
+ } else if(y2 >= height) {
+ y2 = y2 - height;
+ }
+
+ cid = y2 * width + x2;
+ acid = GetAbsoluteCellID(cid);
+
+ if(cid != relative_cell_id) {
+ cells.Add(acid);
+ }
+ }
+ }
+ } //End if world is a torus
+
+} //End GetSurroundingCellIds()
Modified: development/source/main/cDeme.h
===================================================================
--- development/source/main/cDeme.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cDeme.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -233,7 +233,8 @@
void UpdateDemeRes() { deme_resource_count.GetResources(); }
void Update(double time_step) { deme_resource_count.Update(time_step); }
int GetRelativeCellID(int absolute_cell_id) const { return absolute_cell_id % GetSize(); } //!< assumes all demes are the same size
-
+ int GetAbsoluteCellID(int relative_cell_id) const { return relative_cell_id + (_id * GetSize()); } //!< assumes all demes are the same size
+
void SetCellEventGradient(int x1, int y1, int x2, int y2, int delay, int duration, bool static_pos, int time_to_live);
int GetNumEvents();
void SetCellEvent(int x1, int y1, int x2, int y2, int delay, int duration, bool static_position, int total_events);
@@ -286,6 +287,8 @@
// --- Pheromones --- //
void AddPheromone(int absolute_cell_id, double value);
+
+ void GetSurroundingCellIds(tVector<int> &cells, const int absolute_cell_id, const int radius);
};
#endif
Modified: development/source/main/cOrgInterface.h
===================================================================
--- development/source/main/cOrgInterface.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cOrgInterface.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -98,6 +98,7 @@
virtual bool UpdateMerit(double new_merit) = 0;
virtual bool TestOnDivide() = 0;
virtual bool SendMessage(cOrgMessage& msg) = 0;
+ virtual bool BroadcastMessage(cOrgMessage& msg) = 0;
virtual bool BcastAlarm(int jump_jabel, int bcast_range) = 0;
virtual void DivideOrgTestamentAmongDeme(double value) = 0;
virtual void SendFlash() = 0;
Modified: development/source/main/cOrganism.cc
===================================================================
--- development/source/main/cOrganism.cc 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cOrganism.cc 2008-10-27 17:07:01 UTC (rev 2887)
@@ -689,6 +689,31 @@
}
+// Broadcast a message - slightly modified version of SendMessage
+bool cOrganism::BroadcastMessage(cAvidaContext& ctx, cOrgMessage& msg)
+{
+ assert(m_interface);
+ InitMessaging();
+
+ // If we're able to succesfully send the message...
+ if(m_interface->BroadcastMessage(msg)) {
+ // save it...
+ m_msg->sent.push_back(msg);
+ // and set the receiver-pointer of this message to NULL. We don't want to
+ // walk this list later thinking that the receivers are still around.
+ // Also, a broadcast message may have >1 receiver
+ m_msg->sent.back().SetReceiver(0);
+ // stat-tracking... NOTE: this has receiver not specified, so may be a problem for predicates
+ m_world->GetStats().SentMessage(msg);
+ // check to see if we've performed any tasks...NOTE: this has receiver not specified, so may be a problem for tasks that care
+ DoOutput(ctx);
+ return true;
+ }
+
+ return false;
+} //End BroadcastMessage()
+
+
void cOrganism::ReceiveMessage(cOrgMessage& msg)
{
InitMessaging();
@@ -708,7 +733,7 @@
return 0;
}
-// Brian Movement
+
void cOrganism::Move(cAvidaContext& ctx)
{
assert(m_interface);
Modified: development/source/main/cOrganism.h
===================================================================
--- development/source/main/cOrganism.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cOrganism.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -344,6 +344,7 @@
//! Called when this organism attempts to send a message.
bool SendMessage(cAvidaContext& ctx, cOrgMessage& msg);
+ bool BroadcastMessage(cAvidaContext& ctx, cOrgMessage& msg);
//! Called when this organism has been sent a message.
void ReceiveMessage(cOrgMessage& msg);
//! Called when this organism attempts to move a received message into its CPU.
Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cPhenotype.cc 2008-10-27 17:07:01 UTC (rev 2887)
@@ -88,6 +88,7 @@
energy_store = in_phen.energy_store;
energy_tobe_applied = in_phen.energy_tobe_applied;
energy_testament = in_phen.energy_testament;
+ energy_received_buffer = in_phen.energy_received_buffer;
genome_length = in_phen.genome_length;
bonus_instruction_count = in_phen.bonus_instruction_count;
copied_size = in_phen.copied_size;
@@ -142,6 +143,8 @@
last_sense_count = in_phen.last_sense_count;
last_fitness = in_phen.last_fitness;
last_child_germline_propensity = in_phen.last_child_germline_propensity;
+ total_energy_donated = in_phen.total_energy_donated;
+ total_energy_received = in_phen.total_energy_received;
// 4. Records from this organisms life...
num_divides = in_phen.num_divides;
@@ -202,6 +205,12 @@
parent_true = in_phen.parent_true;
parent_sex = in_phen.parent_sex;
parent_cross_num = in_phen.parent_cross_num;
+
+ is_energy_donor = in_phen.is_energy_donor;
+ is_energy_receiver = in_phen.is_energy_receiver;
+ has_used_donated_energy = in_phen.has_used_donated_energy;
+ total_energy_donated = in_phen.total_energy_donated;
+ total_energy_received = in_phen.total_energy_received;
// 6. Child information...
copy_true = in_phen.copy_true;
@@ -240,6 +249,7 @@
assert(time_used >= 0);
assert(age >= 0);
assert(child_copied_size >= 0);
+ assert(energy_received_buffer >= 0);
// assert(to_die == false);
return (m_world);
}
@@ -267,6 +277,7 @@
energy_store = min(energy_store, (double) m_world->GetConfig().ENERGY_CAP.Get());
energy_tobe_applied = 0.0;
energy_testament = 0.0;
+ energy_received_buffer = 0.0;
genome_length = _genome.GetSize();
copied_size = parent_phenotype.child_copied_size;
executed_size = parent_phenotype.executed_size;
@@ -382,6 +393,12 @@
to_die = false;
to_delete = false;
+ is_energy_donor = false;
+ is_energy_receiver = false;
+ has_used_donated_energy = false;
+ total_energy_donated = 0.0;
+ total_energy_received = 0.0;
+
// Setup child info...
copy_true = false;
divide_sex = false;
@@ -417,6 +434,7 @@
energy_store = min(m_world->GetConfig().ENERGY_GIVEN_ON_INJECT.Get(), m_world->GetConfig().ENERGY_CAP.Get());
energy_tobe_applied = 0.0;
energy_testament = 0.0;
+ energy_received_buffer = 0.0;
executionRatio = 1.0;
gestation_time = 0;
gestation_start = 0;
@@ -519,6 +537,12 @@
parent_cross_num = 0;
to_die = false;
to_delete = false;
+
+ is_energy_donor = false;
+ is_energy_receiver = false;
+ has_used_donated_energy = false;
+ total_energy_donated = 0.0;
+ total_energy_received = 0.0;
// Setup child info...
copy_true = false;
@@ -558,7 +582,7 @@
SetEnergy(energy_store + cur_energy_bonus);
m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
energy_testament = 0.0;
-
+ energy_received_buffer = 0.0; // If donated energy not applied, it's lost here
genome_length = _genome.GetSize();
(void) copied_size; // Unchanged
@@ -833,6 +857,7 @@
energy_store = clone_phenotype.energy_store;
energy_tobe_applied = 0.0;
energy_testament = 0.0;
+ energy_received_buffer = 0.0;
if(m_world->GetConfig().INHERIT_EXE_RATE.Get() == 0)
executionRatio = 1.0;
@@ -949,6 +974,9 @@
parent_cross_num = clone_phenotype.cross_num;
to_die = false;
to_delete = false;
+ is_energy_donor = false;
+ is_energy_receiver = false;
+ has_used_donated_energy = false;
// Setup child info...
copy_true = false;
@@ -1242,6 +1270,20 @@
energy_testament += value;
} //! external energy given to organism
+
+void cPhenotype::ApplyDonatedEnergy() {
+ SetEnergy(energy_store + energy_received_buffer);
+ energy_received_buffer = 0.0;
+} //End AppplyDonatedEnergy()
+
+
+void cPhenotype::ReceiveDonatedEnergy(const double donation) {
+ assert(donation >= 0.0);
+ energy_received_buffer += donation;
+ is_energy_receiver = true;
+} //End ReceiveDonatedEnergy()
+
+
double cPhenotype::ExtractParentEnergy() {
assert(m_world->GetConfig().ENERGY_ENABLED.Get() > 0);
// energy model config variables
@@ -1399,6 +1441,8 @@
is_receiver_threshgb = false;
is_receiver_quanta_threshgb_last = is_receiver_quanta_threshgb;
is_receiver_quanta_threshgb = false;
+ is_energy_donor = false;
+ is_energy_receiver = false;
(void) is_modifier;
(void) is_modified;
(void) is_fertile;
@@ -1514,3 +1558,28 @@
return false;
}
+
+// Return an integer classifying the organism's energy level as -1=error,0=low,1=med,2=high
+int cPhenotype::GetDiscreteEnergyLevel() const {
+ double max_energy = m_world->GetConfig().ENERGY_CAP.Get();
+ double high_pct = m_world->GetConfig().ENERGY_THRESH_HIGH.Get();
+ double low_pct = m_world->GetConfig().ENERGY_THRESH_LOW.Get();
+
+ assert(max_energy >= 0);
+ assert(high_pct <= 1);
+ assert(high_pct >= 0);
+ assert(low_pct <= 1);
+ assert(low_pct >= 0);
+ assert(low_pct <= high_pct);
+
+ if (energy_store < (low_pct * max_energy)) {
+ return ENERGY_LEVEL_LOW;
+ } else if ( (energy_store >= (low_pct * max_energy)) && (energy_store <= (high_pct * max_energy)) ) {
+ return ENERGY_LEVEL_MEDIUM;
+ } else if (energy_store > (high_pct * max_energy)) {
+ return ENERGY_LEVEL_HIGH;
+ } else {
+ return -1;
+ }
+
+} //End GetDiscreteEnergyLevel()
Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cPhenotype.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -110,6 +110,9 @@
double cur_energy_bonus; // Current energy bonus
double energy_tobe_applied; // Energy that has not yet been added to energy store.
double energy_testament;
+ double energy_received_buffer; // Energy received through donation, but not yet applied to energy store
+ double total_energy_donated; // Tota amount of energy that has been donated
+ double total_energy_received; // Total amount of energy received through donations
int cur_num_errors; // Total instructions executed illeagally.
int cur_num_donates; // Number of donations so far
tArray<int> cur_task_count; // Total times each task was performed
@@ -180,6 +183,9 @@
bool is_donor_threshgb_last;// Did this org's parent threshgbg_donate?
bool is_donor_quanta_threshgb; // Has this organism quanta_threshgb_donated (true green beard)?
bool is_donor_quanta_threshgb_last;// Did this org's parent quanta_threshgbg_donate?
+ bool is_energy_donor; // Has this organism donated energy?
+ bool is_energy_receiver; // Has this organism received an energy donation?
+ bool has_used_donated_energy; // Has the organism actively used an energy donation?
int num_thresh_gb_donations; // Num times this organism threshgb_donated (thresh green beard)?
int num_thresh_gb_donations_last; // Num times this org's parent thresh_donated?
int num_quanta_thresh_gb_donations; // Num times this organism threshgb_donated (thresh green beard)?
@@ -233,7 +239,8 @@
cPhenotype& operator=(const cPhenotype&);
~cPhenotype();
-
+ enum energy_levels {ENERGY_LEVEL_LOW = 0, ENERGY_LEVEL_MEDIUM, ENERGY_LEVEL_HIGH};
+
bool OK();
// Run when being setup *as* and offspring.
@@ -295,6 +302,8 @@
double GetCurMeritBase() const { assert(initialized == true); return CalcSizeMerit(); }
double GetStoredEnergy() const { return energy_store; }
double GetEnergyBonus() const { assert(initialized == true); return cur_energy_bonus; }
+ int GetDiscreteEnergyLevel() const;
+ double GetEnergyInBufferAmount() const { return energy_received_buffer; }
bool GetToDie() const { assert(initialized == true); return to_die; }
bool GetToDelete() const { assert(initialized == true); return to_delete; }
@@ -363,6 +372,9 @@
bool IsDonorThreshGbLast() const { assert(initialized == true); return is_donor_threshgb_last; }
bool IsDonorQuantaThreshGb() const { assert(initialized == true); return is_donor_quanta_threshgb; }
bool IsDonorQuantaThreshGbLast() const { assert(initialized == true); return is_donor_quanta_threshgb_last; }
+ bool IsEnergyDonor() const { assert(initialized == true); return is_energy_donor; }
+ bool IsEnergyReceiver() const { assert(initialized == true); return is_energy_receiver; }
+ bool HasUsedEnergyDonation() const { assert(initialized == true); return has_used_donated_energy; }
bool IsReceiver() const { assert(initialized == true); return is_receiver; }
bool IsReceiverLast() const { assert(initialized == true); return is_receiver_last; }
bool IsReceiverRand() const { assert(initialized == true); return is_receiver_rand; }
@@ -415,7 +427,9 @@
void SetCrossNum(int _cross_num) { cross_num = _cross_num; }
void SetToDie() { to_die = true; }
void SetToDelete() { to_delete = true; }
-
+ void IncreaseEnergyDonated(double amount) { assert(amount >=0); total_energy_donated += amount; }
+ void IncreaseEnergyReceived(double amount) { assert(amount >=0); total_energy_received += amount; }
+
void SetIsDonorCur() { is_donor_cur = true; }
void SetIsDonorRand() { SetIsDonorCur(); is_donor_rand = true; }
void SetIsDonorKin() { SetIsDonorCur(); is_donor_kin = true; }
@@ -433,6 +447,9 @@
void SetIsReceiverTrueGb() { SetIsReceiver(); is_receiver_truegb = true; }
void SetIsReceiverThreshGb() { SetIsReceiver(); is_receiver_threshgb = true; }
void SetIsReceiverQuantaThreshGb() { SetIsReceiver(); is_receiver_quanta_threshgb = true; }
+ void SetIsEnergyDonor() { is_energy_donor = true; }
+ void SetIsEnergyReceiver() { is_energy_receiver = true; }
+ void SetHasUsedDonatedEnergy() {has_used_donated_energy = true; }
void SetCurBonus(double _bonus) { cur_bonus = _bonus; }
void SetCurBonusInstCount(int _num_bonus_inst) {bonus_instruction_count = _num_bonus_inst;}
@@ -473,6 +490,8 @@
void RefreshEnergy();
void ApplyToEnergyStore();
void EnergyTestament(const double value); //! external energy given to organism
+ void ApplyDonatedEnergy();
+ void ReceiveDonatedEnergy(const double value);
double ExtractParentEnergy();
bool operator<(const cPhenotype& rhs) const;
Modified: development/source/main/cPopulationInterface.cc
===================================================================
--- development/source/main/cPopulationInterface.cc 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cPopulationInterface.cc 2008-10-27 17:07:01 UTC (rev 2887)
@@ -275,7 +275,42 @@
return true;
}
+/* Send a message to the given organism */
+bool cPopulationInterface::SendMessage(cOrganism* recvr, cOrgMessage& msg) {
+ assert(recvr != NULL);
+ recvr->ReceiveMessage(msg);
+ return true;
+} //End SendMessage()
+
+// Broadcast the message to all living organisms within range
+bool cPopulationInterface::BroadcastMessage(cOrgMessage& msg) {
+ bool all_sent = true;
+ const int bcast_range = m_world->GetConfig().MESSAGE_BCAST_RADIUS.Get();
+ assert(bcast_range >= 0);
+ tVector<int> neighbors;
+ neighbors.Clear();
+
+ cDeme& deme = m_world->GetPopulation().GetDeme(GetDemeID());
+ deme.GetSurroundingCellIds(neighbors, GetCellID(), bcast_range);
+
+ for(int i = 0; i < neighbors.Size(); i++) {
+ cPopulationCell& rcell = m_world->GetPopulation().GetCell(neighbors[i]);
+ if(rcell.IsOccupied()) {
+ cOrganism* neighbor = rcell.GetOrganism();
+ assert(neighbor != NULL);
+
+ if(!SendMessage(neighbor, msg)) {
+ all_sent = false;
+ }
+ }
+ }
+
+ return all_sent;
+
+} //End BroadcastMessage
+
+
bool cPopulationInterface::BcastAlarm(int jump_label, int bcast_range) {
bool successfully_sent(false);
cPopulationCell& scell = m_world->GetPopulation().GetCell(m_cell_id);
Modified: development/source/main/cPopulationInterface.h
===================================================================
--- development/source/main/cPopulationInterface.h 2008-10-27 16:54:45 UTC (rev 2886)
+++ development/source/main/cPopulationInterface.h 2008-10-27 17:07:01 UTC (rev 2887)
@@ -105,6 +105,8 @@
bool TestOnDivide();
//! Send a message to the faced organism.
bool SendMessage(cOrgMessage& msg);
+ bool SendMessage(cOrganism* recvr, cOrgMessage& msg);
+ bool BroadcastMessage(cOrgMessage& msg);
bool BcastAlarm(int jump_label, int bcast_range);
void DivideOrgTestamentAmongDeme(double value);
//! Send a flash to all neighboring organisms.
More information about the Avida-cvs
mailing list