179 lines
4.6 KiB
C
179 lines
4.6 KiB
C
|
|
#include "maze_masks.h"
|
||
|
|
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#include "error.h"
|
||
|
|
|
||
|
|
/***********************/
|
||
|
|
/*+ Fonctions de base +*/
|
||
|
|
/***********************/
|
||
|
|
|
||
|
|
mask* create_empty_mask(int hsize, int vsize) {
|
||
|
|
// Vérification des paramètres
|
||
|
|
if (hsize <= 0 || vsize <= 0) {
|
||
|
|
ERROR("dimensions invalides pour le masque\n");
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Allocation mémoire pour le masque
|
||
|
|
mask* m = malloc(sizeof(mask));
|
||
|
|
if (m == NULL) {
|
||
|
|
ERROR("Erreur d'allocation mémoire pour le masque");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initialisation des dimensions
|
||
|
|
m->hsize = hsize;
|
||
|
|
m->vsize = vsize;
|
||
|
|
m->nbmasked = 0;
|
||
|
|
|
||
|
|
// Initialisation de la grille
|
||
|
|
m->grid = malloc(hsize * vsize * sizeof(bool));
|
||
|
|
if (m->grid == NULL) {
|
||
|
|
ERROR("Erreur d'allocation mémoire pour la grille du masque");
|
||
|
|
free(m); // Libération la structure
|
||
|
|
}
|
||
|
|
for (int i = 0; i < hsize * vsize; i++) {
|
||
|
|
m->grid[i] = false; // Initialisation à faux
|
||
|
|
}
|
||
|
|
|
||
|
|
return m;
|
||
|
|
}
|
||
|
|
|
||
|
|
void free_mask(mask* m) {
|
||
|
|
// Vérification des paramètres
|
||
|
|
if (m == NULL) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
free(m->grid);
|
||
|
|
free(m);
|
||
|
|
}
|
||
|
|
|
||
|
|
void resize_mask(mask* m, int new_hsize, int new_vsize) {
|
||
|
|
// Vérification des paramètres
|
||
|
|
if (!m || new_hsize <= 0 || new_vsize <= 0) {
|
||
|
|
ERROR("dimensions invalides ou masque NULL\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Allocation de la nouvelle grille
|
||
|
|
bool* new_grid = malloc(new_hsize * new_vsize * sizeof(bool));
|
||
|
|
if (new_grid == NULL) {
|
||
|
|
ERROR("allocation de la grille de masquage échouée\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Échelles de redimensionnement
|
||
|
|
double scale_x = (double)m->hsize / new_hsize;
|
||
|
|
double scale_y = (double)m->vsize / new_vsize;
|
||
|
|
|
||
|
|
// Remplissage de la nouvelle grille en conservant le motif
|
||
|
|
for (int new_y = 0; new_y < new_vsize; ++new_y) {
|
||
|
|
for (int new_x = 0; new_x < new_hsize; ++new_x) {
|
||
|
|
// Calcul de l'abcsisse dans dans l'ancienne grille
|
||
|
|
int old_x = (int)(new_x * scale_x);
|
||
|
|
// Calcul de l'ordonnée dans l'ancienne grille
|
||
|
|
int old_y = (int)(new_y * scale_y);
|
||
|
|
// Copie dans la nouvelle cellule la valeur de la cellule trouvée dans l'ancienne grille
|
||
|
|
new_grid[new_y * new_hsize + new_x] = m->grid[old_y * m->hsize + old_x];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Libération de l'ancienne grille
|
||
|
|
free(m->grid);
|
||
|
|
|
||
|
|
// Mise à jour des dimensions et de la grille
|
||
|
|
m->grid = new_grid;
|
||
|
|
m->hsize = new_hsize;
|
||
|
|
m->vsize = new_vsize;
|
||
|
|
|
||
|
|
// Recalcul du nombre de cellules masquées
|
||
|
|
m->nbmasked = 0;
|
||
|
|
for (int i = 0; i < new_hsize * new_vsize; ++i) {
|
||
|
|
if (m->grid[i]) {
|
||
|
|
m->nbmasked++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Vérification qu'au moins une cellule reste non masquée
|
||
|
|
if (m->nbmasked == new_hsize * new_vsize) {
|
||
|
|
m->grid[0] = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void print_mask(mask* m) {
|
||
|
|
// Vérification des paramètres
|
||
|
|
if (m == NULL) {
|
||
|
|
ERROR("Le masque est NULL.\n");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Parcours du masque ligne par ligne
|
||
|
|
for (int i = 0; i < m->vsize; i++) {
|
||
|
|
for (int j = 0; j < m->hsize; j++) {
|
||
|
|
int index = i * m->hsize + j; // Calcul de l'indice dans le tableau 1D
|
||
|
|
if (m->grid[index]) {
|
||
|
|
printf("X"); // Cellule masquée
|
||
|
|
} else {
|
||
|
|
printf("."); // Cellule non-masquée
|
||
|
|
}
|
||
|
|
}
|
||
|
|
printf("\n"); // Nouvelle ligne après chaque ligne du masque
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**************************************/
|
||
|
|
/*+ Génération à partir d'un fichier +*/
|
||
|
|
/**************************************/
|
||
|
|
|
||
|
|
mask* read_mask(const char* file) {
|
||
|
|
// Ouverture du fichier en lecture
|
||
|
|
FILE* f = fopen(file, "r");
|
||
|
|
|
||
|
|
int countv = 1;
|
||
|
|
int count_total = 0;
|
||
|
|
int c = fgetc(f);
|
||
|
|
while (c != EOF) {
|
||
|
|
int d = fgetc(f);
|
||
|
|
if (c == '\n' && d != EOF) {
|
||
|
|
countv++;
|
||
|
|
}
|
||
|
|
count_total++;
|
||
|
|
c = d;
|
||
|
|
}
|
||
|
|
|
||
|
|
count_total -= countv - 1;
|
||
|
|
int counth = count_total / countv;
|
||
|
|
mask* m = create_empty_mask(counth, countv);
|
||
|
|
|
||
|
|
m->hsize = counth;
|
||
|
|
m->vsize = countv;
|
||
|
|
m->grid = malloc(counth * countv * sizeof(bool));
|
||
|
|
|
||
|
|
for (int i = 0; i < counth * countv; i++) {
|
||
|
|
m->grid[i] = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
fseek(f, 0, SEEK_SET);
|
||
|
|
|
||
|
|
int c1 = fgetc(f);
|
||
|
|
int i = 0;
|
||
|
|
|
||
|
|
while (c1 != EOF && i < counth * countv) {
|
||
|
|
if (c1 != '\n') {
|
||
|
|
if (c1 == 'X') {
|
||
|
|
m->grid[i] = true;
|
||
|
|
m->nbmasked++;
|
||
|
|
}
|
||
|
|
i++;
|
||
|
|
}
|
||
|
|
c1 = fgetc(f);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (m->nbmasked == counth * countv) {
|
||
|
|
ERROR("toutes les cellules sont masquées après la lecture du fichier\n");
|
||
|
|
free(m->grid);
|
||
|
|
m->grid = NULL;
|
||
|
|
}
|
||
|
|
fclose(f);
|
||
|
|
return m;
|
||
|
|
}
|