cmds
unknown
plain_text
13 days ago
9.6 kB
3
Indexable
#include "type.h" // função geral para libertar memória void libertarMemoria(ESTADO *e) { if (e->tabuleiro != NULL) { for (int i = 0; i < e->linhas; i++) { free(e->tabuleiro[i]); } free(e->tabuleiro); e->tabuleiro = NULL; } } // função geral para alocar memória bool alocarMemoria(ESTADO *e) { e->tabuleiro = malloc(e->linhas * sizeof(char *)); if (e->tabuleiro == NULL) return false; for (int i = 0; i < e->linhas; i++) { e->tabuleiro[i] = malloc(e->colunas * sizeof(char)); // liberta a memória alocada parcialmente em caso de erro if (e->tabuleiro[i] == NULL) { e->linhas = i; // para saber quantas linhas já estavam alocadas libertarMemoria(e); return false; } } return true; } // função geral para libertar o histórico void libertarHistorico(ESTADO *e) { JOGADA_SALVA *atual = e->historico; while (atual != NULL) { JOGADA_SALVA *proximo = atual->ant; // liberta o tabuleiro salvo for (int i = 0; i < atual->linhas; i++) { free(atual->tabuleiro[i]); } free(atual->tabuleiro); // liberta a estrutura da jogada free(atual); atual = proximo; } e->historico = NULL; } int toInt_Alpha (char c) { return c - 'a'; } int toInt_Number (char c) { return c - '0'; } int isDigit (char c) { return ('0' <= c && c <= '9'); } int isLower (char c) { return ('a' <= c && c <= 'z'); } int capital (char c) { return c - ('a' - 'A'); } // função do comando 'gravar' bool gravar (char cmd, char *arg, ESTADO *e) { if (cmd == 'g') { if (arg == NULL) { fprintf(stderr, "Erro: O comando gravar precisa de um argumento!\n"); return false; } printf("Gravado em %s\n", arg); return true; } else return false; } // função do comando 'sair' bool sair(char cmd, char *arg, ESTADO *e) { if (arg != NULL) return false; if (cmd == 's') { // liberta a memória alocada para o tabuleiro libertarMemoria(e); // liberta a memória alocada para o histórico libertarHistorico(e); // sinaliza que o programa deve terminar e->looping = false; return true; } return false; } // função que imprime o tabuleiro void imprimir_tabuleiro(ESTADO *e) { printf("\n"); if (e -> tabuleiro == NULL || e -> linhas <= 0 || e -> colunas <= 0) { printf("Erro: Tabuleiro não inicializado ou inválido!\n"); return; } for (int i = 0; i < e -> linhas; i++) { for (int j = 0; j < e -> colunas; j++) { printf("%c ", e -> tabuleiro[i][j]); } printf("\n"); } } // função do comando 'ler' bool ler(char cmd, char *arg, ESTADO *e) { if (cmd != 'l') return false; if (arg == NULL) { fprintf(stderr, "Erro: O comando ler precisa de um argumento!\n"); return false; } guardarEstado(e); // liberta a memória do tabuleiro anterior, se existir libertarMemoria(e); // abre o ficheiro FILE *file = fopen(arg, "r"); if (file == NULL) { fprintf(stderr, "Erro: Não foi possível abrir o ficheiro %s\n", arg); return false; } // lê as dimensões do tabuleiro if (fscanf(file, "%d %d", &e->linhas, &e->colunas) != 2) { fprintf(stderr, "Erro: Formato inválido no arquivo!\n"); fclose(file); return false; } // aloca memória if (!alocarMemoria(e)) { fprintf(stderr, "Erro: Falha ao alocar memória para o tabuleiro!\n"); fclose(file); return false; } // lê o conteúdo do tabuleiro for (int i = 0; i < e -> linhas; i++) { int j = 0; while (j < e -> colunas) { char c = fgetc(file); if (c != '\n') e -> tabuleiro[i][j++] = c; } } printf("Tabuleiro carregado de %s:\n", arg); fclose(file); imprimir_tabuleiro(e); return true; } // função do comando 'riscar' bool riscar(char cmd, char *arg, ESTADO *e) { if (cmd != 'r') return false; // verifica se o tabuleiro está carregado if (e -> tabuleiro == NULL || e -> linhas <= 0 || e -> colunas <= 0) { fprintf(stderr, "Erro: Tabuleiro não carregado!\n"); return false; } // verifica se o argumento é fornecido if (arg == NULL) { fprintf(stderr, "Erro: O comando riscar precisa de um argumento!\n"); return false; } // verifica se as coordenadas são válidas if (strlen(arg) != 2 || !isLower(arg[0]) || !isDigit(arg[1])) { fprintf(stderr, "Erro: Coordenadas inválidas.\nUse o formato <letra><número> (ex: a1)\n"); return false; } // converte as coordenadas int coluna = toInt_Alpha(arg[0]); int linha = toInt_Number(arg[1]) - 1; // valida os índices if (linha < 0 || linha >= e -> linhas || coluna < 0 || coluna >= e -> colunas) { fprintf(stderr, "Erro: Coordenadas fora dos limites do tabuleiro (%dx%d)!\n", e -> linhas, e -> colunas); return false; } // risca o caracter (substituir por um #) else { // guarda o tabuleiro antes de modificar guardarEstado(e); e -> tabuleiro[linha][coluna] = '#'; } imprimir_tabuleiro(e); return true; } // função do comando 'branco' bool branco (char cmd, char *arg, ESTADO *e) { if (cmd != 'b') return false; // verifica se o tabuleiro está carregado if (e -> tabuleiro == NULL || e -> linhas <= 0 || e -> colunas <= 0) { fprintf(stderr, "Erro: Tabuleiro não carregado!\n"); return false; } // verifica se o argumento é fornecido if (arg == NULL) { fprintf(stderr, "Erro: O comando riscar precisa de um argumento!\n"); return false; } // verifica se as coordenadas são válidas if (strlen(arg) != 2 || !isLower(arg[0]) || !isDigit(arg[1])) { fprintf(stderr, "Erro: Coordenadas inválidas.\nUse o formato <letra><número> (ex: a1)\n"); return false; } // converte as coordenadas int coluna = toInt_Alpha(arg[0]); int linha = toInt_Number(arg[1]) - 1; // a1 internamente vira (0,0) // valida os índices if (linha < 0 || linha >= e -> linhas || coluna < 0 || coluna >= e -> colunas) { fprintf(stderr, "Erro: Coordenadas fora dos limites do tabuleiro (%dx%d)!\n", e -> linhas, e -> colunas); return false; } //substitui por um caracter branco (maiúsculo) else { // guarda o tabuleiro antes de o modificar guardarEstado(e); char letter = e -> tabuleiro[linha][coluna]; e -> tabuleiro[linha][coluna] = capital(letter); } imprimir_tabuleiro(e); return true; } // função para guardar o estado bool guardarEstado(ESTADO *estadoAtual) { // verificação da entrada if (!estadoAtual || !estadoAtual->tabuleiro) return false; // cria um novo nó para armazenar a cópia do tabuleiro atual JOGADA_SALVA *novaJogada = malloc(sizeof(JOGADA_SALVA)); if(!novaJogada) return false; // aloca memória novaJogada->tabuleiro = malloc(estadoAtual->linhas * sizeof(char *)); if(!novaJogada->tabuleiro) { free(novaJogada); return false; } // copia dados do estado novaJogada->linhas = estadoAtual->linhas; novaJogada->colunas = estadoAtual->colunas; // copia cada linha do tabuleiro for(int i = 0; i < estadoAtual->linhas; i++) { novaJogada->tabuleiro[i] = malloc(estadoAtual->colunas * sizeof(char)); if(!novaJogada->tabuleiro[i]) { // libertar memória em caso de erro for(int j = 0; j < i; j++) free(novaJogada->tabuleiro[j]); free(novaJogada->tabuleiro); free(novaJogada); return false; } // cópia dos elementos for(int j = 0; j < estadoAtual->colunas; j++) { novaJogada->tabuleiro[i][j] = estadoAtual->tabuleiro[i][j]; } } // empilha o novo nó no topo da lista ligada novaJogada->ant = estadoAtual->historico; // o novo nó (novaJogada) aponta para o antigo topo da pilha (historico) estadoAtual->historico = novaJogada; // atualiza o topo da pilha para apontar para o novo nó. return true; } // função do comando 'desfazer' bool desfazer(char cmd, char *arg, ESTADO *estadoAtual) { if (cmd != 'd' || arg != NULL) return false; // verifica o histórico if (!estadoAtual->historico) { printf("Não há mais estados para desfazer.\n"); return true; } // salva o topo JOGADA_SALVA *topo = estadoAtual->historico; // restaura as dimensões e o tabuleiro estadoAtual->linhas = topo->linhas; estadoAtual->colunas = topo->colunas; libertarMemoria(estadoAtual); if (!alocarMemoria(estadoAtual)) { fprintf(stderr, "Erro: Falha ao alocar memória para desfazer.\n"); return false; } for (int i = 0; i < topo->linhas; i++) { for (int j = 0; j < topo->colunas; j++) { estadoAtual->tabuleiro[i][j] = topo->tabuleiro[i][j]; } } // atualiza o topo estadoAtual->historico = topo->ant; for (int i = 0; i < topo->linhas; i++) free(topo->tabuleiro[i]); free(topo->tabuleiro); free(topo); printf("Tabuleiro anterior restaurado:\n"); imprimir_tabuleiro(estadoAtual); return true; }
Editor is loading...
Leave a Comment