diff --git a/conf.h b/conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..36f148ac13a0202fe5a94ead3c289499976234a6
--- /dev/null
+++ b/conf.h
@@ -0,0 +1,12 @@
+#ifndef CONF_H_
+#define CONF_H_
+
+// Game setup
+#define TRIES_COUNT 6
+#define WORD_LENGHT 5
+
+// Enums
+typedef enum Gamemode { SOLO, VERSUS, TOOL_ASSISTED } Gamemode;
+typedef enum Pattern { WRONG, MISPLACED, CORRECT, NAP } Pattern; // NAP => Not A Pattern (Only used when computing all possible patterns)
+
+#endif
\ No newline at end of file
diff --git a/tmp.txt b/tmp.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2ee515d11c8b58d5a54114630ad969cdb00b804f
--- /dev/null
+++ b/tmp.txt
@@ -0,0 +1,16 @@
+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 fed7b6a9230cdcfa18508c55a49bdf61234636b8..00b537d93d8f8eceaca31cd33d34a0cbffac76cb 100644
--- a/tool/test/tool-test.c
+++ b/tool/test/tool-test.c
@@ -12,24 +12,44 @@ void test_compute_matches_should_remain_BALAI(void) {
 
     // Act
     set_gamemode(MENU_SOLO);
-    init_tool();
 
-    set_answer("BALAI");
+    char *answer = "BALAI";
+    set_answer(answer);
+
+    printf("ANSWER: %s\n\n", answer);
 
     set_try("BRUTE");
     Pattern *pattern = generate_pattern();
     possibility_t **p = compute_matches("BRUTE", pattern);
-    save_computed_matches(p);
 
-    free(pattern);
-    pattern = NULL;
-
-    set_try("SALUT");
-    pattern = generate_pattern();
-    p = compute_matches("SALUT", pattern);
-    save_computed_matches(p);
+    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("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);
@@ -39,5 +59,4 @@ void test_compute_matches_should_remain_BALAI(void) {
     free(target);
 
     destroy_possibilities(p);
-    destroy_tool();
 }
diff --git a/tool/tool.c b/tool/tool.c
index 2a09095f2506e483867b451ea943e249d2a5504e..7a801048869f64a59a33665912d7d65824cf29f6 100644
--- a/tool/tool.c
+++ b/tool/tool.c
@@ -8,21 +8,6 @@ char **remaining_bank;
 int remaining_bank_count;
 possibility_t **possibilities;
 
-/**
- * @brief Create a possibility
- *
- * @param word
- * @param entropy
- * @return
- */
-possibility_t *create_possibility(char *word, double entropy) {
-    possibility_t *p = malloc(sizeof(possibility_t));
-    p->word = calloc(WORD_LENGHT + 1, sizeof(char));
-    strcpy(p->word, word);
-    p->entropy = entropy;
-    return p;
-}
-
 /**
  * @brief Destroiy a given matches set
  *
@@ -56,6 +41,10 @@ matches_t *filter_out_remaining_bank(char *word, Pattern *pattern) {
         char current_word[WORD_LENGHT + 1];
         strcpy(current_word, remaining_bank[j]);
 
+        // Exclude current word
+        if (strcmp(current_word, word) == 0)
+            continue;
+
         bool valid_word = true;
         for (int i = 0; i < WORD_LENGHT; i++) {
             // Filter out the non-valid words
@@ -115,14 +104,12 @@ double compute_entropy(char *word) {
         matches_t *matches = filter_out_remaining_bank(word, (Pattern[WORD_LENGHT]){*curr[0], *curr[1], *curr[2], *curr[3], *curr[4]});
 
         // Skip unmatch pattern
-        if (matches->count == 0) {
-            destroy_matches(matches);
-            break;
+        if (matches->count != 0) {
+            // Apply Shannon's formula
+            double px = ((double)matches->count / (double)remaining_bank_count);
+            sum += px * (log2(1 / px));
         }
 
-        // Apply Shannon's formula
-        double px = ((double)matches->count / (double)remaining_bank_count);
-        sum += px * (log2(1 / px));
         destroy_matches(matches);
 
         // Go to next pattern
@@ -146,6 +133,21 @@ double compute_entropy(char *word) {
     return sum;
 }
 
+/**
+ * @brief Create a possibility
+ *
+ * @param word
+ * @param entropy
+ * @return
+ */
+possibility_t *create_possibility(char *word) {
+    possibility_t *p = malloc(sizeof(possibility_t));
+    p->word = calloc(WORD_LENGHT + 1, sizeof(char));
+    strcpy(p->word, word);
+    p->entropy = compute_entropy(word);
+    return p;
+}
+
 /**
  * @brief Compare two given possibilites
  *
@@ -216,8 +218,9 @@ possibility_t **compute_matches(char *word, Pattern *pattern) {
     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], 0.0); // compute_entropy(matches->words[i])
+        possibilities[i] = create_possibility(matches->words[i]);
 
+    save_computed_matches(possibilities);
     destroy_matches(matches);
 
     // Sort possibilities by entropy ASC
diff --git a/tool/tool.h b/tool/tool.h
index c1894a0b7000566bdbf7d816e809b4660d6afaf2..94a27a4d7be9a4359e9a4b7689947510c869d1e6 100644
--- a/tool/tool.h
+++ b/tool/tool.h
@@ -1,8 +1,8 @@
 #ifndef TOOL_H
 #define TOOL_H
 
+#include "../conf.h"
 #include "../word-bank/bank.h"
-#include "../wordle/wordle.h"
 #include <math.h>
 #include <stdbool.h>
 
diff --git a/ui/ui.c b/ui/ui.c
index 1dbf5ec6f223df4a19ab47770c8fb70a16594bff..5dfc769c1ef5b43947c0ca7cdd9371a65678937c 100644
--- a/ui/ui.c
+++ b/ui/ui.c
@@ -11,6 +11,7 @@
 // Windows
 WINDOW *ui_window = NULL;
 WINDOW *help = NULL;
+WINDOW *tool = NULL;
 
 char main_title[8][64] = {"$$\\      $$\\  $$$$$$\\  $$$$$$$\\  $$$$$$$\\  $$\\       $$$$$$$$\\ ",
                           "$$ | $\\  $$ |$$  __$$\\ $$  __$$\\ $$  __$$\\ $$ |      $$  _____|",
@@ -90,6 +91,17 @@ void hide_help() {
     help = NULL;
 }
 
+/**
+ * @brief Hide the tool subwindow
+ */
+void hide_tool() {
+    wclear(ui_window);
+    delwin(tool);
+    refresh();
+
+    tool = NULL;
+}
+
 //==========================
 //        PUBLIC
 //==========================
@@ -151,6 +163,7 @@ bool init_term() {
 void cleanup_term() {
     curs_set(1);
     nocbreak();
+    delwin(tool);
     delwin(help);
     delwin(ui_window);
     endwin();
@@ -237,7 +250,35 @@ void toggle_help() {
     wrefresh(help);
 }
 
-void show_gameboard(int tries_count, int word_length, char **tries, int **validations, int score) {
+void toggle_tool(int count, char words[count][WORD_LENGHT + 1], double *entropies) {
+    // Delete existing instance of the subwindow
+    if (tool != NULL) {
+        hide_tool();
+        return;
+    }
+
+    // Create new instance of the subwindow
+    tool = subwin(ui_window, LINES - 2, 30, 1, 1);
+    refresh();
+
+    if (tool == NULL) {
+        cleanup_term();
+        exit(EXIT_FAILURE);
+    }
+
+    scrollok(tool, TRUE);
+    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]);
+
+    refresh();
+    wrefresh(tool);
+}
+
+void show_gameboard(int tries_count, int word_length, char **tries, Pattern **patterns, int score) {
     for (int i = 0; i < tries_count; i++) {
         // Draw current try letters
         for (int j = 0; j < word_length; j++) {
@@ -248,9 +289,9 @@ void show_gameboard(int tries_count, int word_length, char **tries, int **valida
             }
 
             // Letters
-            if (validations[i][j] == 1)
+            if (patterns[i][j] == MISPLACED)
                 attron(COLOR_PAIR(ORANGE_PAIR));
-            if (validations[i][j] == 2)
+            if (patterns[i][j] == CORRECT)
                 attron(COLOR_PAIR(GREEN_PAIR));
 
             mvaddch(GAMEBOARD_Y_OFFSET + i - menu_offset_modifer() + 5, TERM_MID_COLS - word_length + (j * 2), tries[i][j]);
diff --git a/ui/ui.h b/ui/ui.h
index 75042339ac83a38733d962f2c1ae4c53b285dc81..6a19096cc3bf81b7f4fe25085ba01367804414ac 100644
--- a/ui/ui.h
+++ b/ui/ui.h
@@ -1,6 +1,7 @@
 #ifndef UI_H_
 #define UI_H_
 
+#include "../conf.h"
 #include <ncurses.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -96,15 +97,24 @@ int show_menu();
  */
 void toggle_help();
 
+/**
+ * @brief Toggle the tool window
+ *
+ * @param count
+ * @param words
+ * @param entropies
+ */
+void toggle_tool(int count, char words[count][WORD_LENGHT + 1], double *entropies);
+
 /**
  * @brief Show the gameboard
  *
  * @param tries_count
  * @param word_length
  * @param tries
- * @param validations
+ * @param patterns
  * @param score
  */
-void show_gameboard(int tries_count, int word_length, char **tries, int **validations, int score);
+void show_gameboard(int tries_count, int word_length, char **tries, Pattern **patterns, int score);
 
 #endif
\ No newline at end of file
diff --git a/wordle/wordle.c b/wordle/wordle.c
index 20992deb13c844ab1abd8c89c6086fc9dedd3a3f..556ba748f9a3b9b9f4a8f5267932079bdef285e8 100644
--- a/wordle/wordle.c
+++ b/wordle/wordle.c
@@ -8,7 +8,8 @@ bool _game_finished = false;
 int score = 0;
 char **tries;
 char *chosen_word;
-int **validations;
+Pattern **patterns;
+possibility_t **remaining_possibilities;
 int current_try_id = 0;
 int current_try_letter_id = 0;
 
@@ -30,7 +31,7 @@ void render_game() {
         break;
     }
 
-    show_gameboard(TRIES_COUNT, WORD_LENGHT, tries, validations, score);
+    show_gameboard(TRIES_COUNT, WORD_LENGHT, tries, patterns, score);
 }
 
 /**
@@ -44,6 +45,23 @@ 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;
@@ -52,10 +70,10 @@ void handle_controls(int key) {
         if (!validate_guess(tries[current_try_id]))
             break;
 
-        // Validations
+        // Patterns
         Pattern *pattern = generate_pattern();
         for (int i = 0; i < WORD_LENGHT; i++)
-            validations[current_try_id][i] = pattern[i];
+            patterns[current_try_id][i] = pattern[i];
         free(pattern);
 
         current_try_id += 1;
@@ -64,10 +82,12 @@ void handle_controls(int key) {
         // Place correct letters from previous in the current one
         if (current_try_id < TRIES_COUNT) {
             for (int i = 0; i < WORD_LENGHT; i++) {
-                if (validations[current_try_id - 1][i] == CORRECT)
+                if (patterns[current_try_id - 1][i] == CORRECT)
                     tries[current_try_id][i] = tries[current_try_id - 1][i];
             }
         }
+
+        remaining_possibilities = compute_matches(tries[current_try_id - 1], patterns[current_try_id - 1]);
         break;
     }
 }
@@ -76,6 +96,8 @@ void handle_controls(int key) {
 //        PUBLIC
 //==========================
 void initialize_game() {
+    init_tool();
+
     // Reset game variables
     _game_finished = false;
     current_try_id = 0;
@@ -86,10 +108,10 @@ void initialize_game() {
     set_answer(get_random_word());
 
     tries = calloc(TRIES_COUNT, sizeof(char *));
-    validations = malloc(sizeof(int *) * TRIES_COUNT);
+    patterns = malloc(sizeof(Pattern *) * TRIES_COUNT);
 
     for (int i = 0; i < TRIES_COUNT; i++) {
-        validations[i] = calloc(WORD_LENGHT + 1, sizeof(int));
+        patterns[i] = calloc(WORD_LENGHT + 1, sizeof(Pattern));
         tries[i] = calloc(WORD_LENGHT + 1, sizeof(char)); // +1 because of \0
     }
 }
@@ -97,16 +119,20 @@ void initialize_game() {
 void terminate_game() { _game_finished = true; }
 
 void destroy_game() {
+    destroy_tool();
+
     for (int i = 0; i < TRIES_COUNT; i++) {
         free(tries[i]);
-        free(validations[i]);
+        free(patterns[i]);
     }
 
     free(tries);
-    free(validations);
+    free(patterns);
 }
 
 void restart_game() {
+    destroy_tool();
+    init_tool();
     score += (TRIES_COUNT - current_try_id) * 10;
     set_answer(get_random_word());
 
@@ -115,7 +141,7 @@ void restart_game() {
 
     for (int i = 0; i < TRIES_COUNT; i++) {
         for (int j = 0; j < WORD_LENGHT; j++) {
-            validations[i][j] = 0;
+            patterns[i][j] = WRONG;
             tries[i][j] = '\0';
         }
     }
@@ -125,7 +151,7 @@ bool lose_condition() { return (current_try_id > TRIES_COUNT - 1); }
 
 bool win_condition() {
     for (int i = 0; i < WORD_LENGHT; i++) {
-        if (validations[current_try_id - (current_try_id > 0 ? 1 : 0)][i] != CORRECT)
+        if (patterns[current_try_id - (current_try_id > 0 ? 1 : 0)][i] != CORRECT)
             return false;
     }
 
@@ -135,7 +161,7 @@ bool win_condition() {
 bool validate_letter(int key) { return (islower(key) || isupper(key)); }
 
 Pattern *generate_pattern() {
-    Pattern *validation = calloc(WORD_LENGHT, sizeof(int));
+    Pattern *pattern = calloc(WORD_LENGHT, sizeof(int));
     char cpy[WORD_LENGHT + 1];
     strcpy(cpy, chosen_word);
 
@@ -144,20 +170,20 @@ Pattern *generate_pattern() {
             continue;
 
         if (tries[current_try_id][i] == chosen_word[i]) {
-            validation[i] = CORRECT;
+            pattern[i] = CORRECT;
             cpy[i] = ' ';
             continue;
         }
 
         char *addr;
         if ((addr = strchr(chosen_word, tries[current_try_id][i])) != NULL) {
-            validation[i] = MISPLACED;
+            pattern[i] = MISPLACED;
             cpy[(int)(addr - chosen_word)] = ' '; // Get the index of the found char and replace with space
             continue;
         }
     }
 
-    return validation;
+    return pattern;
 }
 
 bool validate_guess(char current_try[WORD_LENGHT]) {
diff --git a/wordle/wordle.h b/wordle/wordle.h
index 3c6c0fd99dbad815294bb0fcd72771f265030172..87ba5166767059bd08e6eb0babf60f4bd0a4c131 100644
--- a/wordle/wordle.h
+++ b/wordle/wordle.h
@@ -1,20 +1,14 @@
 #ifndef WORDLE_H_
 #define WORDLE_H_
 
+#include "../conf.h"
+#include "../tool/tool.h"
 #include "../ui/ui.h"
 #include "../word-bank/bank.h"
 #include <ctype.h>
 #include <stdbool.h>
 #include <string.h>
 
-// Game setup
-#define TRIES_COUNT 6
-#define WORD_LENGHT 5
-
-// Enums
-typedef enum Gamemode { SOLO, VERSUS, TOOL_ASSISTED } Gamemode;
-typedef enum Pattern { WRONG, MISPLACED, CORRECT, NAP } Pattern; // NAP => Not A Pattern (Only used when computing all possible patterns)
-
 /**
  * @brief Initialize the game
  */