back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/pacman.c
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-04-12 03:17:46 +0300
committerscratko <m@scratko.xyz>2024-04-12 03:17:46 +0300
commit04a6703fd66a7d34b2556a9c203c4dada3baca38 (patch)
tree3d2cbdaae515d90747e507ba8a8ebfd7bdc44fed /pacman.c
parent235f8481502263fcdb4823ff0bc4e8f831bc934d (diff)
downloadpacman-04a6703fd66a7d34b2556a9c203c4dada3baca38.tar.gz
pacman-04a6703fd66a7d34b2556a9c203c4dada3baca38.tar.bz2
pacman-04a6703fd66a7d34b2556a9c203c4dada3baca38.zip
Added behavior modes
Reverse direction Random direction
Diffstat (limited to 'pacman.c')
-rw-r--r--pacman.c218
1 files changed, 197 insertions, 21 deletions
diff --git a/pacman.c b/pacman.c
index 95d121d..f9b1278 100644
--- a/pacman.c
+++ b/pacman.c
@@ -5,14 +5,62 @@
#include <ncurses.h>
#include <stdlib.h>
#include <unistd.h>
+#include <time.h>
enum {
- timeout_duration = 0,
- sleep_duration = 190000,
- key_escape = 27,
- count_get_out_moves = 5
+ timeout_duration = 0,
+ sleep_duration = 190000,
+ key_escape = 27,
+ count_get_out_moves = 6,
+ chase_move_limit = 100,
+ scatter_move_limit = 35,
+ frightened_move_limit = 30,
+ phase_limit = 4
};
+struct mode_type {
+ enum behavior_mode current_mode;
+ int chase_count;
+ int scatter_count;
+ int frightened_count;
+ int phase_number;
+ int reverse_direction;
+};
+
+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;
+ ++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 int is_up_move_blocked(const struct ghost_type *ghost,
enum intersection_type intersection)
{
@@ -20,7 +68,9 @@ static int is_up_move_blocked(const struct ghost_type *ghost,
ghost->direction == right);
}
-static void pathfinder_stage(game_space field, struct pacman pac,
+static void pathfinder_stage(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,
@@ -30,39 +80,117 @@ static void pathfinder_stage(game_space field, struct pacman pac,
enum intersection_type intersection;
int color_priority;
struct ghost_type *current_ghost;
- struct coordinates target_point;
+ struct coordinates new_target_point;
for(color_priority = 0; color_priority <= orange; ++color_priority) {
switch(color_priority) {
case red:
current_ghost = red_ghost;
- target_point = pac.position;
- search_method = breadth_first_search;
+ new_target_point = mode_params->current_mode == scatter ?
+ current_ghost->home_position : pac->position;
+ search_method = mode_params->current_mode == scatter ?
+ compute_distance_between_points : breadth_first_search;
break;
case pink:
current_ghost = pink_ghost;
- target_point = identify_target_in_front(pac, pink_shift);
+ new_target_point = mode_params->current_mode == scatter ?
+ current_ghost->home_position :
+ identify_target_in_front(*pac, pink_shift);
search_method = compute_distance_between_points;
break;
case blue:
current_ghost = blue_ghost;
- target_point = identify_blue_target(pac, red_ghost);
+ new_target_point = mode_params->current_mode == scatter ?
+ current_ghost->home_position :
+ identify_blue_target(*pac, red_ghost);
search_method = compute_distance_between_points;
break;
case orange:
current_ghost = orange_ghost;
- target_point = pac.position;
- search_method = breadth_first_search;
- break;
+ new_target_point = mode_params->current_mode == scatter ?
+ current_ghost->home_position : pac->position;
+ search_method = mode_params->current_mode == scatter ?
+ compute_distance_between_points : breadth_first_search;
}
intersection = get_intersection(field, current_ghost);
if(is_up_move_blocked(current_ghost, intersection))
continue;
if(intersection != direct_path)
- redirect(field, intersection, current_ghost, target_point,
+ redirect(field, intersection, current_ghost, new_target_point,
search_method);
}
}
+static void random_pathfinder_stage(game_space field,
+ struct ghost_type *red_ghost,
+ struct ghost_type *pink_ghost,
+ struct ghost_type *blue_ghost,
+ struct ghost_type *orange_ghost)
+{
+ enum intersection_type intersection;
+ int color_priority;
+ struct ghost_type *current_ghost;
+ 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;
+ }
+ intersection = get_intersection(field, current_ghost);
+ if(intersection != direct_path)
+ random_redirect(field, current_ghost);
+ }
+}
+
+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);
+}
+
static void initialize_ghosts(struct ghost_type *red_ghost,
struct ghost_type *pink_ghost,
struct ghost_type *blue_ghost,
@@ -74,8 +202,20 @@ static void initialize_ghosts(struct ghost_type *red_ghost,
initialize_ghost(orange_ghost, orange);
}
-static void ncurses_params()
+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 void initialize_params()
{
+ srand(time(NULL));
initscr();
start_color();
cbreak();
@@ -92,38 +232,74 @@ int main()
struct ghost_type red_ghost, pink_ghost, blue_ghost, orange_ghost;
struct pacman pac;
struct queue eaten_coins;
+ struct mode_type mode_params;
int key, get_out_stage;
enum movement_direction stored_direction;
stored_direction = none;
- get_out_stage = count_get_out_moves;
- ncurses_params();
+ initialize_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);
usleep(sleep_duration);
while((key = getch()) != key_escape) {
+ /*
+ * pacman
+ */
if(key != ERR)
change_pac_direction(field, &pac, key, &stored_direction);
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;
+ }
+ /*
+ * ghosts
+ */
if(get_out_stage)
pull_out_ghosts(&get_out_stage, &red_ghost, &pink_ghost,
&blue_ghost, &orange_ghost);
- else
- pathfinder_stage(field, pac, &red_ghost, &pink_ghost, &blue_ghost,
- &orange_ghost);
- make_pac_move(field, &pac, &eaten_coins);
+ else if(mode_params.reverse_direction) {
+ reverse_all_ghosts(&red_ghost, &pink_ghost,
+ &blue_ghost, &orange_ghost);
+ mode_params.reverse_direction = 0;
+ }
+ else if(mode_params.current_mode == chase)
+ 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,
+ &blue_ghost, &orange_ghost);
+ else if(mode_params.current_mode == frightened)
+ frightened_mode(field, &mode_params, &red_ghost, &pink_ghost,
+ &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);
display_ghosts_on_field(&red_ghost, &pink_ghost, &blue_ghost,
&orange_ghost);
usleep(sleep_duration);
+#if 1
+ move(0, 50);
+ if(mode_params.current_mode == chase)
+ printw("CHASE");
+ else if(mode_params.current_mode == scatter)
+ printw("SCATTER");
+ else if(mode_params.current_mode == frightened)
+ printw("FRIGHTENED");
+ refresh();
+#endif
}
queue_clear(&eaten_coins);
endwin();