From: Laurent Mazet Date: Tue, 23 Jul 2024 19:07:01 +0000 (+0200) Subject: blocks stuck on ground X-Git-Tag: v1.0~7 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=5310b7caff2e8a4ae458ba5114d9df203165e0dc;p=tetris.git blocks stuck on ground --- diff --git a/display.c b/display.c index 12fd83b..b1c0470 100644 --- a/display.c +++ b/display.c @@ -224,7 +224,7 @@ void displayblock (board_t *board, block_t *block, int x, int y) for (i = 0; i < block->width; i++) { for (j = 0; j < block->height; j++) { if (*getcell (block, i, j) != ' ') { - _element (board, x + i, y + j, '0' + block->color); + _element (board, x - block->width / 2 + i, y + j, '0' + block->color); } } } diff --git a/function.c b/function.c index 7e9c160..2e6429d 100644 --- a/function.c +++ b/function.c @@ -87,7 +87,7 @@ int _makecomments (char *buffer, board_t *board) for (j = 0; j < board->height; j++) { l += sprintf (buffer + l, "rem: \""); for (i = 0; i < board->width; i++) { - l += sprintf (buffer + l, "%c", getvalue (board, i, j)); + l += sprintf (buffer + l, "%c", *getcell (board, i, j)); } l += sprintf (buffer + l, "\"\n"); } @@ -308,4 +308,37 @@ block_t *rotateblock (block_t *block, int rot) return block; } +int testvalidpos (board_t *board, block_t *block, int x, int y) +{ + int ret = 1; + if ((x - block->width / 2 < 0) || (x - block->width / 2 + block->width > board->width) || + (y + block->height > board->height)) { + ret = 0; + } else { + int i, j; + for (i = 0; i < block->width; i++) { + for (j = 0; j < block->height; j++) { + if (*getcell (block, i, j) == '.') { + if (*getcell (board, x - block->width / 2 + i, y + j) != ' ') { + ret = 0; + } + } + } + } + } + return ret; +} + +void settleblock (board_t *board, block_t *block, int x, int y) +{ + int i, j; + for (i = 0; i < block->width; i++) { + for (j = 0; j < block->height; j++) { + if (*getcell (block, i, j) == '.') { + *getcell (board, x - block->width / 2 + i, y + j) = '0' + block->color; + } + } + } +} + /* vim: set ts=4 sw=4 et: */ diff --git a/function.h b/function.h index e7a5340..2cd7c8c 100644 --- a/function.h +++ b/function.h @@ -39,8 +39,6 @@ board_t *loadboard (char *str); #define getcell(b, x, y) ({ __typeof__ (b) _b = (b); int _x = (x), _y = (y);_b->tab + _x + _b->width * _y; }) -#define getvalue(b, x, y) ({ __typeof__ (b) _b = (b); int _x = (x), _y = (y); (_x >= 0) && (_x < _b->width) && (_y >= 0) && (_y < _b->height) ? *(getcell (_b, _x, _y)) : 0; }) - block_t *initblock (int xsize, int ysize); block_t *changeblock (block_t *dest, block_t *src); @@ -51,6 +49,10 @@ void freeblock (block_t *block); block_t *rotateblock (block_t *block, int rot); +int testvalidpos (board_t *board, block_t *block, int x, int y); + +void settleblock (board_t *board, block_t *block, int x, int y); + #endif /* __FUNCTION_H__ */ /* vim: set ts=4 sw=4 et: */ diff --git a/tetris.c b/tetris.c index 37383cc..4eda0a2 100644 --- a/tetris.c +++ b/tetris.c @@ -152,7 +152,7 @@ int main (int argc, char *argv[]) block_t *blocks = getblocks ("std", &nb_blocks); int current = rand () % nb_blocks; block_t *cblock = copyblock (blocks + current); - int xblock = (board->width - cblock->width) / 2; + int xblock = board->width / 2; int yblock = 0; int next = rand () % nb_blocks; VERBOSE (DEBUG, fprintf (stderr, "%d/%d: (%d, %d)\n", current, nb_blocks, xblock, yblock)); @@ -170,8 +170,6 @@ int main (int argc, char *argv[]) int xboard = board->xoffset = xoffset + 1; int yboard = board->yoffset = xoffset + 1; int xhelp = xboard + xoffset + 1 + board->xsize; - int xcursor = 1; - int ycursor = 0; int yhelp = yboard - 1; int xsave = max (xboard + (board->xsize - savelen) / 2, 1); int ysave = yboard + (board->ysize - 1) / 2; @@ -188,77 +186,113 @@ int main (int argc, char *argv[]) /* event loop */ int mode = 0; int speed = 5000; - int rot = 0; + int settle = 0; int stop = 0; struct timeval tend = {0, 0}; while (!stop) { + char msg[128] = {0}; - boardwindow (board); - if (1) { /* not end of game */ - char msg[128] = {0}; - switch (mode) { - case 0: -freeblock (cblock); -current = next; -cblock = copyblock (blocks + current); -xblock = (board->width - cblock->width) / 2; -yblock = 0; -next = rand () % nb_blocks; -sprintf (msg, "%d/%d: (%d, %d)\n", current, nb_blocks, xblock, yblock); - halfdelay (0); - //sprintf (msg, "Get ready player One"); - break; - case 1: - halfdelay (10); - rotateblock (cblock, rot); - if (isovertime (&tend)) { + switch (mode) { + case 0: + halfdelay (0); + sprintf (msg, "Get ready player One"); + break; + case 1: + halfdelay (1); + if (tend.tv_sec && isovertime (&tend)) { + if (testvalidpos (board, cblock, xblock, yblock + 1)) { yblock++; - if (yblock + cblock->height >= board->height) { - freeblock (cblock); - current = next; - cblock = copyblock (blocks + current); - xblock = (board->width - cblock->width) / 2; - yblock = 0; - next = rand () % nb_blocks; - } - setendtime (&tend, speed); + } else { + settle = 1; } - displayblock (board, cblock, xblock, yblock); - rot = 0; -sprintf (msg, "%ld/%06ld\n", tend.tv_sec, tend.tv_usec); - break; + setendtime (&tend, 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, "End of game"); } - msgwindow (msg, xmsg, ymsg, lmsg); - } else { - msgwindow ("End of game", xmsg, ymsg, lmsg); + break; + case 2: + freeblock (cblock); + cblock = NULL; + sprintf (msg, "Press q to quit"); + } + + msgwindow (msg, xmsg, ymsg, lmsg); + boardwindow (board); + if (mode == 1) { + displayblock (board, cblock, xblock, yblock); } int ch = getch (); - switch (ch) { - case KEY_ENTER: - case '\n': - case '\r': - case 'c': - yblock = board->height - cblock->height; - break; - case KEY_LEFT: - case 'j': - xblock--; + switch (mode) { + case 0: break; - case KEY_DOWN: - case 'k': - yblock++; - break; - case KEY_RIGHT: - case 'l': - xblock++; + case 1: + switch (ch) { + case KEY_ENTER: + case '\n': + case '\r': + case 'c': + while (testvalidpos (board, cblock, xblock, yblock + 1)) { + yblock++; + } + settle = 1; + break; + case KEY_LEFT: + case 'j': + if (testvalidpos (board, cblock, xblock - 1, yblock)) { + xblock--; + } + break; + case KEY_DOWN: + case 'k': + if (testvalidpos (board, cblock, xblock, yblock + 1)) { + yblock++; + } else { + settle = 1; + } + break; + case KEY_RIGHT: + case 'l': + if (testvalidpos (board, cblock, xblock + 1, yblock)) { + xblock++; + } + break; + case KEY_UP: + case ' ': + case 'i': + case 'o': + if (!testvalidpos (board, rotateblock (cblock, 1), xblock, yblock)) { + rotateblock (cblock, -1); + } + break; + case KEY_BACKSPACE: + case KEY_DELETE: + case 127: + case '\b': + case 'u': + if (!testvalidpos (board, rotateblock (cblock, -1), xblock, yblock)) { + rotateblock (cblock, 1); + } + break; + } break; - case KEY_UP: - case ' ': - case 'i': - case 'o': - rot = 1; + case 2: break; + } + switch (ch) { case 'p': mode = (mode == 0) ? 1 : 0; if (mode == 1) { @@ -280,13 +314,6 @@ sprintf (msg, "%ld/%06ld\n", tend.tv_sec, tend.tv_usec); free (savename); } break; - case KEY_BACKSPACE: - case KEY_DELETE: - case 127: - case '\b': - case 'u': - rot = -1; - break; //case ERR: //default: }