A *寻路不适用于困难的障碍

时间:2016-09-12 05:57:43

标签: python algorithm graph-algorithm a-star

我最近开始制作A *探路者,所以我可以在游戏中拥有良好的AI。我取得了很大的进步,在我看来,探路者准备好了,但是当我尝试它时,发生了奇怪的事情。我这样做的方式是,当程序创建了要去的路径时,终点开始向开始点移动。它的工作方式是在没有"困难的情况下绘制路径的时候。障碍物,但是当有障碍物迫使它以完全不同的方式出现问题时出现的问题......终点并没有完全直接地到达起点而是跳来跳去......

下图显示了问题发生的时间以及何时没有。

import pygame

pygame.init()


class Node():
    def __init__(self, x, y, parent, color, move, end):
        if end != None:
            self.H = abs(end[0]/25 - x/25) + abs(end[1]/25 - y/25)
        else:
            self.H = 0
        self.G = 1
        self.F = self.G + self.H
        self.x = x
        self.y = y
        self.child = []
        self.color = color
        self.move = move

        self.parent = parent

    def AddChild(self, end, current_node, nodes):
        for node in nodes[0]:
            if pygame.Rect(nodes[Closed][current_node].x + tile, nodes[Closed][current_node].y, tile, tile).colliderect(pygame.Rect(node.x, node.y, tile, tile)):
                node.color = (0, 255-self.F, 255)
                node.parent = nodes[Closed][current_node]
                nodes[Closed][current_node].child = node
                nodes[1].append(node)
            elif pygame.Rect(nodes[Closed][current_node].x - tile, nodes[Closed][current_node].y, tile, tile).colliderect(pygame.Rect(node.x, node.y, tile, tile)):
                node.color = (0, 255-self.F, 255)
                node.parent = nodes[Closed][current_node]
                nodes[Closed][current_node].child = node
                nodes[1].append(node)

            elif pygame.Rect(nodes[Closed][current_node].x, nodes[Closed][current_node].y - tile, tile, tile).colliderect(pygame.Rect(node.x, node.y, tile, tile)):
                node.color = (0, 255-self.F, 255)
                node.parent = nodes[Closed][current_node]
                nodes[Closed][current_node].child = node
                nodes[1].append(node)
            elif pygame.Rect(nodes[Closed][current_node].x, nodes[Closed][current_node].y + tile, tile, tile).colliderect(pygame.Rect(node.x, node.y, tile, tile)):
                node.color = (0, 255-self.F, 255)
                node.parent = nodes[Closed][current_node]
                nodes[Closed][current_node].child = node
                nodes[1].append(node)

        for i in range(0, len(nodes[1])-1):
            if nodes[1][0] in nodes[0]:
                nodes[0].remove(nodes[0][nodes[1][0]])



    def Draw(self, font):
        pygame.draw.rect(screen, (0, 0, 0), (self.x, self.y, tile, tile))
        pygame.draw.rect(screen, self.color, (self.x+1, self.y+1, tile-2, tile-2))



        label = font.render((str(self.H)), True, (0, 0, 0))
        screen.blit(label, (self.x+3, self.y+5))
        label = font.render((str(self.F)), True, (0, 0, 0))
        screen.blit(label, (self.x+3, self.y+int(tile/2)))

    def Source(self):
        return self.parent, self



Open = 0
Closed = 1

nodes = [[], []]
current_node = 0
used_nodes = []

path = []

W = 1000
H = 950

tile = 25

screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("A*")

clock = pygame.time.Clock()

End = Node(500, 650, None, (255, 0, 0), False, None)
Start = Node(300, 300, None, (0, 255, 0), False, [End.x, End.y])


for i in range(0, int(H/tile)):
    for j in range(0, int(W/tile)):
        nodes[Open].append(Node(j*tile, i*tile, None, (255, 255, 255), False, [End.x, End.y]))

for node in nodes[Open]:
    if pygame.Rect(Start.x, Start.y, tile, tile).colliderect(pygame.Rect(node.x, node.y, tile, tile)):
        print(nodes[Open][nodes[Open].index(node)+1].x, nodes[Open][nodes[Open].index(node)+1].y)
        nodes[Closed].insert(nodes[Open].index(node), node)
        node.color = (0, 255, 255)
        nodes[Open].remove(node)


font = pygame.font.Font(None, int(tile/2))

A = W*tile
B = None
Break = False

Draw = False

while len(path) == 0:
    clock.tick(120)
    pygame.display.flip()
    screen.fill((0, 0, 0))
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()

        elif e.type == pygame.KEYDOWN:

            if e.key == pygame.K_SPACE and Draw == False:
                Draw = True
            elif e.key == pygame.K_SPACE and Draw == True:
                Draw = False





            elif e.key == pygame.K_c:
                for i in nodes[Closed]:
                    if i.child == []:
                        pygame.draw.rect(screen, (255, 255, 255), (i.x, i.y, tile, tile))
                        clock.tick(10)
                        pygame.display.flip()
                    else:
                        pygame.draw.rect(screen, (255, 0, 0), (i.x, i.y, tile, tile))


        elif e.type == pygame.MOUSEBUTTONDOWN:
            for i in nodes:
                for node in i:
                    x, y = pygame.mouse.get_pos()
                    if pygame.Rect(x, y, 1, 1).colliderect(pygame.Rect(node.x, node.y, tile, tile)):
                        B = [node, nodes.index(i)]
                        Break = True
                    elif Break == False:
                        B = [x, y]


            if B != None:
                if Break == False:
                    nodes[Open].append(Node(int(x/tile)*tile, int(y/tile)*tile, None, (255, 255, 255), False, [End.x, End.y]))
                else:
                    nodes[B[1]].remove(B[0])

    if Draw == True:
        A = W*H*tile
        used_nodes.append(current_node)
        nodes[Open][0].AddChild(End, current_node, nodes)
        for node in nodes[Closed]:
            if node.F < A and nodes[Closed].index(node) != 0 and nodes[Closed].index(node) not in used_nodes:
                A = node.F
                current_node = nodes[Closed].index(node)
            elif current_node in used_nodes:
                current_node += 1





    for node in nodes[Closed]:
        if pygame.Rect(End.x, End.y, tile, tile).colliderect(node.x, node.y, tile, tile):
            parent, self = nodes[Closed][len(nodes[Closed])-1].Source()
            path.append(parent)
            nodes[Open].append(self)
            nodes[Closed].remove(self)
            break
    try:
        while [path[len(path)-1].x, path[len(path)-1].y] != [Start.x, Start.y]:
            parent, self = nodes[Closed][len(nodes[Closed])-1].Source()
            if parent not in path:
                path.append(parent)
            nodes[Open].append(self)
            nodes[Closed].remove(self)
    except: IndexError


    if Break == True:
        Break = False



    for i in nodes[Open]:
        i.Draw(font)

    for i in nodes[Closed]:
        i.Draw(font)

    Start.Draw(font)
    End.Draw(font)

while True:
    clock.tick(10)
    pygame.display.flip()
    screen.fill((0, 0, 0))
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()


    if len(path) > 0:
        End.x = path[0].x
        End.y = path[0].y
        path.remove(path[0])





    for i in nodes[Open]:
        i.Draw(font)

    for i in nodes[Closed]:
        i.Draw(font)

    Start.Draw(font)
    End.Draw(font)

关于问题的图片:

img

0 个答案:

没有答案