From e982c42eda5540fa22636618ba4d252e06088903 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Tue, 17 Dec 2024 23:56:00 +0100 Subject: [PATCH] add element's move feature --- function.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ function.h | 2 + sokoban.c | 11 +++++- 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/function.c b/function.c index 446e0c1..f628035 100644 --- a/function.c +++ b/function.c @@ -7,6 +7,11 @@ #include "function.h" +typedef struct { + int x; + int y; +} point; + int strmaxlen (char *str, char ch) { int len = 0; @@ -216,4 +221,110 @@ char getvalue (board_t *board, int x, int y) return (x >= 0) && (x < board->width) && (y >= 0) && (y < board->height) ? *getcell (board, x, y) : 0; } +int _moveelements (board_t *board, point *pt, int dir) +{ + /* define direction */ + point _move = {0, 0}; + point *move = &_move; + switch (dir) { + case 0: + move->y--; + break; + case 1: + move->x++; + break; + case 2: + move->y++; + break; + case 3: + move->x--; + break; + } + + /* check 2 next positions in line */ + int rc = 1; + char next = getvalue (board, pt->x + move->x, pt->y + move->y); + char next2 = getvalue (board, pt->x + 2 * move->x, pt->y + 2 * move->y); + switch (next) { + case '$': + case '*': + switch (next2) { + case ' ': + *getcell (board, pt->x + 2 * move->x, pt->y + 2 * move->y) = '$'; + break; + case '.': + *getcell (board, pt->x + 2 * move->x, pt->y + 2 * move->y) = '*'; + break; + default: + rc = 0; + } + } + + /* push box */ + if (rc == 1) { + switch (next) { + case '$': + *getcell (board, pt->x + move->x, pt->y + move->y) = ' '; + break; + case '*': + *getcell (board, pt->x + move->x, pt->y + move->y) = '.'; + break; + } + } + + /* move sokoban */ + switch (next) { + case ' ': + *getcell (board, pt->x + move->x, pt->y + move->y) = '@'; + rc = 1; + break; + case '.': + *getcell (board, pt->x + move->x, pt->y + move->y) = '+'; + rc = 1; + break; + default: + rc = 0; + } + + /* clean old sokoban position */ + if (rc == 1) { + char sokoban = getvalue (board, pt->x, pt->y); + switch (sokoban) { + case '@': + *getcell (board, pt->x, pt->y) = ' '; + break; + case '+': + *getcell (board, pt->x, pt->y) = '.'; + break; + } + } + + return rc; +} + +void _findsokoban (board_t *board, point *pt) +{ + int x, y; + for (x = 0; x < board->width; x++) { + for (y = 0; y < board->height; y++) { + switch (getvalue (board, x, y)) { + case '@': + case '+': + pt->x = x; + pt->y = y; + break; + } + } + } +} + +void movesokoban (board_t *board, int dir) +{ + point sokoban = {-1, -1}; + _findsokoban (board, &sokoban); + if (sokoban.x != -1) { + _moveelements (board, &sokoban, dir); + } +} + /* vim: set ts=4 sw=4 et: */ diff --git a/function.h b/function.h index 34f8760..f0fa0ef 100644 --- a/function.h +++ b/function.h @@ -37,6 +37,8 @@ char *getcell (board_t *board, int x, int y); char getvalue (board_t *board, int x, int y); +void movesokoban (board_t *board, int dir); + #endif /* __FUNCTION_H__ */ /* vim: set ts=4 sw=4 et: */ diff --git a/sokoban.c b/sokoban.c index 49557f1..eeb17f4 100644 --- a/sokoban.c +++ b/sokoban.c @@ -134,7 +134,7 @@ int main (int argc, char *argv[]) } } if (board == NULL) { - VERBOSE (ERROR, fprintf (stderr, "no board defined")); + VERBOSE (ERROR, fprintf (stderr, "no board defined\n")); return 1; } setscale (board, scale); @@ -170,9 +170,14 @@ int main (int argc, char *argv[]) /* event loop */ int mode = 0; int stop = 0; + int dir = -1; while (!stop) { char *ptr = NULL; + if (dir >= 0) { + movesokoban (board, dir); + dir = -1; + } boardwindow (board); int ch = getch (); @@ -187,15 +192,19 @@ int main (int argc, char *argv[]) break; case KEY_UP: case 'i': + dir = 0; break; case KEY_LEFT: case 'j': + dir = 3; break; case KEY_DOWN: case 'k': + dir = 2; break; case KEY_RIGHT: case 'l': + dir = 1; break; case KEY_ESC: case 'q': -- 2.30.2