示例#1
0
void choose_direction_for_ghost(char * map, struct pacghost * pacman, struct pacghost * ghost, int difficulty, int is_pacman_powered_up){
    if (!is_pacman_powered_up){
        if (difficulty == 0){
            move_randomly(ghost);
        } else if (difficulty == 1){
            int random = random_in_range(0,10);
            if (random < 5)
                move_randomly(ghost);
            else
                chase_after_pacman(pacman, ghost);
        } else if (difficulty == 2){
            int random = random_in_range(0,10);
            if (random < 2)
                move_randomly(ghost);
            else
                chase_after_pacman(pacman, ghost);

        } else {
            chase_after_pacman(pacman, ghost);
        }
    /* The ghost move to the point nearer to him than pacman when pacman powered */
    } else {
        /* As the point search in order. The ghost tend to stuck when came to top left */
        for (int rows = 0; rows < height; rows++) {
            for (int cols = 0; cols < width; cols++){
                if (isValidMoveCell(rows, cols)){
                    if (distance_between_two_points(pacman->xLocation,pacman->yLocation,rows,cols) > distance_between_two_points(ghost->xLocation,ghost->yLocation,rows,cols)){
                        ghost->direction = direction_from_node_to_node(ghost->xLocation,ghost->yLocation,rows,cols);
                        return;
                    }
                }
            }
        }
    }   
}
示例#2
0
void distance_by_vector_projection_angle_between_robot_and_direction (float final_x, float final_y, float robot_x, float robot_y, float robot_angle, float *distance, float *angle)
{
	float scalar_product=0.0;
	float angle_sign =0.0;
	
	scalar_product = scalar_product_between_robot_and_direction(final_x, final_y, robot_x, robot_y, robot_angle);
	*distance = distance_between_two_points( final_x, final_y, robot_x, robot_y);

	// Calcul de la valeur absolue de l'angle à parcourir avec le produit scalaire
	*angle = acos( scalar_product / *distance );

	// Calcul du sinus de l'angle à parcourir pour avoir le sens de rotation. Avec la produit vectoriel
	angle_sign = vector_product_between_robot_and_direction(final_x, final_y, robot_x, robot_y, robot_angle); // ATTENTION : on avait divisé par error_distance .. normalement ca ne sert à rien mais au cas ou ... / error_distance );

	// Détermination si l'on doit reculer plutôt qu'avancer.
	if (*angle >= M_PI/2)		// quart arrière gauche
	{
		*angle = *angle - M_PI;					// on replace l'angle devant le robot
		*distance = (*distance) * (-1);		// on recule
	}

	if ( angle_sign < 0.0 )
	{
		*angle = (*angle) * (-1);		// Application du signe.
	}
}
示例#3
0
// Distance + Angle in theta-alpha control
/// Improvements : parameter for the final approach distance
unsigned char mode_3_control_motion(StructPos *psetpoint, StructPos *pcurrent, float *raw_command_right, float *raw_command_left)
{
	float error_angle=0.0;
	float error_distance=0.0;
	float error_filtered_angle=0.0;
	float error_filtered_distance=0.0;
	
	float speed_ratio_distance = DEFAULT_SPEED_DISTANCE;

	unsigned char end_movement_flag=0;
	
	// Compute error
	
	// Compute distance : ABS value for vectorial considerations
	error_distance = distance_between_two_points( psetpoint->x, psetpoint->y, pcurrent->x, pcurrent->y);

	if(error_distance<= DISTANCE_ALPHA_ONLY) // final distance reached
	{
		error_angle=angle_between_two_points(psetpoint->angle, pcurrent->angle);
		if(error_angle<=ANGLE_APPROACH_PRECISION) end_movement_flag=1;
		error_distance = scalar_product_between_robot_and_direction(psetpoint->x, psetpoint->y, pcurrent->x, pcurrent->y, pcurrent->angle);
	}
	else
	{
		distance_by_vector_projection_angle_between_robot_and_direction(psetpoint->x, psetpoint->y, pcurrent->x, pcurrent->y, pcurrent->angle, &error_distance, &error_angle);
	}

	// QUADRAMP filter on errors
	speed_ratio_distance = QUADRAMP_Compute(&distance_quadramp_data, error_distance);
	
	// PID filter on errors
	error_filtered_angle = PID_Computation(&angle_pid_data, error_angle);
	error_filtered_distance = PID_Computation(&distance_pid_data, error_distance);

	// Re-scale errors to fit on expected scale
	error_filtered_distance = error_rescale (error_filtered_distance, (1.0 - ANGLE_VS_DISTANCE_RATIO), speed_ratio_distance);
	error_filtered_angle = error_rescale (error_filtered_angle, ANGLE_VS_DISTANCE_RATIO, SPEED_ANGLE);

	// Command merge
	*raw_command_right = error_filtered_distance + error_filtered_angle;
	*raw_command_left = error_filtered_distance - error_filtered_angle;

	return end_movement_flag;
}
示例#4
0
int direction_from_node_to_node(int xStart, int yStart, int xDestination, int yDestination){
    if (isValidMoveCell(xStart, yStart) && isValidMoveCell(xDestination,yDestination)){
        struct list * open_list = list_create();
        struct list * close_list = list_create();
        struct node * new_node = node_create();
        new_node->x = xStart;
        new_node->y = yStart;
        new_node->g = 0;
        new_node->h = distance_between_two_points(xStart,yStart,xDestination,yDestination);
        new_node->f = new_node->h;
        open_list->root = new_node;
        while (open_list->root != NULL){
            struct node * q = node_with_least_f(open_list);
            pop_a_node_off_list(open_list,q);
            int availableWay = ghost_map[q->x * width + q->y] - '0';
            int up_added = 0;
            int right_added = 0;
            int down_added = 0;
            struct node * sucessor[availableWay];
            for (int i = 0; i < availableWay; i++){
                sucessor[i] = node_create();
                sucessor[i]->parent = q;
                if (isValidMoveCell(q->x-1,q->y) && (up_added == 0)) {
                    sucessor[i]->x = q->x-1;
                    sucessor[i]->y = q->y;
                    up_added = 1;
                } else if (isValidMoveCell(q->x, q->y+1) && (right_added == 0)){
                    sucessor[i]->x = q->x;
                    sucessor[i]->y = q->y+1;
                    right_added = 1;
                } else if (isValidMoveCell(q->x+1, q->y) && (down_added == 0)){
                    sucessor[i]->x = q->x+1;        
                    sucessor[i]->y = q->y;
                    down_added = 1;
                } else if (isValidMoveCell(q->x, q->y-1)){
                    sucessor[i]->x = q->x;
                    sucessor[i]->y = q->y-1;      
                }
                if (sucessor[i]->x == xDestination && sucessor[i]->y == yDestination) {
                    struct node * start_node = starting_node(sucessor[i]);
                    if (start_node->x < xStart){
                        free_node_and_list(sucessor[i],q,open_list,close_list);
                        return 0;
                    } else if (start_node->x > xStart){
                        free_node_and_list(sucessor[i],q,open_list,close_list);
                        return 2;
                    } else if (start_node->y > yStart){
                        free_node_and_list(sucessor[i],q,open_list,close_list);
                        return 1;
                    } else {
                        free_node_and_list(sucessor[i],q,open_list,close_list);
                        return 3;
                    }
                } else {
                    sucessor[i]->g = q->g + distance_between_two_points(q->x, q->y, sucessor[i]->x, sucessor[i]->y);
                    sucessor[i]->h = distance_between_two_points(sucessor[i]->x,sucessor[i]->y, xDestination, yDestination);
                    sucessor[i]->f = sucessor[i]->g + sucessor[i]->h;
                    if ((ghost_map[sucessor[i]->x * width + sucessor[i]->y] - '0') == 1)
                        add_a_node_to_list(close_list,sucessor[i]);
                    else if (better_node_exist(open_list,sucessor[i]))
                        free(sucessor[i]);
                    else if (better_node_exist(close_list,sucessor[i])) 
                        free(sucessor[i]);
                    else 
                        add_a_node_to_list(open_list,sucessor[i]);
                }
            }
            add_a_node_to_list(close_list, q);
        }
    }
    return 4;
}