back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-04-15 20:40:14 +0300
committerscratko <m@scratko.xyz>2024-04-15 20:40:14 +0300
commite42ac35110b1819bf9762fbb4504ab920a17e207 (patch)
tree8d5465dc0251f392883dc8e01dcae1fba7ec715b
parent0cf5dfed3e492608d044a5fc90c1815fab506fd7 (diff)
downloadpacman-e42ac35110b1819bf9762fbb4504ab920a17e207.tar.gz
pacman-e42ac35110b1819bf9762fbb4504ab920a17e207.tar.bz2
pacman-e42ac35110b1819bf9762fbb4504ab920a17e207.zip
Game over and restart
Game over screen. Corrected coordinates in is_liberation_zone(). The capture of pacman. Changed the function name from caughting_stage() to catching_stage().
-rw-r--r--field.c9
-rw-r--r--field.h2
-rw-r--r--ghosts.c18
-rw-r--r--pac.c10
-rw-r--r--pac.h2
-rw-r--r--pacman.c275
6 files changed, 200 insertions, 116 deletions
diff --git a/field.c b/field.c
index 340e380..560cae9 100644
--- a/field.c
+++ b/field.c
@@ -53,6 +53,12 @@ game_space get_new_field()
return field;
}
+void clear_field(game_space field)
+{
+ free(field);
+ field = NULL;
+}
+
int field_has_coin(int x, int y)
{
return !((x == 9 && y == 12)|| (x == 18 && y == 12) ||
@@ -107,6 +113,9 @@ void print_field(game_space field)
case door:
addch('#');
break;
+ case ' ':
+ addch(' ');
+ break;
}
refresh();
}
diff --git a/field.h b/field.h
index 56921d6..4f84dc6 100644
--- a/field.h
+++ b/field.h
@@ -67,4 +67,6 @@ void clear_energizer(game_space field, struct coordinates point);
int is_equal_points(struct coordinates first_point, struct coordinates
second_point);
+void clear_field(game_space field);
+
#endif
diff --git a/ghosts.c b/ghosts.c
index 20d19dd..d558ba5 100644
--- a/ghosts.c
+++ b/ghosts.c
@@ -19,8 +19,8 @@ void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
ghost->color = red;
ghost->frightened_status = 0;
ghost->direction = none;
- ghost->prison_params.position.x = red_home_x;
- ghost->prison_params.position.y = red_home_y;
+ ghost->prison_params.position.x = red_prison_x;
+ ghost->prison_params.position.y = red_prison_y;
ghost->prison_params.prison_counter = 0;
ghost->prison_params.active = 0;
ghost->capture_info.status = 0;
@@ -33,8 +33,8 @@ void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
ghost->color = pink;
ghost->frightened_status = 0;
ghost->direction = none;
- ghost->prison_params.position.x = pink_home_x;
- ghost->prison_params.position.y = pink_home_y;
+ ghost->prison_params.position.x = pink_prison_x;
+ ghost->prison_params.position.y = pink_prison_y;
ghost->prison_params.prison_counter = 0;
ghost->prison_params.active = 0;
ghost->capture_info.status = 0;
@@ -47,8 +47,8 @@ void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
ghost->color = blue;
ghost->frightened_status = 0;
ghost->direction = none;
- ghost->prison_params.position.x = blue_home_x;
- ghost->prison_params.position.y = blue_home_y;
+ ghost->prison_params.position.x = blue_prison_x;
+ ghost->prison_params.position.y = blue_prison_y;
ghost->prison_params.prison_counter = 0;
ghost->prison_params.active = 0;
ghost->capture_info.status = 0;
@@ -61,8 +61,8 @@ void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
ghost->color = orange;
ghost->frightened_status = 0;
ghost->direction = none;
- ghost->prison_params.position.x = orange_home_x;
- ghost->prison_params.position.y = orange_home_y;
+ ghost->prison_params.position.x = orange_prison_x;
+ ghost->prison_params.position.y = orange_prison_y;
ghost->prison_params.prison_counter = 0;
ghost->prison_params.active = 0;
ghost->capture_info.status = 0;
@@ -429,7 +429,7 @@ void random_redirect(game_space field, struct ghost_type *ghost)
static int is_liberation_zone(const struct ghost_type *ghost)
{
return ghost->position.y == liberation_y &&
- (ghost->position.x == 14 || ghost->position.x == 15) &&
+ (ghost->position.x == 13 || ghost->position.x == 14) &&
ghost->direction == up;
}
diff --git a/pac.c b/pac.c
index 6579e14..97c3833 100644
--- a/pac.c
+++ b/pac.c
@@ -177,3 +177,13 @@ void make_pac_move(game_space field, struct pacman *pac,
change_point_if_outside_tunnel(&pac->position);
eat_energizer(field, pac);
}
+
+void catch_pac(struct pacman *pac)
+{
+ --pac->lives;
+ if(pac->lives >= 1) {
+ pac->position.y = pac_y;
+ pac->position.x = pac_x;
+ pac->direction = none;
+ }
+}
diff --git a/pac.h b/pac.h
index ccee0e3..29e83a1 100644
--- a/pac.h
+++ b/pac.h
@@ -28,4 +28,6 @@ struct queue;
void make_pac_move(game_space field, struct pacman *pac,
struct queue *eaten_coins);
+void catch_pac(struct pacman *pac);
+
#endif
diff --git a/pacman.c b/pacman.c
index 1fb296c..679fcc2 100644
--- a/pacman.c
+++ b/pacman.c
@@ -28,39 +28,46 @@ struct mode_type {
int reverse_direction;
};
-static void change_mode(struct mode_type *mode_params)
+struct game_params_type {
+ int exit;
+ int pause;
+};
+
+static void initialize_params(struct game_params_type *basic_params)
{
- 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) {
- mode_params->current_mode = scatter;
- mode_params->chase_count = 0;
- ++mode_params->phase_number;
- if(mode_params->phase_number == phase_limit)
- mode_params->current_mode = chase;
- if(mode_params->phase_number != phase_limit)
- ++mode_params->reverse_direction;
- }
- break;
- case scatter:
- if(mode_params->scatter_count > scatter_move_limit) {
- mode_params->current_mode = chase;
- mode_params->scatter_count = 0;
- ++mode_params->reverse_direction;
- }
- break;
- case frightened:
- if(mode_params->frightened_count > frightened_move_limit) {
- mode_params->current_mode =
- mode_params->chase_count || mode_params->phase_number ==
- phase_limit ? chase : scatter;
- mode_params->frightened_count = 0;
- ++mode_params->reverse_direction;
- }
- }
+ 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,
+ struct ghost_type *orange_ghost)
+{
+ initialize_ghost(red_ghost, red);
+ initialize_ghost(pink_ghost, pink);
+ initialize_ghost(blue_ghost, blue);
+ initialize_ghost(orange_ghost, orange);
+}
+
+static void initialize_modes(struct mode_type *mode_params, int *get_out_stage)
+{
+ mode_params->current_mode = scatter;
+ mode_params->chase_count = 0;
+ mode_params->scatter_count = 0;
+ mode_params->frightened_count = 0;
+ mode_params->phase_number = 0;
+ mode_params->reverse_direction = 0;
+ *get_out_stage = count_get_out_moves;
}
static int is_up_move_blocked(const struct ghost_type *ghost,
@@ -168,6 +175,84 @@ static void random_pathfinder_stage(game_space field,
}
}
+static void change_mode(struct mode_type *mode_params)
+{
+ 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) {
+ mode_params->current_mode = scatter;
+ mode_params->chase_count = 0;
+ ++mode_params->phase_number;
+ if(mode_params->phase_number == phase_limit)
+ mode_params->current_mode = chase;
+ if(mode_params->phase_number != phase_limit)
+ ++mode_params->reverse_direction;
+ }
+ break;
+ case scatter:
+ if(mode_params->scatter_count > scatter_move_limit) {
+ mode_params->current_mode = chase;
+ mode_params->scatter_count = 0;
+ ++mode_params->reverse_direction;
+ }
+ break;
+ case frightened:
+ if(mode_params->frightened_count > frightened_move_limit) {
+ mode_params->current_mode =
+ mode_params->chase_count || mode_params->phase_number ==
+ phase_limit ? chase : scatter;
+ mode_params->frightened_count = 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 ghost_type *pink_ghost,
+ struct ghost_type *blue_ghost,
+ struct ghost_type *orange_ghost)
+{
+ 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);
+ }
+}
+
+static void scatter_mode(game_space field, struct mode_type *mode_params,
+ struct ghost_type *red_ghost,
+ struct ghost_type *pink_ghost,
+ struct ghost_type *blue_ghost,
+ struct ghost_type *orange_ghost)
+{
+ 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);
+ }
+}
+
+static void frightened_mode(game_space field, struct mode_type *mode_params,
+ 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);
+}
+
static int is_outside_prison(struct ghost_type ghost)
{
return ghost.prison_params.active && ghost.direction == up;
@@ -224,8 +309,8 @@ static int is_castling(struct pacman pac, struct ghost_type ghost)
ghost.position.y == ghost.capture_info.previous_pac_position.y;
}
-static void caughting_stage(game_space field,
- const struct mode_type *mode_params,
+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,
@@ -269,89 +354,53 @@ static void caughting_stage(game_space field,
is_castling(*pac, *current_ghost)) {
if(mode_params->current_mode == frightened)
catch_ghost(field, current_ghost);
- else
- --pac->lives;
+ else {
+ catch_pac(pac);
+ if(pac->lives)
+ initialize_ghosts(red_ghost, pink_ghost, blue_ghost,
+ orange_ghost);
+ initialize_modes(mode_params, get_out_stage);
+ usleep(sleep_duration);
+ return;
+ }
}
- current_ghost->capture_info.status = 0;
+ if(current_ghost->capture_info.status)
+ 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,
- struct ghost_type *pink_ghost,
- struct ghost_type *blue_ghost,
- struct ghost_type *orange_ghost)
+static void show_defeat_screen()
{
- 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);
- }
+ move(17, 9);
+ printw("GAME OVER");
+ refresh();
}
-static void scatter_mode(game_space field, struct mode_type *mode_params,
- struct ghost_type *red_ghost,
+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)
{
- 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);
- }
-}
-
-static void frightened_mode(game_space field, struct mode_type *mode_params,
- 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);
-}
-
-static void initialize_ghosts(struct ghost_type *red_ghost,
- struct ghost_type *pink_ghost,
- struct ghost_type *blue_ghost,
- struct ghost_type *orange_ghost)
-{
- initialize_ghost(red_ghost, red);
- initialize_ghost(pink_ghost, pink);
- initialize_ghost(blue_ghost, blue);
- initialize_ghost(orange_ghost, orange);
-}
-
-static void initialize_modes(struct mode_type *mode_params, int *get_out_stage)
-{
- mode_params->current_mode = scatter;
- mode_params->chase_count = 0;
- mode_params->scatter_count = 0;
- mode_params->frightened_count = 0;
- mode_params->phase_number = 0;
- mode_params->reverse_direction = 0;
- *get_out_stage = count_get_out_moves;
+ 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 initialize_params()
+static void defeat_stage(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();
+ int key;
+ show_defeat_screen();
+ timeout(-1);
+ while((key = getch()) != 'y' && key != 'n')
+ {}
+ if(key == 'y')
+ basic_params->exit = 0;
}
int main()
@@ -361,10 +410,11 @@ 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;
enum movement_direction stored_direction;
stored_direction = none;
- initialize_params();
+ initialize_params(&basic_params);
field = get_new_field();
print_field(field);
initialize_ghosts(&red_ghost, &pink_ghost, &blue_ghost, &orange_ghost);
@@ -415,8 +465,8 @@ int main()
/*
* displaying characters
*/
- caughting_stage(field, &mode_params, &pac, &red_ghost, &pink_ghost,
- &blue_ghost, &orange_ghost);
+ 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);
@@ -432,8 +482,19 @@ int main()
printw("SCATTER %d ", mode_params.scatter_count);
else if(mode_params.current_mode == frightened)
printw("FRIGHTENED %d ", mode_params.frightened_count);
+ move(1, 50);
+ 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);
+ }
}
queue_clear(&eaten_coins);
endwin();