From: Laurent Mazet Date: Fri, 9 Aug 2024 20:40:18 +0000 (+0200) Subject: correct special cases X-Git-Tag: v1.3~5^2 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=cc1e651d83b75e8e9d90a20a8e3d249a49acc375;p=tetris.git correct special cases --- diff --git a/display.c b/display.c index b7396b5..2facdf5 100644 --- a/display.c +++ b/display.c @@ -7,6 +7,7 @@ #include "color.h" #include "debug.h" #include "function.h" +#include "time.h" #include "type.h" #include "display.h" @@ -293,4 +294,14 @@ void msgwindow (char *msg, int xoffset, int yoffset, int length) setcolor (black_gray); } +void removelines (board_t *board, int nblines, int tempo) +{ + while (nblines-- > 0) { + boardwindow (board, 0); + stackboard (board); + msleep (tempo); + refresh (); + } +} + /* vim: set ts=4 sw=4 et: */ diff --git a/display.h b/display.h index 045d1b2..cbaef2c 100644 --- a/display.h +++ b/display.h @@ -18,6 +18,8 @@ char *savewindow (int length, int xoffset, int yoffset); void msgwindow (char *msg, int xoffset, int yoffset, int length); +void removelines (board_t *board, int nblines, int tempo); + #endif /* __DISPLAY_H__ */ /* vim: set ts=4 sw=4 et: */ diff --git a/oneplayer.c b/oneplayer.c index 8b9d277..1e4f752 100644 --- a/oneplayer.c +++ b/oneplayer.c @@ -21,6 +21,11 @@ static char *help = " Save file\n" ; +static int computetempo (int lines) +{ + return 20 + 200 / (lines / 10 + 1); +} + /* main function for one player*/ int oneplayer (int width, int height, int scale, int chrono, char *filename) { @@ -133,21 +138,17 @@ int oneplayer (int width, int height, int scale, int chrono, char *filename) if (settle) { settleblock (board, cblock, xblock, yblock); - } - int nblines = checkline (board, &score, &lines); - if (nblines) { - while (nblines-- > 0) { - boardwindow (board, 0); - stackboard (board); - msleep (20 + 200 / (lines / 10 + 1)); - refresh (); - } - if (chrono) { + int nblines = checkline (board, &score, &lines); + removelines (board, nblines, computetempo (lines)); + if (nblines && chrono) { setendtime (&lineend, chronoratio * speed); } - } else if (chrono && lineend.tv_sec && isovertime (&lineend)) { + } + if (chrono && lineend.tv_sec && isovertime (&lineend)) { if (!testvalidpos (board, cblock, xblock, yblock + 1)) { settleblock (board, cblock, xblock, yblock); + int nblines = checkline (board, &score, &lines); + removelines (board, nblines, computetempo (lines)); settle = 1; } int isempty = addline (board, nbholes); diff --git a/twoplayers.c b/twoplayers.c index 2fee681..452e75b 100644 --- a/twoplayers.c +++ b/twoplayers.c @@ -20,6 +20,16 @@ static char *help = " Quit\n" ; +static int computetempo (int lines) +{ + return 20 + 200 / (lines / 20 + 1); +} + +static int computepenalty (int nblines) +{ + return (nblines == 4) ? 4 : (nblines > 1) ? nblines - 1 : 0; +} + /* main function for two players */ int twoplayers (int width, int height, int scale) { @@ -109,8 +119,14 @@ int twoplayers (int width, int height, int scale) break; case 1: halfdelay (1); + boardwindow (nextblock, 1); displayblock (nextblock, blocks + next, -1, -1); + + int penalty_left = 0; + int penalty_right = 0; + + /* check timeout */ if (blockend_left.tv_sec && isovertime (&blockend_left)) { if (testvalidpos (board_left, cblock_left, xblock_left, yblock_left + 1)) { yblock_left++; @@ -131,17 +147,9 @@ int twoplayers (int width, int height, int scale) /* Player one */ if (settle_left) { settleblock (board_left, cblock_left, xblock_left, yblock_left); - } - int nblines_left = checkline (board_left, &score_left, &lines); - if (nblines_left) { - while (nblines_left-- > 0) { - boardwindow (board_left, 0); - stackboard (board_left); - msleep (20 + 200 / (lines / 20 + 1)); - refresh (); - } - } - if (settle_left) { + int nblines_left = checkline (board_left, &score_left, &lines); + penalty_right = computepenalty (nblines_left); + removelines (board_left, nblines_left, computetempo (lines)); if (!testvalidpos (board_left, blocks + next , board_left->width / 2, 0)) { sprintf (msg, "To bad, player One looses. Score is %d / %d", score_left, score_right); mode = 2; @@ -156,17 +164,9 @@ int twoplayers (int width, int height, int scale) /* Player two */ if (settle_right) { settleblock (board_right, cblock_right, xblock_right, yblock_right); - } - int nblines_right = checkline (board_right, &score_right, &lines); - if (nblines_right) { - while (nblines_right-- > 0) { - boardwindow (board_right, 0); - stackboard (board_right); - msleep (20 + 200 / (lines / 20 + 1)); - refresh (); - } - } - if (settle_right) { + int nblines_right = checkline (board_right, &score_right, &lines); + penalty_left = computepenalty (nblines_right); + removelines (board_right, nblines_right, computetempo (lines)); if (!testvalidpos (board_right, blocks + next , board_right->width / 2, 0)) { sprintf (msg, "To bad, player Two looses. Score is %d / %d", score_left, score_right); mode = 2; @@ -178,6 +178,58 @@ int twoplayers (int width, int height, int scale) settle_right = 0; } + /* Penalty */ + while ((penalty_left > 0) || (penalty_right > 0)) { + + /* Player one */ + if (penalty_left) { + if (!testvalidpos (board_left, cblock_left, xblock_left, yblock_left + 1)) { + settleblock (board_left, cblock_left, xblock_left, yblock_left); + int nblines_left = checkline (board_left, &score_left, &lines); + penalty_right += computepenalty (nblines_left); + removelines (board_left, nblines_left, computetempo (lines)); + if (!testvalidpos (board_left, blocks + next , board_left->width / 2, 0)) { + sprintf (msg, "To bad, player One looses. Score is %d / %d", score_right, score_left); + mode = 2; + } else { + cblock_left = drawblock (board_left, blocks, nb_blocks, cblock_left, ¤t_left, &xblock_left, &yblock_left, &next); + boardwindow (nextblock, 1); + displayblock (nextblock, blocks + next, -1, -1); + } + } + int isempty = addline (board_left, nbholes); + if (!isempty) { + sprintf (msg, "Shame, player One looses. Score is %d / %d", score_right, score_left); + mode = 2; + } + penalty_left--; + } + + /* Player two */ + if (penalty_right) { + if (!testvalidpos (board_right, cblock_right, xblock_right, yblock_right + 1)) { + settleblock (board_right, cblock_right, xblock_right, yblock_right); + int nblines_right = checkline (board_right, &score_right, &lines); + penalty_left += computepenalty (nblines_right); + removelines (board_right, nblines_right, computetempo (lines)); + if (!testvalidpos (board_right, blocks + next , board_right->width / 2, 0)) { + sprintf (msg, "To bad, player Two looses. Score is %d / %d", score_left, score_right); + mode = 2; + } else { + cblock_right = drawblock (board_right, blocks, nb_blocks, cblock_right, ¤t_right, &xblock_right, &yblock_right, &next); + boardwindow (nextblock, 1); + displayblock (nextblock, blocks + next, -1, -1); + } + } + int isempty = addline (board_right, nbholes); + if (!isempty) { + sprintf (msg, "Shame, player Two looses. Score is %d / %d", score_left, score_right); + mode = 2; + } + penalty_right--; + } + } + break; case 2: freeblock (cblock_left);