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