Exemple #1
0
def test_merge_slide_one_side():
    """Tests merge slide.

    Splits a1 to a4 and d1 and then merges to d4.
    The square c4 will block one path of the merge in superposition.
    """
    b = simulator(u.squares_to_bitboard(["a1", "c3"]))
    assert b.perform_moves(
        "a1^a4d1:SPLIT_SLIDE:BASIC",
        "c3^c4c5:SPLIT_JUMP:BASIC",
        "a4d1^d4:MERGE_SLIDE:BASIC",
    )
    possibilities = [
        u.squares_to_bitboard(["a4", "c4"]),
        u.squares_to_bitboard(["d4", "c4"]),
        u.squares_to_bitboard(["d4", "c5"]),
    ]
    assert_samples_in(b, possibilities)
    probs = b.get_probability_distribution(20000)
    assert_fifty_fifty(probs, qb.square_to_bit("c4"))
    assert_fifty_fifty(probs, qb.square_to_bit("c5"))
    assert_prob_about(probs, qb.square_to_bit("a4"), 0.25)
    assert_prob_about(probs, qb.square_to_bit("d4"), 0.75)
    board_probs = b.get_board_probability_distribution(20000)
    assert len(board_probs) == len(possibilities)
    assert_prob_about(board_probs, possibilities[0], 0.25)
    assert_prob_about(board_probs, possibilities[1], 0.25)
    assert_prob_about(board_probs, possibilities[2], 0.5)
def test_pawn_capture(board):
    """Tests pawn capture with entanglement.

    Rook on a3 => a4/a5 and rook on c3 => c4/c5.
    Pawn on b3 attempts to capture both rooks.
    The first capture should put the pawn in super-position,
    and the second should force a measurement.
    """
    b = board.with_state(u.squares_to_bitboard(['a3', 'b3', 'c3']))
    # Capture and put the pawn in superposition
    assert b.perform_moves('a3a4a5:SPLIT_JUMP:BASIC',
                           'b3a4:PAWN_CAPTURE:BASIC')
    possibilities = [
        u.squares_to_bitboard(['a5', 'b3', 'c3']),
        u.squares_to_bitboard(['a4', 'c3']),
    ]
    assert_samples_in(b, possibilities)
    probs = b.get_probability_distribution(5000)
    assert_fifty_fifty(probs, qb.square_to_bit('a5'))
    assert_fifty_fifty(probs, qb.square_to_bit('a4'))
    assert_fifty_fifty(probs, qb.square_to_bit('b3'))

    did_it_move = b.perform_moves('c3c4c5:SPLIT_JUMP:BASIC',
                                  'b3c4:PAWN_CAPTURE:BASIC')
    if did_it_move:
        possibilities = [
            u.squares_to_bitboard(['a5', 'b3', 'c5']),
            u.squares_to_bitboard(['a5', 'c4']),
        ]
    else:
        possibilities = [
            u.squares_to_bitboard(['a4', 'c4']),
            u.squares_to_bitboard(['a4', 'c5']),
        ]
    assert_samples_in(b, possibilities)
def test_split_move(move_type, board):
    b = board.with_state(u.squares_to_bitboard(['a1']))
    b.do_move(
        move.Move('a1',
                  'a3',
                  target2='c1',
                  move_type=move_type,
                  move_variant=enums.MoveVariant.BASIC))
    samples = b.sample(100)
    assert_this_or_that(samples, u.squares_to_bitboard(['a3']),
                        u.squares_to_bitboard(['c1']))
    probs = b.get_probability_distribution(5000)
    assert_fifty_fifty(probs, qb.square_to_bit('a3'))
    assert_fifty_fifty(probs, qb.square_to_bit('c1'))

    # Test doing a jump after a split move
    m = move.Move('c1',
                  'd1',
                  move_type=enums.MoveType.JUMP,
                  move_variant=enums.MoveVariant.BASIC)
    did_it_move = b.do_move(m)
    samples = b.sample(100)
    assert_this_or_that(samples, u.squares_to_bitboard(['a3']),
                        u.squares_to_bitboard(['d1']))
    probs = b.get_probability_distribution(5000)
    assert_fifty_fifty(probs, u.square_to_bit('a3'))
    assert_fifty_fifty(probs, u.square_to_bit('d1'))
Exemple #4
0
def test_split_one_slide():
    """Tests a split slide with one blocked path.

    a1 will split to a3 and c1 with square a2 blocked in superposition.
    """
    b = simulator(u.squares_to_bitboard(["a1", "b2"]))
    assert b.perform_moves(
        "b2^a2c2:SPLIT_JUMP:BASIC",
        "a1^a3c1:SPLIT_SLIDE:BASIC",
    )
    samples = b.sample(100)
    possibilities = [
        u.squares_to_bitboard(["c1", "a2"]),
        u.squares_to_bitboard(["a3", "c2"]),
        u.squares_to_bitboard(["c1", "c2"]),
    ]
    assert all(sample in possibilities for sample in samples)
    probs = b.get_probability_distribution(10000)
    assert_fifty_fifty(probs, qb.square_to_bit("a2"))
    assert_fifty_fifty(probs, qb.square_to_bit("c2"))
    assert_prob_about(probs, qb.square_to_bit("a3"), 0.25)
    assert_prob_about(probs, qb.square_to_bit("c1"), 0.75)
    board_probs = b.get_board_probability_distribution(10000)
    assert len(board_probs) == len(possibilities)
    assert_prob_about(board_probs, possibilities[0], 0.5)
    assert_prob_about(board_probs, possibilities[1], 0.25)
    assert_prob_about(board_probs, possibilities[2], 0.25)
Exemple #5
0
def test_merge_slide_one_side(board):
    """Tests merge slide.

    Splits a1 to a4 and d1 and then merges to d4.
    The square c4 will block one path of the merge in superposition.
    """
    b = board(u.squares_to_bitboard(['a1', 'c3']))
    assert b.perform_moves(
        'a1^a4d1:SPLIT_SLIDE:BASIC',
        'c3^c4c5:SPLIT_JUMP:BASIC',
        'a4d1^d4:MERGE_SLIDE:BASIC',
    )
    possibilities = [
        u.squares_to_bitboard(['a4', 'c4']),
        u.squares_to_bitboard(['d4', 'c4']),
        u.squares_to_bitboard(['d4', 'c5']),
    ]
    assert_samples_in(b, possibilities)
    probs = b.get_probability_distribution(20000)
    assert_fifty_fifty(probs, qb.square_to_bit('c4'))
    assert_fifty_fifty(probs, qb.square_to_bit('c5'))
    assert_prob_about(probs, qb.square_to_bit('a4'), 0.25)
    assert_prob_about(probs, qb.square_to_bit('d4'), 0.75)
    board_probs = b.get_board_probability_distribution(20000)
    assert len(board_probs) == len(possibilities)
    assert_prob_about(board_probs, possibilities[0], 0.25)
    assert_prob_about(board_probs, possibilities[1], 0.25)
    assert_prob_about(board_probs, possibilities[2], 0.5)
Exemple #6
0
def test_split_one_slide(board):
    """Tests a split slide with one blocked path.

    a1 will split to a3 and c1 with square a2 blocked in superposition.
    """
    b = board(u.squares_to_bitboard(['a1', 'b2']))
    assert b.perform_moves(
        'b2^a2c2:SPLIT_JUMP:BASIC',
        'a1^a3c1:SPLIT_SLIDE:BASIC',
    )
    samples = b.sample(100)
    possibilities = [
        u.squares_to_bitboard(['c1', 'a2']),
        u.squares_to_bitboard(['a3', 'c2']),
        u.squares_to_bitboard(['c1', 'c2']),
    ]
    assert (all(sample in possibilities for sample in samples))
    probs = b.get_probability_distribution(10000)
    assert_fifty_fifty(probs, qb.square_to_bit('a2'))
    assert_fifty_fifty(probs, qb.square_to_bit('c2'))
    assert_prob_about(probs, qb.square_to_bit('a3'), 0.25)
    assert_prob_about(probs, qb.square_to_bit('c1'), 0.75)
    board_probs = b.get_board_probability_distribution(10000)
    assert len(board_probs) == len(possibilities)
    assert_prob_about(board_probs, possibilities[0], 0.5)
    assert_prob_about(board_probs, possibilities[1], 0.25)
    assert_prob_about(board_probs, possibilities[2], 0.25)
def test_undo_last_move():
    # TODO  (cantwellc) more comprehensive tests
    b = qb.CirqBoard(u.squares_to_bitboard(['a2']))
    assert b.perform_moves('a2a4:PAWN_TWO_STEP:BASIC')
    probs = b.get_probability_distribution(1000)
    assert_prob_about(probs, qb.square_to_bit('a4'), 1.0)
    assert b.undo_last_move()
    probs = b.get_probability_distribution(1000)
    assert_prob_about(probs, qb.square_to_bit('a2'), 1.0)
Exemple #8
0
def test_undo_entangled_measurement():
    b = simulator(u.squares_to_bitboard(["a2", "b1", "c2", "d1"]))
    assert b.perform_moves("b1^a3c3:SPLIT_JUMP:BASIC",
                           "c2c4:PAWN_TWO_STEP:BASIC")
    probs = b.get_probability_distribution(10000)
    assert_prob_about(probs, qb.square_to_bit("a3"), 0.5)
    assert_prob_about(probs, qb.square_to_bit("c2"), 0.5)
    assert_prob_about(probs, qb.square_to_bit("c3"), 0.5)
    assert_prob_about(probs, qb.square_to_bit("c4"), 0.5)
    board_probs = b.get_board_probability_distribution(10000)
    assert len(board_probs) == 2
    assert_prob_about(board_probs,
                      u.squares_to_bitboard(["a3", "c4", "a2", "d1"]), 0.5)
    assert_prob_about(board_probs,
                      u.squares_to_bitboard(["c3", "c2", "a2", "d1"]), 0.5)
    b.perform_moves("d1c2:JUMP:EXCLUDED")
    assert b.undo_last_move()
    probs = b.get_probability_distribution(10000)
    assert_prob_about(probs, qb.square_to_bit("a3"), 0.5)
    assert_prob_about(probs, qb.square_to_bit("c2"), 0.5)
    assert_prob_about(probs, qb.square_to_bit("c3"), 0.5)
    assert_prob_about(probs, qb.square_to_bit("c4"), 0.5)
    board_probs = b.get_board_probability_distribution(10000)
    assert len(board_probs) == 2
    assert_prob_about(board_probs,
                      u.squares_to_bitboard(["a3", "c4", "a2", "d1"]), 0.5)
    assert_prob_about(board_probs,
                      u.squares_to_bitboard(["c3", "c2", "a2", "d1"]), 0.5)
Exemple #9
0
def test_undo_entangled_measurement():
    b = simulator(u.squares_to_bitboard(['a2', 'b1', 'c2', 'd1']))
    assert b.perform_moves('b1^a3c3:SPLIT_JUMP:BASIC',
                           'c2c4:PAWN_TWO_STEP:BASIC')
    probs = b.get_probability_distribution(10000)
    assert_prob_about(probs, qb.square_to_bit('a3'), 0.5)
    assert_prob_about(probs, qb.square_to_bit('c2'), 0.5)
    assert_prob_about(probs, qb.square_to_bit('c3'), 0.5)
    assert_prob_about(probs, qb.square_to_bit('c4'), 0.5)
    board_probs = b.get_board_probability_distribution(10000)
    assert len(board_probs) == 2
    assert_prob_about(board_probs,
                      u.squares_to_bitboard(['a3', 'c4', 'a2', 'd1']), 0.5)
    assert_prob_about(board_probs,
                      u.squares_to_bitboard(['c3', 'c2', 'a2', 'd1']), 0.5)
    b.perform_moves('d1c2:JUMP:EXCLUDED')
    assert b.undo_last_move()
    probs = b.get_probability_distribution(10000)
    assert_prob_about(probs, qb.square_to_bit('a3'), 0.5)
    assert_prob_about(probs, qb.square_to_bit('c2'), 0.5)
    assert_prob_about(probs, qb.square_to_bit('c3'), 0.5)
    assert_prob_about(probs, qb.square_to_bit('c4'), 0.5)
    board_probs = b.get_board_probability_distribution(10000)
    assert len(board_probs) == 2
    assert_prob_about(board_probs,
                      u.squares_to_bitboard(['a3', 'c4', 'a2', 'd1']), 0.5)
    assert_prob_about(board_probs,
                      u.squares_to_bitboard(['c3', 'c2', 'a2', 'd1']), 0.5)
Exemple #10
0
def test_undo_last_move():
    # TODO  (cantwellc) more comprehensive tests
    b = simulator(u.squares_to_bitboard(["a2"]))
    assert b.perform_moves("a2a4:PAWN_TWO_STEP:BASIC")
    probs = b.get_probability_distribution(1000)
    assert_prob_about(probs, qb.square_to_bit("a4"), 1.0)
    board_probs = b.get_board_probability_distribution(1000)
    assert len(board_probs) == 1
    assert_prob_about(board_probs, u.squares_to_bitboard(["a4"]), 1.0)
    assert b.undo_last_move()
    probs = b.get_probability_distribution(1000)
    assert_prob_about(probs, qb.square_to_bit("a2"), 1.0)
    board_probs = b.get_board_probability_distribution(1000)
    assert len(board_probs) == 1
    assert_prob_about(board_probs, u.squares_to_bitboard(["a2"]), 1.0)
def test_merge_slide_both_side(board):
    """Tests a merge slide where both paths are blocked.

    Splits a1 to a4/d1 and merges back to d4. c4 and d3 will
    block one square on each path.
    """
    b = board.with_state(u.squares_to_bitboard(['a1', 'c2', 'c3']))
    assert b.perform_moves(
        'a1a4d1:SPLIT_SLIDE:BASIC',
        'c3c4c5:SPLIT_JUMP:BASIC',
        'c2d2e2:SPLIT_JUMP:BASIC',
        'a4d4--d1:MERGE_SLIDE:BASIC',
    )
    possibilities = [
        u.squares_to_bitboard(['a4', 'd2', 'c4']),
        u.squares_to_bitboard(['d1', 'd2', 'c4']),
        u.squares_to_bitboard(['a4', 'e2', 'c4']),
        u.squares_to_bitboard(['d4', 'e2', 'c4']),
        u.squares_to_bitboard(['d1', 'd2', 'c5']),
        u.squares_to_bitboard(['d4', 'd2', 'c5']),
        u.squares_to_bitboard(['d4', 'e2', 'c5']),
    ]
    assert_samples_in(b, possibilities)
    probs = b.get_probability_distribution(20000)
    assert_fifty_fifty(probs, qb.square_to_bit('c4'))
    assert_fifty_fifty(probs, qb.square_to_bit('c5'))
    assert_fifty_fifty(probs, qb.square_to_bit('d2'))
    assert_fifty_fifty(probs, qb.square_to_bit('e2'))
    assert_fifty_fifty(probs, qb.square_to_bit('d4'))
    assert_prob_about(probs, qb.square_to_bit('a4'), 0.25)
    assert_prob_about(probs, qb.square_to_bit('d1'), 0.25)
Exemple #12
0
def test_pawn_capture():
    """Tests pawn capture with entanglement.

    Rook on a3 => a4/a5 and rook on c3 => c4/c5.
    Pawn on b3 attempts to capture both rooks.
    The first capture should put the pawn in super-position,
    and the second should force a measurement.
    """
    b = simulator(u.squares_to_bitboard(["a3", "b3", "c3"]))
    # Capture and put the pawn in superposition
    assert b.perform_moves("a3^a4a5:SPLIT_JUMP:BASIC",
                           "b3a4:PAWN_CAPTURE:BASIC")
    possibilities = [
        u.squares_to_bitboard(["a5", "b3", "c3"]),
        u.squares_to_bitboard(["a4", "c3"]),
    ]
    assert_samples_in(b, possibilities)
    probs = b.get_probability_distribution(5000)
    assert_fifty_fifty(probs, qb.square_to_bit("a5"))
    assert_fifty_fifty(probs, qb.square_to_bit("a4"))
    assert_fifty_fifty(probs, qb.square_to_bit("b3"))
    board_probs = b.get_board_probability_distribution(5000)
    assert len(board_probs) == len(possibilities)
    assert_fifty_fifty(board_probs, possibilities[0])
    assert_fifty_fifty(board_probs, possibilities[1])

    did_it_move = b.perform_moves("c3^c4c5:SPLIT_JUMP:BASIC",
                                  "b3c4:PAWN_CAPTURE:BASIC")
    if did_it_move:
        possibilities = [
            u.squares_to_bitboard(["a5", "b3", "c5"]),
            u.squares_to_bitboard(["a5", "c4"]),
        ]
    else:
        possibilities = [
            u.squares_to_bitboard(["a4", "c4"]),
            u.squares_to_bitboard(["a4", "c5"]),
        ]
    assert_samples_in(b, possibilities)
    board_probs = b.get_board_probability_distribution(5000)
    assert len(board_probs) == 2
    assert_fifty_fifty(board_probs, possibilities[0])
    assert_fifty_fifty(board_probs, possibilities[1])
Exemple #13
0
def test_split_both_sides():
    """Tests a split slide move where both paths of the slide
    are blocked in superposition.

    The piece will split from a1 to a5/e1.
    The squares c1 and d1 will block one side of the path in superposition.
    The square a3 will be blocked on the other path.

    This will create a lop-sided distribution to test multi-square paths.
    """
    b = simulator(u.squares_to_bitboard(["a1", "b3", "c3", "d3"]))
    assert b.perform_moves(
        "b3^a3b4:SPLIT_JUMP:BASIC",
        "c3^c2c1:SPLIT_JUMP:BASIC",
        "d3^d2d1:SPLIT_JUMP:BASIC",
        "a1^a5e1:SPLIT_SLIDE:BASIC",
    )
    samples = b.sample(1000)
    assert len(samples) == 1000
    possibilities = [
        #                 a1/a5/e1 a3/b4 c1/c2 d1/d2
        u.squares_to_bitboard(["a1", "a3", "c1", "d1"]),
        u.squares_to_bitboard(["a1", "a3", "c1", "d2"]),
        u.squares_to_bitboard(["a1", "a3", "c2", "d1"]),
        u.squares_to_bitboard(["e1", "a3", "c2", "d2"]),
        u.squares_to_bitboard(["a5", "b4", "c1", "d1"]),
        u.squares_to_bitboard(["a5", "b4", "c1", "d2"]),
        u.squares_to_bitboard(["a5", "b4", "c2", "d1"]),
        u.squares_to_bitboard(["a5", "b4", "c2", "d2"]),
        u.squares_to_bitboard(["e1", "b4", "c2", "d2"]),
    ]
    assert all(sample in possibilities for sample in samples)
    probs = b.get_probability_distribution(25000)
    assert_fifty_fifty(probs, qb.square_to_bit("a3"))
    assert_fifty_fifty(probs, qb.square_to_bit("b4"))
    assert_fifty_fifty(probs, qb.square_to_bit("c1"))
    assert_fifty_fifty(probs, qb.square_to_bit("c2"))
    assert_fifty_fifty(probs, qb.square_to_bit("d1"))
    assert_fifty_fifty(probs, qb.square_to_bit("d2"))
    assert_prob_about(probs, qb.square_to_bit("a1"), 0.375)
    assert_prob_about(probs, qb.square_to_bit("e1"), 0.1875)
    assert_prob_about(probs, qb.square_to_bit("a5"), 0.4375)
    board_probs = b.get_board_probability_distribution(25000)
    assert len(board_probs) == len(possibilities)
    for possibility in possibilities[:7]:
        assert_prob_about(board_probs, possibility, 0.125)
    for possibility in possibilities[7:]:
        assert_prob_about(board_probs, possibility, 0.0625)
Exemple #14
0
def test_split_both_sides(board):
    """ Tests a split slide move where both paths of the slide
    are blocked in superposition.

    The piece will split from a1 to a5/e1.
    The squares c1 and d1 will block one side of the path in superposition.
    The square a3 will be blocked on the other path.

    This will create a lop-sided distribution to test multi-square paths.
    """
    b = board(u.squares_to_bitboard(['a1', 'b3', 'c3', 'd3']))
    assert b.perform_moves(
        'b3^a3b4:SPLIT_JUMP:BASIC',
        'c3^c2c1:SPLIT_JUMP:BASIC',
        'd3^d2d1:SPLIT_JUMP:BASIC',
        'a1^a5e1:SPLIT_SLIDE:BASIC',
    )
    samples = b.sample(1000)
    assert len(samples) == 1000
    possibilities = [
        #                 a1/a5/e1 a3/b4 c1/c2 d1/d2
        u.squares_to_bitboard(['a1', 'a3', 'c1', 'd1']),
        u.squares_to_bitboard(['a1', 'a3', 'c1', 'd2']),
        u.squares_to_bitboard(['a1', 'a3', 'c2', 'd1']),
        u.squares_to_bitboard(['e1', 'a3', 'c2', 'd2']),
        u.squares_to_bitboard(['a5', 'b4', 'c1', 'd1']),
        u.squares_to_bitboard(['a5', 'b4', 'c1', 'd2']),
        u.squares_to_bitboard(['a5', 'b4', 'c2', 'd1']),
        u.squares_to_bitboard(['a5', 'b4', 'c2', 'd2']),
        u.squares_to_bitboard(['e1', 'b4', 'c2', 'd2']),
    ]
    assert (all(sample in possibilities for sample in samples))
    probs = b.get_probability_distribution(25000)
    assert_fifty_fifty(probs, qb.square_to_bit('a3'))
    assert_fifty_fifty(probs, qb.square_to_bit('b4'))
    assert_fifty_fifty(probs, qb.square_to_bit('c1'))
    assert_fifty_fifty(probs, qb.square_to_bit('c2'))
    assert_fifty_fifty(probs, qb.square_to_bit('d1'))
    assert_fifty_fifty(probs, qb.square_to_bit('d2'))
    assert_prob_about(probs, qb.square_to_bit('a1'), 0.375)
    assert_prob_about(probs, qb.square_to_bit('e1'), 0.1875)
    assert_prob_about(probs, qb.square_to_bit('a5'), 0.4375)
    board_probs = b.get_board_probability_distribution(25000)
    assert len(board_probs) == len(possibilities)
    for possibility in possibilities[:7]:
        assert_prob_about(board_probs, possibility, 0.125)
    for possibility in possibilities[7:]:
        assert_prob_about(board_probs, possibility, 0.0625)
Exemple #15
0
def test_split_move(move_type, board):
    b = board(u.squares_to_bitboard(["a1"]))
    b.do_move(
        move.Move(
            "a1",
            "a3",
            target2="c1",
            move_type=move_type,
            move_variant=enums.MoveVariant.BASIC,
        ))
    samples = b.sample(100)
    assert_this_or_that(samples, u.squares_to_bitboard(["a3"]),
                        u.squares_to_bitboard(["c1"]))
    probs = b.get_probability_distribution(5000)
    assert_fifty_fifty(probs, qb.square_to_bit("a3"))
    assert_fifty_fifty(probs, qb.square_to_bit("c1"))
    board_probs = b.get_board_probability_distribution(5000)
    assert len(board_probs) == 2
    assert_fifty_fifty(board_probs, u.squares_to_bitboard(["a3"]))
    assert_fifty_fifty(board_probs, u.squares_to_bitboard(["c1"]))

    # Test doing a jump after a split move
    m = move.Move("c1",
                  "d1",
                  move_type=enums.MoveType.JUMP,
                  move_variant=enums.MoveVariant.BASIC)
    assert b.do_move(m)
    samples = b.sample(100)
    assert_this_or_that(samples, u.squares_to_bitboard(["a3"]),
                        u.squares_to_bitboard(["d1"]))
    probs = b.get_probability_distribution(5000)
    assert_fifty_fifty(probs, u.square_to_bit("a3"))
    assert_fifty_fifty(probs, u.square_to_bit("d1"))
    board_probs = b.get_board_probability_distribution(5000)
    assert len(board_probs) == 2
    assert_fifty_fifty(board_probs, u.squares_to_bitboard(["a3"]))
    assert_fifty_fifty(board_probs, u.squares_to_bitboard(["d1"]))
Exemple #16
0
def test_merge_slide_both_side():
    """Tests a merge slide where both paths are blocked.

    Splits a1 to a4/d1 and merges back to d4. c4 and d3 will
    block one square on each path.
    """
    b = simulator(u.squares_to_bitboard(["a1", "c2", "c3"]))
    assert b.perform_moves(
        "a1^a4d1:SPLIT_SLIDE:BASIC",
        "c3^c4c5:SPLIT_JUMP:BASIC",
        "c2^d2e2:SPLIT_JUMP:BASIC",
        "a4d1^d4:MERGE_SLIDE:BASIC",
    )
    possibilities = [
        u.squares_to_bitboard(["a4", "d2", "c4"]),
        u.squares_to_bitboard(["d1", "d2", "c4"]),
        u.squares_to_bitboard(["a4", "e2", "c4"]),
        u.squares_to_bitboard(["d4", "e2", "c4"]),
        u.squares_to_bitboard(["d1", "d2", "c5"]),
        u.squares_to_bitboard(["d4", "d2", "c5"]),
        u.squares_to_bitboard(["d4", "e2", "c5"]),
    ]
    assert_samples_in(b, possibilities)
    probs = b.get_probability_distribution(20000)
    assert_fifty_fifty(probs, qb.square_to_bit("c4"))
    assert_fifty_fifty(probs, qb.square_to_bit("c5"))
    assert_fifty_fifty(probs, qb.square_to_bit("d2"))
    assert_fifty_fifty(probs, qb.square_to_bit("e2"))
    assert_fifty_fifty(probs, qb.square_to_bit("d4"))
    assert_prob_about(probs, qb.square_to_bit("a4"), 0.25)
    assert_prob_about(probs, qb.square_to_bit("d1"), 0.25)
    board_probs = b.get_board_probability_distribution(20000)
    assert len(board_probs) == len(possibilities)
    for possibility in possibilities[:6]:
        assert_prob_about(board_probs, possibility, 0.125)
    assert_prob_about(board_probs, possibilities[6], 0.25)