반응형
지도 파싱 생각하기
- 이미지 파일, RGB는 순서 상관없이 읽을 수 있어야 함.
- 그 밑에 지도는 무조건 제일 밑에 옴
- 허용되는 것은 0, 1, N, S, W, E이며 공백이 들어오더라도 읽을 수 있어야함.
NO ./path_to_the_north_texture
SO ./path_to_the_south_texture
WE ./path_to_the_west_texture
EA ./path_to_the_east_texture
F 220,100,0
C 225,30,0
1111111111111111111111111
1000000000110000000000001
1011000001110000000000001
1001000000000000000000001
111111111011000001110000000000001
100000000011000001110111111111111
11110111111111011100000010001
11110111111111011101010010001
11000000110101011100000010001
10000000000000001100000010001
10000000000000001101010010001
11000001110101011111011110N0111
11110111 1110101 101111010001
11111111 1111111 111111111111
알고리즘
- gnl을 사용해서 한 줄을 읽는데 count 변수를 주어서 무조건 지도 윗부분을 먼저 읽게 만든다.
- 이미지 파일과 rgb를 읽고 유효한지 검사.
- 지도를 읽을 때는 gnl을 한 값들이 0, 1, N, S, W, E, (공백)인지 본다.
- 읽은 지도를 통해 wall벽을 검사한다.
- 읽은 지도의 0주변을 검사한다.
- xml 파일과 rgb가 겹치는 것이 없는지 검사한다.
5번은 무슨 말이냐 → 규칙을 찾은 것이다.
지도에서 0을 기준으로 동, 서, 남, 북, 대각선 전부 포함하여 8개가 나오는데 이 8개가 널이 아니며 공백이 아니다 이것을 검사하면 유효한 지도인지 판별 할 수가 있다.
헤더 파일
typedef struct s_img
{
void *img_no;
char *img_no_name;
void *img_so;
char *img_so_name;
void *img_we;
char *img_we_name;
void *img_ea;
char *img_ea_name;
int ceil[3];
int ceil_flag;
int floor[3];
int floor_flag;
} t_img;
typedef struct s_game
{
char *map;
char **map_copy;
int height;
int width;
int player_count;
int fd;
t_img *img;
void *mlx;
void *mlx_win;
} t_game;
- t_game
- map → gnl을 할 때 사용
- map_copy → map을 1차원으로 만들어줄 것임.
- height → map의 높이
- player_count → player의 수
- fd → gnl 사용
- t_img
- void *(변수) → mlx_put_img 사용
- char *(변수) → xml의 이름들을 넣어줄 것임.
cub3d_main.c
int main(int argc, char **argv)
{
t_game game;
if (argc != 2)
error("Error\\n");
if (!(check_argv(argv[1])))
error("Error\\n");
init_game(&game, argv[1]);
read_map(&game);
if (game.map == (void *)0)
error("map error\\n");
check_map(&game);
check_overlap(&game);
exit(0);
}
- check_argv → 지도의 .cub가 잘 들어오는지 확인
- init_game → 구조체 초기화
- read_map → gnl
- check_map → wall, 0주변 검사
- check_overlap → xml 파일, rgb 중복 검사.
read_map 함수
void read_map(t_game *game)
{
char *map_buf;
char *line;
int count;
map_buf = NULL;
line = NULL;
count = 0;
while (1)
{
line = get_next_line(game->fd);
if (!line)
break ;
if (count <= 5)
check_dir_rgb(line, game, &count);
else
if (map_check(&line, &map_buf, game) == 1)
error("invalid input map2\\n");
free(line);
line = NULL;
}
close(game->fd);
game->map = map_buf;
free(line);
}
- count ≤ 5 → rgb, xml 파일 읽기
- 이게 아니면 map을 전부 읽음 개행 포함.
- check_dir_rgb → xml 파일인지, rgb에 따라 각각 검사와 실행.
- map_check → 0, 1, N, S, W, E, (공백) 검사.
check_map 함수
void check_map(t_game *game)
{
char **map_copy;
long location;
char *one_copy;
int hei;
hei = 0;
if (game->player_count >= 2 || game->player_count == 0)
error("play_direction error\\n");
location = first_new_line_delete(game->map);
one_copy = middle_new_line_check(game->map + location);
map_copy = split_string(one_copy, '\\n');
if (map_copy == (void *)0)
error("map two error\\n");
if (only_space(map_copy[0]) == 1)
error("first error\\n");
check_zero(map_copy);
check_wall(map_copy);
game->map_copy = map_copy;
while (game->map_copy[hei])
hei++;
game->height = hei;
free(one_copy);
free(game->map);
}
- if (game->player_count >= 2 || game->player_count == 0)
- player가 2개 이상일 때와 없을 때 에러
- first_new_line_delete → 1차원 map에 앞에 개행부분 없애주기. 그 위치 저장
- middle_new_line_check → 앞에 개행 없애준 1차원 map.
- split_string → 개행 기준으로 split → 2차원 배열 map
- check_zero → 0주변 검사
- check_wall
- 2차원의 맵에서 첫 번째 줄과 마지막 줄이 (공백), 1로 이루어져 있는지 검사.
- 한 줄마다 검사를 진행하는데 만약 공백만 있는 게 아니라면 한 줄의 첫 번째 자리와 마지막 1인지 검사.
check_overlap 함수
void check_overlap(t_game *game)
{
int i;
int j;
char **temp;
i = -1;
temp = (char **)malloc(sizeof(char *) * 5);
temp[0] = game->img->img_no_name;
temp[1] = game->img->img_so_name;
temp[2] = game->img->img_we_name;
temp[3] = game->img->img_ea_name;
temp[4] = 0;
while (++i < 4)
{
j = -1;
while (++j < 4)
{
if (i == j)
continue ;
else
overlap_direction(temp[i], temp[j]);
}
}
overlap_rgb(game);
char_two_free(temp);
}
반응형