ajouts des fichiers perso
Le plagiat c'est mal donc gare à vos culs
This commit is contained in:
358
maze/maze_VM.c
Normal file
358
maze/maze_VM.c
Normal file
@@ -0,0 +1,358 @@
|
||||
#include "maze_2.h"
|
||||
|
||||
#include "data_queue.h"
|
||||
|
||||
#include <bits/types/siginfo_t.h>
|
||||
|
||||
/*****************************************/
|
||||
/*+ Récupération de numéros de cellules +*/
|
||||
/*****************************************/
|
||||
|
||||
int get_adj_maze(maze* p_maze, const int cellule, const cardinal card) {
|
||||
switch (card) {
|
||||
case NORTH:
|
||||
if(cellule < p_maze->hsize) { // Si on est sur la première ligne (on ne peut donc aller plus au nord)
|
||||
return -1;
|
||||
}
|
||||
return cellule - p_maze->hsize;
|
||||
case EAST:
|
||||
if(cellule % p_maze->hsize == p_maze->hsize - 1) { // Si on est sur la dernière colonne (on ne peut donc aller plus à l'est)
|
||||
return -1;
|
||||
}
|
||||
return cellule + 1;
|
||||
case SOUTH:
|
||||
if(cellule >= (p_maze->vsize - 1) * p_maze->hsize) { // Si on est sur la dernière ligne (on ne peut donc aller plus au sud)
|
||||
return -1;
|
||||
}
|
||||
return cellule + p_maze->hsize;
|
||||
case WEST:
|
||||
if(cellule % p_maze->hsize == 0) { // Si on est sur la première colonne (on ne peut donc aller plus à l'ouest)
|
||||
return -1;
|
||||
}
|
||||
return cellule - 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/*+ Gestion des cellules du labyrinthe +*/
|
||||
/****************************************/
|
||||
|
||||
|
||||
void mask_cell_maze(maze *p_maze, const int cellule) {
|
||||
p_maze->props[cellule] |= 32; // On masque la cellule (on met le 6ème bit à 1)
|
||||
}
|
||||
|
||||
bool valid_maze(maze *p_maze, const int cellule) {
|
||||
if(cellule < 0 || cellule / p_maze->vsize >= p_maze->hsize || cellule % p_maze->vsize >= p_maze->vsize) { // Si la cellule n'est pas dans la grille
|
||||
return false;
|
||||
}
|
||||
// ReSharper disable once CppDFANullDereference
|
||||
return !(p_maze->props[cellule] & 32); // Si la cellule est accessible (booléen stocké dans le 6ème bit)
|
||||
}
|
||||
|
||||
bool is_reach_maze(maze *p_maze, const int cellule) {
|
||||
return p_maze->props[cellule] & 64; // Si la cellule est accessible (booléen stocké dans le 7ème bit)
|
||||
}
|
||||
|
||||
void make_reach_maze(maze *p_maze, const int cellule) {
|
||||
p_maze->props[cellule] |= 64; // On rend la cellule accessible (on met le 7ème bit à 1)
|
||||
}
|
||||
|
||||
bool has_wall_maze(maze *p_maze, const int cellule, const cardinal card) {
|
||||
switch (card)
|
||||
{
|
||||
case NORTH:
|
||||
return p_maze->props[cellule] & 1; // Si il y a un mur au nord (booléen stocké dans le 1er bit)
|
||||
case EAST:
|
||||
return p_maze->props[cellule] & 2; // Si il y a un mur à l'est (booléen stocké dans le 2ème bit)
|
||||
case SOUTH:
|
||||
return p_maze->props[cellule] & 4; // Si il y a un mur au sud (booléen stocké dans le 3ème bit)
|
||||
case WEST:
|
||||
return p_maze->props[cellule] & 8; // Si il y a un mur à l'ouest (booléen stocké dans le 4ème bit)
|
||||
default:
|
||||
fprintf(stderr, "has_wall_maze: cardinal inconnu\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void build_wall_maze(maze *p_maze, const int cellule, const cardinal card) {
|
||||
switch (card)
|
||||
{
|
||||
case NORTH:
|
||||
p_maze->props[cellule] |= 1; // On met un mur au nord (on met le 1er bit à 1)
|
||||
int neighbour = get_adj_maze(p_maze, cellule, NORTH);
|
||||
if(neighbour != -1) {
|
||||
p_maze->props[neighbour] |= 4; // On met un mur au sud de la cellule voisine (on met le 3ème bit à 1)
|
||||
}
|
||||
return;
|
||||
case EAST:
|
||||
p_maze->props[cellule] |= 2; // On met un mur à l'est (on met le 2ème bit à 1)
|
||||
neighbour = get_adj_maze(p_maze, cellule, EAST);
|
||||
if(neighbour != -1) {
|
||||
p_maze->props[neighbour] |= 8; // On met un mur à l'ouest de la cellule voisine (on met le 4ème bit à 1)
|
||||
}
|
||||
return;
|
||||
case SOUTH:
|
||||
p_maze->props[cellule] |= 4; // On met un mur au sud (on met le 3ème bit à 1)
|
||||
neighbour = get_adj_maze(p_maze, cellule, SOUTH);
|
||||
if(neighbour != -1) {
|
||||
p_maze->props[neighbour] |= 1; // On met un mur au nord de la cellule voisine (on met le 1er bit à 1)
|
||||
}
|
||||
return;
|
||||
case WEST:
|
||||
p_maze->props[cellule] |= 8; // On met un mur à l'ouest (on met le 4ème bit à 1)
|
||||
neighbour = get_adj_maze(p_maze, cellule, WEST);
|
||||
if(neighbour != -1) {
|
||||
p_maze->props[neighbour] |= 2; // On met un mur à l'est de la cellule voisine (on met le 2ème bit à 1)
|
||||
}
|
||||
return;
|
||||
default:
|
||||
fprintf(stderr, "build_wall_maze: cardinal inconnu\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
void del_wall_maze(maze *p_maze, const int cellule, const cardinal card) {
|
||||
switch (card)
|
||||
{
|
||||
case NORTH:
|
||||
p_maze->props[cellule] &= 254; // On enlève le mur au nord (on met le 1er bit à 0)
|
||||
int neighbour = get_adj_maze(p_maze, cellule, NORTH);
|
||||
if(neighbour != -1) {
|
||||
p_maze->props[neighbour] &= 251; // On enlève le mur au sud de la cellule voisine (on met le 3ème bit à 0)
|
||||
}
|
||||
return;
|
||||
case EAST:
|
||||
p_maze->props[cellule] &= 253; // On enlève le mur à l'est (on met le 2ème bit à 0)
|
||||
neighbour = get_adj_maze(p_maze, cellule, EAST);
|
||||
if(neighbour != -1) {
|
||||
p_maze->props[neighbour] &= 247; // On enlève le mur à l'ouest de la cellule voisine (on met le 4ème bit à 0)
|
||||
}
|
||||
return;
|
||||
case SOUTH:
|
||||
p_maze->props[cellule] &= 251; // On enlève le mur au sud (on met le 3ème bit à 0)
|
||||
neighbour = get_adj_maze(p_maze, cellule, SOUTH);
|
||||
if(neighbour != -1) {
|
||||
p_maze->props[neighbour] &= 254; // On enlève le mur au nord de la cellule voisine (on met le 1er bit à 0)
|
||||
}
|
||||
return;
|
||||
case WEST:
|
||||
p_maze->props[cellule] &= 247; // On enlève le mur à l'ouest (on met le 4ème bit à 0)
|
||||
neighbour = get_adj_maze(p_maze, cellule, WEST);
|
||||
if(neighbour != -1) {
|
||||
p_maze->props[neighbour] &= 253; // On enlève le mur à l'est de la cellule voisine (on met le 2ème bit à 0)
|
||||
}
|
||||
return;
|
||||
default:
|
||||
fprintf(stderr, "build_wall_maze: cardinal inconnu\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_occupied_maze(maze *p_maze, const int cellule) {
|
||||
return p_maze->props[cellule] & 16; // Si la cellule est occupée (booléen stocké dans le 5ème bit)
|
||||
}
|
||||
|
||||
void make_occupied_maze(maze *p_maze, const int cellule) {
|
||||
p_maze->props[cellule] |= 16; // On marque la cellule comme occupée (on met le 5ème bit à 1)
|
||||
}
|
||||
void free_occupied_maze(maze *p_maze, const int cellule) {
|
||||
p_maze->props[cellule] &= 239; // On libère la cellule (on met le 5ème bit à 0)
|
||||
}
|
||||
|
||||
bool can_be_used(maze *p_maze, const int cellule) {
|
||||
return is_reach_maze(p_maze, cellule) && valid_maze(p_maze, cellule); // Si la cellule est utilisable
|
||||
}
|
||||
|
||||
|
||||
/************************/
|
||||
/*+ Gestion des objets +*/
|
||||
/************************/
|
||||
|
||||
|
||||
object get_object_maze(maze *p_maze, const int cellule) {
|
||||
//on ne vérifie pas si la cellule est valide
|
||||
return p_maze->objects[cellule]; // On retourne l'objet contenu dans la cellule
|
||||
}
|
||||
|
||||
|
||||
void add_object_maze(maze *p_maze, const int cellule, const object obj) {
|
||||
//on ne vérifie pas si la cellule ou l'objet sont valides
|
||||
p_maze->objects[cellule] = obj; // On ajoute un objet dans la cellule
|
||||
}
|
||||
|
||||
int get_exits_maze(maze *p_maze) {
|
||||
int exits = 0;
|
||||
for(int i = 0; i < p_maze->vsize * p_maze->hsize; i++)
|
||||
{
|
||||
if(get_object_maze(p_maze, i) == EXIT)
|
||||
{
|
||||
exits++;
|
||||
}
|
||||
}
|
||||
return exits;
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
/*+ Création d'un labyrinthe basique +*/
|
||||
/**************************************/
|
||||
|
||||
|
||||
maze* create_proto_maze_nomask(const int hsize, const int vsize) {
|
||||
maze *p_maze = malloc(sizeof(maze));
|
||||
//check sécurité
|
||||
if(p_maze == NULL) {
|
||||
fprintf(stderr, "create_proto_maze_nomask: erreur d'allocation\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
p_maze->hsize = hsize;
|
||||
p_maze->vsize = vsize;
|
||||
p_maze->props = malloc(hsize * vsize * sizeof(unsigned char));
|
||||
p_maze->objects = malloc(hsize * vsize * sizeof(object));
|
||||
//check sécurité
|
||||
if(p_maze->props == NULL || p_maze->objects == NULL) {
|
||||
fprintf(stderr, "create_proto_maze_nomask: erreur d'allocation\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
p_maze->nb_minotaurs = 0;
|
||||
p_maze->minotaurs = NULL;
|
||||
p_maze->nb_reachable = hsize * vsize; //puisqu'il n'y a pas de masque, toutes les cellules sont accessibles
|
||||
for(int i = 0; i < hsize * vsize; i++) {
|
||||
p_maze->props[i] = 79; // On initialise les propriétés des cellules (toutes les cellules sont murées dans les quatre directions, non occupées, non masquées et accessibles)
|
||||
p_maze->objects[i] = NONE; // On initialise les objets à NONE
|
||||
}
|
||||
const int i = rand() % (hsize * vsize);
|
||||
p_maze->player = i; // On place le joueur dans une cellule aléatoire
|
||||
make_occupied_maze(p_maze, i); // On marque la cellule comme occupée
|
||||
return p_maze;
|
||||
}
|
||||
|
||||
maze* create_proto_maze(mask *m) {
|
||||
maze *p_maze = malloc(sizeof(maze));
|
||||
//check sécurité
|
||||
if(p_maze == NULL) {
|
||||
fprintf(stderr, "create_proto_maze: erreur d'allocation\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
p_maze->vsize = m->vsize;
|
||||
p_maze->hsize = m->hsize;
|
||||
p_maze->props = malloc(m->vsize * m->hsize * sizeof(unsigned char));
|
||||
p_maze->objects = malloc(m->vsize * m->hsize * sizeof(object));
|
||||
//check sécurité
|
||||
if(p_maze->props == NULL || p_maze->objects == NULL) {
|
||||
fprintf(stderr, "create_proto_maze: erreur d'allocation\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
p_maze->nb_minotaurs = 0;
|
||||
p_maze->minotaurs = NULL;
|
||||
for(int i = 0; i < m->vsize * m->hsize; i++) {
|
||||
p_maze->props[i] = 15; // On initialise les murs (toutes les cellules sont murées dans les quatre directions)
|
||||
p_maze->objects[i] = NONE;
|
||||
if(m->grid[i]) {
|
||||
mask_cell_maze(p_maze, i); // On masque les cellules masquées
|
||||
}
|
||||
}
|
||||
int i = rand() % (m->vsize * m->hsize); // NOLINT(*-msc50-cpp)
|
||||
while(!valid_maze(p_maze, i)) // On placera le joueur dans une cellule aléatoire valide
|
||||
{
|
||||
i = rand() % (m->vsize * m->hsize); // NOLINT(*-msc50-cpp)
|
||||
}
|
||||
p_maze->player = i; // On place le joueur dans une cellule aléatoire
|
||||
queue *q = create_queue();
|
||||
enqueue(i, q);
|
||||
make_reach_maze(p_maze, i); // On marque la cellule comme accessible
|
||||
p_maze->nb_reachable = 1;
|
||||
while(!is_empty_queue(q)) {
|
||||
i = dequeue(q);
|
||||
for(cardinal c = NORTH; c < 4; c++) {
|
||||
const int neighbour = get_adj_maze(p_maze, i, c);
|
||||
if(valid_maze(p_maze, neighbour) && !is_reach_maze(p_maze, neighbour)) {
|
||||
enqueue(neighbour, q);
|
||||
make_reach_maze(p_maze, neighbour); // On marque les cellules accessibles
|
||||
p_maze->nb_reachable++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return p_maze;
|
||||
}
|
||||
|
||||
void free_maze(maze *p_maze) {
|
||||
free(p_maze->objects);
|
||||
free(p_maze->props);
|
||||
free(p_maze->minotaurs);
|
||||
free(p_maze);
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/*+ Gestion des minotaures +*/
|
||||
/****************************/
|
||||
|
||||
int has_minotaur_maze(maze *p_maze, const int cellule) {
|
||||
for(int i = 0; i < p_maze->nb_minotaurs; i++) {
|
||||
if(p_maze->minotaurs[i] == cellule) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gen_minotaurs_maze(maze *p_maze, int nb_minotaurs) {
|
||||
//la boucle aléatoire est plutôt lourde, on pourrait l'alléger en utilisant un tableau de booléens par exemple
|
||||
if(p_maze->minotaurs)
|
||||
{
|
||||
free(p_maze->minotaurs);
|
||||
}
|
||||
if(nb_minotaurs > p_maze -> hsize * p_maze -> vsize - 1) { // Si le nombre de minotaures est supérieur au nombre de cellules - 1
|
||||
nb_minotaurs = p_maze -> hsize * p_maze -> vsize - 1; // On réduit au maximum disponible
|
||||
}
|
||||
p_maze->nb_minotaurs = nb_minotaurs;
|
||||
p_maze->minotaurs = malloc(nb_minotaurs * sizeof(int));
|
||||
//check sécurité
|
||||
if(p_maze->minotaurs == NULL) {
|
||||
fprintf(stderr, "gen_minotaurs_maze: erreur d'allocation\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int cellule;
|
||||
for(int i = 0; i < nb_minotaurs; i++) {
|
||||
do{
|
||||
cellule = rand() % (p_maze->vsize * p_maze->hsize); // NOLINT(*-msc50-cpp)
|
||||
}
|
||||
while(!valid_maze(p_maze, cellule) || is_occupied_maze(p_maze, cellule) || !is_reach_maze(p_maze, cellule)); // On place les minotaures dans des cellules aléatoires valides et non occupées
|
||||
p_maze->minotaurs[i] = cellule; // On place le minotaure dans la cellule
|
||||
make_occupied_maze(p_maze, cellule); // On marque la cellule comme occupée
|
||||
}
|
||||
}
|
||||
|
||||
/********************************/
|
||||
/*+ Récupération d'information +*/
|
||||
/********************************/
|
||||
|
||||
bool valid_move_maze(maze *p_maze, const int cellule, const move mv)
|
||||
{
|
||||
if(mv == M_WAIT)
|
||||
{
|
||||
return true; // Si on est sur une cellule, c'est qu'elle est valide
|
||||
}
|
||||
const int neighbour = get_adj_maze(p_maze, cellule, (cardinal)mv);
|
||||
if(neighbour == -1) {
|
||||
return false; // Si il n'y a pas de cellule adjacente dans la direction donnée, le mouvement n'est pas valide
|
||||
}
|
||||
return !has_wall_maze(p_maze, cellule, (cardinal)mv) && can_be_used(p_maze, neighbour) && !is_occupied_maze(p_maze, neighbour);
|
||||
// Si il n'y a pas de mur, que la cellule adjacente est valide et non occupée, le mouvement est valide
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user