Nieskonczony A*

This commit is contained in:
Miron 2021-05-09 11:27:22 +02:00
parent d3cc39c5bc
commit 7288e4901c
2 changed files with 130 additions and 16 deletions

BIN
src/img/stain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -4,7 +4,6 @@ import time
pygame.init() pygame.init()
WIDTH = 675 WIDTH = 675
HEIGHT = 675 HEIGHT = 675
size = 75 size = 75
@ -14,7 +13,6 @@ RECT_SIZE = 9
IMAGE = pygame.image.load('img/wozek2.png') IMAGE = pygame.image.load('img/wozek2.png')
BACKGROUND = pygame.transform.scale(pygame.image.load('img/background.png'), (WIDTH, HEIGHT)) BACKGROUND = pygame.transform.scale(pygame.image.load('img/background.png'), (WIDTH, HEIGHT))
DOCK = pygame.transform.scale(pygame.image.load('img/dock_left.png'), (75, 75)) DOCK = pygame.transform.scale(pygame.image.load('img/dock_left.png'), (75, 75))
get_pix_from_position = {} get_pix_from_position = {}
@ -25,7 +23,20 @@ def get_position_from_pix(pix_pos):
print("ERROR: THERE IS NO POSITION LIKE THIS (get_position_from_pix)") print("ERROR: THERE IS NO POSITION LIKE THIS (get_position_from_pix)")
def create_postiions(): WAREHOUSE_MAP = [
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[20, 20, 20, 20, 20, 20, 20, 20, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 199, 199, 199, 199, 199, 199, 199, 199],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
]
def create_positions():
size_agent = 40 size_agent = 40
x_position_pix = size_agent x_position_pix = size_agent
y_position_pix = size_agent y_position_pix = size_agent
@ -45,6 +56,7 @@ def generate_package(a, b):
p1 = Package((a, b), rand_x, name_list[rand_y - 1], image_list[rand_y - 1]) p1 = Package((a, b), rand_x, name_list[rand_y - 1], image_list[rand_y - 1])
return p1 return p1
# FRINGE - struktura danych przechowująca wierzchołki do odwiedzenia # FRINGE - struktura danych przechowująca wierzchołki do odwiedzenia
# EXPLORED - lista odwiedzonych stanów # EXPLORED - lista odwiedzonych stanów
# istate - stan początkowy # istate - stan początkowy
@ -96,6 +108,92 @@ def breadth_first_search(istate, agent_direction): # COORDINATES OF A START PLA
fringe.append(x) fringe.append(x)
def a_star_search(start, end):
open_nodes = []
closed_nodes = []
start_node = NodeAStar(None, start)
start_node.g = start_node.h = start_node.f = 0
end_node = NodeAStar(None, end)
end_node.g = end_node.h = end_node.f = 0
open_nodes.append(start_node)
while len(open_nodes) != 0:
current_node = open_nodes[0]
current_node_index = 0
for index, node in enumerate(open_nodes):
if node.f < current_node.f:
current_node = node
current_node_index = index
open_nodes.pop(current_node_index)
closed_nodes.append(current_node)
# Sprawdzam czy jesteśmy u celu jeżeli tak zwracamy ścieżkę
neighbour_nodes = []
if current_node == end_node:
path = []
current = current_node
while current is not None:
path.append(current.position)
current = current.parent
return path[::-1]
x = current_node.position[0]
y = current_node.position[1]
if x < 8: # RIGHT NEIGHBOUR
neighbour_nodes.append(
NodeAStar(current_node,
(x + 1, y)
))
if x > 0: # LEFT NEIGHBOUR
neighbour_nodes.append(
NodeAStar(current_node,
(x - 1, y)
))
if y > 0: # UP NEIGHBOUR
neighbour_nodes.append(
NodeAStar(current_node,
(x, y - 1)
))
if y < 8: # DOWN NEIGHBOUR
neighbour_nodes.append(
NodeAStar(current_node,
(x, y + 1)
))
for neighbour in neighbour_nodes:
if len([closed_neighbour for closed_neighbour in closed_nodes if closed_neighbour == neighbour]) > 0:
continue
neighbour.g = current_node.g + WAREHOUSE_MAP[neighbour.position[0]][neighbour.position[1]]
neighbour.h = abs(neighbour.position[0] - end_node.position[0]) + abs(neighbour.position[1] - end_node.position[1])
neighbour.f = neighbour.g + neighbour.h
if len([open_node for open_node in open_nodes if
neighbour.position == open_node.position and neighbour.g > open_node.g]) > 0:
continue
open_nodes.append(neighbour)
class NodeAStar:
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
print(a_star_search((0, 0), (3, 0)))
#print(a_star_search((2, 2), (7, 7)))
print(WAREHOUSE_MAP[5][0])
print(5, 0)
class Node: class Node:
def __init__(self, state, agent_direction, action=None, parent=None): def __init__(self, state, agent_direction, action=None, parent=None):
self.state = state self.state = state
@ -178,6 +276,13 @@ class Shelf:
self.rect = self.image.get_rect(center=self.pos_pix) self.rect = self.image.get_rect(center=self.pos_pix)
class Stain:
def __init__(self, pos):
self.pos_pix = get_pix_from_position[pos]
self.image = STAIN = pygame.transform.scale(pygame.image.load("img/stain.png"), (60, 60))
self.rect = self.image.get_rect(center=self.pos_pix)
class Agent: class Agent:
def __init__(self, pos, agent_direction="right"): def __init__(self, pos, agent_direction="right"):
self.pos = pos self.pos = pos
@ -273,7 +378,7 @@ class Agent:
board = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA) # transparently surface board = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA) # transparently surface
# #
create_postiions() create_positions()
# #
@ -283,15 +388,17 @@ for x in range(9):
agent = Agent((40, 640)) agent = Agent((40, 640))
Shelf_list = [ Shelf_list = [
Shelf((5, 2), 'Explosive', 5), Shelf((6, 2), 'Explosive', 5), Shelf((7, 2), 'Explosive', 5), Shelf((8, 2), 'Explosive', 5), Shelf((5, 2), 'Explosive', 5), Shelf((6, 2), 'Explosive', 5), Shelf((7, 2), 'Explosive', 5),
Shelf((8, 2), 'Explosive', 5),
Shelf((5, 4), 'Grocery', 5), Shelf((6, 4), 'Grocery', 5), Shelf((7, 4), 'Grocery', 5), Shelf((8, 4), 'Grocery', 5), Shelf((5, 4), 'Grocery', 5), Shelf((6, 4), 'Grocery', 5), Shelf((7, 4), 'Grocery', 5), Shelf((8, 4), 'Grocery', 5),
Shelf((5, 6), 'Builders', 5), Shelf((6, 6), 'Builders', 5), Shelf((7, 6), 'Builders', 5), Shelf((8, 6), 'Builders', 5), Shelf((5, 6), 'Builders', 5), Shelf((6, 6), 'Builders', 5), Shelf((7, 6), 'Builders', 5),
Shelf((5, 8), 'Electronic', 5), Shelf((6, 8), 'Electronic', 5), Shelf((7, 8), 'Electronic', 5), Shelf((8, 8), 'Electronic', 5)] Shelf((8, 6), 'Builders', 5),
Shelf((5, 8), 'Electronic', 5), Shelf((6, 8), 'Electronic', 5), Shelf((7, 8), 'Electronic', 5),
Shelf((8, 8), 'Electronic', 5)]
coord_goals = [(6, 8), (0, 0), (5, 8), (0, 0), (7, 8), (0, 0), (8, 8), (0, 0),
coord_goals = [(6, 8), (0, 0), (5,8), (0, 0), (7,8), (0, 0), (8,8), (0, 0), (5,6), (0, 0), (6,6), (0, 0), (7,6), (0, 0), (8,6), (0, 8)] (5, 6), (0, 0), (6, 6), (0, 0), (7, 6), (0, 0), (8, 6), (0, 8)]
screen = pygame.display.set_mode([WIDTH, HEIGHT]) screen = pygame.display.set_mode([WIDTH, HEIGHT])
@ -301,18 +408,22 @@ Package_list = [
agent.path = breadth_first_search(agent.pos_coord, agent.agent_direction) agent.path = breadth_first_search(agent.pos_coord, agent.agent_direction)
Stain_list = []
# Pętla służąca do tworzenia plam oleju na podstawie mapy magazynu
for index_x in range(9):
for index_y in range(9):
if WAREHOUSE_MAP[index_x][index_y] == 5:
Stain_list.append(Stain((index_y, index_x)))
running = True running = True
while running:
while running:
time.sleep(0.25)
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
running = False running = False
if event.type == pygame.KEYDOWN: if event.type == pygame.KEYDOWN:
pass pass
# agent.move(event.key)
# agent.lift_package(event.key)
# agent.rotate(event.key)
for package in Package_list: for package in Package_list:
if package.is_package_up: if package.is_package_up:
@ -337,6 +448,7 @@ while running:
agent.move_bfs() agent.move_bfs()
else: else:
time.sleep(.25) time.sleep(.25)
@ -353,6 +465,8 @@ while running:
screen.blit(board, board.get_rect()) screen.blit(board, board.get_rect())
for shelf in Shelf_list: for shelf in Shelf_list:
screen.blit(shelf.image, shelf.rect) screen.blit(shelf.image, shelf.rect)
for stain in Stain_list:
screen.blit(stain.image, stain.rect)
screen.blit(agent.image, agent.rect) screen.blit(agent.image, agent.rect)
for package in Package_list: for package in Package_list:
screen.blit(package.image, package.rect) screen.blit(package.image, package.rect)