From: Laurent MAZET Date: Tue, 11 Jun 2024 17:20:13 +0000 (+0200) Subject: add spell checking support X-Git-Tag: v1.0~27 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=06c8137f08d97902c2634e75d025c95bad01eb00;p=scrabble.git add spell checking support --- diff --git a/display.c b/display.c index 218ce78..d4fd871 100644 --- a/display.c +++ b/display.c @@ -138,16 +138,19 @@ int _helpwindow (char *msg, int xoffset, int yoffset, int length) return j; } -int helpwindow (char *msg, char *msg2, int xoffset, int yoffset) +void _displaytitle (char *title, int xoffset, int yoffset) { - char *title = "Help message"; - int length = strmaxlen (msg, '\n'); - int i; - for (i = 0; (i < length) && (title[i] != '\0'); i++) { - mvaddch (yoffset , xoffset + i, title[i]); + for (i = 0; title[i] != '\0'; i++) { + mvaddch (yoffset, xoffset + i, title[i]); mvaddch (yoffset + 1, xoffset + i, ACS_HLINE); } +} + +int helpwindow (char *msg, char *msg2, int xoffset, int yoffset) +{ + _displaytitle ("Help message", xoffset, yoffset); + int length = strmaxlen (msg, '\n'); int j = 2; j += _helpwindow (msg, xoffset, yoffset + j, length); j++; @@ -158,15 +161,9 @@ int helpwindow (char *msg, char *msg2, int xoffset, int yoffset) void valuewindow (bag_t *bag, int xoffset, int yoffset, int length, char current) { - char *title = "Tile values"; + _displaytitle ("Tile values", xoffset, yoffset); int i; int n = length / 5; - - for (i = 0; (i < length) && (title[i] != '\0'); i++) { - mvaddch (yoffset, xoffset + i, title[i]); - mvaddch (yoffset + 1, xoffset + i, ACS_HLINE); - } - int N = (bag->nbletters + n - 1) / n; for (i = 0; i < bag->nbletters; i++) { int x = xoffset + (i % 2) + 5 * (i / N); @@ -216,15 +213,31 @@ void drawwindow (draw_t *game, int score, int xoffset, int yoffset, int mode) void scorewindow (int score, int xoffset, int yoffset) { - char *title = "Score"; - int i; - for (i = 0; title[i] != '\0'; i++) { - mvaddch (yoffset, xoffset + i, title[i]); - mvaddch (yoffset + 1, xoffset + i, ACS_HLINE); - } + _displaytitle ("Score", xoffset, yoffset); char str[12] = {0}; sprintf (str, " %3d", score); mvaddstr (yoffset + 2, xoffset, str); } +void spellwindow (word_t *words, int xoffset, int yoffset, int mode) +{ + _displaytitle ("Spelling", xoffset, yoffset); + int i, n = 0; + for (i = 0; i < words->maxnbwords; i++) { + if (words->status[i] != none) { + if (mode) { + set_color ((words->status[i] == correct) ? wgreen : wred); + mvaddstr (yoffset + 2 + n, xoffset, words->tab[i]); + set_color (white); + } else { + int j; + for (j = 0; words->tab[i][j] != '\0'; j++) { + mvaddch (yoffset + 2 + n, xoffset + j, ' '); + } + } + n++; + } + } +} + /* vim: set ts=4 sw=4 et: */ diff --git a/display.h b/display.h index ad9d86c..e8ef41d 100644 --- a/display.h +++ b/display.h @@ -17,6 +17,8 @@ void drawwindow (draw_t *game, int score, int xoffset, int yoffset, int mode); void scorewindow (int score, int xoffset, int yoffset); +void spellwindow (word_t *words, int xoffset, int yoffset, int mode); + #endif /* __DISPLAY_H__ */ /* vim: set ts=4 sw=4 et: */ diff --git a/function.c b/function.c index 267f013..97fd3fc 100644 --- a/function.c +++ b/function.c @@ -331,4 +331,117 @@ int isturnempty (play_t *turn) return ret; } +word_t *initword (int maxnbwords, int maxlength) +{ + int i; + word_t *words = (word_t *) calloc (1, sizeof (word_t)); + words->tab = (char **) calloc (maxnbwords, sizeof (char *)); + for (i = 0; i < maxnbwords; i++) { + words->tab[i] = (char *) calloc (maxlength, 1); + } + words->status = (spelling_e *) calloc (maxnbwords, sizeof (spelling_e)); + words->maxnbwords = maxnbwords; + return words; +} + +void freeword (word_t *words) +{ + if (words) { + if (words->tab) { + int i; + for (i = 0; i < words->maxnbwords; i++) { + free (words->tab[i]); + } + } + free (words->tab); + free (words->status); + } + free (words); +} + +spelling_e _checkdict (char *word, char *dict) +{ + spelling_e ret = incorrect; + FILE *fd = fopen (dict, "r"); + if (fd) { + while (!feof (fd)) { + char str[128] = {0}; + fscanf (fd, "%s", str); + if (strcmp (word, str) == 0) { + ret = correct; + break; + } + } + fclose (fd); + } else { + ret = correct; + } + return ret; +} + +void checkspelling (word_t *words, play_t *play, play_t *turn, char *dict) +{ + int i, j; + + /* clean */ + for (i = 0; i < words->maxnbwords; i++) { + words->tab[i][0] = '\0'; + words->status[i] = none; + } + + int n = 0; + + /* words in line */ + for (j = 0; j < play->ysize; j++) { + int nbletters = 0; + int accountable = 0; + for (i = 0; i < play->xsize; i++) { + char letter = *_getletteraddr (play, i, j); + if (letter != ' ') { + words->tab[n][nbletters++] = letter; + if (*_getletteraddr (turn, i, j) != ' ') { + accountable = 1; + } + } + if (((letter == ' ') || (i == play->xsize - 1)) && (accountable)) { + if (nbletters > 1) { + words->tab[n][nbletters] = '\0'; + words->status[n] = _checkdict (words->tab[n], dict); + } + n++; + } + if (letter == ' ') { + nbletters = 0; + accountable = 0; + } + } + } + + /* words in column */ + for (i = 0; i < play->xsize; i++) { + int nbletters = 0; + int accountable = 0; + for (j = 0; j < play->ysize; j++) { + char letter = *_getletteraddr (play, i, j); + if (letter != ' ') { + words->tab[n][nbletters++] = letter; + if (*_getletteraddr (turn, i, j) != ' ') { + accountable = 1; + } + } + if (((letter == ' ') || (i == play->xsize - 1)) && (accountable)) { + if (nbletters > 1) { + words->tab[n][nbletters] = '\0'; + words->status[n] = _checkdict (words->tab[n], dict); + } + n++; + } + if (letter == ' ') { + nbletters = 0; + accountable = 0; + } + } + } +} + /* vim: set ts=4 sw=4 et: */ diff --git a/function.h b/function.h index 67ca4fb..e30a035 100644 --- a/function.h +++ b/function.h @@ -41,6 +41,12 @@ int evalscore (play_t *play, play_t *turn, board_t *board, bag_t *bag); int isturnempty (play_t *turn); +word_t *initword (int maxnbwords, int maxlength); + +void freeword (word_t *words); + +void checkspelling (word_t *words, play_t *play, play_t *turn, char *dict); + #endif /* __FUNCTION_H__ */ /* vim: set ts=4 sw=4 et: */ diff --git a/scrabble.c b/scrabble.c index 512e9f1..a14fd3a 100644 --- a/scrabble.c +++ b/scrabble.c @@ -26,6 +26,7 @@ char *version = "0.1"; char *boardname = "15x15-7"; char *language = "fr"; int nbplayers = 2; +char *dict = NULL; int xoffset = 4; int yoffset = 3; @@ -48,8 +49,9 @@ char *help = int usage (int ret) { FILE *fd = ret ? stderr : stdout; - fprintf (fd, "usage: %s [-b board] [-h] [-l lang] [-n nb] [-v level]\n", progname); + fprintf (fd, "usage: %s [-b board] [-d dict] [-h] [-l lang] [-n nb] [-v level]\n", progname); fprintf (fd, " -b: board (%s)\n", boardname); + fprintf (fd, " -d: dictionary (%s)\n", (dict) ? dict : "none"); fprintf (fd, " -h: help message\n"); fprintf (fd, " -l: language (%s)\n", language); fprintf (fd, " -n: number of players (%d)\n", nbplayers); @@ -91,6 +93,15 @@ int main (int argc, char *argv[]) return usage (1); } break; + case 'd': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg) { + dict = arg; + } else { + VERBOSE (ERROR, fprintf (stderr, "%s: no dictionary specified\n", progname)); + return usage (1); + } + break; case 'l': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; if (arg) { @@ -136,6 +147,15 @@ int main (int argc, char *argv[]) VERBOSE (ERROR, fprintf (stderr, "incorrect number of player [1, 4] (%d)\n", nbplayers)); return 1; } + if (dict) { + FILE *fd = fopen (dict, "r"); + if (fd) { + fclose (fd); + } else { + VERBOSE (ERROR, fprintf (stderr, "dictionary not found\n")); + return 1; + } + } srand (time (NULL)); @@ -154,6 +174,8 @@ int main (int argc, char *argv[]) turn[n] = initplay (board->xsize, board->ysize); } + word_t *words = initword (board->length * 2, max (board->xsize, board->ysize) + 1); + initscr (); noecho (); cbreak (); @@ -176,9 +198,12 @@ int main (int argc, char *argv[]) int helplen = helpwindow (help, getextrahelp (language), xhelpwin, yhelpwin); - int xscorewin = xhelpwin + helplen+ xoffset; + int xscorewin = xhelpwin + helplen + xoffset; int yscorewin = yhelpwin; + int xspellwin = xscorewin; + int yspellwin = yscorewin + 3 + 1; + int mode = 0; showboard (play, board, xoffset, yoffset, mode); @@ -203,7 +228,11 @@ int main (int argc, char *argv[]) valuewindow (bag, xvaluewin, yvaluewin, 10, highlight); scorewindow (nbpoints, xscorewin, yscorewin); - switch (getch ()) { + checkspelling (words, play, turn[n], dict); + spellwindow (words, xspellwin, yspellwin, 1); + int ch = getch (); + spellwindow (words, xspellwin, yspellwin, 0); + switch (ch) { case '\t': case 'c': letter = getnextletter (game[n]); @@ -305,12 +334,15 @@ int main (int argc, char *argv[]) free (ydrawwin); free (score); freedraw (draw); + freeword (words); return 0; } /* test: scrabble.exe -b 2>&1 | grep 'no board' */ /* test: scrabble.exe -b 6x6-7i 2>&1 | grep 'not found' */ +/* test: scrabble.exe -d 2>&1 | grep 'no dictionary' */ +/* test: scrabble.exe -d none.dict 2>&1 | grep 'not found' */ /* test: scrabble.exe -h | grep usage */ /* test: scrabble.exe -l 2>&1 | grep 'no language' */ /* test: scrabble.exe -l aa 2>&1 | grep 'not found' */ diff --git a/type.h b/type.h index af66756..d184813 100644 --- a/type.h +++ b/type.h @@ -38,6 +38,18 @@ typedef struct { int index; } draw_t; +typedef enum { + incorrect = -1, + none = 0, + correct = 1 +} spelling_e; + +typedef struct { + int maxnbwords; + char **tab; + spelling_e *status; +} word_t; + #endif /* __TYPE_H__ */ /* vim: set ts=4 sw=4 et: */