nice architecture, 12 tetri -> 20s

This commit is contained in:
Jack Halford 2016-08-31 18:59:11 +02:00
parent c72b51aeea
commit a349813cd3
33 changed files with 1083 additions and 123 deletions

View file

@ -0,0 +1,4 @@
####
...#
....
....

View file

@ -0,0 +1,4 @@
...#
..#.
.#..
#...

View file

@ -0,0 +1,4 @@
##...
##...
....
....

View file

@ -0,0 +1,3 @@
#.
##
#.

View file

@ -0,0 +1,4 @@
....
....
....
....

View file

@ -0,0 +1,4 @@
..##
....
....
##..

View file

@ -0,0 +1,4 @@
####
####
####
####

View file

@ -0,0 +1,4 @@
,,,,
####
,,,,
,,,,

View file

@ -0,0 +1,4 @@
.HH.
HH..
....
....

View file

@ -0,0 +1,4 @@
....
.##.
.##.
....

View file

@ -0,0 +1,4 @@
....
....
....
####

View file

@ -0,0 +1,4 @@
....
#...
#...
##..

View file

@ -0,0 +1,4 @@
...#
..##
...#
....

20
fillit/examples/ko_00 Normal file
View file

@ -0,0 +1,20 @@
...#
...#
...#
...#
....
....
....
####
.###
...#
....
....
....
..##
.##.
....

9
fillit/examples/ko_01 Normal file
View file

@ -0,0 +1,9 @@
....
....
####
....
....
...
..##
..##

9
fillit/examples/ok_01 Normal file
View file

@ -0,0 +1,9 @@
#...
#...
#...
#...
##..
##..
....
....

19
fillit/examples/ok_02 Normal file
View file

@ -0,0 +1,19 @@
....
##..
.#..
.#..
....
####
....
....
#...
###.
....
....
....
##..
.##.
....

39
fillit/examples/ok_03 Normal file
View file

@ -0,0 +1,39 @@
...#
...#
...#
...#
....
....
....
####
.###
...#
....
....
....
..##
.##.
....
....
.##.
.##.
....
....
....
##..
.##.
##..
.#..
.#..
....
....
###.
.#..
....

View file

@ -0,0 +1,44 @@
....
.##.
.##.
....
...#
...#
...#
...#
....
..##
.##.
....
....
..#.
.##.
.#..
.###
...#
....
....
##..
.#..
.#..
....
....
..##
.##.
....
.#..
.##.
..#.
....
....
###.
.#..
....

View file

@ -0,0 +1,54 @@
....
.##.
.##.
....
...#
...#
...#
...#
....
..##
.##.
....
....
.##.
.##.
....
....
..#.
.##.
.#..
.###
...#
....
....
##..
.#..
.#..
....
....
..##
.##.
....
##..
.#..
.#..
....
.#..
.##.
..#.
....
....
###.
.#..
....

View file

@ -0,0 +1,59 @@
....
.##.
.##.
....
.#..
.##.
.#..
....
....
..##
.##.
....
....
.##.
.##.
....
....
..#.
.##.
.#..
.###
...#
....
....
##..
.#..
.#..
....
....
.##.
.##.
....
....
..##
.##.
....
##..
.#..
.#..
....
.#..
.##.
..#.
....
....
###.
.#..
....

View file

@ -0,0 +1,64 @@
....
.##.
.##.
....
.##.
.#..
.#..
....
.#..
.##.
.#..
....
....
..##
.##.
....
....
.##.
.##.
....
....
..#.
.##.
.#..
.###
...#
....
....
##..
.#..
.#..
....
....
.##.
.##.
....
....
..##
.##.
....
##..
.#..
.#..
....
.#..
.##.
..#.
....
....
###.
.#..
....

View file

@ -0,0 +1,124 @@
....
.##.
.##.
....
.#..
.##.
.#..
....
....
..##
.##.
....
....
.##.
.##.
....
....
..#.
.##.
.#..
.###
...#
....
....
##..
.#..
.#..
....
....
..##
.##.
....
##..
.#..
.#..
....
.#..
.##.
..#.
....
...#
.###
....
....
....
###.
.#..
....
....
.##.
.##.
....
.#..
.##.
.#..
....
....
..##
.##.
....
....
.##.
.##.
....
....
..#.
.##.
.#..
.###
...#
....
....
##..
.#..
.#..
....
....
.##.
.##.
....
....
..##
.##.
....
##..
.#..
.#..
....
.#..
.##.
..#.
....
...#
.###
....
....
....
###.
.#..
....

View file

@ -0,0 +1,129 @@
....
.##.
.##.
....
.#..
.##.
.#..
....
....
..##
.##.
....
....
.##.
.##.
....
....
..#.
.##.
.#..
.###
...#
....
....
##..
.#..
.#..
....
....
.##.
.##.
....
....
..##
.##.
....
##..
.#..
.#..
....
.#..
.##.
..#.
....
...#
.###
....
....
....
###.
.#..
....
....
.##.
.##.
....
.#..
.##.
.#..
....
....
..##
.##.
....
....
.##.
.##.
....
....
..#.
.##.
.#..
.###
...#
....
....
##..
.#..
.#..
....
....
.##.
.##.
....
....
..##
.##.
....
##..
.#..
.#..
....
.#..
.##.
..#.
....
...#
.###
....
....
....
###.
.#..
....

View file

@ -5,7 +5,9 @@
# define FILLIT_H # define FILLIT_H
# define BUF_SIZE 32 # define BUF_SIZE 32
extern size_t g_size; extern size_t g_target;
extern size_t g_ttmn;
extern char **g_sol;
typedef struct s_ttmn typedef struct s_ttmn
{ {
@ -14,7 +16,25 @@ typedef struct s_ttmn
} t_ttmn; } t_ttmn;
t_ttmn *ft_get_ttmn(char *filename); t_ttmn *ft_get_ttmn(char *filename);
void ft_free_board(char ***board);
char **ft_empty_board(size_t size);
void ft_fill_board(char **dst, char **src);
char **ft_copy_board(char **board);
void ft_show_ttmn(t_ttmn ttmn); void ft_show_ttmn(t_ttmn ttmn);
void ft_show_board(char **board); void ft_show_board(char **board);
void ft_grow_board(char **board);
void ft_shrink_board(char **board);
int ft_addto_board(char **board, t_ttmn block, size_t i, size_t j);
void ft_takeoff_board(char **board, char c);
int ft_check_pos(char **board, t_ttmn block, int i, int j);
int ft_solver(char **board, t_ttmn *ttmn);
int ft_validate_waste(char **board, t_ttmn *blocks);
int ft_waste_around(char ***board_ptr, int i, int j);
int ft_waste_here(char ***board_ptr, int i, int j);
#endif #endif

@ -1 +1 @@
Subproject commit b12c10b76eee97e4ed9f5aafef7954cd06c0e9f3 Subproject commit c431b5aeb40a6679537c6a88cced23b0d409d8ba

135
fillit/src/fillit_lib.c Normal file
View file

@ -0,0 +1,135 @@
#include "fillit.h"
char **ft_copy_board(char **board)
{
size_t size;
char **copy;
size = ft_strlen(*board);
copy = ft_empty_board(size);
ft_fill_board(copy, board);
return (copy);
}
void ft_fill_board(char **dst, char **src)
{
int i;
int j;
i = 0;
while (src[i])
{
j = 0;
while (src[i][j])
{
dst[i][j] = src[i][j];
j++;
}
i++;
}
}
char **ft_empty_board(size_t size)
{
char **board;
int i;
int j;
board = (char **)malloc(sizeof(char *) * (size + 1));
i = -1;
while (++i < (int)size)
{
board[i] = ft_strnew(size);
j = -1;
while (++j < (int)size)
board[i][j] = '.';
}
board[i] = NULL;
return (board);
}
void ft_free_board(char ***board)
{
int i;
i = 0;
while ((*board)[i])
{
free((*board)[i]);
i++;
}
free(*board);
*board = NULL;
}
void ft_grow_board(char **board)
{
int i;
int size;
size = ft_strlen(*board);
i = 0;
while (++i <= size)
{
board[i][size] = '.';
board[size][i] = '.';
}
}
void ft_shrink_board(char **board)
{
int i;
int size;
size = ft_strlen(*board);
i = -1;
while (++i < size)
{
board[i][size - 1] = '\0';
board[size - 1][i] = '\0';
}
}
void ft_takeoff_board(char **board, char c)
{
int i;
int j;
i = -1;
while (board[++i])
{
j = -1;
while (board[i][++j])
{
if (board[i][j] == c)
board[i][j] = '.';
}
}
}
int ft_addto_board(char **board, t_ttmn block, size_t i, size_t j)
{
int x;
int y;
size_t k;
int size;
size = ft_strlen(*board);
k = 0;
if (block.id)
while (k < 4)
{
x = (int)j + block.pos[k][1];
y = (int)i + 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] != '.')
return (1);
board[y][x] = block.id;
/* ft_show_board(board); */
k++;
}
return (0);
}

120
fillit/src/fillit_parser.c Normal file
View file

@ -0,0 +1,120 @@
#include "fillit.h"
size_t g_target = 0;
size_t g_ttmn = 0;
int ft_validate_ttmn(t_ttmn block)
{
size_t i;
size_t j;
int touch;
if (!(block.id >= 'A' && block.id <= 'Z'))
return(0);
i = -1;
touch = 0;
while (++i < 4)
{
j = -1;
while (++j < 4)
{
if (i != j
&& ((DIST(block.pos[i][0], block.pos[j][0]) == 0
&& DIST(block.pos[i][1], block.pos[j][1]) == 1)
|| (DIST(block.pos[i][0], block.pos[j][0]) == 1
&& DIST(block.pos[i][1], block.pos[j][1]) == 0)))
touch++;
}
}
if (touch == 6 || touch == 8)
return (1);
return (0);
}
t_ttmn *ft_get_ttmn(char *filename)
{
int fd;
char buf[BUF_SIZE + 1];
int ret;
size_t i;
size_t j;
size_t k;
size_t l;
int ref[2];
t_ttmn *ttmn;
ttmn = (t_ttmn *)ft_memalloc(sizeof(*ttmn) * 27);
fd = open(filename, O_RDONLY);
if (fd == -1)
return (0);
k = 0;
j = 0;
l = 0;
while ((ret = read(fd, buf, BUF_SIZE)))
{
buf[ret] = '\0';
i = 0;
while (buf[i])
{
/* printf("%i, %i, %i: '%c'\n", i, j, k, buf[i]); */
if (buf[i] == '.')
;
else if (buf[i] == '#')
{
if (k == 0)
{
ref[0] = j / 5;
ref[1] = j % 5;
ttmn[l].pos[0][0] = 0;
ttmn[l].pos[0][1] = 0;
ttmn[l].id = 'A' + l;
}
else if (k <= 3)
{
ttmn[l].pos[k][0] = j / 5 - ref[0];
ttmn[l].pos[k][1] = j % 5 - ref[1];
}
else
return (0);
k++;
}
else if (buf[i] == '\n')
{
if (i > 0 && buf[i - 1] == '\n')
{
if (j != 20)
return (0);
if (!ft_validate_ttmn(ttmn[l]))
return (0);
l++;
j = -1;
k = 0;
}
else
{
if ((j + 1) % 5 != 0)
return (0);
}
}
else
{
return (0);
}
i++;
j++;
}
}
if (j != 20)
return (0);
if (!ft_validate_ttmn(ttmn[l]))
return (0);
l++;
g_target = 2;
g_ttmn = l;
while ((l * 4) > (g_target) * (g_target))
g_target++;
printf("n_ttmn=%zu, target=%zu\n", l, g_target);
ttmn[l].id = '\0';
return (ttmn);
}

View file

@ -0,0 +1,19 @@
#include "fillit.h"
void ft_show_ttmn(t_ttmn ttmn)
{
int i;
printf("%c",ttmn.id);
for (i=1; i < 4; i++)
printf("\t%d,%d\n", ttmn.pos[i][0], ttmn.pos[i][1]);
ft_putendl("");
}
void ft_show_board(char **board)
{
/* ft_putendl("-s-"); */
while (*board)
ft_putendl(*board++);
ft_putendl("");
}

View file

@ -0,0 +1,72 @@
#include "fillit.h"
int ft_check_pos(char **board, t_ttmn block, int i, int j)
{
size_t k;
int new_size;
int size;
int x;
int y;
size = ft_strlen(*board);
new_size = size;
k = -1;
while (++k < 4)
{
x = (int)j + block.pos[k][1];
y = (int)i + block.pos[k][0];
/* if (block.id == 'L') */
/* printf("trying %i, %i\n", y, x); */
if (x < 0 || x < 0)
return (100);
if (x > size - 1 || y > size - 1)
{
new_size = MAX(new_size, MAX(x + 1, y + 1));
continue ;
}
if (board[y][x] != '.' && board[y][x] != '*')
return (100);
}
return (new_size);
}
int ft_solver(char **board, t_ttmn *ttmn)
{
int i;
int j;
int size;
char **tmp;
size = ft_strlen(*board);
if (!(*ttmn).id)
{
printf("new solution : size %i\n", size);
g_sol = ft_copy_board(board);
return (1);
}
i = -1;
while (++i < size)
{
j = -1;
while (++j < size)
{
if (ft_addto_board(board, *ttmn, i, j))
{
ft_takeoff_board(board, ttmn->id);
continue ;
}
/* printf("validated for addto\n"); */
tmp = ft_copy_board(board);
if (size == (int)g_target && !ft_validate_waste(tmp, ttmn + 1))
{
ft_takeoff_board(board, ttmn->id);
continue ;
}
/* printf("validated for waste\n"); */
if (ft_solver(board, ttmn + 1))
return (1);
ft_takeoff_board(board, ttmn->id);
}
}
return (0);
}

82
fillit/src/fillit_waste.c Normal file
View file

@ -0,0 +1,82 @@
#include "fillit.h"
int ft_waste_here(char ***board_ptr, int i, int j)
{
int n;
n = 0;
if (board_ptr[0][i][j] == '.')
{
board_ptr[0][i][j] = '*';
n++;
n += ft_waste_around(board_ptr, i, j);
}
return (n);
}
int ft_waste_around(char ***board_ptr, int i, int j)
{
size_t size;
size_t 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;
/* printf("waste around %i,%i = %zu\n", i, j, n); */
return (n);
}
int ft_validate_waste(char **board, t_ttmn *ttmn)
{
int max_waste;
int waste;
int i;
int j;
int l;
int blob;
size_t size;
max_waste = g_target * g_target - g_ttmn * 4;
waste = 0;
size = ft_strlen(*board);
i = -1;
/* ft_show_board(board); */
while (++i < (int)size)
{
j = -1;
while (++j < (int)size)
{
blob = ft_waste_here(&board, i, j);
if (blob / 4 == 1)
{
waste += 4;
l = -1;
/* ft_show_board(board); */
while (ttmn[++l].id)
{
/* ft_show_ttmn(ttmn[l]); */
/* printf("checking at %i,%i = %i vs %i\n", i, j, ft_check_pos(board, ttmn[l], i, j), (int)size); */
fflush(stdout);
if (ft_check_pos(board, ttmn[l], i, j) == (int)size)
{
waste -= 4;
break ;
}
}
}
waste += blob % 4;
if (waste > max_waste)
{
/* printf("waste = %i (failed: max = %i)\n", waste, max_waste); */
/* fflush(stdout); */
return (0);
}
}
}
/* printf("waste = %i (passed: max = %i)\n", waste, max_waste); */
/* fflush(stdout); */
return(1);
}

View file

@ -1,140 +1,31 @@
#include "fillit.h" #include "fillit.h"
size_t g_size = 20; char **g_sol = NULL;
void ft_usage(void) void ft_usage(void)
{ {
ft_putendl("error"); ft_putendl("error");
} }
int ft_check_pos(char **board, t_ttmn block, size_t i, size_t j)
{
size_t size;
size_t k;
size = 0;
if (board)
size = ft_strlen(*board);
k = -1;
while (++k < 3)
{
if (i + block.pos[k][0] >= size || j + block.pos[k][1] >= size)
continue ;
if (board[i + block.pos[k][0]][j + block.pos[k][1]] != '.')
return (0);
}
return (1);
}
void ft_grow_board(char ***board_ptr)
{
size_t size;
size_t i;
size_t j;
char **new_board;
char **board;
board = *board_ptr;
size = board ? ft_strlen(*board) : 0;
new_board = (char **)malloc(sizeof(char *) * (size + 1));
i = -1;
while (++i < size)
{
new_board[i] = ft_strjoin(board[i], ".");
free(board[i]);
}
j = -1;
new_board[i] = (char *)malloc(sizeof(char) * (size + 1));
while (++j < size + 1)
{
new_board[i][j] = '.';
}
free(*board_ptr);
*board_ptr = new_board;
}
char **ft_next_board(char **board, t_ttmn block, size_t i, size_t j)
{
size_t size;
size_t k;
char **new_board;
size = board ? ft_strlen(*board) : 0;
new_board = size ? (char **)malloc(sizeof(char *) * size) : NULL;
k = -1;
while (++k < size)
new_board[k] = ft_strdup(board[k]);
k = 0;
while (k < 4)
{
if (i + block.pos[k][0] >= size || j + block.pos[k][1] >= size)
{
ft_grow_board(&new_board);
size++;
continue ;
}
new_board[i + block.pos[k][0]][j + block.pos[k][1]] = block.id;
k++;
}
return (new_board);
}
int ft_solver(char **board, t_ttmn *ttmn)
{
size_t i;
size_t j;
char **new_board;
ft_show_ttmn(*ttmn);
ft_show_board(board);
if (!(*ttmn).id)
{
g_size = ft_strlen(*board);
printf("new solution : size = %zu\n", g_size);
return(0);
}
i = 0;
while (i < g_size)
{
j = 0;
while (j <= i)
{
printf("trying: %zu,%zu\n", i, j);
if (ft_check_pos(board, *ttmn, i, j))
{
printf("pos ok : %zu,%zu\n", i, j);
new_board = ft_next_board(board, *ttmn, i, j);
if (ft_solver(new_board, ttmn + 1))
return (1);
free(new_board);
}
if (j != i && ft_check_pos(board, *ttmn, j, i))
{
printf("pos ok : %zu,%zu\n", j, i);
new_board = ft_next_board(board, *ttmn, j, i);
if (ft_solver(new_board, ttmn + 1))
return (1);
free(new_board);
}
j++;
}
i++;
}
return (0);
}
int main(int ac, char **av) int main(int ac, char **av)
{ {
t_ttmn *ttmn; t_ttmn *ttmn;
char **board;
int size;
if (ac != 2 || !(ttmn = ft_get_ttmn(av[1]))) if (ac != 2 || !(ttmn = ft_get_ttmn(av[1])))
{ {
ft_usage(); ft_usage();
return (1); return (1);
} }
/* int l = -1; */ size = g_target + 3;
/* while (ttmn[++l].id) */ while (size >= (int)g_target)
/* ft_show_ttmn(ttmn[l]); */ {
ft_solver(NULL, ttmn); board = ft_empty_board(size);
ft_solver(board, ttmn);
ft_free_board(&board);
size--;
}
ft_show_board(g_sol);
return (0); return (0);
} }