From a9574591d86e9ac727da4ad6f6295725f3b2a3a2 Mon Sep 17 00:00:00 2001 From: Oxore Date: Sat, 9 Dec 2017 12:31:13 +0300 Subject: [PATCH] Implement NES Tetris scoring system --- README.md | 4 +-- include/common.h | 1 + include/functions.h | 1 + include/tet_conf.h | 20 +++++++++++++- src/functions.c | 66 ++++++++++++++++++++++++++++++++++++++------- src/main.c | 10 +++++-- 6 files changed, 88 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7120001..6e9176c 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,8 @@ make clean __TODO:__ - Add screenshots and gameplay gif -- Levels speed and scores calibration -- Scoring system as in Tetris for NES which is described on [this page](https://tetris.wiki/Scoring) +- [x] Levels speed and scores calibration +- [x] Scoring system as in Tetris for NES which is described on [this page](https://tetris.wiki/Scoring) - [Wall kick](https://tetris.wiki/Wall_kick) - Table of records - Settings menu with external `config.yml` file which allows diff --git a/include/common.h b/include/common.h index 9e1a847..773cb3f 100644 --- a/include/common.h +++ b/include/common.h @@ -50,6 +50,7 @@ typedef struct Game { int isStarted; int scoreCurrent; int level; + int moveLatency; int lines; } Game; diff --git a/include/functions.h b/include/functions.h index b307a31..f47f816 100644 --- a/include/functions.h +++ b/include/functions.h @@ -12,6 +12,7 @@ void resetActiveShape(Shape *active); void putShape(); int outOfFieldCheck(Field *fld, Shape *active); void checkLevelUp(Game *game); +int getMoveLatencyOfLevel(int level); int cellCollisionCheckHere(Field *fld, Shape *active); int cellCollisionCheck(int dir); int wallCollisionCheck(); diff --git a/include/tet_conf.h b/include/tet_conf.h index 55a4011..44da289 100644 --- a/include/tet_conf.h +++ b/include/tet_conf.h @@ -14,8 +14,26 @@ #define moveRepeatLatency2 30000 // microseconds, for Left, Right and Down // arrows, the rest repeat move when long push #define basicLatency 500000 +#define L00LATENCY 800000 +#define L01LATENCY 716667 +#define L02LATENCY 633334 +#define L03LATENCY 550000 +#define L04LATENCY 466667 +#define L05LATENCY 383334 +#define L06LATENCY 300000 +#define L07LATENCY 216667 +#define L08LATENCY 133334 +#define L09LATENCY 100000 +#define L10LATENCY 83334 +#define L13LATENCY 66667 +#define L16LATENCY 50000 +#define L19LATENCY 33334 +#define L29LATENCY 16667 #define PUT_LATENCY 300000 -#define RM_LINE_SCORE 100 +#define RM_1LINES_SCORE 40 +#define RM_2LINES_SCORE 100 +#define RM_3LINES_SCORE 300 +#define RM_4LINES_SCORE 1200 #define LEVELUP_LINES 10 diff --git a/src/functions.c b/src/functions.c index ab887b4..eebbf67 100644 --- a/src/functions.c +++ b/src/functions.c @@ -150,7 +150,20 @@ void putShape() } int removedLines = rmLines(); game.lines += removedLines; - game.scoreCurrent += removedLines*RM_LINE_SCORE; + switch (removedLines) { + case 1: + game.scoreCurrent += RM_1LINES_SCORE * game.level; + break; + case 2: + game.scoreCurrent += RM_2LINES_SCORE * game.level; + break; + case 3: + game.scoreCurrent += RM_3LINES_SCORE * game.level; + break; + case 4: + game.scoreCurrent += RM_4LINES_SCORE * game.level; + break; + } resetActiveShape(&active); checkLevelUp(&game); } @@ -170,11 +183,46 @@ int outOfFieldCheck(Field *fld, Shape *active) void checkLevelUp(Game *game) { - if (game->level < 15) - while (game->lines >= LEVELUP_LINES) { - game->level++; - game->lines -= LEVELUP_LINES; - } + while (game->lines >= LEVELUP_LINES) { + game->level++; + game->lines -= LEVELUP_LINES; + game->moveLatency = getMoveLatencyOfLevel(game->level); + } +} + +int getMoveLatencyOfLevel(int level) +{ + if (level >= 29) + return L29LATENCY; + else if (level >= 19) + return L19LATENCY; + else if (level >= 16) + return L16LATENCY; + else if (level >= 13) + return L13LATENCY; + else if (level >= 10) + return L10LATENCY; + else if (level == 9) + return L09LATENCY; + else if (level == 8) + return L08LATENCY; + else if (level == 7) + return L07LATENCY; + else if (level == 6) + return L06LATENCY; + else if (level == 5) + return L05LATENCY; + else if (level == 4) + return L04LATENCY; + else if (level == 3) + return L03LATENCY; + else if (level == 2) + return L02LATENCY; + else if (level == 1) + return L01LATENCY; + else if (level == 0) + return L00LATENCY; + return L00LATENCY; } void resetActiveShape(Shape *active) @@ -201,8 +249,7 @@ void resetActiveShape(Shape *active) void tTick() { // If tick exceeds current level tick latency if (sfClock_getElapsedTime(gameTick).microseconds - >= moveRepeatLatency2*(16-game.level) - && game.level <= 15) { + >= game.moveLatency) { sfClock_restart(gameTick); /* if bottom not reached */ if ((wallCollisionCheck(DOWN) == 0) @@ -557,7 +604,8 @@ void gameover(Game *game) { game->isStarted = 0; game->scoreCurrent = 0; - game->level = 1; + game->level = 0; + game->moveLatency = L00LATENCY; game->lines = 0; } diff --git a/src/main.c b/src/main.c index af6f6ba..8c1d7a1 100644 --- a/src/main.c +++ b/src/main.c @@ -13,7 +13,13 @@ #include "tet_conf.h" Window w = {.mode = {450, 570, 32}}; -Game game = {.isStarted = 0, .scoreCurrent = 0, .level = 1, .lines = 0}; +Game game = { + .isStarted = 0, + .scoreCurrent = 0, + .level = 0, + .moveLatency = L00LATENCY, + .lines = 0 +}; List *texts; sfFont *fontScore; Shape active, next; @@ -90,7 +96,7 @@ void gameLoop() { void menuTick() { - if(sfClock_getElapsedTime(mTick).microseconds >= basicLatency/game.level) { + if(sfClock_getElapsedTime(mTick).microseconds >= basicLatency) { sfClock_restart(mTick); colorizeRandom(&fld); }