#include "ghosts.h" #include "field.h" #include "pac.h" #include "queue.h" #include void initialize_ghost(struct ghost_type *ghost, enum ghost_color color) { switch(color) { case red: ghost->position.y = red_y; ghost->position.x = red_x; ghost->home_position.y = red_home_y; ghost->home_position.x = red_home_x; ghost->color = red; ghost->mode = scatter; ghost->direction = none; break; case pink: ghost->position.y = pink_y; ghost->position.x = pink_x; ghost->home_position.y = pink_home_y; ghost->home_position.x = pink_home_x; ghost->color = pink; ghost->mode = scatter; ghost->direction = none; break; case blue: ghost->position.y = blue_y; ghost->position.x = blue_x; ghost->home_position.y = blue_home_y; ghost->home_position.x = blue_home_x; ghost->color = blue; ghost->mode = scatter; ghost->direction = none; break; case orange: ghost->position.y = orange_y; ghost->position.x = orange_x; ghost->home_position.y = orange_home_y; ghost->home_position.x = orange_home_x; ghost->color = orange; ghost->mode = scatter; ghost->direction = none; break; } } void pull_out_ghosts(int *get_out_stage, struct ghost_type *red_ghost, struct ghost_type *pink_ghost, struct ghost_type *blue_ghost, struct ghost_type *orange_ghost) { enum { final_stage = 1 }; enum movement_direction red_moves[] = { none, right, up, up, left }; enum movement_direction blue_moves[] = { none, left, up, up, left }; enum movement_direction pink_moves[] = { right, up, up, up, right }; enum movement_direction orange_moves[] = { left, up, up, up, right }; int index = *get_out_stage - 1; if(*get_out_stage > final_stage) { red_ghost->direction = red_moves[index]; blue_ghost->direction = blue_moves[index]; } pink_ghost->direction = pink_moves[index]; orange_ghost->direction = orange_moves[index]; --*get_out_stage; } static void change_position(struct ghost_type *ghost, enum movement_direction direction) { switch(direction) { case left: --ghost->position.x; return; case right: ++ghost->position.x; return; case up: --ghost->position.y; return; case down: ++ghost->position.y; return; default: return; } } void make_ghost_moves(game_space field, struct ghost_type *red_ghost, struct ghost_type *pink_ghost, struct ghost_type *blue_ghost, struct ghost_type *orange_ghost) { eat_or_revert_symbol(field, red_ghost->position.y, red_ghost->position.x, ghost_char); eat_or_revert_symbol(field, pink_ghost->position.y, pink_ghost->position.x, ghost_char); eat_or_revert_symbol(field, blue_ghost->position.y, blue_ghost->position.x, ghost_char); eat_or_revert_symbol(field, orange_ghost->position.y, orange_ghost->position.x, ghost_char); change_position(red_ghost, red_ghost->direction); change_position(pink_ghost, pink_ghost->direction); change_position(blue_ghost, blue_ghost->direction); change_position(orange_ghost, orange_ghost->direction); } static void pave_only_way(game_space field, struct ghost_type *ghost) { struct free_directions path = find_free_directions(field, ghost->position.y, ghost->position.x); enum movement_direction reverse_direction = ghost->direction; reverse_direction ^= 1; if(path.left && left != reverse_direction) ghost->direction = left; else if(path.right && right != reverse_direction) ghost->direction = right; else if(path.up && up != reverse_direction) ghost->direction = up; else if(path.down && down != reverse_direction) ghost->direction = down; } void redirect(game_space field, enum intersection_type paths, struct ghost_type *ghost, struct pacman pac, void (*pathfinder)(game_space, struct ghost_type*, struct pacman pac)) { if(paths == one_path) pave_only_way(field, ghost); else pathfinder(field, ghost, pac); } static struct coordinates get_near_point(struct coordinates consider_point, int dx, int dy) { struct coordinates found_point; found_point.x = consider_point.x + dx; found_point.y = consider_point.y + dy; return found_point; } static enum movement_direction find_direction(struct coordinates found_point, struct coordinates ghost_position) { int dx, dy; enum movement_direction new_direction; dx = found_point.x - ghost_position.x; dy = found_point.y - ghost_position.y; switch(dx) { case 1: new_direction = dy == 0 ? right : none; break; case 0: new_direction = dy == -1 ? up : down; break; case -1: new_direction = dy == 0 ? left : none; break; } return new_direction; } void breadth_first_search(game_space field, struct ghost_type *ghost, struct pacman pac) { struct coordinates consider_point, near_point; struct coordinates start_point = { ghost->position.y, ghost->position.x }; struct coordinates target_point = { pac.position.y, pac.position.x }; struct queue next_points, reviewed_points; queue_init(&next_points); queue_init(&reviewed_points); queue_push(&next_points, &target_point); queue_push(&reviewed_points, &target_point); while(!empty(&next_points)) { consider_point = queue_front(&next_points); pop(&next_points); int dx; for(dx = -1; dx <= 1; ++dx) { int dy; for(dy = -1; dy <= 1; ++dy) { if(dx != 0 && dy != 0) continue; near_point = get_near_point(consider_point, dx, dy); if(is_obstacle(field, near_point.x, near_point.y)) continue; if(is_consist_point(&next_points, near_point)) continue; #if 0 init_pair(1, COLOR_RED, COLOR_BLACK); attron(COLOR_PAIR(1)); move(near_point.y, near_point.x); addch('X'); attron(COLOR_PAIR(1)); refresh(); #endif if(equal_points(start_point, near_point)) { ghost->direction = find_direction(consider_point, start_point); queue_clear(&next_points); return; } queue_push(&next_points, &near_point); } } } }