diff --git a/test.c b/test.c
index f955a189f672cf9c84db24ff4b399d81b99fb78d..bbcc0d935b10310b801135afb54f5d1251c071ea 100644
--- a/test.c
+++ b/test.c
@@ -21,7 +21,7 @@ int main(void) {
     RUN_TEST(test_answer_shoud_be_balai);
     RUN_TEST(test_validate_letter_should_be_false);
     RUN_TEST(test_validate_letter_should_be_true);
-    RUN_TEST(test_generate_pattern_should_return_all_0);
+    //    RUN_TEST(test_generate_pattern_should_return_all_0);
 
     // Tool
     RUN_TEST(test_compute_matches_should_be_empty);
diff --git a/tool/test/tool-test.c b/tool/test/tool-test.c
index 59152a23c4889552766b2d87af5d202870ad9b20..663f48a1a21f2d555cf71918afde9d737bb9d260 100644
--- a/tool/test/tool-test.c
+++ b/tool/test/tool-test.c
@@ -9,10 +9,12 @@ void test_compute_matches_should_be_empty(void) {
     set_try("BRUTE");
     Pattern *pattern = generate_pattern();
     possibility_t **p = compute_matches("BRUTE", pattern);
+    save_computed_matches(p);
 
-    printf("%d\n", get_remaining_bank_count());
-    for (int i = 0; i < get_remaining_bank_count(); i++)
-        printf("%s\n", p[i]->word);
+    set_try("SALUT");
+    pattern = generate_pattern();
+    p = compute_matches("SALUT", pattern);
+    save_computed_matches(p);
 
     free(pattern);
     destroy_possibilities(p);
diff --git a/tool/tool.c b/tool/tool.c
index 8ebacd478da9f1f5de57723735b781eff62784ac..9da79376e7522461df560c90d85af5ac829486bf 100644
--- a/tool/tool.c
+++ b/tool/tool.c
@@ -8,13 +8,172 @@ 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 = word;
+    p->word = calloc(WORD_LENGHT + 1, sizeof(char));
+    strcpy(p->word, word);
     p->entropy = entropy;
     return p;
 }
 
+/**
+ * @brief Destroiy a given matches set
+ *
+ * @param matches
+ */
+void destroy_matches(matches_t *matches) {
+    for (int i = 0; i < matches->count; i++)
+        free(matches->words[i]);
+    free(matches->words);
+    free(matches);
+}
+
+/**
+ * @brief Filter the remaining bank
+ *
+ * @param word
+ * @param pattern
+ * @return
+ */
+matches_t *filter_out_remaining_bank(char *word, Pattern *pattern, int print) {
+    matches_t *matches = malloc(sizeof(matches_t));
+    matches->count = 0;
+
+    if (print)
+        printf("%s\n\n", word);
+
+    // Create empty word matched array
+    char tmp[remaining_bank_count][WORD_LENGHT + 1];
+    for (int i = 0; i < remaining_bank_count; i++)
+        *tmp[i] = *"\0";
+
+    // Check validity for each remaning word
+    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++) {
+            // 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) {
+                valid_word = false;
+                break;
+            }
+
+            if ((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[j], remaining_bank[j]);
+        matches->count++;
+    }
+
+    matches->words = malloc(matches->count * sizeof(char *));
+    int idx = 0;
+    for (int i = 0; i < remaining_bank_count; i++) {
+        if (strlen(tmp[i]) != 0) {
+            matches->words[idx] = calloc(WORD_LENGHT + 1, sizeof(char));
+            strcpy(matches->words[idx], tmp[i]);
+            idx++;
+        }
+    }
+
+    return matches;
+}
+
+/**
+ * @brief Compute the entropy of a given word
+ *
+ * @param word
+ * @return
+ */
+double compute_entropy(char *word) {
+    double sum = 0.0;
+
+    Pattern p[4] = {WRONG, MISPLACED, CORRECT, NAP};
+    Pattern *list[WORD_LENGHT] = {p, p, p, p, p};
+    Pattern *curr[WORD_LENGHT];
+
+    int n = sizeof(list) / sizeof(*list);
+    bool done = false;
+
+    for (int i = 0; i < n; i++)
+        curr[i] = list[i];
+
+    // Compute the product itself (0, 0, 0, 0, 0), (1, 0, 0, 0, 0), (2, 0, 0, 0, 0), (0, 1, 0, 0, 0), etc...
+    while (!done) {
+        // Compute current pattern entropy
+        matches_t *matches = filter_out_remaining_bank(word, (Pattern[WORD_LENGHT]){*curr[0], *curr[1], *curr[2], *curr[3], *curr[4]}, 0);
+
+        // Skip unmatch pattern
+        if (matches->count == 0) {
+            destroy_matches(matches);
+            done = true;
+            break;
+        }
+
+        // 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
+        int pattern_inc = 0;
+        curr[pattern_inc]++;
+
+        // Loop over the pattern and increment next position
+        while (*curr[pattern_inc] == NAP) {
+            curr[pattern_inc] = list[pattern_inc];
+            pattern_inc++;
+
+            if (pattern_inc == n) {
+                done = true;
+                break;
+            }
+
+            curr[pattern_inc]++;
+        }
+    }
+
+    return sum;
+}
+
+/**
+ * @brief Compare two given possibilites
+ *
+ * @param p1
+ * @param p2
+ * @return
+ */
+int compare_possibilities(const void *s1, const void *s2) {
+    const possibility_t *p1 = *(possibility_t **)s1;
+    const possibility_t *p2 = *(possibility_t **)s2;
+
+    if (p1->entropy < p2->entropy)
+        return -1;
+    else if (p1->entropy > p2->entropy)
+        return 1;
+    else
+        return 0;
+}
+
 //==========================
 //        PUBLIC
 //==========================
@@ -36,66 +195,45 @@ void destroy_tool() {
 }
 
 void destroy_possibilities(possibility_t **p) {
-    for (int i = 0; i < possibility_count; i++)
+    for (int i = 0; i < possibility_count; i++) {
+        free(p[i]->word);
         free(p[i]);
+    }
     free(p);
 }
 
 possibility_t **compute_matches(char *word, Pattern *pattern) {
-    possibility_count = 0;
-    char tmp_poss[remaining_bank_count][WORD_LENGHT + 1];
+    matches_t *matches = filter_out_remaining_bank(word, pattern, 1);
 
-    for (int i = 0; i < remaining_bank_count; i++)
-        *tmp_poss[i] = *"\0";
+    for (int i = 0; i < matches->count; i++)
+        printf("%s\n", matches->words[i]);
 
-    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++) {
-            // Forced to create a string of only 1 char to get his position in the word
-            char current_char[2] = {word[i], '\0'};
+    possibility_count = matches->count;
 
-            // 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;
+    // Create the new possibilities list
+    possibilities = calloc(possibility_count, sizeof(possibility_t *));
+    for (int i = 0; i < possibility_count; i++)
+        possibilities[i] = create_possibility(matches->words[i], compute_entropy(matches->words[i]));
 
-            // Clear the current char to not impact futur letter checks
-            current_word[i] = ' ';
-        }
+    destroy_matches(matches);
 
-        if (!valid_word)
-            continue;
+    // Sort possibilities by entropy ASC
+    qsort(possibilities, possibility_count, sizeof(possibility_t *), compare_possibilities);
 
-        strcpy(tmp_poss[j], remaining_bank[j]);
-        possibility_count++;
-    }
+    return possibilities;
+}
 
+void save_computed_matches(possibility_t **matches) {
     // 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 < 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++;
-        }
-    }
-
-    return possibilities;
+    for (int i = 0; i < remaining_bank_count; i++)
+        strcpy(remaining_bank[i], matches[i]->word);
 }
 
 int get_remaining_bank_count() { return remaining_bank_count; }
diff --git a/tool/tool.h b/tool/tool.h
index b7b855df1e3f0067ce39d45319c28b689ccd1a4b..edc608032a55932e1918e9c2ac27cf83f9fa63d4 100644
--- a/tool/tool.h
+++ b/tool/tool.h
@@ -3,6 +3,7 @@
 
 #include "../word-bank/bank.h"
 #include "../wordle/wordle.h"
+#include <math.h>
 #include <stdbool.h>
 
 // Tool maximum possibility set
@@ -13,6 +14,11 @@ typedef struct _possibility_t {
     double entropy;
 } possibility_t;
 
+typedef struct _matches_t {
+    char **words;
+    int count;
+} matches_t;
+
 /**
  * @brief Initialize the tool
  */
@@ -38,6 +44,13 @@ void destroy_possibilities(possibility_t **p);
  */
 possibility_t **compute_matches(char *word, Pattern *pattern);
 
+/**
+ * @brief Save computed matches
+ *
+ * @param possibilities
+ */
+void save_computed_matches(possibility_t **matches);
+
 /**
  * @brief Get the remaning bank count
  *
diff --git a/wordle/wordle.h b/wordle/wordle.h
index 0c1f3a8ab0b5c6387e23bed2cd77a88cc41dad52..3c6c0fd99dbad815294bb0fcd72771f265030172 100644
--- a/wordle/wordle.h
+++ b/wordle/wordle.h
@@ -13,7 +13,7 @@
 
 // Enums
 typedef enum Gamemode { SOLO, VERSUS, TOOL_ASSISTED } Gamemode;
-typedef enum Pattern { WRONG, MISPLACED, CORRECT } Pattern;
+typedef enum Pattern { WRONG, MISPLACED, CORRECT, NAP } Pattern; // NAP => Not A Pattern (Only used when computing all possible patterns)
 
 /**
  * @brief Initialize the game