Beispiel #1
0
 def __init__(self, level: Map, game_settings):
     self.max_steps = game_settings['timeout']
     self.boxes = level.boxes
     self.goals = level.filter_tiles([Tiles.GOAL, Tiles.BOX_ON_GOAL])
     self.keeper = level.keeper
     self.initial_state = {
         'boxes': self.boxes,
         'keeper': self.keeper,
         'goals': self.goals
     }
     self.path_finder: SokobanSolver = SokobanSolver(level_map=level,
                                                     method='mixed')
Beispiel #2
0
async def solver(puzzle, solution):
    while True:
        start = time.time()
        game_properties = await puzzle.get()
        mapa = Map(game_properties["map"])
        print(mapa)
        domain = Sokosolver(mapa)
        domain.pair()  #calculates the pairs atribution for the heuristic
        initstate = State(
            mapa.filter_tiles([Tiles.BOX]) +
            mapa.filter_tiles([Tiles.BOX_ON_GOAL]), mapa.keeper)
        problem = SearchProblem(
            domain, initstate,
            mapa.filter_tiles([Tiles.GOAL]) +
            mapa.filter_tiles([Tiles.BOX_ON_GOAL]) +
            mapa.filter_tiles([Tiles.MAN_ON_GOAL]))
        st = SearchTree(problem, "greedy")
        lista = await (st.search())
        keys = translate(lista)
        end = time.time()
        print(f"Time spent: {end-start}")
        print(keys)
        await solution.put(keys)
async def solver(puzzle, solution):

    while True:
        game_properties = await puzzle.get()
        print("GAME PROPERTIES: " + str(game_properties))

        #print(game_properties["map"])
        print("levels/" + str(ant_level) + ".xsb")
        mapa = Map("levels/" + str(ant_level) + ".xsb")
        boxes, keeper, goal = get_grid("levels/" + str(ant_level) + ".xsb")
        print(goal)
        # Criar o dominio
        domain = SokobanDomain(mapa, boxes, keeper, goal)
        sokoban = domain.sokoban

        # Localização do Sokoban
        print("Sokoban Pos: " + str(sokoban))

        # Localização das caixas
        boxes = tuple(tuple(i) for i in domain.boxes)
        print("Boxes: " + str(boxes))

        # Caixas nos diamantes (apenas retorna o número de caixas no objetivo, não a localização)
        boxesOnGoal = domain.mapa.on_goal
        print("Boxes on goal: " + str(boxesOnGoal))

        # Posições dos objetivos livres (objetivos onde falta colocar a caixa)
        emptyGoals = domain.mapa.empty_goals
        print("Empty goals: " + str(emptyGoals))

        # Caixas que não estão nos objetivos
        boxTiles = list(domain.mapa.filter_tiles(Tiles.BOX))
        floor = list(domain.mapa.filter_tiles(Tiles.FLOOR))

        boxesNotInGoal = []
        count = 0
        t = ()

        for i in boxTiles:
            for j in floor:
                if (i[0] == j[0]) and (i[1] == j[1]):
                    count += 1
            if (count == 0):
                boxesNotInGoal += [i]
            count = 0

        print("Boxes Not In Goal: " + str(boxesNotInGoal))

        keys = []

        # Retorna todas as posições de deadlock do mapa
        # A caixa não pode ir para uma destas posições
        # TODO:
        # Falta calcular todas as posições entre duas posições de deadlock que estejam junto a uma parede sem um objetivo
        # Para o 1º nível basta os cantos
        def getDeadlockPositions(realWalls, floors):
            corners = []
            for wall_1 in realWalls:
                for wall_2 in realWalls:
                    x = abs(wall_1[0] - wall_2[0])
                    y = abs(wall_1[1] - wall_2[1])
                    if (x == 1 and y == 1):
                        corners += [(wall_1, wall_2)]

            for a, b in corners:
                for c, d in corners:
                    if a == d and b == c:
                        corners.remove((c, d))

            cornersFloor = []
            print("corner")
            print(corners)
            for corner in corners:
                count = 0
                for goal in emptyGoals:
                    if corner[0][0] == goal[0] and corner[1][1] == goal[1]:
                        count += 1
                    if count == 0:
                        if (corner[0][0], corner[1][1]) in floors:
                            cornersFloor += [(corner[0][0], corner[1][1])]
                        else:
                            cornersFloor += [(corner[1][0], corner[0][1])]

            deadlock = cornersFloor
            deadlock = [d for d in deadlock if d not in emptyGoals]
            return deadlock

        walls = list(domain.mapa.filter_tiles(Tiles.WALL))
        floors = list(domain.mapa.filter_tiles(Tiles.FLOOR))

        # A variável 'realWalls' tem as coordenadas de todas as paredes do jogo
        realWalls = []
        for wall in walls:
            count = 0
            for floor in floors:
                if (wall[0] == floor[0] and wall[1] == floor[1]):
                    count += 1
            if (count == 0):
                realWalls += [wall]

        # DeadlockPos apenas tem os cantos do mapa
        deadlockPos = getDeadlockPositions(realWalls, floors)
        print("REAL WALLS: " + str(realWalls))

        print("ALL DEADLOCK POSITIONS: " + str(deadlockPos))
        domain.setDeadlockPositions(deadlockPos)

        goal = mapa.filter_tiles(
            [Tiles.GOAL, Tiles.MAN_ON_GOAL, Tiles.BOX_ON_GOAL])
        print("GOAL: " + str(goal))

        problem = SearchProblem(domain, tuple(tuple(i) for i in domain.state),
                                goal)
        print("DOMAIN STATE: " + str(domain.state))

        gen_task = loop.create_task(SokobanTree(problem).search())
        await gen_task
        array = gen_task.result()

        keys = "" + "".join(array)

        print("KEYS: " + str(keys))

        await asyncio.sleep(0)
        await solution.put(keys)
Beispiel #4
0
async def solver(puzzle, solution):
    while True:
        game_properties = await puzzle.get()
        mapa = Map(game_properties["map"])

        inittime = time.time()

        dominio = BoxDomain()

        initial = [set(mapa.boxes), mapa.keeper]
        walls = set(mapa.filter_tiles([Tiles.WALL]))
        diamonds = set(
            mapa.filter_tiles(
                [Tiles.GOAL, Tiles.BOX_ON_GOAL, Tiles.MAN_ON_GOAL]))
        all_coords = set(
            mapa.filter_tiles([
                Tiles.BOX, Tiles.BOX_ON_GOAL, Tiles.FLOOR, Tiles.GOAL,
                Tiles.MAN_ON_GOAL, Tiles.MAN
            ]))
        goal = diamonds

        dominio2 = KeeperDomain(all_coords)
        p = SearchProblem(dominio2, mapa.keeper, (-1, -1))
        t = SearchTree(p, 'Greedy')
        await t.search()
        all_coords = set(t.all_nodes)

        blocked_pos = set({})
        for coord in all_coords:
            if check_blocks(coord, diamonds, walls):
                blocked_pos.add(coord)

        tiles_divisoras_mapa = set({})
        contador = 0
        possivel_tile = None
        for i in range(0, mapa.size[0]):
            for coord in all_coords:
                if coord[0] == i:
                    contador += 1
                    possivel_tile = coord
                if contador > 1:
                    possivel_tile = None
                    break
            if possivel_tile != None:
                tiles_divisoras_mapa.add(possivel_tile)
            contador = 0
        contador = 0
        possivel_tile = None
        for i in range(0, mapa.size[1]):
            for coord in all_coords:
                if coord[1] == i:
                    contador += 1
                    possivel_tile = coord
                if contador > 1:
                    possivel_tile = None
                    break
            if possivel_tile != None:
                tiles_divisoras_mapa.add(possivel_tile)
            contador = 0

        p = SearchProblemBox(dominio, initial, goal, all_coords, diamonds,
                             walls, blocked_pos, tiles_divisoras_mapa)
        total = 0
        for box in initial[0]:
            if box not in goal:
                for goal in diamonds:
                    if goal not in initial[0]:
                        custo = abs(box[0] - goal[0]) + abs(box[1] - goal[1])
                        total = total + custo

        if total * len(initial[0]) < 500:
            t = SearchTreeBox(p, strategy="A*")
            await t.search()
        else:
            t = SearchTreeBox(p, strategy="Greedy")
            await t.search()

        no = t.solution
        dicionario_nos = {}
        contador = 0
        while no != None:
            dicionario_nos[str(contador)] = no
            no = no.parent
            contador = contador + 1

        keys = ""
        pos_keeper = mapa.keeper
        contador2 = contador - 1
        for action in t.plan:
            caixaX = action[0][0]
            caixaY = action[0][1]

            if (action[2][0] == 'w'):
                keeper_empurrar_pos = (caixaX, caixaY + 1)
            elif (action[2][0] == 's'):
                keeper_empurrar_pos = (caixaX, caixaY - 1)
            elif (action[2][0] == 'a'):
                keeper_empurrar_pos = (caixaX + 1, caixaY)
            elif (action[2][0] == 'd'):
                keeper_empurrar_pos = (caixaX - 1, caixaY)

            coords = set({
                d
                for d in all_coords
                if d not in dicionario_nos[str(contador2)].state[0]
            })
            dominio = KeeperDomain(coords)
            p = SearchProblem(dominio, pos_keeper, keeper_empurrar_pos)
            t = SearchTree(p, 'A*')
            await t.search()

            for move in t.plan:
                firstCoordX = move[0][0]
                firstCoordY = move[0][1]
                secondCoordX = move[1][0]
                secondCoordY = move[1][1]
                if (firstCoordX == secondCoordX + 1
                        and firstCoordY == secondCoordY):
                    keys = keys + "a"
                elif (firstCoordX == secondCoordX - 1
                      and firstCoordY == secondCoordY):
                    keys = keys + "d"
                elif (firstCoordX == secondCoordX
                      and firstCoordY == secondCoordY + 1):
                    keys = keys + "w"
                elif (firstCoordX == secondCoordX
                      and firstCoordY == secondCoordY - 1):
                    keys = keys + "s"

            keys = keys + action[2]
            if (action[2][0] == 'w'):
                pos_keeper = (action[1][0], action[1][1] + 1)
            elif (action[2][0] == 's'):
                pos_keeper = (action[1][0], action[1][1] - 1)
            elif (action[2][0] == 'a'):
                pos_keeper = (action[1][0] + 1, action[1][1])
            elif (action[2][0] == 'd'):
                pos_keeper = (action[1][0] - 1, action[1][1])
            contador2 = contador2 - 1

        await solution.put(keys)