diff --git a/Makefile b/Makefile index 028fc912e70eacaf98ffec46d54a6b4bc2b03866..55f097af98a9ef8e877bf788c1c02ddde70826a1 100644 --- a/Makefile +++ b/Makefile @@ -10,9 +10,10 @@ test: main chmod +x runTests.sh; \ ./runTests.sh -main: main.c libs/jogador.o libs/tabuleiro.o libs/filha.o +main: main.c libs/tabuleiro.o libs/grafo.o libs/vertice.o libs/filha.o libs/lista.o libs/no.o $(CC) $(CFLAGS) -o $@ $^ clean: $(RM) *.o + $(RM) libs/*.o $(RM) tests/*.in diff --git a/libs/filha.c b/libs/filha.c index 8cefe87f591c833a4527c0624fce4dcc6a66d2a8..841081d1646162662f6adda58d0c8edbf2f54ff2 100644 --- a/libs/filha.c +++ b/libs/filha.c @@ -1,11 +1,7 @@ -#include "filha.h" #include <stdbool.h> #include <stdlib.h> - -struct No { - void *conteudo; - No anterior, proximo; -}; +#include "filha.h" +#include "no.h" struct Filha { unsigned int tamanho; @@ -24,58 +20,46 @@ unsigned int tamanhoFilha(Filha f) { return f->tamanho; } -No primeiroNo(Filha f) { +No primeiroNoFilha(Filha f) { if(f->tamanho == 0) { return NULL; } No n = f->primeiro; - f->primeiro = f->primeiro->proximo; - n->anterior = NULL; - n->proximo = NULL; + f->primeiro = getSucessorNo(f->primeiro); + setSucessorNo(n, NULL); + setAntecessorNo(n, NULL); return n; } -No ultimoNo(Filha f) { +No ultimoNoFilha(Filha f) { if(f->tamanho == 0) { return NULL; } No n = f->ultimo; - f->ultimo = f->ultimo->anterior; - n->anterior = NULL; - n->proximo = NULL; + f->ultimo = getAntecessorNo(f->ultimo); + setSucessorNo(n, NULL); + setAntecessorNo(n, NULL); return n; } -No sucessorNo(No n) { - return n->proximo; -} - -No antecessorNo(No n) { - return n->anterior; -} - -void *conteudo(No n) { - return n->conteudo; -} - -No insere(void *conteudo, Filha f) { - No novo = malloc(sizeof(struct No)); +No insereFilha(void *conteudo, Filha f) { + No novo = criaNo(); if(!novo) return NULL; - novo->conteudo = conteudo; - novo->anterior = f->ultimo; + setConteudo(novo, conteudo); + setAntecessorNo(novo, f->ultimo); ++f->tamanho; return f->ultimo = novo; } -bool destroi(Filha f, bool destroi(void *)) { +bool destroiFilha(Filha f, bool destroi(void *)) { No n; bool ok=true; - while( (n = primeiroNo(f)) ) { + while( (n = primeiroNoFilha(f)) ) { if(destroi) - ok &= destroi(conteudo(n)); + ok &= destroi(getConteudo(n)); free(n); } free(f); diff --git a/libs/filha.h b/libs/filha.h index f011de42bfdf16acaefb481ec2e139e18f4421d1..b4831a5dcb22075290c508919dfac50b1d98d59e 100644 --- a/libs/filha.h +++ b/libs/filha.h @@ -1,6 +1,7 @@ #ifndef _FILHA_ #define _FILHA_ #include <stdbool.h> +#include "no.h" // Filha é uma estrutura que pode ser vista como Fila ou Pilha typedef struct Filha *Filha; @@ -16,24 +17,15 @@ Filha constroiFilha(); unsigned int tamanhoFilha(Filha f); // Remove o primeiro nó da filha f ou retorna NULL se f for vazia -No primeiroNo(Filha f); +No primeiroNoFilha(Filha f); // Remove o último nó da filha f ou retorna NULL se f for vazia -No ultimoNo(Filha f); - -// Devolve o nó sucessor de n ou NULL se n é o último nó da filha -No sucessorNo(No n); - -// Devolve o nó antecessor de n ou NULL se n é o primeiro nó da filha -No antecessorNo(No n); - -// Devolve o conteúdo de n -void *conteudo(No n); +No ultimoNoFilha(Filha f); // Insere um novo nó no fim da Filha f // // Devolve o nó recém criado ou NULL em caso de falha -No insere(void *conteudo, Filha f); +No insereFilha(void *conteudo, Filha f); // Desaloca a filha f e todos os seus nós // @@ -42,7 +34,7 @@ No insere(void *conteudo, Filha f); // para cada nó n da filha // // devolve true em caso de sucesso ou false em caso de falha -bool destroi(Filha f, bool destroi(void *)); +bool destroiFilha(Filha f, bool destroi(void *)); // Impreme todos os nós da filha f // diff --git a/libs/grafo.c b/libs/grafo.c new file mode 100644 index 0000000000000000000000000000000000000000..2e11e81ad56d1045443b69325593e55f40249630 --- /dev/null +++ b/libs/grafo.c @@ -0,0 +1,110 @@ +#include <stdlib.h> +#include "grafo.h" +#include "lista.h" +#include "vertice.h" +#include "tabuleiro.h" + +struct Grafo { + Lista vertices; +}; + +Grafo criaGrafo() { + Grafo g = malloc(sizeof(struct Grafo)); + + g->vertices = constroiLista(); + return g; +} + +Vertice insereVertice(Grafo g, Vertice v) { + if(insereLista(v, g->vertices)) { + return v; + } + return NULL; +} + +void criaArco(Vertice v, Vertice w) { + insereLista(w, v->filhos); + insereLista(v, w->pais); +} + +void tabuleiroParaGrafo(Tblr t, Grafo g) { + for(int i=0; i < t->x; ++i) { + for(int j=0; j < t->y; ++j) { + Celula c = t->celulas[i * t->y + j]; + Vertice v = NULL; + if(c->vert == NULL) { + v = criaVertice(); + v->cor = c->cor; + v->peso = 1; + c->vert = v; + insereVertice(g, v); + } else { + v = c->vert; + } + //------Vizinhos + Celula cima, baixo, esq, dir; + // Cima + if(i > 0) { + cima = t->celulas[(i-1) * t->y + j]; + if(cima->vert == NULL) { + Vertice w = criaVertice(); + w->cor = cima->cor; + w->peso = 1; + c->vert = w; + insereVertice(g, w); + criaArco(v, w); + criaArco(w, v); + } + } + // Direita + if(j < t->y - 1) { + dir = t->celulas[i * t->y + (j + 1)]; + if(dir->vert == NULL) { + Vertice w = criaVertice(); + w->cor = dir->cor; + w->peso = 1; + c->vert = w; + insereVertice(g, w); + criaArco(v, w); + criaArco(w, v); + } + } + // Baixo + if(i < t->x - 1) { + baixo = t->celulas[(i + 1) * t->y + j]; + if(baixo->vert == NULL) { + Vertice w = criaVertice(); + w->cor = baixo->cor; + w->peso = 1; + c->vert = w; + insereVertice(g, w); + criaArco(v, w); + criaArco(w, v); + } + } + // Esquerda + if(j > 0) { + esq = t->celulas[i * t->y + (j - 1)]; + if(esq->vert == NULL) { + Vertice w = criaVertice(); + w->cor = esq->cor; + w->peso = 1; + c->vert = w; + insereVertice(g, w); + criaArco(v, w); + criaArco(w, v); + } + } + } + } + return; +} + +void agrupaGrafo(Grafo g) { + return; +} + +int *buscaCaminho(Grafo g) { + int *caminho = malloc(sizeof(int)); + return caminho; +} diff --git a/libs/grafo.h b/libs/grafo.h new file mode 100644 index 0000000000000000000000000000000000000000..d2c4de482292008ce99e3db9d8dced3f7d890103 --- /dev/null +++ b/libs/grafo.h @@ -0,0 +1,19 @@ +#ifndef _GRAFO_ +#define _GRAFO_ +#include "tabuleiro.h" + +typedef struct Grafo *Grafo; + +Grafo criaGrafo(); + +Vertice insereVertice(Grafo g, Vertice v); + +void criaArco(Vertice v, Vertice w); + +void tabuleiroParaGrafo(Tblr t, Grafo g); + +void agrupaGrafo(Grafo g); + +int *buscaCaminho(Grafo g); + +#endif diff --git a/libs/lista.c b/libs/lista.c new file mode 100644 index 0000000000000000000000000000000000000000..bea275b79ebb30ee846f43c4a3caf15d28c2ff7c --- /dev/null +++ b/libs/lista.c @@ -0,0 +1,121 @@ +#include <malloc.h> +#include "lista.h" +#include "no.h" +//--------------------------------------------------------------------------- +// Lista encadeada + +struct Lista { + + unsigned int tamanho; + int padding; // só pra evitar warning + No primeiro; +}; +//--------------------------------------------------------------------------- +// devolve o número de nós da Lista l + +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; } + +//--------------------------------------------------------------------------- +// cria uma Lista vazia e a devolve +// +// devolve NULL em caso de falha + +Lista constroiLista(void) { + + Lista l = malloc(sizeof(struct Lista)); + + if ( ! l ) + return NULL; + + l->primeiro = NULL; + l->tamanho = 0; + + return l; +} +//--------------------------------------------------------------------------- +// desaloca a Lista l e todos os seus nós +// +// se destroi != NULL invoca +// +// destroi(getConteudo(n)) +// +// para cada nó n da Lista. +// +// devolve 1 em caso de sucesso, +// ou 0 em caso de falha + +int destroiLista(Lista l, int destroi(void *)) { + + No p; + int ok=1; + + while ( (p = primeiroNoLista(l)) ) { + + l->primeiro = getSucessorNo(p); + + if ( destroi ) + ok &= destroi(getConteudo(p)); + + free(p); + } + + free(l); + + return ok; +} +//--------------------------------------------------------------------------- +// insere um novo nó na Lista l cujo conteúdo é p +// +// devolve o No recém-criado +// ou NULL em caso de falha + +No insereLista(void *conteudo, Lista l) { + + No novo = criaNo(); + + if ( ! novo ) + return NULL; + + setConteudo(novo, conteudo); + setSucessorNo(novo, primeiroNoLista(l)); + ++l->tamanho; + + return l->primeiro = novo; +} + +//------------------------------------------------------------------------------ +// remove o No de endereço rNo de l +// se destroi != NULL, executa destroi(getConteudo(rNo)) +// devolve 1, em caso de sucesso +// 0, se rNo não for um No de l + +int removeNo(struct Lista *l, struct No *rNo, int destroi(void *)) { + int r = 1; + if (l->primeiro == rNo) { + l->primeiro = getSucessorNo(rNo); + if (destroi != NULL) { + r = destroi(getConteudo(rNo)); + } + free(rNo); + l->tamanho--; + return r; + } + for (No n = primeiroNoLista(l); getSucessorNo(n); n = getSucessorNo(n)) { + if (getSucessorNo(n) == rNo) { + setSucessorNo(n, getSucessorNo(rNo)); + if (destroi != NULL) { + r = destroi(getConteudo(rNo)); + } + free(rNo); + l->tamanho--; + return r; + } + } + return 0; +} diff --git a/libs/lista.h b/libs/lista.h new file mode 100644 index 0000000000000000000000000000000000000000..2056e1a479b4a6d520db14cfb45e7fde4b0b60c6 --- /dev/null +++ b/libs/lista.h @@ -0,0 +1,55 @@ +#ifndef _LISTA_ +#define _LISTA_ +#include "no.h" + +//----------------------------------------------------------------------------- +// (apontador para) Lista encadeada + +typedef struct Lista *Lista; + +//------------------------------------------------------------------------------ +// devolve o número de nós da Lista l + +unsigned int tamanhoLista(Lista l); + +//------------------------------------------------------------------------------ +// devolve o primeiro nó da Lista l, +// ou NULL, se l é vazia + +No primeiroNoLista(Lista l); + +//------------------------------------------------------------------------------ +// insere um Novo nó na Lista l cujo conteúdo é p +// +// devolve o No recém-criado +// ou NULL em caso de falha + +No insereLista(void *conteudo, Lista l); +//------------------------------------------------------------------------------ +// cria uma Lista vazia e a devolve +// +// devolve NULL em caso de falha + +Lista constroiLista(void); +//------------------------------------------------------------------------------ +// desaloca a Lista l e todos os seus nós +// +// se destroi != NULL invoca +// +// destroi(conteudo(n)) +// +// para cada nó n da Lista. +// +// devolve 1 em caso de sucesso, +// ou 0 em caso de falha + +int destroiLista(Lista l, int destroi(void *)); + +//------------------------------------------------------------------------------ +// remove o No de endereço rNo de l +// se destroi != NULL, executa destroi(conteudo(rNo)) +// devolve 1, em caso de sucesso +// 0, se rNo não for um No de l + +int removeNoLista(struct Lista *l, struct No *rNo, int destroi(void *)); +#endif diff --git a/libs/no.c b/libs/no.c new file mode 100644 index 0000000000000000000000000000000000000000..b88cfce6e0a4b6e7d03fc8691f67014756a513b4 --- /dev/null +++ b/libs/no.c @@ -0,0 +1,39 @@ +#include <stdlib.h> +#include "no.h" + +struct No { + void *conteudo; + No anterior, proximo; +}; + +No criaNo() { + No n = malloc(sizeof(struct No)); + + n->anterior = NULL; + n->proximo = NULL; + return n; +} + +No getSucessorNo(No n) { + return n->proximo; +} + +void setSucessorNo(No n, No p) { + n->proximo = p; +} + +No getAntecessorNo(No n) { + return n->anterior; +} + +void setAntecessorNo(No n, No p) { + n->anterior = p; +} + +void *getConteudo(No n) { + return n->conteudo; +} + +void setConteudo(No n, void *conteudo) { + n->conteudo = conteudo; +} diff --git a/libs/no.h b/libs/no.h new file mode 100644 index 0000000000000000000000000000000000000000..343bb78dec3a7a3b2d0289dd3c3c71808c69c83e --- /dev/null +++ b/libs/no.h @@ -0,0 +1,27 @@ +#ifndef _NO_ +#define _NO_ + +// Nó cujo conteúdo é um void * +typedef struct No *No; + +// Cria um nó vazio e devolve +No criaNo(); + +// Devolve o nó sucessor de n ou NULL se n é o último nó da filha +No getSucessorNo(No n); + +// Define o nó sucessor de n +void setSucessorNo(No n, No p); + +// Devolve o nó antecessor de n ou NULL se n é o primeiro nó da filha +No getAntecessorNo(No n); + +// Define o nó antecessor de n +void setAntecessorNo(No n, No p); + +// Devolve o conteúdo de n +void *getConteudo(No n); + +void setConteudo(No n, void *conteudo); + +#endif diff --git a/libs/tabuleiro.c b/libs/tabuleiro.c index 6958e5db0c3e3b950164dc47be7a68ee7dba9c17..6019933c9787473e026946963a222b6bdb08798a 100644 --- a/libs/tabuleiro.c +++ b/libs/tabuleiro.c @@ -2,18 +2,8 @@ #include <stdlib.h> #include <stdbool.h> #include "tabuleiro.h" - -struct Celula { - // Cor da célula - int cor; - // Se a célula já foi visitada - bool visitada; -}; - -struct Tblr { - int x, y, cores; - Celula *celulas; -}; +#include "vertice.h" +#include "grafo.h" Tblr criaTblr() { Tblr t = malloc(sizeof(struct Tblr)); @@ -36,6 +26,7 @@ bool leTblr(Tblr t) { // Para acessar uma matrix [X][Y] em um vetor fazemos i*Y + j Celula c = malloc(sizeof(struct Celula)); c->visitada = false; + c->vert = NULL; scanf("%d", &(c->cor)); t->celulas[i * y + j] = c; } diff --git a/libs/tabuleiro.h b/libs/tabuleiro.h index 621f37b90aa4fbd8a3bfa9bce52c56772e22ee3b..2cd5d3694b706397c22b7e7ad851917fc18d027b 100644 --- a/libs/tabuleiro.h +++ b/libs/tabuleiro.h @@ -1,9 +1,25 @@ #ifndef _BOARD_ #define _BOARD_ #include <stdbool.h> +#include "vertice.h" + +struct Celula { + // Cor da célula + int cor; + // Se a célula já foi visitada + bool visitada; + // Vertice a qual a célula foi mapeada + Vertice vert; +}; typedef struct Celula *Celula; +struct Tblr { + int x, y, cores; + Celula *celulas; +}; + + typedef struct Tblr *Tblr; // Cria um tabuleiro vazio e retorna diff --git a/libs/vertice.c b/libs/vertice.c new file mode 100644 index 0000000000000000000000000000000000000000..12e996e535534c776e98141655595ad24f89c183 --- /dev/null +++ b/libs/vertice.c @@ -0,0 +1,13 @@ +#include <stdlib.h> +#include "vertice.h" +#include "lista.h" + +Vertice criaVertice() { + Vertice v = malloc(sizeof(struct Vertice)); + + v->cor = -1; + v->peso = 0; + Lista pais = constroiLista(); + Lista filhos = constroiLista(); + return v; +} diff --git a/libs/vertice.h b/libs/vertice.h new file mode 100644 index 0000000000000000000000000000000000000000..fc061ef37405e26817b9b61e5eb1e02e9ec4c23f --- /dev/null +++ b/libs/vertice.h @@ -0,0 +1,16 @@ +#ifndef _VERTICE_ +#define _VERTICE_ +#include "lista.h" + +struct Vertice { + int cor; + int peso; + Lista pais; + Lista filhos; +}; + +typedef struct Vertice *Vertice; + +Vertice criaVertice(); + +#endif diff --git a/main.c b/main.c index 44f602fc19a61dfc4713c863dfb28ba9b5700cd6..1ae1b1634d5b11e22a312edf6d0f24f7209520b6 100644 --- a/main.c +++ b/main.c @@ -3,7 +3,6 @@ #include <stdio.h> #include <time.h> #include "libs/tabuleiro.h" -#include "libs/jogador.h" int main() { Tblr t = criaTblr(); @@ -14,16 +13,16 @@ int main() { } imprimeTblr(t); - // declara o grafo ponderado e seu primeiro nodo - Nodo grafo = criaGrafo(t); - if(grafo == NULL) { - puts("Erro na criacao do grafo"); - return -1; - } - // faz o jogador jogar o jogo a partir do tabuleiro dado - // o retorno do jogador sera um vetor contendo os numeros referentes a menor jogada encontrada por ele - int *jogadas; - jogadas = Joga(grafo, t); + // // declara o grafo ponderado e seu primeiro nodo + // grafo = criaGrafo(t); + // if(grafo == NULL)) { + // puts("Erro na criacao do grafo"); + // return -1; + // } + // // faz o jogador jogar o jogo a partir do tabuleiro dado + // // o retorno do jogador sera um vetor contendo os numeros referentes a menor jogada encontrada por ele + // int *jogadas; + // jogadas = Joga(grafo, t); return 0; } diff --git a/tests/runTests.sh b/tests/runTests.sh index e419dd7bb355336dbff78161df8322e08513cc98..5c58e4e3e86e8c4464906e1b75525e29b79af16e 100755 --- a/tests/runTests.sh +++ b/tests/runTests.sh @@ -4,10 +4,10 @@ tempo_max=500 # tamanhos do tabuleiro -tams=(8 16 32 64 128 512 1024) +tams=(4 8 16 32 64 128) # lista de cores -cores=(4 8 16 32 64) +cores=(2 4 8 16) #-- Cores do terminal RED='\033[0;31m'