back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/pacman.c
diff options
context:
space:
mode:
Diffstat (limited to 'pacman.c')
-rw-r--r--pacman.c139
1 files changed, 136 insertions, 3 deletions
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);