Ejemplo n.º 1
0
def test_taboo_cells(n):
    problem_file = "./warehouses/warehouse_%s.txt" % str(n)
    wh = Warehouse()
    wh.read_warehouse_file(problem_file)
    answer = taboo_cells(wh)
    print(set(find_2D_iterator(answer.split('\n'), "X")))
    print(answer)
 def actions(self, state):
     """
     Return the list of actions that can be executed in the given state.
     
     As specified in the header comment of this class, the attributes
     'self.allow_taboo_push' and 'self.macro' should be tested to determine
     what type of list of actions is to be returned.
     """
     warehouse = sokoban.Warehouse()
     warehouse.extract_locations(state.splitlines())
     # print(warehouse)
     # print(state)
     taboo = set(
         sokoban.find_2D_iterator(
             taboo_cells(str(warehouse)).splitlines(), "X"))
     for box in warehouse.boxes:
         for move in movement:
             worker_position = (box[0] - move[0], box[1] - move[1])
             box_after_pushed = (box[0] + move[0], box[1] + move[1])
             # print(taboo)
             if (can_go_there(warehouse, worker_position)
                     and box_after_pushed not in taboo
                     and box_after_pushed not in warehouse.walls
                     and box_after_pushed not in warehouse.boxes):
                 yield (box, direction(move))
Ejemplo n.º 3
0
    def __init__(self,
                 warehouse,
                 macro=False,
                 allow_taboo_push=False,
                 push_costs=None):
        """
        initialisation function

        stores the state as a tuple of (worker, frozenset((box, cost), ...)
        and any other necessary information for performing the a* graph search algorithm

        @param warehouse: the warehouse object
        @param macro: default False, whether to use macro actions
        @param allow_taboo_push: default False, whether to allow boxes to be pushed onto taboo cells
        @push_costs: default None, list of integer costs following the same order of warehouse.boxes
        """
        self.initial = (warehouse.worker, frozenset(zip(warehouse.boxes, push_costs))) \
            if push_costs is not None \
            else (warehouse.worker, frozenset((box, 0) for box in warehouse.boxes))

        # custom variable inputs
        self.push_costs = push_costs
        self.macro = macro
        self.allow_taboo_push = allow_taboo_push

        # helpers
        self.taboo_cells = set(
            sokoban.find_2D_iterator(
                taboo_cells(warehouse).split(sep='\n'), "X"))
        self.walls = set(warehouse.walls)
        self.goal = set(warehouse.targets)

        # for macro actions can_go_there purposes
        self.warehouse = warehouse
Ejemplo n.º 4
0
 def __init__(self, warehouse, push_costs=None):
     self.warehouse = warehouse
     self.initial = (warehouse.worker, tuple(warehouse.boxes))
     self.goal = warehouse.targets
     self.walls = warehouse.walls
     self.push_costs = push_costs
     self.taboo = sokoban.find_2D_iterator(
         taboo_cells(self.warehouse).split('\n'), 'X')
Ejemplo n.º 5
0
 def __init__(self, warehouse):
     self.warehouse = warehouse
     self.initial = (warehouse.worker, tuple(warehouse.boxes))
     self.goal = warehouse.targets
     self.walls = warehouse.walls
     # by default does not allow push of boxes on taboo cells
     self.allow_taboo_push = False
     # use elementary actions if self.macro == False
     self.macro = False
     self.taboo = sokoban.find_2D_iterator(
         taboo_cells(self.warehouse).split('\n'), 'X')
    def actions(self, state):

        warehouse = sokoban.Warehouse()
        warehouse.extract_locations(state.splitlines())
        taboo = set(sokoban.find_2D_iterator(taboo_cells(str(warehouse)), "X"))
        for box in warehouse.boxes:
            for move in movement:
                worker_position = (box[0] - move[0], box[1] - move[1])
                box_after_pushed = (box[0] + move[0], box[1] + move[1])

                if (can_go_there(warehouse, worker_position)
                        and box_after_pushed not in taboo
                        and box_after_pushed not in warehouse.walls
                        and box_after_pushed not in warehouse.boxes):
                    yield (box, direction(move))
Ejemplo n.º 7
0
    def __init__(self, warehouse, initial=None, goal=None):
        
        self.warehouse = warehouse
        self.taboo = list(sokoban.find_2D_iterator(taboo_cells(warehouse).split(sep='\n'), "X"))
        self.walls = warehouse.walls
        self.targets = warehouse.targets
        

        if initial is not None:
            self.initial = initial
        else:
            self.initial = (self.warehouse.worker,tuple(self.warehouse.boxes))
            
        if goal is not None:
            self.goal = goal
        else: 
            self.goal = self.warehouse.targets
        assert set(self.goal) == set(warehouse.targets)
Ejemplo n.º 8
0
def taboo_reader(taboo_cells_str):
    # reference from from_lines
    lines = taboo_cells_str.split(sep='\n')
    first_row, first_col = None, None
    for row, line in enumerate(lines):
        brick_column = line.find('#')
        if brick_column >= 0:
            if first_row is None:
                first_row = row
            if first_col is None:
                first_col = brick_column
            else:
                first_col = min(first_col, brick_column)
    if first_col is None:
        raise ValueError('Warehouse with no walls!')
    canonical_lines = [
        line[first_col:] for line in lines[first_row:] if line.find('#') >= 0
    ]
    return list(sokoban.find_2D_iterator(canonical_lines, "X"))
Ejemplo n.º 9
0
    def actions(self, state):
        """
        Returns the list of actions that can be executed in the given state.
        """

        #Warehouse current state
        the_warehouse = sokoban.Warehouse()
        #Positional information of boxes, worker, targets and walls extracted
        the_warehouse.extract_locations(state[1].split(sep="\n"))
        #If allow_taboo_push is True, return all legal moves including the box on a taboo cell
        if self.allow_taboo_push:
            #Find bad cell spots
            is_cell_taboo = set(
                find_2D_iterator(taboo_cells(the_warehouse), "X"))
            #find directions for the box
            for box in the_warehouse.boxes:
                for offset in worker_offsets:
                    offset = offset_of_direction(offset)
                    b_position = add_coordinates(box, offset)
                    ppos1 = (box[0] + offset[0] * -1)
                    ppos0 = (box[1] + offset[1] * -1)
                    p_position = (ppos1, ppos0)
                    p_position = flip_coordinates(p_position)
                    if can_go_there(the_warehouse, p_position):
                        if b_position not in is_cell_taboo:
                            if b_position not in the_warehouse.boxes:
                                if b_position not in the_warehouse.walls:
                                    yield (box, direction_of_offset(offset))

        #if allow_taboo_push is False, taboo and shouldn't be included in list of moves.
        elif not self.allow_taboo_push:
            #find directions for the box
            for box in the_warehouse.boxes:
                for offset in worker_offsets:
                    b_position = add_coordinates(box, offset)
                    p_position = flip_coordinates((box[0] + offset[0] * -1),
                                                  (box[1] + offset[1] * -1))
                    if can_go_there(the_warehouse, p_position):
                        if b_position not in the_warehouse.boxes:
                            if b_position not in the_warehouse.walls:
                                yield (box, direction_of_offset(offset))
Ejemplo n.º 10
0
    def actions_macro(self, state):
        '''
        return action as a direction in the (x, y) coordinate for macro

        @param state: coordinate of the worker and boxes

        '''
        state_Of_Worker = state[0]
        state_Of_Boxes = list(state[1])
        Directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
        directions_In_Words = ['Left', 'Right', 'Up', 'Down']
        actions = []
        for boxState in state_Of_Boxes:
            taboo_cells_list = sokoban.find_2D_iterator(
                taboo_cells(self.warehouse).split('\n'), 'X')
            for dId, direction in enumerate(Directions):
                # moves boxes in the before state
                before_box_x = boxState[0] + direction[0]
                before_box_y = boxState[1] + direction[1]
                before_box_state = (before_box_x, before_box_y)
                # moves boxes in the after state
                after_box_x = boxState[0] - direction[0]
                after_box_y = boxState[1] - direction[1]
                after_box_state = (after_box_x, after_box_y)
                if after_box_state in self.warehouse.walls or before_box_state in self.warehouse.walls:
                    continue
                if after_box_state in state_Of_Boxes or before_box_state in state_Of_Boxes:
                    continue
                if not self.allow_taboo_push:
                    if after_box_state in taboo_cells_list:
                        continue
                temp_warehouse = self.warehouse.copy(state_Of_Worker,
                                                     state_Of_Boxes)
                if can_go_there(temp_warehouse,
                                (before_box_state[1], before_box_state[0])):
                    actions.append(
                        ((boxState[1], boxState[0]), directions_In_Words[dId]))
                    search
        return actions
Ejemplo n.º 11
0
def read_taboo_cells(taboo_cells_str):
    '''
    Parameters
    ----------
    taboo_cells_str : string
        A warehouse string version onyl with taboo and walls.

    Raises
    ------
    ValueError
        When wall is empty raise error.

    Returns
    -------
    list
        A list that represent taboo position exmaple :[[x,y]...[xn,yn]].

    '''
    lines = taboo_cells_str.split(sep='\n')
    first_row_brick, first_column_brick = None, None
    for row, line in enumerate(lines):
        brick_column = line.find('#')
        if brick_column >= 0:
            if first_row_brick is None:
                first_row_brick = row  # found first row with a brick
            if first_column_brick is None:
                first_column_brick = brick_column
            else:
                first_column_brick = min(first_column_brick, brick_column)
    if first_row_brick is None:
        raise ValueError('Warehouse with no walls!')
    # compute the canonical representation
    # keep only the lines that contain walls
    canonical_lines = [
        line[first_column_brick:] for line in lines[first_row_brick:]
        if line.find('#') >= 0
    ]
    return list(sokoban.find_2D_iterator(canonical_lines, "X"))
    def actions(self, state):
        # Extract the warehouse from the current state.
        current_warehouse = sokoban.Warehouse()
        current_warehouse.extract_locations(state[1].split(sep="\n"))
        global bad_cells

        if bad_cells is None:
            # If taboo cells haven't been computed, compute them.
            # This is done once for optimisation purposes.
            bad_cells = set(
                find_2D_iterator(
                    taboo_cells(current_warehouse).split("\n"), "X"))

        # Find every box, and every direction it can be pushed.
        for box in current_warehouse.boxes:
            for offset in offset_states:
                player_position = flip_tuple(
                    (box[0] + (offset[0] * -1), box[1] + (offset[1] * -1)))
                new_box_position = add_tuples(box, offset)
                if can_go_there(current_warehouse, player_position) \
                        and new_box_position not in bad_cells \
                        and new_box_position not in current_warehouse.walls \
                        and new_box_position not in current_warehouse.boxes:
                    yield (box, offset_to_direction(offset))
Ejemplo n.º 13
0
def extract_taboo(lines):
    taboo =  list(sokoban.find_2D_iterator(lines, "X"))  # taboo_cells
    return taboo
Ejemplo n.º 14
0
    def actions(self, state):
        """
        Return the list of actions that can be executed in the given state.
        
        As specified in the header comment of this class, the attributes
        'self.allow_taboo_push' and 'self.macro' should be tested to determine
        what type of list of actions is to be returned.
        """
        # These are in (y, x) format
        moveLeft = (-1, 0)
        moveRight = (1, 0)
        moveUp = (0, -1)
        moveDown = (0, 1)
        possibleMoves = [moveLeft, moveRight, moveUp, moveDown]

        nodeAsString = state.split('\n')
        warehouseObject = sokoban.Warehouse()
        warehouseObject.extract_locations(nodeAsString)
        justTabooCells = taboo_cells(warehouseObject)
        tabooCells = list(sokoban.find_2D_iterator(justTabooCells.split('\n'), 'X')) \
            if not self.allow_taboo_push else []

        currentWalls = warehouseObject.walls
        currentBoxes = warehouseObject.boxes
        currentWorker = warehouseObject.worker

        if self.macro:
            for box in currentBoxes:
                for move in possibleMoves:
                    testNewBoxPosition = box[0] + move[0], box[1] + move[1]
                    # Need to reverse the tuple to be in a (x,y) format
                    testNewPlayerPosition = box[1] + (move[1] * -1), box[0] + (
                        move[0] * -1)
                    canIGetThere = can_go_there(warehouseObject,
                                                testNewPlayerPosition)

                    if canIGetThere and testNewBoxPosition not in currentWalls \
                            and testNewBoxPosition not in currentBoxes \
                            and testNewBoxPosition not in tabooCells:
                        revBox = box[1], box[0]
                        if move == moveLeft:
                            yield (revBox, "Left")
                        elif move == moveRight:
                            yield (revBox, "Right")
                        elif move == moveUp:
                            yield (revBox, "Up")
                        elif move == moveDown:
                            yield (revBox, "Down")
        else:
            for move in possibleMoves:
                # Need to reverse the tuple to be in a (x,y) format
                testNewPlayerPosition = currentWorker[0] + move[
                    0], currentWorker[1] + move[1]
                if testNewPlayerPosition not in currentWalls:
                    if testNewPlayerPosition not in currentBoxes:
                        if move == moveLeft:
                            yield ("Left")
                        elif move == moveRight:
                            yield ("Right")
                        elif move == moveUp:
                            yield ("Up")
                        elif move == moveDown:
                            yield ("Down")
                    else:
                        # If there is a box in the way, make sure the box can legally be moved
                        newBoxPosition = testNewPlayerPosition[0] + move[
                            0], testNewPlayerPosition[1] + move[1]
                        if newBoxPosition not in currentWalls and \
                                newBoxPosition not in currentBoxes and \
                                newBoxPosition not in tabooCells:
                            if move == moveLeft:
                                yield ("Left")
                            elif move == moveRight:
                                yield ("Right")
                            elif move == moveUp:
                                yield ("Up")
                            elif move == moveDown:
                                yield ("Down")