Untitled
unknown
plain_text
7 months ago
6.0 kB
12
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#define TMAX_MATRIZ 26
typedef struct {
char tabuleiro[TMAX_MATRIZ][TMAX_MATRIZ];
int linhas, colunas;
bool carregouTabuleiro;
bool looping;
} Estado;
// Define um tipo de ponteiro chamado comando que aponta para uma função que retorna bool e recebe aqueles argumentos
// Comando já é o próprio ponteiro
typedef bool (*Comando)(char cmd, char *arg, Estado *e);
void mostrarTabuleiro(Estado *e) {
printf("\n");
for (int i = 0; i < e->linhas; i++) {
for (int j = 0; j < e->colunas; j++) {
printf("%c ", e->tabuleiro[i][j]);
}
printf("\n");
}
printf("\n");
}
bool cmdLer(char cmd, char *arg, Estado *e) {
if (cmd != 'l' || arg == NULL) return false;
// ficheiro é ponteiro para o tipo file (fopen retorna endereco)
FILE *ficheiro = fopen(arg, "r");
if (ficheiro == NULL) {
printf("Erro ao abrir %s\n", arg);
return true; // O comando foi reconhecido apesar de ter havido erro
}
// armazena no estado -> linhas
if (fscanf(ficheiro, "%d %d", &(e->linhas), &(e->colunas)) != 2) {
fclose(ficheiro);
printf("Formato inválido no ficheiro\n");
return true;
}
if (e->linhas <= 0 || e->colunas <= 0 || e->linhas > TMAX_MATRIZ || e->colunas > TMAX_MATRIZ) {
printf("As dimensões do tabuleiro são inválidas\n");
fclose(ficheiro);
return true;
}
while (fgetc(ficheiro) != '\n'); // Retira os espaços e passa o "cursor" para depois do \n
char linha[TMAX_MATRIZ + 2]; // adiciona o \n e o \0
for (int i = 0; i < e->linhas; i++) {
if (fgets(linha, sizeof(linha), ficheiro) == NULL) {
printf("Erro ao ler a linha %d\n", i+1);
break;
}
// Remove o '\n' no final (strcspn retorna o indice do \n) p possibilitar futura comparacao
linha[strcspn(linha, "\n")] = '\0';
for (int j = 0; j < e->colunas; j++) {
if (linha[j] == '\0') {
printf("Aviso linha %d menor que o esperado\n", i+1); // se introduziu uma dimensao e depois a linha era dif
break;
}
e->tabuleiro[i][j] = linha[j];
}
}
fclose(ficheiro);
e->carregouTabuleiro = true;
printf("\nTabuleiro inicial %dx%d carregado:\n", e->linhas, e->colunas);
mostrarTabuleiro(e);
return true;
}
bool cmdSair(char cmd, char *arg, Estado *e) {
if (cmd == 's' && arg == NULL) {
e->looping = false;
return true; // comando foi reconhecido
}
return false; // comando não foi reconhecido
}
bool cmdPintar(char cmd, char *arg, Estado *e) {
if (cmd != 'b' || e->carregouTabuleiro == false) return false;
int x;
char y;
if (sscanf(arg, "%c%d", &y, &x) != 2) return false;
int coluna = y - 'a'; // 'a' corresponde a 0, 'b' a 1 etc
if (x >= 0 && x < e->linhas && coluna >= 0 && coluna < e->colunas) {
e->tabuleiro[x][coluna] = toupper(e->tabuleiro[x][coluna]);
mostrarTabuleiro(e);
return true;
}
return false;
}
bool cmdRiscar(char cmd, char *arg, Estado *e) {
if (cmd != 'r' || e->carregouTabuleiro == false) return false;
int x;
char y;
if (sscanf(arg, "%c%d", &y, &x) != 2) return false;
int coluna = y - 'a';
if (x >= 0 && x < e->linhas && coluna >= 0 && coluna < e->colunas) {
e->tabuleiro[x][coluna] = '#';
mostrarTabuleiro(e);
return true;
}
return false;
}
int main() {
Estado estado = {0}; // inicializa todos os campos com zero
estado.looping = true;
Comando comandos[] = {cmdLer,cmdSair,cmdPintar,cmdRiscar,NULL};
char input[100];
printf("Bem-vindo ao Puzzle!\n");
printf("Comandos disponíveis:\n");
printf(" l [arquivo] - Carregar tabuleiro\n");
printf(" b [coord] - Pintar casa (ex: b a1)\n");
printf(" r [coord] - Riscar casa (ex: r b2)\n");
printf(" s - Sair\n");
while (estado.looping) {
// le o que foi introduzido (stdin) e armazena em input (para quando chega no \n ou ultrapassa o sizeof) e retorna o ponteiro
if (fgets(input, sizeof(input), stdin) == NULL) estado.looping = false;
// Quando escrevemos b a1 e damos enter o ultimo caractere é o \n, precisamos remove-lo.
int length = strlen(input);
if (length > 0 && input[length-1] == '\n') { // se for \n substitui.
input[length-1] = '\0';
}
char cmd = '\0';
char arg[100] = {0};
// vai ler da string input (%99s para usar no máx 99 caracteres (precisa de espaço pro \0 no fim))
int argsLido = sscanf(input, "%c %99s", &cmd, arg);
bool temArgumento = (cmd == 'l' || cmd == 'b' || cmd == 'r');
// ver se leu o comando
if (argsLido < 1) {
printf("Comando inválido!\n");
}
// ver se era necessário argumento e não havia
else if (temArgumento && argsLido < 2) {
printf("Este comando requer um argumento!\n");
}
else {
bool reconhecido = false; // é uma flag
// enquanto não chegar ao fim da lista de comandos e não houver nenhum que foi reconhecido procura o comando
for (int i = 0; comandos[i] != NULL && !reconhecido; i++) {
if (argsLido > 1) {
reconhecido = comandos[i](cmd, arg, &estado);
}
else {
// se não tiver argumentos passa o ponteiro nulo
reconhecido = comandos[i](cmd, NULL, &estado);
}
}
if (!reconhecido) { // se não houve nenhum reconhecido então é inválido
printf("Comando inválido.\n");
}
}
}
printf("Jogo encerrado.\n");
return 0;
}Editor is loading...
Leave a Comment