test: cover testEndGen

This commit is contained in:
dualfroz committed 2026-09-11 17:58:41 +02:00
1 parent 04c01edcbc
commit 60fc109ba6
1 file changed
+198
+198
View File
@@ -154,3 +154,201 @@ VF_TEST(obsidianPillarsRingTheCentreDeterministically) {
CHECK_EQ(ring.size(), static_cast<std::size_t>(params.pillarCount)); CHECK_EQ(ring.size(), static_cast<std::size_t>(params.pillarCount));
CHECK_EQ(again.size(), ring.size()); CHECK_EQ(again.size(), ring.size());
std::set<int> heights;
int crowned = 0;
for (std::size_t index = 0; index < ring.size(); ++index) {
const ObsidianPillar& pillar = ring[index];
CHECK_EQ(pillar.base.x, again[index].base.x);
CHECK_EQ(pillar.base.z, again[index].base.z);
CHECK_EQ(pillar.height, again[index].height);
float distance = distanceFromOrigin(pillar.base.x, pillar.base.z);
CHECK(distance > static_cast<float>(params.pillarRing) - 6.0f);
CHECK(distance < static_cast<float>(params.pillarRing) + 6.0f);
CHECK(pillar.radius >= 1 && pillar.radius <= 3);
CHECK(pillar.base.y + pillar.height < params.ceilingY - 1);
heights.insert(pillar.height);
if (pillar.crowned) ++crowned;
}
CHECK(heights.size() > 1);
CHECK(crowned > 0);
}
VF_TEST(pillarsAreStampedIntoTheGeneratedWorld) {
EndGenerator generator;
World world;
for (int columnX = -4; columnX <= 4; ++columnX)
for (int columnZ = -4; columnZ <= 4; ++columnZ)
generator.generateColumn(world, columnX, columnZ);
ObsidianPillar pillar = generator.pillars().front();
CHECK_EQ(world.blockAt(pillar.base.x, pillar.base.y, pillar.base.z), Block::Obsidian);
CHECK_EQ(world.blockAt(pillar.base.x, pillar.base.y + pillar.height, pillar.base.z),
Block::Obsidian);
CHECK_EQ(world.blockAt(pillar.base.x, pillar.base.y + pillar.height + 2, pillar.base.z),
Block::Air);
}
VF_TEST(exitPortalSitsAtTheOriginOfTheCentralIsland) {
EndGenerator generator;
World world;
for (int columnX = -1; columnX <= 0; ++columnX)
for (int columnZ = -1; columnZ <= 0; ++columnZ)
generator.generateColumn(world, columnX, columnZ);
int surface = generator.surfaceHeight(0, 0);
CHECK_EQ(world.blockAt(0, surface, 0), Block::EndPortal);
CHECK_EQ(world.blockAt(1, surface, 1), Block::EndPortal);
CHECK_EQ(world.blockAt(2, surface, 0), Block::Bedrock);
CHECK_EQ(world.blockAt(0, surface - 1, 0), Block::Bedrock);
CHECK_EQ(world.blockAt(-2, surface + 1, -2), Block::Bedrock);
CHECK_EQ(world.blockAt(0, surface + 1, 0), Block::Air);
int portalCells = 0;
for (int dx = -2; dx <= 2; ++dx)
for (int dz = -2; dz <= 2; ++dz)
if (world.blockAt(dx, surface, dz) == Block::EndPortal) ++portalCells;
CHECK_EQ(portalCells, 9);
}
VF_TEST(exitPortalCanBeSwitchedOff) {
EndGenerator::Params bare;
bare.exitPortal = false;
EndGenerator generator(bare);
World world;
generator.generateColumn(world, 0, 0);
CHECK_EQ(world.blockAt(0, generator.surfaceHeight(0, 0), 0), Block::EndStone);
}
VF_TEST(chorusGrowsAStemWithBranchesAndFlowers) {
EndGenerator generator;
World world;
world.setBlock(0, 50, 0, Block::EndStone);
int written = generator.growChorus(world, {0, 51, 0}, 4711u, 3);
CHECK(written > 3);
int stems = 0;
int flowers = 0;
int highest = 50;
int widest = 0;
for (int gx = -8; gx <= 8; ++gx) {
for (int gz = -8; gz <= 8; ++gz) {
for (int gy = 50; gy < 90; ++gy) {
Block block = world.blockAt(gx, gy, gz);
if (block != Block::ChorusPlant && block != Block::ChorusFlower) continue;
if (block == Block::ChorusPlant) ++stems;
else ++flowers;
if (gy > highest) highest = gy;
int reach = std::abs(gx) > std::abs(gz) ? std::abs(gx) : std::abs(gz);
if (reach > widest) widest = reach;
}
}
}
CHECK_EQ(stems + flowers, written);
CHECK(stems > 0);
CHECK(flowers > 0);
CHECK(highest > 51);
CHECK(widest > 0);
CHECK(widest <= 3);
}
VF_TEST(chorusGrowthIsRepeatableAndBoundedByItsDepth) {
EndGenerator generator;
World first, second;
first.setBlock(0, 50, 0, Block::EndStone);
second.setBlock(0, 50, 0, Block::EndStone);
int written = generator.growChorus(first, {0, 51, 0}, 88u, 3);
CHECK_EQ(generator.growChorus(second, {0, 51, 0}, 88u, 3), written);
int differences = 0;
for (int gx = -8; gx <= 8; ++gx)
for (int gz = -8; gz <= 8; ++gz)
for (int gy = 50; gy < 90; ++gy)
if (first.blockAt(gx, gy, gz) != second.blockAt(gx, gy, gz)) ++differences;
CHECK_EQ(differences, 0);
World shallow;
shallow.setBlock(0, 50, 0, Block::EndStone);
int small = generator.growChorus(shallow, {0, 51, 0}, 88u, 1);
CHECK(small > 0);
CHECK(small < written);
int shallowTop = 50;
for (int gy = 50; gy < 90; ++gy)
if (shallow.blockAt(0, gy, 0) != Block::Air) shallowTop = gy;
CHECK(shallowTop <= 54);
}
VF_TEST(chorusRefusesAnythingButEndStoneUnderneath) {
EndGenerator generator;
World world;
CHECK_EQ(generator.growChorus(world, {0, 51, 0}, 1u, 3), 0);
world.setBlock(0, 50, 0, Block::Obsidian);
CHECK_EQ(generator.growChorus(world, {0, 51, 0}, 1u, 3), 0);
world.setBlock(0, 50, 0, Block::EndStone);
world.setBlock(0, 51, 0, Block::Purpur);
CHECK_EQ(generator.growChorus(world, {0, 51, 0}, 1u, 3), 0);
}
VF_TEST(outerIslandsOnlyAppearBeyondTheDistanceThreshold) {
EndGenerator generator;
int islandX = 0;
int islandZ = 0;
CHECK(locateOuterIsland(generator, islandX, islandZ));
CHECK(distanceFromOrigin(islandX, islandZ) >=
static_cast<float>(generator.settings().outerDistance));
CHECK_EQ(generator.biomeAt(islandX, islandZ), EndBiome::OuterIsland);
CHECK(!generator.islandAt(islandX, islandZ).central);
CHECK(generator.islandAt(islandX, islandZ).radius > 0.0f);
}
VF_TEST(outerIslandsCarryChorusAndPurpur) {
EndGenerator generator;
int islandX = 0;
int islandZ = 0;
CHECK(locateOuterIsland(generator, islandX, islandZ));
World world;
int columnX = floorDiv(islandX, chunkSize);
int columnZ = floorDiv(islandZ, chunkSize);
for (int dx = -1; dx <= 1; ++dx)
for (int dz = -1; dz <= 1; ++dz)
generator.generateColumn(world, columnX + dx, columnZ + dz);
int minX = (columnX - 1) * chunkSize;
int minZ = (columnZ - 1) * chunkSize;
int endStone = tallyBlocks(world, Block::EndStone, minX, minZ, chunkSize * 3, 128);
int chorusStems = tallyBlocks(world, Block::ChorusPlant, minX, minZ, chunkSize * 3, 128);
int chorusFlowers = tallyBlocks(world, Block::ChorusFlower, minX, minZ, chunkSize * 3, 128);
CHECK(endStone > 1000);
CHECK(chorusStems > 0);
CHECK(chorusFlowers > 0);
// Nothing from the central island's furniture leaks out here.
CHECK_EQ(tallyBlocks(world, Block::EndPortal, minX, minZ, chunkSize * 3, 128), 0);
CHECK_EQ(tallyBlocks(world, Block::Obsidian, minX, minZ, chunkSize * 3, 128), 0);
}
VF_TEST(endGenerationStaysInsideTheColumnItWasAskedFor) {
EndGenerator generator;
int islandX = 0;
int islandZ = 0;
CHECK(locateOuterIsland(generator, islandX, islandZ));
World world;
int columnX = floorDiv(islandX, chunkSize);
int columnZ = floorDiv(islandZ, chunkSize);
generator.generateColumn(world, columnX, columnZ);
int strays = 0;
for (const auto& entry : world.allChunks())
if (entry.first.x != columnX || entry.first.z != columnZ) ++strays;
CHECK_EQ(strays, 0);
}