예제 #1
0
        def it_can_undo_last_move_or_pull(self, reverse_mover):
            src = index_1d(4, 2, reverse_mover.board.width)
            dest = index_1d(3, 2, reverse_mover.board.width)

            assert reverse_mover.move(Direction.LEFT)
            reverse_mover.undo()
            assert reverse_mover.state.pusher_position(DEFAULT_PIECE_ID) == src
            assert reverse_mover.board[src].has_pusher
            assert not reverse_mover.board[dest].has_pusher

            reverse_mover.pulls_boxes = True
            box_src = index_1d(4, 1, reverse_mover.board.width)
            box_dest = index_1d(4, 2, reverse_mover.board.width)
            pusher_src = box_dest
            pusher_dest = index_1d(4, 3, reverse_mover.board.width)
            reverse_mover.move(Direction.DOWN)
            reverse_mover.undo()

            assert reverse_mover.state.box_position(DEFAULT_PIECE_ID) == box_src
            assert reverse_mover.state.pusher_position(DEFAULT_PIECE_ID) == pusher_src

            assert reverse_mover.board[box_src].has_box
            assert reverse_mover.board[pusher_src].has_pusher
            assert not reverse_mover.board[box_dest].has_box
            assert not reverse_mover.board[pusher_dest].has_pusher
예제 #2
0
        def it_moves_pusher_in_requested_direction(self, forward_mover):
            src = index_1d(4, 2, forward_mover.board.width)
            dest = index_1d(3, 2, forward_mover.board.width)

            assert forward_mover.move(Direction.LEFT)
            assert forward_mover.state.pusher_position(DEFAULT_PIECE_ID) == dest
            assert not forward_mover.board[src].has_pusher
            assert forward_mover.board[dest].has_pusher
예제 #3
0
 def it_can_undo_last_jump(self, reverse_mover):
     src = index_1d(4, 2, reverse_mover.board.width)
     dest = index_1d(1, 1, reverse_mover.board.width)
     reverse_mover.jump(dest)
     reverse_mover.undo()
     assert reverse_mover.state.pusher_position(DEFAULT_PIECE_ID) == src
     assert reverse_mover.board[src].has_pusher == True
     assert reverse_mover.board[dest].has_pusher == False
예제 #4
0
 def it_skips_explicitly_excluded_positions(self):
     root = index_1d(5, 1, 7)
     assert self.board_graph.reachables(
         root, excluded_positions=[root]
     ) == [index_1d(4, 1, 7)]
     root = index_1d(5, 1, 7)
     assert self.board_graph.reachables(
         root, excluded_positions=[index_1d(4, 1, 7)]
     ) == [root]
예제 #5
0
        def it_can_undo_last_move_or_push(self, forward_mover):
            src = index_1d(4, 2, forward_mover.board.width)
            dest = index_1d(3, 2, forward_mover.board.width)

            forward_mover.move(Direction.LEFT)
            forward_mover.undo()

            assert forward_mover.state.pusher_position(DEFAULT_PIECE_ID) == src
            assert forward_mover.board[src].has_pusher == True
            assert forward_mover.board[dest].has_pusher == False
예제 #6
0
 def it_can_exclude_some_positions(self):
     expected = [index_1d(5, 1, 7), index_1d(4, 1, 7), index_1d(3, 1, 7), index_1d(3, 2, 7)]
     excluded = [index_1d(3, 3, 7), index_1d(2, 3, 7), index_1d(1, 3, 7), index_1d(1, 2, 7), index_1d(1, 1, 7)]
     assert (
         self.variant_board.positions_reachable_by_pusher(
             pusher_position=index_1d(5, 1, 7), excluded_positions=excluded
         )
         == expected
     )
예제 #7
0
 def it_returns_list_of_positions_reachable_by_pusher_movement_only(self):
     expected = [
         index_1d(5, 1, 7),
         index_1d(4, 1, 7),
         index_1d(3, 1, 7),
         index_1d(3, 2, 7),
         index_1d(3, 3, 7),
         index_1d(2, 3, 7),
         index_1d(1, 3, 7),
         index_1d(1, 2, 7),
         index_1d(1, 1, 7),
     ]
     assert self.variant_board.positions_reachable_by_pusher(pusher_position=index_1d(5, 1, 7)) == expected
예제 #8
0
 def test_returns_sequence_of_positions_defining_shortest_path_for_pusher_jump(self, variant_board):
     start_position = index_1d(11, 8, variant_board.width)
     end_position = index_1d(8, 5, variant_board.width)
     expected = variant_board.position_path_to_direction_path(
         variant_board.find_jump_path(start_position, end_position)
     )
     assert expected["path"] == [
         Direction.UP,
         Direction.UP,
         Direction.UP,
         Direction.LEFT,
         Direction.LEFT,
         Direction.LEFT,
     ]
예제 #9
0
 def it_doesnt_require_that_start_position_actually_contain_pusher(self):
     expected = [
         index_1d(4, 1, 7),
         index_1d(3, 1, 7),
         index_1d(3, 2, 7),
         index_1d(3, 3, 7),
         index_1d(2, 3, 7),
         index_1d(1, 3, 7),
         index_1d(1, 2, 7),
         index_1d(1, 1, 7),
     ]
     assert self.variant_board.positions_reachable_by_pusher(pusher_position=index_1d(4, 1, 7)) == expected
예제 #10
0
        def it_doesnt_pull_boxes_if_flag_is_not_set(self, reverse_mover):
            reverse_mover.pulls_boxes = False

            box_src = index_1d(4, 1, reverse_mover.board.width)
            pusher_src = index_1d(4, 2, reverse_mover.board.width)
            pusher_dest = index_1d(4, 3, reverse_mover.board.width)

            assert reverse_mover.move(Direction.DOWN)

            assert reverse_mover.state.box_position(
                DEFAULT_PIECE_ID
            ) == box_src
            assert reverse_mover.state.pusher_position(
                DEFAULT_PIECE_ID
            ) == pusher_dest

            assert reverse_mover.board[box_src].has_box
            assert not reverse_mover.board[pusher_src].has_box
            assert not reverse_mover.board[pusher_src].has_pusher
            assert reverse_mover.board[pusher_dest].has_pusher
예제 #11
0
 def it_memoizes_last_jump_into_movement_history(self, reverse_mover):
     expected = [
         AtomicMove(Direction.UP, False),
         AtomicMove(Direction.LEFT, False),
         AtomicMove(Direction.LEFT, False),
         AtomicMove(Direction.LEFT, False),
     ]
     for am in expected:
         am.is_jump = True
     reverse_mover.jump(index_1d(1, 1, reverse_mover.board.width))
     assert reverse_mover.last_performed_moves == expected
예제 #12
0
        def it_pulls_box_behind_pusher(self, reverse_mover):
            reverse_mover.pulls_boxes = True

            box_src = index_1d(4, 1, reverse_mover.board.width)
            box_dest = index_1d(4, 2, reverse_mover.board.width)
            pusher_src = box_dest
            pusher_dest = index_1d(4, 3, reverse_mover.board.width)
            assert reverse_mover.move(Direction.DOWN)

            assert reverse_mover.state.box_position(
                DEFAULT_PIECE_ID
            ) == box_dest
            assert reverse_mover.state.pusher_position(
                DEFAULT_PIECE_ID
            ) == pusher_dest

            assert not reverse_mover.board[box_src].has_box
            assert not reverse_mover.board[pusher_src].has_pusher
            assert reverse_mover.board[box_dest].has_box
            assert reverse_mover.board[pusher_dest].has_pusher
예제 #13
0
        def it_pushes_box_in_front_of_pusher(self, forward_mover):
            assert forward_mover.move(Direction.DOWN)
            assert forward_mover.move(Direction.RIGHT)

            box_src = index_1d(5, 2, forward_mover.board.width)
            box_dest = index_1d(5, 1, forward_mover.board.width)
            pusher_src = index_1d(5, 3, forward_mover.board.width)
            pusher_dest = box_src
            assert forward_mover.move(Direction.UP)

            assert forward_mover.state.box_position(
                DEFAULT_PIECE_ID + 1
            ) == box_dest
            assert forward_mover.state.pusher_position(
                DEFAULT_PIECE_ID
            ) == pusher_dest

            assert not forward_mover.board[box_src].has_box
            assert not forward_mover.board[pusher_src].has_pusher
            assert forward_mover.board[box_dest].has_box
            assert forward_mover.board[pusher_dest].has_pusher
예제 #14
0
def boxes_positions(board_str_width):
    return {
        DEFAULT_PIECE_ID: index_1d(5, 2, board_str_width),
        DEFAULT_PIECE_ID + 1: index_1d(7, 3, board_str_width),
        DEFAULT_PIECE_ID + 2: index_1d(5, 4, board_str_width),
        DEFAULT_PIECE_ID + 3: index_1d(7, 4, board_str_width),
        DEFAULT_PIECE_ID + 4: index_1d(2, 7, board_str_width),
        DEFAULT_PIECE_ID + 5: index_1d(5, 7, board_str_width),
    }
예제 #15
0
def goals_positions(board_str_width):
    return {
        DEFAULT_PIECE_ID: index_1d(16, 6, board_str_width),
        DEFAULT_PIECE_ID + 1: index_1d(17, 6, board_str_width),
        DEFAULT_PIECE_ID + 2: index_1d(16, 7, board_str_width),
        DEFAULT_PIECE_ID + 3: index_1d(17, 7, board_str_width),
        DEFAULT_PIECE_ID + 4: index_1d(16, 8, board_str_width),
        DEFAULT_PIECE_ID + 5: index_1d(17, 8, board_str_width),
    }
예제 #16
0
 def test_silently_stops_search_on_illegal_direction(self, variant_board):
     direction_path = [Direction.DOWN, Direction.NORTH_WEST]
     start_position = index_1d(11, 8, variant_board.width)
     assert variant_board.path_destination(start_position, direction_path) == index_1d(
         11, 9, variant_board.width
     )
예제 #17
0
 def test_silently_stops_search_on_first_of_board_position(self, variant_board):
     direction_path = [Direction.DOWN, Direction.DOWN, Direction.DOWN]
     start_position = index_1d(11, 8, variant_board.width)
     assert variant_board.path_destination(start_position, direction_path) == index_1d(
         11, 10, variant_board.width
     )
예제 #18
0
 def test_calculates_destination_position_from_source_and_direction_path(self, variant_board):
     direction_path = [Direction.UP, Direction.RIGHT]
     start_position = index_1d(11, 8, variant_board.width)
     assert variant_board.path_destination(start_position, direction_path) == index_1d(
         12, 7, variant_board.width
     )
예제 #19
0
 def test_can_exclude_some_positions(self):
     assert self.variant_board.normalized_pusher_position(
         pusher_position=index_1d(4, 1, 7), excluded_positions=[index_1d(1, 1, 7)]
     ) == index_1d(3, 1, 7)
예제 #20
0
 def test_doesnt_require_that_start_position_actually_contain_pusher(self):
     assert self.variant_board.normalized_pusher_position(pusher_position=index_1d(4, 1, 7)) == index_1d(1, 1, 7)
예제 #21
0
 def test_returns_top_left_position_of_pusher_in_his_reachable_area(self):
     assert self.variant_board.normalized_pusher_position(pusher_position=index_1d(5, 1, 7)) == index_1d(1, 1, 7)
예제 #22
0
 def it_refuses_to_jump_off_the_board(self, reverse_mover):
     with pytest.raises(IndexError):
         reverse_mover.jump(index_1d(42, 42, reverse_mover.board.width))
예제 #23
0
 def it_calculates_all_positions_reachable_from_root(self):
     root = index_1d(5, 1, 7)
     assert self.board_graph.reachables(root
                                       ) == [root, index_1d(4, 1, 7)]
예제 #24
0
def pushers_positions(board_str_width):
    return {
        DEFAULT_PIECE_ID: index_1d(7, 1, board_str_width),
        DEFAULT_PIECE_ID + 1: index_1d(11, 8, board_str_width),
    }
예제 #25
0
 def it_calculates_1D_index_from_2D_coordinates(self):
     assert index_1d(0, 0, 5) == 0
     assert index_1d(4, 5, 5) == 29
     assert index_1d(3, 3, 5) == 18
예제 #26
0
def invalid_goal_position():
    return index_1d(17, 8, 42)
예제 #27
0
def invalid_pusher_position():
    return index_1d(11, 8, 42)
예제 #28
0
def normalized_pushers_positions(board_str_width):
    return {
        DEFAULT_PIECE_ID: index_1d(5, 1, board_str_width),
        DEFAULT_PIECE_ID + 1: index_1d(8, 4, board_str_width),
    }
예제 #29
0
 def test_returns_empty_sequence_if_movement_is_blocked(self, variant_board):
     assert variant_board.find_move_path(index_1d(11, 8, variant_board.width), 0) == []
예제 #30
0
def invalid_box_position():
    return index_1d(5, 7, 42)