>> ZAMYLA CHAN: Well, here we are, the last p-set in CS50.
Congratulate yourselves from having come so far since your first Hello
Worlds and Printing Up Pyramids for Mario.
You made a website last week.
And we're going to be making another one this week, one that allows you to
drive around the Harvard campus, picking up CS50 staff members and
bringing them back to their residential houses.
>> Now, last week we worked in PHP, a server side language.
For this p-set, we're getting introduced to JavaScript, which is a
client side language.
So let's take a look at some of the distribution code that's provided to
you for this p-set.
In the JavaScript folder, there will be a bunch of JavaScript files.
>> There's buildings.js, which contains an array of buildings around Harvard
campus with their information and position.
Houses.js is an array of Harvard residential houses with their
latitudes and longitudes.
Passengers.js contains an array of passengers, the CS50 staff members
that you'll be bringing back to their residential houses.
>> Math3D.js, that contains a lot of functions to do with the movement.
If you're mathematically minded, then I welcome you to take a look.
But you don't need to understand everything in there.
Shuttle.js, that deals with the Shuttle's movement.
And index.html is the home page where everything happens, really, where the
user is interacting with the site.
>> Service.css is the CSS style sheet, which in addition to the Twitter
Bootstrap Library, controls how index.html looks.
And then we also have service.js, which contains service functions for
the Shuttle.
And here's where you're going to be filling in some of the to-do's.
>> Now let's take a look at objects and associative arrays in JavaScript,
which, for all intents and purposes, are interchangeable.
If I wanted to make an object a variable called a wand, I would
declare it.
And inside those curly braces, I would specify, the core is unicorn, the wood
is cherry, and the length is 13.
>> Now, I can also access values of objects using
associative array notation.
So wand index core, I can set that equal to unicorn, or
check that if I need.
Or I can use the dot operator wand.wood equals cherry, and
so on and so forth.
So you see that associative arrays and objects in JavaScript are going to be
interchangeable, and will come in quite handy.
>> Then we see an array of buildings in buildings.js,
again, an array of objects.
If I wanted to make an array of the best buildings on Harvard campus, then
I would make it as follows.
Using this object notation, where I store the root, name, address,
latitude, and longitude for every single building object.
>> Let's quickly talk about variables in JavaScript.
Like PHP, JavaScript variables are weakly or loosely typed.
To create a local variable, you prefix the variable name with V-A-R, var.
Now, in JavaScript, functions will limit the scope of variables.
So if you have a local variable within a function, then other functions
can't access it.
>> But unlike C, loops and conditions don't limit the scope of a variable.
So even if you declare it inside of a condition, the whole function will
have access to it.
Now, without var, the variable will be global.
So if you just declare the name and assign a value, then that variable
will be a global variable in JavaScript.
>> Now, in houses, we have an associative array of host type objects, where
every house is just a latitude and a longitude.
Then we have the passengers array, which is an array
of object type passenger.
So every passenger has a user name, a name, and a house.
>> Notice that I'm saying of type passenger, which really just means
that every object has the same key value pairs.
So every object of type passenger has a user name, a name, and a house.
So what do we need to do for the p-set?
Well, we need to allow users to pick up staff members, to display all of
the staff members that are currently in our shuttle, and to drop them off.
And then we'll also talk about extra features that can be implemented for
the Shuttle p-set.
>> But let's talk about pickup first.
The faces of CS50 staff have been planted all over campus, where each
face is implemented as a place mark on the 3D Earth, and as a
marker on the 2D map.
So when the user clicks the Pickup button, we want to add nearby
passengers to the shuttle.
And we also want to remove their place mark from the world and remove their
marker from the map, indicating that they're in our shuttle now.
>> So how do we detect if passengers are within range of our shuttle?
Well, the function distance, so shuttle.distance, passing in the
latitude and longitude, will calculate the distance from the current position
of the shuttle to the point that you specify with that given
latitude and longitude.
So you can use this to calculate the distance from the shuttle to the
passengers.
>> But how do you know where the passengers are?
Well, that's where we'll have to edit the populate function.
Populate places all of the staff members in passengers into the world
and into the map, but doesn't store their location.
So perhaps you can store their place marks and markers
in some global array.
>> Now, there already is a global array storing information from passengers.
The passengers array stores each passenger's name and their house.
So maybe you can add a few parameters there to the passenger objects.
>> To help us detect all of the passengers within range of our
shuttle, let's loop through all of the passengers in the passengers array.
A for loop in JavaScript might look something like this, very similar to
those for loops in C. Or we can use an alternative for loop structure, for
var i in array, where i will still be the index, but you don't need to
specify the array.length condition and i++.
>> Every passenger's location is given by their place mark.
But the place mark isn't the latitude and the longitude.
We have to access those parameters by getting the geometry, using get
geometry on the place mark, and then once we have the geometry, getting
either the latitude or the longitude using those functions.
>> So now we know how to detect whether passengers are within
range of our shuttle.
Once we have those passengers, we'll want to add any passengers that are
within that range.
We want to allow them to hop on and take a seat on our shuttle, but only
if we have enough room to them.
>> The shuttle.seats array will indicate whether seats are empty, or
who's in that seat.
So if a seat is empty, then that seat will be null.
So iterate over the seats array, checking for empty seats, storing
passengers into those seats until you don't have any more empty seats.
And unfortunately, any other passengers will have to wait for the
next time the shuttle comes down.
>> Once they get on the shuttle, we'll want to remove their place mark, which
is their photo in the 3D world.
If I wanted to remove a place mark p, then I would get all of the features
from my Earth, from the Google Earth, and then remove that specific place
mark using the removeChild function.
Then lastly, let's remove the marker, the icon on the 2D map, for any
passenger that we are picking up.
>> To remove a marker m, then I'll just execute m.setMap null.
Do this for any passengers within range, and you've finished pickup.
The chart function should display all of the passengers that are in your
shuttle, and empty seat if empty.
So chart should iterate over shuttle.seats, displaying the
passenger information for every index, and empty seat if that index is null.
>> Now if HTML text is put inside of a JavaScript variable, then by using
document.getElementByID, chart can edit the inner HTML of that given
element by assigning the HTML text to the
document.getElementByID inner HTML variable.
When the users click the Drop Off button in index.html, it'll call the
dropoff function.
And it's our job to implement that.
>> In dropoff, we'll want to remove any passengers from the shuttle only if
we're in range of their destination, their residential house.
So dropoff will have to check whether the shuttle is in range of any of the
houses, and remove any needed passengers from the shuttle.
So how do we check if we're in range of any houses?
Well, yet again, we'll make use of the shuttle.distance function, passing in
the latitude and longitude of the point that we're checking against.
>> But what are those points?
Well, the houses array, if you remember in houses.js, stores the
latitude and longitude of each house in an associative array, where every
index is the name of that house.
Then to remove passengers--
well, only if we're in range of their house that they want to go to.
So again, remember that passengers stores the house that every passenger
wants to go to.
If they are within range of their house, then we'll remove that
passenger from shuttle.seats and set their position in the array to null.
>> Now let's talk about some extra features that can be implemented in
the CS50 Shuttle p-set.
There's a point system whereby you keep track of how many
points a user has.
For dropping off passengers successfully, they can get points.
But for trying to drop off passengers where there isn't any house nearby,
well, they can get penalized for that.
So perhaps you want to keep track of the points in a global variable.
>> You can implement perhaps a timer, where the user has a certain amount of
time to pick up and drop off a certain number of passengers.
Maybe even integrate this with the point system.
Or you can Edit Chart such that passengers are sorted by house.
So that would probably be a sort function to shuttle.seats.
>> You can implement a flying feature, where if the user inputs the Konami
code, then the shuttle lifts off the ground and the shuttle can fly.
But for a safe drop off, best to make the shuttle land its wheels on the
ground first.
You can also implement teleportation, where you make a drop down list of
buildings in index.html.
And selecting one of those, the user will be transported to
that building on campus.
OK, though, to travel through the walls of some
buildings on your way there.
>> You can also change the speed of the shuttle, allowing the user to increase
or decrease the speed.
Perhaps you want a global variable to keep track of how much fuel the
shuttle has, decreasing it as you go along.
Once you hit zero, though, the shuttle won't be able to move unless you've
refueled, perhaps using a button, or even make your own gas station.
>> But that certainly isn't an exhaustive list.
Check out the spec for the full list, or perhaps propose
your own to your TF.
The sky is the limit.
This is your last CS50 p-set, so have fun with it.
This was CS50 Shuttle.
>> I've got to say, it's been a pleasure making these for you with the
production team.
And I hope that you've enjoy them, as well.
My name is Zamyla.
And this was CS50.