diff --git a/libs/jogador.c b/libs/jogador.c index 00d83b3439f12b7bf9bebcede1298958f7ad9786..33ab0538313d2432e7de0bb6fb28a302b8149ad7 100644 --- a/libs/jogador.c +++ b/libs/jogador.c @@ -10,8 +10,19 @@ 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); while(tamanhoLista(grupo) < tamanhoLista(g->vertices)) { + // Calcula a altura int altura = calculaAltura(g, grupo); + + int naoConsumidos = tamanhoLista(g->vertices) - tamanhoLista(grupo); + int profundidade = 32; + if(altura > 10) { + profundidade = sqrt(max) * (sqrt(altura) / sqrt(min)) * (altura/sqrt(naoConsumidos)); + if (profundidade <= 0) profundidade = 1; + } + // Pega os filhos do grupo Lista filhos = filhosGrupo(grupo); // Monta a árvore de busca: @@ -20,7 +31,7 @@ Lista Joga(Grafo g, Lista grupo){ // - 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); - Lista coresFilhos = agrupaCores(filhos, g, altura, tamanhoLista(g->vertices) - tamanhoLista(grupo)); + Lista coresFilhos = agrupaCores(filhos, g, profundidade); // 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)); @@ -45,6 +56,18 @@ Lista Joga(Grafo g, Lista grupo){ } else if((v->bonus) == (maior->bonus)) { if(v->peso > maior->peso) { maior = v; + } else if(v->peso == maior->peso) { + int maiorFilhoM = 0; + int maiorFilhoV = 0; + for(No m = primeiroNoLista(maior->filhos); m; m = getSucessorNo(m)) { + Vertice w = (Vertice) getConteudo(m); + if(w->altura > maiorFilhoM) maiorFilhoM = w->altura; + } + for(No m = primeiroNoLista(v->filhos); m; m = getSucessorNo(m)) { + Vertice w = (Vertice) getConteudo(m); + if(w->altura > maiorFilhoV) maiorFilhoV = w->altura; + } + if(maiorFilhoV > maiorFilhoM) maior = v; } } } @@ -65,13 +88,13 @@ Lista Joga(Grafo g, Lista grupo){ 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; } @@ -92,55 +115,61 @@ Lista filhosGrupo(Lista grupoPai) { return filhos; } -// TODO: primeiro agrupa, DEPOIS calcula os bônus!!! -// Para calcular o bônus, agrupa os filhos de um grupo e aà calcula o bônus -// Ou seja, 2 ou mais vértices da MESMA COR que tenham o mesmo filho (repetição) -// só contarão UMA VEZ o bônus+peso daquele filho -Lista agrupaCores(Lista filhos, Grafo g, int altura, int naoConsumidos) { +Lista agrupaCores(Lista vertices, Grafo g, int profundidade) { + if(profundidade < 0 ) return NULL; Lista agrupa = constroiLista(); - 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); - int profundidade = sqrt(max) * (sqrt(altura) / sqrt(min)) * (altura/sqrt(naoConsumidos)); - // printf("\t\tProfundidade: %d\n", profundidade); - // printf("\t\tRazão: %f\n", (altura/sqrt(naoConsumidos))); - for(No n = primeiroNoLista(filhos); n; n = getSucessorNo(n)) { + for(No n = primeiroNoLista(vertices); n; n = getSucessorNo(n)) { Vertice v = (Vertice) getConteudo(n); - // Verifica se a cor já está na lista - bool estaNaLista = false; - for(No m = primeiroNoLista(agrupa); m; m = getSucessorNo(m)) { + // Verifica se a cor já está agrupada + bool estaAgrupado = false; + for(No m = primeiroNoLista(agrupa); m && !estaAgrupado; m = getSucessorNo(m)) { Vertice w = (Vertice) getConteudo(m); // Se está, soma o peso do vértice if(w->cor == v->cor) { w->peso += v->peso; - w->bonus += calculaBonus(v, filhos, profundidade); - estaNaLista = true; + insereUnicoLista(v, w->pais); + for(No o = primeiroNoLista(v->filhos); o; o = getSucessorNo(o)) { + Vertice x = (Vertice) getConteudo(o); + if(x->altura > v->altura) insereUnicoLista(x, w->filhos); + } + estaAgrupado = true; } } - // Se não está, cria um vértice para a cor - if(!estaNaLista) { + + // Se não está agrupado... + if(!estaAgrupado) { Vertice w = criaVertice(); w->cor = v->cor; w->peso = v->peso; - w->bonus = calculaBonus(v, filhos, profundidade); + w->altura = v->altura; + insereUnicoLista(v, w->pais); + for(No m = primeiroNoLista(v->filhos); m; m = getSucessorNo(m)) { + Vertice x = (Vertice) getConteudo(m); + if(x->altura > v->altura) insereUnicoLista(x, w->filhos); + } insereLista(w, agrupa); } } - // Depois de agrupar, verifica se alguma cor vai chegar ao fim nesta jogada + // Depos do laço anterior, temos uma lista de vértices agrupados + // Então, agrupamos os filhos e calculamos os bônus for(No n = primeiroNoLista(agrupa); n; n = getSucessorNo(n)) { Vertice v = (Vertice) getConteudo(n); - int somaCor = 0; - for(No m = primeiroNoLista(g->vertices); m; m = getSucessorNo(m)) { + Lista filhosAgrupa = agrupaCores(v->filhos, g, profundidade-1); + for(No m = primeiroNoLista(filhosAgrupa); m; m = getSucessorNo(m)) { Vertice w = (Vertice) getConteudo(m); - if(!w->grupo && w->cor == v->cor) { - somaCor += w->peso; + // TODO: verificar se W não é sobrinho de V + // para não dar o bônus duas vezes + if(!w->grupo && (w->altura > v->altura) && !w->visitado){ + v->bonus += w->peso + w->bonus; + w->visitado = true; } } - // Se a soma de todos os vértices que não pertencem ao grupo 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 + for(No m = primeiroNoLista(v->pais); m; m = getSucessorNo(m)) { + Vertice w = (Vertice) getConteudo(m); + w->bonus = v->bonus; } + destroiLista(filhosAgrupa, NULL); } return agrupa; diff --git a/libs/jogador.h b/libs/jogador.h index 5ec0b205bb2df6601906a6cbf42f2f9f98fab00b..e3c83184d12dfb12bdad3bb45e6accc196016fa9 100644 --- a/libs/jogador.h +++ b/libs/jogador.h @@ -13,7 +13,7 @@ Lista Joga(Grafo g, Lista grupo); Lista filhosGrupo(Lista grupoPai); // Retorna uma lista de vértices com as cores e pesos agrupadas a partir de l -Lista agrupaCores(Lista filhos, Grafo g, int altura, int naoConsumidos); +Lista agrupaCores(Lista vertices, Grafo g, int profundidade); int calculaBonus(Vertice v, Lista irmaos, int profundidade); #endif diff --git a/libs/lista.c b/libs/lista.c index 9178c23940ea2789675097c236e1df9d00c7c532..4a3eebb780b331b93726dcb58a8efd76e3f7bfc4 100644 --- a/libs/lista.c +++ b/libs/lista.c @@ -20,7 +20,13 @@ unsigned int tamanhoLista(Lista l) { return l->tamanho; } // devolve o primeiro nó da Lista l, // ou NULL, se l é vazia -No primeiroNoLista(Lista l) { return l->primeiro; } +No primeiroNoLista(Lista l) { + if(!l) return NULL; + if(l->tamanho == 0) { + return NULL; + } + return l->primeiro; +} //--------------------------------------------------------------------------- // cria uma Lista vazia e a devolve diff --git a/libs/vertice.c b/libs/vertice.c index 2dd459044f81ae554a843ee91254e31e48493383..28dc7c06b873a4ae91a5cea49d16b01acc690449 100644 --- a/libs/vertice.c +++ b/libs/vertice.c @@ -11,6 +11,7 @@ Vertice criaVertice() { v->bonus = 0; v->altura = -1; v->grupo = false; + v->visitado = false; v->pais = constroiLista(); v->filhos = constroiLista(); return v; diff --git a/libs/vertice.h b/libs/vertice.h index c740ffc9d38be94c3d019445db9baa06bf2e1774..fb225fb5d1680159d8b9dabeee161378e9420344 100644 --- a/libs/vertice.h +++ b/libs/vertice.h @@ -9,6 +9,7 @@ struct Vertice { int bonus; int altura; bool grupo; + bool visitado; Lista pais; Lista filhos; };