Skip to content

Commit 1ebae63

Browse files
Merge pull request #276 from K-Johnson-Horrigan/complex-syms-clean
self OR parent bitset + if/if escapee/offspring
2 parents 47f4a6b + ca67362 commit 1ebae63

8 files changed

Lines changed: 76 additions & 16 deletions

File tree

source/sgp_mode/CPU.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class CPU {
8989
~CPU() {
9090
state.parent_tasks_performed.Delete();
9191
state.tasks_performed.Delete();
92+
state.parent_or_current_tasks_performed.Delete();
9293
}
9394

9495
/**

source/sgp_mode/CPUState.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct CPUState {
4949

5050
emp::Ptr<emp::BitSet<CPU_BITSET_LENGTH>> tasks_performed = emp::NewPtr<emp::BitSet<CPU_BITSET_LENGTH>>();
5151
emp::Ptr<emp::BitSet<CPU_BITSET_LENGTH>> parent_tasks_performed = emp::NewPtr<emp::BitSet<CPU_BITSET_LENGTH>>(false);
52+
emp::Ptr<emp::BitSet<CPU_BITSET_LENGTH>> parent_or_current_tasks_performed = emp::NewPtr<emp::BitSet<CPU_BITSET_LENGTH>>(false);
53+
5254
int task_change_lose[CPU_BITSET_LENGTH] = { 0 };
5355
int task_change_gain[CPU_BITSET_LENGTH] = { 0 };
5456

source/sgp_mode/SGPConfigSetup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ EMP_EXTEND_CONFIG(SymConfigSGP, SymConfigBase,
1313
VALUE(RANDOM_IO_INPUT, bool, true, "1 to give organisms random input when they IO, 0 to give them only ones"),
1414
VALUE(INTERACTION_MECHANISM, size_t, DEFAULT, "What sgp organisms should population the world? (0 for default SGP, 1 for Health organisms, 2 for stress organisms, 3 for nutrient organisms)"),
1515
VALUE(VT_TASK_MATCH, bool, 0, "Should task matching be required for vertical transmission? (0 for no, 1 for yes)"),
16+
VALUE(TRACK_PARENT_TASKS, int, 0, "Should parental task completion data be used for reproductive task matching (instead of the individual's task completion data?) (0 to use only current tasks, 1 to use only the parental tasks, 2 to use an OR of the parent and current tasks)"),
1617
VALUE(HT_TASK_MATCH, bool, 1, "Should task matching be required for horizontal transmission? (0 for no, 1 for yes)"),
17-
VALUE(TRACK_PARENT_TASKS, bool, 0, "Should parental task completion data be used for reproductive task matching (instead of the individual's task completion data?) (0 for no, 1 for yes)"),
1818
VALUE(NUTRIENT_DONATE_STEAL_PROP, double, 0.5, "What proportion of points should a symbiont donate to its host and what proportion of points should a symbiont steal from its host during nutrient type interactions"),
1919
VALUE(SYMBIONT_TYPE, size_t, MUTUALIST, "What kind of stress symbionts should be incorporated in stressful environments? (0 for mutualists, 1 for parasites, 2 for neutrals"),
2020
VALUE(ALLOW_TRANSITION_EVOLUTION, int, 0, "Should symbionts be allowed to evolve from mutualists to parasites and vice versa"),

source/sgp_mode/SGPHost.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ emp::Ptr<Organism> SGPHost::Reproduce() {
1919
cpu.state.in_progress_repro = -1;
2020

2121
host_baby->GetCPU().state.parent_tasks_performed->Import(*GetCPU().state.tasks_performed);
22+
if (sgp_config->TRACK_PARENT_TASKS() == 2) {
23+
host_baby->GetCPU().state.parent_or_current_tasks_performed->Import(*GetCPU().state.tasks_performed);
24+
}
2225
if (sgp_config->TRACK_PARENT_TASKS()) {
2326
for (int i = 0; i < CPU_BITSET_LENGTH; i++) {
2427
host_baby->GetCPU().state.task_change_lose[i] = cpu.state.task_change_lose[i];

source/sgp_mode/SGPSymbiont.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ class SGPSymbiont : public Symbiont {
202202
// This organism is reproducing, so it must have gotten off the queue
203203
cpu.state.in_progress_repro = -1;
204204
sym_baby->GetCPU().state.parent_tasks_performed->Import(*GetCPU().state.tasks_performed);
205+
if (sgp_config->TRACK_PARENT_TASKS() == 2) {
206+
sym_baby->GetCPU().state.parent_or_current_tasks_performed->Import(*GetCPU().state.tasks_performed);
207+
}
205208
if (sgp_config->TRACK_PARENT_TASKS()) {
206209
//inherit towards-from tracking
207210
for (int i = 0; i < CPU_BITSET_LENGTH; i++) {

source/sgp_mode/SGPWorldSetup.cc

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,28 @@ void SGPWorld::SetupSymbionts(unsigned long *total_syms) {
6464
* Purpose: Setup the task profile retriever function.
6565
*/
6666
void SGPWorld::SetupTaskProfileFun() {
67-
if (sgp_config->TRACK_PARENT_TASKS()) {
67+
if (sgp_config->TRACK_PARENT_TASKS() == 2) {
68+
fun_get_task_profile = [](const emp::Ptr<Organism> org) -> const emp::BitSet<CPU_BITSET_LENGTH>&{
69+
if (org->IsHost()) {
70+
return (*org.DynamicCast<SGPHost>()->GetCPU().state.parent_or_current_tasks_performed).OR_SELF(*org.DynamicCast<SGPHost>()->GetCPU().state.tasks_performed);
71+
}
72+
else {
73+
return (*org.DynamicCast<SGPSymbiont>()->GetCPU().state.parent_or_current_tasks_performed).OR_SELF(*org.DynamicCast<SGPSymbiont>()->GetCPU().state.tasks_performed);
74+
}
75+
};
76+
}
77+
else if (sgp_config->TRACK_PARENT_TASKS() == 1) {
6878
fun_get_task_profile = [](const emp::Ptr<Organism> org) -> const emp::BitSet<CPU_BITSET_LENGTH>&{
6979
if (org->IsHost()) {
7080
return *org.DynamicCast<SGPHost>()->GetCPU().state.parent_tasks_performed;
7181
}
7282
else {
7383
return *org.DynamicCast<SGPSymbiont>()->GetCPU().state.parent_tasks_performed;
7484
}
75-
};
85+
};
7686
}
77-
else {
78-
fun_get_task_profile = [](const emp::Ptr<Organism> org) -> emp::BitSet<CPU_BITSET_LENGTH>&{
87+
else if (sgp_config->TRACK_PARENT_TASKS() == 0) {
88+
fun_get_task_profile = [](const emp::Ptr<Organism> org) -> const emp::BitSet<CPU_BITSET_LENGTH>&{
7989
if (org->IsHost()) {
8090
return *org.DynamicCast<SGPHost>()->GetCPU().state.tasks_performed;
8191
}

source/sgp_mode/StressHost.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,8 @@ class StressHost : public SGPHost {
9393
else if (sgp_config->SYMBIONT_TYPE() == PARASITE && tasks_satisfactory) death_chance = sgp_config->PARASITE_DEATH_CHANCE();
9494
}
9595
if (random->P(death_chance)) {
96-
if (sgp_config->SYMBIONTS_ESCAPE()) {
97-
//Symbionts get to escape during an extinction event
98-
for (size_t j = 0; j < syms.size(); j++) {
99-
emp::Ptr<Organism> cur_sym = syms[j];
100-
RemoveSymbiont(j + 1); //RemoveSymbiont uses 1-indexed value
101-
my_world->SymFindHost(cur_sym, emp::WorldPosition(j + 1, pos.GetIndex()));
102-
}
103-
}
104-
else if (sgp_config->SYMBIONT_TYPE() == PARASITE && sgp_config->PARASITE_NUM_OFFSPRING_ON_STRESS_INTERACTION() > 0) {
96+
// escapee offspring go first (so that parent sym is not removed before they can use it!)
97+
if (sgp_config->SYMBIONT_TYPE() == PARASITE && sgp_config->PARASITE_NUM_OFFSPRING_ON_STRESS_INTERACTION() > 0) {
10598
for (size_t j = 0; j < syms.size(); j++) {
10699
const emp::BitSet<CPU_BITSET_LENGTH>& sym_infection_tasks = my_world->fun_get_task_profile(syms[j]);
107100
if (my_world->TaskMatchCheck(sym_infection_tasks, my_world->fun_get_task_profile(this))) {
@@ -112,6 +105,14 @@ class StressHost : public SGPHost {
112105
}
113106
}
114107
}
108+
if (sgp_config->SYMBIONTS_ESCAPE()) {
109+
//Symbionts get to escape during an extinction event
110+
for (size_t j = 0; j < syms.size(); j++) {
111+
emp::Ptr<Organism> cur_sym = syms[j];
112+
RemoveSymbiont(j + 1); //RemoveSymbiont uses 1-indexed value
113+
my_world->SymFindHost(cur_sym, emp::WorldPosition(j + 1, pos.GetIndex()));
114+
}
115+
}
115116
SetDead();
116117
}
117118
}

source/test/sgp_mode_test/SGPWorldSetup.test.cc

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,40 @@ TEST_CASE("SetupTaskProfileFun", "[sgp]") {
44
emp::Random random(61);
55
SymConfigSGP config;
66

7-
WHEN("TRACK_PARENT_TASKS is on") {
7+
WHEN("TRACK_PARENT_TASKS is 2 (on, returns parent OR self tasks)") {
8+
config.TRACK_PARENT_TASKS(2);
9+
SGPWorld world(random, &config, LogicTasks);
10+
11+
emp::Ptr<SGPHost> host_parent = emp::NewPtr<SGPHost>(&random, &world, &config);
12+
emp::Ptr<SGPSymbiont> symbiont_parent = emp::NewPtr<SGPSymbiont>(&random, &world, &config);
13+
14+
host_parent->GetCPU().state.tasks_performed->Set(1);
15+
symbiont_parent->GetCPU().state.tasks_performed->Set(8);
16+
symbiont_parent->GetCPU().state.tasks_performed->Set(7);
17+
18+
emp::Ptr<SGPHost> host = host_parent->Reproduce().DynamicCast<SGPHost>(); // parent tasks get imported to the ORed bitset on repro
19+
emp::Ptr<SGPSymbiont> symbiont = symbiont_parent->Reproduce().DynamicCast<SGPSymbiont>();
20+
21+
host->GetCPU().state.tasks_performed->Set(0);
22+
symbiont->GetCPU().state.tasks_performed->Set(7);
23+
24+
THEN("fun_get_task_profile returns parental OR self tasks completed") {
25+
REQUIRE(world.fun_get_task_profile(host).CountOnes() == 2);
26+
REQUIRE(world.fun_get_task_profile(host).Get(0) == 1);
27+
REQUIRE(world.fun_get_task_profile(host).Get(1) == 1);
28+
29+
REQUIRE(world.fun_get_task_profile(symbiont).CountOnes() == 2);
30+
REQUIRE(world.fun_get_task_profile(symbiont).Get(7) == 1);
31+
REQUIRE(world.fun_get_task_profile(symbiont).Get(8) == 1);
32+
}
33+
34+
host.Delete();
35+
symbiont.Delete();
36+
host_parent.Delete();
37+
symbiont_parent.Delete();
38+
}
39+
40+
WHEN("TRACK_PARENT_TASKS is 1 (on, returns parent tasks only)") {
841
config.TRACK_PARENT_TASKS(1);
942
SGPWorld world(random, &config, LogicTasks);
1043

@@ -23,8 +56,12 @@ TEST_CASE("SetupTaskProfileFun", "[sgp]") {
2356
REQUIRE(world.fun_get_task_profile(symbiont).CountOnes() == 1);
2457
REQUIRE(world.fun_get_task_profile(symbiont).Get(8) == 1);
2558
}
59+
60+
host.Delete();
61+
symbiont.Delete();
2662
}
27-
WHEN("TRACK_PARENT_TASKS is off") {
63+
64+
WHEN("TRACK_PARENT_TASKS is 0 (off, returns self tasks only)") {
2865
config.TRACK_PARENT_TASKS(0);
2966
SGPWorld world(random, &config, LogicTasks);
3067

@@ -43,5 +80,8 @@ TEST_CASE("SetupTaskProfileFun", "[sgp]") {
4380
REQUIRE(world.fun_get_task_profile(symbiont).CountOnes() == 1);
4481
REQUIRE(world.fun_get_task_profile(symbiont).Get(7) == 1);
4582
}
83+
84+
host.Delete();
85+
symbiont.Delete();
4686
}
4787
}

0 commit comments

Comments
 (0)