Under “normal” semester circumstances (circumstances in which you’re actually allowed to walk around campus :), many of you probably had a typical campus routine for navigating between your various UofA commitments - parking, classes, housing, work, etc. In some cases, you may have even had a very specific route through campus to make it to these locations. In this assignment, you will be implementing a program that visually maps out routes across campus, as shown in the animation to the right. This program will need to make sure that the path avoids obstructions, such as buildings and parking garages. The basic steps of this assignment are as follows:
campus.py
, which contains a 2D grid (2d list) of information about where a student can walk (for instance, the mall, walkways, roadways) and where a student may not walk (buildings, parking garages, etc).Name your program path_finder.py
.
Continue reading for more detailed information on each of these steps.
In order to display the map of campus, you’ll have to render an image onto the canvas.
Go ahead and download this image, and place it in the same folder as your path_finder.py
file:
Once there, you should use the graphics.image
function to display the image onto the canvas.
Note that you should also make sure you download the latest version of graphics.py
from the class website.
The version you downloaded earlier in the semester might be missing this function!
The function has 5 parameters: X coordinate, Y coordinate, upscale value, downscale value, and image file name.
Since you don’t want to resize the image, make sure that the upscale value and downscale value are both set to 1
.
Also, make sure to size the canvas to the same dimensions as the image file, so that it perfectly fits on it.
I know I just provided that whole description, however I am also going to provide you with some starter code (that you are not required to use) which sets up the canvas for you. You can download it here:
Your program will get the information about what path to find from the stops file. This file will contain the building and coordinates of the student’s starting location, as well as the building and coordinates for all of the stops along the path. Often, the ending location will be the same building that the student started at, though the exact coordinates may differ. Here’s an example of what the contents of a stops file might look like:
Cherry Garage - 672,312
Bio East - 436,312
Administration - 450,124
Chemistry - 390,218
Sonett - 632,160
Cherry Garage - 680,300
The first line indicates the starting point, and each subsequent line indicates a stopping point to get to. The program’s job will be to plot a path that reaches all of the stops, in the order they are shown in the file. Each line contains the name of the building, then a dash, then the x,y coordinate of that stop, in terms of pixels on the image. Eventually, when your program is fully functional, when the program reads in that file it should produce the path shown. Your program should read this file, and load the data into a 2d list, where each row of the 2d list is one of the rows of the file, split up into its three components (x, y, and building name). Later in this spec, I provide three test input files. You are also welcome, and even encouraged, to create some of your own. Note that the TAs may test your program with input files other than these three.
“But wait!” you might say… “Isn’t this assignment super easy? Can’t we just draw lines with gui.line
between each of the (x,y) coordinates from the file and call it a day?”
Well, the problem is not quite that simple.
One of the “tricks” for this assignment is figuring out how to plot these paths, while avoiding walking through obstructions such as buildings.
One way to determine where you can and cannot walk would be by the pixel colors!
Orange represents a building, dark gray represents parking garages, green represents grass, etc.
For the purpose of this assignment, I have simplified this by providing you with campus.py
:
This python file contains a HUGE 2D list, that gives you all the information you need.
The dimensions of the 2D list are the same as the image file, so one element in this list corresponds with one pixel on the canvas.
Every element will be either '#'
representing a pixel you cannot walk on, or ' '
representing one that you can walk on.
The image file is 1000 pixels wide by 560 pixels tall.
The campus_grid
2D list in campus.py
has 560 rows (the height), and 1000 elements in each row (the width).
You should download this file, place it in the same directory as path_finder.py
, and import it.
From there, you can access this big 2D list directly.
To summarize, at this point you should:
campus.py
.Now, to actually “find” the “path!” When working on the path, it is best to break up finding the path into each individual segment. For instance, don’t try to find that traverses Cherry Garage, Bio East, Admin, Chem, and Sonnet all at once. Instead, iterate through each pair ans solve them one-at-a-time. First produce the path from Cherry to Bio East, next work on the path from Bio East to Admin, and so on.
For any given rout from one point (x1,y1) and another point (x2,y2), you should work on the path pixel-by-pixel. For each pixel of movement, you need to somehow decide which direction to move (out of 8 possible directions: N, NE, E, SE, S, SW, W, NW). Thus, for every one-pixel movement, here’s how to decide what direction to go:
(cx + 1, cy + 1)
, (cx + 1, cy)
, or (cx, cy + 1)
.
As another example, if the direction you nead to head is W, then the three most optimal changes to the current position are (cx - 1, cy)
, (cx - 1, cy - 1)
, or (cx - 1, cy + 1)
.
*(3) Next, check if there is a building in the way of the direction you want to move.
First, check the most optimal direction, and if there’s no building, then that will be the move.
If there is, try the other two.
I will guarantee that in all test cases, one of those three directions will work for any given move.This program must follow the style guidelines from the class website.
You should also structure all of the code into functions.
The only code that is allowed to not be in a function are your import
statements and a call to main()
.
Shown below are four examples. Your implementation should produce the same paths (though you may get creative with the colors). Note that the cherry and sixth examples are the same as the ones shown earlier int he spec.
The path-finding algorithm that I described earlier in the spec works well for some routes, but not for others. For instance, there might be some more “tricky” routes, where the regular algorithm would get stuck in a dead-end situation. You are only required to get the simple algorithm working, but for extra credit, you can experiment with algorithms of your own (or additions to the base algorithm) that can handle more complex stop sequences.
For instance, the standard algorithm would get stuck in the below gila.txt test case. However, with some modifications using the random module, I am able to find a route (though, it’s not th emost efficient!). You can earn up to 5 bonus points for this, depending on how well your algorithm works.
This PA is due on Tuesday, May 5th, at 7pm. You should turn it in on Gradescope. Remember: there are not going to be autograder test cases, so do the best you can to match the correct behavior described and shown in the spec.