From 3cbd237f5dc6c3ed4df86c0fa80980ab99ce1cc9 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Mon, 29 Jul 2024 21:08:34 +0200 Subject: [PATCH] add time penalty mode --- display.c | 3 ++ function.c | 35 +++++++++++++++ function.h | 2 + tetris.c | 124 +++++++++++++++++++++++++++++++++++++---------------- 4 files changed, 128 insertions(+), 36 deletions(-) diff --git a/display.c b/display.c index 96f44db..e6ed047 100644 --- a/display.c +++ b/display.c @@ -93,6 +93,9 @@ void _put_color_block (int y, int x, char symb) case '7': mvaddcb (y, x, green); break; + case '8': + mvaddcb (y, x, white); + break; } } diff --git a/function.c b/function.c index 894f61f..943dfb2 100644 --- a/function.c +++ b/function.c @@ -415,4 +415,39 @@ void stackboard (board_t *board) } } +int addline (board_t *board, int nbholes) +{ + int i, j; + + /* check empty ligne */ + int isempty = 1; + for (i = 0; i < board->width; i++) { + if (*getcell (board, i, 0) != ' ') { + isempty = 0; + break; + } + } + + /* move up */ + for (j = 1; j < board->height; j++) { + for (i = 0; i < board->width; i++) { + *getcell (board, i, j - 1) = *getcell (board, i, j); + } + } + + /* random line */ + for (i = 0; i < board->width; i++) { + *getcell (board, i, board->height - 1) = '8'; + } + while (nbholes) { + i = rand () % board->width; + if (*getcell (board, i, board->height - 1) == '8') { + *getcell (board, i, board->height - 1) = ' '; + nbholes--; + } + } + + return isempty; +} + /* vim: set ts=4 sw=4 et: */ diff --git a/function.h b/function.h index 86420f9..e9af813 100644 --- a/function.h +++ b/function.h @@ -59,6 +59,8 @@ int checkline (board_t *board, int *score, int *lines); void stackboard (board_t *board); +int addline (board_t *board, int nbholes); + #endif /* __FUNCTION_H__ */ /* vim: set ts=4 sw=4 et: */ diff --git a/tetris.c b/tetris.c index 256caf7..bb610fc 100644 --- a/tetris.c +++ b/tetris.c @@ -22,6 +22,7 @@ char *progname = NULL; char *version = "1.1"; +int chrono = 0; char *filename = NULL; int scale = 1; @@ -32,6 +33,7 @@ int maxwidth = 15; int nbdigit = 5; int maxscor = 100000; +int nbholes = 2; int savelen = 12; int xoffset = 1; @@ -52,7 +54,8 @@ char *help = int usage (int ret) { FILE *fd = ret ? stderr : stdout; - fprintf (fd, "usage: %s [-f file] [-h] [-s int] [-v int] [-w int]\n", progname); + fprintf (fd, "usage: %s [-c] [-f file] [-h] [-s int] [-v int] [-w int]\n", progname); + fprintf (fd, " -c: time penalty (%s)", (chrono) ? "yes" : "no" ); fprintf (fd, " -f: file name (%s)\n", (filename) ? filename : "none"); fprintf (fd, " -s: scale [0..3] (%d)\n", scale); fprintf (fd, " -v: verbose level (%d)\n", verbose); @@ -62,6 +65,30 @@ int usage (int ret) return ret; } +block_t *drawblock (board_t *board, block_t *blocks, int nb_blocks, block_t *cblock, int *current, int *xblock, int *yblock, int *next) +{ + /* clean block and get next */ + if (cblock) { + freeblock (cblock); + *current = *next; + *next = rand () % nb_blocks; + } + + /* init state */ + if (*current == -1) { + *current = rand () % nb_blocks; + } + if (*next == -1) { + *next = rand () % nb_blocks; + } + + cblock = copyblock (blocks + *current); + *xblock = board->width / 2; + *yblock = 0; + + return cblock; +} + void setendtime (struct timeval *t, int s) { gettimeofday (t, NULL); @@ -100,6 +127,9 @@ int main (int argc, char *argv[]) } char c = arg[1]; switch (c) { + case 'c': + chrono = 1; + break; case 'f': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; if (arg == NULL) { @@ -188,15 +218,8 @@ int main (int argc, char *argv[]) srand (time (NULL)); /* get first bloc */ - if (current == -1) { - current = rand () % nb_blocks; - } - block_t *cblock = copyblock (blocks + current); - int xblock = board->width / 2; - int yblock = 0; - if (next == -1) { - next = rand () % nb_blocks; - } + int xblock, yblock; + block_t *cblock = drawblock (board, blocks, nb_blocks, NULL, ¤t, &xblock, &yblock, &next); VERBOSE (DEBUG, fprintf (stderr, "%d/%d: (%d, %d)\n", current, nb_blocks, xblock, yblock)); /* init curses window */ @@ -233,10 +256,13 @@ int main (int argc, char *argv[]) int mode = -1; int settle = 0; int speed = 5000; + float chronoratio = 5.0; int stop = 0; - struct timeval tend = {0, 0}; + struct timeval blockend = {0, 0}; + struct timeval lineend = {0, 0}; while (!stop) { char msg[128] = {0}; + msgwindow (msg, xmsg, ymsg, lmsg); switch (mode) { case -1: @@ -245,38 +271,58 @@ int main (int argc, char *argv[]) sprintf (msg, "Get ready player One. Press to start"); break; case 0: - halfdelay (0); boardwindow (nextblock, 1); displayblock (nextblock, blocks + current, -1, -1); sprintf (msg, "Game in pause. Pause

to continue"); break; case 1: halfdelay (1); - if (tend.tv_sec && isovertime (&tend)) { + if (blockend.tv_sec && isovertime (&blockend)) { if (testvalidpos (board, cblock, xblock, yblock + 1)) { yblock++; } else { settle = 1; } - setendtime (&tend, speed); + setendtime (&blockend, speed); } if (settle) { settleblock (board, cblock, xblock, yblock); - freeblock (cblock); - current = next; - cblock = copyblock (blocks + current); - xblock = board->width / 2; - yblock = 0; - next = rand () % nb_blocks; - settle = 0; } - if (!testvalidpos (board, cblock, xblock, yblock)) { - halfdelay (0); - mode = 2; - sprintf (msg, "To bad, you loose. Score is %d", score); + int nblines = checkline (board, &score, &lines); + if (nblines) { + while (nblines-- > 0) { + boardwindow (board, 0); + stackboard (board); + usleep ((200 + 2000 / (lines / 10 + 1)) * 100); + refresh (); + } + if (chrono) { + setendtime (&lineend, chronoratio * speed); + } + } else if (chrono && lineend.tv_sec && isovertime (&lineend)) { + if (!testvalidpos (board, cblock, xblock, yblock + 1)) { + settleblock (board, cblock, xblock, yblock); + settle = 1; + } + int isempty = addline (board, nbholes); + if (!isempty) { + sprintf (msg, "Shame, you loose. Score is %d", score); + mode = 2; + settle = 0; + } + setendtime (&lineend, chronoratio * speed); + } + if (settle) { + if (!testvalidpos (board, blocks + next , board->width / 2, 0)) { + sprintf (msg, "To bad, you loose. Score is %d", score); + mode = 2; + } else { + cblock = drawblock (board, blocks, nb_blocks, cblock, ¤t, &xblock, &yblock, &next); + boardwindow (nextblock, 1); + displayblock (nextblock, blocks + next, -1, -1); + } + settle = 0; } - boardwindow (nextblock, 1); - displayblock (nextblock, blocks + next, -1, -1); break; case 2: freeblock (cblock); @@ -284,20 +330,21 @@ int main (int argc, char *argv[]) sprintf (msg, "End of game. Press to quit"); } - msgwindow (msg, xmsg, ymsg, lmsg); - int nblines = checkline (board, &score, &lines); - while (nblines-- > 0) { - boardwindow (board, 0); - stackboard (board); - usleep ((200 + 2000 / (lines / 10 + 1)) * 100); - refresh (); + if (*msg) { + halfdelay (0); + msgwindow (msg, xmsg, ymsg, lmsg); + usleep (800000); } + boardwindow (board, 0); scorewindow (xscore, yscore, nbdigit, score, (lines / 10) + 1); int newspeed = 10 + 4900 / (lines / 10 + 1); if (newspeed != speed) { speed = newspeed; - setendtime (&tend, speed); + setendtime (&blockend, speed); + if (chrono) { + setendtime (&lineend, chronoratio * speed); + } } if (mode == 1) { displayblock (board, cblock, xblock, yblock); @@ -371,7 +418,10 @@ int main (int argc, char *argv[]) switch (mode) { case 0: mode = 1; - setendtime (&tend, speed); + setendtime (&blockend, speed); + if (chrono) { + setendtime (&lineend, chronoratio * speed); + } break; case 1: mode = 0; @@ -432,5 +482,7 @@ int main (int argc, char *argv[]) /* test: { echo -n s; sleep 1; echo lllololo; sleep 1; echo jjjujuju; sleep 1; echo lllololo; sleep 1; echo jjjujuju; sleep 1; echo q; } | tetris.exe -w 9*/ /* test: { echo -n s; sleep 1; echo ccccccccccccc; sleep 1; echo q; } | tetris.exe */ /* test: { echo -n s; sleep 1; echo -n jjuuuc; sleep 1; echo -n jjoc; sleep 1; echo q; } | tetris.exe -f lines.ttr */ +/* test: { echo -n s; sleep 1; echo -n jjuuuc; sleep 1; echo -n jjoc; sleep 1; echo q; } | tetris.exe -c -f lines.ttr */ +/* test: { echo -n sccccccc; sleep 50; echo q; } | tetris.exe -c */ /* vim: set ts=4 sw=4 et: */ -- 2.30.2