Dodanie szukania najbliższej paczki, szukania najbliższego regału pasującego do paczki, i ładowania i odkładania paczki na miejsce
This commit is contained in:
parent
b29f027943
commit
7606871afb
86
agent.py
86
agent.py
@ -1,13 +1,16 @@
|
|||||||
from warehouse import Coordinates, Tile, Pack
|
from warehouse import Coordinates, Tile, Pack
|
||||||
from queue import PriorityQueue
|
from queue import PriorityQueue
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
from attributes import TURN_LEFT_DIRECTIONS, TURN_RIGHT_DIRECTIONS
|
from attributes import TURN_LEFT_DIRECTIONS, TURN_RIGHT_DIRECTIONS, PackStatus, PackSize
|
||||||
|
import pdb
|
||||||
|
|
||||||
class Node:
|
class Node:
|
||||||
def __init__(self, coord_x, coord_y):
|
def __init__(self, coord_x, coord_y, package=None, is_rack=False):
|
||||||
self.x = coord_x
|
self.x = coord_x
|
||||||
self.y = coord_y
|
self.y = coord_y
|
||||||
self.parent = None
|
self.parent = None
|
||||||
|
self.package = package
|
||||||
|
self.is_rack = is_rack
|
||||||
self.g_cost = 0
|
self.g_cost = 0
|
||||||
self.h_cost = 0
|
self.h_cost = 0
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
@ -38,12 +41,20 @@ class Agent:
|
|||||||
|
|
||||||
def find_path(self):
|
def find_path(self):
|
||||||
self.closed = []
|
self.closed = []
|
||||||
|
self.path = []
|
||||||
self.open = PriorityQueue()
|
self.open = PriorityQueue()
|
||||||
|
if self.is_loaded:
|
||||||
|
rack = self.find_nearest_rack_for(self.transported_package)
|
||||||
|
self.dest = Node(rack.x_position, rack.y_position, is_rack=True)
|
||||||
|
else:
|
||||||
|
package = self.find_nearest_package()
|
||||||
|
self.dest = Node(package.lays_on_field.x_position, package.lays_on_field.y_position, package=package)
|
||||||
|
|
||||||
start_node = Node(self.x, self.y)
|
start_node = Node(self.x, self.y)
|
||||||
|
|
||||||
self.open.put((0, start_node))
|
self.open.put((0, start_node))
|
||||||
while self.open:
|
while self.open:
|
||||||
_, current_node = self.open.get()
|
_, current_node = self.open.get()
|
||||||
print(current_node.x, current_node.y)
|
|
||||||
self.closed.append(current_node)
|
self.closed.append(current_node)
|
||||||
if current_node.x == self.dest.x and current_node.y == self.dest.y:
|
if current_node.x == self.dest.x and current_node.y == self.dest.y:
|
||||||
while current_node.x != start_node.x or current_node.y != start_node.y:
|
while current_node.x != start_node.x or current_node.y != start_node.y:
|
||||||
@ -98,13 +109,21 @@ class Agent:
|
|||||||
return neighbours
|
return neighbours
|
||||||
|
|
||||||
def move(self):
|
def move(self):
|
||||||
|
dest_coords = (self.dest.x, self.dest.y)
|
||||||
if not self.path:
|
if not self.path:
|
||||||
|
print("chuj")
|
||||||
if not self.find_path():
|
if not self.find_path():
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
next = self.path.pop()
|
next = self.path.pop()
|
||||||
|
if (next.x, next.y) == dest_coords:
|
||||||
|
if self.dest.package:
|
||||||
|
self.pick_up_package(self.dest.package)
|
||||||
|
return
|
||||||
|
elif self.dest.is_rack:
|
||||||
|
self.unload_package(self.dest)
|
||||||
|
return
|
||||||
star_dir = self.direction
|
star_dir = self.direction
|
||||||
print(next.x, next.y)
|
|
||||||
if self.x > next.x and not self.direction == 'left':
|
if self.x > next.x and not self.direction == 'left':
|
||||||
if self.direction == 'down':
|
if self.direction == 'down':
|
||||||
self.turn_right()
|
self.turn_right()
|
||||||
@ -133,17 +152,70 @@ class Agent:
|
|||||||
self.path.append(next)
|
self.path.append(next)
|
||||||
self.closed = []
|
self.closed = []
|
||||||
|
|
||||||
def check_if_can_move(self, next_coords: Coordinates):
|
def check_if_can_move(self, next_coords: Coordinates, rack_searching=False):
|
||||||
tile_on_map = 0 <= next_coords.x < self.warehouse.width and 0 <= next_coords.y < self.warehouse.height
|
tile_on_map = 0 <= next_coords.x < self.warehouse.width and 0 <= next_coords.y < self.warehouse.height
|
||||||
|
tile_passable = True
|
||||||
if not tile_on_map:
|
if not tile_on_map:
|
||||||
return False
|
return False
|
||||||
next_tile = self.warehouse.tiles[next_coords.x][next_coords.y]
|
next_tile = self.warehouse.tiles[next_coords.x][next_coords.y]
|
||||||
|
if not self.is_loaded:
|
||||||
tile_passable = isinstance(next_tile, Tile) and next_tile.category.passable
|
tile_passable = isinstance(next_tile, Tile) and next_tile.category.passable
|
||||||
return tile_passable
|
return tile_passable
|
||||||
|
|
||||||
|
def find_nearest_package(self):
|
||||||
|
packages_costs = []
|
||||||
|
start_node = Node(self.x, self.y)
|
||||||
|
if not self.warehouse.packages:
|
||||||
|
return
|
||||||
|
for package in self.warehouse.packages:
|
||||||
|
if package.status == PackStatus.STORED:
|
||||||
|
continue
|
||||||
|
new_node = Node(package.lays_on_field.x_position, package.lays_on_field.y_position)
|
||||||
|
cost = self.heuristic(start_node, new_node)
|
||||||
|
if cost > 0:
|
||||||
|
packages_costs.append((package, cost))
|
||||||
|
package = min(packages_costs, key=lambda l: l[1])[0]
|
||||||
|
return package
|
||||||
|
|
||||||
|
def find_nearest_rack_for(self, package, expand_box=0):
|
||||||
|
weight = package.size
|
||||||
|
accepted_weights = [weight, PackSize.ALL]
|
||||||
|
start_node = Node(self.x, self.y)
|
||||||
|
quarter_x = int(self.warehouse.width/4) + expand_box
|
||||||
|
quarter_y = int(self.warehouse.height/4) + expand_box
|
||||||
|
start_quarter_x = self.x - quarter_x if self.x - quarter_x > 0 else 0
|
||||||
|
end_quarter_x = self.x + quarter_x if self.x + quarter_x < self.warehouse.width else self.warehouse.width - 1
|
||||||
|
start_quarter_y = self.y - quarter_y if self.y - quarter_y > 0 else 0
|
||||||
|
end_quarter_y = self.y + quarter_y if self.y + quarter_y < self.warehouse.height else self.warehouse.height - 1
|
||||||
|
quarter = [row[start_quarter_y:end_quarter_y] for row in self.warehouse.tiles[start_quarter_x:end_quarter_x]]
|
||||||
|
quarter_racks = [[t for t in row if t.category.name == "Rack" and not t.occupied and t.category.pack_size in accepted_weights] for row in quarter]
|
||||||
|
quarter_racks = [t for row in quarter_racks for t in row]
|
||||||
|
racks_costs = []
|
||||||
|
if not quarter_racks:
|
||||||
|
self.find_nearest_rack_for(package, expand_box+1)
|
||||||
|
for rack in quarter_racks:
|
||||||
|
new_node = Node(rack.x_position, rack.y_position)
|
||||||
|
cost = self.heuristic(start_node, new_node)
|
||||||
|
if cost > 0:
|
||||||
|
racks_costs.append((rack, cost))
|
||||||
|
rack = min(racks_costs, key=lambda l: l[1])[0]
|
||||||
|
return rack
|
||||||
|
|
||||||
|
|
||||||
def pick_up_package(self, pack):
|
def pick_up_package(self, pack):
|
||||||
tile = pack.lays_on_field
|
self.warehouse.packages.remove(pack)
|
||||||
self.assigned_warehouse.tiles[tile.x_position][tile.y_position] = tile
|
|
||||||
self.is_loaded = True
|
self.is_loaded = True
|
||||||
|
self.warehouse.tiles[pack.lays_on_field.x_position][pack.lays_on_field.y_position].occupied = False
|
||||||
|
self.dest.package = None
|
||||||
pack.lays_on_field = None
|
pack.lays_on_field = None
|
||||||
self.transported_package = pack
|
self.transported_package = pack
|
||||||
|
|
||||||
|
def unload_package(self, rack):
|
||||||
|
pack = self.transported_package
|
||||||
|
tile = self.warehouse.tiles[rack.x][rack.y]
|
||||||
|
self.transported_package = None
|
||||||
|
self.is_loaded = False
|
||||||
|
pack.lays_on_field = tile
|
||||||
|
self.warehouse.tiles[rack.x][rack.y].occupied = True
|
||||||
|
pack.status = PackStatus.STORED
|
||||||
|
self.warehouse.packages.append(pack)
|
2
main.py
2
main.py
@ -21,7 +21,7 @@ class MainGameFrame:
|
|||||||
self.display = pygame.display.set_mode(WINDOW_SIZE)
|
self.display = pygame.display.set_mode(WINDOW_SIZE)
|
||||||
agent_radius = int(TILE_WIDTH/2)
|
agent_radius = int(TILE_WIDTH/2)
|
||||||
self.agent_tex = pygame.image.load('forklift.png')
|
self.agent_tex = pygame.image.load('forklift.png')
|
||||||
self.warehouse_map = warehouse.Warehouse(20, 20, 150, 20)
|
self.warehouse_map = warehouse.Warehouse(20, 20, 150, 25)
|
||||||
starting_x, starting_y = self.set_starting_agent_position()
|
starting_x, starting_y = self.set_starting_agent_position()
|
||||||
self.agent = agent.Agent(starting_x, starting_y, self.warehouse_map, agent_radius)
|
self.agent = agent.Agent(starting_x, starting_y, self.warehouse_map, agent_radius)
|
||||||
self.clock = pygame.time.Clock()
|
self.clock = pygame.time.Clock()
|
||||||
|
@ -161,6 +161,7 @@ class Warehouse:
|
|||||||
for i in range(no_of_packages):
|
for i in range(no_of_packages):
|
||||||
pack_x, pack_y = self._set_package_position()
|
pack_x, pack_y = self._set_package_position()
|
||||||
package_field = self.tiles[pack_x][pack_y]
|
package_field = self.tiles[pack_x][pack_y]
|
||||||
|
self.tiles[pack_x][pack_y].occupied = True
|
||||||
new_package = Pack(lays_on_field=package_field)
|
new_package = Pack(lays_on_field=package_field)
|
||||||
packages.append(new_package)
|
packages.append(new_package)
|
||||||
return packages
|
return packages
|
||||||
@ -206,6 +207,7 @@ class Tile:
|
|||||||
self.category = CATEGORY.get(category, CATEGORY['floor'])
|
self.category = CATEGORY.get(category, CATEGORY['floor'])
|
||||||
self.x_position = x_position
|
self.x_position = x_position
|
||||||
self.y_position = y_position
|
self.y_position = y_position
|
||||||
|
self.occupied = False
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user