Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions Fission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ namespace Fission {
rules(xt::empty<int>({settings.sizeX, settings.sizeY, settings.sizeZ})),
isActive(xt::empty<bool>({settings.sizeX, settings.sizeY, settings.sizeZ})),
isModeratorInLine(xt::empty<bool>({settings.sizeX, settings.sizeY, settings.sizeZ})),
visited(xt::empty<bool>({settings.sizeX, settings.sizeY, settings.sizeZ})) {}
visited(xt::empty<bool>({settings.sizeX, settings.sizeY, settings.sizeZ})),
accessible(xt::empty<bool>({settings.sizeX, settings.sizeY, settings.sizeZ})) {}

int Evaluator::getTileSafe(int x, int y, int z) const {
if (!state->in_bounds(x, y, z))
Expand Down Expand Up @@ -105,25 +106,51 @@ namespace Fission {
bool Evaluator::checkAccessibility(int compatibleTile, int x, int y, int z) {
visited.fill(false);
this->compatibleTile = compatibleTile;
return checkAccessibility(x, y, z);
// Active cooler can only touch other active cooler if they are the same type.
// If it touches a cooler of another type, it's an invalid placement, don't bother checking accessbility
return
checkCompatible(compatibleTile, x - 1, y, z) &&
checkCompatible(compatibleTile, x + 1, y, z) &&
checkCompatible(compatibleTile, x, y - 1, z) &&
checkCompatible(compatibleTile, x, y + 1, z) &&
checkCompatible(compatibleTile, x, y, z - 1) &&
checkCompatible(compatibleTile, x, y, z + 1) &&
checkAccessibility(x, y, z);
}

bool Evaluator::checkCompatible(int compatibleTile, int x, int y, int z) {
if (!state->in_bounds(x, y, z))
return true;
int tile((*state)(x, y, z));
return tile < Active || tile == compatibleTile || tile >= Cell;
}

// Ensure there is a path from a casing (technically Buffer) to this cooler, via cooler of the same type or air
// Recursive check
bool Evaluator::checkAccessibility(int x, int y, int z) {
// If current tile is casing, then we reached a path to a potential buffer, so it's accessible.
if (!state->in_bounds(x, y, z))
return true;
// If already visited tile during current recursion, it went in a loop. Not accessible through this path
if (visited(x, y, z))
return false;
visited(x, y, z) = true;
int tile((*state)(x, y, z));
// Only accessible through air or another active cooler of the same type
if (tile != Air && tile != compatibleTile)
return false;
return
// The current recursion reached an active cooler of the same type that was already deemed accessible
if(accessible(x, y, z))
return true;
bool accessibility =
checkAccessibility(x - 1, y, z) ||
checkAccessibility(x + 1, y, z) ||
checkAccessibility(x, y - 1, z) ||
checkAccessibility(x, y + 1, z) ||
checkAccessibility(x, y, z - 1) ||
checkAccessibility(x, y, z + 1);
accessible(x, y, z) = accessibility;
return accessibility;
}

void Evaluator::run(const xt::xtensor<int, 3> &state, Evaluation &result) {
Expand All @@ -134,6 +161,7 @@ namespace Fission {
result.breed = 0;
isActive.fill(false);
isModeratorInLine.fill(false);
accessible.fill(false);
this->state = &state;
for (int x{}; x < settings.sizeX; ++x) {
for (int y{}; y < settings.sizeY; ++y) {
Expand All @@ -153,7 +181,7 @@ namespace Fission {
} else if (tile < Cell) {
if (settings.ensureActiveCoolerAccessible && !checkAccessibility(tile, x, y, z)) {
rules(x, y, z) = -1;
} else {
} else {
rules(x, y, z) = tile - Active;
}
} else {
Expand Down
3 changes: 2 additions & 1 deletion Fission.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace Fission {
class Evaluator {
const Settings &settings;
xt::xtensor<int, 3> mults, rules;
xt::xtensor<bool, 3> isActive, isModeratorInLine, visited;
xt::xtensor<bool, 3> isActive, isModeratorInLine, visited, accessible;
const xt::xtensor<int, 3> *state;
int compatibleTile;

Expand All @@ -63,6 +63,7 @@ namespace Fission {
int countNeighbors(int tile, int x, int y, int z) const;
int countCasingNeighbors(int x, int y, int z) const;
bool checkAccessibility(int compatibleTile, int x, int y, int z);
bool checkCompatible(int compatibleTile, int x, int y, int z);
bool checkAccessibility(int x, int y, int z);
public:
Evaluator(const Settings &settings);
Expand Down