// 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;
            }
            }
        }
    }