From ddac1329df5f81f35f449e594b98fd3dcd0179a0 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Sun, 18 Aug 2024 16:09:44 +0200 Subject: [PATCH] most functions are implemented --- function.c | 90 ++++++++++++++++++++++++++++++++++++++--- function.h | 8 ++++ pentomino.c | 114 +++++++++++++++++++++++++++++++--------------------- type.h | 1 + 4 files changed, 161 insertions(+), 52 deletions(-) diff --git a/function.c b/function.c index cfd96da..ce21140 100644 --- a/function.c +++ b/function.c @@ -261,6 +261,32 @@ void freeblock (block_t *block) free (block); } +block_t *mirrorblock (block_t *block, int dir) +{ + int i, j; + switch (dir % 2) { + case 0: + for (i = 0; i < block->width; i++) { + for (j = 0; j < block->height / 2; j++) { + char t = *getcell (block, i, j); + *getcell (block, i, j) = *getcell (block, i, block->height - 1 - j); + *getcell (block, i, block->height - 1 - j) = t; + } + } + break; + case 1: + for (i = 0; i < block->width / 2; i++) { + for (j = 0; j < block->height; j++) { + char t = *getcell (block, i, j); + *getcell (block, i, j) = *getcell (block, block->width - 1 - i, j); + *getcell (block, block->width - 1 - i, j) = t; + } + } + break; + } + return block; +} + block_t *rotateblock (block_t *block, int rot) { int i, j; @@ -320,20 +346,72 @@ blocks_t *initblocks (int nb) CHECKALLOC (blocks->y); blocks->block = (block_t **) calloc (nb, sizeof (block_t *)); CHECKALLOC (blocks->block); + blocks->settle = (int *) calloc (nb, sizeof (int)); + CHECKALLOC (blocks->settle); return (blocks); } void freeblocks (blocks_t *blocks) { - int i; - for (i = 0; i < blocks->nb; i++) { - freeblock (blocks->block[i]); + if (blocks) { + int i; + for (i = 0; i < blocks->nb; i++) { + freeblock (blocks->block[i]); + } + free (blocks->x); + free (blocks->y); + free (blocks->block); + free (blocks->settle); } - free (blocks->x); - free (blocks->y); - free (blocks->block); free (blocks); } +int findnext (int i, int *tab, int n) +{ + int c = 0; + do { + i++; + if (i >= n) { + i = 0; + } + c++; + if (c > n) { + return -1; + } + } while (tab[i]); + + return i; +} + +int testposition (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) != ' ') { + if (*getcell (board, x + i, y + j) != ' ') { + return 0; + } + } + } + } + + return 1; +} + +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 + i, y + j) = ' ' + block->color; + } + } + } +} + /* vim: set ts=4 sw=4 et: */ diff --git a/function.h b/function.h index 3c82c94..325005f 100644 --- a/function.h +++ b/function.h @@ -47,12 +47,20 @@ block_t *copyblock (block_t *block); void freeblock (block_t *block); +block_t *mirrorblock (block_t *block, int dir); + block_t *rotateblock (block_t *block, int rot); blocks_t *initblocks (int nb); void freeblocks (blocks_t *blocks); +int testposition (board_t *board, block_t *block, int x, int y); + +void settleblock (board_t *board, block_t *block, int x, int y); + +int findnext (int i, int *tab, int n); + #endif /* __FUNCTION_H__ */ /* vim: set ts=4 sw=4 et: */ diff --git a/pentomino.c b/pentomino.c index e2973e7..b864f0e 100644 --- a/pentomino.c +++ b/pentomino.c @@ -28,7 +28,9 @@ char *help = " Move left cursor\n" " Move down cursor\n" " Move right cursor\n" + " Mirror horizontally \n" " Rotate piece right\n" + "

Mirror vertically \n" " Rotate piece left\n" " Yank next piece\n" " Quit\n" @@ -172,12 +174,12 @@ int main (int argc, char *argv[]) n = 3; break; } - bench = initboard (xoffset + (xoffset + wblock) * (blocks->nb) / n, (1 + n) * yoffset + n * hblock); + bench = initboard (xoffset + (xoffset + wblock) * (blocks->nb) / n, (n - 1) * yoffset + n * hblock); VERBOSE (DEBUG, fprintf (stderr, "windows: %dx%d\n", xoffset + (xoffset + wblock) * (blocks->nb + n - 1) / n, (1 + n) * yoffset + n * hblock)); setscale (bench, scale); for (i = 0; i < blocks->nb; i++) { blocks->x[i] = xoffset + (xoffset + wblock) * (i / n) + (wblock - blocks->block[i]->width + 1) / 2; - blocks->y[i] = yoffset + (yoffset + hblock) * (i % n) + (hblock - blocks->block[i]->height + 1) / 2; + blocks->y[i] = (yoffset + hblock) * (i % n) + (hblock - blocks->block[i]->height + 1) / 2; } /* init curses window */ @@ -189,31 +191,34 @@ int main (int argc, char *argv[]) curs_set (0); start_color (); - /* window positions */ + /* window positions (board) */ int xboard = board->xoffset = xoffset + 1; int yboard = board->yoffset = xoffset + 1; - int xhelp = xboard + xoffset + 1 + board->xsize; - int xcursor = board->width / 2; - int ycursor = board->height / 2; - int cursor = 0; - int yhelp = yboard - 1; int xsave = max (xboard + (board->xsize - savelen) / 2, 1); int ysave = yboard + (board->ysize - 1) / 2; - char *savename = NULL; - /* help window */ + /* cursor definition */ + int cursor = 0; + int xcursor = (board->width - blocks->block[cursor]->width) / 2; + int ycursor = (board->height - blocks->block[cursor]->height) / 2; + + /* window positions (bench) */ + int xbench = bench->xoffset = xboard; + int ybench = bench->yoffset = yboard + board->ysize + 1 + yoffset; + + /* window positions (help) */ + int xhelp = xbench + bench->xsize + xoffset + 1; + int yhelp = yboard - 1; int lhelp = helpwindow (help, xhelp, yhelp); - /* window positions */ - int xblocks = bench->xoffset = xboard; - int yblocks = bench->yoffset = max (yboard + board->ysize + 1, yhelp + lhelp) + yoffset + 1; - int xmsg = xblocks; - int ymsg = yblocks + yoffset + 2; - int lmsg = xhelp - xmsg + strmaxlen (help, '\n'); + /* window positions (msg) */ + int xmsg = xbench; + int ymsg = ybench + bench->ysize + yoffset + 1; + int lmsg = bench->xsize + strmaxlen (help, '\n') + xoffset + 1; /* blocks positions */ - boardwindow (bench, 0); + boardwindow (bench, 1); for (i = 0; i < blocks->nb; i++) { displayblock (bench, blocks->block[i], blocks->x[i], blocks->y[i]); } @@ -223,30 +228,61 @@ int main (int argc, char *argv[]) while (!stop) { boardwindow (board, 0); - block_t *block = blocks->block[cursor]; - displayblock (board, block, xcursor, ycursor); - - if (1) { //if (!endofgame (board)) { - // cursorwindow (board, xcursor, ycursor, mode); + block_t *block = NULL; + if (cursor >= 0) { + block = blocks->block[cursor]; + displayblock (board, block, xcursor, ycursor); + msgwindow ("Can you solve this puzzle?", xmsg, ymsg, lmsg); } else { - msgwindow ("End of game", xmsg, ymsg, lmsg); + msgwindow ("Puzzle solved", xmsg, ymsg, lmsg); } int ch = getch (); + + /* general controls */ + switch (ch) { + case KEY_ESC: + case 'q': + stop = 1; + break; + case 's': + savename = savewindow (savelen, xsave, ysave); + if (savename != NULL) { + char *ptr = saveboard (board); + if (writedata (savename, ptr)) { + VERBOSE (WARNING, printf ("issue writing Board\n")); + } + free (ptr); + free (savename); + } + break; + } + + /* test end of game */ + if (cursor < 0) { + continue; + } + + /* game controls */ switch (ch) { case '\n': case '\r': case 'h': + if (testposition (board, block, xcursor, ycursor)) { + settleblock (board, block, xcursor, ycursor); + blocks->settle[cursor] = 1; + cursor = findnext (cursor, blocks->settle, blocks->nb); + } break; case KEY_UP: case 'i': - if (ycursor > - (block->height + 0) / 2) { + if (ycursor > - block->height / 2) { ycursor--; } break; case KEY_LEFT: case 'j': - if (xcursor > - (block->width + 0) / 2) { + if (xcursor > - block->width / 2) { xcursor--; } break; @@ -262,25 +298,16 @@ int main (int argc, char *argv[]) xcursor++; } break; + case 'm': + mirrorblock (block, 0); + break; case KEY_DELETE: case 127: case 'o': rotateblock (block, 1); break; - case KEY_ESC: - case 'q': - stop = 1; - break; - case 's': - savename = savewindow (savelen, xsave, ysave); - if (savename != NULL) { - char *ptr = saveboard (board); - if (writedata (savename, ptr)) { - VERBOSE (WARNING, printf ("issue writing Board\n")); - } - free (ptr); - free (savename); - } + case 'p': + mirrorblock (block, 1); break; case KEY_BACKSPACE: case '\b': @@ -289,14 +316,8 @@ int main (int argc, char *argv[]) break; case ' ': case 'y': - cursor++; - if (cursor >= blocks->nb) { - cursor = 0; - } - break; + cursor = findnext (cursor, blocks->settle, blocks->nb); break; - //case ERR: - //default: } } @@ -304,6 +325,7 @@ int main (int argc, char *argv[]) endwin (); freeboard (board); + freeblocks (blocks); return 0; } diff --git a/type.h b/type.h index 9f49930..c912717 100644 --- a/type.h +++ b/type.h @@ -28,6 +28,7 @@ typedef struct { int *x; int *y; block_t **block; + int *settle; } blocks_t; #endif /* __TYPE_H__ */ -- 2.30.2