def test_valid_remove_only_free(start: int, end: int, expected_valid: bool, reason: str): board = SpookState("""\ A C E G 7 B B . . 7 5 B B . . 5 3 . W R . 3 1 . . . . 1 A C E G B D F 6 B . . 6 4 . . . 4 2 . . . 2 B D F >R(B,R) """) valid_moves = board.get_valid_moves() assert len(valid_moves) == 31 # 30 removes, plus pass for move in range(start, end): assert valid_moves[move] == expected_valid, move
def test_pass(): state1 = SpookState("""\ A C E G 7 B B . R 7 5 B B . . 5 3 . . . . 3 1 W R . . 1 A C E G >R(R) """) expected_display = """\ A C E G 7 B B . R 7 5 B B . . 5 3 . . . . 3 1 W R . . 1 A C E G >B(B,R) """ state2 = state1.make_move(30) display = state2.display() active_player = state2.get_active_player() assert display == expected_display assert active_player == state2.BLACK
def test_valid_removes_black(start: int, end: int, expected_valid: bool, reason: str): board = SpookState("""\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B W . 6 4 R R B 4 2 R R R 2 B D F >R(B) """) valid_moves = board.get_valid_moves() assert len(valid_moves) == 31 # 30 removes, plus pass for move in range(start, end): assert valid_moves[move] == expected_valid, move
def test_getaway_move_count(): state = SpookState("""\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 B B 5 3 R W 3 C E >B(B,R) """) expected_move_count = 29 assert state.get_move_count() == expected_move_count
def test_valid_drop_only(start: int, end: int, expected_valid: bool, reason: str): """ Ghost has neighbours, but none are free. Valid moves are to remove opponent pieces. """ board = SpookState("""\ A C E G 7 B B . . 7 5 R R . . 5 3 . . . B 3 1 . . . R 1 A C E G B D F 6 W . . 6 4 . . . 4 2 . . . 2 B D F >B(B,R) """) valid_moves = board.get_valid_moves() for move in range(start, end): assert valid_moves[move] == expected_valid, move
def test_remove_drop(): state1 = SpookState("""\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 B B 5 3 R R 3 C E D 4 W 4 D >R(B,R) """) expected_display = """\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 B W 5 3 R R 3 C E >B(B,R) """ state2 = state1.make_move(28) display = state2.display() active_player = state2.get_active_player() assert display == expected_display assert active_player == state2.BLACK
def test_remove_first_neighbour(): """ One neighbour on same level with another of that colour. """ state1 = SpookState("""\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 B W 5 3 R R 3 C E >B(B,R) """) expected_display = """\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 B . 5 3 R W 3 C E >B(R) """ state2 = state1.make_move(26) display = state2.display() active_player = state2.get_active_player() assert display == expected_display assert active_player == state2.BLACK
def test_remove_only_neighbour(): """ One neighbour on same level with no more of that colour. """ state1 = SpookState("""\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 B W 5 3 R R 3 C E >B(B,R) """) expected_display = """\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 W . 5 3 R R 3 C E >R(B,R) """ state2 = state1.make_move(27) display = state2.display() active_player = state2.get_active_player() assert display == expected_display assert active_player == state2.RED
def test_remove_only_free_neighbour(): """ One neighbour on same level with no more of that colour. """ state1 = SpookState("""\ A C E G 7 B B . . 7 5 B B B W 5 3 . . . . 3 1 . . . . 1 A C E G B D F 6 R . . 6 4 . . . 4 2 . . . 2 B D F >B(B,R) """) expected_display = """\ A C E G 7 B B . . 7 5 B B W . 5 3 . . . . 3 1 . . . . 1 A C E G B D F 6 R . . 6 4 . . . 4 2 . . . 2 B D F >R(B,R) """ state2 = state1.make_move(10) display = state2.display() active_player = state2.get_active_player() assert display == expected_display assert active_player == state2.RED
def test_valid_ghost(start: int, end: int, expected_valid: bool, reason: str): board = SpookState("""\ A C E G 7 B B . R 7 5 B B . . 5 3 . . . . 3 1 W . . . 1 A C E G >R(B,R) """) valid_moves = board.get_valid_moves() for move in range(start, end): assert valid_moves[move] == expected_valid, move
def test_remove_opponent_piece_with_free_neighbour(): state1 = SpookState("""\ A C E G 7 B B . . 7 5 R R . . 5 3 W . . R 3 1 . . . R 1 A C E G B D F 6 B . . 6 4 . . . 4 2 . . . 2 B D F >B(B,R) """) expected_display = """\ A C E G 7 B B . . 7 5 R R . . 5 3 W . . R 3 1 . . . . 1 A C E G B D F 6 B . . 6 4 . . . 4 2 . . . 2 B D F >R(B,R) """ state2 = state1.make_move(3) display = state2.display() active_player = state2.get_active_player() assert display == expected_display assert active_player == state2.RED
def test_move_ghost_one_space(): state1 = SpookState("""\ A C E G 7 B R . . 7 5 B R . W 5 3 B R . . 3 1 . . . . 1 A C E G B D F 6 . . . 6 4 B . . 4 2 . . . 2 B D F >R(B,R) """) expected_display = """\ A C E G 7 B R . . 7 5 B R W . 5 3 B R . . 3 1 . . . . 1 A C E G B D F 6 . . . 6 4 B . . 4 2 . . . 2 B D F >B(B,R) """ state2 = state1.make_move(10) display = state2.display() active_player = state2.get_active_player() assert display == expected_display assert active_player == state2.BLACK
def test_valid_adds(start: int, end: int, expected_valid: bool, reason: str): board = SpookState("""\ A C E G 7 . . . . 7 5 . . . . 5 3 . . . . 3 1 . . R . 1 A C E G >B """) valid_moves = board.get_valid_moves() assert len(valid_moves) == 31 # 30 adds, plus pass for move in range(start, end): assert valid_moves[move] == expected_valid, move
def test_start(): expected_display = """\ A C E G 7 . . . . 7 5 . . . . 5 3 . . . . 3 1 . . . . 1 A C E G >R """ state = SpookState() display = state.display() active_player = state.get_active_player() assert display == expected_display assert active_player == state.RED assert not state.is_ended()
def test_add_move(): expected_display = """\ A C E G 7 . . . . 7 5 . . . . 5 3 . . . . 3 1 . . R . 1 A C E G >B """ state1 = SpookState() state2 = state1.make_move(2) display = state2.display() active_player = state2.get_active_player() assert display == expected_display assert active_player == state2.BLACK
def test_hover_enter_remove(pixmap_differ: PixmapDiffer): actual: QPainter expected: QPainter with pixmap_differ.create_painters( 240, 240, 'spook_hover_enter_remove') as (actual, expected): expected_scene = QGraphicsScene(0, 0, 240, 240) expected_scene.addPixmap( SpookDisplay.load_pixmap('board-1.png', QSize(240, 240))).setPos(1, 0) white_ball = SpookDisplay.load_pixmap('ball-w-shadow-1.png', QSize(60, 60)) red_ball = SpookDisplay.load_pixmap('ball-r-shadow-1.png', QSize(60, 60)) black_ball = SpookDisplay.load_pixmap('ball-b-shadow-1.png', QSize(60, 60)) black_piece = expected_scene.addPixmap(black_ball) black_piece.setPos(115, 114) black_piece.setOpacity(0.5) red_piece = expected_scene.addPixmap(red_ball) red_piece.setPos(63, 62) white_piece = expected_scene.addPixmap(white_ball) white_piece.setPos(115, 62) expected_scene.render(expected) display = SpookDisplay() display.update_board( SpookState('''\ A C E G 7 . . . . 7 5 . R W . 5 3 . . B . 3 1 . . . . 1 A C E G >R(R,B) ''')) height = 0 row = 1 column = 2 piece_item = display.item_levels[height][row][column] display.resize(348, 264) display.grab() # Force layout to recalculate. display.on_hover_enter(piece_item) render_display(display, actual)
def test_win(): state = SpookState("""\ A C E G 7 . . . . 7 5 . . B W 5 3 . . . . 3 1 . . . . 1 A C E G >B(B,R) """) assert not state.is_win(state.BLACK) assert state.is_win(state.RED) assert state.get_winner() == state.RED assert state.is_ended()
def test_add_last_piece(): state1 = SpookState("""\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 . B 5 3 R . 3 C E >B """) expected_display = """\ A C E G 7 B B B B 7 5 B B B B 5 3 R R R R 3 1 R R R R 1 A C E G B D F 6 B B B 6 4 R R B 4 2 R R R 2 B D F C E 5 B B 5 3 R R 3 C E D 4 W 4 D >R(B,R) """ state2 = state1.make_move(27) display = state2.display() active_player = state2.get_active_player() assert state1.get_move_count() == 27 assert state2.get_move_count() == 28 assert display == expected_display assert active_player == state2.RED
def test_display_pass(): state = SpookState() move_display = state.display_move(30) assert move_display == 'PASS'
def test_display_move(): state = SpookState() move_display = state.display_move(0) assert move_display == '1A'
def __init__(self): super().__init__(SpookState()) self.ui.pass_button.clicked.connect(self.make_pass_move)