This commit is contained in:
Leo Firmin 2025-10-08 17:07:41 +02:00
parent a3e025e6b9
commit 2fa3015af4
29 changed files with 744 additions and 584 deletions

View File

@ -1,5 +1,5 @@
CC = gcc CC = gcc
CFLAGS = -Wall -Wextra -Werror CFLAGS = -fsanitize=address -g -Wall -Wextra -Werror
NAME = cub3d NAME = cub3d
SRCDIR = srcs SRCDIR = srcs
@ -17,12 +17,11 @@ SRCS = $(SRCDIR)/main.c \
$(SRCDIR)/parsing/check_colors.c \ $(SRCDIR)/parsing/check_colors.c \
$(SRCDIR)/utils/utils.c \ $(SRCDIR)/utils/utils.c \
$(SRCDIR)/utils/init.c \ $(SRCDIR)/utils/init.c \
$(SRCDIR)/utils/debug.c \
$(SRCDIR)/parsing/check_map.c \ $(SRCDIR)/parsing/check_map.c \
$(SRCDIR)/parsing/check_map_2.c \
INCS = $(INCDIR)/parsing.h \ INCS = $(INCDIR)/parsing.h \
$(INCDIR)/cub.h \ $(INCDIR)/cub.h \
$(INCDIR)/messages.h \
all: $(NAME) all: $(NAME)

BIN
cub3d

Binary file not shown.

View File

@ -16,9 +16,8 @@ INCS_DIR = includes/
OBJ_DIR = obj/ OBJ_DIR = obj/
SRC = get_next_line.c get_next_line_utils.c SRC = get_next_line.c get_next_line_utils.c
CC = cc CC = cc
CFLAGS = -Wall -Wextra -Werror CFLAGS = -Wall -Wextra -Werror -fPIE
INCLUDE = -I $(INCS_DIR) INCLUDE = -I $(INCS_DIR)
SRCS = $(addprefix $(SRCS_DIR), $(SRC)) SRCS = $(addprefix $(SRCS_DIR), $(SRC))
OBJ = $(addprefix $(OBJ_DIR), $(SRC:.c=.o)) OBJ = $(addprefix $(OBJ_DIR), $(SRC:.c=.o))

BIN
gnl/gnl.a

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,30 +1,57 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cub.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 14:56:25 by lfirmin #+# #+# */
/* Updated: 2025/10/07 12:14:42 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef CUB_H #ifndef CUB_H
#define CUB_H
#include "parsing.h" # define CUB_H
#include "messages.h"
#include "../libft/include/libft.h" # include "parsing.h"
#include "../gnl/include/get_next_line.h" # include "../libft/include/libft.h"
# include "../gnl/include/get_next_line.h"
# define ERROR_PREFIX "Error\n"
# define ERROR_EXT "Invalid file extension. Only .cub files are accepted."
# define ERROR_EMPT_PATH "Invalid map file path."
# define ERROR_INIT_DATA "Initialization of the data structure failed."
# define ERROR_INIT_TEX "Initialization of the textures structure failed."
# define ERROR_INIT_PARS "Initialization of the parsing structure failed."
# define ERROR_EMPTY "You have provided an empty file."
# define ERROR_COL "The RGB values provided are not valid or absent."
# define ERROR_NULL_P "Player not found or multiple players."
# define ERROR_BAD_CHAR "Invalid character in map."
# define ERROR_POS "Player position not found."
# define ERROR_ALLOC "Allocation failed."
# define ERROR_PLAYER "Player not found or multiple players."
# define ERROR_CHAR "Invalid character in map."
# define ERROR_DOUBLE "Multiple images/colors have been provided \
for the same texture."
# define ERROR_NOT_CLOSE "Map is not closed by walls."
# define ERROR_NOT_XMP "The texture file is not an xpm image."
typedef struct s_data typedef struct s_data
{ {
char **map; char **map;
char *map_path; char *map_path;
t_textures *texture; t_textures *texture;
t_data_parsing parsing; t_data_parsing parsing;
} t_data; } t_data;
//////utils/////
//utils //utils
void ft_error(char *message); void ft_error(char *message);
void free_char_array(char **array); void free_char_array(char **array);
int ft_arrlen(char **arr); int ft_arrlen(char **arr);
void print_array(char **array);//temp
//init //init
int init_data(t_data *data, char *path); int init_data(t_data *data, char *path);
void free_data(t_data *data); void free_data(t_data *data);
/////debug #endif
void print_char_array_debug(char **arr, char *name);
#endif

View File

@ -1,31 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* messages.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 15:00:45 by lfirmin #+# #+# */
/* Updated: 2025/08/22 15:01:20 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MESSAGE_H
#define MESSAGE_H
#define ERROR_PREFIX "\033[1m[❌]\033[0m\033[1;31mError\033[0m: "
#define ERROR_EXT "Invalid file extension. Only .cub files are accepted."
#define ERROR_EMPT_PATH "Invalid map file path."
#define ERROR_INIT_DATA "Initialization of the data structure failed."
#define ERROR_INIT_TEX "Initialization of the textures structure failed."
#define ERROR_INIT_PARS "Initialization of the parsing structure failed."
#define ERROR_EMPTY "You have provided an empty file."
#define ERROR_COL "The RGB values provided are not valid."
#define ERROR_NULL_P "Player not found or multiple players."
#define ERROR_BAD_CHAR "Invalid character in map."
#define ERROR_POS "Player position not found."
#define ERROR_ALLOC "Allocation failed."
#define ERROR_PLAYER "Player not found or multiple players."
#define ERROR_CHAR "Invalid character in map."
#define ERROR_NOT_CLOSE "Map is not closed by walls."
#define DEBUG "test"
#endif

View File

@ -6,71 +6,84 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 14:08:04 by lfirmin #+# #+# */ /* Created: 2025/08/22 14:08:04 by lfirmin #+# #+# */
/* Updated: 2025/08/22 14:18:06 by lfirmin ### ########.fr */ /* Updated: 2025/10/07 12:16:07 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#ifndef PARSING_H #ifndef PARSING_H
#define PARSING_H # define PARSING_H
#include <stdio.h> # include <stdio.h>
#include <stdlib.h> # include <stdlib.h>
#include <unistd.h> # include <unistd.h>
#include <fcntl.h> # include <fcntl.h>
struct s_data; struct s_data;
typedef struct s_data t_data; typedef struct s_data t_data;
typedef struct s_textures typedef struct s_textures
{ {
char *north; //Path to texture.xmp char *north;
char *south; //Path to texture.xmp char *south;
char *east; //Path to texture.xmp char *east;
char *west; //Path to texture.xmp char *west;
int floor[3]; //RGB: [0] = R, [1] = G, [2] = B int floor[3];
int ceiling[3]; //RGB: [0] = R, [1] = G, [2] = B int ceiling[3];
} t_textures; } t_textures;
typedef struct s_data_parsing typedef struct s_data_parsing
{ {
char **raw_map; char **raw_map;
int fd_map; int fd_map;
int fd_map_dup; int fd_map_dup;
int player[3]; int player[3];
} t_data_parsing; } t_data_parsing;
//player -> 0 = x, 1 = y, 2 = head
//parsing //parsing
int parsing(t_data *data); int parsing(t_data *data);
//check_file //check_file
int check_extension(char *map_path); int check_extension(char *map_path);
int check_file(char *map_path, t_data_parsing *parsing); int check_file(char *map_path, t_data_parsing *parsing);
//get_map //get_map
int get_map(t_data *data); int get_map(t_data *data);
int line_counter(int fd); int line_counter(int fd);
int put_map_on_array(t_data *data); int put_map_on_array(t_data *data);
char *clean_line(char *raw_line); char *clean_line(char *raw_line);
//init_parsing //init_parsing
int init_parsing(t_data_parsing *parsing); int init_parsing(t_data_parsing *parsing);
int init_textures(t_textures *textures); int init_textures(t_textures *textures);
int free_textures(t_textures *textures); int free_textures(t_textures *textures);
//line_detect //line_detect
int is_config_line(char *line); int is_config_line(char *line);
int is_empty_line(char *line); int is_empty_line(char *line);
int is_texture_line(char *line); int is_texture_line(char *line);
int is_color_line(char *line); int is_color_line(char *line);
int check_extension_2(char *str);
//get_textures //get_textures
int get_texture_path(char *line, t_textures *texture); int get_texture_path(char *line, t_textures *texture, int *j);
int get_rgb_values(char *line, int rgb[3]); int validate_and_convert_rgb(char **parts, int rgb[3]);
int get_rgb_values(char *line, int rgb[3]);
int is_valid_number(char *str);
//check_colors //check_colors
int check_colors(t_textures *texture); int check_colors(t_textures *texture);
int is_rgb(int color[3]); int is_rgb(int color[3]);
// check_mao // check_map
int validate_map(char **map, int *player); int check_map_char(char **map);
#endif void find_player_pos(char **map, int *player);
int flood_fill(char **map_cp, int x, int y);
int rep_ex_wall(char **map_cp, int x, int y);
int check_char_and_count(char c, int *p);
//check_map_2
int hasivalidchar(char **map);
int validate_map(char **map, int *player);
#endif

View File

@ -23,7 +23,7 @@ SRC = ft_isalnum.c ft_isprint.c ft_memcmp.c ft_putchar_fd.c ft_split.c \
ft_lstnew_bonus.c ft_lstadd_front_bonus.c ft_lstsize_bonus.c \ ft_lstnew_bonus.c ft_lstadd_front_bonus.c ft_lstsize_bonus.c \
ft_lstlast_bonus.c ft_lstadd_back_bonus.c ft_lstdelone_bonus.c \ ft_lstlast_bonus.c ft_lstadd_back_bonus.c ft_lstdelone_bonus.c \
ft_lstclear_bonus.c ft_lstiter_bonus.c ft_lstmap_bonus.c ft_strcmp.c \ ft_lstclear_bonus.c ft_lstiter_bonus.c ft_lstmap_bonus.c ft_strcmp.c \
ft_atoll.c ft_straddchar.c ft_strcpy.c ft_atoll.c ft_straddchar.c ft_strcpy.c ft_arrcpy.c
SRCS = $(addprefix $(SRCS_DIR), $(SRC)) SRCS = $(addprefix $(SRCS_DIR), $(SRC))
CC = cc CC = cc

View File

@ -83,6 +83,7 @@ char *ft_strmapi(char const *s, char (*f)(unsigned int, char));
char *ft_itoa(int n); char *ft_itoa(int n);
char *ft_straddchar(char *str, char c); char *ft_straddchar(char *str, char c);
char *ft_strcpy(char *dest, char *src); char *ft_strcpy(char *dest, char *src);
char **ft_arrcpy(char **array);
t_list *ft_lstnew(void *content); t_list *ft_lstnew(void *content);
t_list *ft_lstlast(t_list *lst); t_list *ft_lstlast(t_list *lst);

Binary file not shown.

BIN
libft/obj/ft_arrcpy.o Normal file

Binary file not shown.

Binary file not shown.

41
libft/srcs/ft_arrcpy.c Normal file
View File

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_arrcpy.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 02:18:17 by lfirmin #+# #+# */
/* Updated: 2025/10/06 14:06:37 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char **ft_arrcpy(char **array)
{
char **copy;
int i;
int len;
len = 0;
while (array[len])
len++;
copy = malloc(sizeof(char *) * (len + 1));
if (!copy)
return (NULL);
i = 0;
while (i < len)
{
copy[i] = strdup(array[i]);
if (!copy[i])
{
while (i > 0)
free(copy[--i]);
free(copy);
return (NULL);
}
i++;
}
copy[i] = NULL;
return (copy);
}

View File

@ -1,11 +1,61 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 14:56:25 by lfirmin #+# #+# */
/* Updated: 2025/10/08 16:25:42 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "cub.h" #include "cub.h"
int main(int ac, char **av) void print_int_array(int *array, int size)
{ {
t_data data; int i;
init_data(&data, av[1]);
parsing(&data); if (!array)
free_char_array(data.parsing.raw_map); return ;
free_textures(data.texture); i = 0;
free_data(&data); while (i < size)
} {
ft_putnbr_fd(array[i], 1);
if (i < size - 1)
write(1, ", ", 2);
i++;
}
write(1, "\n", 1);
}
void debug(t_data data)
{
printf("map:\n\n");
print_array(data.map);
printf("\n");
printf("c: ");
fflush(stdout);
print_int_array(data.texture->ceiling, 3);
printf("f: ");
fflush(stdout);
print_int_array(data.texture->floor, 3);
printf("p: ");
fflush(stdout);
print_int_array(data.parsing.player, 3);
printf("\n");
printf("\ntexture:\n\n");
printf("%s\n", data.texture->east);
printf("%s\n", data.texture->north);
printf("%s\n", data.texture->west);
printf("%s\n", data.texture->south);
}
int main(int ac, char **av)
{
t_data data;
init_data(&data, av[1]);
if (parsing(&data));
debug(data);
free_char_array(data.parsing.raw_map);
free_textures(data.texture);
free_data(&data);
}

View File

@ -6,30 +6,30 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/25 18:41:26 by lfirmin #+# #+# */ /* Created: 2025/08/25 18:41:26 by lfirmin #+# #+# */
/* Updated: 2025/08/25 18:41:26 by lfirmin ### ########.fr */ /* Updated: 2025/10/07 10:06:32 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
int check_colors(t_textures *texture) int check_colors(t_textures *texture)
{ {
if (is_rgb(texture->floor)) if (is_rgb(texture->floor))
return (ft_error(ERROR_COL), 1); return (ft_error(ERROR_COL), 1);
if (is_rgb(texture->ceiling)) if (is_rgb(texture->ceiling))
return (ft_error(ERROR_COL), 1); return (ft_error(ERROR_COL), 1);
return (0); return (0);
} }
int is_rgb(int color[3]) int is_rgb(int color[3])
{ {
int i; int i;
i = 0; i = 0;
while (i < 3) while (i < 3)
{ {
if (color[i] > 255 || color[i] < 0) if (color[i] > 255 || color[i] < 0)
return (1); return (1);
i++; i++;
} }
return (0); return (0);
} }

View File

@ -6,35 +6,35 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 15:07:29 by lfirmin #+# #+# */ /* Created: 2025/08/22 15:07:29 by lfirmin #+# #+# */
/* Updated: 2025/08/22 15:07:33 by lfirmin ### ########.fr */ /* Updated: 2025/10/07 10:11:50 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
int check_file(char *map_path, t_data_parsing *parsing) int check_file(char *map_path, t_data_parsing *parsing)
{ {
if (!map_path) if (!map_path)
return (ft_error(ERROR_EMPT_PATH), 1); return (ft_error(ERROR_EMPT_PATH), 1);
if (check_extension(map_path)) if (check_extension(map_path))
return (1); return (1);
parsing->fd_map = open(map_path, O_RDONLY); parsing->fd_map = open(map_path, O_RDONLY);
if (parsing->fd_map < 0) if (parsing->fd_map < 0)
return (perror("\033[1m[❌]\033[0m\033[1;31mError\033[0m"), 1); return (perror("Error\n"), 1);
parsing->fd_map_dup = open(map_path, O_RDONLY); parsing->fd_map_dup = open(map_path, O_RDONLY);
if (parsing->fd_map_dup < 0) if (parsing->fd_map_dup < 0)
return (perror("\033[1m[❌]\033[0m\033[1;31mError\033[0m"), 1); return (perror("Error\n"), 1);
return (0); return (0);
} }
int check_extension(char *map_path) int check_extension(char *map_path)
{ {
int len_map_path; int len_map_path;
len_map_path = ft_strlen(map_path); len_map_path = ft_strlen(map_path);
if (len_map_path < 4) if (len_map_path < 4)
return (ft_error(ERROR_EXT), 1); return (ft_error(ERROR_EXT), 1);
if (ft_strcmp(map_path + len_map_path - 4, ".cub") != 0) if (ft_strcmp(map_path + len_map_path - 4, ".cub") != 0)
return (ft_error(ERROR_EXT), 1); return (ft_error(ERROR_EXT), 1);
return (0); return (0);
} }

View File

@ -1,157 +1,123 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_map.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 15:07:29 by lfirmin #+# #+# */
/* Updated: 2025/10/07 10:11:50 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "cub.h" #include "cub.h"
int has_playable_neighbor(int x, int y, char **map) int check_char_and_count(char c, int *p)
{ {
if (map[y] && map[y][x + 1] && if (c == '1' || c == '0' || c == ' ' || c == '\n')
(map[y][x + 1] == '0' || map[y][x + 1] == 'N' || return (0);
map[y][x + 1] == 'S' || map[y][x + 1] == 'E' || else if (c == 'S' || c == 'N' || c == 'E' || c == 'W')
map[y][x + 1] == 'W')) {
return (1); (*p)++;
if (x > 0 && map[y][x - 1] && return (0);
(map[y][x - 1] == '0' || map[y][x - 1] == 'N' || }
map[y][x - 1] == 'S' || map[y][x - 1] == 'E' || else
map[y][x - 1] == 'W')) return (2);
return (1);
if (map[y + 1] && map[y + 1][x] &&
(map[y + 1][x] == '0' || map[y + 1][x] == 'N' ||
map[y + 1][x] == 'S' || map[y + 1][x] == 'E' ||
map[y + 1][x] == 'W'))
return (1);
if (y > 0 && map[y - 1] && map[y - 1][x] &&
(map[y - 1][x] == '0' || map[y - 1][x] == 'N' ||
map[y - 1][x] == 'S' || map[y - 1][x] == 'E' ||
map[y - 1][x] == 'W'))
return (1);
return (0);
} }
int check_isolated_walls(char **map) int check_map_char(char **map)
{ {
int i = 0; int i;
int j; int j;
int p;
while (map[i]) int ret;
{
j = 0; i = 0;
while (map[i][j]) p = 0;
{ while (map[i])
if (map[i][j] == '1') {
{ j = 0;
if (!has_playable_neighbor(j, i, map)) while (map[i][j])
return (0); // '1' isolé détecté {
} ret = check_char_and_count(map[i][j], &p);
j++; if (ret != 0)
} return (ret);
i++; j++;
} }
return (1); // Pas de '1' isolé i++;
}
if (p != 1)
return (1);
return (0);
} }
int check_map_char(char **map) void find_player_pos(char **map, int *player)
{ {
int i = 0; int i;
int j; int j;
int p = 0;
i = 0;
while (map[i]) while (map[i])
{ {
j = 0; j = 0;
while (map[i][j]) while (map[i][j])
{ {
if (map[i][j] == '1' || map[i][j] == '0' || if (map[i][j] == 'S' || map[i][j] == 'N' ||
map[i][j] == ' ' || map[i][j] == '\n') map[i][j] == 'E' || map[i][j] == 'W')
j++; {
else if (map[i][j] == 'S' || map[i][j] == 'N' || player[0] = j;
map[i][j] == 'E' || map[i][j] == 'W') player[1] = i;
{ player[2] = map[i][j];
j++; return ;
p++; }
} j++;
else }
return (2); i++;
} }
i++;
}
if (p != 1)
return (1);
return (0);
} }
void find_player_pos(char **map, int *player) int flood_fill(char **map_cp, int x, int y)
{ {
int i = 0; if (!map_cp[y] || !map_cp[y][x])
int j; return (1);
if (map_cp[y][x] == 'v')
while (map[i]) return (0);
{ if (map_cp[y][x] == '1')
j = 0; {
while (map[i][j]) map_cp[y][x] = 'v';
{ return (0);
if (map[i][j] == 'S' || map[i][j] == 'N' || }
map[i][j] == 'E' || map[i][j] == 'W') if (map_cp[y][x] == '0' || map_cp[y][x] == 'N' || map_cp[y][x] == 'S'
{ || map_cp[y][x] == 'E' || map_cp[y][x] == 'W')
player[0] = j; {
player[1] = i; map_cp[y][x] = 'v';
player[2] = map[i][j]; if (flood_fill(map_cp, x + 1, y))
return; return (1);
} if (flood_fill(map_cp, x - 1, y))
j++; return (1);
} if (flood_fill(map_cp, x, y + 1))
i++; return (1);
} if (flood_fill(map_cp, x, y - 1))
return (1);
return (0);
}
return (1);
} }
int is_closed_at(int x, int y, char **map) int rep_ex_wall(char **map_cp, int x, int y)
{ {
if (!map[y] || !map[y][x] || map[y][x] == '\0') if (y < 0 || x < 0)
return (0); return (0);
if (map[y][x] == ' ') if (!map_cp[y] || !map_cp[y][x])
return (0); return (0);
return (1); if (map_cp[y][x] == '1')
map_cp[y][x] = 'v';
if (map_cp[y][x] == 'v')
{
map_cp[y][x] = 'c';
rep_ex_wall(map_cp, x + 1, y);
rep_ex_wall(map_cp, x - 1, y);
rep_ex_wall(map_cp, x, y + 1);
rep_ex_wall(map_cp, x, y - 1);
}
return (0);
} }
int check_walls(char **map)
{
int i = 0;
int j;
while (map[i])
{
j = 0;
while (map[i][j])
{
if (map[i][j] == '0' || map[i][j] == 'N' ||
map[i][j] == 'S' || map[i][j] == 'E' || map[i][j] == 'W')
{
if (!is_closed_at(j + 1, i, map) ||
!is_closed_at(j - 1, i, map) ||
!is_closed_at(j, i + 1, map) ||
!is_closed_at(j, i - 1, map))
return (0);
}
j++;
}
i++;
}
return (1);
}
int validate_map(char **map, int *player)
{
int result;
result = check_map_char(map);
if (result == 1)
return (ft_error(ERROR_PLAYER), 1);
if (result == 2)
return (ft_error(ERROR_CHAR), 1);
find_player_pos(map, player);
if (!check_walls(map))
return (ft_error(ERROR_NOT_CLOSE), 1);
// if (!check_isolated_walls(map))
// return (ft_error("Isolated wall detected"), 1);
return (0);
}

View File

@ -0,0 +1,54 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_map_2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 15:07:29 by lfirmin #+# #+# */
/* Updated: 2025/10/07 12:09:03 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "cub.h"
int hasinvalidchar(char **map)
{
int y;
int x;
y = 0;
while (map[y])
{
x = 0;
while (map[y][x])
{
if (map[y][x] != 'c' && map[y][x] != ' ' && map[y][x] != ' '
&& map[y][x] != '\n')
return (1);
x++;
}
y++;
}
return (0);
}
int validate_map(char **map, int *player)
{
int result;
char **map_cp;
map_cp = ft_arrcpy(map);
result = check_map_char(map);
if (result == 1)
return (free_char_array(map_cp), ft_error(ERROR_PLAYER), 1);
if (result == 2)
return (free_char_array(map_cp), ft_error(ERROR_CHAR), 1);
find_player_pos(map, player);
if (flood_fill(map_cp, player[0], player[1]))
return (free_char_array(map_cp), ft_error(ERROR_NOT_CLOSE), 1);
rep_ex_wall(map_cp, player[0], player[1]);
if (hasinvalidchar(map_cp))
return (free_char_array(map_cp), ft_error(ERROR_CHAR), 1);
free_char_array(map_cp);
return (0);
}

View File

@ -6,80 +6,89 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/23 13:29:28 by lfirmin #+# #+# */ /* Created: 2025/08/23 13:29:28 by lfirmin #+# #+# */
/* Updated: 2025/08/23 13:29:28 by lfirmin ### ########.fr */ /* Updated: 2025/10/07 10:13:07 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
int get_map(t_data *data) int get_map(t_data *data)
{ {
int nb_line; int nb_line;
nb_line = line_counter(data->parsing.fd_map); nb_line = line_counter(data->parsing.fd_map);
if (nb_line <= 0) if (nb_line <= 0)
return (ft_error(ERROR_EMPTY), 1); return (ft_error(ERROR_EMPTY), 1);
data->parsing.raw_map = ft_calloc(nb_line + 1, sizeof(char*)); data->parsing.raw_map = ft_calloc(nb_line + 1, sizeof(char *));
put_map_on_array(data); if (put_map_on_array(data))
//print_char_array_debug(data->parsing.raw_map, "debug"); return (1);
//printf("---deb_texture---\n%s\n%s\n%s\n%s\n", data->texture->north, data->texture->south, data->texture->west, data->texture->east); return (0);
// printf("---deb_colors_f---\n%d,%d,%d\n", data->texture->floor[0], data->texture->floor[1], data->texture->floor[2]);
// printf("---deb_colors_c---\n%d,%d,%d\n", data->texture->ceiling[0], data->texture->ceiling[1], data->texture->ceiling[2]);
return (0);
} }
int line_counter(int fd) int line_counter(int fd)
{ {
int nb_line; int nb_line;
char *line; char *line;
line = NULL; line = NULL;
nb_line = 0; nb_line = 0;
while ((line = get_next_line(fd)) != NULL) line = get_next_line(fd);
{ while (line != NULL)
nb_line++; {
free(line); nb_line++;
} free(line);
free(line); line = get_next_line(fd);
line = get_next_line(-1); // force cleanup }
free(line); free(line);
return (nb_line); line = get_next_line(-1);
free(line);
return (nb_line);
} }
int put_map_on_array(t_data *data) int put_map_on_array(t_data *data)
{ {
char *line; char *line;
char *cleaned; char *cleaned;
int i; int i;
int j[6];
i = 0; ft_memset(j, 0, sizeof(j));
while ((line = get_next_line(data->parsing.fd_map_dup)) != NULL) i = 0;
{ while ((line = get_next_line(data->parsing.fd_map_dup)) != NULL)
if (is_config_line(line)) {
{ if (is_config_line(line))
cleaned = clean_line(line); {
get_texture_path(cleaned, data->texture); cleaned = clean_line(line);
free(line); if (get_texture_path(cleaned, data->texture, j))
free(cleaned); {
} free(line);
else if (is_empty_line(line)) free(cleaned);
free(line); line = get_next_line(-1);
else if (line)
data->parsing.raw_map[i++] = line; free(line);
} return (1);
line = get_next_line(-1); }
if (line) free(line);
free(line); free(cleaned);
data->parsing.raw_map[i] = NULL; }
return (0); else if (is_empty_line(line) && i == 0)
free(line);
else
data->parsing.raw_map[i++] = line;
}
line = get_next_line(-1);
if (line)
free(line);
data->parsing.raw_map[i] = NULL;
return (0);
} }
char *clean_line(char *raw_line) char *clean_line(char *raw_line)
{ {
char *cleaned; char *cleaned;
if (!raw_line)
return (NULL);
cleaned = ft_strtrim(raw_line, " \t\n\r"); if (!raw_line)
return (cleaned); return (NULL);
} cleaned = ft_strtrim(raw_line, " \t\n\r");
return (cleaned);
}

View File

@ -6,48 +6,86 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/24 12:37:11 by lfirmin #+# #+# */ /* Created: 2025/08/24 12:37:11 by lfirmin #+# #+# */
/* Updated: 2025/08/24 12:37:11 by lfirmin ### ########.fr */ /* Updated: 2025/10/07 10:13:41 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
int get_texture_path(char *line, t_textures *texture) int get_texture_path(char *line, t_textures *texture, int *j)
{ {
if (is_texture_line(line) == 1) if (check_extension_2(line) && !is_color_line(line))
texture->north = ft_strtrim(line + 2, " \t\n\r"); return (ft_error(ERROR_NOT_XMP), 1);
else if (is_texture_line(line) == 2) else if (is_texture_line(line) == 1 && j[0]++ == 0)
texture->south = ft_strtrim(line + 2, " \t\n\r"); texture->north = ft_strtrim(line + 2, " \t\n\r");
else if (is_texture_line(line) == 3) else if (is_texture_line(line) == 2 && j[1]++ == 0)
texture->west = ft_strtrim(line + 2, " \t\n\r"); texture->south = ft_strtrim(line + 2, " \t\n\r");
else if (is_texture_line(line) == 4) else if (is_texture_line(line) == 3 && j[2]++ == 0)
texture->east = ft_strtrim(line + 2, " \t\n\r"); texture->west = ft_strtrim(line + 2, " \t\n\r");
else if (is_color_line(line) == 1) // F else if (is_texture_line(line) == 4 && j[3]++ == 0)
get_rgb_values(line, texture->floor); texture->east = ft_strtrim(line + 2, " \t\n\r");
else if (is_color_line(line) == 2) // C else if (is_color_line(line) == 1 && j[4]++ == 0)
get_rgb_values(line, texture->ceiling); get_rgb_values(line, texture->floor);
return (0); else if (is_color_line(line) == 2 && j[5]++ == 0)
get_rgb_values(line, texture->ceiling);
else
return (ft_error(ERROR_DOUBLE), 2);
return (0);
} }
int get_rgb_values(char *line, int rgb[3]) int is_valid_number(char *str)
{ {
char *start; int i;
char **parts;
int i;
if (!line || !rgb) if (!str || !*str)
return (1); return (0);
start = ft_strchr(line, ' '); i = 0;
if (!start) while (str[i] == ' ' || str[i] == '\t')
return (1); i++;
parts = ft_split(start + 1, ','); if (!str[i] || !(str[i] >= '0' && str[i] <= '9'))
if (!parts) return (0);
return (1); while (str[i] >= '0' && str[i] <= '9')
i = 0; i++;
while (parts[i] && i < 3) while (str[i] == ' ' || str[i] == '\t')
{ i++;
rgb[i] = ft_atoi(parts[i]); if (str[i] != '\0')
i++; return (0);
} return (1);
free_char_array(parts); }
return (i == 3 ? 0 : 1);
} int validate_and_convert_rgb(char **parts, int rgb[3])
{
int i;
i = -1;
while (++i < 3)
{
if (!is_valid_number(parts[i]))
return (free_char_array(parts), 1);
rgb[i] = ft_atoi(parts[i]);
if (rgb[i] < 0 || rgb[i] > 255)
return (free_char_array(parts), 1);
}
return (free_char_array(parts), 0);
}
int get_rgb_values(char *line, int rgb[3])
{
char *start;
char **parts;
int i;
if (!line || !rgb)
return (1);
start = ft_strchr(line, ' ');
if (!start)
return (1);
parts = ft_split(start + 1, ',');
if (!parts)
return (1);
i = 0;
while (parts[i])
i++;
if (i != 3)
return (free_char_array(parts), 1);
return (validate_and_convert_rgb(parts, rgb));
}

View File

@ -6,45 +6,45 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/23 13:33:00 by lfirmin #+# #+# */ /* Created: 2025/08/23 13:33:00 by lfirmin #+# #+# */
/* Updated: 2025/08/23 13:33:00 by lfirmin ### ########.fr */ /* Updated: 2025/10/07 10:14:37 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
int init_parsing(t_data_parsing *parsing) int init_parsing(t_data_parsing *parsing)
{ {
if (!parsing) if (!parsing)
return (ft_error(ERROR_INIT_PARS), 1); return (ft_error(ERROR_INIT_PARS), 1);
parsing->fd_map = 0; parsing->fd_map = 0;
parsing->raw_map = NULL; parsing->raw_map = NULL;
return (0); return (0);
} }
int init_textures(t_textures *textures) int init_textures(t_textures *textures)
{ {
int i; int i;
if (!textures) if (!textures)
return (ft_error(ERROR_INIT_TEX), 1); return (ft_error(ERROR_INIT_TEX), 1);
textures->north = NULL; textures->north = NULL;
textures->south = NULL; textures->south = NULL;
textures->east = NULL; textures->east = NULL;
textures->west = NULL; textures->west = NULL;
i = 0; i = 0;
while (i < 3) while (i < 3)
{ {
textures->floor[i] = -1; textures->floor[i] = -1;
textures->ceiling[i] = -1; textures->ceiling[i] = -1;
i++; i++;
} }
return (0); return (0);
} }
int free_textures(t_textures *textures) int free_textures(t_textures *textures)
{ {
free(textures->north); free(textures->north);
free(textures->south); free(textures->south);
free(textures->east); free(textures->east);
free(textures->west); free(textures->west);
return (0); return (0);
} }

View File

@ -6,89 +6,99 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/24 11:58:39 by lfirmin #+# #+# */ /* Created: 2025/08/24 11:58:39 by lfirmin #+# #+# */
/* Updated: 2025/08/24 11:58:39 by lfirmin ### ########.fr */ /* Updated: 2025/10/08 14:05:47 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
int is_config_line(char *line) int check_extension_2(char *str)
{ {
char *trimmed; size_t len;
int result;
result = 0; len = strlen(str);
if (!line) if (len < 4)
return (0); return (1);
trimmed = ft_strtrim(line, " \t\n\r"); return (ft_strcmp(str + len - 4, ".xpm"));
if (!trimmed)
return (0);
if (ft_strncmp(trimmed, "NO ", 3) == 0 ||
ft_strncmp(trimmed, "SO ", 3) == 0 ||
ft_strncmp(trimmed, "WE ", 3) == 0 ||
ft_strncmp(trimmed, "EA ", 3) == 0 ||
ft_strncmp(trimmed, "F ", 2) == 0 ||
ft_strncmp(trimmed, "C ", 2) == 0)
result = 1;
free(trimmed);
return (result);
} }
int is_empty_line(char *line) int is_config_line(char *line)
{ {
int i; char *trimmed;
int result;
i = 0; result = 0;
if (!line) if (!line)
return (1); // NULL = vide return (0);
while (line[i]) trimmed = ft_strtrim(line, " \t\n\r");
{ if (!trimmed)
if (line[i] != ' ' && line[i] != '\t' && return (0);
line[i] != '\n' && line[i] != '\r') if (ft_strncmp(trimmed, "NO ", 3) == 0
return (0); || ft_strncmp(trimmed, "SO ", 3) == 0
i++; || ft_strncmp(trimmed, "WE ", 3) == 0
} || ft_strncmp(trimmed, "EA ", 3) == 0
return (1); // Que des whitespaces || ft_strncmp(trimmed, "F ", 2) == 0
|| ft_strncmp(trimmed, "C ", 2) == 0)
result = 1;
free(trimmed);
return (result);
} }
int is_color_line(char *line) int is_empty_line(char *line)
{ {
char *trimmed; int i;
int result;
result = 0; i = 0;
if (!line) if (!line)
return (0); return (1);
trimmed = ft_strtrim(line, " \t\n\r"); while (line[i])
if (!trimmed) {
return (0); if (line[i] != ' ' && line[i] != '\t'
if (ft_strncmp(trimmed, "F ", 2) == 0) && line[i] != '\n' && line[i] != '\r')
result = 1; return (0);
else if (ft_strncmp(trimmed, "C ", 2) == 0) i++;
result = 2; }
free(trimmed); return (1);
return (result);
} }
int is_texture_line(char *line) int is_color_line(char *line)
{ {
char *trimmed; char *trimmed;
int result; int result;
result = 0; result = 0;
if (!line) if (!line)
return (0); return (0);
trimmed = ft_strtrim(line, " \t\n\r"); trimmed = ft_strtrim(line, " \t\n\r");
if (!trimmed) if (!trimmed)
return (0); return (0);
if (ft_strncmp(trimmed, "NO ", 3) == 0) if (ft_strncmp(trimmed, "F ", 2) == 0)
result = 1; result = 1;
else if (ft_strncmp(trimmed, "SO ", 3) == 0) else if (ft_strncmp(trimmed, "C ", 2) == 0)
result = 2; result = 2;
else if (ft_strncmp(trimmed, "WE ", 3) == 0) free(trimmed);
result = 3; return (result);
else if (ft_strncmp(trimmed, "EA ", 3) == 0) }
result = 4;
free(trimmed); int is_texture_line(char *line)
return (result); {
} char *trimmed;
int result;
result = 0;
if (!line)
return (0);
trimmed = ft_strtrim(line, " \t\n\r");
if (!trimmed)
return (0);
if (ft_strncmp(trimmed, "NO ", 3) == 0)
result = 1;
else if (ft_strncmp(trimmed, "SO ", 3) == 0)
result = 2;
else if (ft_strncmp(trimmed, "WE ", 3) == 0)
result = 3;
else if (ft_strncmp(trimmed, "EA ", 3) == 0)
result = 4;
free(trimmed);
return (result);
}

View File

@ -6,21 +6,28 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 14:17:58 by lfirmin #+# #+# */ /* Created: 2025/08/22 14:17:58 by lfirmin #+# #+# */
/* Updated: 2025/08/22 14:17:58 by lfirmin ### ########.fr */ /* Updated: 2025/10/07 10:15:24 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
int parsing(t_data *data) int parsing(t_data *data)
{ {
if (check_file(data->map_path, &data->parsing) == 1) if (check_file(data->map_path, &data->parsing) == 1)
return (1); return (1);
get_map(data); if (get_map(data))
close(data->parsing.fd_map); {
close(data->parsing.fd_map_dup); close(data->parsing.fd_map);
if (check_colors(data->texture) == 1) close(data->parsing.fd_map_dup);
return (1); return (1);
if (validate_map(data->parsing.raw_map, data->parsing.player) == 0) }
return (1); close(data->parsing.fd_map);
return (0); close(data->parsing.fd_map_dup);
if (check_colors(data->texture) == 1)
return (1);
if (validate_map(data->parsing.raw_map, data->parsing.player))
return (1);
data->map = data->parsing.raw_map;
data->parsing.raw_map = NULL;
return (0);
} }

View File

@ -1,34 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* debug.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/23 13:23:51 by lfirmin #+# #+# */
/* Updated: 2025/08/23 13:23:51 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "cub.h"
void print_char_array_debug(char **arr, char *name)
{
int i = 0;
printf("=== %s ===\n", name ? name : "CHAR ARRAY");
if (!arr)
{
printf("Array is NULL\n");
return;
}
while (arr[i])
{
printf("[%d] (%zu chars): '%s'\n", i, strlen(arr[i]), arr[i]);
i++;
}
printf("Total lines: %d\n", i);
printf("==============\n");
}

View File

@ -6,29 +6,30 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 18:57:21 by lfirmin #+# #+# */ /* Created: 2025/08/22 18:57:21 by lfirmin #+# #+# */
/* Updated: 2025/08/22 18:57:21 by lfirmin ### ########.fr */ /* Updated: 2025/10/08 16:21:46 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
int init_data(t_data *data, char *path) int init_data(t_data *data, char *path)
{ {
if (!data) if (!data)
return (ft_error(ERROR_INIT_DATA), 1); return (ft_error(ERROR_INIT_DATA), 1);
data->texture = malloc(sizeof(t_textures)); data->texture = malloc(sizeof(t_textures));
if (!data->texture) if (!data->texture)
return (ft_error(ERROR_INIT_TEX), 1); return (ft_error(ERROR_INIT_TEX), 1);
init_parsing(&data->parsing); init_parsing(&data->parsing);
init_textures(data->texture); init_textures(data->texture);
data->map = NULL; data->map = NULL;
data->map_path = path; data->map_path = path;
return (0); return (0);
} }
void free_data(t_data *data) void free_data(t_data *data)
{ {
if (!data) if (!data)
return; return ;
if (data->texture) if (data->texture)
free(data->texture); free(data->texture);
free_char_array(data->map);
} }

View File

@ -6,40 +6,55 @@
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */ /* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/22 14:56:25 by lfirmin #+# #+# */ /* Created: 2025/08/22 14:56:25 by lfirmin #+# #+# */
/* Updated: 2025/08/22 14:56:25 by lfirmin ### ########.fr */ /* Updated: 2025/10/07 12:14:42 by lfirmin ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "cub.h" #include "cub.h"
void ft_error(char *message) void ft_error(char *message)
{ {
int len; int len;
len = 0; len = 0;
while (message[len]) while (message[len])
len++; len++;
write(2, ERROR_PREFIX, 31); write(2, ERROR_PREFIX, 6);
write(2, message, len); write(2, message, len);
write(2, "\n", 1); write(2, "\n", 1);
} }
void free_char_array(char **array) void free_char_array(char **array)
{ {
int i; int i;
if (!array) if (!array)
return; return ;
i = 0; i = 0;
while (array[i]) while (array[i])
free(array[i++]); free(array[i++]);
free(array); free(array);
} }
int ft_arrlen(char **arr) int ft_arrlen(char **arr)
{ {
int i; int i;
while(arr[i])
i++; while (arr[i])
return (i); i++;
} return (i);
}
void print_array(char **array)
{
int i;
i = 0;
if (!array)
return ;
while (array[i])
{
printf("%s", array[i]);
i++;
}
}

View File

@ -1,34 +1,29 @@
NO textures/test/north.xpm NO textures/test/north.xpm
EA textures/test/east.xpm
WE textures/test/west.xpm
SO textures/test/sud.xpm
EA textures/test/east.xpm C 200,200,200
F 200,200,200
1111
WE textures/test/west.xpm
C 200,200,200
F 200,200,200
11
1001 1001
10S01 10001
10001 10001
10101 10101
10001 1S001
10001 1001
10001
10001 10001
10001 10001
100011
10001 10001
10001 10001
111111
1111
11 11
1111