Skip to content

Commit fb4a646

Browse files
committed
+Inherit free energy provision from parent in case that offspring constructs a non-separating gene
+ Creature tests corrected
1 parent 4c28d53 commit fb4a646

2 files changed

Lines changed: 47 additions & 22 deletions

File tree

source/EngineGpuKernels/ConstructorProcessor.cuh

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,15 @@ __inline__ __device__ Cell* ConstructorProcessor::startConstructionOnNewBranch(
375375
return nullptr;
376376
}
377377

378+
// For bending muscle cells: Reset front angle and restore initial angle
379+
for (int i = 0; i < hostCell->numConnections; ++i) {
380+
auto const& connectedCell = hostCell->connections[i].cell;
381+
if (connectedCell->cellType == CellType_Muscle && connectedCell->cellTypeData.muscle.isBendingMuscle()) {
382+
connectedCell->frontAngle = VALUE_NOT_SET_FLOAT;
383+
MuscleProcessor::restoreInitialAngleFromPrevious(connectedCell, hostCell, i);
384+
}
385+
}
386+
378387
uint64_t cellPointerIndex;
379388
Cell* newCell = constructCellIntern(data, statistics, cellPointerIndex, hostCell, newCellPos, constructionData);
380389

@@ -738,8 +747,17 @@ ConstructorProcessor::constructCellIntern(
738747
result->frontAngleId = hostCell->frontAngleId;
739748

740749
constructor.lastConstructedCellId = result->id;
750+
751+
// Inherit free energy provision from parent in case that offspring constructs a non-separating gene
741752
if (constructor.provideEnergy == ProvideEnergy_FreeGeneration && result->cellType == CellType_Constructor) {
742-
result->cellTypeData.constructor.provideEnergy = ProvideEnergy_FreeGeneration;
753+
auto const& offspringConstructor = result->cellTypeData.constructor;
754+
auto const& offspringGenome = constructionData.creature->genome;
755+
if (offspringConstructor.geneIndex < offspringGenome.numGenes) {
756+
auto const& offspringGene = offspringGenome.genes[offspringConstructor.geneIndex];
757+
if (!offspringGene.separation) {
758+
result->cellTypeData.constructor.provideEnergy = ProvideEnergy_FreeGeneration;
759+
}
760+
}
743761
}
744762

745763
statistics.incNumCreatedCells(hostCell->color);

source/EngineTests/CreatureTests.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class CreatureTests : public IntegrationTestFramework
4848
? GeneratorGenomeDescription().autoTriggerInterval(15)
4949
: GeneratorGenomeDescription().pulseType(GeneratorPulseType_Alternation).autoTriggerInterval(15).alternationInterval(20);
5050
return GenomeDescription().genes({
51-
GeneDescription().separation(false).nodes({
51+
GeneDescription().separation(true).nodes({
5252
NodeDescription().cellType(generator),
5353
NodeDescription(),
5454
NodeDescription(),
@@ -73,9 +73,16 @@ class CreatureTests : public IntegrationTestFramework
7373
.genes({
7474
GeneDescription().separation(false).nodes({
7575
NodeDescription().cellType(generator),
76+
NodeDescription(),
77+
NodeDescription(),
78+
NodeDescription(),
7679
NodeDescription().cellType(muscleDesc),
7780
NodeDescription().cellType(muscleDesc),
7881
NodeDescription().cellType(muscleDesc),
82+
NodeDescription(),
83+
NodeDescription(),
84+
NodeDescription(),
85+
NodeDescription(),
7986
}),
8087
});
8188
}
@@ -95,16 +102,22 @@ TEST_P(CreatureTests_BendingMuscles, constructCreatureWithLegs)
95102
{
96103
auto muscleMode = GetParam();
97104

98-
auto neededEnergy = (1 + 4 + 4 + 6) * _parameters.normalCellEnergy.value[0] + 1.0f;
99105
auto genome = createGenomeForCreatureWithLegs(muscleMode, Direction::Forward);
100106
auto data = Description().creatures({
101-
CreatureDescription().genome(genome).cells({CellDescription().id(0).energy(neededEnergy).pos({200.0f, 200.0f}).cellType(ConstructorDescription().geneIndex(0))}),
107+
CreatureDescription().genome(genome).cells(
108+
{CellDescription().id(0).pos({200.0f, 200.0f}).cellType(ConstructorDescription().provideEnergy(ProvideEnergy_FreeGeneration).geneIndex(0))}),
102109
});
103110

104111
_simulationFacade->setSimulationData(data);
105112
_simulationFacade->calcTimesteps(2000);
106113

107114
auto actualData = _simulationFacade->getSimulationData();
115+
116+
// Check that the seed provides no energy anymore after the creature is constructed
117+
auto constructor = std::get<ConstructorDescription>(actualData.getCellRef(0)._cellType);
118+
if (genome._genes[constructor._geneIndex]._separation) {
119+
EXPECT_EQ(ProvideEnergy_CellOnly, constructor._provideEnergy);
120+
}
108121
DescriptionEditService::get().removeCell(actualData, 0);
109122
ASSERT_EQ(1, actualData._creatures.size());
110123

@@ -250,31 +263,28 @@ TEST_P(CreatureTests_CrawlingMuscles, constructCrawlingCreature)
250263

251264
auto genome = createGenomeForCrawlingCreature(muscleMode, Direction::Forward, 0.0f);
252265
auto data = Description().creatures({
253-
CreatureDescription().genome(genome).cells({CellDescription().id(0).pos({200.0f, 200.0f}).cellType(ConstructorDescription().geneIndex(0))}),
266+
CreatureDescription().genome(genome).cells(
267+
{CellDescription().id(0).pos({200.0f, 200.0f}).cellType(ConstructorDescription().provideEnergy(ProvideEnergy_FreeGeneration).geneIndex(0))}),
254268
});
255269

256-
_parameters.externalEnergyControlToggle.value = true;
257-
_parameters.externalEnergy.value = 4 * _parameters.normalCellEnergy.value[0] + 10.0f;
258-
_simulationFacade->setSimulationParameters(_parameters);
259-
260270
_simulationFacade->setSimulationData(data);
261-
_simulationFacade->calcTimesteps(500);
271+
_simulationFacade->calcTimesteps(1300);
262272

263273
auto actualData = _simulationFacade->getSimulationData();
264274
DescriptionEditService::get().removeCell(actualData, 0);
265275
ASSERT_EQ(1, actualData._creatures.size());
266276

267277
auto creature = actualData._creatures.front();
268-
ASSERT_EQ(4, creature._cells.size());
278+
ASSERT_EQ(11, creature._cells.size());
269279

270280
auto& cells = creature._cells;
271281
std::ranges::sort(cells, [](auto const& left, auto const& right) { return left._id < right._id; });
272282

273283
// Check front angles
274284
EXPECT_TRUE(approxCompareAngles(0.0f, cells.at(0)._frontAngle.value()));
275-
EXPECT_TRUE(approxCompareAngles(180.0f, cells.at(1)._frontAngle.value()));
276-
EXPECT_TRUE(approxCompareAngles(180.0f, cells.at(2)._frontAngle.value()));
277-
EXPECT_TRUE(approxCompareAngles(180.0f, cells.at(3)._frontAngle.value()));
285+
for (int i = 1; i < 11; ++i) {
286+
EXPECT_TRUE(approxCompareAngles(180.0f, cells.at(i)._frontAngle.value()));
287+
}
278288
}
279289

280290
class CreatureTests_CrawlingMuscles_TwoDirections_DifferentFrontAngles
@@ -303,15 +313,12 @@ TEST_P(CreatureTests_CrawlingMuscles_TwoDirections_DifferentFrontAngles, moveCra
303313

304314
auto genome = createGenomeForCrawlingCreature(muscleMode, direction, frontAngle);
305315
auto data = Description().creatures({
306-
CreatureDescription().genome(genome).cells({CellDescription().id(0).pos(refPoint).cellType(ConstructorDescription().geneIndex(0))}),
316+
CreatureDescription().genome(genome).cells(
317+
{CellDescription().id(0).pos(refPoint).cellType(ConstructorDescription().provideEnergy(ProvideEnergy_FreeGeneration).geneIndex(0))}),
307318
});
308319

309-
_parameters.externalEnergyControlToggle.value = true;
310-
_parameters.externalEnergy.value = 4 * _parameters.normalCellEnergy.value[0] + 10.0f;
311-
_simulationFacade->setSimulationParameters(_parameters);
312-
313320
_simulationFacade->setSimulationData(data);
314-
_simulationFacade->calcTimesteps(1000);
321+
_simulationFacade->calcTimesteps(1300);
315322

316323
RealVector2D movementDirection;
317324
{
@@ -323,7 +330,7 @@ TEST_P(CreatureTests_CrawlingMuscles_TwoDirections_DifferentFrontAngles, moveCra
323330
ASSERT_EQ(1, actualData._creatures.size());
324331

325332
auto creature = actualData._creatures.front();
326-
ASSERT_EQ(4, creature._cells.size());
333+
ASSERT_EQ(11, creature._cells.size());
327334

328335
auto& cells = creature._cells;
329336
std::ranges::sort(cells, [](auto const& left, auto const& right) { return left._id < right._id; });
@@ -344,7 +351,7 @@ TEST_P(CreatureTests_CrawlingMuscles_TwoDirections_DifferentFrontAngles, moveCra
344351
ASSERT_EQ(1, actualData._creatures.size());
345352

346353
auto creature = actualData._creatures.front();
347-
ASSERT_EQ(4, creature._cells.size());
354+
ASSERT_EQ(11, creature._cells.size());
348355

349356
auto& cells = creature._cells;
350357
std::ranges::sort(cells, [](auto const& left, auto const& right) { return left._id < right._id; });

0 commit comments

Comments
 (0)