back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--field.c85
-rw-r--r--field.h11
-rw-r--r--pac.c51
-rw-r--r--pac.h2
-rw-r--r--pacman.c168
5 files changed, 169 insertions, 148 deletions
diff --git a/field.c b/field.c
index 560cae9..06179c9 100644
--- a/field.c
+++ b/field.c
@@ -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();
+}
diff --git a/field.h b/field.h
index 4f84dc6..1543ea8 100644
--- a/field.h
+++ b/field.h
@@ -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
diff --git a/pac.c b/pac.c
index 97c3833..c3fcbb7 100644
--- a/pac.c
+++ b/pac.c
@@ -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;
diff --git a/pac.h b/pac.h
index 29e83a1..ea0825b 100644
--- a/pac.h
+++ b/pac.h
@@ -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;
diff --git a/pacman.c b/pacman.c
index 679fcc2..1468765 100644
--- a/pacman.c
+++ b/pacman.c
@@ -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;
}