From 8be4f2cc02a384db2ddbca28114f6894f5d85938 Mon Sep 17 00:00:00 2001 From: vSKAH Date: Fri, 13 Oct 2023 19:54:50 +0200 Subject: [PATCH] fix:(vSKAH): Fix leaks fix:(vSKAH): Collectibles load errors fix:(vSKAH): Exit solve add:(vSKAH): Xpm find security add:(vSKAH): Add parsing errors TODO: print nb of movements --- Makefile | 6 ++- collectible_utils.c | 92 +++++++++++++++------------------ errors_utils.c | 63 +++++++++++++++++++++++ frees.c | 58 +++++++++++++++------ graphics_utils.c | 63 +++++++++-------------- location_utils.c | 12 ++--- main.c | 91 +++++++++------------------------ maps/1.ber | 13 +++-- maps_utils.c | 58 +++++++++++++-------- player.c | 102 ++++++++++++++++--------------------- rectangle_check.c | 100 +++++++++++++++++------------------- so_long.h | 121 ++++++++++++++++++++------------------------ textures_utils.c | 52 +++++++++++++++++++ utils.c | 34 +++++++------ 14 files changed, 467 insertions(+), 398 deletions(-) create mode 100644 errors_utils.c create mode 100644 textures_utils.c diff --git a/Makefile b/Makefile index 50dd0df..617cb36 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,9 @@ SRCS = main.c \ rectangle_check.c \ utils.c \ graphics_utils.c \ - location_utils.c + location_utils.c \ + textures_utils.c \ + errors_utils.c \ LIBFT_FLAGS = -L./libft -l:libft.a OBJ_DIRECTORY = ./.obj/ @@ -34,7 +36,7 @@ OBJ_DIRECTORY = ./.obj/ CC = cc -FLAGS = -c -Wall -Wextra -Werror -g -no-pie +FLAGS = -c -Wall -Wextra -Werror -g INCLUDES = ./headers/so_long.h diff --git a/collectible_utils.c b/collectible_utils.c index de47b9c..58cce7d 100644 --- a/collectible_utils.c +++ b/collectible_utils.c @@ -12,25 +12,25 @@ #include "so_long.h" -t_collectible *load_collectibles(t_world *world) { - int pos_x; - int pos_y; - t_collectible *collectible; +t_collectible *load_collectibles(t_world *world) +{ + int pos_x; + int pos_y; + t_collectible *collectible; + t_location location; pos_x = 0; pos_y = 0; collectible = NULL; - - while (world->map[pos_y]) { - while (world->map[pos_y] && pos_x < (int) ft_strlen(world->map[0])) { - if (world->map[pos_y][pos_x] == 'C') { - t_location location; + while (world->map[pos_y]) + { + while (world->map[pos_y] && pos_x < (int) ft_strlen(world->map[0])) + { + if (world->map[pos_y][pos_x] == 'C') + { location.x = pos_x; location.y = pos_y; - if(!collectible) - collectible = create_collectible(location); - else - collectible->next = create_collectible(location); + last(&collectible, create_collectible(location)); } pos_x++; } @@ -38,66 +38,56 @@ t_collectible *load_collectibles(t_world *world) { pos_y++; } return (collectible); - } - -t_collectible *create_collectible(t_location location) +t_collectible *create_collectible(t_location location) { - t_collectible *collectible; + t_collectible *collectible; collectible = malloc(sizeof (t_collectible)); - if(!collectible) + if (!collectible) return (NULL); - collectible->location = location; collectible->collected = 0; - collectible->is_set = _true; collectible->next = NULL; return (collectible); } -int count_collectibles(t_collectible collectibles, t_boolean o_uncollected, t_boolean o_collected) -{ - int count; - - count = 0; - - while (collectibles.is_set) - { - if(o_uncollected && !collectibles.collected) - count++; - if(o_collected && collectibles.collected) - count++; - if(collectibles.next != NULL) - collectibles = *collectibles.next; - else - break; - } - return (count); -} - - -t_collectible *get_collectible_at(t_world world, t_location location) +t_collectible *get_collectible_at(t_world world, t_location location) { while (world.player.collectibles) { - if(loc_equals(location, world.player.collectibles->location)) + if (loc_equals(location, world.player.collectibles->location)) return (world.player.collectibles); world.player.collectibles = world.player.collectibles->next; } return (NULL); } -#include "stdio.h" -void update_collectible(t_collectible *collectibles, t_location location, t_boolean collected) +void update_col(t_collectible *col, t_location loc, t_boolean bool) { - while (collectibles) + while (col) { - if(loc_equals(collectibles->location, location)) { - collectibles->collected = collected; - break; + if (loc_equals(col->location, loc)) + { + col->collected = bool; + break ; } - collectibles = collectibles->next; + col = col->next; + } +} + +void last(t_collectible **lst, t_collectible *new) +{ + t_collectible *tmp; + + tmp = *lst; + if (tmp == NULL) + { + *lst = new; + return ; } -} \ No newline at end of file + while (tmp->next) + tmp = tmp->next; + tmp->next = new; +} diff --git a/errors_utils.c b/errors_utils.c new file mode 100644 index 0000000..ac41c78 --- /dev/null +++ b/errors_utils.c @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* errors_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jbadaire +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/13 17:50:08 by jbadaire #+# #+# */ +/* Updated: 2023/10/13 17:50:08 by jbadaire ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "so_long.h" +#include + +int handle_file_error(char *argv[]) +{ + int fd; + + if (!argv[1]) + return (ft_putstr_fd("Error\n -> Invalid file path.\n", 1), -2); + fd = open(argv[1], O_RDONLY); + if (fd == -1) + return (ft_putstr_fd("Error\n -> Invalid file path.\n", 1), -2); + return (fd); +} + +int handle_map_error(char *path, t_game game) +{ + int elements_code; + t_world cloned; + + if (has_illegal_character(game.world)){ + free_map(&game.world); + free_collectibles(game.world.player.collectibles); + return (ft_putstr_fd("Error\n -> Invalid Map / illegal character", 1), -1); + + } + if (!is_valid_shape(game.world)) + { + free_map(&game.world); + free_collectibles(game.world.player.collectibles); + return (ft_putstr_fd("Error\n -> Invalid shape / not closed", 1), -1); + } + elements_code = valid_elements(game.world); + if (elements_code < 0) + { + ft_putstr_fd("Error\n -> Please, check your map !", 1); + ft_putstr_fd("\nThe map must contains 1 E, 1 P, minimum 1 C", 1); + return (-1); + } + load_map(open(path, O_RDONLY), path, &cloned); + is_solvable(cloned.map, game.world.player.location.x, game.world.player.location.y, game.world.length_y); + if (count_element(cloned, 'C') > 0 || count_element(cloned, 'E') > 0) + { + ft_putstr_fd("Error\n -> Sorry, your map is not resolvable", 1); + free_map(&game.world); + free_collectibles(game.world.player.collectibles); + return (free_map(&cloned), -2); + } + free_map(&cloned); + return (0); +} \ No newline at end of file diff --git a/frees.c b/frees.c index 1e45511..9bf4b03 100644 --- a/frees.c +++ b/frees.c @@ -6,42 +6,45 @@ /* By: jbadaire +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/03 10:21:10 by jbadaire #+# #+# */ -/* Updated: 2023/10/12 19:51:21 by jbadaire ### ########.fr */ +/* Updated: 2023/10/13 17:09:19 by jbadaire ### ########.fr */ /* */ /* ************************************************************************** */ #include "so_long.h" -void free_map(t_world *world) { - int index; +void free_map(t_world *world) +{ + int index; index = 0; - while (world->map && world->map[index]) { + while (world->map && world->map[index]) + { free(world->map[index]); index++; } free((world->map)); } - -void free_textures(t_game *game) +void free_textures(t_game *game) { - t_textures *textures = &game->textures; - if(textures->wall.is_set) + t_textures *textures; + + textures = &game->textures; + if (textures->wall.is_set && textures->wall.texture != NULL) mlx_destroy_image(game->mlx, game->textures.wall.texture); - if(textures->player.is_set) + if (textures->player.is_set && textures->player.texture != NULL) mlx_destroy_image(game->mlx, game->textures.player.texture); - if(textures->collectible.is_set) + if (textures->collectible.is_set && textures->collectible.texture != NULL) mlx_destroy_image(game->mlx, game->textures.collectible.texture); - if(textures->grass.is_set) + if (textures->grass.is_set && textures->grass.texture != NULL) mlx_destroy_image(game->mlx, game->textures.grass.texture); - if(textures->exit.is_set) + if (textures->exit.is_set && textures->exit.texture != NULL) mlx_destroy_image(game->mlx, game->textures.exit.texture); } -void free_collectibles(t_collectible *collectible) +void free_collectibles(t_collectible *collectible) { - t_collectible *copy; + t_collectible *copy; while (collectible != NULL) { @@ -49,4 +52,29 @@ void free_collectibles(t_collectible *collectible) collectible = collectible->next; free(copy); } -} \ No newline at end of file +} + +int free_unavailable_texture(t_game game) +{ + if (has_unavailable_texture(game.textures)) + { + ft_putstr_fd("Error\n -> Textures can't be loaded.", 1); + free_map(&game.world); + free_textures(&game); + free_collectibles(game.world.player.collectibles); + mlx_destroy_display(game.mlx); + free(game.mlx); + return (1); + } + return (0); +} + +void destroy(t_game *game) +{ + free_map(&game->world); + free_textures(game); + free_collectibles(game->world.player.collectibles); + mlx_destroy_window(game->mlx, game->window); + mlx_destroy_display(game->mlx); + free(game->mlx); +} diff --git a/graphics_utils.c b/graphics_utils.c index 3046db4..97d6ca7 100644 --- a/graphics_utils.c +++ b/graphics_utils.c @@ -6,51 +6,26 @@ /* By: jbadaire +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/03 12:56:12 by jbadaire #+# #+# */ -/* Updated: 2023/10/12 08:56:07 by jbadaire ### ########.fr */ +/* Updated: 2023/10/13 16:28:17 by jbadaire ### ########.fr */ /* */ /* ************************************************************************** */ #include "so_long.h" -t_textures load_textures(void *mlx) +void draw_type(t_game game, t_texture texture) { - t_textures textures; - - textures.wall = load_texture(mlx, '1', "./textures/wall.xpm"); - textures.grass = load_texture(mlx, '0', "./textures/grass.xpm"); - textures.player = load_texture(mlx, 'P', "./textures/player.xpm"); - textures.collectible = load_texture(mlx, 'C', "./textures/collectible.xpm"); - textures.exit = load_texture(mlx, 'E', "./textures/exit.xpm"); - - return (textures); -} - - -t_texture load_texture(void *mlx, char character, char *path) -{ - int img_width; - int img_height; - t_texture texture; - - texture.character = character; - texture.texture = mlx_xpm_file_to_image(mlx, path, &img_width, &img_height); - texture.is_set = _true; - return (texture); -} - -void draw_type(void *mlx, void *mlx_window, t_world *world, t_texture texture) -{ - int index_y; - int index_x; + int index_y; + int index_x; index_y = 0; index_x = 0; - - while (world->map[index_y]) { - while (index_x < (int) ft_strlen(world->map[index_y])) { - if (world->map[index_y][index_x] == texture.character) { - mlx_put_image_to_window(mlx, mlx_window, texture.texture, index_x * 128, index_y * 128); - } + while (game.world.map[index_y]) + { + while (index_x < (int) ft_strlen(game.world.map[index_y])) + { + if (game.world.map[index_y][index_x] == texture.character) + mlx_put_image_to_window(game.mlx, game.window, \ + texture.texture, index_x * 128, index_y * 128); index_x++; } index_x = 0; @@ -58,7 +33,7 @@ void draw_type(void *mlx, void *mlx_window, t_world *world, t_texture texture) } } -void draw_collectibles(t_game game) +void draw_collectibles(t_game game) { t_location loc; void *texture; @@ -67,7 +42,17 @@ void draw_collectibles(t_game game) while (game.world.player.collectibles) { loc = game.world.player.collectibles->location; - mlx_put_image_to_window(game.mlx, game.window, texture, loc.x * 128, loc.y * 128); + mlx_put_image_to_window \ + (game.mlx, game.window, texture, loc.x * 128, loc.y * 128); game.world.player.collectibles = game.world.player.collectibles->next; } -} \ No newline at end of file +} + +void draws(t_game game) +{ + draw_type(game, game.textures.wall); + draw_type(game, game.textures.grass); + draw_type(game, game.textures.player); + draw_type(game, game.textures.exit); + draw_collectibles(game); +} diff --git a/location_utils.c b/location_utils.c index 73eebd2..4ef586a 100644 --- a/location_utils.c +++ b/location_utils.c @@ -12,10 +12,10 @@ #include "so_long.h" -t_boolean loc_equals(t_location loc_1, t_location loc_2) +t_boolean loc_equals(t_location loc_1, t_location loc_2) { - if(loc_1.x == loc_2.x && loc_1.y == loc_2.y) - return (_true); - else - return (_false); -} \ No newline at end of file + if (loc_1.x == loc_2.x && loc_1.y == loc_2.y) + return (_true); + else + return (_false); +} diff --git a/main.c b/main.c index 087b616..f467ce6 100644 --- a/main.c +++ b/main.c @@ -11,77 +11,32 @@ /* ************************************************************************** */ #include "so_long.h" -#include -int main(int argc, char *argv[]) { - void *mlx; - void *window; - int value; - t_textures textures; +int main(int argc, char *argv[]) +{ + int fd; t_game game; + int value; - value = handle_launch_error(argc, argv, &game.world); - if(value == -1) + (void) argc; + fd = handle_file_error(argv); + if (fd < 0) return (0); - - game.world.exit = find_element(game.world, 'E'); - game.world.player = init_player(find_element(game.world, 'P'), load_collectibles(&game.world)); - - if(!is_valid_map(game.world)) - { - ft_putstr_fd("Veuillez verifier votre map (rectangle, collectibles, sortie, ect..)", 1); - free_map(&game.world); - return (-1); - } - - mlx = mlx_init(); - if(!mlx) { + load_map(fd, argv[1], &game.world); + game.world.player = init_player(find_element(game.world, 'P'), \ + load_collectibles(&game.world)); + value = handle_map_error(argv[1], game); + if(value < 0) + return(0); + game.mlx = mlx_init(); + if (!game.mlx) return (0); - } - - - textures = load_textures(mlx); - - game.mlx = mlx; - game.textures = textures; - - window = mlx_new_window(mlx, 128 * ft_strlen(game.world.map[0]), 128 * game.world.length_y, "Xe'Burger"); - game.window = window; - - draw_type(mlx, window, &game.world, textures.wall); - draw_type(mlx, window, &game.world, textures.grass); - draw_type(mlx, window, &game.world, textures.player); - draw_type(mlx, window, &game.world, textures.exit); - draw_collectibles(game); - - mlx_hook(window, 2, (1L<<0), on_player_move, &game); - mlx_loop(mlx); - - free_map(&game.world); - free_textures(&game); - free_collectibles(game.world.player.collectibles); - mlx_destroy_window(mlx, window); - mlx_destroy_display(mlx); - free(mlx); - - return 0; -} - - -int handle_launch_error(int argc, char *argv[], t_world *world) -{ - int fd; - if(argc < 2) - { - ft_putstr_fd( "You must include the abstract path to your map.\n", 1); - return (-1); - } - fd = open(argv[1], O_RDONLY); - if (fd == -1) - { - ft_putstr_fd("You must include the abstract path to your map.\n", 1); - return (-1); - } - load_map(fd, argv[1], world); - return (fd); + game.textures = load_textures(game.mlx); + if (free_unavailable_texture(game)) + return (0); + game.window = mlx_new_window(game.mlx, 128 * ft_strlen(game.world.map[0]), 128 * game.world.length_y, "Xe'Burger"); + draws(game); + mlx_hook(game.window, 2, (1L << 0), on_player_move, &game); + mlx_loop(game.mlx); + return (destroy(&game), 0); } diff --git a/maps/1.ber b/maps/1.ber index 915d05c..c7c87c0 100644 --- a/maps/1.ber +++ b/maps/1.ber @@ -1,5 +1,8 @@ -1111111 -10C00P1 -1000001 -10000E1 -1111111 \ No newline at end of file +1111111111111 +10000000000C1 +10P0000000001 +1000000000001 +1000111110001 +1100000000001 +1C0000C0001E1 +1111111111111 \ No newline at end of file diff --git a/maps_utils.c b/maps_utils.c index 7eed109..961c23c 100644 --- a/maps_utils.c +++ b/maps_utils.c @@ -6,7 +6,7 @@ /* By: jbadaire +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/02 18:09:47 by jbadaire #+# #+# */ -/* Updated: 2023/10/10 17:23:02 by jbadaire ### ########.fr */ +/* Updated: 2023/10/12 20:13:08 by jbadaire ### ########.fr */ /* */ /* ************************************************************************** */ #include "so_long.h" @@ -46,37 +46,53 @@ t_world *load_map(int fd, char *path, t_world *world) return (world->length_y = index, world); } -t_boolean is_valid_map(t_world world) +int valid_elements(t_world world) { - t_location start_loc; - t_location exit_loc; - //int collectibles; + int players; + int exits; + int collectibles; - start_loc = find_element(world, 'P'); - exit_loc = find_element(world, 'E'); - //collectibles = ft_lstsize(world.player->collectibles); - return (start_loc.x != -1 && exit_loc.x != -1); + players = count_element(world, 'P'); + if(players > 1) + return (-1); + if(players < 1) + return (-2); + exits = count_element(world, 'E'); + if(exits > 1) + return (-3); + if(exits < 1) + return (-4); + collectibles = count_element(world, 'C'); + if(collectibles < 1) + return (-5); + return (1); } -void is_solvable(t_world *world, int x, int y) +void is_solvable(char **map, int x, int y, int length_y) { char character; - if(world->map[y] == NULL || y > world->length_y) + if(map[y] == NULL || y > length_y) return; - character = world->map[y][x]; + character = map[y][x]; if (character == 'O') return ; - if (character == '0' || character == 'C' || character == 'P' || character == 'E') + if (character == '0' || character == 'C' || character == 'P') { - world->map[y][x] = 'O'; - is_solvable(world, x - 1, y); - is_solvable(world, x + 1, y); - is_solvable(world, x, y + 1); - is_solvable(world,x, y - 1); + map[y][x] = 'O'; + is_solvable(map, x - 1, y, length_y); + is_solvable(map, x + 1, y, length_y); + is_solvable(map, x, y + 1, length_y); + is_solvable(map,x, y - 1, length_y); + } + if(character == 'E') + { + map[y][x] = 'L'; + is_solvable(map, x - 1, y, length_y); + is_solvable(map, x + 1, y, length_y); + is_solvable(map, x, y + 1, length_y); + is_solvable(map,x, y - 1, length_y); } - return ; - } t_boolean is_inside_world(int y, int x, t_world world) @@ -86,4 +102,4 @@ t_boolean is_inside_world(int y, int x, t_world world) if(x < 0 || x > (int) ft_strlen(world.map[0])) return (_false); return (_true); -} +} \ No newline at end of file diff --git a/player.c b/player.c index eb1a792..8f9b896 100644 --- a/player.c +++ b/player.c @@ -6,27 +6,26 @@ /* By: jbadaire +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/03 10:22:53 by jbadaire #+# #+# */ -/* Updated: 2023/10/12 11:09:13 by jbadaire ### ########.fr */ +/* Updated: 2023/10/13 17:30:36 by jbadaire ### ########.fr */ /* */ /* ************************************************************************** */ #include "so_long.h" -t_player init_player(t_location location, t_collectible *collectibles) +t_player init_player(t_location location, t_collectible *collectibles) { - t_player player; + t_player player; location.x--; location.y--; player.location.x = location.x; player.location.y = location.y; - player.collectibles = collectibles; player.movements = 0; return (player); } -void update_graphics(t_game *game) +void update_graphics(t_game *game) { t_location location; void *texture; @@ -34,89 +33,78 @@ void update_graphics(t_game *game) location = game->world.player.location; texture = game->textures.player.texture; game->world.player.movements = game->world.player.movements + 1; - - mlx_put_image_to_window(game->mlx,game->window,texture,location.x * 128,location.y * 128); + mlx_put_image_to_window(game->mlx, game->window, texture, \ + location.x * 128, location.y * 128); } int on_player_move(int keycode, t_game *game) { - //w = 119 - //s = 115 - //a = 97 - //d = 100 - - if(!can_move(keycode, *game)) - return -1; - - if(keycode != 119 && keycode != 115 && keycode != 97 && keycode != 100) - return -1; - - mlx_put_image_to_window(game->mlx, - game->window, - game->textures.grass.texture, - game->world.player.location.x * 128, + t_collectible *collectible; + + if (!can_move(keycode, *game)) + return (-1); + if (keycode != 119 && keycode != 115 && keycode != 97 && keycode != 100) + return (-1); + mlx_put_image_to_window(game->mlx, game->window, \ + game->textures.grass.texture, game->world.player.location.x * 128, \ game->world.player.location.y * 128); - - if(keycode == 119) + if (keycode == 119) game->world.player.location.y -= 1; - else if(keycode == 115) + else if (keycode == 115) game->world.player.location.y += 1; - else if(keycode == 97) + else if (keycode == 97) game->world.player.location.x -= 1; - else game->world.player.location.x += 1; - + else + game->world.player.location.x += 1; update_graphics(game); - - t_collectible *collectible = get_collectible_at(game->world, game->world.player.location); - if (collectible != NULL && !collectible->collected){ - update_collectible(collectible, game->world.player.location, _true); - } - return 0; + collectible = get_collectible_at(game->world, game->world.player.location); + if (collectible != NULL && !collectible->collected) + update_col(collectible, game->world.player.location, _true); + ft_putstr_fd("INFOS: \nMovements ", 1); + return (0); } - - - -t_boolean can_move(int code, t_game game) +t_boolean can_move(int code, t_game game) { - char **map; - int y; - int x; + char **map; + int y; + int x; map = game.world.map; y = game.world.player.location.y; x = game.world.player.location.x; - if(code == 119) + if (code == 119) y--; - else if(code == 115) + else if (code == 115) y++; - else if(code == 97) + else if (code == 97) x--; - else if(code == 100) + else if (code == 100) x++; - if(!is_inside_world(y, x, game.world)) + if (!is_inside_world(y, x, game.world)) return (_false); - return (!is_solid(map[y][x], game)); } -t_boolean is_solid(char c, t_game game) +t_boolean is_solid(char c, t_game game) { + t_boolean exit; - if(!c) + exit = _true; + if (!c) return (_true); while (game.world.player.collectibles) { - if(c == 'E') {\ - if (!game.world.player.collectibles->collected) - return (_true); - else - mlx_loop_end(game.mlx); + if (!game.world.player.collectibles->collected) + { + exit = _false; + break ; } game.world.player.collectibles = game.world.player.collectibles->next; } - - if(c == '1') + if (exit && c == 'E') + mlx_loop_end(game.mlx); + if (c == '1' || c == 'E') return (_true); - return _false; + return (_false); } diff --git a/rectangle_check.c b/rectangle_check.c index cd2e8f8..7dc612c 100644 --- a/rectangle_check.c +++ b/rectangle_check.c @@ -6,88 +6,80 @@ /* By: jbadaire +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/03 01:27:59 by jbadaire #+# #+# */ -/* Updated: 2023/10/05 15:26:35 by jbadaire ### ########.fr */ +/* Updated: 2023/10/13 17:31:58 by jbadaire ### ########.fr */ /* */ /* ************************************************************************** */ #include "so_long.h" -t_boolean is_rectangle(t_world world) { - return (is_horizontal_rectangle(world) || - is_vertical_rectangle(world)) && is_closed(world); +t_boolean is_valid_shape(t_world world) +{ + return (has_good_shape(world) && is_closed(world)); } -t_boolean is_horizontal_rectangle(t_world world) { - int x_length; - int y_index; +t_boolean has_illegal_character(t_world world) +{ + int index_y; + int index_x; + char c; + + index_y = 0; + index_x = 0; + while (index_y < world.length_y) + { + while (index_x < (int) ft_strlen(world.map[index_y])) + { + c = world.map[index_y][index_x]; + if (c != '1' && c != '0' && c != 'E' && c != 'C' && c != 'P') + return (_true); + index_x++; + } + index_x = 0; + index_y++; + } + return (_false); +} + +t_boolean has_good_shape(t_world world) +{ + int x_length; + int y_index; x_length = (int) ft_strlen(world.map[0]); y_index = 0; - - while (y_index < world.length_y && world.map[y_index]) { + while (y_index < world.length_y && world.map[y_index]) + { if ((int) ft_strlen(world.map[y_index]) != x_length) return (_false); y_index++; } - if (x_length <= y_index) return (_false); - return (_true); } -t_boolean is_vertical_rectangle(t_world world) { - int x_index; - int y_index; - - int x_length; - int y_length; - - x_index = 0; - y_index = 0; - - x_length = (int) ft_strlen(world.map[0]); - y_length = world.length_y; - - while (x_index < x_length) { - while (x_index < x_length && y_index < y_length && world.map[y_index][x_index]) - y_index++; - if (y_index != y_length) - return (_false); - y_index = 0; - x_index++; - } - y_index = 0; - while (y_index < y_length) - if (world.map[y_index] && (int)ft_strlen(world.map[y_index++]) != x_length) - return (_false); - if (x_index >= y_length) - return (_false); - return (_true); -} - - -t_boolean is_closed(t_world world) { - - int x_length; - int x_index; - int y_index; +t_boolean is_closed(t_world world) +{ + int x_length; + int x_index; + int y_index; x_length = (int)ft_strlen(world.map[0]); x_index = 0; y_index = 0; - - while (x_index < x_length) { - if (world.map[0][x_index] != '1' || world.map[world.length_y - 1][x_index] != '1') + while (x_index < x_length) + { + if (world.map[0][x_index] != '1' || \ + world.map[world.length_y - 1][x_index] != '1') return (_false); x_index++; } - - while (y_index < world.length_y) { - if (world.map[y_index][0] != '1' || world.map[y_index][x_length - 1] != '1') + while (y_index < world.length_y) + { + if (world.map[y_index][0] != '1' || \ + world.map[y_index][x_length - 1] != '1') return (_false); y_index++; } - return (_true); } diff --git a/so_long.h b/so_long.h index 9f456eb..746cb1c 100644 --- a/so_long.h +++ b/so_long.h @@ -6,12 +6,10 @@ /* By: jbadaire +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/02 17:59:52 by jbadaire #+# #+# */ -/* Updated: 2023/10/12 17:14:35 by jbadaire ### ########.fr */ +/* Updated: 2023/10/12 20:15:13 by jbadaire ### ########.fr */ /* */ /* ************************************************************************** */ - - #ifndef SO_LONG_H # define SO_LONG_H @@ -21,109 +19,102 @@ # include typedef struct s_location { - int x; - int y; + int x; + int y; } t_location; typedef struct s_collectible { t_location location; int collected; - t_boolean is_set; struct s_collectible *next; } t_collectible; - typedef struct s_player { - t_location location; - t_collectible *collectibles; - int movements; + t_location location; + t_collectible *collectibles; + int movements; } t_player; typedef struct s_world { - char **map; - int length_y; - t_location exit; - t_player player; + char **map; + int length_y; + t_player player; } t_world; typedef struct s_texture { - char character; - void *texture; - t_boolean is_set; + char character; + void *texture; + t_boolean is_set; } t_texture; - typedef struct s_textures { - struct s_texture wall; - struct s_texture grass; - struct s_texture collectible; - struct s_texture player; - struct s_texture exit; + struct s_texture wall; + struct s_texture grass; + struct s_texture collectible; + struct s_texture player; + struct s_texture exit; } t_textures; - typedef struct s_game { - struct s_textures textures; - struct s_world world; - void *mlx; - void *window; + struct s_textures textures; + struct s_world world; + void *mlx; + void *window; } t_game; - // ** UTILS ** // -t_boolean loc_equals(t_location loc_1, t_location loc_2); +t_boolean loc_equals(t_location loc_1, t_location loc_2); +t_boolean is_inside_world(int y, int x, t_world world); +int handle_launch_error(char *argv[], t_world *world); +// ** ERRORS **// +int handle_file_error(char *argv[]); +int handle_map_error(char *path, t_game game); // ** MAP ** // -t_world *load_map(int fd, char *path, t_world *world); -t_location find_element(t_world world, char type); -void is_solvable(t_world *world, int x, int y); -t_boolean is_valid_map(t_world world); -int count_element(t_world world, char type); - - -// ** MATHS ** // -t_boolean is_horizontal_rectangle(t_world world); -t_boolean is_vertical_rectangle(t_world world); -t_boolean is_rectangle(t_world world); -t_boolean is_closed(t_world world); -t_boolean is_inside_world(int y, int x, t_world world); - +t_world *load_map(int fd, char *path, t_world *world); +t_boolean is_valid_shape(t_world world); +t_boolean has_good_shape(t_world world); +t_boolean is_closed(t_world world); +t_boolean has_illegal_character(t_world world); +t_location find_element(t_world world, char type); +int count_element(t_world world, char type); +int valid_elements(t_world world); +void is_solvable(char **map, int x, int y, int length_y); // ** COLLECTIBLES ** // -t_collectible *get_collectible_at(t_world world, t_location location); -void update_collectible(t_collectible *collectibles, t_location location, t_boolean collected); -void draw_collectibles(t_game game); -t_collectible *load_collectibles(t_world *world); -t_collectible *create_collectible(t_location location); -int count_collectibles(t_collectible collectibles, t_boolean o_uncollected, t_boolean o_collected); +t_collectible *load_collectibles(t_world *world); +t_collectible *create_collectible(t_location location); +t_collectible *get_collectible_at(t_world world, t_location location); +void update_col(t_collectible *lst, t_location loc, t_boolean bool); +void draw_collectibles(t_game game); +void last(t_collectible **lst, t_collectible *new); // ** TEXTURES ** // -t_textures load_textures(void *mlx); -t_texture load_texture(void *mlx, char character, char *path); -void draw_type(void *mlx, void *mlx_window, t_world *world, t_texture texture); - +t_textures load_textures(void *mlx); +t_texture load_texture(void *mlx, char character, char *path); +t_boolean has_unavailable_texture(t_textures textures); +void draw_type(t_game game, t_texture texture); +void draws(t_game game); // ** PLAYER ** // -int on_player_move(int keycode, t_game *world); -t_boolean is_solid(char c, t_game player); -t_boolean can_move(int code, t_game world); -t_player init_player(t_location location, t_collectible *collectibles); - +int on_player_move(int keycode, t_game *world); +t_boolean is_solid(char c, t_game player); +t_boolean can_move(int code, t_game world); +t_player init_player(t_location location, t_collectible *collectibles); // ** FREES ** // -void free_map(t_world *world); -void free_textures(t_game *game); -void free_collectibles(t_collectible *collectible); - - -int handle_launch_error(int argc, char *argv[], t_world *world); +void free_map(t_world *world); +void free_textures(t_game *game); +void free_collectibles(t_collectible *collectible); +void destroy(t_game *game); +int free_unavailable_texture(t_game game); #endif diff --git a/textures_utils.c b/textures_utils.c new file mode 100644 index 0000000..3a6de9e --- /dev/null +++ b/textures_utils.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* textures_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jbadaire +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/10/13 16:28:23 by jbadaire #+# #+# */ +/* Updated: 2023/10/13 16:28:23 by jbadaire ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "so_long.h" + +t_textures load_textures(void *mlx) +{ + t_textures textures; + + textures.wall = load_texture(mlx, '1', "./textures/wall.xpm"); + textures.grass = load_texture(mlx, '0', "./textures/grass.xpm"); + textures.player = load_texture(mlx, 'P', "./textures/player.xpm"); + textures.collectible = load_texture(mlx, 'C', "./textures/collectible.xpm"); + textures.exit = load_texture(mlx, 'E', "./textures/exit.xpm"); + return (textures); +} + +t_texture load_texture(void *mlx, char character, char *path) +{ + int img_width; + int img_height; + t_texture texture; + + texture.character = character; + texture.texture = mlx_xpm_file_to_image(mlx, path, &img_width, &img_height); + texture.is_set = _true; + return (texture); +} + +t_boolean has_unavailable_texture(t_textures textures) +{ + if (textures.exit.texture == NULL) + return (_true); + if (textures.player.texture == NULL) + return (_true); + if (textures.wall.texture == NULL) + return (_true); + if (textures.collectible.texture == NULL) + return (_true); + if (textures.grass.texture == NULL) + return (_true); + return (_false); +} diff --git a/utils.c b/utils.c index 7a70855..702ffbf 100644 --- a/utils.c +++ b/utils.c @@ -12,19 +12,22 @@ #include "so_long.h" -t_location find_element(t_world world, char type) +t_location find_element(t_world world, char type) { - int pos_x; - int pos_y; - t_location location; + int pos_x; + int pos_y; + t_location location; pos_x = 0; pos_y = 0; location.x = -1; location.y = -1; - while (world.map[pos_y]) { - while (pos_x < (int) ft_strlen(world.map[0])) { - if (world.map[pos_y][pos_x] == type) { + while (world.map[pos_y]) + { + while (pos_x < (int) ft_strlen(world.map[0])) + { + if (world.map[pos_y][pos_x] == type) + { location.x = ++pos_x; location.y = ++pos_y; return (location); @@ -37,24 +40,25 @@ t_location find_element(t_world world, char type) return (location); } -int count_element(t_world world, char type) +int count_element(t_world world, char type) { - int pos_x; - int pos_y; - int count; + int pos_x; + int pos_y; + int count; pos_x = 0; pos_y = 0; count = 0; - while (pos_y < world.length_y) { - while (pos_x < (int) ft_strlen(world.map[0])) { + while (pos_y < world.length_y) + { + while (pos_x < (int) ft_strlen(world.map[0])) + { if (world.map[pos_y][pos_x] == type) count++; - pos_x++; } pos_x = 0; pos_y++; } return (count); -} \ No newline at end of file +}