コード例 #1
0
ファイル: soko_state.py プロジェクト: mirefek/SokoDLex
    def __init__(self,
                 available,
                 sub_boxes,
                 sup_boxes,
                 storages,
                 storekeeper,
                 storekeepers=None,
                 sub_full=None,
                 storekeeper_goal=None,
                 multi_component=None):
        h, w = available.shape
        self.height = h - 2
        self.width = w - 2
        self.available = available
        self.sub_boxes = sub_boxes
        self.sup_boxes = sup_boxes
        self.storages = storages

        self.storekeeper = storekeeper
        self.storekeeper_goal = storekeeper_goal
        if storekeepers is None:
            multi_component = False
            self.storekeepers = get_component(available & ~sub_boxes,
                                              [storekeeper])
        else:
            self.storekeepers = storekeepers
        if multi_component is not None:
            self.multi_component = multi_component
        else:
            sub_comp = get_component(self.storekeepers,
                                     positions_true(self.storekeepers)[:1])
            self.multi_component = (sub_comp != self.storekeepers).any()

        if sub_full is not None: self.sub_full = sub_full
        else: self.sub_full = (np.sum(sub_boxes) == np.sum(storages))
コード例 #2
0
ファイル: soko_state.py プロジェクト: mirefek/SokoDLex
def level_to_dual_state(level):
    size_bord = level.height + 2, level.width + 2
    available = np.zeros(size_bord, dtype=bool)
    available[1:-1, 1:-1] = ~level.walls
    storages = np.zeros(size_bord, dtype=bool)
    storages[1:-1, 1:-1] = level.boxes
    boxes = np.zeros(size_bord, dtype=bool)
    boxes[1:-1, 1:-1] = level.storages
    storekeepers_ini = np.zeros_like(available)
    for d in directions:
        storekeepers_ini |= dir_shift_array(d, boxes)
    storekeepers = get_component(available & ~boxes,
                                 positions_true(storekeepers_ini))
    max_component = max((comp for pos, comp in component_split(storekeepers)),
                        key=np.sum)
    storekeeper = positions_true(storekeepers_ini & max_component)[0]

    return SokoState(available,
                     boxes,
                     available,
                     storages,
                     storekeeper=storekeeper,
                     storekeepers=storekeepers,
                     sub_full=True,
                     storekeeper_goal=level.storekeeper)
コード例 #3
0
    def deadlock_blocks_gen(deadlock_data):
        max_index = 0
        dl_list = []
        cur_block = []
        for index, storekeeper, boxes, blocked, action_data in deadlock_data:
            assert index == len(dl_list), (index, last_index)

            available = np.array(base_state.available)
            for box in boxes:
                available[box] = False
            sk_component = get_component(available, storekeeper)
            deadlock = Deadlock(boxes, blocked, sk_component)
            deadlock.full_index = index

            dl_list.append(deadlock)
            cur_block.append((deadlock, action_data))
            max_cur = max((desc for _, desc in action_data), default=max_index)
            max_index = max(max_cur, max_index)
            if max_index == index:
                max_index += 1
                for deadlock, action_data in cur_block:
                    deadlock.descendants = {
                        action: dl_list[i]
                        for action, i in action_data
                    }
                    #deadlock.check_dependencies(base_state)
                yield [dl for dl, _ in cur_block]
                cur_block = []
        assert not cur_block
コード例 #4
0
ファイル: soko_state.py プロジェクト: mirefek/SokoDLex
 def generalize(self, sub_boxes, sup_boxes, storekeepers=None):
     assert (sub_boxes <= self.sub_boxes).all()
     if not self.sub_full: assert (self.sup_boxes <= sup_boxes).all()
     if storekeepers is None:
         if (self.sub_boxes == sub_boxes).all():
             storekeepers = self.storekeepers
         else:
             storekeepers = get_component(self.available & ~sub_boxes,
                                          positions_true(self.storekeepers))
     return SokoState(
         self.available,
         sub_boxes,
         sup_boxes,
         self.storages,
         storekeepers=storekeepers,
         storekeeper=self.storekeeper,
         storekeeper_goal=self.storekeeper_goal,
         multi_component=self.multi_component,
     )
コード例 #5
0
    def _find_next_lock(self, next_state):
        ori_lock = self.cur_lock
        if ori_lock.check_state(next_state): return ori_lock

        ori_state = None
        if not self.state.multi_component:
            if next_state.storekeepers[self.state.storekeeper]:
                ori_state = self.state
            elif self.state.storekeepers[next_state.storekeeper]:
                ori_state = self.state
        if ori_state is None:
            sk_intersect = get_component(
                next_state.available & ~next_state.sub_boxes
                & ~self.state.sub_boxes,
                positions_true(next_state.storekeepers),
            )
            if (self.state.storekeepers <= sk_intersect).all():
                ori_state = self.state

        return self.deadlocks.dl_set.find_by_state(next_state,
                                                   ori_state=ori_state)