diff --git a/libs/jogador.c b/libs/jogador.c
index f6824e6cdf0fad15bb3711c2433921e9e89ad3e5..d7880cf32da18a09ff3b7d856ffea2ef4843442e 100644
--- a/libs/jogador.c
+++ b/libs/jogador.c
@@ -8,7 +8,6 @@
 
 Lista Joga(Grafo g, Lista grupo){
     Lista jogadas = constroiLista();
-    //TODO: A Logica toda do jogo vai ficar aqui
     int counter = 1;
     double max = 2*(g->x) + (sqrt(2*g->cores))*(g->x) + g->cores;
     double min = (sqrt(g->cores - 1)*g->x/2) - (g->cores/2);
@@ -17,31 +16,24 @@ Lista Joga(Grafo g, Lista grupo){
         int altura = calculaAltura(g, grupo);
 
         int naoConsumidos = tamanhoLista(g->vertices) - tamanhoLista(grupo);
-        int profundidade = sqrt(max) * (sqrt(altura) / sqrt(min)) * (altura/sqrt(naoConsumidos));
+        int profundidade = (sqrt(max) * (sqrt(altura) / sqrt(min)) * (altura/sqrt(naoConsumidos)));
+        // if(min <= 5) profundidade=altura;
 
-        // Pega os filhos do grupo
         Lista filhos = filhosGrupo(grupo);
-        // Monta a árvore de busca:
-        //      - RAIZ: grupo
-        //      - FILHOS: Cores alcancáveis a partir da raiz
-        //      - NETOS: Cores alcançáveis a partir dos filhos que NÃO são alcançáveis a partir da raiz
-        //          Só é necessário para calcular o bônus de cada filho
+
         // printf("\tJOGADA %d\n", counter);
+        // printf("\t\tProfundidade: %d\n", profundidade);
         Lista coresFilhos = agrupaCores(filhos);
-        // printf("\tAltura da árvore: %d\n", altura);
-        // printf("\tNúmero de grupos: %d\n", tamanhoLista(g->vertices));
-        // printf("\tNúmero de grupos não consumidos: %d\n", tamanhoLista(g->vertices) - tamanhoLista(grupo));
-        // printf("\tTamanho coresFilhos %d\n", tamanhoLista(coresFilhos));
-        // for(No n = primeiroNoLista(coresFilhos); n; n = getSucessorNo(n)) {
-        //     Vertice v = (Vertice) getConteudo(n);
-        //     printf("\t\tVértice - cor: %d, peso: %d, bonus: %d\n", v->cor, v->peso, v->bonus);
+        calculaBonus(coresFilhos, g, profundidade);
+
+        // char prestr[32];
+        // sprintf(prestr, "./prejogada%d.out", counter);
+        // FILE* predebug = fopen(prestr, "w+");
+        // if(predebug) {
+        //     grafoParaDot(g, grupo, predebug);
         // }
-        // Seleciona o melhor filho baseado em peso(filho) + bônus(filho) // (filho com a maior soma de filho e peso)
-        // O bônus é calculado da seguinte forma:
-        //      - Soma o valor de cada neto (que não é alcançável pela raiz)
-        //      - Em caso de empate da soma peso + bônus:
-        //          - Escolher o filho que tem mais netos da mesma cor de um filho
-        // Após escolher um filho, repete o algoritmo até não terem mais filhos fora do grupo
+        // fclose(predebug);
+
 
         Vertice maior = (Vertice) getConteudo(primeiroNoLista(coresFilhos));
         for(No n = primeiroNoLista(coresFilhos); n; n = getSucessorNo(n)) {
@@ -57,7 +49,7 @@ Lista Joga(Grafo g, Lista grupo){
         }
         // printf("\t\tCOR ESCOLHIDA: %d\n", maior->cor);
         insereLista(maior->cor, jogadas);
-        // "Pinta o tablueiro"
+
         for(No n = primeiroNoLista(filhos); n; n = getSucessorNo(n)) {
             Vertice v = (Vertice) getConteudo(n);
             if(v->cor == maior->cor && !v->grupo) {
@@ -66,19 +58,18 @@ Lista Joga(Grafo g, Lista grupo){
             }
         }
 
-        // Limpa as coisas
         destroiLista(filhos, NULL);
         destroiLista(coresFilhos, destroiVertice);
 
         calculaAltura(g, grupo);
         // PARA DEBUG!! Imprime as últimas 10 jogadas em um arquivo
-        char str[32];
-        sprintf(str, "./jogada%d.out", counter );
-        FILE* debug = fopen(str, "w+");
-        if(debug) {
-            grafoParaDot(g, grupo, debug);
-        }
-        fclose(debug);
+        // char str[32];
+        // sprintf(str, "./jogada%d.out", counter );
+        // FILE* debug = fopen(str, "w+");
+        // if(debug) {
+        //     grafoParaDot(g, grupo, debug);
+        // }
+        // fclose(debug);
         ++counter;
     }
 
@@ -137,29 +128,92 @@ Lista agrupaCores(Lista vertices) {
     return agrupa;
 }
 
-// TODO: repensar calculo do bônus
-void calculaBonus(Lista grupo, int profundidade) {
+bool corEstaNaLista(Lista l, int cor) {
+    for(No n = primeiroNoLista(l); n; n = getSucessorNo(n)) {
+        Vertice v = (Vertice) getConteudo(n);
+        if(v->cor == cor) {
+             return true;
+        }
+    }
+    return false;
+}
+
+void calculaBonus(Lista grupo, Grafo g, int profundidade) {
     for(No n = primeiroNoLista(grupo); n; n = getSucessorNo(n)) {
         Vertice v = (Vertice) getConteudo(n);
+        v->bonus = 0;
         for(No m = primeiroNoLista(v->filhos); m; m = getSucessorNo(m)) {
             Vertice filho = (Vertice) getConteudo(m);
-            // Se o filho não está na lista irmaos e não está no grupo de vértices já consumidos
-            if(!filho->grupo && !pertenceLista(filho, grupo) && (filho->altura > v->altura)) {
-                v->bonus += filho->peso + calculaBonusRec(filho, v, profundidade);
+            if((filho->altura > v->altura)) {
+                int bonus = filho->peso + calculaBonusRec(filho, v, g, profundidade);
+                if(corEstaNaLista(grupo, filho->cor)) bonus += 100;
+                v->bonus += bonus;
             }
         }
+        Lista vFilhos = agrupaCores(v->filhos);
+        v->bonus += tamanhoLista(v->filhos) - tamanhoLista(vFilhos);
+        destroiLista(vFilhos, NULL);
+
+        int menorDistancia = v->altura;
+        for(No m = primeiroNoLista(g->vertices); m; m = getSucessorNo(m)) {
+            Vertice w = (Vertice) getConteudo(m);
+            if(w->grupo) continue;
+            if(w == v) continue;
+            if(w->cor == v->cor) {
+                if((w->altura < menorDistancia) || (menorDistancia == v->altura)) menorDistancia = w->altura;
+            }
+        }
+        v->bonus += (menorDistancia - v->altura)^2;
+
+        for(No m = primeiroNoLista(v->pais); m; m = getSucessorNo(m)) {
+            Vertice pai = (Vertice) getConteudo(m);
+            pai->bonus = v->bonus;
+        }
     }
+
+    for(No n = primeiroNoLista(grupo); n; n = getSucessorNo(n)) {
+        Vertice v = (Vertice) getConteudo(n);
+        int somaCor = 0;
+        for(No m = primeiroNoLista(g->vertices); m; m = getSucessorNo(m)) {
+            Vertice w = (Vertice) getConteudo(m);
+            if(!w->grupo && w->cor == v->cor) {
+                somaCor += w->peso;
+            }
+        }
+        // Se a soma de todos os vértices que não pertencem ao grupo consumido
+        //      for igual ao peso do vértice agrupado, esta é a
+        //      última jogada com aquela cor
+        if(v->peso == somaCor) {
+            v->bonus += 100; // Mais bonus para que essa cor seja a escolhida
+        }
+    }
+
     return;
 }
 
-int calculaBonusRec(Vertice v, Vertice pai, int profundidade) {
+int calculaBonusRec(Vertice v, Vertice pai, Grafo g, int profundidade) {
     if(profundidade <= 0) return 0;
     int bonus = 0;
     for(No n = primeiroNoLista(v->filhos); n; n = getSucessorNo(n)) {
         Vertice filho = (Vertice) getConteudo(n);
+        if((filho->altura > v->altura)) {
+            int preBonus = filho->peso + calculaBonusRec(filho, v, g, profundidade-1);
+            // for(No m = primeiroNoLista(g->vertices); m && (profundidade < 10); m = getSucessorNo(m)) {
+            //     Vertice w = (Vertice) getConteudo(m);
+            //     if(w == pai) continue;
+            //     if(!w->grupo) {
+            //         // Se existe alguém um nível acima da mesma cor...
+            //         if((w->altura == (filho->altura - 1)) && (w->cor == filho->cor)) {
+            //             // preBonus += 25;
+            //         }
+            //         // // Se existe alguém dois níves acima com a mesma cor
+            //         // else if((w->altura == (filho->altura - 2)) && (w->cor == filho->cor)) {
+            //         //     preBonus += 15;
+            //         // }
+            //     }
+            // }
 
-        if(!filho->grupo && !pertenceLista(filho, pai->filhos) && (filho->altura > v->altura)) {
-            bonus += filho->peso + calculaBonusRec(filho, v, profundidade-1);
+            bonus += preBonus;
         }
     }
     return v->bonus = bonus;
diff --git a/libs/jogador.h b/libs/jogador.h
index d5698a34d0e87a5a715c3dfc913b0b88c7748f16..272b76203ec5a533d9969b5692942f5b0344f7b9 100644
--- a/libs/jogador.h
+++ b/libs/jogador.h
@@ -15,5 +15,5 @@ Lista filhosGrupo(Lista grupoPai);
 // Retorna uma lista de vértices com as cores e pesos agrupadas a partir de l
 Lista agrupaCores(Lista vertices);
 
-void calculaBonus(Lista grupo, int profundidade);
+void calculaBonus(Lista grupo, Grafo g, int profundidade);
 #endif
diff --git a/libs/vertice.h b/libs/vertice.h
index fb225fb5d1680159d8b9dabeee161378e9420344..56336e98635afe9bd5632306737ab66ef14d754e 100644
--- a/libs/vertice.h
+++ b/libs/vertice.h
@@ -6,7 +6,7 @@
 struct Vertice {
     int cor;
     int peso;
-    int bonus;
+    unsigned long int bonus;
     int altura;
     bool grupo;
     bool visitado;
diff --git a/tests/runTests.sh b/tests/runTests.sh
index ca61958ce5b036d0e33dff06adf88e8ca85ab9ae..bf3fd8481c77670157b028da553e66ee73c7f0a0 100755
--- a/tests/runTests.sh
+++ b/tests/runTests.sh
@@ -48,8 +48,8 @@ do
             ./floodit_h1 < "/tmp/${semente}.in" > /tmp/h1.out
             ./floodit_h2 < "/tmp/${semente}.in" > /tmp/h2.out
             RESP=$(cat /tmp/resp.out | head -n1)
-            H1=$(cat /tmp/h1.out | head -n1)
-            H2=$(cat /tmp/h2.out | head -n1)
+            H1=$(cat /tmp/h1.out | tail -n2 | head -n1)
+            H2=$(cat /tmp/h2.out | tail -n2 | head -n1)
             if [ $RESP -gt $H1 ]; then
                 echo -ne "${RED}Heurística h1 fez tabuleiro ${i} ${i} ${cor} ${semente} em ${H1} e nós em ${RESP}${NC}\n"
                 echo "${i} ${i} ${cor} ${semente} (h1: ${H1})" >> tabuleiros.txt