From 29afbdf8e26f741ac1d090f2e7704093253f17fc Mon Sep 17 00:00:00 2001 From: scratko Date: Thu, 18 Apr 2024 20:05:03 +0300 Subject: Release version --- pacman.c | 242 ++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 161 insertions(+), 81 deletions(-) (limited to 'pacman.c') diff --git a/pacman.c b/pacman.c index ce2fd5d..15a4b63 100644 --- a/pacman.c +++ b/pacman.c @@ -7,15 +7,17 @@ #include #include #include +#include enum { timeout_duration = 0, sleep_duration = 120000, key_escape = 27, + whitespace = 32, max_get_out_stage = 6, - chase_move_limit = 70, - scatter_move_limit = 35, - frightened_move_limit = 50, + chase_limit = 70, + scatter_limit = 35, + fright_limit = 50, phase_limit = 4, prison_limit = 30, max_score = 243 @@ -23,9 +25,9 @@ enum { struct mode_type { enum behavior_mode current_mode; - int chase_count; - int scatter_count; - int frightened_count; + int chase_counter; + int scatter_counter; + int fright_counter; int phase_number; int reverse_direction; int get_out_stage; @@ -50,9 +52,9 @@ static void initialize_ghosts(struct ghost_type *red_ghost, static void initialize_modes(struct mode_type *mode_params) { mode_params->current_mode = scatter; - mode_params->chase_count = 0; - mode_params->scatter_count = 0; - mode_params->frightened_count = 0; + mode_params->chase_counter = 0; + mode_params->scatter_counter = 0; + mode_params->fright_counter = 0; mode_params->phase_number = 0; mode_params->reverse_direction = 0; mode_params->get_out_stage = max_get_out_stage; @@ -73,8 +75,8 @@ static void initialize_params(game_space *field, struct queue *eaten_coins, initialize_ghosts(red_ghost, pink_ghost, blue_ghost, orange_ghost); initialize_modes(mode_params); display_ghosts_on_field(red_ghost, pink_ghost, blue_ghost, - orange_ghost); - display_character(pac->position.y, pac->position.x, pac_char); + orange_ghost, mode_params->fright_counter); + display_character(pac->position.y, pac->position.x, pac_char, 0); } static int is_up_move_blocked(const struct ghost_type *ghost, @@ -182,16 +184,28 @@ static void random_pathfinder_stage(game_space field, } } -static void change_mode(struct mode_type *mode_params) +static void change_mode(struct mode_type *mode_params, struct pacman *pac) { + if(pac->is_energizer_eaten) { + mode_params->current_mode = frightened; + mode_params->reverse_direction = 1; + pac->is_energizer_eaten = 0; + /* if frightened mode is activated already */ + mode_params->fright_counter = 0; + return; + } + /* + * After all phases are completed, you can only change the mode here from + * frightened to chase. + */ if(!(mode_params->current_mode == frightened) && mode_params->phase_number == phase_limit) return; switch(mode_params->current_mode) { case chase: - if(mode_params->chase_count > chase_move_limit) { + if(mode_params->chase_counter > chase_limit) { mode_params->current_mode = scatter; - mode_params->chase_count = 0; + mode_params->chase_counter = 0; ++mode_params->phase_number; if(mode_params->phase_number == phase_limit) mode_params->current_mode = chase; @@ -200,26 +214,25 @@ static void change_mode(struct mode_type *mode_params) } break; case scatter: - if(mode_params->scatter_count > scatter_move_limit) { + if(mode_params->scatter_counter > scatter_limit) { mode_params->current_mode = chase; - mode_params->scatter_count = 0; + mode_params->scatter_counter = 0; ++mode_params->reverse_direction; } break; case frightened: - if(mode_params->frightened_count > frightened_move_limit) { + if(mode_params->fright_counter > fright_limit) { mode_params->current_mode = - mode_params->chase_count || mode_params->phase_number == - phase_limit ? chase : scatter; - mode_params->frightened_count = 0; + mode_params->chase_counter || + (mode_params->phase_number == phase_limit) ? chase : scatter; + mode_params->fright_counter = 0; ++mode_params->reverse_direction; } } } static void chase_mode(game_space field, struct mode_type *mode_params, - const struct pacman *pac, - struct ghost_type *red_ghost, + struct pacman *pac, struct ghost_type *red_ghost, struct ghost_type *pink_ghost, struct ghost_type *blue_ghost, struct ghost_type *orange_ghost) @@ -227,13 +240,13 @@ static void chase_mode(game_space field, struct mode_type *mode_params, pathfinder_stage(field, mode_params, pac, red_ghost, pink_ghost, blue_ghost, orange_ghost); if(mode_params->phase_number < phase_limit) { - ++mode_params->chase_count; - change_mode(mode_params); + ++mode_params->chase_counter; + change_mode(mode_params, pac); } } static void scatter_mode(game_space field, struct mode_type *mode_params, - struct ghost_type *red_ghost, + struct pacman *pac, struct ghost_type *red_ghost, struct ghost_type *pink_ghost, struct ghost_type *blue_ghost, struct ghost_type *orange_ghost) @@ -241,23 +254,21 @@ static void scatter_mode(game_space field, struct mode_type *mode_params, pathfinder_stage(field, mode_params, NULL, red_ghost, pink_ghost, blue_ghost, orange_ghost); if(mode_params->phase_number < phase_limit) { - ++mode_params->scatter_count; - change_mode(mode_params); + ++mode_params->scatter_counter; + change_mode(mode_params, pac); } } static void frightened_mode(game_space field, struct mode_type *mode_params, - struct ghost_type *red_ghost, + struct pacman *pac, struct ghost_type *red_ghost, struct ghost_type *pink_ghost, struct ghost_type *blue_ghost, struct ghost_type *orange_ghost) { random_pathfinder_stage(field, red_ghost, pink_ghost, blue_ghost, 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); + ++mode_params->fright_counter; + change_mode(mode_params, pac); } static int is_outside_prison(struct ghost_type ghost) @@ -365,11 +376,6 @@ static void catching_stage(game_space field, current_ghost->reached_pacman = 1; catch_pac(pac); return; -#if 0 - initialize_ghosts(red_ghost, pink_ghost, blue_ghost, - orange_ghost); - return; -#endif } } if(current_ghost->capture_info.status) @@ -377,6 +383,9 @@ static void catching_stage(game_space field, } } +/* + * to recognize a hit and also to start a new attempt + */ static int ghost_caught_pacman(struct ghost_type red_ghost, struct ghost_type pink_ghost, struct ghost_type blue_ghost, @@ -408,14 +417,93 @@ static void final_stage(struct game_params_type *game_options, int win) game_options->exit = (key == 'y') ? 0 : 1; } -static void clear_field_and_queue(game_space field, struct queue *eaten_coins) +/* + * restart after winning or losing + */ + +static void clear_field_and_queue(game_space *field, struct queue *eaten_coins) { clear_field(field); queue_clear(eaten_coins); } +static void new_game(game_space *field, struct queue *eaten_coins, + 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) +{ + clear_field_and_queue(field, eaten_coins); + initialize_params(field, eaten_coins, mode_params, pac, red_ghost, + pink_ghost, blue_ghost, orange_ghost); + +} + +static void new_attempt(game_space *field, struct queue *eaten_coins, + 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) +{ + erase_hit(pac->position); + clear_ghost_positions(*field, eaten_coins, red_ghost, pink_ghost, + blue_ghost, orange_ghost); + pac->position.x = pac_x; + pac->position.y = pac_y; + initialize_ghosts(red_ghost, pink_ghost, blue_ghost, orange_ghost); + initialize_modes(mode_params); + display_ghosts_on_field(red_ghost, pink_ghost, blue_ghost, orange_ghost, + mode_params->fright_counter); + display_character(pac->position.y, pac->position.x, pac_char, 0); +} + +static void waiting_for_readiness() +{ + display_ready(); + usleep(sleep_duration*5); + clear_ready(); +} + +static void set_pause(struct game_params_type *game_options) +{ + int key; + timeout(-1); + while((key = getch()) != whitespace && key != key_escape) + ; + if(key == whitespace) + game_options->pause = 1; + else + game_options->exit = 1; + timeout(timeout_duration); +} + +static void help_message() +{ + fprintf(stderr, + "Sorry.\n" + "To play Pacman for Console, your console window must be\n" + "at least 28x30. Please resize your window/resolution and\n" + "re-run the game.\n" + ); +} + +static int check_screen_resolution() +{ + initscr(); + int row, col; + getmaxyx(stdscr, row, col); + endwin(); + return row >= field_height && col >= field_width; +} + int main() { + if(!check_screen_resolution()) { + help_message(); + return 1; + } game_space field = NULL; struct ghost_type red_ghost, pink_ghost, blue_ghost, orange_ghost; struct pacman pac; @@ -437,8 +525,19 @@ int main() game_options.pause = 0; initialize_params(&field, &eaten_coins, &mode_params, &pac, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); - usleep(sleep_duration); + waiting_for_readiness(); while((key = getch()) != key_escape) { + /* + * pause + */ + if(key == whitespace) { + set_pause(&game_options); + if(game_options.pause) { + game_options.pause = 0; + continue; + } else + break; + } /* * pacman */ @@ -447,13 +546,8 @@ int main() else check_remaining_direction(field, &pac, &stored_direction); make_pac_move(field, &pac, &eaten_coins); - if(pac.is_energizer_eaten) { - mode_params.current_mode = frightened; - mode_params.reverse_direction = 1; - pac.is_energizer_eaten = 0; - /* if frightened mode is activated already */ - mode_params.frightened_count = 0; - } + if(pac.is_energizer_eaten) + change_mode(&mode_params, &pac); /* * ghosts */ @@ -469,10 +563,10 @@ int main() chase_mode(field, &mode_params, &pac, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); else if(mode_params.current_mode == scatter) - scatter_mode(field, &mode_params, &red_ghost, &pink_ghost, + scatter_mode(field, &mode_params, &pac, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); else if(mode_params.current_mode == frightened) - frightened_mode(field, &mode_params, &red_ghost, &pink_ghost, + frightened_mode(field, &mode_params, &pac, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); make_ghost_moves(field, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost, &eaten_coins); @@ -486,71 +580,57 @@ int main() */ display_score(pac.score); display_ghosts_on_field(&red_ghost, &pink_ghost, &blue_ghost, - &orange_ghost); + &orange_ghost, mode_params.fright_counter); if(ghost_caught_pacman(red_ghost, pink_ghost, blue_ghost, orange_ghost)) { display_hit(pac.position, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); usleep(sleep_duration*5); } else - display_character(pac.position.y, pac.position.x, pac_char); + display_character(pac.position.y, pac.position.x, pac_char, 0); usleep(sleep_duration); prison_leaving_stage(field, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); - #ifdef DEBUG move(0, 50); reset_attr(); if(mode_params.current_mode == chase) - printw("CHASE %d ", mode_params.chase_count); + printw("CHASE %d ", mode_params.chase_counter); else if(mode_params.current_mode == scatter) - printw("SCATTER %d ", mode_params.scatter_count); + printw("SCATTER %d ", mode_params.scatter_counter); else if(mode_params.current_mode == frightened) - printw("FRIGHTENED %d ", mode_params.frightened_count); + printw("FRIGHTENED %d ", mode_params.fright_counter); move(1, 50); printw("LIVES: %d ", pac.lives); - move(2, 50); - printw("%d %d ", orange_ghost.position.x, orange_ghost.position.y); - move(3, 50); - printw("%d %d ", pac.position.x, pac.position.y); refresh(); #endif + /* + * result check + */ if(pac.lives < 0 || pac.score == max_score ) { -#if 0 - if(pac.lives < 0) - display_ghosts_on_field(&red_ghost, &pink_ghost, &blue_ghost, - &orange_ghost); -#endif final_stage(&game_options, pac.lives < 0 ? 0 : 1); if(game_options.exit) break; else { stored_direction = none; - clear_field_and_queue(field, &eaten_coins); - initialize_params(&field, &eaten_coins, &mode_params, &pac, - &red_ghost, &pink_ghost, &blue_ghost, - &orange_ghost); - usleep(sleep_duration); + new_game(&field, &eaten_coins, &mode_params, &pac, &red_ghost, + &pink_ghost, &blue_ghost, &orange_ghost); + waiting_for_readiness(); } continue; } + /* + a new attempt if pacman has any life + */ if(ghost_caught_pacman(red_ghost, pink_ghost, blue_ghost, orange_ghost)) { - erase_hit(pac.position); - clear_ghost_positions(field, &eaten_coins, &red_ghost, &pink_ghost, - &blue_ghost, &orange_ghost); - pac.position.x = pac_x; - pac.position.y = pac_y; - initialize_ghosts(&red_ghost, &pink_ghost, &blue_ghost, - &orange_ghost); - initialize_modes(&mode_params); - 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); + stored_direction = none; + new_attempt(&field, &eaten_coins, &mode_params, &pac, &red_ghost, + &pink_ghost, &blue_ghost, &orange_ghost); + waiting_for_readiness(); } } - clear_field_and_queue(field, &eaten_coins); + clear_field_and_queue(&field, &eaten_coins); endwin(); return 0; } -- cgit v1.2.3