Esempio n. 1
0
File: node.c Progetto: ifzz/exlibs-c
void bt_node_free ( bt_node_t *_node )
{
    // the array could be NULL;
    if ( _node->children ) {
        // free children nodes
        ex_array_each ( _node->children, bt_node_t *, child ) {
            bt_node_free ( child );
        } ex_array_each_end

        // free array
        if ( _node->children ) {
            ex_array_free (_node->children);
        }
    }
Esempio n. 2
0
File: algo.c Progetto: shizkr/dsy_mm
/* clean bt_node tree while it's cleaning bt_node
 */
void clean_bin_tree(struct btree_node *node, int depth)
{
    struct btree_node *parent;

    if (node->left || node->right || !depth)
        return;

    parent = node->parent;

    if (!parent)
        return;

    if (parent->left == node)
        parent->left = NULL;
    if (parent->right == node)
        parent->right = NULL;

    bt_node_free(node);

    clean_bin_tree(parent, --depth);
}
Esempio n. 3
0
File: algo.c Progetto: shizkr/dsy_mm
static int gen_bin_tree_tail(unsigned char *maze, unsigned char *map,
                             struct s_link **head)
{
    struct btree_node *bt_new_node, *bt_node;
    struct s_link *sl_node;
    struct s_link *sl_new_node, *tail_new_list = NULL;
    unsigned char i, index, abs_dir;
    struct btree_node bt_node_backup;
    char dir, is_goal = 0, found_node;
#ifdef CONFIG_PATH_LIMIT
    int path_limit = 0;
#endif

    if (!maze || !map || !head || !*head) {
        print_error("NULL pointer error! %X %X %X %X\n",
                    (unsigned int)maze, (unsigned int)map,
                    (unsigned int)head, (unsigned int)*head);
    }

    print_dbg(DEBUG_S_LINK, "Check input linked list: %08X\n",
              (unsigned int)*head);
    debug_sl_node(*head);

    print_dbg(DEBUG_S_LINK, "Find next lower contour level\n");
    /* Find next lower contour cube arond current location */
    for (sl_node = *head; sl_node; sl_node = sl_node->node) {
        index = sl_node->bt_node->pos;
        abs_dir = sl_node->bt_node->abs_dir;
        bt_node = sl_node->bt_node;

        /* when it's set, found turn. on the unkonwn blocks,
         * there may be too many pathes to calculate.
         **/
        found_node = 0;
        bt_node_backup.time = 0; /* use to check FD detection */

        for (i = NI; i <= WI; i++) {
            if (!(maze[index] & wall_bit(i)) &&
                    (map[index] == map[index + maze_dxy[i]] + 1)) {

                dir = relative_direction(abs_dir, i);

                /* if block is unknown, then take turn prior
                 * to straight path. It's to save memory
                 * and calculation time.
                 */
                if (dir == FD && ((maze[index]&0xF0) != 0xF0)) {
                    bt_node_backup.pos = index+maze_dxy[i];
                    bt_node_backup.dir = dir;
                    bt_node_backup.abs_dir = i;
                    /* to mark block has meaningful data */
                    bt_node_backup.time = 1;
                    continue;
                }

                found_node = 1;
                /* create new bt_node and save next mouse index
                 * and absolute direction of mouse at next block
                 */
                bt_new_node =
                    bt_node_alloc(index+maze_dxy[i], i);

                /* Next bt_node->dir is to save how mouse made
                 * a turn to come the block.
                 */
                bt_new_node->dir = dir;

                /* there can be 3rd child, only take 2 child at
                 * a time
                 */
                if (!add_bt_node(bt_node, bt_new_node)) {
                    sl_new_node = s_link_alloc(bt_new_node);
                    add_sl_node(&tail_new_list, sl_new_node);
#ifdef CONFIG_PATH_LIMIT
                    path_limit++;
#endif
                } else {
                    bt_node_free(bt_new_node);
                }

                /*
                 * debug_sl_node(tail_new_list);
                 */
            }
        }

        /* if forward is the only one in known block,
         * then use it
         */
        if (!found_node && bt_node_backup.time) {
            bt_new_node =
                bt_node_alloc(bt_node_backup.pos,
                              bt_node_backup.abs_dir);
            bt_new_node->dir = bt_node_backup.dir;

            add_bt_node(bt_node, bt_new_node);

            sl_new_node = s_link_alloc(bt_new_node);
            add_sl_node(&tail_new_list, sl_new_node);
#ifdef CONFIG_PATH_LIMIT
            path_limit++;
#endif
        }

        if (map[index] == 1 && !is_goal)
            is_goal = 1;

        /* Remove bt_node if there is no child, it'll search
         * parent node and remove the node if it had no child
         */
        if (!is_goal)
            clean_bin_tree(bt_node, 80);

#ifdef CONFIG_PATH_LIMIT
        /* 10 pathes : max 20KB
         * 20 pathes : max 30 KB
         * 40 pathes : max 57 KB
         */
        if (path_limit >= 20)
            break;
#endif
    }
    if (tail_new_list)
        debug_sl_node(tail_new_list);

#ifdef DEBUG
    if (is_goal) {
        i = 0;
        print_dbg(DEBUG_BINTREE,
                  "Found maze goal!!!\n");
        print_dbg(DEBUG_BINTREE,
                  "tail_new_list for tail: 0x%08X\n",
                  (unsigned int)tail_new_list);
        print_dbg(DEBUG_BINTREE,
                  "*head pointer: %08X\n",
                  (unsigned int)*head);
        if (tail_new_list)
            print_error("tail_new_list must be NULL!\n");
        for (sl_node = *head; sl_node; sl_node = sl_node->node) {
            index = sl_node->bt_node->pos;
            bt_node = sl_node->bt_node;
            i++;
        }
        print_dbg(DEBUG_BINTREE, "Total path: %d\n", i);
    }
#endif

    /* critical error to find next contour maps */
    if (!is_goal && tail_new_list == NULL) {
        printf("contour map\n");
        print_full(map);
        printf("maze map\n");
        print_map(maze);
        for (sl_node = *head; sl_node; sl_node = sl_node->node) {
            index = sl_node->bt_node->pos;
            abs_dir = sl_node->bt_node->abs_dir;
            bt_node = sl_node->bt_node;
            printf("mouse:(%d,%d),abs_dir:%d\n", pos_x(index),
                   pos_y(index), abs_dir);
        }
    }

    /* free s_link nodes */
    if (!is_goal) {
        sl_node_free(*head);
        *head = tail_new_list;
    }

    return is_goal;
}