gdmc_http_client_python icon indicating copy to clipboard operation
gdmc_http_client_python copied to clipboard

Treecutting function

Open Flashing-Blinkenlights opened this issue 4 years ago • 2 comments

Feature branch: None

Currently, dealing with trees in forested areas can be difficult and improper execution can result in floating trees or leaves that won't decay due to nearby logs. It would be very convenient to have a function that, when called on a particular coordinate, detects and cleanly removes the tree. Caution may be taken not to remove e.g. wooden support pillars (from mineshafts etc.). Depending on the type of tree (e.g. Acacia), further steps may need to be taken to effectively remove the tree.

Help wanted:

Any suggestions or thoughts on the implementation of this issue will be warmly embraced.

Suggested implementation:

def removetree(x, y, z):
    toRemove = []
    # search down until block is no longer a log
    # add log to toRemove
    # move up until not log, adding to toRemove
    # if block is not leaf, return with error "Not a tree"
    # find adjoining leaf and log blocks and add to toremove
    # clever algorithm to figure out whether the leaves belong to this tree
    for coords in toRemove:
        interfaceUtils.setblock(*coords, "air")
    

Pro:

  • Facilitates the tedious task of removing trees
  • Allows for simple removal of more complex trees

Con:

  • Is slower then just removing the logs (optional 'fast' setting?)
  • May detect false negatives
  • Handling of custom trees is ambiguous

Flashing-Blinkenlights avatar Apr 22 '21 11:04 Flashing-Blinkenlights

I was encouraged by @Flashing-Blinkenlights to post the current state of my Rust implementation for finding trees. Here it is: https://gist.github.com/terjesc/4e0d5d8e63fe034d803c7b2ac47084b7

Roughly, it:

  1. Locates the closest Log (if on Log, already found; if on Leaves, BFS for Log; if on neither, not a tree, return empty set.)
  2. From that Log, locates all Logs of the same tree, to use for basis of next step.
  3. BFS through Leaves starting from the set of Logs from 2).
  4. Find vines on the sides of Leaves and remove those (as well as vines hanging from them)

For the BFS in 3:

  • Keep track of the distance back to the Logs of the tree.
  • If encountering a Log that is not part of the tree, backtrack by running a BFS from that "foreign" Log through already found nodes, until the distance from that foreign Log reaches the distance from the Logs of the tree that we try to find.
  • If encountering a Leaves that is already known to belong to a foreign tree, do similar backtracking as when finding a Log.

There is some weirdness going on not giving quite the result that I want. (Sometimes the searched tree gets assigned a few too many leaves, when close to another tree of the same type, but for the most time it seems OK...) I think there might be multiple issues, as the code became quite clumsy.

My thoughts for future improvement is to use the "distance to trunk" property of leaves directly, in order to vastly simplify the algorithm. (First find logs, then BFS for leaves by only adding leaves that have lower "distance to trunk" than the parent in the search.)

terjesc avatar May 16 '21 09:05 terjesc

Moved to https://github.com/avdstaaij/gdpc/issues/24

avdstaaij avatar Sep 24 '22 16:09 avdstaaij