back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/ghosts.c
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-04-02 17:43:35 +0300
committerscratko <m@scratko.xyz>2024-04-02 17:43:35 +0300
commitbdee2852c13f6b02ec5207ded584839a3118233e (patch)
tree39f1c14be91fb848ce0f94a64532e48a7667e5de /ghosts.c
downloadpacman-bdee2852c13f6b02ec5207ded584839a3118233e.tar.gz
pacman-bdee2852c13f6b02ec5207ded584839a3118233e.tar.bz2
pacman-bdee2852c13f6b02ec5207ded584839a3118233e.zip
Initial commit
Diffstat (limited to 'ghosts.c')
-rw-r--r--ghosts.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/ghosts.c b/ghosts.c
new file mode 100644
index 0000000..2559740
--- /dev/null
+++ b/ghosts.c
@@ -0,0 +1,140 @@
+#include "ghosts.h"
+#include "field.h"
+
+void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
+{
+ switch(color) {
+ case red:
+ ghost->position.y = red_y;
+ ghost->position.x = red_x;
+ ghost->home_position.y = red_home_y;
+ ghost->home_position.x = red_home_x;
+ ghost->color = red;
+ ghost->mode = scatter;
+ ghost->direction = none;
+ break;
+ case pink:
+ ghost->position.y = pink_y;
+ ghost->position.x = pink_x;
+ ghost->home_position.y = pink_home_y;
+ ghost->home_position.x = pink_home_x;
+ ghost->color = pink;
+ ghost->mode = scatter;
+ ghost->direction = none;
+ break;
+ case blue:
+ ghost->position.y = blue_y;
+ ghost->position.x = blue_x;
+ ghost->home_position.y = blue_home_y;
+ ghost->home_position.x = blue_home_x;
+ ghost->color = blue;
+ ghost->mode = scatter;
+ ghost->direction = none;
+ break;
+ case orange:
+ ghost->position.y = orange_y;
+ ghost->position.x = orange_x;
+ ghost->home_position.y = orange_home_y;
+ ghost->home_position.x = orange_home_x;
+ ghost->color = orange;
+ ghost->mode = scatter;
+ ghost->direction = none;
+ break;
+ }
+}
+
+void pull_out_ghosts(int *get_out_stage,
+ struct ghost_type *red_ghost,
+ struct ghost_type *pink_ghost,
+ struct ghost_type *blue_ghost,
+ struct ghost_type *orange_ghost)
+{
+ enum { final_stage = 1 };
+ enum movement_direction red_moves[] = { none, right, up, up, left };
+ enum movement_direction blue_moves[] = { none, left, up, up, left };
+ enum movement_direction pink_moves[] = { right, up, up, up, right };
+ enum movement_direction orange_moves[] = { left, up, up, up, right };
+ int index = *get_out_stage - 1;
+ if(*get_out_stage > final_stage) {
+ red_ghost->direction = red_moves[index];
+ blue_ghost->direction = blue_moves[index];
+ }
+ pink_ghost->direction = pink_moves[index];
+ orange_ghost->direction = orange_moves[index];
+ --*get_out_stage;
+}
+
+static void change_position(struct ghost_type *ghost,
+ enum movement_direction direction)
+{
+ switch(direction) {
+ case left:
+ --ghost->position.x;
+ return;
+ case right:
+ ++ghost->position.x;
+ return;
+ case up:
+ --ghost->position.y;
+ return;
+ case down:
+ ++ghost->position.y;
+ return;
+ default:
+ return;
+ }
+}
+
+void make_ghost_moves(game_space field,
+ struct ghost_type *red_ghost,
+ struct ghost_type *pink_ghost,
+ struct ghost_type *blue_ghost,
+ struct ghost_type *orange_ghost)
+{
+ clear_symbol(field, red_ghost->position.y, red_ghost->position.x,
+ ghost_char);
+ clear_symbol(field, pink_ghost->position.y, pink_ghost->position.x,
+ ghost_char);
+ clear_symbol(field, blue_ghost->position.y, blue_ghost->position.x,
+ ghost_char);
+ clear_symbol(field, orange_ghost->position.y, orange_ghost->position.x,
+ ghost_char);
+ change_position(red_ghost, red_ghost->direction);
+ change_position(pink_ghost, pink_ghost->direction);
+ change_position(blue_ghost, blue_ghost->direction);
+ change_position(orange_ghost, orange_ghost->direction);
+}
+
+static void pave_only_way(game_space field, struct ghost_type *ghost)
+{
+ struct free_directions path = find_free_directions(field, ghost->position.y,
+ ghost->position.x);
+ enum movement_direction reverse_direction = ghost->direction;
+ reverse_direction ^= 1;
+ if(path.left && left != reverse_direction)
+ ghost->direction = left;
+ else if(path.right && right != reverse_direction)
+ ghost->direction = right;
+ else if(path.up && up != reverse_direction)
+ ghost->direction = up;
+ else if(path.down && down != reverse_direction)
+ ghost->direction = down;
+}
+
+void redirect(game_space field, enum intersection_type paths,
+ struct ghost_type *ghost,
+ void (*pathfinder)(game_space field, enum intersection_type paths,
+ struct ghost_type *ghost))
+{
+ if(paths == one_path)
+ pave_only_way(field, ghost);
+ else if(paths == two_paths || paths == three_paths)
+ pathfinder(field, paths, ghost);
+}
+
+
+void breadth_first_search(game_space field, enum intersection_type paths,
+ struct ghost_type *ghost)
+{
+
+}