2020-04-23 19:43:51 +02:00
|
|
|
from warehouse import Coordinates, Tile, Pack
|
2020-04-02 15:25:15 +02:00
|
|
|
|
2020-04-27 22:14:07 +02:00
|
|
|
class Node:
|
|
|
|
def __init__(self, coord_x, coord_y):
|
|
|
|
self.x = coord_x
|
|
|
|
self.y = coord_y
|
|
|
|
self.parent = None
|
|
|
|
self.g_cost = 0
|
|
|
|
self.h_cost = 0
|
|
|
|
def __eq__(self, other):
|
|
|
|
if isinstance(other, Node):
|
|
|
|
return self.x == other.x and self.y == self.y
|
|
|
|
return False
|
|
|
|
|
2020-04-04 22:03:15 +02:00
|
|
|
class Agent:
|
2020-04-27 22:14:07 +02:00
|
|
|
def __init__(self, start_x, start_y, assigned_warehouse, radius=5):
|
|
|
|
self.x = start_x
|
|
|
|
self.y = start_y
|
|
|
|
self.radius = radius
|
|
|
|
self.warehouse = assigned_warehouse
|
|
|
|
self.is_loaded = False
|
|
|
|
self.transported_package = None
|
|
|
|
self.dest = Node(0, 0)
|
|
|
|
self.closed = list()
|
|
|
|
self.open = list()
|
|
|
|
self.path = list()
|
|
|
|
|
|
|
|
def find_path(self):
|
|
|
|
start_node = Node(self.x, self.y)
|
|
|
|
self.open.append(start_node)
|
|
|
|
while self.open:
|
|
|
|
current_node = self.open.pop()
|
|
|
|
self.closed.append(current_node)
|
|
|
|
if current_node.x == self.dest.x and current_node.y == self.dest.y:
|
|
|
|
while current_node != start_node:
|
|
|
|
path.append(current_node)
|
|
|
|
current_node = current_node.parent
|
|
|
|
return True
|
|
|
|
neighbour_list = self.get_neighbours(current_node)
|
|
|
|
for neighbour in neighbour_list:
|
|
|
|
if neighbour in self.closed:
|
|
|
|
continue
|
|
|
|
cost = current_node.g_cost + self.heur_cost_est(current_node, neighbour)
|
|
|
|
if cost < neighbour.g_cost or neighbour not in self.open:
|
|
|
|
neighbour.g_cost = cost
|
|
|
|
neighbour.h_cost = self.heur_cost_est(neighbour, self.dest)
|
|
|
|
neighbour.parent = current_node
|
|
|
|
if neighbour not in self.open:
|
|
|
|
self.open.append(neighbour);
|
|
|
|
return False
|
|
|
|
|
|
|
|
def heur_cost_est(self, nodeA: Node, nodeB: Node):
|
|
|
|
deltaX = abs(nodeA.x - nodeB.x)
|
|
|
|
deltaY = abs(nodeA.y - nodeB.y)
|
|
|
|
if deltaX > deltaY:
|
|
|
|
return (14 * deltaY) + (10 * (deltaX - deltaY))
|
|
|
|
return (14 * deltaX) + (10 *(deltaY - deltaX))
|
|
|
|
|
|
|
|
def get_neighbours(self, node: Node):
|
|
|
|
neighbours = list()
|
|
|
|
#if self.check_if_can_move(Coordinates(node.x + 1, node.y)):
|
|
|
|
neighbours.append(Node(node.x + 1, node.y))
|
|
|
|
#if self.check_if_can_move(Coordinates(node.x - 1, node.y)):
|
|
|
|
neighbours.append(Node(node.x - 1, node.y))
|
|
|
|
#if self.check_if_can_move(Coordinates(node.x, node.y + 1)):
|
|
|
|
neighbours.append(Node(node.x, node.y + 1))
|
|
|
|
#if self.check_if_can_move(Coordinates(node.x, node.y - 1)):
|
|
|
|
neighbours.append(Node(node.x, node.y - 1))
|
|
|
|
return neighbours
|
|
|
|
|
|
|
|
def move(self):
|
|
|
|
if not self.path:
|
|
|
|
if not self.find_path():
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
next = self.path.pop()
|
|
|
|
self.x = next.x
|
|
|
|
self.y = next.y
|
2020-04-28 00:14:29 +02:00
|
|
|
|
2020-04-27 22:14:07 +02:00
|
|
|
def check_if_can_move(self, next_coords: Coordinates):
|
2020-04-28 00:14:29 +02:00
|
|
|
tile_on_map = 0 <= next_coords.x < self.assigned_warehouse.width and 0 <= next_coords.y < self.assigned_warehouse.height
|
|
|
|
if not tile_on_map:
|
|
|
|
return False
|
|
|
|
next_tile = self.assigned_warehouse.tiles[next_coords.x][next_coords.y]
|
2020-04-27 22:14:07 +02:00
|
|
|
tile_passable = isinstance(next_tile, Tile) and next_tile.category.passable
|
2020-04-28 00:14:29 +02:00
|
|
|
return tile_passable
|
|
|
|
|
2020-04-27 22:14:07 +02:00
|
|
|
def pick_up_package(self, pack):
|
|
|
|
tile = pack.lays_on_field
|
|
|
|
self.assigned_warehouse.tiles[tile.x_position][tile.y_position] = tile
|
|
|
|
self.is_loaded = True
|
|
|
|
pack.lays_on_field = None
|
|
|
|
self.transported_package = pack
|