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')
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)
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)