intra to gitea

This commit is contained in:
lfirmin
2025-11-16 09:58:07 +01:00
commit 50c15b30e1
163 changed files with 12672 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/12 11:00:04 by lfirmin #+# #+# */
/* Updated: 2024/11/12 15:53:59 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../include/so_long.h"
int get_map_dimensions(t_data *data, int *width, int *height)
{
*height = 0;
while (data->map[*height])
{
if (*height == 0)
*width = ft_strlen(data->map[0]);
else if ((int)ft_strlen(data->map[*height]) != *width)
return (1);
(*height)++;
}
return (0);
}
int launch_game(t_data *data)
{
t_game *game;
int width;
int height;
if (get_map_dimensions(data, &width, &height))
return (ft_printf_fd(2, "Error : Invalid map dimensions\n"), 1);
game = malloc(sizeof(t_game));
if (!game)
return (1);
init_struct(game);
game->map = data->map;
game->map_width = width;
game->map_height = height;
game->collectibles = data->colect;
game->moves = 0;
game->data = data;
if (init_game(game))
return (free(game), 1);
mlx_hook(game->win, 2, 1L << 0, key_hook, game);
mlx_hook(game->win, 17, 1L << 17, close_game, game);
draw_map(game);
mlx_loop(game->mlx);
return (0);
}
int main(int ac, char **av)
{
t_data *data;
if (ac != 2)
return (ft_printf_fd(2, "Error : Usage: ./so_long map.ber\n"), 1);
data = init_data();
if (!data)
return (ft_printf_fd(2, "Error : Init failed\n"), 1);
if (pars_map(data, av[1]) == 1)
return (1);
if (launch_game(data))
return (clean_data(data), 1);
return (0);
}
+129
View File
@@ -0,0 +1,129 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pars_map.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/12 16:16:49 by lfirmin #+# #+# */
/* Updated: 2024/11/16 18:41:22 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../include/so_long.h"
int ft_count_lines(char *file)
{
char c;
int fd;
int ret;
int count;
int last;
fd = open(file, O_RDONLY);
if (fd < 0)
return (-1);
count = 0;
last = '\n';
ret = read(fd, &c, 1);
while (ret > 0)
{
if (c == '\n')
count++;
last = c;
ret = read(fd, &c, 1);
}
if (last != '\n')
count++;
return (close(fd), count);
}
char *add_newline_if_needed(char *line)
{
size_t len;
char *new_line;
if (!line)
return (NULL);
len = strlen(line);
if (len > 0 && line[len - 1] != '\n')
{
new_line = malloc(len + 2);
if (!new_line)
return (NULL);
strcpy(new_line, line);
new_line[len] = '\n';
new_line[len + 1] = '\0';
free(line);
return (new_line);
}
return (line);
}
int get_map(char *file, t_data *data)
{
int fd;
int i;
int nb_lines;
nb_lines = ft_count_lines(file);
if (nb_lines <= 0)
return (ft_printf_fd(2, "Error : The map is empty\n"), 1);
data->map = malloc(sizeof(char *) * (nb_lines + 1));
if (!data->map)
return (1);
i = 0;
fd = open(file, O_RDONLY);
if (fd == -1)
return (ft_printf_fd(2, "Error : opening file %s\n", file), 1);
if (get_map_2(i, nb_lines, data, fd) == 1)
return (close(fd), 1);
return (close(fd), 0);
}
int check_close(t_data *data)
{
int i;
int j;
i = 1;
if (check_first_last_lines(data, 0) == 1)
return (1);
while (data->map[i + 1])
{
j = 1;
if (data->map[i][0] != '1')
return (ft_printf_fd(2, "Error : Map not closed\n"), 1);
while (data->map[i][j + 1])
j++;
if (data->map[i][j - 1] != '1')
return (ft_printf_fd(2, "Error : Map not closed\n"), 1);
i++;
}
return (check_first_last_lines(data, i));
}
int check_first_last_lines(t_data *data, int i)
{
int j;
j = 0;
while (data->map[0][j + 1] && data->map[0][j + 1] != '\n')
{
if (data->map[0][j] != '1')
return (ft_printf_fd(2, "Error : Map not closed\n"), 1);
j++;
}
if (data->map[0][j] != '1')
return (ft_printf_fd(2, "Error : Map not closed\n"), 1);
j = 0;
while (data->map[i][j + 1] && data->map[i][j + 1] != '\n')
{
if (data->map[i][j] != '1')
return (ft_printf_fd(2, "Error : Map not closed\n"), 1);
j++;
}
if (data->map[i][j] != '1')
return (ft_printf_fd(2, "Error : Map not closeds\n"), 1);
return (0);
}
+106
View File
@@ -0,0 +1,106 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pars_map_2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/12 17:51:27 by lfirmin #+# #+# */
/* Updated: 2024/11/12 17:51:27 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../include/so_long.h"
char **copy_map(char **original)
{
char **copy;
int i;
int height;
height = 0;
while (original[height])
height++;
copy = malloc(sizeof(char *) * (height + 1));
if (!copy)
return (NULL);
i = 0;
while (original[i])
{
copy[i] = ft_strdup(original[i]);
if (!copy[i])
{
while (i > 0)
free(copy[--i]);
free(copy);
return (NULL);
}
i++;
}
copy[i] = NULL;
return (copy);
}
int is_playable(t_data *data, int x, int y)
{
char **tmp_map;
tmp_map = copy_map(data->map);
if (!tmp_map)
return (clean_data(data), 1);
if (play_check(tmp_map, x, y) == 0)
return (free_map(tmp_map), 0);
return (free_map(tmp_map), 1);
}
int play_check(char **map, int x, int y)
{
if (map[y][x] == 'P')
return (0);
if (map[y][x] != '0' && map[y][x] != 'C' && map[y][x] != 'E')
return (2);
map[y][x] = '1';
if (play_check(map, x + 1, y) == 0)
return (0);
if (play_check(map, x - 1, y) == 0)
return (0);
if (play_check(map, x, y + 1) == 0)
return (0);
if (play_check(map, x, y - 1) == 0)
return (0);
return (1);
}
void free_map(char **map)
{
int i;
i = 0;
while (map[i])
free(map[i++]);
free(map);
}
int check_playable(t_data *data)
{
int i;
int j;
i = 1;
j = 1;
while (data->map[i + 1])
{
j = 1;
while (data->map[i][j + 1])
{
if (data->map[i][j] == 'C' || data->map[i][j] == 'E')
{
if (is_playable(data, j, i) == 1)
return (1);
}
j++;
}
i++;
}
return (0);
}
+124
View File
@@ -0,0 +1,124 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pars_map_3.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/12 20:07:42 by lfirmin #+# #+# */
/* Updated: 2024/11/12 20:07:42 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../include/so_long.h"
int have_require_item(t_data *data)
{
int i;
int j;
i = 1;
while (data->map[i])
{
j = 1;
while (data->map[i][j])
{
if (data->map[i][j] == 'E')
data->e++;
if (data->map[i][j] == 'P')
data->p++;
if (data->map[i][j] == 'C')
data->colect++;
j++;
}
i++;
}
if (data->e != 1 || data->p != 1)
return (ft_printf_fd(2, "Error : The number of E/P is invalid\n"), 1);
if (data->colect < 1)
return (ft_printf_fd(2, \
"Error : There are no collectables\n"), 1);
return (0);
}
int pars_map(t_data *data, char *file)
{
if (is_ber(file) == 1)
return (clean_data(data), 1);
if (get_map(file, data) == 1)
return (clean_data(data), 1);
if (check_char(data) == 1)
return (clean_data(data), 1);
if (check_rectangle(data) == 1)
return (clean_data(data), 1);
if (check_close(data) == 1)
return (clean_data(data), 1);
if (have_require_item(data) == 1)
return (clean_data(data), 1);
if (check_playable(data) == 1)
return (ft_printf_fd(2, \
"Error : Map not playable\n"), clean_data(data), 1);
return (0);
}
int check_rectangle(t_data *data)
{
size_t len;
int i;
len = ft_strlen(data->map[0]);
i = 1;
while (data->map[i])
{
if (ft_strlen(data->map[i]) != len)
return (ft_printf_fd(2, "Error : Invalid map format\n"), 1);
i++;
}
return (0);
}
int is_ber(char *file)
{
size_t len;
char *ext;
int i;
ext = ".ber";
if (!file)
return (ft_printf_fd(2, "Error: No file provided\n"), 1);
len = ft_strlen(file);
if (len < 4)
return (ft_printf_fd(2, "Error: Invalid file name\n"), 1);
i = 0;
while (i < 4)
{
if (file[len - 4 + i] != ext[i])
return (ft_printf_fd(2, "Error: File type isn't .ber\n"), 1);
i++;
}
return (0);
}
int check_char(t_data *data)
{
int i;
int j;
char c;
i = 0;
c = 0;
while (data->map[i])
{
j = 0;
while (data->map[i][j] && data->map[i][j] != '\n')
{
c = data->map[i][j];
if (c != 'E' && c != 'P' && c != 'C' && c != '0' && c != '1')
return (ft_printf_fd(2, \
"Error : invalid char -> '%c'\n", c), 1);
j++;
}
i++;
}
return (0);
}
+108
View File
@@ -0,0 +1,108 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/12 16:24:49 by lfirmin #+# #+# */
/* Updated: 2024/11/17 13:04:59 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../include/so_long.h"
t_data *init_data(void)
{
t_data *data;
data = malloc(sizeof(t_data));
if (!data)
return (NULL);
data->map = NULL;
data->colect = 0;
data->p = 0;
data->e = 0;
return (data);
}
void clean_data(t_data *data)
{
int i;
if (!data)
return ;
if (data->map)
{
i = 0;
while (data->map[i])
{
free(data->map[i]);
i++;
}
free(data->map);
}
free(data);
}
int init_window(t_game *game)
{
int screen_width;
int screen_height;
game->mlx = mlx_init();
if (!game->mlx)
return (1);
game->win = mlx_new_window(game->mlx,
game->map_width * 32 - 32,
game->map_height * 32,
"so_long");
mlx_get_screen_size(game->mlx, &screen_width, &screen_height);
if (screen_width < (game->map_width * 32 - 32))
return (ft_printf_fd(2, "Error : Map too big in width\n"), \
close_game(game), 1);
if (screen_height < (game->map_height * 32))
return (ft_printf_fd(2, "Error : Map too big in height\n"), \
close_game(game), 1);
if (!game->win)
return (ft_printf_fd(2, "Error\nMLX initialization failed\n"), \
close_game(game), 1);
return (0);
}
int init_images(t_game *game)
{
int img_width;
int img_height;
game->img_floor = mlx_xpm_file_to_image(game->mlx,
"assets/floor.xpm", &img_width, &img_height);
game->img_wall = mlx_xpm_file_to_image(game->mlx,
"assets/wall.xpm", &img_width, &img_height);
game->img_player = mlx_xpm_file_to_image(game->mlx,
"assets/player.xpm", &img_width, &img_height);
game->img_collect = mlx_xpm_file_to_image(game->mlx,
"assets/collectible.xpm", &img_width, &img_height);
game->img_exit = mlx_xpm_file_to_image(game->mlx,
"assets/exit.xpm", &img_width, &img_height);
if (!game->img_floor || !game->img_wall || !game->img_player
|| !game->img_collect || !game->img_exit)
{
ft_printf_fd(2, "Error : Image not found\n");
close_game(game);
return (1);
}
return (0);
}
int init_game(t_game *game)
{
if (init_window(game))
return (1);
if (init_images(game))
return (1);
game->moves = 0;
find_player_pos(game);
find_exit_pos(game);
return (0);
}
+93
View File
@@ -0,0 +1,93 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils_2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/13 12:34:24 by lfirmin #+# #+# */
/* Updated: 2024/11/13 12:34:24 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../include/so_long.h"
int close_game(t_game *game)
{
if (!game)
return (0);
if (game->img_floor)
mlx_destroy_image(game->mlx, game->img_floor);
if (game->img_wall)
mlx_destroy_image(game->mlx, game->img_wall);
if (game->img_player)
mlx_destroy_image(game->mlx, game->img_player);
if (game->img_collect)
mlx_destroy_image(game->mlx, game->img_collect);
if (game->img_exit)
mlx_destroy_image(game->mlx, game->img_exit);
if (game->win)
mlx_destroy_window(game->mlx, game->win);
if (game->mlx)
{
mlx_destroy_display(game->mlx);
free(game->mlx);
}
clean_data(game->data);
free(game);
return (exit(0), 0);
}
void update_player_position(t_game *game, int x, int y)
{
int old_x;
int old_y;
old_x = game->player_x;
old_y = game->player_y;
game->map[old_y][old_x] = '0';
if (old_x == game->exit_x && old_y == game->exit_y)
game->map[old_y][old_x] = 'E';
draw_tile(game, game->map[old_y][old_x], old_x, old_y);
game->map[y][x] = 'P';
draw_tile(game, 'P', x, y);
game->player_x = x;
game->player_y = y;
game->moves++;
printf("Moves: %d\n", game->moves);
}
void move_player(t_game *game, int new_x, int new_y)
{
char current_pos;
current_pos = game->map[new_y][new_x];
if (current_pos == 'E' && game->collectibles == 0)
{
ft_printf_fd(1, "Congratulations! You won in %d moves!\n", \
game->moves + 1);
close_game(game);
}
if (current_pos == 'C')
{
game->collectibles--;
if (game->collectibles == 0)
draw_tile(game, 'E', game->exit_x, game->exit_y);
}
update_player_position(game, new_x, new_y);
}
int is_valid_move(t_game *game, int x, int y)
{
if (x < 0 || x >= game->map_width || y < 0 || y >= game->map_height)
return (0);
if (game->map[y][x] == '1')
return (0);
if (game->map[y][x] == 'E')
{
if (game->collectibles == 0)
return (1);
return (1);
}
return (1);
}
+111
View File
@@ -0,0 +1,111 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils_3.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/13 16:51:15 by lfirmin #+# #+# */
/* Updated: 2024/11/13 16:51:15 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../include/so_long.h"
void draw_tile(t_game *game, char current, int x, int y)
{
mlx_put_image_to_window(game->mlx, game->win,
game->img_floor, x * 32, y * 32);
if (current == '1')
mlx_put_image_to_window(game->mlx, game->win,
game->img_wall, x * 32, y * 32);
else if (current == 'P')
mlx_put_image_to_window(game->mlx, game->win,
game->img_player, x * 32, y * 32);
else if (current == 'C')
mlx_put_image_to_window(game->mlx, game->win,
game->img_collect, x * 32, y * 32);
else if (current == 'E' && game->collectibles == 0)
mlx_put_image_to_window(game->mlx, game->win,
game->img_exit, x * 32, y * 32);
}
void draw_map(t_game *game)
{
int x;
int y;
char current;
y = 0;
while (y < game->map_height)
{
x = 0;
while (x < game->map_width)
{
current = game->map[y][x];
if (current != '\n')
draw_tile(game, current, x, y);
x++;
}
y++;
}
}
int check_player(t_game *game, int x, int y, int *found)
{
if (game->map[y][x] == 'P')
{
game->player_x = x;
game->player_y = y;
*found = 1;
}
return (0);
}
int find_player_pos(t_game *game)
{
int x;
int y;
int found;
if (!game || !game->map)
return (1);
y = 0;
found = 0;
while (y < game->map_height)
{
x = 0;
while (x < game->map_width)
{
check_player(game, x, y, &found);
x++;
}
y++;
}
if (!found)
return (ft_printf_fd(2, "Error: Player position not found\n"), 1);
return (0);
}
int key_hook(int keycode, t_game *game)
{
int new_x;
int new_y;
new_x = game->player_x;
new_y = game->player_y;
if (keycode == KEY_ESC)
close_game(game);
else if (keycode == KEY_W || keycode == KEY_UP)
new_y--;
else if (keycode == KEY_S || keycode == KEY_DOWN)
new_y++;
else if (keycode == KEY_A || keycode == KEY_LEFT)
new_x--;
else if (keycode == KEY_D || keycode == KEY_RIGHT)
new_x++;
else
return (0);
if (is_valid_move(game, new_x, new_y))
move_player(game, new_x, new_y);
return (0);
}
+75
View File
@@ -0,0 +1,75 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils_4.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/17 13:04:09 by lfirmin #+# #+# */
/* Updated: 2024/11/17 13:04:09 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../include/so_long.h"
void init_struct(t_game *game)
{
game->mlx = NULL;
game->win = NULL;
game->img_floor = NULL;
game->img_wall = NULL;
game->img_player = NULL;
game->img_collect = NULL;
game->img_exit = NULL;
game->player_x = 0;
game->player_y = 0;
game->moves = 0;
game->collectibles = 0;
game->map = NULL;
game->map_width = 0;
game->map_height = 0;
game->exit_x = 0;
game->exit_y = 0;
game->data = NULL;
}
int get_map_2(int i, int nb_lines, t_data *data, int fd)
{
char *line;
line = get_next_line(fd);
while (line != NULL && i < nb_lines)
{
if (i == nb_lines - 1)
line = add_newline_if_needed(line);
if (!line)
return (1);
data->map[i++] = line;
line = get_next_line(fd);
}
data->map[i] = NULL;
return (0);
}
void find_exit_pos(t_game *game)
{
int x;
int y;
y = 0;
while (y < game->map_height)
{
x = 0;
while (x < game->map_width)
{
if (game->map[y][x] == 'E')
{
game->exit_x = x;
game->exit_y = y;
return ;
}
x++;
}
y++;
}
}