diff --git a/tmp.txt b/tmp.txt deleted file mode 100644 index 2ee515d11c8b58d5a54114630ad969cdb00b804f..0000000000000000000000000000000000000000 --- a/tmp.txt +++ /dev/null @@ -1,16 +0,0 @@ -AddressSanitizer:DEADLYSIGNAL -================================================================= -==43005==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5577b8bb4608 bp 0x7fffa0d74860 sp 0x7fffa0d745c0 T0) -==43005==The signal is caused by a READ memory access. -==43005==Hint: address points to the zero page. - #0 0x5577b8bb4608 in handle_controls wordle/wordle.c:58 - #1 0x5577b8bb4e85 in launch_game wordle/wordle.c:261 - #2 0x5577b8baca69 in main /home/toguy/dev/hepia/sequencial-programming/wordle/main.c:18 - #3 0x7f4b4553afcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 - #4 0x7f4b4553b07c in __libc_start_main_impl ../csu/libc-start.c:409 - #5 0x5577b8bacbd4 in _start (/home/toguy/dev/hepia/sequencial-programming/wordle/bin/main+0x3bd4) - -AddressSanitizer can not provide additional info. -SUMMARY: AddressSanitizer: SEGV wordle/wordle.c:58 in handle_controls -==43005==ABORTING -make: *** [Makefile:18: main] Error 1 diff --git a/tool/test/tool-test.c b/tool/test/tool-test.c index 00b537d93d8f8eceaca31cd33d34a0cbffac76cb..b9f41db809974f5a2331f94dd7c533e428950508 100644 --- a/tool/test/tool-test.c +++ b/tool/test/tool-test.c @@ -16,47 +16,32 @@ void test_compute_matches_should_remain_BALAI(void) { char *answer = "BALAI"; set_answer(answer); - printf("ANSWER: %s\n\n", answer); - - set_try("BRUTE"); + set_try("SALUT"); Pattern *pattern = generate_pattern(); - possibility_t **p = compute_matches("BRUTE", pattern); + possibility_t **p = compute_matches("SALUT", pattern); - for (int i = 0; i < get_remaining_bank_count(); i++) - printf("%s\t%f\n", p[i]->word, p[i]->entropy); + free(pattern); + pattern = NULL; + + set_try("BARRE"); + pattern = generate_pattern(); + p = compute_matches("BARRE", pattern); + + free(pattern); + pattern = NULL; + + set_try("BILAN"); + pattern = generate_pattern(); + p = compute_matches("BILAN", pattern); free(pattern); pattern = NULL; - // - // printf("\n\n"); - // - // set_try("BLOCS"); - // pattern = generate_pattern(); - // p = compute_matches("BLOCS", pattern); - // - // for (int i = 0; i < get_remaining_bank_count(); i++) - // printf("%s\t%f\n", p[i]->word, p[i]->entropy); - // - // free(pattern); - // pattern = NULL; - // - // printf("\n\n"); - // - // set_try("BILLY"); - // pattern = generate_pattern(); - // p = compute_matches("BILLY", pattern); - // - // for (int i = 0; i < get_remaining_bank_count(); i++) - // printf("%s\t%f\n", p[i]->word, p[i]->entropy); - // - // free(pattern); // Assert TEST_ASSERT_EQUAL_INT(get_remaining_bank_count(), 1); - TEST_ASSERT_EQUAL_STRING_ARRAY(target, get_remaining_bank(), 1); + TEST_ASSERT_EQUAL_STRING_ARRAY(target, get_remaining_bank(), get_remaining_bank_count()); free(target[0]); free(target); - destroy_possibilities(p); } diff --git a/tool/tool.c b/tool/tool.c index 7a801048869f64a59a33665912d7d65824cf29f6..462851a424fef7f8bd2b6a7babfcbe794810ae98 100644 --- a/tool/tool.c +++ b/tool/tool.c @@ -48,14 +48,16 @@ matches_t *filter_out_remaining_bank(char *word, Pattern *pattern) { bool valid_word = true; for (int i = 0; i < WORD_LENGHT; i++) { // Filter out the non-valid words - if ((pattern[i] == WRONG && string_contains(current_word, word[i])) || - (pattern[i] == MISPLACED && !string_contains(current_word, word[i])) || - (pattern[i] == CORRECT && (strchr(current_word, word[i]) - current_word) != i)) { + if ((pattern[i] == CORRECT && (int)strcspn(current_word, (char[2]){word[i], '\0'}) != i) || + (pattern[i] == MISPLACED && strchr(current_word, word[i]) == NULL) || + (pattern[i] == WRONG && strchr(current_word, word[i]) != NULL)) { valid_word = false; + break; } // Clear the current char to not impact futur letter checks - current_word[i] = ' '; + if (pattern[i] == CORRECT) + current_word[i] = ' '; } if (!valid_word) @@ -69,6 +71,7 @@ matches_t *filter_out_remaining_bank(char *word, Pattern *pattern) { int idx = 0; for (int i = 0; i < remaining_bank_count; i++) { if (strlen(tmp[i]) != 0) { + // printf("%s\n", tmp[i]); matches->words[idx] = calloc(WORD_LENGHT + 1, sizeof(char)); strcpy(matches->words[idx], tmp[i]); idx++; @@ -108,6 +111,14 @@ double compute_entropy(char *word) { // Apply Shannon's formula double px = ((double)matches->count / (double)remaining_bank_count); sum += px * (log2(1 / px)); + + // printf("%s\t%f\t%f\t%d\t(%d, %d, %d, %d, %d) ", word, px, px * log2(1 / px), matches->count, *curr[0], *curr[1], + // *curr[2], + // *curr[3], *curr[4]); + // + // for (int i = 0; i < matches->count; i++) + // printf("%s ", matches->words[i]); + // printf("\n"); } destroy_matches(matches); @@ -173,6 +184,8 @@ int compare_possibilities(const void *s1, const void *s2) { void init_tool() { remaining_bank_count = get_bank_size(); remaining_bank = malloc(remaining_bank_count * sizeof(char *)); + possibility_count = remaining_bank_count; + possibilities = NULL; char **tmp = get_bank(); for (int i = 0; i < remaining_bank_count; i++) { @@ -185,6 +198,9 @@ void destroy_tool() { for (int i = 0; i < remaining_bank_count; i++) free(remaining_bank[i]); free(remaining_bank); + + if (possibilities != NULL) + destroy_possibilities(possibilities); } void destroy_possibilities(possibility_t **p) { @@ -210,13 +226,16 @@ possibility_t **compute_matches(char *word, Pattern *pattern) { // Create the new possibilities list // Delete no longer used words - for (int i = matches->count - 1; i < possibility_count; i++) { - free(possibilities[i]->word); - free(possibilities[i]); + if (possibility_count != get_bank_size()) { + for (int i = 0; i < possibility_count; i++) { + free(possibilities[i]->word); + free(possibilities[i]); + } } possibility_count = matches->count; possibilities = realloc(possibilities, possibility_count * sizeof(possibility_t *)); + for (int i = 0; i < possibility_count; i++) possibilities[i] = create_possibility(matches->words[i]); diff --git a/ui/ui.c b/ui/ui.c index 5dfc769c1ef5b43947c0ca7cdd9371a65678937c..2f0ab684f960f064b832042304e7a092b22450e6 100644 --- a/ui/ui.c +++ b/ui/ui.c @@ -132,12 +132,9 @@ void draw_title(int id) { } } -void show_answer(char *answer) { printw_center(answer, GAMEBOARD_Y_OFFSET + 10); } +void show_answer(char *answer) { printw_center(answer, GAMEBOARD_Y_OFFSET + 15); } -void hide_answer() { - move(GAMEBOARD_Y_OFFSET + 10, 0); - clrtoeol(); -} +void hide_answer() { printw_center(" ", GAMEBOARD_Y_OFFSET + 15); } bool init_term() { ui_window = initscr(); @@ -250,7 +247,7 @@ void toggle_help() { wrefresh(help); } -void toggle_tool(int count, char words[count][WORD_LENGHT + 1], double *entropies) { +void show_tool() { // Delete existing instance of the subwindow if (tool != NULL) { hide_tool(); @@ -266,13 +263,20 @@ void toggle_tool(int count, char words[count][WORD_LENGHT + 1], double *entropie exit(EXIT_FAILURE); } - scrollok(tool, TRUE); + refresh(); + wrefresh(tool); +} + +void update_tool(int count, char words[count][WORD_LENGHT + 1], double *entropies) { + wclear(tool); + box(tool, 0, 0); mvwprintw(tool, 0, 1, " Tool "); // Title - // Content - for (int i = 0; i < count; i++) - mvwprintw(tool, 2 + i, 1, "%s\t%f\n", words[i], entropies[i]); + mvwprintw(tool, 2, 2, " Mot \t\tEntropie"); + + for (int i = 0; i < (count > 30 ? 30 : count); i++) + mvwprintw(tool, 4 + i, 2, "%s\t\t%f", words[i], entropies[i]); refresh(); wrefresh(tool); diff --git a/ui/ui.h b/ui/ui.h index 6a19096cc3bf81b7f4fe25085ba01367804414ac..9bf570213f7a97a014dab13a624c751e1d7c1edf 100644 --- a/ui/ui.h +++ b/ui/ui.h @@ -99,12 +99,17 @@ void toggle_help(); /** * @brief Toggle the tool window + */ +void show_tool(); + +/** + * @brief Update the tool subwindow * * @param count * @param words * @param entropies */ -void toggle_tool(int count, char words[count][WORD_LENGHT + 1], double *entropies); +void update_tool(int count, char words[count][WORD_LENGHT + 1], double *entropies); /** * @brief Show the gameboard diff --git a/wordle/wordle.c b/wordle/wordle.c index 556ba748f9a3b9b9f4a8f5267932079bdef285e8..53aae199093a3169ddb6e89e585323afd69f4858 100644 --- a/wordle/wordle.c +++ b/wordle/wordle.c @@ -32,6 +32,8 @@ void render_game() { } show_gameboard(TRIES_COUNT, WORD_LENGHT, tries, patterns, score); + + move(LINES - 2, COLS - 10); } /** @@ -45,23 +47,6 @@ void handle_controls(int key) { toggle_help(); break; - case KEYBIND_TAG: - if (mode == TOOL_ASSISTED) { - if (current_try_id == 0) - break; - - char words[get_remaining_bank_count()][WORD_LENGHT + 1]; - double entropies[get_remaining_bank_count()]; - - for (int i = 0; i < get_remaining_bank_count(); i++) { - strcpy(words[i], remaining_possibilities[i]->word); - entropies[i] = remaining_possibilities[i]->entropy; - } - - toggle_tool(get_remaining_bank_count(), words, entropies); - } - break; - case KEYBIND_QUIT: terminate_game(); break; @@ -75,6 +60,7 @@ void handle_controls(int key) { for (int i = 0; i < WORD_LENGHT; i++) patterns[current_try_id][i] = pattern[i]; free(pattern); + pattern = NULL; current_try_id += 1; current_try_letter_id = 0; @@ -87,7 +73,23 @@ void handle_controls(int key) { } } - remaining_possibilities = compute_matches(tries[current_try_id - 1], patterns[current_try_id - 1]); + if (get_remaining_bank_count() > 0 && mode == TOOL_ASSISTED) + remaining_possibilities = compute_matches(tries[current_try_id - 1], patterns[current_try_id - 1]); + + if (mode == TOOL_ASSISTED && remaining_possibilities != NULL) { + if (current_try_id == 0 || get_remaining_bank_count() <= 0) + break; + + char words[get_remaining_bank_count()][WORD_LENGHT + 1]; + double entropies[get_remaining_bank_count()]; + + for (int i = 0; i < get_remaining_bank_count(); i++) { + strcpy(words[i], remaining_possibilities[i]->word); + entropies[i] = remaining_possibilities[i]->entropy; + } + + update_tool(get_remaining_bank_count(), words, entropies); + } break; } } @@ -96,7 +98,10 @@ void handle_controls(int key) { // PUBLIC //========================== void initialize_game() { - init_tool(); + if (mode == TOOL_ASSISTED) { + show_tool(); + init_tool(); + } // Reset game variables _game_finished = false; @@ -119,7 +124,8 @@ void initialize_game() { void terminate_game() { _game_finished = true; } void destroy_game() { - destroy_tool(); + if (mode == TOOL_ASSISTED) + destroy_tool(); for (int i = 0; i < TRIES_COUNT; i++) { free(tries[i]);