back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-04-17 17:00:48 +0300
committerscratko <m@scratko.xyz>2024-04-17 18:33:03 +0300
commitef3844bf2128fa82f20c5995d1fca66fadba2ce3 (patch)
tree905048a285a8cd8fd6a070ce3b6c075e9681e59a
parent194f71c150eb9ee696acca17176092e8b0ce6e4f (diff)
downloadpacman-ef3844bf2128fa82f20c5995d1fca66fadba2ce3.tar.gz
pacman-ef3844bf2128fa82f20c5995d1fca66fadba2ce3.tar.bz2
pacman-ef3844bf2128fa82f20c5995d1fca66fadba2ce3.zip
Added colors
Changed the number of pacman's lives. Fixed clear_or_revert_symbol(). Target hit display. Changed ghost initialization. Clearing ghost positions is moved to the function. Added flag in struct ghost_type (reached_pacman). Changed catching stage. Now eating an energizer resets the counter.
-rw-r--r--Makefile2
-rw-r--r--color_palette.c69
-rw-r--r--color_palette.h15
-rw-r--r--field.c112
-rw-r--r--field.h10
-rw-r--r--ghosts.c46
-rw-r--r--ghosts.h7
-rw-r--r--pac.c5
-rw-r--r--pac.h2
-rw-r--r--pacman.c72
10 files changed, 266 insertions, 74 deletions
diff --git a/Makefile b/Makefile
index 334b90d..12433c4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-SRCMODULES = field.c ghosts.c pac.c queue.c pacman.c
+SRCMODULES = field.c ghosts.c pac.c queue.c color_palette.c pacman.c
OBJMODULES = $(SRCMODULES:.c=.o)
CC = gcc
CFLAGS = -Wall -g -c -D DEBUG
diff --git a/color_palette.c b/color_palette.c
new file mode 100644
index 0000000..e839e8b
--- /dev/null
+++ b/color_palette.c
@@ -0,0 +1,69 @@
+#include "color_palette.h"
+#include <ncurses.h>
+
+void set_pairs()
+{
+ init_pair(2, COLOR_BLUE, COLOR_BLUE);
+ init_pair(3, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(4, COLOR_MAGENTA, COLOR_MAGENTA);
+ init_pair(5, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(6, COLOR_RED, COLOR_BLACK);
+ init_pair(7, COLOR_BLUE, COLOR_BLACK);
+ init_pair(8, COLOR_MAGENTA, COLOR_BLACK);
+}
+
+void paint_field_element(int element)
+{
+ int color;
+ switch(element) {
+ case block:
+ color = COLOR_PAIR(2);
+ break;
+ case coin:
+ color = COLOR_PAIR(3) | A_BOLD;
+ break;
+ case door:
+ color = COLOR_PAIR(4);
+ break;
+ }
+ attrset(color);
+}
+
+void paint_stats()
+{
+ attrset(COLOR_PAIR(5));
+}
+
+void paint_ghost(enum ghost_color color, int blink)
+{
+ int attr;
+ switch(color) {
+ case red:
+ attr = COLOR_PAIR(6);
+ break;
+ case pink:
+ attr = COLOR_PAIR(8);
+ break;
+ case blue:
+ attr = COLOR_PAIR(7);
+ break;
+ case orange:
+ attr = COLOR_PAIR(3);
+ }
+ attrset(attr);
+}
+
+void paint_pac()
+{
+ attrset(COLOR_PAIR(3) | A_BOLD);
+}
+
+void paint_hit()
+{
+ attrset(COLOR_PAIR(6));
+}
+
+void reset_attr()
+{
+ attrset(A_NORMAL);
+}
diff --git a/color_palette.h b/color_palette.h
new file mode 100644
index 0000000..81ccce8
--- /dev/null
+++ b/color_palette.h
@@ -0,0 +1,15 @@
+#ifndef COLOR_PALETTE_H_SENTRY
+#define COLOR_PALETTE_H_SENTRY
+
+#include "field.h"
+#include "ghosts.h"
+
+void set_pairs();
+void paint_field_element(int element);
+void paint_stats();
+void paint_ghost(enum ghost_color color, int blink);
+void paint_pac();
+void paint_hit();
+void reset_attr();
+
+#endif
diff --git a/field.c b/field.c
index 06179c9..f0190e9 100644
--- a/field.c
+++ b/field.c
@@ -3,6 +3,7 @@
#include "queue.h"
#include <ncurses.h>
#include <stdlib.h>
+#include "color_palette.h"
static const char field_sample[field_height][field_width] = {
{"////////////////////////////"},
@@ -34,7 +35,7 @@ static const char field_sample[field_height][field_width] = {
{"/.//////////.//.//////////./"},
{"/1..........2..2..........1/"},
{"////////////////////////////"},
- {" C C C Score: "}
+ {" C C Score: "}
};
static void copy_field(game_space field)
@@ -107,6 +108,7 @@ void print_field(game_space field)
symbol = field[i][j];
move(i, j);
if(is_coin_symbol(symbol, j, i) && field_has_coin(j, i)) {
+ paint_field_element(coin);
symbol == energizer ? addch('*') : addch('.');
continue;
}
@@ -114,23 +116,31 @@ void print_field(game_space field)
case one_path:
case two_paths:
case yellow_block:
+ reset_attr();
addch(' ');
break;
case block:
- addch('/');
+ paint_field_element(block);
+ addch(' ');
break;
+#if 0
case energizer:
addch('*');
break;
+#endif
case door:
- addch('#');
+ paint_field_element(door);
+ addch(' ');
break;
case ' ':
+ reset_attr();
addch(' ');
break;
}
- if(i == field_height-1)
+ if(i == field_height-1) {
+ symbol != ' ' ? paint_stats() : reset_attr();
addch(symbol);
+ }
refresh();
}
}
@@ -139,6 +149,8 @@ void print_field(game_space field)
void display_character(int y, int x, enum select_character symbol)
{
move(y, x);
+ if(symbol == pac_char)
+ paint_pac();
addch(symbol);
refresh();
}
@@ -148,11 +160,15 @@ void display_ghosts_on_field(struct ghost_type *red_ghost,
struct ghost_type *blue_ghost,
struct ghost_type *orange_ghost)
{
+ paint_ghost(red_ghost->color, red_ghost->frightened_status);
display_character(red_ghost->position.y, red_ghost->position.x, ghost_char);
+ paint_ghost(pink_ghost->color, pink_ghost->frightened_status);
display_character(pink_ghost->position.y, pink_ghost->position.x,
ghost_char);
+ paint_ghost(blue_ghost->color, blue_ghost->frightened_status);
display_character(blue_ghost->position.y, blue_ghost->position.x,
ghost_char);
+ paint_ghost(orange_ghost->color, orange_ghost->frightened_status);
display_character(orange_ghost->position.y, orange_ghost->position.x,
ghost_char);
}
@@ -160,13 +176,14 @@ void display_ghosts_on_field(struct ghost_type *red_ghost,
void display_score(int value)
{
move(field_height-1, 25);
+ paint_stats();
printw("%d", value);
refresh();
}
void clear_or_revert_symbol(const game_space field, struct coordinates position,
enum select_character character,
- struct queue *eaten_coins)
+ const struct queue *eaten_coins)
{
int x, y;
x = position.x;
@@ -174,40 +191,44 @@ void clear_or_revert_symbol(const game_space field, struct coordinates position,
int symbol = field[y][x];
move(y, x);
if(character == ghost_char) {
+ if(is_coin_symbol(symbol, x, y) && field_has_coin(x, y) &&
+ !queue_consists_point(eaten_coins, position)) {
+ if(symbol == energizer && field_has_energizer(field, x, y)) {
+ paint_field_element(coin);
+ addch('*');
+ } else {
+ paint_field_element(coin);
+ addch('.');
+ }
+ refresh();
+ return;
+ }
switch(symbol) {
case one_path:
case two_paths:
case three_paths:
- if(field_has_coin(x, y))
- queue_consists_point(eaten_coins, position) ?
- addch(' ') : addch('.');
- else
- addch(' ');
- break;
case yellow_block:
- if(yellow_block_contains_coin(x, y))
- queue_consists_point(eaten_coins, position) ?
- addch(' ') : addch('.');
- else
- addch(' ');
+ reset_attr();
+ addch(' ');
+ break;
+ case coin:
+ reset_attr();
+ addch(' ');
break;
case door:
+ paint_field_element(door);
addch('#');
break;
- case energizer:
- field_has_energizer(field, x, y) ? addch('*') : addch(' ');
- break;
- case coin:
- queue_consists_point(eaten_coins, position) ?
- addch(' ') : addch('.');
- break;
case ' ':
+ reset_attr();
addch(' ');
break;
}
}
- else if(character == pac_char)
+ else if(character == pac_char) {
+ reset_attr();
addch(' ');
+ }
refresh();
}
@@ -288,25 +309,54 @@ int is_equal_points(struct coordinates first_point, struct coordinates
void erase_life(int value)
{
enum {
- two_lives_left = 2,
one_life_left = 1,
no_lives_left = 0,
gap = 2,
- three_lives_x = 5
+ two_lives_x = 3
};
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;
+ x = two_lives_x;
break;
case no_lives_left:
- x = three_lives_x - gap * 2;
+ x = two_lives_x - gap;
}
move(y, x);
+ reset_attr();
+ addch(' ');
+ refresh();
+}
+
+void display_hit(struct coordinates pac_position,
+ const struct ghost_type *red_ghost,
+ const struct ghost_type *pink_ghost,
+ const struct ghost_type *blue_ghost,
+ const struct ghost_type *orange_ghost)
+{
+ struct coordinates ghost_position;
+ if(red_ghost->reached_pacman)
+ ghost_position = red_ghost->position;
+ else if(pink_ghost->reached_pacman)
+ ghost_position = pink_ghost->position;
+ else if(blue_ghost->reached_pacman)
+ ghost_position = blue_ghost->position;
+ else
+ ghost_position = orange_ghost->position;
+ reset_attr();
+ move(ghost_position.y, ghost_position.x);
+ addch(' ');
+ paint_hit();
+ move(pac_position.y, pac_position.x);
+ addch('X');
+ refresh();
+}
+
+void erase_hit(struct coordinates point)
+{
+ move(point.y, point.x);
+ reset_attr();
addch(' ');
refresh();
}
diff --git a/field.h b/field.h
index 1543ea8..c527309 100644
--- a/field.h
+++ b/field.h
@@ -45,12 +45,17 @@ void display_ghosts_on_field(struct ghost_type *red_ghost,
struct ghost_type *blue_ghost,
struct ghost_type *orange_ghost);
void display_score(int value);
+struct coordinates;
+void display_hit(struct coordinates pac_position,
+ const struct ghost_type *red_ghost,
+ const struct ghost_type *pink_ghost,
+ const struct ghost_type *blue_ghost,
+ const struct ghost_type *orange_ghost);
struct queue;
-struct coordinates;
void clear_or_revert_symbol(game_space field, struct coordinates position,
enum select_character character,
- struct queue *eaten_coins);
+ const struct queue *eaten_coins);
enum intersection_type get_intersection(const game_space field,
struct ghost_type *ghost);
@@ -75,5 +80,6 @@ int is_equal_points(struct coordinates first_point, struct coordinates
void clear_field(game_space field);
void erase_life(int value);
+void erase_hit(struct coordinates point);
#endif
diff --git a/ghosts.c b/ghosts.c
index d558ba5..5c60200 100644
--- a/ghosts.c
+++ b/ghosts.c
@@ -17,13 +17,8 @@ void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
ghost->home_position.y = red_home_y;
ghost->home_position.x = red_home_x;
ghost->color = red;
- ghost->frightened_status = 0;
- ghost->direction = none;
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;
break;
case pink:
ghost->position.y = pink_y;
@@ -31,13 +26,8 @@ void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
ghost->home_position.y = pink_home_y;
ghost->home_position.x = pink_home_x;
ghost->color = pink;
- ghost->frightened_status = 0;
- ghost->direction = none;
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;
break;
case blue:
ghost->position.y = blue_y;
@@ -45,13 +35,8 @@ void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
ghost->home_position.y = blue_home_y;
ghost->home_position.x = blue_home_x;
ghost->color = blue;
- ghost->frightened_status = 0;
- ghost->direction = none;
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;
break;
case orange:
ghost->position.y = orange_y;
@@ -59,15 +44,16 @@ void initialize_ghost(struct ghost_type *ghost, enum ghost_color color)
ghost->home_position.y = orange_home_y;
ghost->home_position.x = orange_home_x;
ghost->color = orange;
- ghost->frightened_status = 0;
- ghost->direction = none;
ghost->prison_params.position.x = orange_prison_x;
ghost->prison_params.position.y = orange_prison_y;
+ break;
+ }
+ ghost->frightened_status = 0;
+ ghost->direction = none;
ghost->prison_params.prison_counter = 0;
ghost->prison_params.active = 0;
ghost->capture_info.status = 0;
- break;
- }
+ ghost->reached_pacman = 0;
}
void pull_out_ghosts(int *get_out_stage,
@@ -114,12 +100,11 @@ static void change_position(struct ghost_type *ghost,
change_point_if_outside_tunnel(&ghost->position);
}
-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,
- struct queue *eaten_coins)
+void clear_ghost_positions(game_space field, const struct queue *eaten_coins,
+ const struct ghost_type *red_ghost,
+ const struct ghost_type *pink_ghost,
+ const struct ghost_type *blue_ghost,
+ const struct ghost_type *orange_ghost)
{
clear_or_revert_symbol(field, red_ghost->position, ghost_char, eaten_coins);
clear_or_revert_symbol(field, pink_ghost->position, ghost_char,
@@ -128,6 +113,17 @@ void make_ghost_moves(game_space field,
eaten_coins);
clear_or_revert_symbol(field, orange_ghost->position, ghost_char,
eaten_coins);
+}
+
+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,
+ struct queue *eaten_coins)
+{
+ clear_ghost_positions(field, eaten_coins, red_ghost, pink_ghost, blue_ghost,
+ orange_ghost);
change_position(red_ghost, red_ghost->direction);
change_position(pink_ghost, pink_ghost->direction);
change_position(blue_ghost, blue_ghost->direction);
diff --git a/ghosts.h b/ghosts.h
index 3eb58f7..ff8eb75 100644
--- a/ghosts.h
+++ b/ghosts.h
@@ -63,6 +63,7 @@ struct ghost_type {
enum movement_direction direction;
struct prison prison_params;
struct capture capture_info;
+ int reached_pacman;
};
void initialize_ghost(struct ghost_type *ghost, enum ghost_color color);
@@ -74,6 +75,12 @@ void pull_out_ghosts(int *get_out_stage,
struct ghost_type *orange_ghost);
struct queue;
+void clear_ghost_positions(game_space field, const struct queue *eaten_coins,
+ const struct ghost_type *red_ghost,
+ const struct ghost_type *pink_ghost,
+ const struct ghost_type *blue_ghost,
+ const struct ghost_type *orange_ghost);
+
void make_ghost_moves(game_space field,
struct ghost_type *red_ghost,
struct ghost_type *pink_ghost,
diff --git a/pac.c b/pac.c
index c3fcbb7..2aac83c 100644
--- a/pac.c
+++ b/pac.c
@@ -140,9 +140,12 @@ void catch_pac(struct pacman *pac)
{
--pac->lives;
erase_life(pac->lives);
- if(pac->lives >= 1) {
+ pac->direction = none;
+#if 0
+ if(pac->lives >= 0) {
pac->position.y = pac_y;
pac->position.x = pac_x;
pac->direction = none;
}
+#endif
}
diff --git a/pac.h b/pac.h
index ea0825b..f415f06 100644
--- a/pac.h
+++ b/pac.h
@@ -4,7 +4,7 @@
#include "ghosts.h"
enum {
- max_live = 3,
+ max_live = 2,
pac_y = 22,
pac_x = 14
};
diff --git a/pacman.c b/pacman.c
index 1468765..ce2fd5d 100644
--- a/pacman.c
+++ b/pacman.c
@@ -2,6 +2,7 @@
#include "ghosts.h"
#include "pac.h"
#include "queue.h"
+#include "color_palette.h"
#include <ncurses.h>
#include <stdlib.h>
#include <unistd.h>
@@ -9,12 +10,12 @@
enum {
timeout_duration = 0,
- sleep_duration = 190000,
+ sleep_duration = 120000,
key_escape = 27,
max_get_out_stage = 6,
chase_move_limit = 70,
scatter_move_limit = 35,
- frightened_move_limit = 30,
+ frightened_move_limit = 50,
phase_limit = 4,
prison_limit = 30,
max_score = 243
@@ -361,13 +362,14 @@ static void catching_stage(game_space field,
if(mode_params->current_mode == frightened)
catch_ghost(field, current_ghost);
else {
+ current_ghost->reached_pacman = 1;
catch_pac(pac);
- if(pac->lives)
- initialize_ghosts(red_ghost, pink_ghost, blue_ghost,
- orange_ghost);
- initialize_modes(mode_params);
- usleep(sleep_duration);
return;
+#if 0
+ initialize_ghosts(red_ghost, pink_ghost, blue_ghost,
+ orange_ghost);
+ return;
+#endif
}
}
if(current_ghost->capture_info.status)
@@ -375,9 +377,19 @@ static void catching_stage(game_space field,
}
}
+static int ghost_caught_pacman(struct ghost_type red_ghost,
+ struct ghost_type pink_ghost,
+ struct ghost_type blue_ghost,
+ struct ghost_type orange_ghost)
+{
+ return red_ghost.reached_pacman || pink_ghost.reached_pacman ||
+ blue_ghost.reached_pacman || orange_ghost.reached_pacman;
+}
+
static void final_stage(struct game_params_type *game_options, int win)
{
int key;
+ reset_attr();
if(win) {
move(17, 10);
printw("YOU WIN");
@@ -415,6 +427,7 @@ int main()
srand(time(NULL));
initscr();
start_color();
+ set_pairs();
cbreak();
noecho();
curs_set(0);
@@ -438,6 +451,8 @@ int main()
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;
}
/*
* ghosts
@@ -469,17 +484,23 @@ int main()
/*
* displaying characters and score
*/
+ display_score(pac.score);
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);
-
+ 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);
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);
else if(mode_params.current_mode == scatter)
@@ -487,11 +508,20 @@ int main()
else if(mode_params.current_mode == frightened)
printw("FRIGHTENED %d ", mode_params.frightened_count);
move(1, 50);
- printw("LIVES: %d", pac.lives);
+ 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
- if(!pac.lives || pac.score == max_score ) {
- final_stage(&game_options, !pac.lives ? 0 : 1);
+ 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 {
@@ -502,6 +532,22 @@ int main()
&orange_ghost);
usleep(sleep_duration);
}
+ continue;
+ }
+ 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);
}
}
clear_field_and_queue(field, &eaten_coins);