예제 #1
2
    def testDescribeMove(self):
        domino1 = Domino(1, 2)
        dx, dy = 1, 0
        expected_move = '12r'

        move = domino1.describe_move(dx, dy)

        self.assertEqual(expected_move, move)
예제 #2
2
    def testEqualFlipped(self):
        domino1 = Domino(5, 3)
        domino2 = Domino(3, 5)

        eq_result = domino1 == domino2
        neq_result = domino1 != domino2
        self.assertTrue(eq_result)
        self.assertFalse(neq_result)
예제 #3
1
    def testRotateFullCircle(self):
        domino1 = Domino(1, 5)

        domino1.rotate(180)
        domino1.rotate(180)

        self.assertEqual(0, domino1.degrees)
예제 #4
1
    def testDescribeMove(self):
        domino1 = Domino(1, 2)
        dx, dy = 1, 0
        expected_move = '12r'

        move = domino1.describe_move(dx, dy)

        self.assertEqual(expected_move, move)
예제 #5
1
    def testDescribeMoveUpReversed(self):
        domino1 = Domino(1, 2)
        domino1.rotate(90)
        dx, dy = 0, 1
        expected_move = '21u'

        move = domino1.describe_move(dx, dy)

        self.assertEqual(expected_move, move)
예제 #6
0
    def testRotateFullCircle(self):
        domino1 = Domino(1, 5)

        domino1.rotate(180)
        domino1.rotate(180)

        self.assertEqual(0, domino1.degrees)
예제 #7
0
    def testHashFlipped(self):
        domino1 = Domino(5, 3)
        domino2 = Domino(3, 5)

        hash1 = hash(domino1)
        hash2 = hash(domino2)

        self.assertEqual(hash1, hash2)
예제 #8
0
    def testIsMatch(self):
        domino1 = Domino(0, 1)

        self.assertFalse(domino1.isMatch(Domino(2, 2)))
        self.assertTrue(domino1.isMatch(Domino(0, 2)))
        self.assertTrue(domino1.isMatch(Domino(2, 1)))
        self.assertTrue(domino1.isMatch(Domino(2, 0)))
        self.assertTrue(domino1.isMatch(Domino(1, 2)))
예제 #9
0
    def testIsMatch(self):
        domino1 = Domino(0, 1)

        self.assertFalse(domino1.isMatch(Domino(2, 2)))
        self.assertTrue(domino1.isMatch(Domino(0, 2)))
        self.assertTrue(domino1.isMatch(Domino(2, 1)))
        self.assertTrue(domino1.isMatch(Domino(2, 0)))
        self.assertTrue(domino1.isMatch(Domino(1, 2)))
예제 #10
0
    def testDescribeMoveReversed(self):
        domino1 = Domino(1, 2)
        domino1.rotate(180)
        dx, dy = 1, 0
        expected_move = '21r'

        move = domino1.describe_move(dx, dy)

        self.assertEqual(expected_move, move)
예제 #11
0
    def testRemoveAndRotate(self):
        board = Board(3, 4)
        domino1 = Domino(1, 5)
        board.add(domino1, 0, 0)

        board.remove(domino1)
        domino1.rotate(270)

        self.assertEqual(270, domino1.degrees)
예제 #12
0
    def testDescribeMoveUpReversed(self):
        domino1 = Domino(1, 2)
        domino1.rotate(90)
        dx, dy = 0, 1
        expected_move = '21u'

        move = domino1.describe_move(dx, dy)

        self.assertEqual(expected_move, move)
예제 #13
0
    def testDescribeMoveReversed(self):
        domino1 = Domino(1, 2)
        domino1.rotate(180)
        dx, dy = 1, 0
        expected_move = '21r'

        move = domino1.describe_move(dx, dy)

        self.assertEqual(expected_move, move)
예제 #14
0
    def testRemoveAndRotate(self):
        board = Board(3, 4)
        domino1 = Domino(1, 5)
        board.add(domino1, 0, 0)

        board.remove(domino1)
        domino1.rotate(270)

        self.assertEqual(270, domino1.degrees)
예제 #15
0
    def testDifferentPips(self):
        domino1 = Domino(5, 3)
        domino2 = Domino(5, 4)
        domino3 = Domino(6, 3)

        eq_result = domino1 == domino2
        neq_result = domino1 != domino2
        self.assertFalse(eq_result)
        self.assertTrue(neq_result)
        self.assertNotEqual(domino1, domino3)
예제 #16
0
    def testFillWithBacktrack(self, mock_choose):
        """ Force a backtrack.

        This scenario will get to the following grid and then be forced to
        backtrack, because the gaps are size 1 and 3: odd.
        x 3 x x
          -
        0 0 x 2
        -     -
        0 0|1 0
        """
        mock_choose.side_effect = [[Domino(0, 0)], [Domino(0, 1)],
                                   [Domino(0, 2)], [Domino(0, 3)],
                                   [Domino(0, 3)], [Domino(0, 3)],
                                   [Domino(0, 3)], [Domino(0, 4)],
                                   [Domino(0, 5)]]
        dummy_random = DummyRandom(randints={(0, 3): [1, 0, 1,
                                                      1]})  # directions
        board = Board(4, 3, max_pips=6)
        expected_display = """\
0|4 0|5

0 0|3 2
-     -
0 0|1 0
"""

        board.fill(dummy_random)
        display = board.display()

        self.assertMultiLineEqual(expected_display, display)
예제 #17
0
    def testFlip(self):
        board = Board(3, 2, max_pips=6)
        domino1 = Domino(1, 5)
        expected_display = """\
x x x

5|1 x
"""

        board.add(domino1, 0, 0)
        domino1.flip()

        self.assertMultiLineEqual(expected_display, board.display())
예제 #18
0
    def testFlip(self):
        board = Board(3, 2, max_pips=6)
        domino1 = Domino(1, 5)
        expected_display = """\
x x x

5|1 x
"""

        board.add(domino1, 0, 0)
        domino1.flip()

        self.assertMultiLineEqual(expected_display, board.display())
예제 #19
0
    def testFillWithRandomDomino(self, mock_choose):
        mock_choose.side_effect = [[Domino(0, 5)], [Domino(0, 2)]]
        dummy_random = DummyRandom(randints={(0, 3): [1, 1]})  # directions
        board = Board(2, 2, max_pips=6)
        expected_display = """\
5 2
- -
0 0
"""

        board.fill(dummy_random)
        display = board.display()

        self.assertMultiLineEqual(expected_display, display)
예제 #20
0
    def testFillWithNoMatchesNext(self, mock_choose):
        mock_choose.side_effect = [[Domino(0, 5)],
                                   [Domino(0, 0), Domino(0, 1)]]
        dummy_random = DummyRandom(randints={(0, 3): [1, 1]})  # directions
        board = Board(2, 2, max_pips=6)
        expected_display = """\
5 0
- -
0 1
"""

        board.fill(dummy_random, matches_allowed=False)
        display = board.display()

        self.assertMultiLineEqual(expected_display, display)
예제 #21
0
    def testAddDomino(self):
        board = Board(4, 3)
        board.add(Domino(5, 6), 1, 2)

        pips = board[1][2].pips

        self.assertEqual(5, pips)
예제 #22
0
    def testRotateAndAdd(self):
        board = Board(4, 3)
        domino1 = Domino(5, 6)
        domino1.rotate(-90)
        board.add(domino1, 1, 2)
        expected_display = """\
x 5 x x
  -
x 6 x x

x x x x
"""

        display = board.display()

        self.assertMultiLineEqual(expected_display, display)
예제 #23
0
    def testRotateAndAdd(self):
        board = Board(4, 3)
        domino1 = Domino(5, 6)
        domino1.rotate(-90)
        board.add(domino1, 1, 2)
        expected_display = """\
x 5 x x
  -
x 6 x x

x x x x
"""

        display = board.display()

        self.assertMultiLineEqual(expected_display, display)
예제 #24
0
    def test_create(self):
        state = """\
0 1|2
-
1 3|4
===
4|5
5|6
"""
        expected_queue = [Domino(4, 5), Domino(5, 6)]

        board = QueuedBoard.create(state)

        self.assertEqual(1, board[0][0].pips)
        self.assertEqual(2, board[2][1].pips)
        self.assertEqual(expected_queue, board.queue)
예제 #25
0
    def testMoveLeft(self):
        board = Board(4, 3)
        domino1 = Domino(5, 6)
        board.add(domino1, 1, 2)
        domino1.move(-1, 0)
        expected_display = """\
5|6 x x

x x x x

x x x x
"""

        display = board.display()

        self.assertMultiLineEqual(expected_display, display)
예제 #26
0
    def testMoveLeft(self):
        board = Board(4, 3)
        domino1 = Domino(5, 6)
        board.add(domino1, 1, 2)
        domino1.move(-1, 0)
        expected_display = """\
5|6 x x

x x x x

x x x x
"""

        display = board.display()

        self.assertMultiLineEqual(expected_display, display)
예제 #27
0
    def testExtraDominoes(self):
        state = """\
0|0 x

1|1 x
"""
        max_pips = 2
        expected_extra_dominoes = [
            Domino(0, 1),
            Domino(0, 2),
            Domino(1, 2),
            Domino(2, 2)
        ]

        board = Board.create(state, max_pips=max_pips)

        self.assertEqual(expected_extra_dominoes, board.extra_dominoes)
예제 #28
0
    def test_get_from_queue(self):
        state = """\
0 1|2
-
1 2|0
===
0|0
1|1
"""
        board = QueuedBoard.create(state)
        expected_from_queue = Domino(0, 0)
        expected_queue = [Domino(1, 1)]

        from_queue = board.get_from_queue()

        self.assertEqual(expected_from_queue, from_queue)
        self.assertEqual(expected_queue, board.queue)
예제 #29
0
    def testRemove(self):
        board = Board(3, 4)
        domino1 = Domino(1, 5)
        board.add(domino1, 0, 0)

        board.remove(domino1)

        self.assertEqual([], board.dominoes)
예제 #30
0
    def testCreate(self):
        expected_dominoes = [Domino(0, 0),
                             Domino(0, 1),
                             Domino(0, 2),
                             Domino(1, 1),
                             Domino(1, 2),
                             Domino(2, 2)]
        dominoes = Domino.create(2)

        self.assertEqual(expected_dominoes, dominoes)
예제 #31
0
 def create(cls, state, border=0, max_pips=None):
     board_state, *other_states = state.split('===\n')
     board = super().create(board_state, border, max_pips)
     if other_states:
         queue_state, = other_states
         for line in queue_state.splitlines():
             head = int(line[0])
             tail = int(line[-1])
             board.add_to_queue(Domino(head, tail))
     return board
예제 #32
0
    def testCreate(self):
        expected_dominoes = [
            Domino(0, 0),
            Domino(0, 1),
            Domino(0, 2),
            Domino(1, 1),
            Domino(1, 2),
            Domino(2, 2)
        ]
        dominoes = Domino.create(2)

        self.assertEqual(expected_dominoes, dominoes)
예제 #33
0
    def test_extra_dominoes(self):
        state = """\
0 1|2
-
1 2|0
===
0|0
1|1
"""
        expected_extras = [Domino(2, 2)]

        board = QueuedBoard.create(state, max_pips=2)

        self.assertEqual(expected_extras, board.extra_dominoes)
예제 #34
0
    def testDisplay(self):
        board = Board(4, 3)
        board.add(Domino(5, 6), 1, 2)
        expected_display = """\
x 5|6 x

x x x x

x x x x
"""

        display = board.display()

        self.assertMultiLineEqual(expected_display, display)
예제 #35
0
    def testRotateNegative(self):
        domino1 = Domino(1, 5)

        domino1.rotate(-90)

        self.assertEqual(270, domino1.degrees)
예제 #36
0
    def testOccupied(self):
        board = Board(4, 3)
        board.add(Domino(2, 3), 1, 0)

        with self.assertRaisesRegex(BoardError, 'Position 1, 0 is occupied.'):
            board.add(Domino(1, 2), 0, 0)
예제 #37
0
    def testInit(self):
        domino1 = Domino(5, 3)

        pips = domino1.head.pips

        self.assertEqual(5, pips)
예제 #38
0
    def testRepr(self):
        domino1 = Domino(5, 3)

        s = repr(domino1)

        self.assertEqual("Domino(5, 3)", s)
예제 #39
0
    def testRotateWithoutBoard(self):
        domino1 = Domino(5, 6)
        domino1.rotate(90)

        self.assertEqual(90, domino1.degrees)
예제 #40
0
    def testGetDirection(self):
        dx, dy = Domino.get_direction('l')

        self.assertEqual((-1, 0), (dx, dy))
예제 #41
0
    def testName(self):
        domino = Domino(1, 2)
        name = domino.get_name()

        self.assertEqual("12", name)
예제 #42
0
    def testOffBoard(self):
        board = Board(4, 3)

        with self.assertRaisesRegex(BoardError,
                                    'Position 4, 0 is off the board.'):
            board.add(Domino(1, 2), 3, 0)
예제 #43
0
    def testRotateNegative(self):
        domino1 = Domino(1, 5)

        domino1.rotate(-90)

        self.assertEqual(270, domino1.degrees)
예제 #44
0
    def testName(self):
        domino = Domino(1, 2)
        name = domino.get_name()

        self.assertEqual("12", name)
예제 #45
0
def draw_diagram(turtle, state, cell_size, solution=False):
    marks = {'>': partial(draw_arrow, turtle, cell_size),
             '^': partial(draw_arrow, turtle, cell_size, 90),
             '<': partial(draw_arrow, turtle, cell_size, 180),
             'v': partial(draw_arrow, turtle, cell_size, 270),
             '*': partial(draw_capture, turtle, cell_size)}
    pos = turtle.pos()
    lines = state.splitlines()
    turtle.up()
    turtle.forward(cell_size*0.5)
    turtle.right(90)
    turtle.forward(cell_size*len(lines)*0.5)
    turtle.left(90)
    origin = turtle.pos()
    board = Board.create(state)
    draw_board(turtle, board, cell_size)
    turtle.up()
    for y, line in enumerate(reversed(lines)):
        for x, c in enumerate(line):
            if (x+y) % 2:
                mark = marks.get(c)
                if mark is not None:
                    mark()
                    turtle.up()
            turtle.forward(cell_size*.5)
        turtle.back(cell_size*len(line)*.5)
        turtle.left(90)
        turtle.forward(cell_size*.5)
        turtle.right(90)
    turtle.setpos(pos)
    if solution:
        border = 1
        offset = [border, border]
        board = Board.create(state, border=border)
        graph = CaptureBoardGraph()
        graph.walk(board)
        solution = graph.get_solution()
        for move_num, move in enumerate(solution, 1):
            domino_name = move[:2]
            for domino in board.dominoes:
                if domino.get_name() == domino_name:
                    shade = (move_num-1) * 1.0/(len(solution)-1)
                    rgb = (0, 1-shade, shade)
                    turtle.setpos(origin)
                    turtle.forward((domino.head.x-offset[0]) * cell_size)
                    turtle.left(90)
                    turtle.forward((domino.head.y-offset[1]) * cell_size)
                    turtle.right(90)
                    turtle.setheading(domino.degrees)
                    turtle.forward(cell_size*.5)
                    dx, dy = Domino.get_direction(move[-1])
                    turtle.setheading(math.atan2(dy, dx) * 180/math.pi)
                    pen = turtle.pen()
                    turtle.pencolor(rgb)
                    circle_pos = turtle.pos()
                    turtle.width(4)
                    turtle.forward(cell_size*0.05)
                    turtle.down()
                    turtle.forward(cell_size*0.4)
                    turtle.up()
                    turtle.pen(pen)
                    turtle.setpos(circle_pos)
                    turtle.forward(8)
                    turtle.setheading(0)
                    turtle.right(90)
                    turtle.forward(8)
                    turtle.left(90)
                    turtle.down()
                    turtle.down()
                    turtle.pencolor(rgb)
                    turtle.fillcolor('white')
                    turtle.begin_fill()
                    turtle.circle(8)
                    turtle.end_fill()
                    turtle.pen(pen)
                    turtle.write(move_num, align='center')
                    turtle.up()
                    state = graph.move(domino, dx, dy, offset)
                    offset[0] += border
                    offset[1] += border
                    board = Board.create(state, border=border)
                    break
        turtle.setpos(pos)
예제 #46
0
def draw_diagram(turtle, state, cell_size, solution=False):
    marks = {'>': partial(draw_arrow, turtle, cell_size),
             '^': partial(draw_arrow, turtle, cell_size, 90),
             '<': partial(draw_arrow, turtle, cell_size, 180),
             'v': partial(draw_arrow, turtle, cell_size, 270),
             '*': partial(draw_capture, turtle, cell_size)}
    pos = turtle.pos()
    lines = state.splitlines()
    turtle.up()
    turtle.forward(cell_size*0.5)
    turtle.right(90)
    turtle.forward(cell_size*len(lines)*0.5)
    turtle.left(90)
    origin = turtle.pos()
    board = Board.create(state)
    draw_board(turtle, board, cell_size)
    turtle.up()
    for y, line in enumerate(reversed(lines)):
        for x, c in enumerate(line):
            if (x+y) % 2:
                mark = marks.get(c)
                if mark is not None:
                    mark()
                    turtle.up()
            turtle.forward(cell_size*.5)
        turtle.back(cell_size*len(line)*.5)
        turtle.left(90)
        turtle.forward(cell_size*.5)
        turtle.right(90)
    turtle.setpos(pos)
    if solution:
        border = 1
        offset = [border, border]
        board = Board.create(state, border=border)
        for cell in board.findMatches():
            turtle.setpos(origin)
            draw_match(turtle,
                       cell_size,
                       offset,
                       cell)
        graph = CaptureBoardGraph()
        graph.walk(board)
        solution = graph.get_solution(partial=True)
        step_count = max(len(solution)-1, 1)
        for move_num, move in enumerate(solution, 1):
            domino_name = move[:2]
            for domino in board.dominoes:
                if domino.get_name() == domino_name:
                    dx, dy = Domino.get_direction(move[-1])
                    turtle.setpos(origin)
                    draw_move(turtle,
                              cell_size,
                              offset,
                              domino,
                              dx,
                              dy,
                              move_num,
                              step_count)
                    old_offset = offset[:]
                    state = graph.move(domino, dx, dy, offset)
                    new_board = Board.create(state, border=border)
                    captures = set(board.dominoes)
                    captures.difference_update(new_board.dominoes)
                    captures.discard(domino)
                    for capture in captures:
                        turtle.setpos(origin)
                        draw_capture_circle(turtle,
                                            cell_size,
                                            old_offset,
                                            capture,
                                            move_num)
                    offset[0] += border
                    offset[1] += border
                    board = new_board
                    break
        # Mark uncaptured dominoes
        for domino in board.dominoes:
            turtle.setpos(origin)
            draw_capture_circle(turtle, cell_size, offset, domino)
        turtle.setpos(pos)