Beispiel #1
0
    def test_callbacks(self):
        # 'L' letter
        columns = [3, 1]
        rows = [1, 1, 2]

        board = BlackBoard(columns, rows)
        rows_updated = []
        cols_updated = []
        rounds = []

        board.on_row_update = lambda index, **kwargs: rows_updated.append(index)
        board.on_column_update = lambda index, **kwargs: cols_updated.append(index)
        board.on_solution_round_complete = lambda **kwargs: rounds.append(1)
        propagation.solve(board)

        # the solution will go like following:
        # 1. draw the lower '_' in L (row 2)
        # 2. the column 0 updated
        #   3. during that update the row 0 updated
        #     4. during that update the column 1 updated

        assert rows_updated == [2, 0]
        # draw the vertical '|' in L
        # and fill the spaces on the second column
        assert cols_updated == [0, 1]

        # it takes only one round to solve that
        assert sum(rounds) == 1
Beispiel #2
0
    def test_several_solutions(self, stream):
        columns = [3, None, 1, 1]
        rows = [
            1,
            '1 1',
            '1 1',
        ]

        board = BlackBoard(columns, rows, renderer=AsciiRenderer, stream=stream)
        propagation.solve(board)
        board.draw()

        assert stream.getvalue().rstrip() == '\n'.join([
            '+---+---++---+---+---+---+',
            '| # | # || 3 | 0 | 1 | 1 |',
            '|===+===++===+===+===+===|',
            '|   | 1 || # |   |   |   |',
            '|---+---++---+---+---+---|',
            '| 1 | 1 || # |   | ? | ? |',
            '|---+---++---+---+---+---|',
            '| 1 | 1 || # |   | ? | ? |',
            '+---+---++---+---+---+---+',
        ])

        assert board.solution_rate * 3 == 2.0
Beispiel #3
0
    def test_bold_lines(self, stream):
        """
        M letter
        """
        columns = [5, 1, 1, 1, 5]
        rows = ['1 1', '2 2', '1 1 1', '1 1', '1 1']

        renderer = AsciiRendererWithBold(stream=stream)
        renderer.BOLD_LINE_EVERY = 2
        board = BlackBoard(columns, rows, renderer=renderer)
        propagation.solve(board)
        board.draw()

        assert stream.getvalue().rstrip() == '\n'.join([
            '+---+---+---+++---+---++---+---++---+',
            '| # | # | # ||| 5 | 1 || 1 | 1 || 5 |',
            '|===+===+===+++===+===++===+===++===|',
            '|   | 1 | 1 ||| # |   ||   |   || # |',
            '|---+---+---+++---+---++---+---++---|',
            '|   | 2 | 2 ||| # | # ||   | # || # |',
            '|===+===+===+++===+===++===+===++===|',
            '| 1 | 1 | 1 ||| # |   || # |   || # |',
            '|---+---+---+++---+---++---+---++---|',
            '|   | 1 | 1 ||| # |   ||   |   || # |',
            '|===+===+===+++===+===++===+===++===|',
            '|   | 1 | 1 ||| # |   ||   |   || # |',
            '+---+---+---+++---+---++---+---++---+',
        ])
Beispiel #4
0
    def test_two_digits_bad_drawing(self, stream):
        width = 10
        cols = [1] * width + [0, 1]
        rows = [[width, 1]]

        b = BlackBoard(cols, rows, renderer=BaseAsciiRenderer, stream=stream)
        b.draw()

        assert stream.getvalue().rstrip() == '\n'.join([
            '# # 1 1 1 1 1 1 1 1 1 1 0 1',
            '101 _ _ _ _ _ _ _ _ _ _ _ _',
        ])
Beispiel #5
0
    def test_solve_board(self):
        columns, rows = read_example('w')

        board = BlackBoard(columns, rows)

        propagation.solve(board, methods='simpson')
        assert board.is_solved_full
Beispiel #6
0
    def test_smile(self):
        columns, rows = read_example('smile.txt')
        board = BlackBoard(columns, rows)

        propagation.solve(board)
        assert is_close(board.solution_rate, 0.6)
        # assert is_close(board.solution_rate, 407.0 / 625)

        Solver(board).solve()
        assert board.is_solved_full
Beispiel #7
0
    def test_many_solutions(self):
        # source: https://en.wikipedia.org/wiki/Nonogram#Contradictions
        columns = [3, 1, 2, 2, '1 1', '1 1']
        rows = ['1 2', 1, 1, 3, 2, 2]

        board = BlackBoard(columns, rows)

        propagation.solve(board)
        assert board.solution_rate == 0

        Solver(board).solve()
        assert is_close(board.solution_rate, 7.0 / 9)
        assert len(board.solutions) == 2
Beispiel #8
0
def test_space_hints_solving():
    columns = [3, 1, 3]
    rows = [
        3,
        '1 1',
        '1 1',
    ]
    board = BlackBoard(columns, rows)
    _solve_on_space_hints(board, [[0], [0, 1], [0, 1]])
    assert board.cells == [
        [BOX, BOX, BOX],
        [BOX, SPACE, BOX],
        [BOX, SPACE, BOX],
    ]
Beispiel #9
0
    def test_hello(self):
        columns, rows = read_example('hello.txt')

        stream = StringIO()
        board = BlackBoard(columns,
                           rows,
                           renderer=BaseAsciiRenderer,
                           stream=stream)
        propagation.solve(board)
        board.draw()

        assert stream.getvalue().rstrip() == '\n'.join([
            '# # # # # # # # #               1 1                          ',
            '# # # # # # # # #               1 1               1   1     5',
            '# # # # # # # # # 7 1 1 1 7 0 3 1 1 2 0 6 0 6 0 3 1 5 1 3 0 1',
            '            1 1 1 X . . . X . . . . . . . . . . . . . . . . X',
            '        1 1 1 1 1 X . . . X . . . . . . X . X . . . . . . . X',
            '    1 1 2 1 1 3 1 X . . . X . . X X . . X . X . . X X X . . X',
            '5 1 1 1 1 1 1 1 1 X X X X X . X . . X . X . X . X . X . X . X',
            '1 1 4 1 1 1 1 1 1 X . . . X . X X X X . X . X . X . X . X . X',
            '  1 1 1 1 1 1 1 1 X . . . X . X . . . . X . X . X . X . X . .',
            '    1 1 2 1 1 3 1 X . . . X . . X X . . X . X . . X X X . . X',
        ])
        assert board.is_solved_full
Beispiel #10
0
    def test_chessboard(self):
        # The real chessboard could be defined like this
        #
        # `columns = rows = [[1, 1, 1, 1]] * 8`
        #
        # but it really slows down the test.
        #
        # So we just use simple 2x2 chessboard here
        # with the same effect on test coverage

        columns = rows = [[1, 1, 1, 1]] * 8
        board = BlackBoard(columns, rows)

        propagation.solve(board)
        assert board.solution_rate == 0

        Solver(board).solve()
        assert board.solution_rate == 0
Beispiel #11
0
    def test_columns_and_rows_does_not_match(self):
        with pytest.raises(ValueError) as ei:
            BlackBoard(columns=[1, 1], rows=[1, 2])

        assert str(ei.value), \
            'Number of boxes differs: 3 (rows) and 2 (columns)'
Beispiel #12
0
    def test_bad_row_value(self):
        with pytest.raises(ValueError) as ei:
            BlackBoard(columns=[2.0, 1], rows=[1, 2])

        assert str(ei.value), 'Bad row: 2.0'
Beispiel #13
0
    def test_row_does_not_fit(self):
        with pytest.raises(ValueError) as ei:
            BlackBoard(columns=[1, 1], rows=[1, [1, 1]])

        assert str(ei.value), \
            'Cannot allocate row [1, 1] in just 2 cells'
Beispiel #14
0
 def test_board_changed(self, renderer):
     prev_board = id(renderer.board)
     renderer.board_init(BlackBoard([], []))
     assert prev_board != id(renderer.board)
Beispiel #15
0
 def one_row_table(cls, width, stream):
     cols = [1] * width
     rows = [width]
     return BlackBoard(cols, rows, renderer=SvgRenderer, stream=stream)