GRA_tpCondRet GRA_ExcluirVizinhoCorrente (GRA_tppGrafo pGrafo, int idVertice) { tpAresta* vizinho = NULL; tpNode* no = NULL; GRA_tpCondRet r; tpVertice * pVertice = NULL; tpVertice * pVerticeCorrente = NULL; int achou = 0; if (pGrafo->corrente == -1) { //Checagem de grafo vazio return GRA_CondRetGrafoVazio ; } pVerticeCorrente = get_by_id( pGrafo, pGrafo->corrente ); if(pVerticeCorrente == NULL) { return GRA_CondRetGrafoVazio ; //Questionável } pVertice = get_by_id(pGrafo,idVertice); if (pVertice == NULL) { return GRA_CondRetNaoEhVertice; } achou = EhVizinho( pGrafo, pVertice , pVerticeCorrente ); if(achou) { return ExcluirVertice(pGrafo, pVertice); } else { return GRA_CondRetNaoEhVizinho ; } }
GRA_tpCondRet GRA_InserirAresta( GRA_tppGrafo pGrafo, int idVertice1, int idVertice2 , int idAresta) { tpVertice* origem1 = NULL; tpVertice* origem2 = NULL; tpVertice* pVertice1 = get_by_id(pGrafo,idVertice1); tpVertice* pVertice2 = get_by_id(pGrafo,idVertice2); tpAresta* vizinho = NULL; /* Verifica se vertice pertence ao grafo; */ if (pVertice1 == NULL || pVertice2 == NULL) { return GRA_CondRetNaoEhVertice; } if (pVertice1 == pVertice2) { return GRA_CondRetEhVizinho; } if (!EhVizinho(pGrafo, pVertice1, pVertice2) && !EhVizinho(pGrafo, pVertice2, pVertice1) ) { tpAresta * aresta1 = NULL; tpAresta * aresta2 = NULL; origem1 = ObterOrigem(pGrafo, pVertice1); origem2 = ObterOrigem(pGrafo, pVertice2); aresta1 = ( tpAresta * ) calloc(1, sizeof( tpAresta )) ; if (aresta1 == NULL){ return GRA_CondRetFaltouMemoria; } aresta2 = ( tpAresta * ) calloc(1, sizeof( tpAresta )) ; if (aresta2 == NULL ) { free(aresta1); return GRA_CondRetFaltouMemoria; } aresta1->id = idAresta; aresta2->id = idAresta; aresta1->pVizinho = pVertice2; aresta2->pVizinho = pVertice1; LIS_InserirElementoApos(pVertice1->pNode->arestas, aresta1); LIS_InserirElementoApos(pVertice2->pNode->arestas, aresta2); if (origem1 != origem2) { //Estavam em componentes distintas? Se sim, junta LIS_IrInicioLista(pGrafo->componentes); LIS_ProcurarValor(pGrafo->componentes, origem1); LIS_ExcluirElemento(pGrafo->componentes); } return GRA_CondRetOK; } else { return GRA_CondRetEhVizinho; } }
GRA_tpCondRet GRA_InserirVizinhoCorrente( GRA_tppGrafo pGrafo , void* pValor, int idVertice, int idAresta ) { tpVertice * vizinho = NULL; tpVertice * u; tpVertice * v; GRA_tpCondRet r; /* Verifica se vertice pertence ao grafo; */ if (pGrafo->corrente == -1) { return GRA_CondRetGrafoVazio; } vizinho = get_by_id(pGrafo,idVertice); /* por hipotese nao precisamos checar isso if(vizinho != NULL) return GRA_CondRetEhVertice; if(EhVizinho(pGrafo,get_by_id(pGrafo,pGrafo->corrente),vizinho)) return GRA_CondRetEhVizinho; */ r = GRA_InserirVertice(pGrafo, pValor, idVertice); if(r != GRA_CondRetOK) return r; return GRA_InserirAresta(pGrafo,idVertice,pGrafo->corrente,idAresta); }
int find_moves(t_pos *pos, int *moves) { int count = 0; int index = 0; t_hex *hex = &pos->hex; t_tiles *tiles = &pos->tiles; t_done *done = &pos->done; int cell_id = next_cell(done); int cells_count = -1; int *cells_around = NULL; int min_possible = 0; int max_possible = 0; int i, j, ca, dj; if (cell_id < 0) { return count; } cells_around = get_by_id(hex, cell_id)->links; cells_count = get_by_id(hex, cell_id)->link_count; max_possible = cells_count; for (ca = 0; ca < cells_count; ++ca) { j = cells_around[ca]; if (already_done(done, j)) { dj = done->cells[j]; if ((dj > 0) && (dj < 7)) { min_possible += 1; } else if (dj == 0) { max_possible = 0; min_possible += 1; } else if (dj == 7) { max_possible -= 1; } } } for (i = 0; i < 8; ++i) { if ((*tiles)[i] > 0) { if ((i == 7) || ((min_possible <= i) && (i <= max_possible))) { moves[index] = cell_id; moves[index + 1] = i; count += 1; index += 2; } } } return count; }
GRA_tpCondRet GRA_ExcluirVertice (GRA_tppGrafo pGrafo, int idVertice) { tpVertice * pVertice = get_by_id(pGrafo, idVertice); if (pVertice == NULL) { return GRA_CondRetNaoEhVertice; } return ExcluirVertice (pGrafo, pVertice); }
GRA_tpCondRet GRA_IrVizinhoCorrente( GRA_tppGrafo pGrafo , int id ) { tpVertice * vizinho = NULL; /* Verifica se o grafo não está vazio(possui corrente); */ if (pGrafo->corrente == -1) { return GRA_CondRetGrafoVazio; } vizinho = get_by_id(pGrafo,id); if (vizinho == NULL) { return GRA_CondRetNaoEhVertice; } if (!EhVizinho(pGrafo,get_by_id(pGrafo,pGrafo->corrente),vizinho)) { return GRA_CondRetNaoEhVizinho; } pGrafo->corrente = id; return GRA_CondRetOK; }
GRA_tpCondRet GRA_AlterarValor( GRA_tppGrafo pGrafo , int idVertice , void* pDado ) { tpVertice * pVertice = get_by_id(pGrafo,idVertice); /* Verifica se vertice pertence ao grafo; */ if (pVertice == NULL) { return GRA_CondRetNaoEhVertice; } pVertice->pNode->pValor = pDado; return GRA_CondRetOK; }
GRA_tpCondRet GRA_ObterCorrente( GRA_tppGrafo pGrafo , void** pDado ) { tpVertice * tpVertice = NULL; /* Verifica se vertice pertence ao grafo; */ if ( pGrafo->corrente == -1 ) { return GRA_CondRetGrafoVazio; } tpVertice = get_by_id(pGrafo,pGrafo->corrente); *pDado = tpVertice->pNode->pValor; return GRA_CondRetOK; }
GRA_tpCondRet GRA_MudarCorrente( GRA_tppGrafo pGrafo , int id ) { tpVertice * vizinho = NULL; /* Verifica se vertice pertence ao grafo; */ if (pGrafo->corrente == -1) { return GRA_CondRetGrafoVazio; } vizinho = get_by_id(pGrafo,id); if(vizinho == NULL) return GRA_CondRetNaoEhVertice; LIS_ProcurarValor(pGrafo->vertices,vizinho); pGrafo->corrente = id; return GRA_CondRetOK; }
/* Диалог удаления */ void delete_dialog(BookDB* db) { int id; output("Введите номер книги\n"); input("%i", &id); Book *book = get_by_id(db, id); if (!book) { output("Книга с id: %d не найдена!\n", id); return; } output("Вы точно хотите удалить книгу %s? (yes/no)\n", book->title); char answer[MAX_STRING_LENGTH]; input("%s", answer); if (!strcmp(answer, "y") || !strcmp(answer, "yes")) { delete_book(db, book); db->saved = 0; output("Книга удалена!\n"); } }
GRA_tpCondRet GRA_ObterVizinhos ( GRA_tppGrafo pGrafo, int idVertice, LIS_tppLista* pLista) { tpVertice * pVertice = get_by_id(pGrafo,idVertice); LIS_tppLista vizinhos = NULL; LIS_tppLista Ret_vizinhos = NULL; tpAresta* aresta = NULL; int* idVerticeVizinho = NULL; if (pVertice == NULL) return GRA_CondRetNaoEhVertice; Ret_vizinhos = LIS_CriarLista(free); if (Ret_vizinhos == NULL) { return GRA_CondRetFaltouMemoria; } vizinhos = pVertice->pNode->arestas; LIS_IrInicioLista(vizinhos); if (LIS_NumeroDeElementos(vizinhos) > 0) { do { idVerticeVizinho = (int*) calloc(1, sizeof(int)); aresta = (tpAresta *)LIS_ObterValor(vizinhos); (*idVerticeVizinho) = aresta->pVizinho->id; if (LIS_InserirElementoApos( Ret_vizinhos, idVerticeVizinho) != LIS_CondRetOK ) { LIS_DestruirLista(Ret_vizinhos); return GRA_CondRetFaltouMemoria; } } while(LIS_AvancarElementoCorrente(vizinhos, 1) == LIS_CondRetOK); } *pLista = Ret_vizinhos; return GRA_CondRetOK; }
GRA_tpCondRet GRA_BuscarCaminho( GRA_tppGrafo pGrafo , int idVerticeOrigem, int idVerticeDestino, LIS_tppLista * pLista ) { tpVertice * v = NULL; tpVertice * u = NULL; tpVertice * origem1 = NULL; tpVertice * origem2 = NULL; int lenV = 0; LIS_tppLista Q = NULL; //FILA LIS_tppLista arestas = NULL; LIS_tppLista retorno = NULL; int t; int len = 0; int achou = 0; int ok = 0; int i,j,in; int lenD; int alt = 0; int* visitados = NULL; // Vetor de vertices visitados int* vizinhos = NULL; int* idAux = NULL; Dist** dists = NULL; Dist* dist = NULL; //aux; Dist* currDist = NULL; lenD = 1; v = get_by_id(pGrafo, idVerticeOrigem); u = get_by_id(pGrafo, idVerticeDestino); if(v == NULL || u == NULL) { return GRA_CondRetNaoEhVertice; } origem1 = ObterOrigem(pGrafo, v); origem2 = ObterOrigem(pGrafo, u); if (origem1 != origem2) { return GRA_CondRetNaoEhConexo; }//Else: É conexo, devia retornar Ok. for (;;) { dists = (Dist**)calloc(LIS_NumeroDeElementos(pGrafo->vertices)+1, sizeof(Dist*)); if (dists == NULL) {break;} dists[0] = newDist(idVerticeOrigem, 0); retorno = LIS_CriarLista(free); if (retorno == NULL) { break; } else if (v == u) { if( LIS_InserirElementoApos(retorno, newInt(idVerticeOrigem)) == LIS_CondRetOK) { *pLista = retorno; return GRA_CondRetOK; } else { break; } } visitados = (int*) calloc(LIS_NumeroDeElementos(pGrafo->vertices)+1,sizeof(int)); if (visitados == NULL) { break; } Q = LIS_CriarLista(free); if (Q == NULL) { break; } visitados[0] = idVerticeOrigem; lenV = 1; if (LIS_InserirElementoApos(Q, newInt(idVerticeOrigem)) != LIS_CondRetOK) { break;} //enque ok = 1; break; } if (!ok) { free(dists); LIS_DestruirLista(retorno); free(visitados); LIS_DestruirLista(Q); return GRA_CondRetFaltouMemoria; } while (LIS_NumeroDeElementos(Q) > 0) { //dequeue LIS_IrInicioLista(Q); t = getInt(LIS_ObterValor(Q)); LIS_ExcluirElemento(Q); //Iterar sobre vizinhos GRA_ObterVizinhos(pGrafo, t, &arestas); vizinhos = converteListaParaVetorDeInteiros(arestas, &len); LIS_DestruirLista(arestas); arestas = NULL; currDist = getDist(dists, t); if(!currDist) { return GRA_CondRetFaltouMemoria; } else { } alt = currDist->dist + 1; for (i=0; i < len; i++) { in = 0; for (j=0; j < lenV; j++) { if (visitados[j] == vizinhos[i]) { in = 1; } } if (!in) { dist = getDist(dists, vizinhos[i]); if (dist == NULL) { //infinity dists[lenD] = newDist(vizinhos[i], alt); dists[lenD]->prev = currDist; dist = dists[lenD]; lenD++; } else if (alt < dist->dist) { dist->dist = alt; dist->prev = currDist; } if (idVerticeDestino == vizinhos[i]) { currDist = dist; achou = 1; } visitados[lenV] = vizinhos[i]; lenV++; LIS_InserirElementoAntes(Q, newInt(vizinhos[i])); } } free(vizinhos); if (achou) { currDist = dist; break; } if(lenV == LIS_NumeroDeElementos(pGrafo->vertices)) { break; } } if (achou) { //printf("\n"); // for(i=0; i < lenD; i++) { // printf("endr: %p, id: %d, dist: %d, prev: %p \n", *(dists+i), dists[i]->id, dists[i]->dist, dists[i]->prev); // } while (currDist) { LIS_InserirElementoAntes(retorno, newInt(currDist->id)); currDist = currDist->prev; } } //Limpando a memória for (i=0; i < lenD; i++) { free(dists[i]); } free(dists); free(visitados); LIS_DestruirLista(Q); *pLista = retorno; return GRA_CondRetOK; }
/* Диалог поиска */ void find_dialog(BookDB* db) { # define FIELD(s) if(!strcmp(#s, field)) char field[MAX_STRING_LENGTH]; output("По какому полю будем искать?\n"); printf("\t%s\n", "id - номер книги в каталоге"); printf("\t%s\n", "title - название"); printf("\t%s\n", "author - имя автора"); printf("\t%s\n", "ganre - жанр"); input("%s", field); getc(stdin); FIELD(id) { int id; output("Введите номер книги\n<< "); input("%d", &id); getc(stdin); Book* book = get_by_id(db, id); if (book) { print_book(book); } else { output("Книги с таким номером не найдено!\n"); } return; } Book *book, *end; FIELD(title) { output("Название книги\n<< "); fgets(field, MAX_STRING_LENGTH, stdin); delns(field); for (book = db->books, end = db->books + db->count; book < end; book++) { if (!(strcmp(field, book->title))) print_book(book); } return; } FIELD(ganre) { output("Жанр книги\n<< "); fgets(field, MAX_STRING_LENGTH, stdin); delns(field); for (book = db->books, end = db->books + db->count; book < end; book++) { if (!(strcmp(field, book->ganre))) print_book(book); } return; } FIELD(author) { output("Автор книги\n<< "); fgets(field, MAX_STRING_LENGTH, stdin); delns(field); for (book = db->books, end = db->books + db->count; book < end; book++) { if (!(strcmp(field, book->author))) print_book(book); } return; } printf("!! Неизвестная поле для поиска \"%s\"\n", field); # undef FIELD }