diff --git a/fillit/includes/fillit.h b/fillit/includes/fillit.h index 65df691c..54037caf 100644 --- a/fillit/includes/fillit.h +++ b/fillit/includes/fillit.h @@ -25,13 +25,13 @@ void ft_fill_board(char **dst, char **src); void ft_show_ttmn(t_ttmn ttmn); void ft_show_board(char **board); -int ft_board_add(char **board, t_ttmn block, size_t i, size_t j); +int ft_board_add(char **board, t_ttmn block, int i); void ft_board_remove(char **board, char c); int ft_solver(char **board, t_ttmn *ttmn); -int ft_validate_waste(char **board, t_ttmn *blocks, int max_waste); -int ft_waste_around(char ***board_ptr, int i, int j); -int ft_waste_here(char ***board_ptr, int i, int j); +int ft_validate_waste(char **board, t_ttmn *ttmn); +int ft_waste_around(char **board, int size, int i); +int ft_waste_here(char **board, int size, int i); #endif diff --git a/fillit/src/fillit_lib.c b/fillit/src/fillit_lib.c index 8b5602e0..193ec552 100644 --- a/fillit/src/fillit_lib.c +++ b/fillit/src/fillit_lib.c @@ -62,6 +62,22 @@ void ft_free_board(char ***board) *board = NULL; } +void ft_board_replace(char **board, char a, char b) +{ + int i; + int j; + + i = -1; + while (board[++i]) + { + j = -1; + while (board[i][++j]) + { + if (board[i][j] == a) + board[i][j] = b; + } + } +} void ft_board_remove(char **board, char c) { @@ -80,34 +96,34 @@ void ft_board_remove(char **board, char c) } } -int ft_board_add(char **board, t_ttmn block, size_t i, size_t j) +int ft_board_add(char **board, t_ttmn block, int i) { int x; int y; - size_t k; + int k; int size; size = ft_strlen(*board); k = 0; while (k < 4) { - x = (int)j + block.pos[k][1]; - y = (int)i + block.pos[k][0]; + x = i % size + block.pos[k][1]; + y = i / size + block.pos[k][0]; /* printf("adding %c to %i,%i\n", block.id, y, x); */ /* fflush(stdout); */ if (x > size - 1 || y > size - 1 || x < 0 || y < 0) return (1); - if (board[y][x] != '.' && board[y][x] != '*') + if (board[y][x] != '.' && board[y][x] != '*' && board[y][x] != '^') return (1); - /* ft_show_board(board); */ k++; } k = 0; while (k < 4) { - x = (int)j + block.pos[k][1]; - y = (int)i + block.pos[k][0]; + x = i % size + block.pos[k][1]; + y = i / size + block.pos[k][0]; board[y][x] = block.id; + /* ft_show_board(board); */ k++; } return (0); diff --git a/fillit/src/fillit_printer.c b/fillit/src/fillit_printer.c index 34fc407a..46a593d8 100644 --- a/fillit/src/fillit_printer.c +++ b/fillit/src/fillit_printer.c @@ -4,6 +4,11 @@ void ft_show_ttmn(t_ttmn ttmn) { int i; + if (!ttmn.id) + { + ft_putendl("end of ttmn\n"); + return ; + } printf("%c",ttmn.id); for (i=1; i < 4; i++) printf("\t%d,%d\n", ttmn.pos[i][0], ttmn.pos[i][1]); diff --git a/fillit/src/fillit_solver.c b/fillit/src/fillit_solver.c index c5d87179..b9f7a222 100644 --- a/fillit/src/fillit_solver.c +++ b/fillit/src/fillit_solver.c @@ -1,35 +1,35 @@ #include "fillit.h" +int ft_solved(char **board) +{ + printf("new solution : size %i\n", ft_strlen(*board)); + fflush(stdout); + g_sol = ft_copy_board(board); + ft_show_board(g_sol); + return (1); +} + int ft_solver(char **board, t_ttmn *ttmn) { int i; int j; int size; - int max_waste; + if (ttmn->id == '0') + return (ft_solver(board, ttmn + 1)); + if (!ttmn->id) + return (ft_solved(board)); /* ft_show_board(board); */ size = ft_strlen(*board); - max_waste = size * size - 4 * g_ttmn; - if (!(*ttmn).id) - { - printf("new solution : size %i\n", size); - g_sol = ft_copy_board(board); - return (1); - } i = -1; - while (++i < size) + while (++i < size * size) { - j = -1; - while (++j < size) - { - if (ft_board_add(board, *ttmn, i, j)) - continue ; - if (!ft_validate_waste(board, ttmn + 1, max_waste)) - ; - else if (ft_solver(board, ttmn + 1)) - return (1); - ft_board_remove(board, ttmn->id); - } + /* ft_show_board(board); */ + if (ft_board_add(board, *ttmn, i)) + continue ; + if (ft_validate_waste(board, ttmn + 1)) + return (1); + ft_board_remove(board, ttmn->id); } return (0); } diff --git a/fillit/src/fillit_waste.c b/fillit/src/fillit_waste.c index 3c40baed..3cd003d0 100644 --- a/fillit/src/fillit_waste.c +++ b/fillit/src/fillit_waste.c @@ -1,85 +1,127 @@ #include "fillit.h" -int ft_waste_here(char ***board_ptr, int i, int j) +int ft_waste_here(char **board, int size, int i) { int n; n = 0; - if (board_ptr[0][i][j] == '.') + if (board[i / size][i % size] == '.') { - board_ptr[0][i][j] = '*'; + board[i / size][i % size] = '*'; n++; - n += ft_waste_around(board_ptr, i, j); + n += ft_waste_around(board, size, i); } return (n); } -int ft_waste_around(char ***board_ptr, int i, int j) +int ft_waste_around(char **board, int size, int i) { - size_t size; - size_t n; + int n; - size = ft_strlen(**board_ptr); n = 0; - n += i > 0 ? ft_waste_here(board_ptr, i - 1, j) : 0; - n += j > 0 ? ft_waste_here(board_ptr, i, j - 1) : 0; - n += i < (int)size - 1 ? ft_waste_here(board_ptr, i + 1, j) : 0; - n += j < (int)size - 1 ? ft_waste_here(board_ptr, i, j + 1) : 0; + n += i / size > 0 ? ft_waste_here(board, size, i - size) : 0; + n += i % size > 0 ? ft_waste_here(board, size, i - 1) : 0; + n += i / size < size - 1 ? ft_waste_here(board, size, i + size) : 0; + n += i % size < size - 1 ? ft_waste_here(board, size, i + 1) : 0; return (n); } -int ft_additional_waste(char **board, t_ttmn *ttmn, int i, int j) +int ft_fit_any(char **board, t_ttmn *ttmn, int i, int blob) { - int y; - int x; - int l; - int size; + int y; + int l; + int size; + char tmp; + int n; + /* printf("going to fit any at %i,%i\n", i, j); */ + /* fflush(stdout); */ /* ft_show_board(board); */ - y = i - 1; - x = j - 1; + y = i; + n = blob; size = ft_strlen(*board); - while (++y < size) + while (y < size * size) { - x = (x == size ? -1 : x); - while (++x < size); + if (board[y / size][y % size] == '*') { + n--; l = -1; + /* printf("0 trying all at %i\n", y); */ + /* fflush(stdout); */ while (ttmn[++l].id) - if (!ft_board_add(board, ttmn[l], i, j)) - return (0); + { + /* printf("1 trying %c at %i\n", ttmn[l].id, y); */ + /* fflush(stdout); */ + if (ttmn[l].id == '0') + continue ; + if (ft_board_add(board, ttmn[l], y)) + continue ; + /* printf("passed board add\n"); */ + /* fflush(stdout); */ + /* ft_show_board(board); */ + ft_board_remove(board, '*'); + ft_board_remove(board, '^'); + if (!ttmn[1].id) + return(ft_solved(board)); + tmp = ttmn[l].id; + ttmn[l].id = '0'; + if (ft_solver(board, ttmn)) + return (1); + ttmn[l].id = tmp; + ft_board_remove(board, ttmn[l].id); + ft_waste_here(board, size, y); + /* ft_show_board(board); */ + } + /* printf("failed at %i\n", y); */ + /* fflush(stdout); */ } + y++; } - return (1); + return (0); } -int ft_validate_waste(char **board, t_ttmn *ttmn, int max_waste) +int ft_validate_waste(char **board, t_ttmn *ttmn) { int waste; - int i; - int j; + int y; int blob; int size; - board = ft_copy_board(board); + if (ttmn->id == '0') + return (ft_solver(board, ttmn + 1)); + if (!ttmn->id) + return (ft_solved(board)); waste = 0; size = ft_strlen(*board); - i = -1; + y = -1; /* ft_show_board(board); */ - while (++i < size) + while (++y < size * size) { - j = -1; - while (++j < size) + if (board[y / size][y % size] != '.') + continue ; + ft_board_replace(board, '*', '^'); + blob = ft_waste_here(board, size, y); + /* printf("found blob=%i at %i\n", blob, y); */ + /* fflush(stdout); */ + /* ft_show_board(board); */ + waste += blob % 4; + if (waste > size * size - 4 * g_ttmn) { - blob = ft_waste_here(&board, i, j); - /* if (blob / 4 == 1) */ - /* waste += ft_additional_waste(board, ttmn, i, j); */ - waste += blob % 4; - if (waste > max_waste) - { - return (0); - } + ft_board_remove(board, '*'); + ft_board_remove(board, '^'); + return (0); + } + if (blob / 4 == 1 && ft_fit_any(board, ttmn, y, blob)) + return (1); + waste += (blob / 4 == 1) ? 4 : 0; + if (waste > size * size - 4 * g_ttmn) + { + ft_board_remove(board, '*'); + ft_board_remove(board, '^'); + return (0); } } - return(1); + ft_board_remove(board, '*'); + ft_board_remove(board, '^'); + return (ft_solver(board, ttmn)); } diff --git a/fillit/src/main.c b/fillit/src/main.c index 3453b616..75116c60 100644 --- a/fillit/src/main.c +++ b/fillit/src/main.c @@ -18,7 +18,7 @@ int main(int ac, char **av) ft_usage(); return (1); } - size = g_target + 3; + size = g_target + 2; while (size >= (int)g_target) { board = ft_empty_board(size);