diff --git a/source/Organism.h b/source/Organism.h index 1ee29efa..68c3c708 100644 --- a/source/Organism.h +++ b/source/Organism.h @@ -114,8 +114,8 @@ class Organism { std::cout << "GetReproCount called from Organism" << std::endl; throw "Organism method called!"; } - virtual void SetReproCount(size_t _in) { - std::cout << "SetReproCount called from Organism" << std::endl; + virtual void LineageLength(size_t _in) { + std::cout << "LineageLength called from Organism" << std::endl; throw "Organism method called!"; } virtual void SetTowardsPartnerCount(size_t _in) { diff --git a/source/default_mode/Host.h b/source/default_mode/Host.h index 7ba219a2..d07b8d25 100644 --- a/source/default_mode/Host.h +++ b/source/default_mode/Host.h @@ -280,7 +280,7 @@ class Host: public Organism { * * Purpose: To set the count of reproductions in this lineage. */ - void SetReproCount(size_t _in) { reproductions = _in; } + void LineageLength(size_t _in) { reproductions = _in; } /** @@ -767,7 +767,7 @@ class Host: public Organism { emp::Ptr host_baby = MakeNew(); host_baby->Mutate(); - host_baby->SetReproCount(reproductions + 1); + host_baby->LineageLength(reproductions + 1); SetPoints(0); if (my_config->TAG_MATCHING() && HasSym()) { diff --git a/source/default_mode/Symbiont.h b/source/default_mode/Symbiont.h index 899a6067..7445a023 100644 --- a/source/default_mode/Symbiont.h +++ b/source/default_mode/Symbiont.h @@ -224,7 +224,7 @@ class Symbiont: public Organism { * * Purpose: To set the count of reproductions in this lineage. */ - void SetReproCount(size_t _in) { reproductions = _in; } + void LineageLength(size_t _in) { reproductions = _in; } /** @@ -696,7 +696,7 @@ class Symbiont: public Organism { emp::Ptr Reproduce() { emp::Ptr sym_baby = MakeNew(); sym_baby->Mutate(); - sym_baby->SetReproCount(reproductions + 1); + sym_baby->LineageLength(reproductions + 1); if(my_config->PHYLOGENY() == 1) { my_world->AddSymToSystematic(sym_baby, my_taxon); //baby's taxon will be set in AddSymToSystematic diff --git a/source/sgp_mode/DevNotes.md b/source/sgp_mode/DevNotes.md index 518fdcef..f44b12d1 100644 --- a/source/sgp_mode/DevNotes.md +++ b/source/sgp_mode/DevNotes.md @@ -2,13 +2,10 @@ ## Further refactoring list: * Add SGP mode to API reference doc -* Move ProcessSymOutputBuffer into SGPSymbiont to parallel host -* Move SymDoMutation into SGPSymbiont to parallel host -* Look at whether can move SymDonateToHost and SymStealFromHost into SGPSym * Look at fun_host_sym_stress_trans_compatibility_check to try to reduce code duplication of task-profile setups, possibly with decorator pattern, but also definitely just in own file * Move world properties back into protected and make necessary accesssors * Try to fold ProcessStressEscapees into existing code/reduce duplication -* Rename "SetReproCount" to lineage length since it's confusing (or did I already?) +* Rename "SetReproCount" to lineage length since it's confusing (or did I already?) //I did this * Look into what is going on with SGPHost local sgp_config not working * Streamline Host ProcessOutputBuffer and check if easier access to some variables * Break Host Reproduce into helper functions @@ -30,6 +27,7 @@ [x] Make a list from this commit for further shifting todos and update this doc with those todos https://github.com/anyaevostinar/SymbulationEmp/commit/9ea1d53c8bf70c612d1454fac0510ddaf0c70e9d for AEV TODO and Refactor note for what else I already had decided would be good to do [x] Horizontal transmission to make parallel to default mode and integrated to support tags with tasks - Decisions made: reproduce is shared between horizontal transmission and free-living sym reproduction. If free-living sym repro is on, then reproduce places offspring into sym pop (like in default), and then offspring can infect with Infect instruction (not yet implemented). If FLS is off, reproduce does horizontal transmission. Also decided that if HT is off, an "attempt" is not counted. +[x] Move SymDoMutation into SGPSymbiont to parallel host # Journal 4/15/26 diff --git a/source/sgp_mode/SGPConfigSetup.h b/source/sgp_mode/SGPConfigSetup.h index 5300e457..a4686a23 100644 --- a/source/sgp_mode/SGPConfigSetup.h +++ b/source/sgp_mode/SGPConfigSetup.h @@ -69,9 +69,10 @@ EMP_EXTEND_CONFIG(SymConfigSGP, SymConfigBase, VALUE(SYM_ONLY_FIRST_TASK_CREDIT, bool, false, "Only give sym credit for one task (whatever they do first)?"), GROUP(TEMP_CHANGING_ENVIRONMENT, "Temporally changing environment settings (task rewards change over time)"), - VALUE(ENABLE_TEMP_CHANGING_ENVIRONMENT, bool, false, "Do task reward values change over time?"), + VALUE(ENABLE_TEMP_CHANGING_ENVIRONMENT, size_t, 0, "Do task reward values change over time? 0 for off, 1 for consitenet, 2 for random"), VALUE(TEMP_CHANGING_ENVIRONMENT_INTERVAL, size_t, 100, "How many updates elapse between task reward value shuffling?"), VALUE(TEMP_CHANGING_ENVIRONMENT_ORG_TYPE, std::string, "static", "Can organisms sense task reward values? (plastic-both: both symbionts and hosts can sense whether tasks are rewarded; static: neither hosts nor symbiont can sense whether tasks are rewarded)"), + VALUE(RANDOM_CHANGING_ENVIRONMENT_AVERAGE, size_t, 100, "On average how often should the random environment change?"), GROUP(DATA, "Data settings"), VALUE(PRINT_INTERVAL, size_t, 1, "How often to print run status") diff --git a/source/sgp_mode/SGPHost.h b/source/sgp_mode/SGPHost.h index 902b54a0..7ea52778 100644 --- a/source/sgp_mode/SGPHost.h +++ b/source/sgp_mode/SGPHost.h @@ -13,6 +13,8 @@ #include + + namespace sgpmode { template @@ -137,6 +139,10 @@ class SGPHost : public Host { // } } + void HostDoMutation(this_t& host) { + my_world->getMutator().MutateProgram(host.GetProgram()); + } + bool operator<(const Organism& other) const { if (const SGPHost* sgp = dynamic_cast(&other)) { return GetProgram() < sgp->GetProgram(); @@ -169,7 +175,7 @@ class SGPHost : public Host { * * Purpose: To set the count of reproductions in this lineage. */ - void SetReproCount(size_t _in) { reproductions = _in; } + void LineageLength(size_t _in) { reproductions = _in; } void SetLocation(emp::WorldPosition pos) { hardware.GetCPUState().SetLocation(pos); @@ -494,7 +500,7 @@ class SGPHost : public Host { auto& offspring_cpu_state = offspring_hw.GetCPUState(); auto& cpu_state = hardware.GetCPUState(); - host_offspring->SetReproCount(reproductions + 1); + host_offspring->LineageLength(reproductions + 1); cpu_state.SetCPUCyclesSinceRepro(0); offspring_cpu_state.SetCPUCyclesSinceRepro(0); // Offspring needs to be given parent's (this) task profile @@ -527,7 +533,7 @@ class SGPHost : public Host { cpu_state.GetLineageTaskGainCount(task_id) + (size_t)task_gain ); offspring_cpu_state.SetLineageTaskLossCount( - task_id, + task_id, cpu_state.GetLineageTaskLossCount(task_id) + (size_t)task_loss ); @@ -593,7 +599,7 @@ class SGPHost : public Host { // to deviate from what happens in the base class mutate functions Host::Mutate(); // Apply SGP-specific mutations (managed by world) - my_world->HostDoMutation(*this); + HostDoMutation(*this); // TODO - Switch from HostDoMutation() to: // -> my_world->GetHostMutator().DoMutation(*this); // TODO - move Hardware Reset to makenew, keep initializeState (need to reset jumptable) diff --git a/source/sgp_mode/SGPSymbiont.h b/source/sgp_mode/SGPSymbiont.h index 18668c34..cf819cbf 100644 --- a/source/sgp_mode/SGPSymbiont.h +++ b/source/sgp_mode/SGPSymbiont.h @@ -334,6 +334,9 @@ class SGPSymbiont : public Symbiont { } } + void SymDoMutation(this_t& sym) { + my_world->getMutator().MutateProgram(sym.GetProgram()); + } /** * Input: None @@ -440,7 +443,7 @@ class SGPSymbiont : public Symbiont { // to deviate from what happens in the base class mutate functions Symbiont::Mutate(); // Apply SGP-specific mutations (managed by world) - my_world->SymDoMutation(*this); + SymDoMutation(*this); // Reset host's hardware hardware.Reset(); // NOTE - this function was previously just Initializing state, // which didn't reset the cpu. I think we want to reset the CPU here also? diff --git a/source/sgp_mode/SGPWorld.cc b/source/sgp_mode/SGPWorld.cc index 03c7c974..b2ecaa19 100644 --- a/source/sgp_mode/SGPWorld.cc +++ b/source/sgp_mode/SGPWorld.cc @@ -382,12 +382,8 @@ void SGPWorld::ProcessSymOutputBuffer(sgp_sym_t& sym) { output_buffer.clear(); } -void SGPWorld::HostDoMutation(sgp_host_t& host) { - mutator.MutateProgram(host.GetProgram()); -} - -void SGPWorld::SymDoMutation(sgp_sym_t& sym) { - mutator.MutateProgram(sym.GetProgram()); +SGPWorld::mutator_t SGPWorld::getMutator(){ + return mutator; } void SGPWorld::SymDonateToHost(Organism& from_sym, Organism& to_host) { diff --git a/source/sgp_mode/SGPWorld.h b/source/sgp_mode/SGPWorld.h index 5d26a512..3a2bc66b 100644 --- a/source/sgp_mode/SGPWorld.h +++ b/source/sgp_mode/SGPWorld.h @@ -375,6 +375,8 @@ class SGPWorld : public SymWorld { sgp_sym_t& sym ); + bool CheckRandomEnvironment(); + protected: Scheduler scheduler; // Manages order that world locations (organisms) are processed each update @@ -680,6 +682,8 @@ class SGPWorld : public SymWorld { return fun_calc_host_nutrient_interaction(host,sym, task_value_before, task_id,task_matching_sym_count); } + mutator_t getMutator(); + /** * Input: A host, a symbiont, the value of a task before applying nutrient interaction, and the task id. * Output: The amount of points that the symbiont will gain/lose after the nutrient interaction. @@ -908,8 +912,7 @@ class SGPWorld : public SymWorld { emp::WorldPosition parent_pos ) override; - void HostDoMutation(sgp_host_t& host); - void SymDoMutation(sgp_sym_t& sym); + void SymDonateToHost(Organism& from_sym, Organism& to_host); void SymStealFromHost(Organism& to_sym, Organism& from_host); diff --git a/source/sgp_mode/SGPWorldSetup.cc b/source/sgp_mode/SGPWorldSetup.cc index 3fd95371..f7de3d68 100644 --- a/source/sgp_mode/SGPWorldSetup.cc +++ b/source/sgp_mode/SGPWorldSetup.cc @@ -87,7 +87,7 @@ void SGPWorld::Setup() { ); } - if (sgp_config.ENABLE_TEMP_CHANGING_ENVIRONMENT()) { + if (sgp_config.ENABLE_TEMP_CHANGING_ENVIRONMENT() > 0) { SetupChangingEnvironment(); } @@ -154,6 +154,23 @@ void SGPWorld::SetupChangingEnvironment() { or_task_id = task_env.GetTaskSet().GetID("or"); } + size_t nor_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("NOR")) { + nor_task_id = task_env.GetTaskSet().GetID("NOR"); + } + else if (task_env.GetTaskSet().HasTask("nor")) { + nor_task_id = task_env.GetTaskSet().GetID("nor"); + } + + size_t xor_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("XOR")) { + xor_task_id = task_env.GetTaskSet().GetID("XOR"); + } + else if (task_env.GetTaskSet().HasTask("xor")) { + xor_task_id = task_env.GetTaskSet().GetID("xor"); + } + + // update 0 will flip nand-andn-orn to rewarded and not-and-or to punished GetTaskEnv().GetHostTaskReq(nand_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(nand_task_id).task_value; GetTaskEnv().GetSymTaskReq(nand_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(nand_task_id).task_value; @@ -164,32 +181,44 @@ void SGPWorld::SetupChangingEnvironment() { GetTaskEnv().GetHostTaskReq(orn_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(orn_task_id).task_value; GetTaskEnv().GetSymTaskReq(orn_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(orn_task_id).task_value; + GetTaskEnv().GetHostTaskReq(xor_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(xor_task_id).task_value; + GetTaskEnv().GetSymTaskReq(xor_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(xor_task_id).task_value; + begin_update_sig.AddAction( - [this, nand_task_id, andn_task_id, orn_task_id, not_task_id, and_task_id, or_task_id]() { - if (GetUpdate() % sgp_config.TEMP_CHANGING_ENVIRONMENT_INTERVAL() == 0) { + [this, nand_task_id, andn_task_id, orn_task_id, not_task_id, and_task_id, or_task_id, xor_task_id, nor_task_id]() { + if (((sgp_config.ENABLE_TEMP_CHANGING_ENVIRONMENT() == 1) && (GetUpdate() % sgp_config.TEMP_CHANGING_ENVIRONMENT_INTERVAL() == 0)) || ((sgp_config.ENABLE_TEMP_CHANGING_ENVIRONMENT() == 2) && CheckRandomEnvironment())) { GetTaskEnv().GetHostTaskReq(nand_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(nand_task_id).task_value; GetTaskEnv().GetHostTaskReq(andn_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(andn_task_id).task_value; GetTaskEnv().GetHostTaskReq(orn_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(orn_task_id).task_value; + GetTaskEnv().GetHostTaskReq(xor_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(xor_task_id).task_value; GetTaskEnv().GetHostTaskReq(not_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(not_task_id).task_value; GetTaskEnv().GetHostTaskReq(and_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(and_task_id).task_value; GetTaskEnv().GetHostTaskReq(or_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(or_task_id).task_value; + GetTaskEnv().GetHostTaskReq(nor_task_id).task_value = -1 * GetTaskEnv().GetHostTaskReq(nor_task_id).task_value; GetTaskEnv().GetSymTaskReq(nand_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(nand_task_id).task_value; GetTaskEnv().GetSymTaskReq(andn_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(andn_task_id).task_value; GetTaskEnv().GetSymTaskReq(orn_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(orn_task_id).task_value; + GetTaskEnv().GetSymTaskReq(xor_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(xor_task_id).task_value; GetTaskEnv().GetSymTaskReq(not_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(not_task_id).task_value; GetTaskEnv().GetSymTaskReq(and_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(and_task_id).task_value; GetTaskEnv().GetSymTaskReq(or_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(or_task_id).task_value; - + GetTaskEnv().GetSymTaskReq(nor_task_id).task_value = -1 * GetTaskEnv().GetSymTaskReq(nor_task_id).task_value; } } ); } +//Checks if the random environment switches or not +bool SGPWorld::CheckRandomEnvironment(){ + bool environment_change = random_ptr->P(1.0/sgp_config.RANDOM_CHANGING_ENVIRONMENT_AVERAGE()); + return (environment_change == true || GetUpdate() == 0); +} + void SGPWorld::DisableConfigurableInstructions() { // Knock out any mode-related instructions that shouldn't be active for this run diff --git a/source/test/sgp_mode_test/functional_tests/TempChangingEnvironments.test.cc b/source/test/sgp_mode_test/functional_tests/TempChangingEnvironments.test.cc index 61f15bb7..9a7c19b3 100644 --- a/source/test/sgp_mode_test/functional_tests/TempChangingEnvironments.test.cc +++ b/source/test/sgp_mode_test/functional_tests/TempChangingEnvironments.test.cc @@ -100,6 +100,7 @@ TEST_CASE("Symbionts start with a poisoned task in a temporally changing environ // Group 1: NOT, AND, OR (start rewarded) size_t not_task_id = world.GetTaskEnv().GetTaskSet().GetID("NOT"); + WHEN("A symbiont can do only NOT at the start of the experiment"){ // NOT-only symbiont @@ -209,8 +210,10 @@ TEST_CASE("Symbionts start with a rewarded task in a temporally changing environ world.Setup(); auto& builder = world.GetProgramBuilder(); + // Group 2: NAND, AND-NOT, OR-NOT (start punished) size_t nand_task_id = world.GetTaskEnv().GetTaskSet().GetID("NAND"); + WHEN("A symbiont can do only NAND at the start of the experiment"){ // NAND-only symbiont @@ -246,3 +249,189 @@ TEST_CASE("Symbionts start with a rewarded task in a temporally changing environ } } } + + +TEST_CASE("Check if tasks values are switching correctly with a enviornment change", "[sgp]") { + // set up configs + sgpmode::SymConfigSGP config; + config.TASK_ENV_CFG_PATH("source/test/sgp_mode_test/hardware-test-env.json"); + config.FILE_PATH("TempChangingEnv_test_output"); + config.SEED(89); + test_utils::SetWellMixed(config, 4, 0); + config.TASK_IO_BANK_SIZE(10); + config.CYCLES_PER_UPDATE(8); + config.ENABLE_TEMP_CHANGING_ENVIRONMENT(1); + config.TEMP_CHANGING_ENVIRONMENT_INTERVAL(1); + + // initialize world + emp::Random random(config.SEED()); + world_t world(random, &config); + world.Setup(); + auto& builder = world.GetProgramBuilder(); + + sgpmode::SGPWorld::task_env_t& task_env = world.GetTaskEnv(); + //get the ids for all of the tasks + size_t nand_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("NAND")) { + nand_task_id = task_env.GetTaskSet().GetID("NAND"); + } + else if (task_env.GetTaskSet().HasTask("nand")) { + nand_task_id = task_env.GetTaskSet().GetID("nand"); + } + + size_t andn_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("AND_NOT")) { + andn_task_id = task_env.GetTaskSet().GetID("AND_NOT"); + } + else if (task_env.GetTaskSet().HasTask("and_not")) { + andn_task_id = task_env.GetTaskSet().GetID("and_not"); + } + + size_t orn_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("OR_NOT")) { + orn_task_id = task_env.GetTaskSet().GetID("OR_NOT"); + } + else if (task_env.GetTaskSet().HasTask("or_not")) { + orn_task_id = task_env.GetTaskSet().GetID("or_not"); + } + + size_t not_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("NOT")) { + not_task_id = task_env.GetTaskSet().GetID("NOT"); + } + else if (task_env.GetTaskSet().HasTask("not")) { + not_task_id = task_env.GetTaskSet().GetID("not"); + } + + size_t and_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("AND")) { + and_task_id = task_env.GetTaskSet().GetID("AND"); + } + else if (task_env.GetTaskSet().HasTask("and")) { + and_task_id = task_env.GetTaskSet().GetID("and"); + } + + size_t or_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("OR")) { + or_task_id = task_env.GetTaskSet().GetID("OR"); + } + else if (task_env.GetTaskSet().HasTask("or")) { + or_task_id = task_env.GetTaskSet().GetID("or"); + } + + size_t nor_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("NOR")) { + nor_task_id = task_env.GetTaskSet().GetID("NOR"); + } + else if (task_env.GetTaskSet().HasTask("nor")) { + nor_task_id = task_env.GetTaskSet().GetID("nor"); + } + + size_t xor_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("XOR")) { + xor_task_id = task_env.GetTaskSet().GetID("XOR"); + } + else if (task_env.GetTaskSet().HasTask("xor")) { + xor_task_id = task_env.GetTaskSet().GetID("xor"); + } + + WHEN("the world is initialized"){ + world.Update(); + + THEN("NAND, ANDN, ORN, and XOR should be rewarded and NOT, AND, OR, NOR punished"){ + REQUIRE(task_env.GetHostTaskReq(nand_task_id).task_value == 5); + REQUIRE(task_env.GetHostTaskReq(andn_task_id).task_value == 5); + REQUIRE(task_env.GetHostTaskReq(orn_task_id).task_value == 5); + REQUIRE(task_env.GetHostTaskReq(xor_task_id).task_value == 5); + + REQUIRE(task_env.GetHostTaskReq(not_task_id).task_value == -5); + REQUIRE(task_env.GetHostTaskReq(and_task_id).task_value == -5); + REQUIRE(task_env.GetHostTaskReq(or_task_id).task_value == -5); + REQUIRE(task_env.GetHostTaskReq(nor_task_id).task_value == -5); + + REQUIRE(task_env.GetSymTaskReq(nand_task_id).task_value == 5); + REQUIRE(task_env.GetSymTaskReq(andn_task_id).task_value == 5); + REQUIRE(task_env.GetSymTaskReq(orn_task_id).task_value == 5); + REQUIRE(task_env.GetSymTaskReq(xor_task_id).task_value == 5); + + REQUIRE(task_env.GetSymTaskReq(not_task_id).task_value == -5); + REQUIRE(task_env.GetSymTaskReq(and_task_id).task_value == -5); + REQUIRE(task_env.GetSymTaskReq(or_task_id).task_value == -5); + REQUIRE(task_env.GetSymTaskReq(nor_task_id).task_value == -5); + } + + //update world once to swap enviornment + world.Update(); + + THEN("The rewarded tasks should be punished now, and the punished tasks should be rewarded"){ + REQUIRE(task_env.GetHostTaskReq(nand_task_id).task_value == -5); + REQUIRE(task_env.GetHostTaskReq(andn_task_id).task_value == -5); + REQUIRE(task_env.GetHostTaskReq(orn_task_id).task_value == -5); + REQUIRE(task_env.GetHostTaskReq(xor_task_id).task_value == -5); + + REQUIRE(task_env.GetHostTaskReq(not_task_id).task_value == 5); + REQUIRE(task_env.GetHostTaskReq(and_task_id).task_value == 5); + REQUIRE(task_env.GetHostTaskReq(or_task_id).task_value == 5); + REQUIRE(task_env.GetHostTaskReq(nor_task_id).task_value == 5); + + REQUIRE(task_env.GetSymTaskReq(nand_task_id).task_value == -5); + REQUIRE(task_env.GetSymTaskReq(andn_task_id).task_value == -5); + REQUIRE(task_env.GetSymTaskReq(orn_task_id).task_value == -5); + REQUIRE(task_env.GetSymTaskReq(xor_task_id).task_value == -5); + + REQUIRE(task_env.GetSymTaskReq(not_task_id).task_value == 5); + REQUIRE(task_env.GetSymTaskReq(and_task_id).task_value == 5); + REQUIRE(task_env.GetSymTaskReq(or_task_id).task_value == 5); + REQUIRE(task_env.GetSymTaskReq(nor_task_id).task_value == 5); + } + + } + + } + +TEST_CASE("Check if random enviornment change works", "[sgp]") { + // set up configs + sgpmode::SymConfigSGP config; + config.TASK_ENV_CFG_PATH("source/test/sgp_mode_test/hardware-test-env.json"); + config.FILE_PATH("TempChangingEnv_test_output"); + config.SEED(89); + test_utils::SetWellMixed(config, 4, 0); + config.TASK_IO_BANK_SIZE(10); + config.CYCLES_PER_UPDATE(8); + config.ENABLE_TEMP_CHANGING_ENVIRONMENT(2); + config.RANDOM_CHANGING_ENVIRONMENT_AVERAGE(2); + + // initialize world + emp::Random random(config.SEED()); + world_t world(random, &config); + world.Setup(); + auto& builder = world.GetProgramBuilder(); + + bool Env_change = false; + + WHEN("the world is initialized"){ + world.Update(); + sgpmode::SGPWorld::task_env_t& task_env = world.GetTaskEnv(); + + //get the ids for all of the tasks + size_t nand_task_id = task_env.GetTaskSet().GetSize(); + if (task_env.GetTaskSet().HasTask("NAND")) { + nand_task_id = task_env.GetTaskSet().GetID("NAND"); + } + + //update the world 4 times (should have changed at least once by now) + for (int i = 1; i <= 4; i++) { + world.Update(); + if(task_env.GetHostTaskReq(nand_task_id).task_value == -5){ + Env_change = true; + } + } + + THEN("Task reward values should have swapped at least once"){ + REQUIRE(Env_change); + } + + } + +} + diff --git a/source/test/sgp_mode_test/unit_tests/SGPHost.test.cc b/source/test/sgp_mode_test/unit_tests/SGPHost.test.cc index 79401dca..d1fdb38b 100644 --- a/source/test/sgp_mode_test/unit_tests/SGPHost.test.cc +++ b/source/test/sgp_mode_test/unit_tests/SGPHost.test.cc @@ -217,7 +217,7 @@ TEST_CASE("MakeNew returns identical host", "[sgp][sgp-unit]") { } } -TEST_CASE("SetReproCount & GetReproCount","[sgp][sgp-unit]") { +TEST_CASE("LineageLength & GetReproCount","[sgp][sgp-unit]") { using world_t = sgpmode::SGPWorld; using cpu_state_t = sgpmode::CPUState; using hw_spec_t = sgpmode::SGPHardwareSpec; @@ -240,7 +240,7 @@ TEST_CASE("SetReproCount & GetReproCount","[sgp][sgp-unit]") { REQUIRE(host->GetReproCount() == 0); } WHEN("The host's repro count is increased by 1") { - host->SetReproCount(1); + host->LineageLength(1); THEN("Repro count of the host is 1") { REQUIRE(host->GetReproCount() == 1); }