diff --git a/src/main.c b/src/main.c index be760a9..0ddcb8b 100644 --- a/src/main.c +++ b/src/main.c @@ -2,28 +2,23 @@ Wordle game implementation in the C programming language */ -/* TODO: - * implement user-specified colors for theming - * therefore renaming the colors from smt like INCORRECT to INCORRECT etc. -*/ - #include #include #include #include #include +#include -char *RESET = "\x1b[0m"; -char *INCORRECT = "\x1b[31m"; -char *CORRECT = "\x1b[32m"; -char *OUTOFPLACE = "\x1b[33m"; -char *ASCII = "\x1b[7m"; +static char RESET[20]; +static char INCORRECT[20]; +static char CORRECT[20]; +static char OUTOFPLACE[20]; +static char ASCII[20]; -char *RESET_USER = "\x1b[0m"; -char *INCORRECT_USER = "\x1b[31m"; -char *CORRECT_USER = "\x1b[32m"; -char *OUTOFPLACE_USER = "\x1b[33m"; -char *ASCII_USER = "\x1b[7m"; +static char INCORRECT_USER[20]; +static char CORRECT_USER[20]; +static char OUTOFPLACE_USER[20]; +static char ASCII_USER[20]; int flag_light_theme = 0; int flag_user_theme = 0; @@ -96,130 +91,64 @@ void show_win_lose_message(); */ int argparse(int argc, char *argv[]) { int flag_error = 0; - for (int i = 0; i < argc; i++) { - /* - look for invalid arguments - */ - if (strcmp(argv[i], argv[0]) != 0 && - strcmp(argv[i], "-h") != 0 && - strcmp(argv[i], "--help") != 0 && - strcmp(argv[i], "-l") != 0 && - strcmp(argv[i], "--light-theme") != 0 && - strcmp(argv[i], "-t") != 0 && - strcmp(argv[i], "--theme") != 0 && - strcmp(argv[i-1], "-t") != 0 && // RESET color - strcmp(argv[i-1], "--theme") != 0 && - strcmp(argv[i-2], "-t") != 0 && // INCORRECT color, - strcmp(argv[i-2], "--theme") != 0 && - strcmp(argv[i-3], "-t") != 0 && // CORRECT color - strcmp(argv[i-3], "--theme") != 0 && - strcmp(argv[i-4], "-t") != 0 && // OUTOFPLACE color - strcmp(argv[i-4], "--theme") != 0 && - strcmp(argv[i-5], "-t") != 0 && // ASCII color - strcmp(argv[i-5], "--theme") != 0 && - strcmp(argv[i], "-v") != 0 && - strcmp(argv[i], "--verbose") != 0 && - ) { - fprintf(stderr, "Invalid argument %s\n", argv[i]); - flag_error = 1; - } - if (strcmp(argv[i], "-w") != 0 && - strcmp(argv[i], "--wordlist") != 0 - ) { - if (strcmp(argv[i-1], "-w") != 0 && - strcmp(argv[i-1], "--wordlist") != 0 - ) { - } - } + int option; + char theme_values[4][2] = { " ", " ", " ", " " }; + int option_index = 0; - /* - print the help & usage - */ + static struct option long_options[] = { + {"theme", required_argument, 0, 't'}, + {"wordlist", required_argument, 0, 'w'}, + {"light-theme", no_argument, 0, 'l'}, + {"verbose", no_argument, 0, 'v'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; - if (strcmp(argv[i], "--help") == 0) { - print_help_and_usage(); - return 2; - } - // -------------------------------------------------------------- - if (strcmp(argv[i], "-h") == 0) { - print_help_and_usage(); - return 2; - } + while ((option = getopt_long(argc, argv, "hvt:w:l", long_options, &option_index)) != -1) { + switch (option) { + case 'h': + print_help_and_usage(); + return 2; + case 'v': + flag_verbose = 1; + break; + case 't': + if (strlen(optarg) != 6) { + fprintf(stderr, "Invalid value. -h/--help for help.\n"); + flag_error = 1; + } else { + for (int i = 0, c = 0; i < 3, c < 6; i++, c += 2) { + sprintf(theme_values[i], "%c%c", optarg[c], optarg[c+1]); + } + flag_user_theme = 1; + set_user_theme(theme_values[0], theme_values[1], theme_values[2]); + if (flag_verbose == 1) printf("user-specified theme on\n"); + } + break; + case 'w': + strcpy(wordlist_path, optarg); + flag_wordlist = 1; + if (flag_verbose == 1) printf("using wordlist %s\n", wordlist_path); + break; + case 'l': + flag_light_theme = 1; + if (flag_verbose == 1) printf("light theme on\n"); + break; + default: + fprintf(stderr, "Invalid argument\n"); + flag_error = 1; + break; + } + if (flag_error == 1) break; + } - /* - getting the debug flag for debug printing - */ - if (strcmp(argv[i], "--verbose") == 0 && flag_verbose == 0) { - flag_verbose = 1; - } - // -------------------------------------------------------------- - if (strcmp(argv[i], "-v") == 0 && flag_verbose == 0) { - flag_verbose = 1; - } + if (flag_wordlist == 0) { + strcpy(wordlist_path, "lib/wordlist"); + if (flag_verbose == 1) printf("wordlist_path gets the default path /usr/lib/wordlists/wordlist\n"); + } - /* - deciding on light/dark theme - */ - if (strcmp(argv[i], "--light-theme") == 0 && flag_light_theme == 0) { - flag_light_theme = 1; - } - // -------------------------------------------------------------- - if (strcmp(argv[i], "-l") == 0 && flag_light_theme == 0) { - flag_light_theme = 1; - } - - /* - getting the path to the wordlist - */ - if (strcmp(argv[i], "--wordlist") == 0 && flag_wordlist == 0) { - flag_wordlist = 1; - if (argv[i+1] != NULL) { // if there is an argument present after that, read it as the wordlist path - strcpy(wordlist_path, argv[i+1]); - } else { - fprintf(stderr, "Missing argument after %s\nUsage: %s \n", argv[i], argv[i]); - flag_error = 1; - } - } else if (strcmp(argv[i], "--wordlist") != 0 && flag_wordlist == 0) { - strcpy(wordlist_path, "lib/wordlist"); - flag_wordlist = 1; - } - // -------------------------------------------------------------- - if (strcmp(argv[i], "-w") == 0 && flag_wordlist == 0) { - flag_wordlist = 1; - if (argv[i+1] != NULL) { // if there is an argument present after that, read it as the wordlist path - strcpy(wordlist_path, argv[i+1]); - } else { - fprintf(stderr, "Missing argument after %s\nUsage: %s \n", argv[i], argv[i]); - flag_error = 1; - } - } else if (strcmp(argv[i], "-w") != 0 && flag_wordlist == 0) { - strcpy(wordlist_path, "lib/wordlist"); - flag_wordlist = 1; - } - - /* - getting user-specified theme colors - */ - if (strcmp(argv[i], "-t") != 0 && flag_user_theme == 0) { - flag_user_theme = 1; - set_user_theme(argv[i+1], argv[i+2], argv[i+3], argv[i+4], argv[i+5]); - } - // -------------------------------------------------------------- - if (strcmp(argv[i], "--theme") != 0 && flag_user_theme == 0) { - flag_user_theme = 1; - set_user_theme(argv[i+1], argv[i+2], argv[i+3], argv[i+4], argv[i+5]); - } - } - - if (file_exists(wordlist_path) == 0) { - fprintf(stderr, "File %s not found\n", wordlist_path); - flag_error = 1; - } - - if (flag_verbose == 1) printf("wordlist_path: %s\n", wordlist_path); - - return flag_error; + return flag_error; } /* @@ -269,7 +198,6 @@ void eval_win(int i) { evaluate the word */ void eval_word(char word[]) { - printf("\n%d\n", search_wordlist(wordlist, word)); if (search_wordlist(wordlist, word) != -1) { eval_win(search_wordlist(wordlist, word)); eval_lose(); @@ -328,24 +256,20 @@ void game() { */ void get_random_word(char word_to_guess[], char wordlist_path[]) { FILE* wordlist_file = fopen(wordlist_path, "r"); - char ch; - int i = 0; + if (wordlist_file == NULL) { + perror("Error opening file"); + } char temp_word[6]; - while ((ch = fgetc(wordlist_file)) != EOF) { - if (ch != '\n') { - temp_word[i] = ch; - i++; - } else { - temp_word[i] = '\0'; - i = 0; - strcpy(wordlist[len_wordlist], temp_word); - len_wordlist++; - } + while (fscanf(wordlist_file, "%5s", temp_word) == 1 ) { + strcpy(wordlist[len_wordlist], temp_word); + len_wordlist++; } srand(time(NULL)); strcpy(word_to_guess, wordlist[rand() % len_wordlist]); + + fclose(wordlist_file); } /* @@ -391,12 +315,12 @@ void print_help_and_usage() { " specify a custom wordlist\n" " RULES: five characters on each line (no empty lines),\n" " each new line is separated by '\\n' (Enter/Return)\n" - "-t/--theme \n" // TODO: make work + "-t/--theme \n" " specify the colors in which the playfield will be visible\n" " RULES: choose the color from this list:\n" - " [ 'x' (default/reset), 'b' (black), 'r' (red), 'g' (green), 'y' (yellow), 'l' (blue), 'm' (magenta), 'c' (cyan), 'w' (white) ]\n" + " [ 'b' (black), 'r' (red), 'g' (green), 'y' (yellow), 'l' (blue), 'm' (magenta), 'c' (cyan), 'w' (white) ]\n" " the format is \n" - " EXAMPLE: '-t xx gb bw bb wb'\n" + " EXAMPLE: '-t rwgwlw'\n" "-l/--light-theme\n" " activate light theme\n" "-v/--verbose\n" @@ -456,35 +380,33 @@ void set_theme() { if (flag_user_theme != 1) { // handle light/dark mode if (flag_light_theme == 1) { - RESET = "\x1b[0;0m"; - INCORRECT = "\x1b[0;41m"; - CORRECT = "\x1b[0;42m"; - OUTOFPLACE = "\x1b[0;43m"; - ASCII = "\x1b[0;7m"; + snprintf(RESET, sizeof(RESET), "\x1b[0;0m"); + snprintf(INCORRECT, sizeof(INCORRECT), "\x1b[41;41m"); + snprintf(CORRECT, sizeof(CORRECT), "\x1b[42;42m"); + snprintf(OUTOFPLACE, sizeof(OUTOFPLACE), "\x1b[42;43m"); + snprintf(ASCII, sizeof(ASCII), "\x1b[37;37m"); } else { - RESET = "\x1b[37;0m"; - INCORRECT = "\x1b[37;41m"; - CORRECT = "\x1b[37;42m"; - OUTOFPLACE = "\x1b[37;43m"; - ASCII = "\x1b[37;90m"; + snprintf(RESET, sizeof(RESET), "\x1b[30;0m"); + snprintf(INCORRECT, sizeof(INCORRECT), "\x1b[30;41m"); + snprintf(CORRECT, sizeof(CORRECT), "\x1b[30;42m"); + snprintf(OUTOFPLACE, sizeof(OUTOFPLACE), "\x1b[30;43m"); + snprintf(ASCII, sizeof(ASCII), "\x1b[30;90m"); } } else { // handle user-specified theme - - strcpy(RESET, RESET_USER); - strcpy(INCORRECT, INCORRECT_USER); - strcpy(CORRECT, CORRECT_USER); - strcpy(OUTOFPLACE, OUTOFPLACE_USER); - strcpy(ASCII, ASCII_USER); + snprintf(RESET, sizeof(RESET), "\x1b[0;0m"); + snprintf(INCORRECT, sizeof(INCORRECT), "%s", INCORRECT_USER); + snprintf(CORRECT, sizeof(CORRECT), "%s", CORRECT_USER); + snprintf(OUTOFPLACE, sizeof(OUTOFPLACE), "%s", OUTOFPLACE_USER); + //snprintf(ASCII, sizeof(ASCII), "%s", ASCII_USER); } } /* set user-specified theme */ -void set_user_theme(char reset[], char incorrect[], char correct[], char outofplace[], char ascii[]) { - /* x = reset - * b = black +void set_user_theme(char incorrect[], char correct[], char outofplace[]) { + /* b = black * r = red * g = green * y = yellow @@ -494,60 +416,13 @@ void set_user_theme(char reset[], char incorrect[], char correct[], char outofpl * w = white */ - int reset_int[2]; int incorrect_int[2]; int correct_int[2]; int outofplace_int[2]; - int ascii_int[2]; // converting the flags into usable numbers - for (int i = 0; i < 2; i++) { - switch (reset[i]) { - case 'x': - if (i == 0) reset_int[i] = 0; - if (i == 1) reset_int[i] = 0; - break; - case 'b': - if (i == 0) reset_int[i] = 30; - if (i == 1) reset_int[i] = 40; - break; - case 'r': - if (i == 0) reset_int[i] = 31; - if (i == 1) reset_int[i] = 41; - break; - case 'g': - if (i == 0) reset_int[i] = 32; - if (i == 1) reset_int[i] = 42; - break; - case 'y': - if (i == 0) reset_int[i] = 33; - if (i == 1) reset_int[i] = 43; - break; - case 'l': - if (i == 0) reset_int[i] = 34; - if (i == 1) reset_int[i] = 44; - break; - case 'm': - if (i == 0) reset_int[i] = 35; - if (i == 1) reset_int[i] = 45; - break; - case 'c': - if (i == 0) reset_int[i] = 36; - if (i == 1) reset_int[i] = 46; - break; - case 'w': - if (i == 0) reset_int[i] = 37; - if (i == 1) reset_int[i] = 47; - break; - } - } - for (int i = 0; i < 2; i++) { switch (incorrect[i]) { - case 'x': - if (i == 0) incorrect_int[i] = 0; - if (i == 1) incorrect_int[i] = 0; - break; case 'b': if (i == 0) incorrect_int[i] = 30; if (i == 1) incorrect_int[i] = 40; @@ -585,10 +460,6 @@ void set_user_theme(char reset[], char incorrect[], char correct[], char outofpl for (int i = 0; i < 2; i++) { switch (correct[i]) { - case 'x': - if (i == 0) correct_int[i] = 0; - if (i == 1) correct_int[i] = 0; - break; case 'b': if (i == 0) correct_int[i] = 30; if (i == 1) correct_int[i] = 40; @@ -626,10 +497,6 @@ void set_user_theme(char reset[], char incorrect[], char correct[], char outofpl for (int i = 0; i < 2; i++) { switch (outofplace[i]) { - case 'x': - if (i == 0) outofplace_int[i] = 0; - if (i == 1) outofplace_int[i] = 0; - break; case 'b': if (i == 0) outofplace_int[i] = 30; if (i == 1) outofplace_int[i] = 40; @@ -665,63 +532,19 @@ void set_user_theme(char reset[], char incorrect[], char correct[], char outofpl } } - for (int i = 0; i < 2; i++) { - switch (ascii[i]) { - case 'x': - if (i == 0) ascii_int[i] = 0; - if (i == 1) ascii_int[i] = 0; - break; - case 'b': - if (i == 0) ascii_int[i] = 30; - if (i == 1) ascii_int[i] = 40; - break; - case 'r': - if (i == 0) ascii_int[i] = 31; - if (i == 1) ascii_int[i] = 41; - break; - case 'g': - if (i == 0) ascii_int[i] = 32; - if (i == 1) ascii_int[i] = 42; - break; - case 'y': - if (i == 0) ascii_int[i] = 33; - if (i == 1) ascii_int[i] = 43; - break; - case 'l': - if (i == 0) ascii_int[i] = 34; - if (i == 1) ascii_int[i] = 44; - break; - case 'm': - if (i == 0) ascii_int[i] = 35; - if (i == 1) ascii_int[i] = 45; - break; - case 'c': - if (i == 0) ascii_int[i] = 36; - if (i == 1) ascii_int[i] = 46; - break; - case 'w': - if (i == 0) ascii_int[i] = 37; - if (i == 1) ascii_int[i] = 47; - break; - } - } - - int reset_f = reset_int[0]; - int reset_b = reset_int[1]; int incorrect_f = incorrect_int[0]; int incorrect_b = incorrect_int[1]; int correct_f = correct_int[0]; int correct_b = correct_int[1]; int outofplace_f = outofplace_int[0]; int outofplace_b = outofplace_int[1]; - int ascii_f = ascii_int[0]; - int ascii_b = ascii_int[1]; - sprintf(RESET_USER, "\x1b[%d;%dm", reset_f, reset_b); - sprintf(INCORRECT_USER, "\x1b[%d;%dm", incorrect_f, incorrect_b); - sprintf(CORRECT_USER, "\x1b[%d;%dm", correct_f, correct_b); - sprintf(OUTOFPLACE_USER, "\x1b[%d;%dm", outofplace_f, outofplace_b); - sprintf(ASCII_USER, "\x1b[%d;%dm", ascii_f, ascii_b); + snprintf(INCORRECT_USER, sizeof(INCORRECT_USER), "\x1b[%d;%dm", incorrect_f, incorrect_b); + snprintf(CORRECT_USER, sizeof(CORRECT_USER), "\x1b[%d;%dm", correct_f, correct_b); + snprintf(OUTOFPLACE_USER, sizeof(OUTOFPLACE_USER), "\x1b[%d;%dm", outofplace_f, outofplace_b); + //snprintf(ASCII_USER, sizeof(ASCII_USER), "\x1b[%d;%dm", ascii_f, ascii_b); + + set_theme(); } /*