aboutsummaryrefslogtreecommitdiff
path: root/src/pattern/next.c
blob: 10261bce577b750195b95d61af43abc423e75aa8 (plain)
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
#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.
}