Algorytm A*, dodanie kałuż, obrót kelnera, drobne poprawki
This commit is contained in:
parent
d88933f530
commit
ceafb6b12c
@ -2,10 +2,111 @@ import pygame
|
|||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
import queue
|
import queue
|
||||||
|
import math
|
||||||
|
|
||||||
pygame.init()
|
pygame.init()
|
||||||
|
|
||||||
|
|
||||||
|
def heuristic(current, goal):
|
||||||
|
dx = abs(current[0] - goal[0])
|
||||||
|
dy = abs(current[1] - goal[1])
|
||||||
|
return math.sqrt(dx * dx + dy * dy)
|
||||||
|
|
||||||
|
|
||||||
|
class Node():
|
||||||
|
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(start, end):
|
||||||
|
if end in cantwalk:
|
||||||
|
print("Wybrano nieodpowiednie pole!")
|
||||||
|
return []
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
open_list = []
|
||||||
|
closed_list = []
|
||||||
|
open_list.append(start_node)
|
||||||
|
|
||||||
|
while len(open_list) > 0:
|
||||||
|
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
|
||||||
|
|
||||||
|
open_list.pop(current_index)
|
||||||
|
closed_list.append(current_node)
|
||||||
|
|
||||||
|
if current_node == end_node:
|
||||||
|
path = []
|
||||||
|
current = current_node
|
||||||
|
while current is not None:
|
||||||
|
path.append(current.position)
|
||||||
|
current = current.parent
|
||||||
|
return list(map(lambda t: (t[0], t[1]), path[::-1])) #zwraca odwróconą ściezkę
|
||||||
|
|
||||||
|
children = []
|
||||||
|
# można dodać (-1, -1), (-1, 1), (1, -1), (1, 1) dla poruszania się po przekątnej
|
||||||
|
for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0)]:
|
||||||
|
node_position = (current_node.position[0] + new_position[0], current_node.position[1]
|
||||||
|
+ new_position[1])
|
||||||
|
|
||||||
|
if node_position[0] >= (rows - 1) or node_position[0] <= 0 or node_position[1] >= (rows - 1) \
|
||||||
|
or node_position[1] <= 0: #spr. czy w kracie
|
||||||
|
continue
|
||||||
|
|
||||||
|
if node_position in cantwalk: #spr. czy można przejść
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_node = Node(current_node, node_position)
|
||||||
|
children.append(new_node)
|
||||||
|
|
||||||
|
didBreak = False
|
||||||
|
for child in children:
|
||||||
|
didBreak = False
|
||||||
|
for closed_child in closed_list:
|
||||||
|
if child == closed_child:
|
||||||
|
didBreak = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if didBreak:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if child.position in cantwalk:
|
||||||
|
child.g = current_node.g + 99999
|
||||||
|
elif child.position in puddles:
|
||||||
|
child.g = current_node.g + 3
|
||||||
|
else:
|
||||||
|
child.g = current_node.g + 1
|
||||||
|
|
||||||
|
child.h = heuristic(child.position, end_node.position)
|
||||||
|
child.f = child.g + child.h
|
||||||
|
|
||||||
|
for open_node in open_list:
|
||||||
|
if child == open_node and child.g > open_node.g:
|
||||||
|
didBreak = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if didBreak:
|
||||||
|
continue
|
||||||
|
|
||||||
|
open_list.append(child)
|
||||||
|
|
||||||
|
|
||||||
class Dish(object):
|
class Dish(object):
|
||||||
def __init__(self, dishName, prepTime, eatTime, price):
|
def __init__(self, dishName, prepTime, eatTime, price):
|
||||||
self.dishName = dishName
|
self.dishName = dishName
|
||||||
@ -47,7 +148,6 @@ class Kitchen(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def draw(self, surface):
|
def draw(self, surface):
|
||||||
|
|
||||||
image1 = pygame.image.load(r'kitchen1.png')
|
image1 = pygame.image.load(r'kitchen1.png')
|
||||||
image1 = pygame.transform.scale(image1, (sizeBetween - 1, sizeBetween - 1))
|
image1 = pygame.transform.scale(image1, (sizeBetween - 1, sizeBetween - 1))
|
||||||
surface.blit(image1, (13*sizeBetween+1, 0*sizeBetween+1))
|
surface.blit(image1, (13*sizeBetween+1, 0*sizeBetween+1))
|
||||||
@ -80,6 +180,7 @@ class Client(object):
|
|||||||
def takeASeat(self, table):
|
def takeASeat(self, table):
|
||||||
self.myTable = table
|
self.myTable = table
|
||||||
|
|
||||||
|
|
||||||
class Table(object):
|
class Table(object):
|
||||||
def __init__(self, pos, capacity):
|
def __init__(self, pos, capacity):
|
||||||
self.pos = pos
|
self.pos = pos
|
||||||
@ -103,12 +204,13 @@ class Waiter(object):
|
|||||||
def __init__(self, color, pos, direction):
|
def __init__(self, color, pos, direction):
|
||||||
self.color = color
|
self.color = color
|
||||||
self.pos = pos #pozycja agenta, zapisana w formie dwuelementowej listy
|
self.pos = pos #pozycja agenta, zapisana w formie dwuelementowej listy
|
||||||
|
self.posx = pos[0]
|
||||||
|
self.posy = pos[1]
|
||||||
self.dirnx = 0 #zmienne dirnx i dirny używane są do ruchu bota i ustalania, w którą stronę jest zwrócony
|
self.dirnx = 0 #zmienne dirnx i dirny używane są do ruchu bota i ustalania, w którą stronę jest zwrócony
|
||||||
self.dirny = 1
|
self.dirny = 1
|
||||||
self.plates = [] #lista niesionych przez agenta talerzy, planowo lista par: (talerz, klient)
|
self.plates = [] #lista niesionych przez agenta talerzy, planowo lista par: (talerz, klient)
|
||||||
self.direction = direction #kierunek, w ktory jest skierowany bot
|
self.direction = direction #kierunek, w ktory jest skierowany bot
|
||||||
|
|
||||||
|
|
||||||
def moveRandomly(self, noWalkable):
|
def moveRandomly(self, noWalkable):
|
||||||
rand = random.randrange(1, 5, 1) #losuje w zakresie 1-4
|
rand = random.randrange(1, 5, 1) #losuje w zakresie 1-4
|
||||||
#print(rand)
|
#print(rand)
|
||||||
@ -215,23 +317,42 @@ class Waiter(object):
|
|||||||
client.takePlateAndEat(plate)
|
client.takePlateAndEat(plate)
|
||||||
|
|
||||||
def draw(self, surface):
|
def draw(self, surface):
|
||||||
if self.direction == 'right':
|
|
||||||
image = pygame.image.load(r'waiter_right.png')
|
image = pygame.image.load(r'waiter_right.png')
|
||||||
image = pygame.transform.scale(image, (sizeBetween - 1, sizeBetween - 1))
|
image = pygame.transform.scale(image, (sizeBetween - 1, sizeBetween - 1))
|
||||||
|
|
||||||
|
if self.direction == "right":
|
||||||
|
image = pygame.transform.rotate(image, 270)
|
||||||
|
elif self.direction == "left":
|
||||||
|
image = pygame.transform.rotate(image, 90)
|
||||||
|
elif self.direction == "up":
|
||||||
|
image = pygame.transform.rotate(image, 180)
|
||||||
|
|
||||||
i = self.pos[0]
|
i = self.pos[0]
|
||||||
j = self.pos[1]
|
j = self.pos[1]
|
||||||
|
surface.blit(image, (i * sizeBetween + 1, j * sizeBetween + 1))
|
||||||
|
|
||||||
surface.blit(image, (i*sizeBetween+1, j*sizeBetween+1))
|
def goByAStar(self, end):
|
||||||
|
positionList = aStar(self.pos, end)
|
||||||
|
print(positionList)
|
||||||
|
lenght = len(positionList) - 1
|
||||||
|
for i in range(lenght):
|
||||||
|
movex = positionList[i + 1][0] - positionList[i][0]
|
||||||
|
movey = positionList[i + 1][1] - positionList[i][1]
|
||||||
|
self.posx += movex
|
||||||
|
self.posy += movey
|
||||||
|
self.pos = (self.posx, self.posy)
|
||||||
|
|
||||||
|
if movex == -1 and movey == 0:
|
||||||
|
self.direction = "left"
|
||||||
|
elif movex == 1 and movey == 0:
|
||||||
|
self.direction = "right"
|
||||||
|
elif movey == -1 and movex == 0:
|
||||||
|
self.direction = "down"
|
||||||
else:
|
else:
|
||||||
image = pygame.image.load(r'waiter_left.png')
|
self.direction = "up"
|
||||||
image = pygame.transform.scale(image, (sizeBetween - 1, sizeBetween - 1))
|
|
||||||
|
|
||||||
i = self.pos[0]
|
redrawWindow(window)
|
||||||
j = self.pos[1]
|
time.sleep(0.5)
|
||||||
|
|
||||||
surface.blit(image, (i*sizeBetween+1, j*sizeBetween+1))
|
|
||||||
|
|
||||||
|
|
||||||
def drawGrid(width, rows, surface):
|
def drawGrid(width, rows, surface):
|
||||||
@ -252,6 +373,10 @@ def redrawWindow(surface):
|
|||||||
kitchen.draw(surface)
|
kitchen.draw(surface)
|
||||||
for i in range(len(tables)):
|
for i in range(len(tables)):
|
||||||
tables[i].draw(surface)
|
tables[i].draw(surface)
|
||||||
|
for i in range(len(puddles)):
|
||||||
|
image = pygame.image.load(r'puddle.png')
|
||||||
|
image = pygame.transform.scale(image, (sizeBetween - 1, sizeBetween - 1))
|
||||||
|
surface.blit(image, (puddles[i][0]* sizeBetween + 1, puddles[i][1]* sizeBetween + 1))
|
||||||
drawGrid(width, rows, surface)
|
drawGrid(width, rows, surface)
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
|
|
||||||
@ -263,7 +388,7 @@ def noWalkable(tables, kitchen):
|
|||||||
return list
|
return list
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global width, rows, bot, beige, white, black, sizeBetween, tables, kitchen
|
global width, rows, bot, beige, white, black, sizeBetween, tables, kitchen, cantwalk, puddles, window
|
||||||
# skróty do kolorów
|
# skróty do kolorów
|
||||||
beige = (255, 205, 178)
|
beige = (255, 205, 178)
|
||||||
white = (255, 255, 255)
|
white = (255, 255, 255)
|
||||||
@ -273,35 +398,44 @@ def main():
|
|||||||
rows = 15
|
rows = 15
|
||||||
sizeBetween = width // rows #wielkość pojedynczej kratki
|
sizeBetween = width // rows #wielkość pojedynczej kratki
|
||||||
window = pygame.display.set_mode((width, width))
|
window = pygame.display.set_mode((width, width))
|
||||||
bot = Waiter((255, 0, 0), [12, 8], 'right')
|
bot = Waiter((255, 0, 0), (12, 8), "right")
|
||||||
|
|
||||||
tables = []
|
tables = []
|
||||||
tables.append(Table([0, 3], 1))
|
tables.append(Table((0, 3), 1))
|
||||||
tables.append(Table([0, 6], 1))
|
tables.append(Table((0, 6), 1))
|
||||||
tables.append(Table([0, 9], 2))
|
tables.append(Table((0, 9), 2))
|
||||||
tables.append(Table([0, 12], 2))
|
tables.append(Table((0, 12), 2))
|
||||||
tables.append(Table([4, 4], 2))
|
tables.append(Table((4, 4), 2))
|
||||||
tables.append(Table([4, 7], 2))
|
tables.append(Table((4, 7), 2))
|
||||||
tables.append(Table([4, 10], 2))
|
tables.append(Table((4, 10), 2))
|
||||||
tables.append(Table([4, 13], 2))
|
tables.append(Table((4, 13), 2))
|
||||||
tables.append(Table([8, 3], 1))
|
tables.append(Table((8, 3), 1))
|
||||||
tables.append(Table([8, 6], 1))
|
tables.append(Table((8, 6), 1))
|
||||||
tables.append(Table([8, 9], 2))
|
tables.append(Table((8, 9), 2))
|
||||||
tables.append(Table([8, 12], 2))
|
tables.append(Table((8, 12), 2))
|
||||||
|
|
||||||
flag = True
|
flag = True
|
||||||
clock = pygame.time.Clock()
|
clock = pygame.time.Clock()
|
||||||
kitchen = Kitchen([13, 1])
|
kitchen = Kitchen((13, 1))
|
||||||
|
|
||||||
list = noWalkable(tables, kitchen) # lista pozycji, na ktore bot nie moze wejsc
|
cantwalk = noWalkable(tables, kitchen) # lista pozycji, na ktore bot nie moze wejsc
|
||||||
|
puddles = []
|
||||||
|
puddles.append((7, 10))
|
||||||
|
puddles.append((2, 5))
|
||||||
|
puddles.append((3, 12))
|
||||||
|
puddles.append((10, 3))
|
||||||
|
puddles.append((6, 2))
|
||||||
|
puddles.append((12, 10))
|
||||||
|
puddles.append((1, 4))
|
||||||
|
|
||||||
while flag:
|
while flag:
|
||||||
pygame.time.delay(100)
|
pygame.time.delay(100)
|
||||||
clock.tick(60)
|
clock.tick(60)
|
||||||
for i in range(40): #bot testowo ma wykonać 40 kroków
|
|
||||||
bot.moveRandomly(list)
|
|
||||||
redrawWindow(window)
|
redrawWindow(window)
|
||||||
time.sleep(0.5) #opóźnienie każdego kolejnego kroku o pół sekundy
|
#bot.moveRandomly(list)
|
||||||
|
goal = (1,5)
|
||||||
|
bot.goByAStar(goal)
|
||||||
|
time.sleep(120)
|
||||||
flag = False
|
flag = False
|
||||||
|
|
||||||
|
|
||||||
|
BIN
Restaurant/puddle.png
Normal file
BIN
Restaurant/puddle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
Loading…
Reference in New Issue
Block a user