1 00:00:00,000 --> 00:00:09,870 2 00:00:09,870 --> 00:00:13,360 >> ZAMYLA CHAN: Well, here we are, the last p-set in CS50. 3 00:00:13,360 --> 00:00:17,040 Congratulate yourselves from having come so far since your first Hello 4 00:00:17,040 --> 00:00:20,090 Worlds and Printing Up Pyramids for Mario. 5 00:00:20,090 --> 00:00:21,930 You made a website last week. 6 00:00:21,930 --> 00:00:25,110 And we're going to be making another one this week, one that allows you to 7 00:00:25,110 --> 00:00:28,570 drive around the Harvard campus, picking up CS50 staff members and 8 00:00:28,570 --> 00:00:31,910 bringing them back to their residential houses. 9 00:00:31,910 --> 00:00:35,400 >> Now, last week we worked in PHP, a server side language. 10 00:00:35,400 --> 00:00:38,250 For this p-set, we're getting introduced to JavaScript, which is a 11 00:00:38,250 --> 00:00:40,610 client side language. 12 00:00:40,610 --> 00:00:44,020 So let's take a look at some of the distribution code that's provided to 13 00:00:44,020 --> 00:00:46,210 you for this p-set. 14 00:00:46,210 --> 00:00:49,700 In the JavaScript folder, there will be a bunch of JavaScript files. 15 00:00:49,700 --> 00:00:53,600 >> There's buildings.js, which contains an array of buildings around Harvard 16 00:00:53,600 --> 00:00:57,340 campus with their information and position. 17 00:00:57,340 --> 00:01:01,630 Houses.js is an array of Harvard residential houses with their 18 00:01:01,630 --> 00:01:04,030 latitudes and longitudes. 19 00:01:04,030 --> 00:01:08,600 Passengers.js contains an array of passengers, the CS50 staff members 20 00:01:08,600 --> 00:01:11,640 that you'll be bringing back to their residential houses. 21 00:01:11,640 --> 00:01:16,450 >> Math3D.js, that contains a lot of functions to do with the movement. 22 00:01:16,450 --> 00:01:19,500 If you're mathematically minded, then I welcome you to take a look. 23 00:01:19,500 --> 00:01:23,530 But you don't need to understand everything in there. 24 00:01:23,530 --> 00:01:26,710 Shuttle.js, that deals with the Shuttle's movement. 25 00:01:26,710 --> 00:01:31,450 And index.html is the home page where everything happens, really, where the 26 00:01:31,450 --> 00:01:33,610 user is interacting with the site. 27 00:01:33,610 --> 00:01:39,110 >> Service.css is the CSS style sheet, which in addition to the Twitter 28 00:01:39,110 --> 00:01:43,960 Bootstrap Library, controls how index.html looks. 29 00:01:43,960 --> 00:01:48,190 And then we also have service.js, which contains service functions for 30 00:01:48,190 --> 00:01:49,010 the Shuttle. 31 00:01:49,010 --> 00:01:53,010 And here's where you're going to be filling in some of the to-do's. 32 00:01:53,010 --> 00:01:56,600 >> Now let's take a look at objects and associative arrays in JavaScript, 33 00:01:56,600 --> 00:01:59,360 which, for all intents and purposes, are interchangeable. 34 00:01:59,360 --> 00:02:03,030 If I wanted to make an object a variable called a wand, I would 35 00:02:03,030 --> 00:02:04,290 declare it. 36 00:02:04,290 --> 00:02:09,350 And inside those curly braces, I would specify, the core is unicorn, the wood 37 00:02:09,350 --> 00:02:12,710 is cherry, and the length is 13. 38 00:02:12,710 --> 00:02:16,370 >> Now, I can also access values of objects using 39 00:02:16,370 --> 00:02:18,270 associative array notation. 40 00:02:18,270 --> 00:02:22,610 So wand index core, I can set that equal to unicorn, or 41 00:02:22,610 --> 00:02:24,710 check that if I need. 42 00:02:24,710 --> 00:02:28,890 Or I can use the dot operator wand.wood equals cherry, and 43 00:02:28,890 --> 00:02:30,280 so on and so forth. 44 00:02:30,280 --> 00:02:33,930 So you see that associative arrays and objects in JavaScript are going to be 45 00:02:33,930 --> 00:02:37,710 interchangeable, and will come in quite handy. 46 00:02:37,710 --> 00:02:41,570 >> Then we see an array of buildings in buildings.js, 47 00:02:41,570 --> 00:02:43,870 again, an array of objects. 48 00:02:43,870 --> 00:02:48,500 If I wanted to make an array of the best buildings on Harvard campus, then 49 00:02:48,500 --> 00:02:49,710 I would make it as follows. 50 00:02:49,710 --> 00:02:55,250 Using this object notation, where I store the root, name, address, 51 00:02:55,250 --> 00:03:00,260 latitude, and longitude for every single building object. 52 00:03:00,260 --> 00:03:02,930 >> Let's quickly talk about variables in JavaScript. 53 00:03:02,930 --> 00:03:07,760 Like PHP, JavaScript variables are weakly or loosely typed. 54 00:03:07,760 --> 00:03:14,120 To create a local variable, you prefix the variable name with V-A-R, var. 55 00:03:14,120 --> 00:03:17,010 Now, in JavaScript, functions will limit the scope of variables. 56 00:03:17,010 --> 00:03:20,600 So if you have a local variable within a function, then other functions 57 00:03:20,600 --> 00:03:22,060 can't access it. 58 00:03:22,060 --> 00:03:26,090 >> But unlike C, loops and conditions don't limit the scope of a variable. 59 00:03:26,090 --> 00:03:30,600 So even if you declare it inside of a condition, the whole function will 60 00:03:30,600 --> 00:03:32,810 have access to it. 61 00:03:32,810 --> 00:03:35,820 Now, without var, the variable will be global. 62 00:03:35,820 --> 00:03:39,170 So if you just declare the name and assign a value, then that variable 63 00:03:39,170 --> 00:03:41,900 will be a global variable in JavaScript. 64 00:03:41,900 --> 00:03:48,480 >> Now, in houses, we have an associative array of host type objects, where 65 00:03:48,480 --> 00:03:52,100 every house is just a latitude and a longitude. 66 00:03:52,100 --> 00:03:55,140 Then we have the passengers array, which is an array 67 00:03:55,140 --> 00:03:57,370 of object type passenger. 68 00:03:57,370 --> 00:04:01,620 So every passenger has a user name, a name, and a house. 69 00:04:01,620 --> 00:04:04,840 >> Notice that I'm saying of type passenger, which really just means 70 00:04:04,840 --> 00:04:08,150 that every object has the same key value pairs. 71 00:04:08,150 --> 00:04:12,830 So every object of type passenger has a user name, a name, and a house. 72 00:04:12,830 --> 00:04:14,850 So what do we need to do for the p-set? 73 00:04:14,850 --> 00:04:20,779 Well, we need to allow users to pick up staff members, to display all of 74 00:04:20,779 --> 00:04:25,080 the staff members that are currently in our shuttle, and to drop them off. 75 00:04:25,080 --> 00:04:29,395 And then we'll also talk about extra features that can be implemented for 76 00:04:29,395 --> 00:04:30,980 the Shuttle p-set. 77 00:04:30,980 --> 00:04:33,610 >> But let's talk about pickup first. 78 00:04:33,610 --> 00:04:37,480 The faces of CS50 staff have been planted all over campus, where each 79 00:04:37,480 --> 00:04:41,750 face is implemented as a place mark on the 3D Earth, and as a 80 00:04:41,750 --> 00:04:44,020 marker on the 2D map. 81 00:04:44,020 --> 00:04:47,880 So when the user clicks the Pickup button, we want to add nearby 82 00:04:47,880 --> 00:04:49,590 passengers to the shuttle. 83 00:04:49,590 --> 00:04:53,650 And we also want to remove their place mark from the world and remove their 84 00:04:53,650 --> 00:04:58,060 marker from the map, indicating that they're in our shuttle now. 85 00:04:58,060 --> 00:05:02,520 >> So how do we detect if passengers are within range of our shuttle? 86 00:05:02,520 --> 00:05:06,670 Well, the function distance, so shuttle.distance, passing in the 87 00:05:06,670 --> 00:05:10,630 latitude and longitude, will calculate the distance from the current position 88 00:05:10,630 --> 00:05:14,220 of the shuttle to the point that you specify with that given 89 00:05:14,220 --> 00:05:15,860 latitude and longitude. 90 00:05:15,860 --> 00:05:19,180 So you can use this to calculate the distance from the shuttle to the 91 00:05:19,180 --> 00:05:20,310 passengers. 92 00:05:20,310 --> 00:05:24,040 >> But how do you know where the passengers are? 93 00:05:24,040 --> 00:05:27,510 Well, that's where we'll have to edit the populate function. 94 00:05:27,510 --> 00:05:32,500 Populate places all of the staff members in passengers into the world 95 00:05:32,500 --> 00:05:36,300 and into the map, but doesn't store their location. 96 00:05:36,300 --> 00:05:39,850 So perhaps you can store their place marks and markers 97 00:05:39,850 --> 00:05:41,570 in some global array. 98 00:05:41,570 --> 00:05:45,780 >> Now, there already is a global array storing information from passengers. 99 00:05:45,780 --> 00:05:49,960 The passengers array stores each passenger's name and their house. 100 00:05:49,960 --> 00:05:54,985 So maybe you can add a few parameters there to the passenger objects. 101 00:05:54,985 --> 00:05:58,150 >> To help us detect all of the passengers within range of our 102 00:05:58,150 --> 00:06:02,485 shuttle, let's loop through all of the passengers in the passengers array. 103 00:06:02,485 --> 00:06:07,790 A for loop in JavaScript might look something like this, very similar to 104 00:06:07,790 --> 00:06:13,200 those for loops in C. Or we can use an alternative for loop structure, for 105 00:06:13,200 --> 00:06:18,680 var i in array, where i will still be the index, but you don't need to 106 00:06:18,680 --> 00:06:23,310 specify the array.length condition and i++. 107 00:06:23,310 --> 00:06:26,130 >> Every passenger's location is given by their place mark. 108 00:06:26,130 --> 00:06:29,800 But the place mark isn't the latitude and the longitude. 109 00:06:29,800 --> 00:06:34,170 We have to access those parameters by getting the geometry, using get 110 00:06:34,170 --> 00:06:38,180 geometry on the place mark, and then once we have the geometry, getting 111 00:06:38,180 --> 00:06:42,580 either the latitude or the longitude using those functions. 112 00:06:42,580 --> 00:06:45,680 >> So now we know how to detect whether passengers are within 113 00:06:45,680 --> 00:06:47,920 range of our shuttle. 114 00:06:47,920 --> 00:06:52,050 Once we have those passengers, we'll want to add any passengers that are 115 00:06:52,050 --> 00:06:53,140 within that range. 116 00:06:53,140 --> 00:06:57,580 We want to allow them to hop on and take a seat on our shuttle, but only 117 00:06:57,580 --> 00:06:59,630 if we have enough room to them. 118 00:06:59,630 --> 00:07:04,120 >> The shuttle.seats array will indicate whether seats are empty, or 119 00:07:04,120 --> 00:07:05,890 who's in that seat. 120 00:07:05,890 --> 00:07:11,160 So if a seat is empty, then that seat will be null. 121 00:07:11,160 --> 00:07:15,930 So iterate over the seats array, checking for empty seats, storing 122 00:07:15,930 --> 00:07:20,020 passengers into those seats until you don't have any more empty seats. 123 00:07:20,020 --> 00:07:23,330 And unfortunately, any other passengers will have to wait for the 124 00:07:23,330 --> 00:07:26,000 next time the shuttle comes down. 125 00:07:26,000 --> 00:07:30,280 >> Once they get on the shuttle, we'll want to remove their place mark, which 126 00:07:30,280 --> 00:07:32,580 is their photo in the 3D world. 127 00:07:32,580 --> 00:07:38,030 If I wanted to remove a place mark p, then I would get all of the features 128 00:07:38,030 --> 00:07:42,820 from my Earth, from the Google Earth, and then remove that specific place 129 00:07:42,820 --> 00:07:45,910 mark using the removeChild function. 130 00:07:45,910 --> 00:07:51,360 Then lastly, let's remove the marker, the icon on the 2D map, for any 131 00:07:51,360 --> 00:07:53,650 passenger that we are picking up. 132 00:07:53,650 --> 00:07:59,790 >> To remove a marker m, then I'll just execute m.setMap null. 133 00:07:59,790 --> 00:08:03,670 Do this for any passengers within range, and you've finished pickup. 134 00:08:03,670 --> 00:08:07,890 The chart function should display all of the passengers that are in your 135 00:08:07,890 --> 00:08:11,000 shuttle, and empty seat if empty. 136 00:08:11,000 --> 00:08:14,420 So chart should iterate over shuttle.seats, displaying the 137 00:08:14,420 --> 00:08:21,350 passenger information for every index, and empty seat if that index is null. 138 00:08:21,350 --> 00:08:26,160 >> Now if HTML text is put inside of a JavaScript variable, then by using 139 00:08:26,160 --> 00:08:31,950 document.getElementByID, chart can edit the inner HTML of that given 140 00:08:31,950 --> 00:08:36,140 element by assigning the HTML text to the 141 00:08:36,140 --> 00:08:40,840 document.getElementByID inner HTML variable. 142 00:08:40,840 --> 00:08:46,180 When the users click the Drop Off button in index.html, it'll call the 143 00:08:46,180 --> 00:08:47,160 dropoff function. 144 00:08:47,160 --> 00:08:49,510 And it's our job to implement that. 145 00:08:49,510 --> 00:08:54,150 >> In dropoff, we'll want to remove any passengers from the shuttle only if 146 00:08:54,150 --> 00:08:58,740 we're in range of their destination, their residential house. 147 00:08:58,740 --> 00:09:03,300 So dropoff will have to check whether the shuttle is in range of any of the 148 00:09:03,300 --> 00:09:08,200 houses, and remove any needed passengers from the shuttle. 149 00:09:08,200 --> 00:09:11,020 So how do we check if we're in range of any houses? 150 00:09:11,020 --> 00:09:16,630 Well, yet again, we'll make use of the shuttle.distance function, passing in 151 00:09:16,630 --> 00:09:20,990 the latitude and longitude of the point that we're checking against. 152 00:09:20,990 --> 00:09:22,730 >> But what are those points? 153 00:09:22,730 --> 00:09:27,210 Well, the houses array, if you remember in houses.js, stores the 154 00:09:27,210 --> 00:09:32,790 latitude and longitude of each house in an associative array, where every 155 00:09:32,790 --> 00:09:35,980 index is the name of that house. 156 00:09:35,980 --> 00:09:37,590 Then to remove passengers-- 157 00:09:37,590 --> 00:09:41,820 well, only if we're in range of their house that they want to go to. 158 00:09:41,820 --> 00:09:46,380 So again, remember that passengers stores the house that every passenger 159 00:09:46,380 --> 00:09:48,850 wants to go to. 160 00:09:48,850 --> 00:09:51,670 If they are within range of their house, then we'll remove that 161 00:09:51,670 --> 00:09:57,200 passenger from shuttle.seats and set their position in the array to null. 162 00:09:57,200 --> 00:10:00,220 >> Now let's talk about some extra features that can be implemented in 163 00:10:00,220 --> 00:10:02,690 the CS50 Shuttle p-set. 164 00:10:02,690 --> 00:10:05,850 There's a point system whereby you keep track of how many 165 00:10:05,850 --> 00:10:07,520 points a user has. 166 00:10:07,520 --> 00:10:11,120 For dropping off passengers successfully, they can get points. 167 00:10:11,120 --> 00:10:15,100 But for trying to drop off passengers where there isn't any house nearby, 168 00:10:15,100 --> 00:10:16,980 well, they can get penalized for that. 169 00:10:16,980 --> 00:10:21,790 So perhaps you want to keep track of the points in a global variable. 170 00:10:21,790 --> 00:10:25,970 >> You can implement perhaps a timer, where the user has a certain amount of 171 00:10:25,970 --> 00:10:29,800 time to pick up and drop off a certain number of passengers. 172 00:10:29,800 --> 00:10:33,280 Maybe even integrate this with the point system. 173 00:10:33,280 --> 00:10:39,970 Or you can Edit Chart such that passengers are sorted by house. 174 00:10:39,970 --> 00:10:45,250 So that would probably be a sort function to shuttle.seats. 175 00:10:45,250 --> 00:10:49,240 >> You can implement a flying feature, where if the user inputs the Konami 176 00:10:49,240 --> 00:10:53,460 code, then the shuttle lifts off the ground and the shuttle can fly. 177 00:10:53,460 --> 00:10:58,890 But for a safe drop off, best to make the shuttle land its wheels on the 178 00:10:58,890 --> 00:11:00,700 ground first. 179 00:11:00,700 --> 00:11:05,910 You can also implement teleportation, where you make a drop down list of 180 00:11:05,910 --> 00:11:08,380 buildings in index.html. 181 00:11:08,380 --> 00:11:12,270 And selecting one of those, the user will be transported to 182 00:11:12,270 --> 00:11:14,220 that building on campus. 183 00:11:14,220 --> 00:11:16,760 OK, though, to travel through the walls of some 184 00:11:16,760 --> 00:11:19,290 buildings on your way there. 185 00:11:19,290 --> 00:11:22,960 >> You can also change the speed of the shuttle, allowing the user to increase 186 00:11:22,960 --> 00:11:25,490 or decrease the speed. 187 00:11:25,490 --> 00:11:28,840 Perhaps you want a global variable to keep track of how much fuel the 188 00:11:28,840 --> 00:11:31,520 shuttle has, decreasing it as you go along. 189 00:11:31,520 --> 00:11:35,860 Once you hit zero, though, the shuttle won't be able to move unless you've 190 00:11:35,860 --> 00:11:40,610 refueled, perhaps using a button, or even make your own gas station. 191 00:11:40,610 --> 00:11:43,240 >> But that certainly isn't an exhaustive list. 192 00:11:43,240 --> 00:11:46,340 Check out the spec for the full list, or perhaps propose 193 00:11:46,340 --> 00:11:47,840 your own to your TF. 194 00:11:47,840 --> 00:11:48,950 The sky is the limit. 195 00:11:48,950 --> 00:11:53,110 This is your last CS50 p-set, so have fun with it. 196 00:11:53,110 --> 00:11:56,360 This was CS50 Shuttle. 197 00:11:56,360 --> 00:11:59,230 >> I've got to say, it's been a pleasure making these for you with the 198 00:11:59,230 --> 00:12:00,400 production team. 199 00:12:00,400 --> 00:12:04,330 And I hope that you've enjoy them, as well. 200 00:12:04,330 --> 00:12:06,040 My name is Zamyla. 201 00:12:06,040 --> 00:12:08,310 And this was CS50. 202 00:12:08,310 --> 00:12:16,363