back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/pacman.c
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-04-18 20:05:03 +0300
committerscratko <m@scratko.xyz>2024-04-18 20:05:03 +0300
commit29afbdf8e26f741ac1d090f2e7704093253f17fc (patch)
tree453dff441936bf712aaa72d27b62f5ca5d0f1bbf /pacman.c
parentef3844bf2128fa82f20c5995d1fca66fadba2ce3 (diff)
downloadpacman-29afbdf8e26f741ac1d090f2e7704093253f17fc.tar.gz
pacman-29afbdf8e26f741ac1d090f2e7704093253f17fc.tar.bz2
pacman-29afbdf8e26f741ac1d090f2e7704093253f17fc.zip
Release version
Diffstat (limited to 'pacman.c')
-rw-r--r--pacman.c242
1 files changed, 161 insertions, 81 deletions
diff --git a/pacman.c b/pacman.c
index ce2fd5d..15a4b63 100644
--- a/pacman.c
+++ b/pacman.c
@@ -7,15 +7,17 @@
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
+#include <stdio.h>
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,9 +525,20 @@ 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
*/
if(key != ERR)
@@ -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;
}