-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbacktracking.c
111 lines (99 loc) · 2.95 KB
/
backtracking.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* backtracking.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rhallste <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/11/04 12:39:15 by rhallste #+# #+# */
/* Updated: 2017/11/18 15:05:29 by rhallste ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft/inc/libft.h"
#include "fillit.h"
#include <stdio.h>
static long long pad_shape(t_piece *piece, int pad_by)
{
long long num;
int tmp;
int lines;
int shift;
if (pad_by == 0)
return (piece->shape);
num = 0;
lines = piece->height - 1;
shift = (pad_by > 0) ? 4 : 4 + pad_by;
while (lines >= 0)
{
if (num)
num = num << shift;
tmp = (piece->shape >> (lines * 4)) & 0xf;
num = num | tmp;
if (pad_by > 0 && lines != 0)
num = num << pad_by;
lines--;
}
return (num);
}
long long modify_shape_to(t_piece *piece, int map_size, int pos)
{
long long morphed;
int shift_by;
morphed = pad_shape(piece, map_size - 4);
shift_by = pos - (((piece->height - 1) * map_size) + piece->width);
return (morphed << shift_by);
}
static int find_placement(t_piece *piece, t_map *map, int start)
{
long long padded_num;
int can_place;
int min_place;
int cmp;
can_place = 0;
min_place = ((piece->height - 1) * map->size) + piece->width;
while (!can_place && start >= min_place)
{
cmp = (start / map->size) * map->size;
if (start % map->size == 0)
cmp -= map->size;
if (start - (int)piece->width < cmp)
can_place = 0;
else
{
padded_num = modify_shape_to(piece, map->size, start);
can_place = !(padded_num & map->placement);
}
if (!can_place)
start--;
}
return ((can_place) ? start : -1);
}
static void place_piece(t_piece *piece, t_map *map, int placement)
{
long long padded_num;
padded_num = modify_shape_to(piece, map->size, placement);
piece->position = placement;
map->placement = map->placement | padded_num;
}
int try(t_piece **pieces, t_map *map)
{
int place;
int success;
long long pn;
success = 0;
place = find_placement(*pieces, map, (map->size * map->size));
while (!success && place != -1)
{
place_piece(*pieces, map, place);
if (*(pieces + 1) == NULL)
return (1);
success = try(pieces + 1, map);
if (!success)
{
pn = modify_shape_to(*pieces, map->size, (*pieces)->position);
map->placement = map->placement ^ pn;
place = find_placement(*pieces, map, place - 1);
}
}
return (success);
}