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'