aboutsummaryrefslogtreecommitdiff
path: root/src/pattern/next.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pattern/next.c')
-rw-r--r--src/pattern/next.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/pattern/next.c b/src/pattern/next.c
new file mode 100644
index 0000000..10261bc
--- /dev/null
+++ b/src/pattern/next.c
@@ -0,0 +1,79 @@
+#include "next.h"
+#include <stdlib.h>
+
+/*
+ * It gives the first point that:
+ * - Isn't part of pattern->path
+ * - Its index the lowest possible, but minimum min_index
+ * - There isn't any point in-line between it and the last of the path
+ * Returns true if such a point exsist, otherwise returns false.
+ */
+bool free_point(struct pattern *pattern, int min_index, struct coord *new_point)
+{
+ //printf("min_index=%d\n", min_index);
+ struct coord result = index_to_coord(pattern->type.width, min_index);
+ struct coord *last = pattern->length > 0 ? &pattern->path[pattern->length - 1] : NULL;
+ while (result.y < pattern->type.height)
+ {
+ while (result.x < pattern->type.width)
+ {
+ if (last == NULL)
+ {
+ *new_point = result;
+ return true;
+ }
+ else if (find_in_pattern(pattern, &result) < 0 &&
+ nothing_inbetween(pattern, &result))
+ {
+ //printf("fp(%d;%d)\n", result.x, result.y);
+ *new_point = result;
+ return true;
+ }
+ result.x++;
+ }
+ result.y++;
+ result.x = 0;
+ }
+ return false;
+}
+
+/*
+ * Changes pattern->path to the next possible pattern.
+ * It returns false if there's no possible pattern left,
+ * otherwise it returns true.
+ */
+bool next_point(struct pattern *pattern)
+{
+ struct coord next_point;
+ if (len_is_max(pattern))
+ {
+ do
+ {
+ if (pattern->length == 0)
+ return false; //Nincs több minta
+ next_point = pattern->path[--pattern->length];
+ } while (!free_point(
+ pattern,
+ coord_to_index(pattern->type.width, next_point) + 1,
+ &next_point));
+ //printf("(%d;%d)\n", next_point.x, next_point.y);
+ pattern->path[pattern->length++] = next_point;
+ if (pattern->length >= pattern->type.min_length)
+ return true;
+ }
+
+ do
+ {
+ if (free_point(pattern, 0, &next_point))
+ {
+ pattern->path[pattern->length++] = next_point;
+ //return true;
+ }
+ } while (pattern->length < pattern->type.min_length);
+
+ return true;
+
+ // Ha visszalépés volt, akkor az első újra előrelépésnél, csak nagyobb indexű
+ // elemre szabad lépni.
+ // Ha előrelépés volt, akkor a legkissebb indexű szabad elemre kell lépni.
+}