Найти - Пользователи
Полная версия: Лабиринт
Начало » Python для новичков » Лабиринт
1
Ozzi38
Здравствуйте, есть готовый код с лабиринтом. В готовом коде можно повернуть во все стороны. Как изменить эту программу чтобы можно было поворачивать только на право и идти только прямо. Назад и в лево нельзя.
Рабочий код прикрепил к этому сообщению.

 class Node():
    """A node class for A* Pathfinding"""
    def __init__(self, parent=None, position=None):
        self.parent = parent
        self.position = position
        
        self.g = 0
        self.h = 0
        self.f = 0
    def __eq__(self, other):
        return self.position == other.position
def astar(maze, start, end):
    """Returns a list of tuples as a path from the given start to the given end in the given maze"""
    # Create start and end node
    start_node = Node(None, start)
    start_node.g = start_node.h = start_node.f = 0
    end_node = Node(None, end)
    end_node.g = end_node.h = end_node.f = 0
    # Initialize both open and closed list
    open_list = []
    closed_list = []
    # Add the start node
    open_list.append(start_node)
    # Loop until you find the end
    while len(open_list) > 0:
        # Get the current node
        current_node = open_list[0]
        current_index = 0
        for index, item in enumerate(open_list):
            if item.f < current_node.f:
                current_node = item
                current_index = index
        # Pop current off open list, add to closed list
        open_list.pop(current_index)
        closed_list.append(current_node)
        # Found the goal
        if current_node == end_node:
            path = []
            current = current_node
            while current is not None:
                path.append(current.position)
                current = current.parent
            return path[::-1] # Return reversed path
        # Generate children
        children = []
        
        #for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares
        for new_position in [(0, -1), (-1, 0), (1, 0), (0, 1)]: # Adjacent squares
            # Get node position
            node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
            # print(new_position[0]+1, new_position[1]+1)
                   
            # Make sure within range
            if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0:
                continue
            # Make sure walkable terrain
            if maze[node_position[0]][node_position[1]] != 0:
                continue
            # Create new node
            new_node = Node(current_node, node_position)
            # Append
            children.append(new_node)
        # Loop through children
        for child in children:
            
            # Child is on the visited list (search entire visited list)
            if len([closed_child for closed_child in closed_list if closed_child == child]) > 0:
                continue
            # Create the f, g, and h values
            child.g = current_node.g + 1
            ## Heuristic costs calculated here, this is using eucledian distance
            child.h = (((child.position[0] - end_node.position[0]) ** 2) + 
                       ((child.position[1] - end_node.position[1]) ** 2)) 
            child.f = child.g + child.h
            # Child is already in the yet_to_visit list and f cost is already lower
            if len([open_node for open_node in open_list if child == open_node and child.f > open_node.f]) > 0:
                continue
            # Add the child to the yet_to_visit list
            open_list.append(child)
def main():
    maze = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 1, 0, 1, 0 ,1, 1, 1, 0, 1, 1, 1, 0],
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 1, 0, 1, 0 ,1, 1, 1, 1, 1, 0, 1, 0],
            [0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0],
            [0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
            [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0],
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
            [1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0],
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]]
    start = (11, 10)
    end = (11, 2)
    #maze = [[0, 0, 0],
    #        [0, 1, 0],
    #        [0, 0, 0]]
    # start = (0, 0)
FishHook
Ozzi38
Как изменить эту программу чтобы можно было поворачивать только на право и идти только прямо.
а с чего вы взяли, что эту программу можно подобным образом изменить?
Ozzi38
FishHook
Ну если есть задание такое, значит возможно.

Здесь разрешенные квадраты отмечены 0, а стена - 1.
Первоначальная версия алгоритма решает лабиринт с правилами, согласно которым всегда можно двигаться вверх, влево, вправо, вниз. Но ваша задача - изменить начальную версию алгоритма так, чтобы можно было двигаться только прямо вперед и вправо. Прямое движение означает продолжать движение в том направлении, в котором мы уже только что шли, и направление на право также интерпретируется на основе того направления, в котором мы уже только что двигались.
Вы входите в лабиринт в квадрате (11,10), и вам нужно добраться до квадрата (11,2), применяя разрешенные ходы.

Here the allowed squares are marked with 0 and the wall with 1.
The initial version of the algorithm is solving the maze with the rules that it is possible always to move up, left, right, down but also to up-left, up-right, down-left, down-right. But your job is to modify the initial version of the algorithm such that only moves straight forward and right are allowed. The straight forward means to continue to the direction that we were already just going and direction right is also interpreted based on the direction that we were already just going.
You enter the maze in square (11,10) and you need to get to the square (11,2) by applying allowed moves.
PEHDOM
Ozzi38 вам нужно иметь представление что такое “вперед”. Как вариант вы должны хранить “предыдущий квадрат” и в зависимости от его значения у вас будут доступны только два определенных значения “Adjacent squares”
Ozzi38
PEHDOM
Adjacent squares
А можно пожалуйста немного подробнее?
py.user.next
Ozzi38
Здравствуйте, есть готовый код с лабиринтом.
Код такой сложный не потому, что сложный алгоритм, а потому, что писал его какой-то говнокодер. Советую тебе не учиться по таким кодам, так как из-за них у тебя будет складываться впечатление, что программирование непостижимо. При этом всё дело будет только в том, что ты программирование будешь пытаться понять просто через чью-то тупость.

Ozzi38
  
        # Loop through children
        for child in children:
Вот пример говнокодинга: смотри, как он классно поясняет комментарием то, что масло масляное, оказывается.

Выкинь его, возьми сам алгоритм и пиши его заново. Там есть псевдокод уже готовый, для которого можно простой код на питоне сделать.
PEHDOM
Ozzi38
А можно пожалуйста немного подробнее?
в смысле? этож в твоем коде написано:
 for new_position in [(0, -1), (-1, 0), (1, 0), (0, 1)]: # Adjacent squares
Вот этот список и есть “возможные квдраты” в котороые можно переместиться. Если быть точным это значения котороые нужно прибавить к текущим кординатам чтобы переместиться на 1 клетку.
нужно просто понимать в какую сторону смотрит “подопытный” и в зависимости то этого будут разные Adjacent squares. Например Если смотрит на восток то “вперед” будет (0,1 ), “направо” -(1, 0), “назад” - (0,-1) “налево” - (-1,0) (цифры взяты наугад, главное сам принцип). Соотвевенно чтобы нельзя было идти назад иналево, в Adjacent squares должны остаться только вперед и направо. Если подопытный смотрит на запад то все должно быть наоборот. ну и тд. Вариантов не так уж и много, можно все это в словарь запихнуть и в for new_position in …. каждый раз подсовывать те значения которые соответвуют текущему направлению.
Вопрос как определять куда смотрит одельный, Можно просто завести отдельный атрибут - направление, а можно хранить предыдущие координаты и по ним вычислять где “перед”, а где “зад”.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB