Ejemplo n.º 1
0
    def test_colors_conflict(self):
        columns, rows, colors = color_board_def()
        rows[0] = '3g'
        with pytest.raises(KeyError) as ie:
            make_board(columns, rows, colors)

        assert str(ie.value).endswith("'g'")
Ejemplo n.º 2
0
    def test_bad_description(self):
        columns = [(('1', 'r', 1),)]
        rows = [((1, 'r'),), 0, '1']

        colors = ColorMap()
        colors.make_color('r', 'red', 'X')

        with pytest.raises(ValueError, match='Bad description block:'):
            make_board(columns, rows, colors)
Ejemplo n.º 3
0
    def test_same_boxes_in_a_row(self):
        columns = [['1r', (1, 'b'), (1, 'b')]] * 3
        rows = ['3r', '3b', '3b']

        colors = ColorMap()
        for color in [('r', 'red', 'X'), ('b', 'blue', '*')]:
            colors.make_color(*color)

        with pytest.raises(ValueError, match='Cannot allocate clue .+ in just 3 cells'):
            make_board(columns, rows, colors)
Ejemplo n.º 4
0
    def test_color_renderer(self, stream):
        columns = [['1r', 1]] * 3
        rows = [((3, 'r'),), 0, '3']

        colors = ColorMap()
        colors.make_color('r', 'red', '%')

        renderer = BaseAsciiRenderer(stream=stream)
        board = make_board(columns, rows, colors, renderer=renderer)
        for i in range(3):
            board.cells[0][i] = 4
            board.cells[2][i] = Color.black().id_
        # cannot do simply:
        # board.cells[2] = [True, True, True]
        # because of
        # ValueError: could not broadcast input array from shape (3) into shape (3,2)

        board.draw()

        assert stream.getvalue().rstrip() == '\n'.join([
            '# 1 1 1',
            '# 1 1 1',
            '3 % % %',
            '0      ',
            '3 X X X',
        ])
Ejemplo n.º 5
0
    def test_basic(self):
        board = make_board(*Pbn.read(19407))
        assert board.has_blots
        assert board.rows_descriptions[1] == (BlottedBlock,)

        propagation.solve(board)
        assert board.is_solved_full
Ejemplo n.º 6
0
    def test_black_and_white(self):
        columns = [3, None, 1, 1]
        rows = [
            1,
            '1 1',
            '1 1',
        ]

        b = make_board(columns, rows)
        assert isinstance(b, BlackBoard)
Ejemplo n.º 7
0
    def test_depth_search(self):
        board = make_board(*Pbn.read(3469))

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

        Solver(board, max_solutions=2, timeout=600).solve()
        assert board.is_solved_full
        assert len(board.solutions) == 1

        assert board.is_finished
Ejemplo n.º 8
0
    def get_board(cls, _id, create_mode, **renderer_params):
        """Generates a board using given ID and mode"""
        if create_mode == 'local':
            board_def = read_example(_id)
        elif create_mode == 'pbn':
            board_def = Pbn.read(_id)
        elif create_mode == 'nonograms.org':
            board_def = NonogramsOrg.read(_id)
        else:
            raise tornado.web.HTTPError(400, 'Bad mode: %s', create_mode)

        return make_board(*board_def, **renderer_params)
Ejemplo n.º 9
0
    def test_depth_search_colored(self, stream):
        renderer = BaseAsciiRenderer(stream=stream)
        board = make_board(*Pbn.read(5260), renderer=renderer)

        propagation.solve(board)
        assert board.solution_rate == 0.9375
        assert len(board.solutions) == 0

        Solver(board, max_solutions=2, timeout=600).solve()
        assert board.solution_rate == 0.9375
        assert len(board.solutions) == 2

        assert board.is_finished

        board.draw_solutions()
        example_solution = [
            '# # # # # #                   1 1                  ',
            '# # # # # #                   1 1                  ',
            '# # # # # #     1   1         1 1         1   1    ',
            '# # # # # #   1 1 1 1         1 1         1 1 1 1  ',
            '# # # # # #   6 1 2 1 2   1 2 1 1 2 1   2 1 2 1 6  ',
            '# # # # # # 1 1 1 1 1 2 0 1 2 1 1 2 1 0 2 1 1 1 1 1',
            '          1 X . . . . . . . . . . . . . . . . . . .',
            '      1 6 1 . X . . . . . % % % % % % . . . . . X .',
            '    1 1 1 1 . . X . . . . . % . . % . . . X . . . .',
            '      1 2 1 . . . . X . . . . % % . . . . . X . . .',
            '    1 1 1 1 . . . X . @ . . . . . . . . @ . . X . .',
            '        2 2 . . . . @ @ . . . . . . . . @ @ . . . .',
            '          0 . . . . . . . . . . . . . . . . . . . .',
            '        1 1 . % . . . . . . . . . . . . . . . . % .',
            '        2 2 . % % . . . . . . . . . . . . . . % % .',
            '1 1 1 1 1 1 . % . % . . . . . * % . . . . . % . % .',
            '1 1 1 1 1 1 . % . % . . . . . X * . . . . . % . % .',
            '        2 2 . % % . . . . . . . . . . . . . . % % .',
            '        1 1 . % . . . . . . . . . . . . . . . . % .',
            '          0 . . . . . . . . . . . . . . . . . . . .',
            '        2 2 . . . . @ @ . . . . . . . . @ @ . . . .',
            '    1 1 1 1 . X . . . @ . . . . . . . . @ . . X . .',
            '      1 2 1 . . X . . . . . . % % . . . . . X . . .',
            '    1 1 1 1 . . . . X . . . % . . % . . . . . . X .',
            '      1 6 1 . . . X . . . % % % % % % . . X . . . .',
            '          1 . . . . . . . . . . . . . . . . . . . X',
        ]

        actual_drawing = stream.getvalue().rstrip().split('\n')
        sol1, sol2 = actual_drawing[:26], actual_drawing[26:]

        # header
        assert sol1[:6] == sol2[:6] == example_solution[:6]

        # central
        assert sol1[11:21] == sol2[11:21] == example_solution[11:21]
Ejemplo n.º 10
0
    def test_color(self):
        board = make_board(*Pbn.read(19647))
        assert board.has_blots
        assert board.rows_descriptions[15] == (
            (1, 2),
            (BlottedBlock, 8),
            (BlottedBlock, 8),
            (2, 2),
            (2, 2),
            (2, 8),
        )

        propagation.solve(board)
        assert board.is_solved_full
Ejemplo n.º 11
0
    def test_colored(self):
        board = make_board(*Pbn.read(10282))

        propagation.solve(board)
        assert len(board.solutions) == 0

        Solver(board, max_solutions=2, timeout=600).solve()
        assert is_close(board.solution_rate, 0.91625)
        assert len(board.solutions) == 2

        assert len(board.solved_rows[0]) == 3
        assert len(board.solved_rows[1]) == 2
        assert len(board.solved_columns[0]) == 5
        assert len(board.solved_columns[1]) == 9
Ejemplo n.º 12
0
def draw_solution(board_def,
                  draw_final=False,
                  box_symbol=None,
                  curses_animation=False,
                  **solver_args):
    """Solve the given board in terminal with animation"""

    with ignored(locale.Error):
        # to correctly print non-ASCII box symbols
        locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

    if curses_animation:
        if draw_final:
            logging.warning('No need to use curses with draw_final=True')
            curses_animation = False

    if curses_animation:
        board_queue = queue.Queue()
        d_board = make_board(*board_def,
                             renderer=CursesRenderer,
                             stream=board_queue)

        if box_symbol is not None:
            d_board.renderer.icons.update({BOX: box_symbol})

        thread = Thread(target=solve, args=(d_board, ), kwargs=solver_args)
        thread.daemon = True
        thread.start()
        curses.wrapper(PagerWithUptime.draw, board_queue)
    else:
        d_board = make_board(*board_def, renderer=BaseAsciiRenderer)

        if box_symbol is not None:
            d_board.renderer.icons.update({BOX: box_symbol})

        solve(d_board, draw_final=draw_final, **solver_args)
Ejemplo n.º 13
0
    def test_black_and_white(self):
        board = make_board(*Pbn.read(2903))

        propagation.solve(board)
        assert len(board.solutions) == 0

        Solver(board, max_solutions=2, timeout=600).solve()
        assert board.is_solved_full
        assert len(board.solutions) == 1

        assert len(board.solved_rows[0]) == 6
        assert len(board.solved_rows[1]) == 6
        assert len(board.solved_columns[0]) == 4
        assert len(board.solved_columns[1]) == 0

        assert board.is_finished
Ejemplo n.º 14
0
    def test_normalize(self):
        columns = [['1r', 1]] * 3
        rows = [((3, 'r'),), 0, '3']

        colors = ColorMap()
        colors.make_color('r', 'red', 'X')

        board = make_board(columns, rows, colors)

        assert board.rows_descriptions == (
            ((3, 4),),
            (),
            ((3, 2),),
        )
        assert board.columns_descriptions == (
            ((1, 4), (1, 2)),
            ((1, 4), (1, 2)),
            ((1, 4), (1, 2)),
        )
Ejemplo n.º 15
0
def tested_board(renderer=BaseAsciiRenderer, **kwargs):
    """
    Very simple demonstration board with the 'P' letter

    source: https://en.wikipedia.org/wiki/Nonogram#Example
    """
    columns = [[], 9, [9], [2, 2], (2, 2), 4, '4', '']
    rows = [
        None,
        4,
        6,
        '2 2',
        [2] * 2,
        6,
        4,
        2,
        [2],
        2,
        0,
    ]
    return make_board(columns, rows, renderer=renderer, **kwargs)
Ejemplo n.º 16
0
    def test_backtracking(self):
        board = make_board(*Pbn.read(4581))
        propagation.solve(board, methods=self.method_name())

        assert is_close(board.solution_rate, 0.75416666667)
        assert len(board.solutions) == 0
Ejemplo n.º 17
0
    def test_black(self):
        board = make_board(*Pbn.read(20029))
        assert board.rows_descriptions[2] == (BlottedBlock, 1)

        propagation.solve(board)
        assert board.is_solved_full
Ejemplo n.º 18
0
    def test_color_solved(self, stream):
        b = make_board(*color_board_def(), renderer=SvgRenderer, stream=stream)
        propagation.solve(b)

        b.draw()
        table = [line.strip() for line in stream.getvalue().split('\n')]

        svg_def = '''
            <svg baseProfile="full" height="90" version="1.1" width="75" xmlns="
            http://www.w3.org/2000/svg" xmlns:ev=
            "http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
                <defs>
                    <style type="text/css">
                        <![CDATA[
                            g.grid-lines line {
                            stroke-width: 1} g.grid-lines line.bold {
                            stroke-width: 2} g.header-clues text, g.side-clues text {
                            font-size: 9.000000} ]]>
                    </style>

                    <symbol id="color-b">
                        <rect fill="blue" height="15" width="15" x="0" y="0" />
                    </symbol>
                    <symbol id="color-black">
                        <rect fill="#000" height="15" width="15" x="0" y="0" />
                    </symbol>
                    <symbol id="color-r">
                        <rect fill="red" height="15" width="15" x="0" y="0" />
                    </symbol>


                    <symbol id="x2-b-black">
                        <polygon fill="blue" points="0,0 0,15 15,0" />
                        <polygon fill="#000" points="0,15 15,0 15,15" />
                    </symbol>
                    <symbol id="x2-b-r">
                        <polygon fill="blue" points="0,0 0,15 15,0" />
                        <polygon fill="red" points="0,15 15,0 15,15" />
                    </symbol>
                    <symbol id="x2-b-white">
                        <polygon fill="blue" points="0,0 0,15 15,0" />
                        <polygon fill="#fff" points="0,15 15,0 15,15" />
                    </symbol>

                    <symbol id="x2-black-r">
                        <polygon fill="#000" points="0,0 0,15 15,0" />
                        <polygon fill="red" points="0,15 15,0 15,15" />
                    </symbol>
                    <symbol id="x2-black-white">
                        <polygon fill="#000" points="0,0 0,15 15,0" />
                        <polygon fill="#fff" points="0,15 15,0 15,15" />
                    </symbol>

                    <symbol id="x2-r-white">
                        <polygon fill="red" points="0,0 0,15 15,0" />
                        <polygon fill="#fff" points="0,15 15,0 15,15" />
                    </symbol>


                    <symbol id="x3-b-black-r">
                        <rect fill="blue" height="15" width="15" x="0" y="0" />
                        <polygon fill="#000" points="0,0 0,10.61 10.61,0" />
                        <polygon fill="red" points="15,4.39 4.39,15 15,15" />
                    </symbol>
                    <symbol id="x3-b-black-white">
                        <rect fill="blue" height="15" width="15" x="0" y="0" />
                        <polygon fill="#000" points="0,0 0,10.61 10.61,0" />
                        <polygon fill="#fff" points="15,4.39 4.39,15 15,15" />
                    </symbol>
                    <symbol id="x3-b-r-white">
                        <rect fill="blue" height="15" width="15" x="0" y="0" />
                        <polygon fill="red" points="0,0 0,10.61 10.61,0" />
                        <polygon fill="#fff" points="15,4.39 4.39,15 15,15" />
                    </symbol>
                    <symbol id="x3-black-r-white">
                        <rect fill="#000" height="15" width="15" x="0" y="0" />
                        <polygon fill="red" points="0,0 0,10.61 10.61,0" />
                        <polygon fill="#fff" points="15,4.39 4.39,15 15,15" />
                    </symbol>

                    <symbol id="space"><circle cx="0" cy="0" r="1.5" /></symbol>


                    <symbol fill="none" id="check" stroke="green">
                        <circle cx="50" cy="50" r="40" stroke-width="10" />
                        <polyline points="35,35 35,55 75,55" stroke-width="
                        12" transform="rotate(-45 50 50)" />
                    </symbol>
                </defs>

                <rect class="nonogram-thumbnail" height="30" width="15" x="0" y="0" />

                <rect class="nonogram-header" height="30" width="45" x="15" y="0" />
                <g class="header-clues">
                    <rect class="solved" height="30" width="15" x="15" y="0" />
                    <use x="15" xlink:href="#color-b" y="15" />
                    <text x="27.75" y="25.5">1</text>
                    <use x="15" xlink:href="#color-r" y="0" />
                    <text x="27.75" y="10.5">1</text>

                    <rect class="solved" height="30" width="15" x="30" y="0" />
                    <use x="30" xlink:href="#color-b" y="15" />
                    <text x="42.75" y="25.5">1</text>
                    <use x="30" xlink:href="#color-r" y="0" />
                    <text x="42.75" y="10.5">1</text>

                    <rect class="solved" height="30" width="15" x="45" y="0" />
                    <use x="45" xlink:href="#color-b" y="15" />
                    <text x="57.75" y="25.5">1</text>
                    <use x="45" xlink:href="#color-r" y="0" />
                    <text x="57.75" y="10.5">1</text>
                </g>

                <rect class="nonogram-side" height="45" width="15" x="0" y="30" />
                <g class="side-clues">
                    <rect class="solved" height="15" width="15" x="0" y="30" />
                    <use x="0" xlink:href="#color-r" y="30" />
                    <text x="10.5" y="41.25">3</text>

                    <rect class="solved" height="15" width="15" x="0" y="45" />

                    <rect class="solved" height="15" width="15" x="0" y="60" />
                    <use x="0" xlink:href="#color-b" y="60" />
                    <text x="10.5" y="71.25">3</text>
                </g>

                <use x="0" xlink:href="#check" y="0" />

                <rect class="nonogram-grid" height="45" width="45" x="15" y="30" />

                <g class="space">
                    <use x="22.5" xlink:href="#space" y="52.5" />
                    <use x="37.5" xlink:href="#space" y="52.5" />
                    <use x="52.5" xlink:href="#space" y="52.5" />
                </g>
                <g class="color-black" />
                <g class="x2-black-white" />
                <g class="color-r">
                    <use x="15" xlink:href="#color-r" y="30" />
                    <use x="30" xlink:href="#color-r" y="30" />
                    <use x="45" xlink:href="#color-r" y="30" />
                </g>
                <g class="x2-r-white" />
                <g class="x2-black-r" />
                <g class="x3-black-r-white" />
                <g class="color-b">
                    <use x="15" xlink:href="#color-b" y="60" />
                    <use x="30" xlink:href="#color-b" y="60" />
                    <use x="45" xlink:href="#color-b" y="60" />
                </g>
                <g class="x2-b-white" />
                <g class="x2-b-black" />
                <g class="x3-b-black-white" />
                <g class="x2-b-r" />
                <g class="x3-b-r-white" />
                <g class="x3-b-black-r" />

                <g class="grid-lines">
                    <line class="bold" x1="0" x2="60" y1="30" y2="30" />
                    <line x1="0" x2="60" y1="45" y2="45" />
                    <line x1="0" x2="60" y1="60" y2="60" />
                    <line class="bold" x1="0" x2="60" y1="75" y2="75" />
                    <line class="bold" x1="15" x2="15" y1="0" y2="75" />
                    <line x1="30" x2="30" y1="0" y2="75" />
                    <line x1="45" x2="45" y1="0" y2="75" />
                    <line class="bold" x1="60" x2="60" y1="0" y2="75" />
                </g>
            </svg>'''

        assert table[0] == '<?xml version="1.0" encoding="utf-8" ?>'
        svg_def = ''.join([
            line for line in [line.strip() for line in svg_def.split('\n')]
            if line
        ])
        assert table[1] == svg_def
Ejemplo n.º 19
0
 def test_solve_contradictions(self):
     board = make_board(*Pbn.read(2021))
     Solver(board).solve()
     assert board.is_solved_full
     assert board.is_finished
Ejemplo n.º 20
0
def color_board(renderer=BaseAsciiRenderer, **kwargs):
    return make_board(*color_board_def(), renderer=renderer, **kwargs)
Ejemplo n.º 21
0
 def test_bad_make_board(self):
     with pytest.raises(ValueError, match='Bad number of \*args'):  # noqa: W605
         make_board(color_board_def()[0])
Ejemplo n.º 22
0
 def test_color_boxes_differ(self):
     columns, rows, colors = color_board_def()
     rows[0] = '2r'
     with pytest.raises(ValueError, match='Color boxes differ:'):
         make_board(columns, rows, colors)
Ejemplo n.º 23
0
 def test_color_not_defined(self):
     columns, rows, colors = color_board_def()
     del colors['r']
     with pytest.raises(ValueError, match='Some colors not defined:'):
         make_board(columns, rows, colors)
Ejemplo n.º 24
0
 def test_colors(self):
     board = make_board(*color_board_def())
     assert board.symbol_for_color_id('r') == 'X'
     assert board.rgb_for_color_name('b') == 'blue'
Ejemplo n.º 25
0
 def board(self):
     board_def = read_example('uk')
     return make_board(*board_def)