If you happen to get lost, just reload the page, and you’ll be returned to University Hall. Your soon-to-be passengers will also be pseudorandomly repositioned throughout campus.

Above the 2D map is a list of your shuttle’s seats, each of which is initially empty. Above that, in the application’s top-right corner, are two buttons: Pick Up and Drop Off . Neither works yet, but both will before long!

In fact, go ahead and click a few times the minus (−) sign in the top-left corner of the application’s 2D map. You should see more and more red markers as you zoom out, each of which represents a passenger waiting for pickup. If you hover over each marker with your mouse, you’ll see each passenger’s name and origin. The blue bus, of course, represents you! You’re welcome to click and drag the 2D map to see more of campus; as soon as you start driving again, the map will be re-centered around you.

Anyhow, go for a ride! (No bikes in the Yard, but shuttles are okay.) As you approach buildings, you may find that they get prettier and prettier as more satellite imagery is automatically downloaded. See if you can make your way to your own house. (Try not to take any shortcuts through buildings.) Along the way, you’ll likely see some familiar faces. Those will soon be your passengers!

Note that your mouse is not used for driving in this 3D world. In fact, don’t even click on it, else you might take away "focus" from our (and, soon, your) JavaScript code, the result of which is that the shuttle will no longer respond to your keystrokes. If that does happen, simply click Start Engine to give focus back to the code; the shuttle should then respond to your keystrokes again.

Indeed, your shuttle can slide left and right, as though all four wheels can turn 90 degrees. As for looking downward and upward, know that you can look straight ahead down to your shuttle’s toes by holding ↓ for a few seconds, then back up; you can’t look higher than straight ahead. (Sun visor’s in the way.)

Your mission for this problem set is to implement your own shuttle service that picks up passengers all over campus and drops them off at their houses. Your shuttle is already equipped with an engine, a steering wheel, and some seats. Shall we go for a spin? Assuming you’re still at http://w.x.y.z/pset8/ looking at University Hall, here’s how to drive with your keyboard once you’ve clicked Start Engine :

Alright, let’s take a stroll through this problem set’s distribution code. Open up index.html first and read over the lines of HTML within. Notice first how this file references some (local) CSS and JavaScript files in its head as well as the URL of Google’s JavaScript API. Notice how most every one of the div elements in the page’s body is uniquely identified with an id attribute (so that we can stylize it with CSS or access it via JavaScript).

At the moment, the HTML within one of those div elements ( #announcements ) is meant to be temporary. Eventually, there’ll be some announcements, and there will be passengers in seats!

Next open up css/service.css , which stylizes that HTML. You don’t need to understand all of the CSS within, but do know that, in general, something like #foo , refers to the element whose id is foo .

Now take a peek at js/buildings.js . Declared in that file is BUILDINGS , which is an array of objects, each of which represents a building on campus. Associated with each building is a "root" (Harvardspeak for a building’s unique identifier), a name and address, and a pair of coordinates that represents an edge of that building. We could have declared this array in service.js , but because it’s so big, we decided to isolate it in its own file.

Similarly do passengers have their own file. In js/passengers.js is PASSENGERS , another array of objects, each of which this time represents a passenger on campus. Associated with each passenger is a username (i.e., a unique identifier), a name , and a house . Incidentally, each of those usernames maps to a similarly named JPEG in img . Note, though, that some houses comprise multiple buildings, and so even though "Mather House" appears in both js/passengers.js and js/buildings.js , "Quincy House" appears only in passengers.js . In js/buildings.js , meanwhile, are objects for "Quincy House New Residence Hall" , "Quincy House Library" , and (nice and confusingly) "Mather Hall, Quincy House" . And so you will find in houses.js a third (and final!) data structure, this one an object whose keys are houses' names and whose values are objects representing houses' coordinates. And so you can access the best house’s coordinates with something like:

var lat = HOUSES[ " Mather House " ].lat; var lng = HOUSES[ " Mather House " ].lng;

You may assume that the coordinates in js/houses.js are the official coordinates for passengers' destinations. In fact, we’ve already planted yellow markers at those very coordinates on the 2D map to help out the driver. We’ve not bothered planting placemarks at those coordinates on the 3D Earth, since they’re not as easy to spot.

Incidentally, if, during the course of this problem set, you’d like to look up where some building is on campus, feel free to search for it via CS50’s own app:

Now take a peek at js/shuttle.js . This file’s a bit fancy, inasmuch as it effectively implements a data structure called Shuttle . (Although Shuttle behaves like a "class" (if familiar), JavaScript is actually a "prototype-based" language, per http://en.wikipedia.org/wiki/Prototype-based.) You don’t need to understand this file’s entirety, but know that inside of a Shuttle are two properties: position , which encapsulates a shuttle’s position (including its longitude and latitude), and states , which encapsulates a shuttle’s various states.

Okay, now turn your attention to js/service.js , where you’ll do most of your work, though you’re welcome to modify any of this problem set’s files, except for js/math3d.js (which is just a library), js/buildings.js , js/houses.js , and js/passengers.js . Atop js/service.js are a bunch of constants and globals followed by two calls to google.load , which loads the two APIs on which this application relies:

You won’t need to read through the entirety of that documentation; odds are you’ll explore it as needed. But do read the first page or so of each to get a sense of what each API does.

Below those calls to google.load , meanwhile, is some code that will "register" some "event listeners" once a browser has loaded index.html . Also called is load , which is implemented further down in js/service.js . Take a look, and you’ll see that load embeds the 2D map and 3D Earth map in your browser. Next scroll back up to the implementation of initCB ; this function, a "callback," gets called as soon as the Google Earth Plugin has loaded, and so it’s in this function that we finish initializing the app. (If something goes wrong, it’s failureCB , another callback, that’s instead called.) Notice, in particular, that initCB "instantiates" an object, shuttle, of type Shuttle .

Next take a look at the function called keystroke . It’s this function that handles your keystrokes. In response to your keystrokes, this function changes the state of the shuttle simply by updating the appropriate property in shuttle.states with a value of true or false .

Now take a peek at the function called populate . It’s this function that plants friendly faces all over campus. Each face is implemented as a "placemark" on the 3D earth and as a "marker" on the 2D map.