From 0cf5dfed3e492608d044a5fc90c1815fab506fd7 Mon Sep 17 00:00:00 2001 From: scratko Date: Sun, 14 Apr 2024 21:18:36 +0300 Subject: Capture and liberation of ghosts Fixed coordinate in field_has_coin. Added marks on the field for the liberation zone (1 in front of #). Prison parameters for the ghost are set. Fixed condition in BFS search (additionally exclude the current point in the loop, dx == 0 && dy == 0). --- pacman.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 3 deletions(-) (limited to 'pacman.c') diff --git a/pacman.c b/pacman.c index f03941c..1fb296c 100644 --- a/pacman.c +++ b/pacman.c @@ -15,7 +15,8 @@ enum { chase_move_limit = 70, scatter_move_limit = 35, frightened_move_limit = 30, - phase_limit = 4 + phase_limit = 4, + prison_limit = 30 }; struct mode_type { @@ -85,6 +86,8 @@ static void pathfinder_stage(game_space field, for(color_priority = 0; color_priority <= orange; ++color_priority) { switch(color_priority) { case red: + if(red_ghost->prison_params.active) + continue; current_ghost = red_ghost; new_target_point = mode_params->current_mode == scatter ? current_ghost->home_position : pac->position; @@ -92,6 +95,8 @@ static void pathfinder_stage(game_space field, compute_distance_between_points : breadth_first_search; break; case pink: + if(pink_ghost->prison_params.active) + continue; current_ghost = pink_ghost; new_target_point = mode_params->current_mode == scatter ? current_ghost->home_position : @@ -99,6 +104,8 @@ static void pathfinder_stage(game_space field, search_method = compute_distance_between_points; break; case blue: + if(blue_ghost->prison_params.active) + continue; current_ghost = blue_ghost; new_target_point = mode_params->current_mode == scatter ? current_ghost->home_position : @@ -106,6 +113,8 @@ static void pathfinder_stage(game_space field, search_method = compute_distance_between_points; break; case orange: + if(orange_ghost->prison_params.active) + continue; current_ghost = orange_ghost; new_target_point = mode_params->current_mode == scatter ? current_ghost->home_position : pac->position; @@ -133,15 +142,23 @@ static void random_pathfinder_stage(game_space field, for(color_priority = 0; color_priority <= orange; ++color_priority) { switch(color_priority) { case red: + if(red_ghost->prison_params.active) + continue; current_ghost = red_ghost; break; case pink: + if(pink_ghost->prison_params.active) + continue; current_ghost = pink_ghost; break; case blue: + if(blue_ghost->prison_params.active) + continue; current_ghost = blue_ghost; break; case orange: + if(orange_ghost->prison_params.active) + continue; current_ghost = orange_ghost; break; } @@ -151,6 +168,114 @@ static void random_pathfinder_stage(game_space field, } } +static int is_outside_prison(struct ghost_type ghost) +{ + return ghost.prison_params.active && ghost.direction == up; +} + +static int is_ghost_prisoner(struct ghost_type ghost) +{ + return ghost.prison_params.active && ghost.direction == none; +} + +static void prison_leaving_stage(game_space field, struct ghost_type *red_ghost, + struct ghost_type *pink_ghost, + struct ghost_type *blue_ghost, + struct ghost_type *orange_ghost) +{ + struct ghost_type *current_ghost; + int color_priority; + for(color_priority = 0; color_priority <= orange; ++color_priority) { + switch(color_priority) { + case red: + current_ghost = red_ghost; + break; + case pink: + current_ghost = pink_ghost; + break; + case blue: + current_ghost = blue_ghost; + break; + case orange: + current_ghost = orange_ghost; + break; + } + if(is_ghost_prisoner(*current_ghost)) { + ++current_ghost->prison_params.prison_counter; + /* + * liberation + */ + if(current_ghost->prison_params.prison_counter == prison_limit) { + current_ghost->prison_params.prison_counter = 0; + current_ghost->direction = up; + } + } else if(is_outside_prison(*current_ghost)) + current_ghost->prison_params.active = + current_ghost->position.y == liberation_y ? 0 : 1; + } +} + +static int is_castling(struct pacman pac, struct ghost_type ghost) +{ + return ghost.capture_info.status && + pac.position.x == ghost.capture_info.previous_ghost_position.x && + pac.position.y == ghost.capture_info.previous_ghost_position.y && + ghost.position.x == ghost.capture_info.previous_pac_position.x && + ghost.position.y == ghost.capture_info.previous_pac_position.y; +} + +static void caughting_stage(game_space field, + const struct mode_type *mode_params, + struct pacman *pac, struct ghost_type *red_ghost, + struct ghost_type *pink_ghost, + struct ghost_type *blue_ghost, + struct ghost_type *orange_ghost) +{ + struct ghost_type *current_ghost; + current_ghost = red_ghost; + int color_priority; + for(color_priority = 0; color_priority <= orange; ++color_priority) { + switch(color_priority) { + case red: + if(is_pac_nearby(*pac, *red_ghost)) { + set_capture_info(red_ghost, pac); + continue; + } + current_ghost = red_ghost; + break; + case pink: + if(is_pac_nearby(*pac, *pink_ghost)) { + set_capture_info(pink_ghost, pac); + continue; + } + current_ghost = pink_ghost; + break; + case blue: + if(is_pac_nearby(*pac, *blue_ghost)) { + set_capture_info(blue_ghost, pac); + continue; + } + current_ghost = blue_ghost; + break; + case orange: + if(is_pac_nearby(*pac, *orange_ghost)) { + set_capture_info(orange_ghost, pac); + continue; + } + current_ghost = orange_ghost; + break; + } + if(is_equal_points(pac->position, current_ghost->position) || + is_castling(*pac, *current_ghost)) { + if(mode_params->current_mode == frightened) + catch_ghost(field, current_ghost); + else + --pac->lives; + } + current_ghost->capture_info.status = 0; + } +} + static void chase_mode(game_space field, struct mode_type *mode_params, const struct pacman *pac, struct ghost_type *red_ghost, @@ -190,6 +315,8 @@ static void frightened_mode(game_space field, struct mode_type *mode_params, orange_ghost); ++mode_params->frightened_count; change_mode(mode_params); + set_frightened_status(mode_params->current_mode == frightened ? 1 : 0, + red_ghost, pink_ghost, blue_ghost, orange_ghost); } static void initialize_ghosts(struct ghost_type *red_ghost, @@ -284,14 +411,20 @@ int main() &blue_ghost, &orange_ghost); make_ghost_moves(field, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost, &eaten_coins); + /* * displaying characters */ - display_character(pac.position.y, pac.position.x, pac_char); + caughting_stage(field, &mode_params, &pac, &red_ghost, &pink_ghost, + &blue_ghost, &orange_ghost); display_ghosts_on_field(&red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); + display_character(pac.position.y, pac.position.x, pac_char); usleep(sleep_duration); -#if 1 + prison_leaving_stage(field, &red_ghost, &pink_ghost, &blue_ghost, + &orange_ghost); + +#ifdef DEBUG move(0, 50); if(mode_params.current_mode == chase) printw("CHASE %d ", mode_params.chase_count); -- cgit v1.2.3