diff options
-rw-r--r-- | field.c | 85 | ||||
-rw-r--r-- | field.h | 11 | ||||
-rw-r--r-- | pac.c | 51 | ||||
-rw-r--r-- | pac.h | 2 | ||||
-rw-r--r-- | pacman.c | 168 |
5 files changed, 169 insertions, 148 deletions
@@ -27,13 +27,14 @@ static const char field_sample[field_height][field_width] = { {"/1....3..2..1//1..2..3....1/"}, {"/.////./////.//./////.////./"}, {"/*////./////.//./////.////*/"}, - {"/1.1//2..2..y..y..2..2//1.1/"}, + {"/1.1//2..2..y. y..2..2//1.1/"}, {"///.//.//.////////.//.//.///"}, {"///.//.//.////////.//.//.///"}, {"/1.2..1//1..1//1..1//1..2.1/"}, {"/.//////////.//.//////////./"}, {"/1..........2..2..........1/"}, {"////////////////////////////"}, + {" C C C Score: "} }; static void copy_field(game_space field) @@ -59,7 +60,7 @@ void clear_field(game_space field) field = NULL; } -int field_has_coin(int x, int y) +static int field_has_coin(int x, int y) { return !((x == 9 && y == 12)|| (x == 18 && y == 12) || (x == 18 && y == 14) || (x == 9 && y == 15) || @@ -67,14 +68,33 @@ int field_has_coin(int x, int y) (x == 13 && y == 12) || (x == 14 && y == 12)); } -int field_has_energizer(const game_space field, int x, int y) +static int yellow_block_contains_coin(int x, int y) { - return field[y][x] = energizer; + return (x == 12 && y == 22) || (x == 15 && y == 22); } -static int yellow_block_contains_coin(int x, int y) +static int is_coin_symbol(int symbol, int x, int y) { - return (x == 12 && y == 22) || (x == 15 && y == 22); + return + symbol == coin || symbol == energizer || symbol == one_path || + symbol == two_paths || symbol == three_paths || + (symbol == yellow_block && yellow_block_contains_coin(x, y)); +} + +int check_coin_for_pac(game_space field, struct coordinates position, + struct queue *eaten_coins) +{ + int x, y; + x = position.x; + y = position.y; + return + is_coin_symbol(field[y][x], x, y) && field_has_coin(x, y) && + !queue_consists_point(eaten_coins, position); +} + +int field_has_energizer(const game_space field, int x, int y) +{ + return field[y][x] == energizer; } void print_field(game_space field) @@ -86,27 +106,19 @@ void print_field(game_space field) for(j = 0; j < field_width; ++j) { symbol = field[i][j]; move(i, j); + if(is_coin_symbol(symbol, j, i) && field_has_coin(j, i)) { + symbol == energizer ? addch('*') : addch('.'); + continue; + } switch(symbol) { case one_path: case two_paths: - case three_paths: - if(field_has_coin(j, i)) - addch('.'); - else - addch(' '); - break; case yellow_block: - if(yellow_block_contains_coin(j, i)) - addch('.'); - else - addch(' '); + addch(' '); break; case block: addch('/'); break; - case coin: - addch('.'); - break; case energizer: addch('*'); break; @@ -117,6 +129,8 @@ void print_field(game_space field) addch(' '); break; } + if(i == field_height-1) + addch(symbol); refresh(); } } @@ -143,6 +157,13 @@ void display_ghosts_on_field(struct ghost_type *red_ghost, ghost_char); } +void display_score(int value) +{ + move(field_height-1, 25); + printw("%d", value); + refresh(); +} + void clear_or_revert_symbol(const game_space field, struct coordinates position, enum select_character character, struct queue *eaten_coins) @@ -263,3 +284,29 @@ int is_equal_points(struct coordinates first_point, struct coordinates y2 = second_point.y; return x1 == x2 && y1 == y2; } + +void erase_life(int value) +{ + enum { + two_lives_left = 2, + one_life_left = 1, + no_lives_left = 0, + gap = 2, + three_lives_x = 5 + }; + int x, y; + y = field_height - 1; + switch(value) { + case two_lives_left: + x = three_lives_x; + break; + case one_life_left: + x = three_lives_x - gap; + break; + case no_lives_left: + x = three_lives_x - gap * 2; + } + move(y, x); + addch(' '); + refresh(); +} @@ -3,7 +3,7 @@ enum { field_width = 28, - field_height = 29, + field_height = 30, left_outside_tunnel_x = -1, right_outside_tunnel_x = field_width, door = '#', @@ -44,6 +44,7 @@ void display_ghosts_on_field(struct ghost_type *red_ghost, struct ghost_type *pink_ghost, struct ghost_type *blue_ghost, struct ghost_type *orange_ghost); +void display_score(int value); struct queue; struct coordinates; @@ -58,7 +59,11 @@ struct free_directions find_free_directions(game_space field, int y, int x); int is_obstacle(game_space field, int x, int y); -int field_has_coin(int x, int y); + +int check_coin_for_pac(game_space field, struct coordinates position, + struct queue *eaten_coins); + +int field_has_energizer(const game_space field, int x, int y); void change_point_if_outside_tunnel(struct coordinates *point); @@ -69,4 +74,6 @@ int is_equal_points(struct coordinates first_point, struct coordinates void clear_field(game_space field); +void erase_life(int value); + #endif @@ -5,7 +5,7 @@ void initialize_pac(struct pacman *pac) { pac->lives = max_live; - pac->coins_eaten = 0; + pac->score = 0; pac->position.y = pac_y; pac->position.x = pac_x; pac->direction = none; @@ -33,27 +33,6 @@ static enum movement_direction get_matching_for_directions(game_space field, } -#if 0 -void check_remaining_direction(game_space field, struct pacman *pac, - enum movement_direction *stored_direction) -{ - enum movement_direction temp_direction; - struct free_directions free_path = - find_free_directions(field, pac->position.x, pac->position.y); - enum movement_direction current_direction = - stored_direction ? *stored_direction : pac->direction; - temp_direction = get_correct_path(pac, free_path, current_direction); - if(temp_direction != none) - pac->direction = temp_direction; - else { - current_direction = pac->direction; - pac->direction = get_correct_path(pac, free_path, current_direction); - } - if(stored_direction) - *stored_direction = none; -} -#endif - void check_remaining_direction(game_space field, struct pacman *pac, enum movement_direction *stored_direction) { @@ -121,30 +100,9 @@ void change_pac_direction(game_space field, struct pacman *pac, int key, check_remaining_direction_after_pressed_key(field, pac); } -static int is_coin_symbol(int symbol) -{ - return - symbol == coin || symbol == energizer || symbol == one_path || - symbol == two_paths || symbol == three_paths; -} - -static int check_coin(game_space field, struct coordinates position, - struct queue *eaten_coins) -{ - int x, y; - x = position.x; - y = position.y; - return - is_coin_symbol(field[y][x]) && field_has_coin(x, y) && - !queue_consists_point(eaten_coins, position); -} - static void eat_energizer(game_space field, struct pacman *pac) { - int x, y; - x = pac->position.x; - y = pac->position.y; - if(field[y][x] == energizer) { + if(field_has_energizer(field, pac->position.x, pac->position.y)) { pac->is_energizer_eaten = 1; clear_energizer(field, pac->position); } @@ -170,9 +128,9 @@ void make_pac_move(game_space field, struct pacman *pac, default: return; } - if(check_coin(field, pac->position, eaten_coins)) { + if(check_coin_for_pac(field, pac->position, eaten_coins)) { queue_push(eaten_coins, &pac->position); - ++pac->coins_eaten; + ++pac->score; } change_point_if_outside_tunnel(&pac->position); eat_energizer(field, pac); @@ -181,6 +139,7 @@ void make_pac_move(game_space field, struct pacman *pac, void catch_pac(struct pacman *pac) { --pac->lives; + erase_life(pac->lives); if(pac->lives >= 1) { pac->position.y = pac_y; pac->position.x = pac_x; @@ -11,7 +11,7 @@ enum { struct pacman { char lives; - unsigned char coins_eaten; + unsigned char score; struct coordinates position; enum movement_direction direction; int is_energizer_eaten; @@ -11,12 +11,13 @@ enum { timeout_duration = 0, sleep_duration = 190000, key_escape = 27, - count_get_out_moves = 6, + max_get_out_stage = 6, chase_move_limit = 70, scatter_move_limit = 35, frightened_move_limit = 30, phase_limit = 4, - prison_limit = 30 + prison_limit = 30, + max_score = 243 }; struct mode_type { @@ -26,6 +27,7 @@ struct mode_type { int frightened_count; int phase_number; int reverse_direction; + int get_out_stage; }; struct game_params_type { @@ -33,21 +35,6 @@ struct game_params_type { int pause; }; -static void initialize_params(struct game_params_type *basic_params) -{ - srand(time(NULL)); - initscr(); - start_color(); - cbreak(); - noecho(); - curs_set(0); - keypad(stdscr, 1); - timeout(timeout_duration); - start_color(); - basic_params->exit = 0; - basic_params->pause = 0; -} - static void initialize_ghosts(struct ghost_type *red_ghost, struct ghost_type *pink_ghost, struct ghost_type *blue_ghost, @@ -59,7 +46,7 @@ static void initialize_ghosts(struct ghost_type *red_ghost, initialize_ghost(orange_ghost, orange); } -static void initialize_modes(struct mode_type *mode_params, int *get_out_stage) +static void initialize_modes(struct mode_type *mode_params) { mode_params->current_mode = scatter; mode_params->chase_count = 0; @@ -67,7 +54,26 @@ static void initialize_modes(struct mode_type *mode_params, int *get_out_stage) mode_params->frightened_count = 0; mode_params->phase_number = 0; mode_params->reverse_direction = 0; - *get_out_stage = count_get_out_moves; + mode_params->get_out_stage = max_get_out_stage; +} + +static void initialize_params(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) +{ + timeout(timeout_duration); + *field = get_new_field(); + print_field(*field); + queue_init(eaten_coins); + initialize_pac(pac); + 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); } static int is_up_move_blocked(const struct ghost_type *ghost, @@ -310,11 +316,11 @@ static int is_castling(struct pacman pac, struct ghost_type ghost) } static void catching_stage(game_space field, - struct mode_type *mode_params, int *get_out_stage, - struct pacman *pac, struct ghost_type *red_ghost, - struct ghost_type *pink_ghost, - struct ghost_type *blue_ghost, - struct ghost_type *orange_ghost) + 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; @@ -358,8 +364,8 @@ static void catching_stage(game_space field, catch_pac(pac); if(pac->lives) initialize_ghosts(red_ghost, pink_ghost, blue_ghost, - orange_ghost); - initialize_modes(mode_params, get_out_stage); + orange_ghost); + initialize_modes(mode_params); usleep(sleep_duration); return; } @@ -368,39 +374,32 @@ static void catching_stage(game_space field, current_ghost->capture_info.status = 0; } } -static void show_defeat_screen() + +static void final_stage(struct game_params_type *game_options, int win) { - move(17, 9); - printw("GAME OVER"); + int key; + if(win) { + move(17, 10); + printw("YOU WIN"); + } else { + move(17, 9); + printw("GAME OVER"); + } + move(14, 11); + printw("RETRY?"); + move(15, 12); + printw("Y/N"); refresh(); + timeout(-1); + while((key = getch()) != 'y' && key != 'n') + {} + game_options->exit = (key == 'y') ? 0 : 1; } -static void restart_game(struct game_params_type *basic_params, - game_space field, struct queue *eaten_coins, - struct pacman *pac, struct ghost_type *red_ghost, - struct ghost_type *pink_ghost, - struct ghost_type *blue_ghost, - struct ghost_type *orange_ghost) +static void clear_field_and_queue(game_space field, struct queue *eaten_coins) { - initialize_params(basic_params); - initialize_pac(pac); - initialize_ghosts(red_ghost, pink_ghost, blue_ghost, orange_ghost); clear_field(field); - field = get_new_field(); - print_field(field); queue_clear(eaten_coins); - queue_init(eaten_coins); -} - -static void defeat_stage(struct game_params_type *basic_params) -{ - int key; - show_defeat_screen(); - timeout(-1); - while((key = getch()) != 'y' && key != 'n') - {} - if(key == 'y') - basic_params->exit = 0; } int main() @@ -410,20 +409,21 @@ int main() struct pacman pac; struct queue eaten_coins; struct mode_type mode_params; - struct game_params_type basic_params; - int key, get_out_stage; + struct game_params_type game_options; + int key; enum movement_direction stored_direction; + srand(time(NULL)); + initscr(); + start_color(); + cbreak(); + noecho(); + curs_set(0); + keypad(stdscr, 1); stored_direction = none; - initialize_params(&basic_params); - field = get_new_field(); - print_field(field); - initialize_ghosts(&red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); - initialize_pac(&pac); - initialize_modes(&mode_params, &get_out_stage); - queue_init(&eaten_coins); - display_ghosts_on_field(&red_ghost, &pink_ghost, &blue_ghost, - &orange_ghost); - display_character(pac.position.y, pac.position.x, pac_char); + game_options.exit = 0; + game_options.pause = 0; + initialize_params(&field, &eaten_coins, &mode_params, &pac, &red_ghost, + &pink_ghost, &blue_ghost, &orange_ghost); usleep(sleep_duration); while((key = getch()) != key_escape) { /* @@ -442,9 +442,9 @@ int main() /* * ghosts */ - if(get_out_stage) - pull_out_ghosts(&get_out_stage, &red_ghost, &pink_ghost, - &blue_ghost, &orange_ghost); + if(mode_params.get_out_stage) + pull_out_ghosts(&mode_params.get_out_stage, &red_ghost, + &pink_ghost, &blue_ghost, &orange_ghost); else if(mode_params.reverse_direction) { reverse_all_ghosts(&red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); @@ -461,15 +461,19 @@ int main() &blue_ghost, &orange_ghost); make_ghost_moves(field, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost, &eaten_coins); - /* - * displaying characters + * catching + */ + catching_stage(field, &mode_params, &pac, &red_ghost, &pink_ghost, + &blue_ghost, &orange_ghost); + /* + * displaying characters and score */ - catching_stage(field, &mode_params, &get_out_stage, &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); + display_score(pac.score); + usleep(sleep_duration); prison_leaving_stage(field, &red_ghost, &pink_ghost, &blue_ghost, &orange_ghost); @@ -486,17 +490,21 @@ int main() printw("LIVES: %d", pac.lives); refresh(); #endif - if(!pac.lives) { - defeat_stage(&basic_params); - if(basic_params.exit) - return 0; - else - restart_game(&basic_params, field, &eaten_coins, &pac, - &red_ghost, &pink_ghost, &blue_ghost, - &orange_ghost); + if(!pac.lives || pac.score == max_score ) { + final_stage(&game_options, !pac.lives ? 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); + } } } - queue_clear(&eaten_coins); + clear_field_and_queue(field, &eaten_coins); endwin(); return 0; } |