def planttrees(mcmap, treelist):
    '''Take mcmap and add trees to random locations on the surface to treelist.
    '''
    assert isinstance(mcmap, mcInterface.SaveFile)
    # keep looping until all the trees are placed
    # calc the radius difference, for interpolation
    in_out_dif = EDGEHEIGHT - CENTERHEIGHT
    if VERBOSE:
        print('Tree Locations: x, y, z, tree height')
    tries = 0
    max_tries = MAXTRIES
    while len(treelist) < TREECOUNT:
        if tries > max_tries:
            if VERBOSE:
                print("Stopping search for tree locations after {0} tries".format(tries))
                print("If you don't have enough trees, check X, Y, RADIUS, and PLANTON")
            break
        tries += 1
        # choose a location
        rad_fraction = random()
        # this is some kind of square interpolation
        rad_fraction = 1.0 - rad_fraction
        rad_fraction **= 2
        rad_fraction = 1.0 - rad_fraction

        rad = rad_fraction * RADIUS
        ang = random() * pi * 2
        x = X + int(rad * sin(ang) + .5)
        z = Z + int(rad * cos(ang) + .5)
        # check to see if this location is suitable
        y_top = mcmap.surface_block(x, z)
        if y_top is None:
            # this location is off the map!
            continue
        if y_top['B'] in PLANTON:
            # plant the tree on the block above the ground
            # hence the " + 1"
            y = y_top['y'] + 1
        else:
            continue
        # this is linear interpolation also.
        base_height = CENTERHEIGHT + (in_out_dif * rad_fraction)
        height_rand = (random() - .5) * 2 * HEIGHTVARIATION
        height = int(base_height + height_rand)
        # if the option is set, check the surrounding area for trees
        if ONLYINFORESTS:
            '''we are looking for foliage
            it should show up in the "surface_block" search
            check every fifth block in a square pattern,
            offset around the trunk
            and equal to the trees height
            if the area is not at least one third foliage,
            don't build the tree'''
            # spacing is how far apart each sample should be
            spacing = 5
            # search_size is how many blocks to check
            # along each axis
            search_size = 2 + (height // spacing)
            # check at least 3 x 3
            search_size = max([search_size, 3])
            # set up the offset values to offset the starting corner
            offset = ((search_size - 1) * spacing) // 2
            # foliage_count is the total number of foliage blocks found
            foliage_count = 0
            # check each sample location for foliage
            for step_x in range(search_size):
                # search_x is the x location to search this sample
                search_x = x - offset + (step_x * spacing)
                for step_z in range(search_size):
                    # same as for search_x
                    search_z = z - offset + (step_z * spacing)
                    search_block = mcmap.surface_block(search_x, search_z)
                    if search_block is None:
                        continue
                    if search_block['B'] == 18:
                        # this sample contains foliage!
                        # add it to the total
                        foliage_count += 1
            #now that we have the total count, find the ratio
            total_searched = search_size ** 2
            foliage_ratio = foliage_count / total_searched
            # the acceptable amount is about a third
            acceptable_ratio = .3
            if foliage_ratio < acceptable_ratio:
                # after all that work, there wasn't enough foliage around!
                # try again!
                continue

        # generate the new tree
        newtree = Tree([x, y, z], height)
        if VERBOSE:
            print(x, y, z, height)
        treelist += [newtree]
Take mcmap and add trees to random locations on the surface to treelist.
    
stock-filters/Forester.py