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
|
#include "pattern.h"
#include <stdlib.h>
#include "utils/utilities.h"
/*
* Inline functions
*/
bool len_is_max(struct pattern *pattern);
bool len_is_min(struct pattern *pattern);
int coord_to_index(int width, struct coord point);
struct coord index_to_coord(int width, int index);
int pattern_point_to_index(struct pattern *pattern, int index);
struct pattern_type gen_pattern_type(int side_len, int min, int max)
{
struct pattern_type result;
result.width = side_len;
result.height = side_len;
int max_possible = side_len * side_len;
result.min_length = min >= 0 ? min : max_possible;
if (max >= 0 && max <= max_possible)
result.max_length = max;
else
result.max_length = max_possible;
return result;
}
int coord_cmp(const void *a, const void *b)
{
const struct coord *ac = a;
const struct coord *bc = b;
if (ac->x == bc->x && ac->y == bc->y)
return 0;
//TODO: Handle when the inputs are not equal!
return -1;
}
bool is_in_line(struct coord a, struct coord c, struct coord b)
{
if (!(monotonic(a.x, b.x, c.x) && monotonic(a.y, b.y, c.y)))
return false;
return ((b.x - a.x) * (c.y - a.y)) + ((b.y - a.y) * (a.x - c.x)) == 0;
}
int find_in_pattern(struct pattern *pattern, struct coord *coord)
{
for (int i = 0; i < pattern->length; i++)
{
struct coord *current = &pattern->path[i];
if (current->x == coord->x && current->y == coord->y)
return i;
}
return -1;
}
int inbetween(int width, int height, struct coord *from, struct coord *to, struct coord *arr)
{
int length = 0;
struct coord current;
for (current.y = 0; current.y < height; current.y++)
for (current.x = 0; current.x < width; current.x++)
if ((current.x != from->x || current.y != from->y) &&
(current.x != to->x || current.y != to->y))
if (is_in_line(*from, *to, current))
arr[length++] = current;
return length;
}
bool nothing_inbetween(struct pattern *pattern, struct coord *next)
{
if (pattern->length == 0)
return true;
struct coord *last = &pattern->path[pattern->length - 1];
struct coord arr[pattern->type.width * pattern->type.height];
size_t length = inbetween(pattern->type.width, pattern->type.height, last, next, arr);
if (length > pattern->length)
return false;
for (int i = 0; i < length; i++)
if (find_in_pattern(pattern, &arr[i]) < 0)
return false;
return true;
}
|