Question
Here are my code. And the documentation for reference class DeliveryPlanner_PartA: Required methods in this class are: plan_delivery(self, debug = False) which is stubbed
Here are my code. And the documentation for reference
class DeliveryPlanner_PartA:
"""
Required methods in this class are:
plan_delivery(self, debug = False) which is stubbed out below.
You may not change the method signature as it will be called directly
by the autograder but you may modify the internals as needed.
__init__: which is required to initialize the class. Starter code is
provided that initializes class variables based on the definitions in
testing_suite_partA.py. You may choose to use this starter code
or modify and replace it based on your own solution.
You should't change the signature, however.
The following methods are starter code you may use for part A.
However, they are not required and can be replaced with your
own methods.
_search(self, debug=False): Where the bulk of the A* search algorithm
could reside. It should find an optimal path from the robot
location to a goal.
Hint: you may want to structure this based
on whether looking for a box or delivering a box.
"""
## Definitions taken from testing_suite_partA.py
ORTHOGONAL_MOVE_COST = 2
DIAGONAL_MOVE_COST = 3
BOX_LIFT_COST = 4
BOX_DOWN_COST = 2
ILLEGAL_MOVE_PENALTY = 100
def __init__(self, warehouse, robot_position, todo, box_locations):
self.todo = todo
self.boxes_delivered = []
self.total_cost = 0
self.warehouse_viewer = warehouse
self.box_locations = box_locations
self.dropzone = self.robot_position = robot_position
self.delta = [[-1, 0], # north
[0, -1], # west
[1, 0], # south
[0, 1], # east
[-1, -1], # northwest (diag)
[-1, 1], # northeast (diag)
[1, 1], # southeast (diag)
[1, -1]] # southwest (diag)
self.delta_directions = ["n", "w", "s", "e", "nw", "ne", "se", "sw"]
# Can use this for a visual debug
self.delta_name = ['^', '', '', '/', '[', ']']
# You may choose to use arrows instead
# self.delta_name = ['????', '????', '????', '????', '????', '????', '????', '????']
# Costs for each move
self.delta_cost = [self.ORTHOGONAL_MOVE_COST,
self.ORTHOGONAL_MOVE_COST,
self.ORTHOGONAL_MOVE_COST,
self.ORTHOGONAL_MOVE_COST,
self.DIAGONAL_MOVE_COST,
self.DIAGONAL_MOVE_COST,
self.DIAGONAL_MOVE_COST,
self.DIAGONAL_MOVE_COST]
def _search(self, start, goal, debug=False):
"""
This method should be based on lesson modules for A*, see Search, Section 12-14.
The bulk of the search logic should reside here, should you choose to use this starter code.
Please condition any printout on the debug flag provided in the argument.
You may change this function signature (i.e. add arguments) as
necessary, except for the debug argument which must remain with a default of False
"""
#
# # # get a shortcut variable for the warehouse (note this is just a view no copying)
# warehouse = self.warehouse_viewer
# #
# # # Find and fill in the required moves per the instructions - example moves for test case 1
# moves = ['move w',
# 'move nw',
# 'lift 1',
# 'move se',
# 'down e',
# 'move ne',
# 'lift 2',
# 'down s']
#
# return moves
cost = 1
heuristic = [[9, 8, 7, 6, 5, 4],
[8, 7, 6, 5, 4, 3],
[7, 6, 5, 4, 3, 2],
[6, 5, 4, 3, 2, 1],
[5, 4, 3, 2, 1, 0]]
delta = self.delta
delta_name = self.delta_name
closed_list = {}
print(f"Start: {start}, Goal: {goal}")
x = start[0]
y = start[1]
g = 0
h = heuristic[x][y]
f = g + h
open_list = [[f, g, h, x, y]]
found = False
resign = False
while not found and not resign:
if len(open_list) == 0:
resign = True
if debug:
print('Fail')
return [] # return an empty list instead of None
else:
open_list.sort()
open_list.reverse()
next_node = open_list.pop()
x = next_node[3]
y = next_node[4]
g = next_node[1]
if x == goal[0] and y == goal[1]:
found = True
if debug:
print(next_node)
else:
for i in range(len(delta)):
x2 = x + delta[i][0]
y2 = y + delta[i][1]
if (x2, y2) not in closed_list and self.warehouse_viewer[x2][y2] == ' ':
g2 = g + cost
h2 = heuristic[x2][y2]
f2 = g2 + h2
open_list.append([f2, g2, h2, x2, y2])
closed_list[(x2, y2)] = i
path = []
x = goal[0]
y = goal[1]
while x != start[0] or y != start[1]:
idx = closed_list[(x, y)]
path.append(delta_name[idx])
x -= delta[idx][0]
y -= delta[idx][1]
return path[::-1]
def plan_delivery(self, debug=False):
"""
plan_delivery() is required and will be called by the autograder directly.
You may not change the function signature for it.
Add logic here to find the moves. You may use the starter code provided
in any way you choose, but please condition any printouts on the debug flag
"""
# You may wish to break the task into one-way paths, like this:
#
# moves_to_1 = self._search( ..., debug=debug )
# moves_from_1 = self._search( ..., debug=debug )
# moves_to_2 = self._search( ..., debug=debug )
# moves_from_2 = self._search( ..., debug=debug )
# moves = moves_to_1 + moves_from_1 + moves_to_2 + moves_from_2
#
# If you use _search(), you may need to modify it to take some
# additional arguments for starting location, goal location, and
# whether to pick up or deliver a box.
#
# moves = self._search(debug=debug)
#
# if debug:
# for i in range(len(moves)):
# print(moves[i])
#
# return moves
moves = []
print("hello")
for box in self.box_locations:
print("box", box)
# Move to the box
moves_to_box = self._search(self.robot_position, self.box_locations[box], debug)
print("moves_box", moves_to_box)
if moves_to_box is None:
print("Failed to find a path to the box.")
continue
moves += moves_to_box
moves.append('lift {}'.format(box))
# Move back to the dropzone
box_coords = self.box_locations[box]
moves_from_box = self._search(box_coords, self.dropzone, debug)
if moves_from_box is None:
print("Failed to find a path from the box to the dropzone.")
continue
moves += moves_from_box
moves.append('down {}'.format(self.dropzone))
# Update the robot's position
self.robot_position = self.dropzone
if debug:
for move in moves:
print(move)
return moves
Documentation
Part A (40%) Your task is to pick up and deliver all boxes listed in the todo list. You will do this by providing a list of motions that the testing suite will execute in order to complete all the deliveries. Your algorithm should determine the best path to take when completing this task. DeliveryPlanner_PartA's constructor must take five arguments: self, warehouse, robot_position, todo, and box_locations. It must also have a method called plan_delivery that takes 2 arguments: self and debug (set to False by default). Part A Input Specifications warehouse will be a custom object used by the testing suite. For all intents and purposes, you can think of it as a list of m lists, each inner list containing n characters, corresponding to the layout of the warehouse. The warehouse is an m x n grid. warehouse [i][j] corresponds to the spot in the ith row and jth column of the warehouse, where the 0th row is the northern end of the warehouse and the oth column is the western end. NOTE: In part A, your code will not know (nor should it depend on) the size of the warehouse (n and m). You are only allowed to use the warehouse object (WarehouseAccess) in the following 2 ways, if we find that your code is using any other methods/approaches to use or manipulate the warehouse object, you will receive a 0 for part A (this may be done manually after the project is due):
Step by Step Solution
3.29 Rating (155 Votes )
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started