From 3ad68144051eac0a7e718f0ae3fff94cea4e624d Mon Sep 17 00:00:00 2001 From: Camille Chauvet Date: Wed, 3 May 2023 11:09:06 +0000 Subject: [PATCH] init: map parsing --- map/map.h | 17 +++++ map/parsing.c | 12 ++++ map/parsing.h | 7 ++ map/parsing_body.c | 156 ++++++++++++++++++++++++++++++++++++++++++ map/parsing_header.c | 92 +++++++++++++++++++++++++ map/parsing_header2.c | 53 ++++++++++++++ map/parsing_meta.c | 24 +++++++ map/parsing_private.h | 13 ++++ 8 files changed, 374 insertions(+) create mode 100644 map/map.h create mode 100644 map/parsing.c create mode 100644 map/parsing.h create mode 100644 map/parsing_body.c create mode 100644 map/parsing_header.c create mode 100644 map/parsing_header2.c create mode 100644 map/parsing_meta.c create mode 100644 map/parsing_private.h diff --git a/map/map.h b/map/map.h new file mode 100644 index 0000000..307435c --- /dev/null +++ b/map/map.h @@ -0,0 +1,17 @@ +#ifndef MAP_H +# define MAP_H +# include + +// img: 0=Nord, 1=WEST, 2=SOUTH, 3=EAST; + +typedef struct s_map +{ + char **map; + void *img[4]; + long long color_bot; + long long color_top; + long long spawn_x; + long long spawn_y; +} t_map; + +#endif diff --git a/map/parsing.c b/map/parsing.c new file mode 100644 index 0000000..18fdca0 --- /dev/null +++ b/map/parsing.c @@ -0,0 +1,12 @@ +#include "./parsing_private.h" + +t_map *map_parsing(const char *path) +{ + t_map *map; + + map = malloc(sizeof(t_map)); + if (map == NULL) + return (NULL); + (void)path; + return (map); +} diff --git a/map/parsing.h b/map/parsing.h new file mode 100644 index 0000000..148c31f --- /dev/null +++ b/map/parsing.h @@ -0,0 +1,7 @@ +#ifndef PARSING_H +# define PARSING_H +# include "map.h" + +t_map *map_parsing(const char *path); + +#endif diff --git a/map/parsing_body.c b/map/parsing_body.c new file mode 100644 index 0000000..eb3c9e7 --- /dev/null +++ b/map/parsing_body.c @@ -0,0 +1,156 @@ +#include "map.h" +#include "parsing_private.h" +#include +#include + +char **get_body(const char **file_content, size_t header_size) +{ + char **body; + size_t i; + size_t len; + + len = 0; + while (file_content[header_size + len] != NULL) + len++; + body = malloc((len + 1) * sizeof(char *)); + if (body == NULL) + return (NULL); + body[len] = NULL; + i = 0; + while (i < len) + { + body[i] = ft_strdup(file_content[header_size + i]); + if (body[i] == NULL) + { + ft_cancel((void **) body, i); + return (NULL); + } + i++; + } + return (body); +} + +int get_spawn_position(const char **body, long long *spawn_x, long long *spawn_y) +{ + size_t x; + size_t y; + + *spawn_x = -1; + *spawn_y = -1; + y = 0; + while (body[y] != NULL) + { + x = 0; + while (body[y][x] != '\0') + { + if (ft_is_in("NSEW", body[y][x])) + { + if (*spawn_x != -1) + return (1); + *spawn_x = x; + *spawn_y = y; + } + x++; + } + y++; + } + if (*spawn_x == -1) + return (2); + return (0); +} + +static int map_is_in_one_part(const char **body) +{ + size_t y; + + y = ft_tablen((const void **) body); + while (body[y][0] == '\0' || ft_contain_only(body[y], ' ')) + y--; + while (y > 0) + { + if (body[y][0] == '\0' || ft_contain_only(body[y], ' ')) + return (1); + y--; + } + return (0); +} + +static int map_surround_check(char **body, size_t x, size_t y) +{ + if (ft_is_in(";1", body[y][x])) + return (0); + if (ft_is_in(" ", body[y][x])) + return (1); + if (y == 0 || body[y] == NULL) + return (1); + if (x == 0 || body[y][x] == '\0') + return (1); + if (map_surround_check(body, x + 1, y)) + return (1); + if (map_surround_check(body, x - 1, y)) + return (1); + if (map_surround_check(body, x, y + 1)) + return (1); + if (map_surround_check(body, x, y - 1)) + return (1); + return (0); +} + +static int map_surround(const char **body, t_map *map) +{ + size_t i; + char **copy; + + copy = malloc((ft_tablen((const void **) body) + 1) * sizeof(char *)); + if (copy == NULL) + return (1); + i = 0; + while (body[i] != NULL) + { + copy[i] = ft_strdup(body[i]); + if (copy[i] == NULL) + { + ft_cancel((void **) copy, i); + return (1); + } + i++; + } + copy[i] = NULL; + if (map_surround_check(copy, map->spawn_x, map->spawn_y)) + { + ft_freer_tab_ultimate(1, copy); + return (1); + } + ft_freer_tab_ultimate(1, copy); + return (0); +} + +int body_is_valid(const char **body, t_map *map) +{ + int error; + + error = get_spawn_position(body, &map->spawn_x, &map->spawn_y); + if (error == 1) + { + ft_eprintf("map: spawn position: multiple definition"); + return (1); + } + else if (error == 2) + { + ft_eprintf("map: spawn position: not define"); + return (1); + } + error = map_surround(body, map); + if (error) + { + ft_eprintf("map: not surrounded"); + return (1); + } + error = map_is_in_one_part(body); + if (error) + { + ft_eprintf("map: splitted"); + return (1); + } + return (0); +} diff --git a/map/parsing_header.c b/map/parsing_header.c new file mode 100644 index 0000000..3c8750b --- /dev/null +++ b/map/parsing_header.c @@ -0,0 +1,92 @@ +#include "./parsing_private.h" + +int get_token(const char *key) +{ + if (ft_strcmp(key, "NO") == 0) + return (1); + if (ft_strcmp(key, "SO") == 0) + return (3); + if (ft_strcmp(key, "WE") == 0) + return (2); + if (ft_strcmp(key, "EA") == 0) + return (4); + if (ft_strcmp(key, "F") == 0) + return (5); + if (ft_strcmp(key, "C") == 0) + return (6); + return (0); +} + +static int is_header(const char *line) +{ + char **list; + + list = ft_split(line, ' '); + if (list == NULL) + { + ft_eprintf("malloc failed"); + ft_freer_ultimate(1, list); + return (0); + } + if (ft_tablen((const void **) list) != 2) + { + ft_freer_ultimate(1, list); + return (0); + } + if (get_token(list[0]) == 0) + { + ft_freer_ultimate(1, list); + return (0); + } + ft_freer_ultimate(1, list); + return (1); +} + +static size_t get_header_size(const char **file_content, size_t *header_size) +{ + ssize_t i; + size_t len; + + len = 0; + i = -1; + while (file_content[++i] != NULL) + { + if (ft_contain_only(file_content[i], ' ')) + continue; + if (!is_header(file_content[i])) + break ; + len++; + } + *header_size = i; + return (len); +} + +char ***get_header(const char **file_content, size_t *header_size) +{ + char ***header; + size_t len; + size_t i; + size_t y; + + len = get_header_size(file_content, header_size); + header = malloc(sizeof(char *) * (len + 1)); + if (header == NULL) + return (NULL); + header[len] = NULL; + y = 0; + i = 0; + while (y < len) + { + while (ft_contain_only(file_content[i], ' ')) + i++; + header[y] = ft_split(file_content[i], ' '); + if (header[y] == NULL) + { + ft_cancel((void **) header, y); + return (NULL); + } + y++; + i++; + } + return (header); +} diff --git a/map/parsing_header2.c b/map/parsing_header2.c new file mode 100644 index 0000000..afcfeb1 --- /dev/null +++ b/map/parsing_header2.c @@ -0,0 +1,53 @@ +#include "./parsing_private.h" + +static int set_texture(t_map *map, int token, const char *key, char *value) +{ + if (map->img[token - 1] != NULL) + { + ft_eprintf("redefinition of %s", key); + return (1); + } + map->img[token - 1] = value; + return (0); +} + +static int set_color(long long *color, const char *key, char *value) +{ + if (*color != -1) + { + ft_eprintf("redefinition of %s", key); + return (1); + } + if (ft_atoul_check(value)) + { + ft_eprintf("%s is to high", value); + return (1); + } + *color = ft_atoul(value); + return (0); +} + +int header_is_valid(char ***header, t_map *map) +{ + size_t i; + int token; + + + map->color_bot = -1; + map->color_top = -1; + i = 0; + while (i < ft_tablen((const void **) header)) + { + token = get_token(header[i][0]); + if (token > 0 && token < 5 + && set_texture(map, token, header[i][0], header[i][1])) + return (0); + else if ((token == 5 && set_color(&map->color_bot, + header[i][0], header[i][1])) + || (token == 6 && set_color(&map->color_top, + header[i][0], header[i][1]))) + return (0); + i++; + } + return (1); +} diff --git a/map/parsing_meta.c b/map/parsing_meta.c new file mode 100644 index 0000000..3acb5e3 --- /dev/null +++ b/map/parsing_meta.c @@ -0,0 +1,24 @@ +#include "./parsing_private.h" + +static int name_check(const char *path) +{ + size_t len; + + len = ft_strlen(path); + if (len < 4) + { + ft_eprintf("map error: name doesn't finished by .cub"); + return (1); + } + if (ft_strcmp(".cub", path + len - 3) != 0) + { + ft_eprintf("map error: name doesn't finished by .cub"); + return (1); + } + return (1); +} + +int parsing_meta(const char *path) +{ + return (name_check(path)); +} diff --git a/map/parsing_private.h b/map/parsing_private.h new file mode 100644 index 0000000..e2b7187 --- /dev/null +++ b/map/parsing_private.h @@ -0,0 +1,13 @@ +#ifndef PARSING_PRIVATE_H +# define PARSING_PRIVATE_H +# include +# include "../libftx/libftx.h" +# include "./parsing.h" + +int parsing_meta(const char *path); +int get_token(const char *str); +char ***get_header(const char **file_content, size_t *header_size); +int header_is_valid(char ***header, t_map *map); +char **get_body(const char **file_content, size_t header_size); +int body_is_valid(const char **body, t_map *map); +#endif