Exemple #1
0
void chk_walls(unsigned int c_pos, unsigned char m_dir)
{
	unsigned int i;
	unsigned char cnt_L0,cnt_R0,cnt_L45,cnt_R45;

	// Initiate.
	cnt_L0 = cnt_R0 = cnt_L45 = cnt_R45 = 0;

	// Count.
	for(i=0;i<SS_HISTORY_SIZE;i++)	{
		if (ss_history[SS_L45][i] > threshold_L45 ) cnt_L45++;
		if (ss_history[SS_R45][i] > threshold_R45 ) cnt_R45++;
		if (ss_history[SS_L0 ][i] > threshold_L0  ) cnt_L0++;
		if (ss_history[SS_R0 ][i] > threshold_R0  ) cnt_R0++;
	}

	// Decide the existance of walls.
	if ( cnt_L45 > 2 ) 				 maze[c_pos] |= wall_bit(get_absolute_dir(L,m_dir));
	if ( cnt_R45 > 2 )  			 maze[c_pos] |= wall_bit(get_absolute_dir(R,m_dir));
	//if ( cnt_L0  > 2 && cnt_R0 > 2 ) maze[c_pos] |= wall_bit(get_absolute_dir(F,m_dir));
	if ( cnt_L0  > 1 && cnt_R0 > 1 ) maze[c_pos] |= wall_bit(get_absolute_dir(F,m_dir));

	// Process walls of blocks around.
	unsigned char x,y;
	x = pos_x( c_pos ); y = pos_y( c_pos );
	if ( (maze[c_pos] & NORTH) && y < 15 )  maze[ c_pos + dxy[N] ] |= SOUTH;
	if ( (maze[c_pos] & EAST ) && x < 15 )  maze[ c_pos + dxy[E] ] |= WEST;
	if ( (maze[c_pos] & SOUTH) && y >  0 )  maze[ c_pos + dxy[S] ] |= NORTH;
	if ( (maze[c_pos] & WEST ) && x >  0 )  maze[ c_pos + dxy[W] ] |= EAST;

	// Check the block read.
	maze_info[ c_pos ] |= VALID_BLK;
}
Exemple #2
0
void run_algol()
{
	// ALGOL /////////////////////////////////////////////////////////
	if ((maze_info[mouse_pos] & VALID_BLK) == 0)  {
		chk_walls(mouse_pos,mouse_dir);
		ss_pulse_slow();

		#ifdef DEBUG_ALGOL
			unsigned int	steps_checker = steps_L;
		#endif

		unsigned int v_dir;
		if ( run_fptr < run_rptr )	{
			if 		( run_queue[ run_fptr ] == run_sFX )	v_dir = get_absolute_dir(F,mouse_dir);
			else if ( run_queue[ run_fptr ] == run_sRX )	v_dir = get_absolute_dir(R,mouse_dir);
			else if ( run_queue[ run_fptr ] == run_sLX )	v_dir = get_absolute_dir(L,mouse_dir);
			else goto RUN_ALGOL;

			// Conditional running algorithm
			if ( (maze[mouse_pos] & wall_bit(v_dir)) == 0 )	{
				eyes_on();
				goto END_ALGOL;
			}
		}

		RUN_ALGOL:
		//ss_pulse_slow();
		eyes_off();

		disable_adj();
		scan_maze(goal_pos);
		make_path();
		path_cvrt();
		refresh_ss_history();
		enable_adj();

		//ss_pulse_fast();
		END_ALGOL:
		ss_pulse_fast();

		#ifdef 	DEBUG_ALGOL
			led_num((steps_L - steps_checker)/10);
			//led_num((steps_L - steps_checker));
		#endif
	}
	else eyes_on();
	//////////////////////////////////////////////////////////////////
}
Exemple #3
0
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;
}
Exemple #4
0
/* function name: draw_contour
 * Input Parameter
 *   maze : maze array wich has maze information
 *   map  : array to draw contour map
 *   type : maze type to run mouse
 *   pos  : current mouse location in the maze
 */
void draw_contour(unsigned char *maze, unsigned char *map,
                  unsigned int type, unsigned char pos)
{
    int i, contour_lvl = 1;
    int index;
    unsigned int item;
    char found_mouse = 0;
    struct circular_buffer *cb, contour_buffer;

    cb = &contour_buffer;
    circular_buffer_init(cb, contour_cb_buffer,
                         CONTOUR_CB_BUFFER_MAX);

    /* Uninitialized contour map */
    memset(map, 0, MAZEMAX);

    /* Seed value 1 as a goal */
    switch (type) {
    case TO_GOAL_4X4:
        map[get_index(3, 3)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x33));
        break;
    case TO_GOAL_8X8:
        map[get_index(7, 7)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x77));
        break;
    case TO_GOAL_16X16:
        map[get_index(7, 7)] = contour_lvl;
        map[get_index(8, 7)] = contour_lvl;
        map[get_index(7, 8)] = contour_lvl;
        map[get_index(8, 8)] = contour_lvl;

        /* Add list of same level contour value */
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x77));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x78));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x87));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x88));
        break;
    case TO_START_4X4:
    case TO_START_8X8:
    case TO_START_16X16:
        map[get_index(0, 0)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x00));
        break;
    default:
        if (type < MAZEMAX) {
            map[type] = contour_lvl;
            circular_buffer_write(cb, gen_contour_pos(contour_lvl, type));
        } else {
            print_exit("Invalid target goal index!\n");
        }
        break;
    }

    /* Get one contour number from circular buffer.
     * Put next higher value in next block if there is
     * no wall to there and save it inti circular buffer.
     * If contour map reaches to current mouse or
     * circular buffer is empty then it's done.
     */
    while (!circular_buffer_empty(cb) && !found_mouse) {
        circular_buffer_read(cb, &item);
        index = get_contour_index(item);
        contour_lvl = get_contour_lvl(item) + 1;

        /* Calculate contour lvl around current cube */
        for (i = NI; i <= WI; i++) {
            if (!(maze[index] & wall_bit(i)) &&
                    (map[index + maze_dxy[i]] == 0)) {
                map[index + maze_dxy[i]] = contour_lvl;
                circular_buffer_write(cb,
                                      gen_contour_pos(contour_lvl,
                                                      index + maze_dxy[i]));
                if (index + maze_dxy[i] == pos)
                    found_mouse = 1;
            }
        }

#ifdef DEBUG
        if (debug_flag & DEBUG_CONTOUR) {
            print_map(map);
            usleep(20000);
        }
#endif
    }

    if (!found_mouse) {
        /* Mouse alorighm should never hit this location */
        print_map(map);
        print_exit("%s couldn't find mouse location\n",
                   __func__);
    }
}