def test_superposition_slide_move2(board): """Tests a basic slide through a superposition of two pieces. Splits b3 and c3 to b2/b1 and c2/c1 then slides a1 to d1. """ b = board.with_state(u.squares_to_bitboard(['a1', 'b3', 'c3'])) assert b.perform_moves( 'b3b2b1:SPLIT_JUMP:BASIC', 'c3c2c1:SPLIT_JUMP:BASIC', 'a1e1:SLIDE:BASIC', ) possibilities = [ u.squares_to_bitboard(['a1', 'b1', 'c1']), u.squares_to_bitboard(['a1', 'b1', 'c2']), u.squares_to_bitboard(['a1', 'b2', 'c1']), u.squares_to_bitboard(['e1', 'b2', 'c2']) ] samples = b.sample(100) assert (all(sample in possibilities for sample in samples)) probs = b.get_probability_distribution(10000) assert_fifty_fifty(probs, u.square_to_bit('b2')) assert_fifty_fifty(probs, u.square_to_bit('b1')) assert_fifty_fifty(probs, u.square_to_bit('c2')) assert_fifty_fifty(probs, u.square_to_bit('c1')) assert_prob_about(probs, u.square_to_bit('a1'), 0.75) assert_prob_about(probs, u.square_to_bit('e1'), 0.25)
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)
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_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)
def test_split_capture_with_failed_measurement_outcome(board): b = board(0) # Repeat the moves several times because the do_move calls will trigger a # measurement. for _ in range(20): b.with_state(u.squares_to_bitboard(["a1", "c3"])) # a1 splits into a2 + a3 b.do_move( move.Move( "a1", "a2", target2="a3", move_type=enums.MoveType.SPLIT_JUMP, move_variant=enums.MoveVariant.BASIC, )) # Then a3 tries to capture c3, which requires measuring a3. # The provided measurement outcome says that there is not a piece on a3 # after all, so the capture is unsuccessful. b.do_move( move.Move( "a3", "c3", move_type=enums.MoveType.JUMP, move_variant=enums.MoveVariant.CAPTURE, measurement=0, )) # The only possible outcome is unsuccessful capture -- a1 jumped to a2, # not a3, and the to-be-captured piece on c3 still remains. # However, in the presence of readout error, we may not measure the # piece on either a2 or a3 so post-filtered samples may not contain a2 # in rare cases. probs = b.get_probability_distribution(100) assert_prob_about(probs, u.square_to_bit("a2"), 1, atol=0.1) assert_prob_about(probs, u.square_to_bit("a3"), 0, atol=0.1)
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)
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)
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)
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)
def test_superposition_slide_move2(): """Tests a basic slide through a superposition of two pieces. Splits b3 and c3 to b2/b1 and c2/c1 then slides a1 to d1. """ b = simulator(u.squares_to_bitboard(["a1", "b3", "c3"])) assert b.perform_moves( "b3^b2b1:SPLIT_JUMP:BASIC", "c3^c2c1:SPLIT_JUMP:BASIC", "a1e1:SLIDE:BASIC", ) possibilities = [ u.squares_to_bitboard(["a1", "b1", "c1"]), u.squares_to_bitboard(["a1", "b1", "c2"]), u.squares_to_bitboard(["a1", "b2", "c1"]), u.squares_to_bitboard(["e1", "b2", "c2"]), ] samples = b.sample(100) assert all(sample in possibilities for sample in samples) probs = b.get_probability_distribution(10000) assert_fifty_fifty(probs, u.square_to_bit("b2")) assert_fifty_fifty(probs, u.square_to_bit("b1")) assert_fifty_fifty(probs, u.square_to_bit("c2")) assert_fifty_fifty(probs, u.square_to_bit("c1")) assert_prob_about(probs, u.square_to_bit("a1"), 0.75) assert_prob_about(probs, u.square_to_bit("e1"), 0.25) board_probs = b.get_board_probability_distribution(10000) assert len(board_probs) == len(possibilities) for possibility in possibilities: assert_prob_about(board_probs, possibility, 0.25)
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(): """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)
def test_undo_entangled_measurement(): b = qb.CirqBoard(u.squares_to_bitboard(['a2', 'b1', 'c2', 'd1'])) assert b.perform_moves('b1a3c3: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) 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)
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)