def testDisconnectedBeforeCapture(self): """ Board must be connected after move and after capture. Here, move 62L is disconnected after the move, but connected after the capture removes most of the dominoes. Test that the move is still not allowed. """ board = Board.create("""\ x x x x 5 - x x 6|2 3 6|6 2|4 x """) graph = CaptureBoardGraph() expected_states = set("""\ x x x x 5 - x x 6|2 3 6|6 2|4 x """.split('---\n')) states = graph.walk(board) self.assertEqual(expected_states, states)
def testNoSolution(self): graph = CaptureBoardGraph() board = Board.create("""\ 6|2 3 - 2|4 5 """) graph.walk(board) self.assertRaises(NetworkXNoPath, graph.get_solution)
def testSolution(self): graph = CaptureBoardGraph() expected_solution = ['34u', '24r'] board = Board.create("""\ 6|2 3 - 2|4 4 """) graph.walk(board) solution = graph.get_solution() self.assertEqual(expected_solution, solution)
def testPartialSolution(self): graph = CaptureBoardGraph() expected_solution = ['62l'] board = Board.create("""\ 6|2 3 - 2|4 5 """) graph.walk(board) solution = graph.get_solution(return_partial=True) self.assertEqual(expected_solution, solution)
def testPartialSolution(self): graph = CaptureBoardGraph() expected_solution = ['62l'] board = Board.create("""\ 6|2 3 - 2|4 5 """) graph.walk(board) solution = graph.get_solution(partial=True) self.assertEqual(expected_solution, solution)
def testSolution(self): graph = CaptureBoardGraph() expected_solution = ['34u', '24r'] expected_closest = '' board = Board.create("""\ 6|2 3 - 2|4 4 """) graph.walk(board) solution = graph.get_solution() self.assertEqual(expected_solution, solution) self.assertEqual(expected_closest, graph.closest)
def testNoSolution(self): graph = CaptureBoardGraph() board = Board.create("""\ 6|2 3 - 2|4 5 """) expected_closest = """\ 3 - 5 """ graph.walk(board) self.assertEqual(expected_closest, graph.closest) self.assertRaises(NetworkXNoPath, graph.get_solution)
def testCaptureRight(self): board = Board.create("""\ 0|2 x 1|0 x """) graph = CaptureBoardGraph() expected_states = set("""\ 0|2 1|0 --- """.split('---\n')) states = graph.walk(board) self.assertEqual(expected_states, states)
def testSomeUncaptured(self): board = Board.create("""\ 4|4 3 - 1|5 4 """) graph = CaptureBoardGraph() expected_states = set("""\ 4|4 3 - 1|5 4 --- 1|5 """.split('---\n')) states = graph.walk(board) self.assertEqual(expected_states, states)
def testMoveWithoutCapture(self): board = Board.create("""\ 4|3 1|2 """) graph = CaptureBoardGraph() expected_states = set("""\ 4|3 1|2 --- x 4|3 1|2 x """.split('---\n')) states = graph.walk(board) self.assertEqual(expected_states, states)
def testMoveLeftUpdatesOffset(self): start_state = """\ 4|3 1|2 """ board = Board.create(start_state, border=1) graph = CaptureBoardGraph() expected_state = """\ x 4|3 1|2 x """ graph.walk(board) offset = [1, 1] # position of bottom left corner (within border) expected_offset = [1, 0] # equivalent position after move and cropping state = graph.move(board[1][1].domino, -1, 0, offset) self.assertEqual(expected_state, state) self.assertEqual(expected_offset, offset)
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)
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)
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(return_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)