Пример #1
0
 def get_target_positions(self):
     """Gibt ein dict zurück, dass alle bis auf das letzte Element der zu lösenden 
     Reihe auf ihre gewünschte Position abbildet"""
     l = list(self.s[0])
     d = dict()
     for i in l[:-2]:
         d.update({i: puz.get_position(self.s, i)})
     # besondere Position für den Vorletzten
     d.update({l[-2]: tuple(np.array(puz.get_position(self.s, l[-2])) + (0, 1))})
     return d
Пример #2
0
def manhattan_dist_sum(p, tiles = None):
    if not tiles:
        tiles = p.flat
    solved = puzzle.solved(p)
    s = 0
    for t in tiles:
        s_pos = puzzle.get_position(p, t)
        t_pos = puzzle.get_position(solved, t)
        s += u.manhattan_distance(*s_pos, *t_pos)
    return s
Пример #3
0
    def solve_last(self):
#        log.info("solving last:\n{}",format(self.p))
        """Löst die letzten beiden Elemente, womit dann die ganze Reihe gelöst ist"""
        r, d, l, u = (0, 1), (1, 0), (0, -1), (-1, 0)
        final_lst_pos = puz.get_position(self.s, self.s[0][-1])
        lst_pos = self.lst_pos()
        # 1. Fall: 4 ist über der 3 und beide werden zusammen 'reinrotiert' -> fertig
        if all(lst_pos == np.array(final_lst_pos) + d):
            pa = PosAction((0, len(self.s[0]) - 2), [r, d])
            locked = self.locked.union({self.lst_pos()})
            self.exec_pa(pa, locked)
        # 2. Fall: 3 und 4 sind vertauscht -> Überführung in 3. Fall
        elif all(lst_pos == np.array(final_lst_pos) + l):
            pa = PosAction((1, len(self.s[0]) - 2), [u])
            self.exec_pa(pa, self.locked)
            self.solve_last()
        # 3. Fall: Überführung in 1. Fall
        elif (all(lst_pos == np.array(final_lst_pos) + (1, -1)) and
              all(puz.empty_position(self.p) == np.array(final_lst_pos) + l)):
            pa = PosAction(puz.empty_position(self.p), [r, d, d, l, u, u, r, d, l,
                                                        u, r, d, d, l, u, r, d])
            self.exec_pa(pa, set())
            self.solve_last()
        # 4. Fall (default): Die 4 ist irgendwo anders -> Überführung in 1.
        else:
            self.p, acts = move_one_tile(self.p, self.s[0][-1],
                                         tuple(np.array(final_lst_pos) + d), self.locked)
            self._moves += acts
            self.solve_last()
Пример #4
0
 def solve_but_last(self):
     """Löst die ersten n-2 der obersten Reihe und bringt den n-1ten in eine
     geeignete Position um ihn zusammen mit dem n-ten zu lösen (z.B.: '12.3')"""
     d = self.get_target_positions()
     for i in sorted(d):
         log.info("solving element {}".format(i))
         self.p, acts = move_one_tile(self.p, i, d[i], self.locked)
         self._moves += acts
         self.locked.add(puz.get_position(self.p, i))
Пример #5
0
def move_one_tile(p, tile, target_position, locked):
    """tile wird an position bewegt unter Berücksichtigung der locked Tiles
    tile: ein int
    locked: set von Positionen (Tupeln)"""
    start_position = puz.get_position(p, tile)
    path = a_star(p.shape[0], start_position, target_position, locked)
#    print(path)
    pos_actions = coords_to_pos_actions(path)
#    print(pos_actions)
    actions = []
    for a in pos_actions:
#        print("Meta-Action", a.start_position, a.actions)
#        print(p)
        p, acts = a.execute(p, locked)
        actions += acts
    return p, actions
Пример #6
0
 def stl_pos(self):
     """Gibt die aktuelle Position des vorletzten zu lösenden Elements zurück"""
     stl = self.s[0][-2]
     return puz.get_position(self.p, stl)
Пример #7
0
 def lst_pos(self):
     """Gibt die aktuelle Position des letzten zu lösenden Elements zurück"""
     last = self.s[0][-1]
     return puz.get_position(self.p, last)