cmds
unknown
plain_text
14 days ago
9.0 kB
2
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; } void libertarHistorico(ESTADO *e) { JOGADA_SALVA *atual = e->historico; while (atual != NULL) { JOGADA_SALVA *proximo = atual->ant; // libertar o tabuleiro salvo for (int i = 0; i < atual->linhas; i++) { free(atual->tabuleiro[i]); } free(atual->tabuleiro); // libertar 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'); } 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; } 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; } 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"); } } 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); //abrir 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; } //ler 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; } // alocar memória com função genérica if (!alocarMemoria(e)) { fprintf(stderr, "Erro: Falha ao alocar memória para o tabuleiro!\n"); fclose(file); return false; } //ler 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; } bool riscar(char cmd, char *arg, ESTADO *e) { if (cmd != 'r') return false; //verificar 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; } //verificar se o argumento é fornecido if (arg == NULL) { fprintf(stderr, "Erro: O comando riscar precisa de um argumento!\n"); return false; } //verificar 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; } //converter as coordenadas int coluna = toInt_Alpha(arg[0]); int linha = toInt_Number(arg[1]) - 1; //validar 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; } //riscar o caracter (substituir por um #) else { guardarEstado(e); e -> tabuleiro[linha][coluna] = '#'; } imprimir_tabuleiro(e); return true; } bool branco (char cmd, char *arg, ESTADO *e) { if (cmd != 'b') return false; //verificar 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; } //verificar se o argumento é fornecido if (arg == NULL) { fprintf(stderr, "Erro: O comando riscar precisa de um argumento!\n"); return false; } //verificar 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; } //converter as coordenadas int coluna = toInt_Alpha(arg[0]); int linha = toInt_Number(arg[1]) - 1; // a1 internamente vira (0,0) //validar 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; } //substituir por um caracter branco (maiúsculo) else { 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) { JOGADA_SALVA *novaJogada = malloc(sizeof(JOGADA_SALVA)); if(!novaJogada) return false; // alocar memória para o tabuleiro copiado novaJogada->tabuleiro = malloc(estadoAtual->linhas * sizeof(char *)); if(!novaJogada->tabuleiro) { free(novaJogada); return false; } // copiar dados do estado novaJogada->linhas = estadoAtual->linhas; novaJogada->colunas = estadoAtual->colunas; // copiar 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]; } } // ligar ao histórico existente novaJogada->ant = estadoAtual->historico; estadoAtual->historico = novaJogada; return true; } bool desfazer(char cmd, char *arg, ESTADO *estadoAtual) { if (cmd != 'd' || arg != NULL) return false; // verificar histórico if (!estadoAtual->historico) { printf("Não há mais estados para desfazer.\n"); return true; } // obter estado salvo JOGADA_SALVA *topo = estadoAtual->historico; // restaurar dimensões e 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]; } } // atualizar histórico e liberar memória 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