diff --git a/main.c b/main.c
index 502c22a14def718f5b1b364be32ee66155dac803..0a8049a82395812b8271c6d5dcbeeb984fb79ffb 100644
--- a/main.c
+++ b/main.c
@@ -14,7 +14,7 @@ int main(void) {
 
     while ((menu_choice = show_menu()) != MENU_QUIT) {
         clear();
-        set_gamemode(menu_choice);
+        set_gamemode((Gamemode)menu_choice);
         launch_game();
     };
 
diff --git a/tool/test/tool-test.c b/tool/test/tool-test.c
index 18c1a4e4dcb08f0b6a332399e733985913e25a2d..59152a23c4889552766b2d87af5d202870ad9b20 100644
--- a/tool/test/tool-test.c
+++ b/tool/test/tool-test.c
@@ -6,14 +6,15 @@ void test_compute_matches_should_be_empty(void) {
 
     set_answer("BALAI");
 
-    set_try("BALAE");
-    int *pattern = generate_pattern();
-    possibility_t **p = compute_matches("BALAE", pattern);
+    set_try("BRUTE");
+    Pattern *pattern = generate_pattern();
+    possibility_t **p = compute_matches("BRUTE", pattern);
 
-    printf("%d\n", get_remaning_bank_count());
-    //    for (int i = 0; i < get_remaning_bank_count(); i++)
-    //        printf("%s\n", p[i]->word);
+    printf("%d\n", get_remaining_bank_count());
+    for (int i = 0; i < get_remaining_bank_count(); i++)
+        printf("%s\n", p[i]->word);
 
     free(pattern);
     destroy_possibilities(p);
+    destroy_tool();
 }
diff --git a/tool/tool.c b/tool/tool.c
index b120d8b623d59be113b75d6dfe948293c6bf2b47..8ebacd478da9f1f5de57723735b781eff62784ac 100644
--- a/tool/tool.c
+++ b/tool/tool.c
@@ -4,14 +4,14 @@
 //        PRIVATE
 //==========================
 int possibility_count = 0;
-char **remaning_bank;
-int remaning_bank_count;
+char **remaining_bank;
+int remaining_bank_count;
 possibility_t **possibilities;
 
-possibility_t *create_possibility(char *word, double probability) {
+possibility_t *create_possibility(char *word, double entropy) {
     possibility_t *p = malloc(sizeof(possibility_t));
     p->word = word;
-    p->probability = probability;
+    p->entropy = entropy;
     return p;
 }
 
@@ -19,8 +19,20 @@ possibility_t *create_possibility(char *word, double probability) {
 //        PUBLIC
 //==========================
 void init_tool() {
-    remaning_bank = get_bank();
-    remaning_bank_count = get_bank_size();
+    remaining_bank_count = get_bank_size();
+    remaining_bank = malloc(remaining_bank_count * sizeof(char *));
+
+    char **tmp = get_bank();
+    for (int i = 0; i < remaining_bank_count; i++) {
+        remaining_bank[i] = malloc((WORD_LENGHT + 1) * sizeof(char));
+        strcpy(remaining_bank[i], tmp[i]);
+    }
+}
+
+void destroy_tool() {
+    for (int i = 0; i < remaining_bank_count; i++)
+        free(remaining_bank[i]);
+    free(remaining_bank);
 }
 
 void destroy_possibilities(possibility_t **p) {
@@ -29,38 +41,55 @@ void destroy_possibilities(possibility_t **p) {
     free(p);
 }
 
-possibility_t **compute_matches(char *word, int *pattern) {
+possibility_t **compute_matches(char *word, Pattern *pattern) {
     possibility_count = 0;
-    char tmp_poss[remaning_bank_count][WORD_LENGHT + 1];
+    char tmp_poss[remaining_bank_count][WORD_LENGHT + 1];
 
-    for (int i = 0; i < remaning_bank_count; i++)
+    for (int i = 0; i < remaining_bank_count; i++)
         *tmp_poss[i] = *"\0";
 
-    char **tmp_bank = remaning_bank;
-    for (int j = 0; j < remaning_bank_count; j++) {
-        int valid_word = 0;
+    for (int j = 0; j < remaining_bank_count; j++) {
+        char current_word[WORD_LENGHT + 1];
+        strcpy(current_word, remaining_bank[j]);
 
+        bool valid_word = true;
         for (int i = 0; i < WORD_LENGHT; i++) {
-            if (pattern[i] == LETTER_NOT_PRESENT)
-                continue;
-
-            char tmp_c[2] = {word[i], '\0'};
-
-            if (pattern[i] == LETTER_PLACED) {
-                if (strcspn(tmp_bank[j], tmp_c) == i) {
-                    printf("%ld\t%c\t%s\t%s\n", strcspn(tmp_bank[j], tmp_c), word[i], tmp_bank[j], word);
-                    strcpy(tmp_poss[j], tmp_bank[j]);
-                    possibility_count++;
-                    continue;
-                }
-            }
+            // Forced to create a string of only 1 char to get his position in the word
+            char current_char[2] = {word[i], '\0'};
+
+            // Filter out the non-valid words
+            if ((pattern[i] == WRONG && (int)strcspn(current_word, current_char) != WORD_LENGHT) ||
+                (pattern[i] == MISPLACED && (int)strcspn(current_word, current_char) == WORD_LENGHT) ||
+                (pattern[i] == CORRECT && (int)strcspn(current_word, current_char) != i))
+                valid_word = false;
+
+            // Clear the current char to not impact futur letter checks
+            current_word[i] = ' ';
         }
+
+        if (!valid_word)
+            continue;
+
+        strcpy(tmp_poss[j], remaining_bank[j]);
+        possibility_count++;
     }
 
-    possibilities = calloc(possibility_count, sizeof(possibility_t *));
+    // Free non-matching words
+    for (int i = possibility_count; i < remaining_bank_count; i++)
+        free(remaining_bank[i]);
+
+    int previous_remaining_count = remaining_bank_count;
+
+    // Realloc for the new matching words
+    remaining_bank_count = possibility_count;
+    remaining_bank = realloc(remaining_bank, remaining_bank_count * sizeof(char *));
+
+    // Create the new possibilities list
+    possibilities = calloc(remaining_bank_count, sizeof(possibility_t *));
     int idx = 0;
-    for (int i = 0; i < remaning_bank_count; i++) {
+    for (int i = 0; i < previous_remaining_count; i++) {
         if (strlen(tmp_poss[i]) != 0) {
+            strcpy(remaining_bank[idx], tmp_poss[i]);
             possibilities[idx] = create_possibility(tmp_poss[i], 0.0);
             idx++;
         }
@@ -69,9 +98,9 @@ possibility_t **compute_matches(char *word, int *pattern) {
     return possibilities;
 }
 
-int get_remaning_bank_count() { return remaning_bank_count; }
+int get_remaining_bank_count() { return remaining_bank_count; }
 
-char **agregate_possibilities(char *word, int *pattern) {
+char **aggregate_possibilities(char *word, Pattern *pattern) {
     char **words = malloc(sizeof(char *) * POSSIBILITY_SET);
     possibility_t **matches = compute_matches(word, pattern);
 
diff --git a/tool/tool.h b/tool/tool.h
index 8ea019c7e3c001253f71d023a93de25cfd46a9a2..b7b855df1e3f0067ce39d45319c28b689ccd1a4b 100644
--- a/tool/tool.h
+++ b/tool/tool.h
@@ -3,13 +3,14 @@
 
 #include "../word-bank/bank.h"
 #include "../wordle/wordle.h"
+#include <stdbool.h>
 
 // Tool maximum possibility set
 #define POSSIBILITY_SET 10
 
 typedef struct _possibility_t {
     char *word;
-    double probability;
+    double entropy;
 } possibility_t;
 
 /**
@@ -17,6 +18,11 @@ typedef struct _possibility_t {
  */
 void init_tool();
 
+/**
+ * @brief Destroy the tool
+ */
+void destroy_tool();
+
 /**
  * @brief Destroy possibilities
  * @param p
@@ -30,14 +36,14 @@ void destroy_possibilities(possibility_t **p);
  * @param pattern
  * @return
  */
-possibility_t **compute_matches(char *word, int *pattern);
+possibility_t **compute_matches(char *word, Pattern *pattern);
 
 /**
  * @brief Get the remaning bank count
  *
  * @return
  */
-int get_remaning_bank_count();
+int get_remaining_bank_count();
 
 /**
  * @brief Agregate a defined set of possibile words from a given pattern
@@ -46,6 +52,6 @@ int get_remaning_bank_count();
  * @param pattern
  * @return
  */
-char **agregate_possibilities(char *word, int *pattern);
+char **agregate_possibilities(char *word, Pattern *pattern);
 
 #endif
diff --git a/wordle/test/wordle-test.c b/wordle/test/wordle-test.c
index 8d372f2c95f21aa695c3171be9bb9db3fca8d267..489a6be21b827b5e0fccb6abc1795adf82f3b2d3 100644
--- a/wordle/test/wordle-test.c
+++ b/wordle/test/wordle-test.c
@@ -49,13 +49,13 @@ void test_validate_letter_should_be_true(void) {
 }
 
 void test_generate_pattern_should_return_all_0(void) {
-    int target[WORD_LENGHT] = {0, 0, 0, 0, 0};
+    Pattern target[WORD_LENGHT] = {WRONG, WRONG, WRONG, WRONG, WRONG};
     set_gamemode(MENU_SOLO);
 
     set_answer("BALAI");
     set_try("PONTS");
 
-    int *pattern = generate_pattern();
+    Pattern *pattern = generate_pattern();
 
     TEST_ASSERT_EQUAL_INT_ARRAY(target, pattern, WORD_LENGHT);
 
diff --git a/wordle/wordle.c b/wordle/wordle.c
index 9da722e81dd5f584488639fab0120f2deae9c119..20992deb13c844ab1abd8c89c6086fc9dedd3a3f 100644
--- a/wordle/wordle.c
+++ b/wordle/wordle.c
@@ -3,7 +3,7 @@
 //==========================
 //        PRIVATE
 //==========================
-int gamemode = -1;
+Gamemode mode;
 bool _game_finished = false;
 int score = 0;
 char **tries;
@@ -16,16 +16,16 @@ int current_try_letter_id = 0;
  * @brief Render the game for the selected gamemode
  */
 void render_game() {
-    switch (gamemode) {
-    case GAMEMODE_SOLO:
+    switch (mode) {
+    case SOLO:
         draw_title(SOLO_TITLE_ID);
         break;
 
-    case GAMEMODE_1_V_1:
+    case VERSUS:
         draw_title(ONE_V_ONE_TITLE_ID);
         break;
 
-    case GAMEMODE_COMPUTER:
+    case TOOL_ASSISTED:
         draw_title(COMPUTER_TITLE_ID);
         break;
     }
@@ -53,7 +53,7 @@ void handle_controls(int key) {
             break;
 
         // Validations
-        int *pattern = generate_pattern();
+        Pattern *pattern = generate_pattern();
         for (int i = 0; i < WORD_LENGHT; i++)
             validations[current_try_id][i] = pattern[i];
         free(pattern);
@@ -64,7 +64,7 @@ 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] == LETTER_PLACED)
+                if (validations[current_try_id - 1][i] == CORRECT)
                     tries[current_try_id][i] = tries[current_try_id - 1][i];
             }
         }
@@ -125,7 +125,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] != LETTER_PLACED)
+        if (validations[current_try_id - (current_try_id > 0 ? 1 : 0)][i] != CORRECT)
             return false;
     }
 
@@ -134,8 +134,8 @@ bool win_condition() {
 
 bool validate_letter(int key) { return (islower(key) || isupper(key)); }
 
-int *generate_pattern() {
-    int *validation = calloc(WORD_LENGHT, sizeof(int));
+Pattern *generate_pattern() {
+    Pattern *validation = calloc(WORD_LENGHT, sizeof(int));
     char cpy[WORD_LENGHT + 1];
     strcpy(cpy, chosen_word);
 
@@ -144,14 +144,14 @@ int *generate_pattern() {
             continue;
 
         if (tries[current_try_id][i] == chosen_word[i]) {
-            validation[i] = LETTER_PLACED;
+            validation[i] = CORRECT;
             cpy[i] = ' ';
             continue;
         }
 
         char *addr;
         if ((addr = strchr(chosen_word, tries[current_try_id][i])) != NULL) {
-            validation[i] = LETTER_WRONG_PLACE;
+            validation[i] = MISPLACED;
             cpy[(int)(addr - chosen_word)] = ' '; // Get the index of the found char and replace with space
             continue;
         }
@@ -183,13 +183,13 @@ bool validate_guess(char current_try[WORD_LENGHT]) {
     return true;
 }
 
-void set_gamemode(int menu_gamemode) { gamemode = menu_gamemode; }
+void set_gamemode(Gamemode menu_gamemode) { mode = menu_gamemode; }
 
 void set_answer(char answer[WORD_LENGHT]) { chosen_word = answer; }
 
 void set_try(char current_try[WORD_LENGHT]) { strcpy(tries[current_try_id], current_try); }
 
-int get_gamemode() { return gamemode; }
+Gamemode get_gamemode() { return mode; }
 
 char *get_answer() { return chosen_word; }
 
diff --git a/wordle/wordle.h b/wordle/wordle.h
index 9f86eda80b22d2f45c3e5568478519b2c56f4ea8..0c1f3a8ab0b5c6387e23bed2cd77a88cc41dad52 100644
--- a/wordle/wordle.h
+++ b/wordle/wordle.h
@@ -7,19 +7,13 @@
 #include <stdbool.h>
 #include <string.h>
 
-// Gamemodes
-#define GAMEMODE_SOLO 0
-#define GAMEMODE_1_V_1 1
-#define GAMEMODE_COMPUTER 2
-
 // Game setup
 #define TRIES_COUNT 6
 #define WORD_LENGHT 5
 
-// Try validation values
-#define LETTER_PLACED 2
-#define LETTER_WRONG_PLACE 1
-#define LETTER_NOT_PRESENT 0
+// Enums
+typedef enum Gamemode { SOLO, VERSUS, TOOL_ASSISTED } Gamemode;
+typedef enum Pattern { WRONG, MISPLACED, CORRECT } Pattern;
 
 /**
  * @brief Initialize the game
@@ -71,7 +65,7 @@ bool validate_letter(int key);
 /**
  * @brief Control the placement of each letter
  */
-int *generate_pattern();
+Pattern *generate_pattern();
 
 /**
  * @brief Is a try valid
@@ -87,7 +81,7 @@ bool validate_guess(char current_try[WORD_LENGHT]);
  *
  * @param menu_gamemode
  */
-void set_gamemode(int menu_gamemode);
+void set_gamemode(Gamemode menu_gamemode);
 
 /**
  * @brief Set the answer
@@ -108,9 +102,9 @@ void set_try(char current_try[WORD_LENGHT]);
 /**
  * @brief Get the gamemode
  *
- * @return int
+ * @return Gamemode
  */
-int get_gamemode();
+Gamemode get_gamemode();
 
 /**
  * @brief Get the answer