Пример #1
0
def search_point(board, gen_pattern, color, point):
    """Search for a 1d pattern on a 2d board including the given point."""

    (x, y) = point

    side = board.shape[0]
    pattern = get_pattern(gen_pattern, color)
    length = pattern.size

    matches = []
    for d in range(NUM_DIRECTIONS):
        (row_inc, col_inc) = increments(d)
        (s_min, s_max) = index_bounds_incl(side, length, x, y, row_inc, col_inc)

        for h in range(s_min, s_max):
            (i, j) = (x + row_inc * h, y + col_inc * h)

            for k in range(length):
                if not pattern[k] & board[i + row_inc * k, j + col_inc * k]:
                    break
            else:
                # Store Ordered Line Segment, a -> b, where the pattern lies.
                a = (i, j)
                b = (i + row_inc * (length - 1), j + col_inc * (length - 1))
                matches.append((a, b))

    dedupe_matches(matches)
    return matches
Пример #2
0
def subtest_search_fns(gen_pattern, color, own_sqs, defcon):
    pattern = get_pattern(gen_pattern, color)
    length = pattern.size

    for i in range(SIDE_LEN):
        for j in range(SIDE_LEN):
            for d in range(NUM_DIRECTIONS):
                board = new_board()
                if apply_pattern(board, pattern, (i, j), d):
                    (row_inc, col_inc) = increments(d)
                    start = (i, j)
                    end = (i + row_inc * (length - 1),
                           j + col_inc * (length - 1))

                    subtest_search_board(board, gen_pattern, color, start, end)
                    subtest_search_point(board, gen_pattern, color, start, end)
                    subtest_search_point_own(board, gen_pattern, color,
                                             own_sqs, start, end)

                    subtest_search_board_next_sq(board, gen_pattern, color,
                                                 own_sqs, defcon, start, end)
                    subtest_search_point_next_sq(board, gen_pattern, color,
                                                 own_sqs, defcon, start, end)
                    subtest_search_point_own_next_sq(board, gen_pattern, color,
                                                     own_sqs, defcon, start,
                                                     end)
Пример #3
0
def search_board(board, gen_pattern, color):
    """Search for a 1d pattern on a 2d board."""

    side = board.shape[0]
    pattern = get_pattern(gen_pattern, color)
    length = pattern.size

    matches = []
    for d in range(NUM_DIRECTIONS):
        (row_inc, col_inc) = increments(d)
        (row_min, row_max) = index_bounds(side, length, row_inc)
        (col_min, col_max) = index_bounds(side, length, col_inc)

        for i in range(row_min, row_max):
            for j in range(col_min, col_max):
                for k in range(length):
                    if not pattern[k] & board[i + row_inc * k, j + col_inc * k]:
                        break
                else:
                    # Store Ordered Line Segment, a -> b, where the pattern lies.
                    a = (i, j)
                    b = (i + row_inc * (length - 1), j + col_inc * (length - 1))
                    matches.append((a, b))

    dedupe_matches(matches)
    return matches
Пример #4
0
def apply_pattern(board, pattern, point, d):
    """Apply given pattern at given point in given direction.

    Returns True if application was succesful.
    Else, returns False.
    If application fails then board is unchanged.

    We only check that the length fits at that point.
    We will apply a non-standard element as it is,
    including overwriting a wall with any element whatsoever.

    Useful for testing purposes.
    """

    (x, y) = point

    side = board.shape[0]
    length = pattern.size

    (row_inc, col_inc) = increments(d)

    can_apply = True
    for k in range(length):
        (i, j) = (x + row_inc * k, y + col_inc * k)
        if i not in range(side) or j not in range(side):
            can_apply = False
            break

    if can_apply:
        for k in range(length):
            # NOTE: If it's a non-standard element, we just apply it as is.
            board[x + row_inc * k, y + col_inc * k] = pattern[k]

    return can_apply
Пример #5
0
def search_point_own(board, gen_pattern, color, point, own_sqs):
    """Search for a 1d pattern on a 2d board including the given point as an own_sq."""

    (x, y) = point

    side = board.shape[0]
    pattern = get_pattern(gen_pattern, color)
    length = pattern.size

    matches = []

    # We are searching for patterns including the given point as an "own_sq".
    if board[point] == color:
        for d in range(NUM_DIRECTIONS):
            (row_inc, col_inc) = increments(d)
            (s_min, s_max) = index_bounds_incl(side, length, x, y, row_inc, col_inc)

            for own_sq in own_sqs:
                if s_min <= -own_sq < s_max:
                    (i, j) = (x - row_inc * own_sq, y - col_inc * own_sq)

                    for k in range(length):
                        if not pattern[k] & board[i + row_inc * k, j + col_inc * k]:
                            break
                    else:
                        # Store Ordered Line Segment, a -> b, where the pattern lies.
                        a = (i, j)
                        b = (i + row_inc * (length - 1), j + col_inc * (length - 1))
                        matches.append((a, b))

    dedupe_matches(matches)
    return matches
Пример #6
0
def search_point_own_next_sq(board, gen_pattern, color, point, own_sqs):
    """Search for a 1d pattern on a 2d board including the given point as an own_sq.

    Returns "next_sq"s and the corresponding pattern matches (as in above functions)
    as a list of (next_sq, match) pairs.

    In existing terminology, "point" is a "rest" square,
    and "next_sq" is the "gain" square.
    """

    (x, y) = point

    side = board.shape[0]
    pattern = get_pattern(gen_pattern, color)
    length = pattern.size

    next_sq_match_pairs = []

    # We are searching for patterns including the given point as an "own_sq".
    if board[point] == color:
        for d in range(NUM_DIRECTIONS):
            (row_inc, col_inc) = increments(d)
            (s_min, s_max) = index_bounds_incl(side, length, x, y, row_inc, col_inc)

            for own_sq in own_sqs:
                if s_min <= -own_sq < s_max:
                    (i, j) = (x - row_inc * own_sq, y - col_inc * own_sq)

                    found_next_sq = False
                    k_next_sq = -1

                    for k in range(length):
                        p_val = pattern[k]
                        b_val = board[i + row_inc * k, j + col_inc * k]

                        if not p_val & b_val:
                            if not found_next_sq and p_val == color and b_val == EMPTY:
                                found_next_sq = True
                                k_next_sq = k
                            else:
                                break
                    else:
                        if found_next_sq:
                            # Store Ordered Line Segment, a -> b, where the pattern lies.
                            a = (i, j)
                            b = (i + row_inc * (length - 1), j + col_inc * (length - 1))
                            next_sq = (i + row_inc * k_next_sq, j + col_inc * k_next_sq)
                            next_sq_match_pairs.append((next_sq, (a, b)))

    dedupe_next_sq_match_pairs(next_sq_match_pairs)
    return next_sq_match_pairs
Пример #7
0
def search_board_next_sq(board, gen_pattern, color):
    """Search for a 1d pattern on a 2d board.

    Returns "next_sq"s and the corresponding pattern matches (as in above functions)
    as a list of (next_sq, match) pairs.

    In existing terminology, "point" is a "rest" square,
    and "next_sq" is the "gain" square.
    """

    side = board.shape[0]
    pattern = get_pattern(gen_pattern, color)
    length = pattern.size

    next_sq_match_pairs = []
    for d in range(NUM_DIRECTIONS):
        (row_inc, col_inc) = increments(d)
        (row_min, row_max) = index_bounds(side, length, row_inc)
        (col_min, col_max) = index_bounds(side, length, col_inc)

        for i in range(row_min, row_max):
            for j in range(col_min, col_max):
                found_next_sq = False
                k_next_sq = -1

                for k in range(length):
                    p_val = pattern[k]
                    b_val = board[i + row_inc * k, j + col_inc * k]

                    if not p_val & b_val:
                        if not found_next_sq and p_val == color and b_val == EMPTY:
                            found_next_sq = True
                            k_next_sq = k
                        else:
                            break
                else:
                    if found_next_sq:
                        # Store Ordered Line Segment, a -> b, where the pattern lies.
                        a = (i, j)
                        b = (i + row_inc * (length - 1), j + col_inc * (length - 1))
                        next_sq = (i + row_inc * k_next_sq, j + col_inc * k_next_sq)
                        next_sq_match_pairs.append((next_sq, (a, b)))

    dedupe_next_sq_match_pairs(next_sq_match_pairs)
    return next_sq_match_pairs