From 7ce9c75d92309de54327c684cd594a47539a65c2 Mon Sep 17 00:00:00 2001 From: girst Date: Thu, 24 May 2018 22:41:31 +0200 Subject: [PATCH] Bonus items: shorten/elongate snake, speed up/down --- schemes.h | 7 +++++-- viiper.c | 35 +++++++++++++++++++++++++++++------ viiper.h | 3 +++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/schemes.h b/schemes.h index 19e01f3..3e91b0f 100644 --- a/schemes.h +++ b/schemes.h @@ -78,6 +78,9 @@ struct scheme unic0de = { }, .boni = { [BONUS_SNIP] = "✂️ ", + [BONUS_GROW] = "🐍", + [BONUS_SLOW] = "🐌", + [BONUS_FAST] = "🐇", }, .cell_width = 2, @@ -101,8 +104,8 @@ struct scheme vt220_charset = { }, .color = {"0", "0", "1"}, - .food = { "$", "%", "&" }, - .boni = { "x" }, + .food = { "$", "%", "&", }, + .boni = { "x", "|", "s", "f", }, .init_seq = "\033(0\033*B\x0f" /* G0=Graphics, G2=ASCII, invoke G0 */ "\033[?3l", /* disable 132 column mode (DECCOLM) */ diff --git a/viiper.c b/viiper.c index 524b24a..34fe108 100644 --- a/viiper.c +++ b/viiper.c @@ -49,6 +49,7 @@ #define CW op.sch->cell_width #define SPEEDUP_AFTER 100 /* increment speed every n points */ +#define BONUS_INTERVAL 90 /* how often a bonus item is spawned */ struct game { int w; /* field width */ @@ -56,6 +57,7 @@ struct game { int d; /* direction the snake is looking */ int t; /* time of game start */ int p; /* score */ + int b; /* time of last bonus item spawned */ float v; /* velocity in moves per second */ struct snake* s; /* snek */ struct item* i; /* items (food, boni) */ @@ -164,12 +166,12 @@ int viiper(void) { g.t = time(NULL); g.p = 0; g.k.n = 0; + g.b = time(NULL) + BONUS_INTERVAL; spawn_item(FOOD, rand() % NUM_FOODS, NULL); //TODO: shape distribution, so bigger values get selected less for(;;) { switch (getctrlseq()) { -case '#': spawn_item(BONUS, BONUS_SNIP, NULL); case CTRSEQ_CURSOR_LEFT: case 'h':append_movement(WEST); break; case CTRSEQ_CURSOR_DOWN: case 'j':append_movement(SOUTH); break; case CTRSEQ_CURSOR_UP: case 'k':append_movement(NORTH); break; @@ -286,15 +288,26 @@ void consume_item (struct item* i) { case BONUS: switch (i->v) { case BONUS_SNIP: - for (int i = 10; i && g.s->next->next; i--) { /* must have at least 2 elements, otherwise segfault during snake drawing */ - struct snake* old_head = g.s; - g.s = g.s->next; - free (old_head); + for (int i = 5; i && g.s->next->next; i--) { + struct snake* p = g.s; + while (p->next->next) p = p->next; + free (p->next); + p->next = NULL; } show_playfield(); break; + case BONUS_GROW: + for (int i = 5; i; i--) snake_append(&g.s, -1, -1); + break; + case BONUS_SLOW: + if (g.v > 1) g.v--; + timer_setup(1); + break; + case BONUS_FAST: + g.v++; + timer_setup(1); + break; } - //TODO: handle bonus break; } @@ -306,6 +319,15 @@ void consume_item (struct item* i) { if (g.p/SPEEDUP_AFTER - old_score/SPEEDUP_AFTER) g.v++; } +void spawn_bonus(void) { //TODO: items should be removed after a timeout (and blink x seconds before timeout) if not eaten + if (g.b > time(NULL)) return; + for (struct item* i = g.i; i; i = i->next) /*don't spawn bonus*/ + if (i->t == BONUS) return; /* if one is already there */ + + spawn_item(BONUS, rand() % NUM_BONI, NULL); + g.b = time(NULL) + BONUS_INTERVAL; +} + void show_playfield (void) { move_ph (0,0); @@ -563,6 +585,7 @@ void signal_handler (int signum) { switch (signum) { case SIGALRM: snake_advance(); + spawn_bonus(); break; case SIGINT: exit(128+SIGINT); diff --git a/viiper.h b/viiper.h index 701402d..e1dfeef 100644 --- a/viiper.h +++ b/viiper.h @@ -51,6 +51,9 @@ enum food_value { }; enum bonus_value { BONUS_SNIP, + BONUS_GROW, + BONUS_SLOW, + BONUS_FAST, NUM_BONI, }; enum game_state { -- 2.39.3