From 11034b729ba6d8a3ef0a2a0d97247c2e3df62376 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Fri, 28 Jun 2024 22:30:04 +0200 Subject: [PATCH] most of the code is ready --- constant.c | 15 ++++-- display.c | 130 ++++++++++++++++++++++++++++++++++++++-------------- display.h | 4 +- function.c | 106 +++++++++++++++++++++++++++++++++--------- function.h | 8 ++++ solitaire.c | 58 ++++++++++++++++++----- type.h | 7 ++- 7 files changed, 251 insertions(+), 77 deletions(-) diff --git a/constant.c b/constant.c index 09d804c..d0dcbb2 100644 --- a/constant.c +++ b/constant.c @@ -12,7 +12,8 @@ board_t _board_french = {7, 7, "XXXXXXX" "XXXXXXX" " XXXXX " - " XXX "}; + " XXX ", + 1, 0, 0}; board_t _board_german = {9, 9, " XXX " @@ -23,7 +24,8 @@ board_t _board_german = {9, 9, "XXXXXXXXX" " XXX " " XXX " - " XXX "}; + " XXX ", + 1, 0, 0}; board_t _board_assymetric = {8, 9, " XXX " @@ -34,7 +36,8 @@ board_t _board_assymetric = {8, 9, "XXXXXXXX" " XXX " " XXX " - " XXX "}; + " XXX ", + 1, 0, 0}; board_t _board_english = {7, 7, " XXX " @@ -43,7 +46,8 @@ board_t _board_english = {7, 7, "XXXOXXX" "XXXXXXX" " XXX " - " XXX "}; + " XXX ", + 1, 0, 0}; board_t _board_diamond = {9, 9, " X " @@ -54,7 +58,8 @@ board_t _board_diamond = {9, 9, " XXXXXXX " " XXXXX " " XXX " - " X "}; + " X ", + 1, 0, 0}; board_t *getboard (char *name) { diff --git a/display.c b/display.c index 10cf02e..9ba3e7a 100644 --- a/display.c +++ b/display.c @@ -17,6 +17,12 @@ typedef enum { cyan, magenta, yellow, + bred, + bgreen, + bblue, + bcyan, + bmagenta, + byellow, black, wred, wgreen, @@ -32,12 +38,18 @@ void set_color (color_t color) if (init) { init_pair (white, COLOR_WHITE, COLOR_BLACK); - init_pair (red, COLOR_BLACK, COLOR_RED); - init_pair (green, COLOR_BLACK, COLOR_GREEN); - init_pair (blue, COLOR_BLACK, COLOR_BLUE); - init_pair (magenta, COLOR_BLACK, COLOR_MAGENTA); - init_pair (yellow, COLOR_BLACK, COLOR_YELLOW); - init_pair (cyan, COLOR_BLACK, COLOR_CYAN); + init_pair (red, COLOR_RED, COLOR_BLACK); + init_pair (green, COLOR_GREEN, COLOR_BLACK); + init_pair (blue, COLOR_BLUE, COLOR_BLACK); + init_pair (magenta, COLOR_MAGENTA, COLOR_BLACK); + init_pair (yellow, COLOR_YELLOW, COLOR_BLACK); + init_pair (cyan, COLOR_CYAN, COLOR_BLACK); + init_pair (bred, COLOR_BLACK, COLOR_RED); + init_pair (bgreen, COLOR_BLACK, COLOR_GREEN); + init_pair (bblue, COLOR_BLACK, COLOR_BLUE); + init_pair (bmagenta, COLOR_BLACK, COLOR_MAGENTA); + init_pair (byellow, COLOR_BLACK, COLOR_YELLOW); + init_pair (bcyan, COLOR_BLACK, COLOR_CYAN); init_pair (black, COLOR_BLACK, COLOR_WHITE); init_pair (wred, COLOR_WHITE, COLOR_RED); init_pair (wgreen, COLOR_WHITE, COLOR_GREEN); @@ -106,41 +118,89 @@ int helpwindow (char *msg, int xoffset, int yoffset) return j; } -void boardwindow (board_t *board, int xoffset, int yoffset) +void _element (board_t *board, int x, int y, int symb) +{ + int element = ' '; + switch (board->scale) { + case 1: + set_color (black); + switch (symb) { + case 'C': + set_color (bgreen); + break; + case 'F': + element = ACS_DIAMOND; + set_color (wgreen); + break; + case 'H': + element = ACS_DIAMOND; + set_color (red); + break; + case 'P': + element = ACS_DIAMOND; + set_color (byellow); + break; + case 'O': + set_color (white); + break; + case 'X': + set_color (white); + element = ACS_DIAMOND; + break; + case 'Z': + set_color (bblue); + break; + case ' ': + set_color (black); + break; + } + mvaddch (board->yoffset + y, board->xoffset + x, element); + set_color (white); + break; + } +} + +void boardwindow (board_t *board) { int i, j; set_color (black); - _dobound (board->xsize, board->ysize, xoffset, yoffset); + _dobound (board->width * board->scale, board->height * board->scale, board->xoffset, board->yoffset); set_color (white); - for (i = 0; i < board->xsize; i++) { - for (j = 0; j < board->ysize; j++) { - int element = ' '; - char cell = *getcell (board, i, j); - switch (cell) { - case 'H': - element = ACS_DIAMOND; - set_color (green); - break; - case 'P': - element = ACS_DIAMOND; - set_color (red); - break; - case 'O': - set_color (white); - break; - case 'X': - element = ACS_DIAMOND; - break; - case ' ': - set_color (black); - break; - default: - VERBOSE (WARNING, printf ("unknown code '%c'\n", cell)); - } - mvaddch (yoffset + j, xoffset + i, element); - set_color (white); + for (i = 0; i < board->width; i++) { + for (j = 0; j < board->height; j++) { + _element (board, i, j, getvalue (board, i, j)); + } + } +} + +void cursorwindow (board_t *board, int x, int y, int mode) +{ + switch (getvalue (board, x, y)) { + case 'O': + _element (board, x, y, 'C'); + break; + case 'X': + _element (board, x, y, (mode) ? 'H' : 'F'); + break; + case ' ': + _element (board, x, y, 'Z'); + break; + } + if (mode) { + set_color (wred); + if (testjump (board, x, y, 0)) { + _element (board, x, y - 2, 'P'); + } + if (testjump (board, x, y, 1)) { + _element (board, x - 2, y, 'P'); + } + if (testjump (board, x, y, 2)) { + _element (board, x, y + 2, 'P'); + } + if (testjump (board, x, y, 3)) { + _element (board, x + 2, y, 'P'); } } } diff --git a/display.h b/display.h index 3b4611d..4ec85b5 100644 --- a/display.h +++ b/display.h @@ -8,7 +8,9 @@ int helpwindow (char *msg, int xoffset, int yoffset); -void boardwindow (board_t *board, int xboard, int yboard); +void boardwindow (board_t *board); + +void cursorwindow (board_t *board, int x, int y, int mode); char *savewindow (int length, int xoffset, int yoffset); diff --git a/function.c b/function.c index f8e5daa..d64ff5e 100644 --- a/function.c +++ b/function.c @@ -21,18 +21,32 @@ int strmaxlen (char *str, char ch) return len; } -board_t *initboard (int xsize, int ysize) +board_t *initboard (int width, int height) { board_t *board = (board_t *) malloc (sizeof (board_t)); CHECKALLOC (board); - board->tab = (char *) calloc (1, xsize * ysize + 1); + board->tab = (char *) calloc (1, width * height + 1); CHECKALLOC (board->tab); - memset (board->tab, ' ', xsize * ysize); - board->xsize = xsize; - board->ysize = ysize; + memset (board->tab, ' ', width * height); + board->width = width; + board->height = height; + board->scale = 1; + board->xoffset = 0; + board->yoffset = 0; return board; } +board_t *copyboard (board_t *board) +{ + board_t *newboard = (board_t *) malloc (sizeof (board_t)); + CHECKALLOC (board); + memcpy (newboard, board, sizeof (board_t)); + newboard->tab = (char *) calloc (1, board->width * board->height + 1); + CHECKALLOC (newboard->tab); + memcpy (newboard->tab, board->tab, board->width * board->height + 1); + return newboard; +} + void freeboard (board_t *board) { if (board) { @@ -44,10 +58,10 @@ void freeboard (board_t *board) int _makecomments (char *buffer, board_t *board) { int i, j, l = 0; - for (j = 0; j < board->ysize; j++) { + for (j = 0; j < board->height; j++) { l += sprintf (buffer + l, "rem: \""); - for (i = 0; i < board->xsize; i++) { - l += sprintf (buffer + l, "%c", *getcell (board, i, j)); + for (i = 0; i < board->width; i++) { + l += sprintf (buffer + l, "%c", getvalue (board, i, j)); } l += sprintf (buffer + l, "\"\n"); } @@ -56,14 +70,14 @@ int _makecomments (char *buffer, board_t *board) char *saveboard (board_t *board) { - int size = 2 * (8 + 3) + 8 + board->xsize * board->ysize + 1; - VERBOSE (INFO, size += board->ysize * (8 + board->xsize)); + int size = 2 * (8 + 3) + 8 + board->width * board->height + 1; + VERBOSE (INFO, size += board->height * (8 + board->width)); char *buffer = (char *) calloc (size, 1); CHECKALLOC (buffer); - int l = sprintf (buffer, "xsize: %d\n", board->xsize); - l += sprintf (buffer + l, "ysize: %d\n", board->ysize); + int l = sprintf (buffer, "width: %d\n", board->width); + l += sprintf (buffer + l, "height: %d\n", board->height); l += sprintf (buffer + l, "tab: \"%s\"\n", board->tab); VERBOSE (INFO, _makecomments (buffer + l, board)); @@ -128,8 +142,8 @@ char *atos (char *str) board_t *loadboard (char *str) { - int xsize = 0; - int ysize = 0; + int width = 0; + int height = 0; char *tab = NULL; char *saveptr1, *saveptr2; @@ -144,10 +158,10 @@ board_t *loadboard (char *str) value++; } - if (strcmp (keyword, "xsize") == 0) { - xsize = atoi (value); - } else if (strcmp (keyword, "ysize") == 0) { - ysize = atoi (value); + if (strcmp (keyword, "width") == 0) { + width = atoi (value); + } else if (strcmp (keyword, "height") == 0) { + height = atoi (value); } else if (strcmp (keyword, "tab") == 0) { tab = atos (value); } else if (strcmp (keyword, "rem") == 0) { @@ -160,9 +174,9 @@ board_t *loadboard (char *str) } board_t *board = NULL; - if ((tab) && (strlen (tab) == (size_t)(xsize * ysize))) { - board = initboard (xsize, ysize); - memcpy (board->tab, tab, xsize * ysize); + if ((tab) && (strlen (tab) == (size_t)(width * height))) { + board = initboard (width, height); + memcpy (board->tab, tab, width * height); } return board; @@ -170,7 +184,55 @@ board_t *loadboard (char *str) char *getcell (board_t *board, int x, int y) { - return board->tab + x + board->xsize * y; + return board->tab + x + board->width * y; +} + +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 testjump (board_t *board, int x, int y, int mode) +{ + int ret = 0; + switch (mode) { + case 0: + ret = (getvalue (board, x, y - 1) == 'X') && (getvalue (board, x, y - 2) == 'O'); + break; + case 1: + ret = (getvalue (board, x - 1, y) == 'X') && (getvalue (board, x - 2, y) == 'O'); + break; + case 2: + ret = (getvalue (board, x, y + 1) == 'X') && (getvalue (board, x, y + 2) == 'O'); + break; + case 3: + ret = (getvalue (board, x + 1, y) == 'X') && (getvalue (board, x + 2, y) == 'O'); + break; + } + return ret; +} + +void dojump (board_t *board, int x, int y, int mode) +{ + *getcell (board, x, y) = 'O'; + switch (mode) { + case 0: + *getcell (board, x, y - 1) = 'O'; + *getcell (board, x, y - 2) = 'X'; + break; + case 1: + *getcell (board, x - 1, y) = 'O'; + *getcell (board, x - 2, y) = 'X'; + break; + case 2: + *getcell (board, x, y + 1) = 'O'; + *getcell (board, x, y + 2) = 'X'; + break; + case 3: + *getcell (board, x + 1, y) = 'O'; + *getcell (board, x + 2, y) = 'X'; + break; + } } /* vim: set ts=4 sw=4 et: */ diff --git a/function.h b/function.h index 55ba397..32878a8 100644 --- a/function.h +++ b/function.h @@ -19,6 +19,8 @@ int strmaxlen (char *str, char ch); board_t *initboard (int xsize, int ysize); +board_t *copyboard (board_t *board); + void freeboard (board_t *board); char *saveboard (board_t *board); @@ -31,6 +33,12 @@ board_t *loadboard (char *str); char *getcell (board_t *board, int x, int y); +char getvalue (board_t *board, int x, int y); + +int testjump (board_t *board, int x, int y, int mode); + +void dojump (board_t *board, int x, int y, int mode); + #endif /* __FUNCTION_H__ */ /* vim: set ts=4 sw=4 et: */ diff --git a/solitaire.c b/solitaire.c index 7dde7ae..f6f99da 100644 --- a/solitaire.c +++ b/solitaire.c @@ -34,6 +34,7 @@ char *help = " Move down cursor\n" " Move right cursor\n" " Quit\n" + " Release pet\n" " Save file\n" ; @@ -106,10 +107,11 @@ int main (int argc, char *argv[]) board_t *board = NULL; if (filename) { } else if (boardname) { - board = getboard (boardname); - if (board == (board_t *)(-1)) { + board_t *temp = getboard (boardname); + if (temp == (board_t *)(-1)) { return 0; } + board = copyboard (temp); } if (board == NULL) { return 1; @@ -125,25 +127,27 @@ int main (int argc, char *argv[]) start_color (); /* window positions */ - int xboard = xoffset + 1; - int yboard = xoffset + 1; - int xhelp = xboard + xoffset + 1 + board->xsize; + int xboard = board->xoffset = xoffset + 1; + int yboard = board->yoffset = xoffset + 1; + int xhelp = xboard + xoffset + 1 + board->width * board->scale; int xcursor = 0; int ycursor = 0; int yhelp = yboard; - int xsave = max (xboard + (board->xsize - savelen) / 2, 1); - int ysave = yboard + (board->ysize - 1) / 2; + int xsave = max (xboard + (board->width * board->scale - savelen) / 2, 1); + int ysave = yboard + (board->height * board->scale - 1) / 2; char *savename = NULL; /* init windows */ helpwindow (help, xhelp, yhelp); /* event loop */ + int mode = 0; int stop = 0; while (!stop) { char *ptr = NULL; - boardwindow (board, xboard, yboard); + boardwindow (board); + cursorwindow (board, xcursor, ycursor, mode); int ch = getch (); switch (ch) { @@ -151,22 +155,51 @@ int main (int argc, char *argv[]) case '\n': case '\r': case 'c': + if (mode == 1) { + mode = 0; + } else if (getvalue (board, xcursor, ycursor) == 'X') { + mode = 1; + } break; case KEY_UP: case 'i': - ycursor = (ycursor + board->ysize - 1) % board->ysize; + if (mode == 0) { + ycursor = (ycursor + board->height - 1) % board->height; + } else if (testjump (board, xcursor, ycursor, 0)) { + dojump (board, xcursor, ycursor, 0); + mode = 0; + ycursor -= 2; + } break; case KEY_LEFT: case 'j': - xcursor = (xcursor + board->xsize - 1) % board->xsize; + if (mode == 0) { + xcursor = (xcursor + board->width - 1) % board->width; + } else if (testjump (board, xcursor, ycursor, 1)) { + dojump (board, xcursor, ycursor, 1); + mode = 0; + xcursor -= 2; + } break; case KEY_DOWN: case 'k': - ycursor = (ycursor + 1) % board->ysize; + if (mode == 0) { + ycursor = (ycursor + 1) % board->height; + } else if (testjump (board, xcursor, ycursor, 2)) { + dojump (board, xcursor, ycursor, 2); + mode = 0; + ycursor += 2; + } break; case KEY_RIGHT: case 'l': - xcursor = (xcursor + 1) % board->xsize; + if (mode == 0) { + xcursor = (xcursor + 1) % board->width; + } else if (testjump (board, xcursor, ycursor, 3)) { + dojump (board, xcursor, ycursor, 3); + mode = 0; + xcursor += 2; + } break; case KEY_ESC: case 'q': @@ -188,6 +221,7 @@ int main (int argc, char *argv[]) case 127: case '\b': case 'x': + mode = 0; break; //case ERR: //default: diff --git a/type.h b/type.h index b32dd56..46cef0e 100644 --- a/type.h +++ b/type.h @@ -2,9 +2,12 @@ #define __TYPE_H__ typedef struct { - int xsize; - int ysize; + int width; + int height; char *tab; + int scale; + int xoffset; + int yoffset; } board_t; #endif /* __TYPE_H__ */ -- 2.30.2