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'))
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_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_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)
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)
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)
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])
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_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"]))
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)