// Recursively add danger to the 2D array void addDangerToBlockAndNeighbors(int i, int j, WeaponType type, float probability, int ammo, bool facingRight, BlockWorld blockWorld, bool isFalling = false) { // Base cases if (probability < epsilon) { return; } if (ammo == 0) { return; // Master mode has negative ammo - do not return } // Blow out ground if there is any at the current position. If there is if (blockWorld.CheckGroundByIndex(i, j)) { // Another base case for immutable ground bool immutable = blockWorld.CheckGroundImmutableByIndex(i, j); if (immutable) { return; // End of the line } // Blow out ground otherwise blockWorld.SetGroundByIndex(i, j, false); addDangerToBlockAndNeighbors(i, j, type, probability * groundBlowoutFactor, ammo - 1, facingRight, blockWorld); return; } else { int normalized = facingRight ? -1 : 1; switch (type) { case WeaponType.Rockets: { addDanger(i, j, probability * RocketsDangerWeight); addDangerToBlockAndNeighbors(i + normalized, j, type, probability, ammo, facingRight, blockWorld); break; } case WeaponType.Bombs: { addDanger(i, j, probability * BombsDangerWeight); addDangerToBlockAndNeighbors(i, j + 1, type, probability, ammo, facingRight, blockWorld); break; } case WeaponType.Minions: { addDanger(i, j, probability * MinionsDangerWeight); bool groundDown = blockWorld.CheckGroundByIndex(i, j + 1); bool groundRight = blockWorld.CheckGroundByIndex(i + normalized, j); bool goRight = false; bool goDown = false; // Do natural motion - right first unless hasn't fallen if (!groundRight && !groundDown) { if (isFalling && blockWorld.CheckGroundByIndex(i + normalized, j + 1)) { goRight = true; } else { goDown = true; } } else if (!groundRight && groundDown) { goRight = true; } else if (groundRight && !groundDown) { goDown = true; } else { // Block worlds diverge, so make a new one BlockWorld newBlockWorld = blockWorld.Clone(); // Go both directions addDangerToBlockAndNeighbors(i + normalized, j, type, probability / 2.0f, ammo, facingRight, blockWorld, false); addDangerToBlockAndNeighbors(i, j + 1, type, probability / 2.0f, ammo, facingRight, newBlockWorld, true); } // Do sole motions if (goRight) { addDangerToBlockAndNeighbors(i + normalized, j, type, probability, ammo, facingRight, blockWorld, false); return; } if (goDown) { addDangerToBlockAndNeighbors(i, j + 1, type, probability, ammo, facingRight, blockWorld, true); return; } break; } } } }