コード例 #1
0
ファイル: wfc_solver.py プロジェクト: Dkpalea/midi-wfc
def test_recurse_vs_loop():
    from wfc_tiles import make_tile_catalog
    from wfc_patterns import make_pattern_catalog, pattern_grid_to_tiles
    from wfc_adjacency import adjacency_extraction
    from wfc_solver import run, makeWave, makeAdj, lexicalLocationHeuristic, lexicalPatternHeuristic
    from wfc_visualize import figure_list_of_tiles, figure_false_color_tile_grid, figure_pattern_catalog, render_tiles_to_output, figure_adjacencies

    import imageio
    img = imageio.imread("../images/samples/Red Maze.png")
    tile_size = 1
    pattern_width = 2
    rotations = 0
    output_size = [84, 84]
    ground = None
    direction_offsets = list(enumerate([(0, -1), (1, 0), (0, 1), (-1, 0)]))
    tile_catalog, tile_grid, code_list, unique_tiles = make_tile_catalog(
        img, tile_size)
    pattern_catalog, pattern_weights, pattern_list, pattern_grid = make_pattern_catalog(
        tile_grid, pattern_width, rotations)
    adjacency_relations = adjacency_extraction(pattern_grid, pattern_catalog,
                                               direction_offsets)
    number_of_patterns = len(pattern_weights)
    encode_patterns = dict(enumerate(pattern_list))
    decode_patterns = {x: i for i, x in enumerate(pattern_list)}
    decode_directions = {j: i for i, j in direction_offsets}
    adjacency_list = {}
    for i, d in direction_offsets:
        adjacency_list[d] = [set() for i in pattern_weights]
    for i in adjacency_relations:
        adjacency_list[i[0]][decode_patterns[i[1]]].add(decode_patterns[i[2]])
    wave = makeWave(number_of_patterns, output_size[0], output_size[1])
    adjacency_matrix = makeAdj(adjacency_list)
    solution_loop = run(wave.copy(),
                        adjacency_matrix,
                        locationHeuristic=lexicalLocationHeuristic,
                        patternHeuristic=lexicalPatternHeuristic,
                        periodic=True,
                        backtracking=False,
                        onChoice=None,
                        onBacktrack=None)
    solution_recurse = run_recurse(wave.copy(),
                                   adjacency_matrix,
                                   locationHeuristic=lexicalLocationHeuristic,
                                   patternHeuristic=lexicalPatternHeuristic,
                                   periodic=True,
                                   backtracking=False,
                                   onChoice=None,
                                   onBacktrack=None)
    assert (numpy.array_equiv(solution_loop, solution_recurse))
コード例 #2
0
ファイル: wfc_solver.py プロジェクト: Dkpalea/midi-wfc
def test_run():
    wave = makeWave(3, 3, 4)
    adjLists = {}
    adjLists[(+1, 0)] = adjLists[(-1,
                                  0)] = adjLists[(0,
                                                  +1)] = adjLists[(0,
                                                                   -1)] = [[1],
                                                                           [0],
                                                                           [2]]
    adj = makeAdj(adjLists)

    first_result = run(wave.copy(),
                       adj,
                       locationHeuristic=lexicalLocationHeuristic,
                       patternHeuristic=lexicalPatternHeuristic,
                       periodic=False)

    expected_first_result = numpy.array([[0, 1, 0, 1], [1, 0, 1, 0],
                                         [0, 1, 0, 1]])

    assert numpy.array_equal(first_result, expected_first_result)

    event_log = []

    def onChoice(pattern, i, j):
        event_log.append((pattern, i, j))

    def onBacktrack():
        event_log.append('backtrack')

    second_result = run(wave.copy(),
                        adj,
                        locationHeuristic=lexicalLocationHeuristic,
                        patternHeuristic=lexicalPatternHeuristic,
                        periodic=True,
                        backtracking=True,
                        onChoice=onChoice,
                        onBacktrack=onBacktrack)

    expected_second_result = numpy.array([[2, 2, 2, 2], [2, 2, 2, 2],
                                          [2, 2, 2, 2]])

    assert numpy.array_equal(second_result, expected_second_result)
    print(event_log)
    assert event_log == [(0, 0, 0), 'backtrack']

    def explode(wave):
        if wave.sum() < 20:
            raise Infeasible

    try:
        result = run(wave.copy(),
                     adj,
                     locationHeuristic=lexicalLocationHeuristic,
                     patternHeuristic=lexicalPatternHeuristic,
                     periodic=True,
                     backtracking=True,
                     checkFeasible=explode)
        print(result)
        happy = False
    except Contradiction:
        happy = True

    assert happy
コード例 #3
0
ファイル: wfc_solver.py プロジェクト: Dkpalea/midi-wfc
def run(wave,
        adj,
        locationHeuristic,
        patternHeuristic,
        periodic=False,
        backtracking=False,
        onBacktrack=None,
        onChoice=None,
        onObserve=None,
        onPropagate=None,
        checkFeasible=None,
        onFinal=None,
        depth=0,
        depth_limit=None):
    #print("run.")
    if checkFeasible:
        if not checkFeasible(wave):
            raise Contradiction
        if depth_limit:
            if depth > depthlimit:
                raise TimedOut
    if depth % 50 == 0:
        print(depth)
    original = wave.copy()
    propagate(wave, adj, periodic=periodic, onPropagate=onPropagate)
    try:
        pattern, i, j = observe(wave, locationHeuristic, patternHeuristic)
        if onChoice:
            onChoice(pattern, i, j)
        wave[:, i, j] = False
        wave[pattern, i, j] = True
        if onObserve:
            onObserve(wave)
        propagate(wave, adj, periodic=periodic, onPropagate=onPropagate)
        if wave.sum() > wave.shape[1] * wave.shape[2]:
            #return run(wave, adj, locationHeuristic, patternHeuristic, periodic, backtracking, onBacktrack)
            return run(wave,
                       adj,
                       locationHeuristic,
                       patternHeuristic,
                       periodic=periodic,
                       backtracking=backtracking,
                       onBacktrack=onBacktrack,
                       onChoice=onChoice,
                       onObserve=onObserve,
                       onPropagate=onPropagate,
                       checkFeasible=checkFeasible,
                       depth=depth + 1,
                       depth_limit=depth_limit)
        else:
            if onFinal:
                onFinal(wave)
            return numpy.argmax(wave, 0)
    except Contradiction:
        if backtracking:
            if onBacktrack:
                onBacktrack()
            wave = original
            wave[pattern, i, j] = False
            return run(wave,
                       adj,
                       locationHeuristic,
                       patternHeuristic,
                       periodic=periodic,
                       backtracking=backtracking,
                       onBacktrack=onBacktrack,
                       onChoice=onChoice,
                       onObserve=onObserve,
                       onPropagate=onPropagate,
                       checkFeasible=checkFeasible,
                       depth=depth + 1,
                       depth_limit=depth_limit)
        else:
            if onFinal:
                onFinal(wave)
            raise