def test_ko_rule(): text1 = """\ A C E G 7 . . . . 7 5 . . . . 5 3 . W B . 3 1 W B . B 1 A C E G >W """ text2 = """\ A C E G 7 . . . . 7 5 . . . . 5 3 . W B . 3 1 W . W B 1 A C E G >B """ board1 = SpargoState(text1) board2 = board1.make_move(2) display = board2.display(show_coordinates=True) valid_moves = board2.get_valid_moves() assert display == text2 assert not valid_moves[1]
def test_capture(): board = SpargoState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 . . . . 3 1 W B . . 1 A C E G >B """) expected_board = """\ A C E G 7 . . . . 7 5 . . . . 5 3 B . . . 3 1 . B . . 1 A C E G >W """ board2 = board.make_move(4) assert board2.display() == expected_board
def test_capture_in_top_right(): board = SpargoState("""\ A C E G 7 . . B W 7 5 . . . . 5 3 . . . . 3 1 . . . . 1 A C E G >B """) expected_board = """\ A C E G 7 . . B . 7 5 . . . B 5 3 . . . . 3 1 . . . . 1 A C E G >W """ board2 = board.make_move(11) assert board2.display() == expected_board
def test_draw(): board = SpargoState("""\ A C E G 7 . W W . 7 5 W W W W 5 3 B B B B 3 1 . B B B 1 A C E G B D F 6 . W . 6 4 W B W 4 2 . B W 2 B D F C E 5 . . 5 3 . B 3 C E >B """) assert board.is_ended() assert not board.is_win(board.BLACK) assert not board.is_win(board.WHITE) assert board.get_winner() == board.NO_PLAYER
def test_capture_group(): board = SpargoState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 . W . . 3 1 B B W . 1 A C E G >W """) expected_board = """\ A C E G 7 . . . . 7 5 . . . . 5 3 W W . . 3 1 . . W . 1 A C E G >B """ board2 = board.make_move(4) assert board2.display() == expected_board
def test_connected_to_freedom(): board = SpargoState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 . . . . 3 1 B B . . 1 A C E G >W """) expected_board = """\ A C E G 7 . . . . 7 5 . . . . 5 3 W . . . 3 1 B B . . 1 A C E G >B """ board2 = board.make_move(4) assert board2.display() == expected_board
def test_overpass_at_edge(): """ The edge should not contribute to overpasses. Playing white at 3G should not capture black, because it has a freedom at 1A. The white at 2D doesn't cut it off, because it's only one side of an overpass. """ start_state = SpargoState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 . W W . 3 1 . B B B 1 A C E G B D F 6 . . . 6 4 . . . 4 2 . W . 2 B D F >W """) expected_display = """\ A C E G 7 . . . . 7 5 . . . . 5 3 . W W W 3 1 . B B B 1 A C E G B D F 6 . . . 6 4 . . . 4 2 . W . 2 B D F >B """ new_state = start_state.make_move(7) display = new_state.display(show_coordinates=True) assert display == expected_display
def test_overpass(): """ Overpass should cut underpass. Playing black at 5G should capture 3G and 1G, because the black overpass cuts off their connection to 3C. 3C and 3E survive as zombies, because they are supporting pieces on level 2. """ start_state = SpargoState("""\ A C E G 7 . . . . 7 5 . B B . 5 3 . W W W 3 1 . B B W 1 A C E G B D F 6 . . . 6 4 . B . 4 2 . B . 2 B D F >B """) expected_display = """\ A C E G 7 . . . . 7 5 . B B B 5 3 . W W . 3 1 . B B . 1 A C E G B D F 6 . . . 6 4 . B . 4 2 . B . 2 B D F >W """ new_state = start_state.make_move(11) display = new_state.display(show_coordinates=True) assert display == expected_display
def test_covered_piece_not_connected(): start_state = SpargoState("""\ A C E G 7 . W . . 7 5 B W B . 5 3 B W B B 3 1 B W W W 1 A C E G B D F 6 . . . 6 4 W B . 4 2 B W . 2 B D F >B """) expected_display = """\ A C E G 7 . W . . 7 5 B W B . 5 3 B W B B 3 1 B W W . 1 A C E G B D F 6 . . . 6 4 W B . 4 2 B W . 2 B D F C E 5 . . 5 3 B . 3 C E >W """ new_state = start_state.make_move(25) display = new_state.display(show_coordinates=True) assert display == expected_display
def test_piece_count_tiny_board(): board_text = """\ A C 3 B W 3 1 W B 1 A C B 2 B 2 B >W """ start_state = SpargoState(board_text, size=2) assert start_state.get_piece_count(SpargoState.BLACK) == 3
def test_update(pixmap_differ: PixmapDiffer): actual: QPainter expected: QPainter with pixmap_differ.create_painters(240, 240, 'spargo_update') as ( actual, expected): expected_scene = QGraphicsScene(0, 0, 240, 240) expected_scene.addPixmap( SpargoDisplay.load_pixmap('board-1.png', QSize(240, 240))).setPos(1, 0) black_ball = SpargoDisplay.load_pixmap('ball-b-shadow-1.png', QSize(60, 60)) expected_scene.addPixmap(black_ball).setPos(63, 166) expected_scene.render(expected) display = SpargoDisplay() display.resize(348, 264) display.update_board(SpargoState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 . . . . 3 1 . B . . 1 A C E G >W """)) render_display(display, actual) assert display.ui.black_count.text() == '1' assert display.ui.white_count.text() == '0'
def test_count_new_piece_in_overpass(): start_state = SpargoState("""\ A C E G 7 . B W . 7 5 . B W W 5 3 B B B W 3 1 . W B B 1 A C E G B D F 6 . . . 6 4 . W . 4 2 . . . 2 B D F >W """) expected_display = """\ A C E G 7 . B W . 7 5 . B W W 5 3 B B B W 3 1 . W B . 1 A C E G B D F 6 . . . 6 4 . W . 4 2 . W . 2 B D F >B """ new_state = start_state.make_move(17) display = new_state.display(show_coordinates=True) assert display == expected_display
def test_zombie(): board = SpargoState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 . W W . 3 1 B B W . 1 A C E G B D F 6 . . . 6 4 . . . 4 2 . W . 2 B D F >W """) expected_board = """\ A C E G 7 . . . . 7 5 . . . . 5 3 W W W . 3 1 . B W . 1 A C E G B D F 6 . . . 6 4 . . . 4 2 . W . 2 B D F >B """ board2 = board.make_move(4) assert board2.display() == expected_board
def test_climb_to_freedom(): board = SpargoState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 . W B . 3 1 B B W . 1 A C E G B D F 6 . . . 6 4 . . . 4 2 . B . 2 B D F >W """) expected_board = """\ A C E G 7 . . . . 7 5 . . . . 5 3 W W B . 3 1 B B W . 1 A C E G B D F 6 . . . 6 4 . . . 4 2 . B . 2 B D F >B """ board2 = board.make_move(4) assert board2.display() == expected_board
def test_suicide_invalid(): board = SpargoState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 B . . . 3 1 . B . . 1 A C E G >W """) valid_moves = board.get_valid_moves() is_second_level_valid = valid_moves[16] is_bottom_left_valid = valid_moves[0] assert not is_second_level_valid assert not is_bottom_left_valid
def test_blocked_player_wins(): board = SpargoState("""\ A C E G 7 . W W . 7 5 W W W W 5 3 B B B B 3 1 . B B B 1 A C E G B D F 6 . W . 6 4 B W B 4 2 . B B 2 B D F C E 5 . . 5 3 . W 3 C E >B """) assert board.is_ended() assert board.is_win(board.BLACK) assert not board.is_win(board.WHITE) assert board.get_winner() == board.BLACK
def test_winner(): board = SpargoState("""\ A C E G 7 . B B . 7 5 B B B B 5 3 B B B B 3 1 . B B . 1 A C E G >W """) assert board.is_ended() assert board.is_win(board.BLACK) assert not board.is_win(board.WHITE) assert board.get_winner() == board.BLACK
def __init__(self, size: int = 4): super().__init__(SpargoState(size=size)) self.visible_counts = PlayerCode.BLACK, PlayerCode.WHITE
def test_board_size_3(pixmap_differ: PixmapDiffer): actual: QPainter expected: QPainter with pixmap_differ.create_painters(240, 240, 'margo_board_size_3') as (actual, expected): expected_scene = QGraphicsScene(0, 0, 240, 240) full_board = MargoDisplay.load_pixmap('board-1.png') width = full_board.width() height = full_board.height() top_height = round(height * 0.28) mid_height = round(height * 0.21) bottom_height = round(height * 0.29) left_width = round(width * 0.28) mid_width = round(width * 0.22) right_width = round(width * 0.279) assembled_board = QPixmap(left_width + mid_width + right_width, top_height + mid_height + bottom_height) assembled_board.fill(Qt.transparent) assembled_painter = QPainter(assembled_board) # top left assembled_painter.drawPixmap(0, 0, left_width, top_height, full_board, 0, 0, left_width, top_height) # top middle assembled_painter.drawPixmap(left_width, 0, mid_width, top_height, full_board, left_width, 0, mid_width, top_height) # top right assembled_painter.drawPixmap(left_width + mid_width, 0, right_width, top_height, full_board, width - right_width, 0, right_width, top_height) # left middle assembled_painter.drawPixmap(0, top_height, left_width, mid_height, full_board, 0, top_height, left_width, mid_height) # middle middle assembled_painter.drawPixmap(left_width, top_height, mid_width, mid_height, full_board, left_width, top_height, mid_width, mid_height) # right middle assembled_painter.drawPixmap(left_width + mid_width, top_height, right_width, mid_height, full_board, width - right_width, top_height, right_width, mid_height) # bottom left assembled_painter.drawPixmap(0, top_height + mid_height, left_width, bottom_height, full_board, 0, height - bottom_height, left_width, bottom_height) # bottom middle assembled_painter.drawPixmap(left_width, top_height + mid_height, mid_width, bottom_height, full_board, left_width, height - bottom_height, mid_width, bottom_height) # bottom right assembled_painter.drawPixmap(left_width + mid_width, top_height + mid_height, right_width, bottom_height, full_board, width - right_width, height - bottom_height, right_width, bottom_height) assembled_painter.end() scaled_board = assembled_board.scaled(240, 240, Qt.KeepAspectRatio, Qt.SmoothTransformation) board_item = expected_scene.addPixmap(scaled_board) board_item.setPos(2, 0) white_ball = MargoDisplay.load_pixmap('ball-w-shadow-1.png', QSize(76, 76)) black_ball = MargoDisplay.load_pixmap('ball-b-shadow-1.png', QSize(76, 76)) expected_scene.addPixmap(white_ball).setPos(15, 145) expected_scene.addPixmap(black_ball).setPos(81, 79) expected_scene.render(expected) display = MargoDisplay(size=3) display.resize(348, 264) board_text = """\ A C E 5 . . . 5 3 . B . 3 1 W . . 1 A C E >B """ display.update_board(SpargoState(board_text, size=3)) render_display(display, actual)
def test_board_size_2(pixmap_differ: PixmapDiffer): actual: QPainter expected: QPainter with pixmap_differ.create_painters(240, 240, 'margo_board_size_2') as (actual, expected): expected_scene = QGraphicsScene(0, 0, 240, 240) full_board = MargoDisplay.load_pixmap('board-1.png') width = full_board.width() height = full_board.height() top_height = round(height * 0.28) left_width = round(width * 0.28) right_width = round(width * 0.279) bottom_height = round(height * 0.29) assembled_board = QPixmap(left_width + right_width, top_height + bottom_height) assembled_board.fill(Qt.transparent) assembled_painter = QPainter(assembled_board) # top left assembled_painter.drawPixmap(0, 0, left_width, top_height, full_board, 0, 0, left_width, top_height) # top right assembled_painter.drawPixmap(left_width, 0, right_width, top_height, full_board, width - right_width, 0, right_width, top_height) # bottom left assembled_painter.drawPixmap(0, top_height, left_width, bottom_height, full_board, 0, height - bottom_height, left_width, bottom_height) # bottom right assembled_painter.drawPixmap(left_width, top_height, right_width, bottom_height, full_board, width - right_width, height - bottom_height, right_width, bottom_height) assembled_painter.end() scaled_board = assembled_board.scaled(232, 240, Qt.KeepAspectRatio, Qt.SmoothTransformation) board_item = expected_scene.addPixmap(scaled_board) board_item.setPos(4, 0) white_ball = MargoDisplay.load_pixmap('ball-w-shadow-1.png', QSize(103, 103)) black_ball = MargoDisplay.load_pixmap('ball-b-shadow-1.png', QSize(103, 103)) expected_scene.addPixmap(white_ball).setPos(23, 108) expected_scene.addPixmap(black_ball).setPos(113, 18) expected_scene.render(expected) display = MargoDisplay(size=2) trigger_resize(display, 292, 240) display.resize(348, 264) board_text = """\ A C 3 . B 3 1 W . 1 A C >B """ display.update_board(SpargoState(board_text, size=2)) render_display(display, actual)