1 00:00:00,506 --> 00:00:09,486 [ Silence ] 2 00:00:09,986 --> 00:00:13,796 >> Alright everybody, welcome to the walkthrough for Pset 4 3 00:00:14,026 --> 00:00:17,136 or sudoku which is a very, very fun Pset. 4 00:00:17,386 --> 00:00:18,856 On case interview, we're wondering 5 00:00:18,856 --> 00:00:19,966 if the musical is beforehand. 6 00:00:20,346 --> 00:00:22,896 If you recognized it, then you are as nerdy as I am 7 00:00:22,896 --> 00:00:26,136 because that was in fact Dubstep remixes of video game songs. 8 00:00:26,746 --> 00:00:28,906 So yeah, awesome! 9 00:00:29,426 --> 00:00:32,916 So today I will first be going over the distribution code 10 00:00:32,916 --> 00:00:34,376 which a lot-- there's a lot of it 11 00:00:34,376 --> 00:00:35,876 so I'm hoping not to overwhelm you. 12 00:00:35,876 --> 00:00:38,526 And then each of the things you have to do a sudoku, 13 00:00:38,526 --> 00:00:40,786 so how to move the cursor around, how to input numbers, 14 00:00:40,786 --> 00:00:43,206 blanks, make sure the users are allowed to do that 15 00:00:43,206 --> 00:00:45,376 and then checking if the board has been won. 16 00:00:45,656 --> 00:00:49,676 So just a reminder, it mentions this in the Pset spec. 17 00:00:49,906 --> 00:00:51,186 But if you're used to using gedit 18 00:00:51,186 --> 00:00:53,306 and the little terminal window below gedit to run 19 00:00:53,306 --> 00:00:55,556 and compile your programs you probably don't wanna do 20 00:00:55,556 --> 00:00:58,596 that with sudoku just because the board takes up more pixels 21 00:00:58,596 --> 00:01:00,586 than that little terminal window is gonna allow, 22 00:01:00,796 --> 00:01:03,136 unless you stretch it up so high you're editing one line of code 23 00:01:03,136 --> 00:01:05,566 at a time which is good for procrastination 24 00:01:05,566 --> 00:01:08,366 but it's not that productive. 25 00:01:08,366 --> 00:01:11,546 So just a recap of the basic rules of sudoku, 26 00:01:11,546 --> 00:01:13,036 you wanna have one number 27 00:01:13,206 --> 00:01:14,876 in every single square on the board. 28 00:01:14,876 --> 00:01:16,856 So it's 9 by 9, there are 81 squares, 29 00:01:17,446 --> 00:01:20,306 so in every row there needs to be one of each number, 30 00:01:20,546 --> 00:01:22,436 so the numbers 1 through 9, no duplicates, 31 00:01:22,766 --> 00:01:24,086 same thing for every column. 32 00:01:24,286 --> 00:01:29,146 And then this 9 by 9 board is divided into nine 3 by 3 squares 33 00:01:29,646 --> 00:01:32,006 and you wanna have one of those numbers in each 34 00:01:32,006 --> 00:01:33,926 of those 3 by 3 squares. 35 00:01:34,246 --> 00:01:37,136 So let's just go through the distribution code, 36 00:01:37,136 --> 00:01:39,666 so there is a lot like 600 lines-ish but that's not 37 00:01:39,666 --> 00:01:41,186 so scary 'cause we'll go through all of it right now. 38 00:01:41,186 --> 00:01:43,786 So it's not scary I promise. 39 00:01:44,366 --> 00:01:46,716 So first inside of Main, it does things that, you know, 40 00:01:46,716 --> 00:01:49,126 you're used to Main doing for you kind of what happened 41 00:01:49,126 --> 00:01:51,946 in 15.C. We just did some things like [inaudible] the board, 42 00:01:51,946 --> 00:01:53,316 doing some error checking. 43 00:01:53,566 --> 00:01:55,756 And then it's also gonna have this Main game loop 44 00:01:55,756 --> 00:01:57,756 where it's gonna be asking you for some input 45 00:01:57,896 --> 00:01:59,206 and you're gonna respond to that input. 46 00:01:59,206 --> 00:02:01,746 So you don't have to worry about any of those things. 47 00:02:02,376 --> 00:02:05,366 There's also a new construction in C 48 00:02:05,366 --> 00:02:06,426 that we're seeing in this Pset. 49 00:02:06,426 --> 00:02:08,196 It's called the case switch statement. 50 00:02:08,846 --> 00:02:10,846 So a lot of times in C you'll see something like this. 51 00:02:11,166 --> 00:02:12,366 If, you know, this something-- 52 00:02:12,366 --> 00:02:13,886 this letter is an A then do something, 53 00:02:13,886 --> 00:02:15,246 if it's a B then do something else, 54 00:02:15,246 --> 00:02:16,376 if it's a C then do something else. 55 00:02:16,376 --> 00:02:18,136 And this can get kind of annoying to type, 56 00:02:18,136 --> 00:02:19,876 it's kind of more words than it needs to be. 57 00:02:19,876 --> 00:02:22,106 So kind of an easier reading compressed way 58 00:02:22,106 --> 00:02:24,426 of writing this is a case switch statement. 59 00:02:24,676 --> 00:02:27,276 So your first block here switch and then some variable. 60 00:02:27,276 --> 00:02:29,206 And this is the variable that was being used 61 00:02:29,206 --> 00:02:30,966 in every single one of these if else if, 62 00:02:31,046 --> 00:02:33,356 so it' kind of redundant to have to keep typing that variable. 63 00:02:34,086 --> 00:02:37,706 So now you're gonna say, if C is the letter A, so in the case, 64 00:02:37,836 --> 00:02:39,816 that is an A then there is a colon there 65 00:02:39,816 --> 00:02:41,746 and then you could have all of your statements. 66 00:02:41,746 --> 00:02:42,896 You can have if statements in there, 67 00:02:42,896 --> 00:02:43,966 printfs whatever you want. 68 00:02:44,516 --> 00:02:46,616 And then once you're done, you're gonna say break. 69 00:02:46,706 --> 00:02:49,706 So that keyword is also used to do something like break 70 00:02:49,706 --> 00:02:51,236 out of a while loop or a for loop. 71 00:02:51,386 --> 00:02:53,116 In the case switch statement, it's the same word 72 00:02:53,116 --> 00:02:56,136 and that means that this is the end of the case A 73 00:02:56,816 --> 00:02:58,746 and now we can move on to the case that it's a B 74 00:02:58,876 --> 00:03:01,466 and do something else and break and then so on and so forth. 75 00:03:01,466 --> 00:03:04,926 So one thing to note is that everything after these cases has 76 00:03:04,976 --> 00:03:07,996 to be integers, so you notice that I have chars here, 77 00:03:07,996 --> 00:03:08,986 chars they're just integers, right? 78 00:03:09,106 --> 00:03:11,476 Because they're just gonna be immediately converted 79 00:03:11,476 --> 00:03:13,176 to their ASCII value which is an integer, 80 00:03:13,176 --> 00:03:14,806 so I can't do something like a string here. 81 00:03:15,236 --> 00:03:18,626 Only numbers but that's so common in C that we decided 82 00:03:18,626 --> 00:03:20,286 to introduce a new construction for it. 83 00:03:20,936 --> 00:03:22,186 So questions on case switch? 84 00:03:22,666 --> 00:03:22,926 Yup? 85 00:03:23,216 --> 00:03:25,646 >> You know how you had it set to C equals A 86 00:03:25,646 --> 00:03:28,176 and you have an operation like a C is less than A or greater 87 00:03:28,176 --> 00:03:29,336 than A or something like that? 88 00:03:29,466 --> 00:03:31,686 >> So, in the case switch segment, 89 00:03:31,686 --> 00:03:33,206 you can only do equality. 90 00:03:33,966 --> 00:03:36,996 So with the, if and else if you can do things like an and or 91 00:03:36,996 --> 00:03:39,306 and less than and all that but case switch statement is 92 00:03:39,306 --> 00:03:41,596 so simple that it's really just equality. 93 00:03:42,046 --> 00:03:43,456 Believe it or not this is pretty common thing 94 00:03:43,456 --> 00:03:45,706 that you're gonna need to do in C, yup? 95 00:03:46,716 --> 00:03:50,666 >> Can you have more than one line of code in these cases? 96 00:03:51,016 --> 00:03:52,646 >> So can you have more than one line of code 97 00:03:52,646 --> 00:03:53,436 in each of these cases? 98 00:03:53,436 --> 00:03:56,296 Yes. It's only gonna stop as soon as you hit that break. 99 00:03:56,646 --> 00:03:58,686 So this do something could be a hundred lines of code, 100 00:03:58,686 --> 00:03:59,426 you probably don't want it 101 00:03:59,426 --> 00:04:01,076 to be 'cause that's not the best design in the world 102 00:04:01,176 --> 00:04:03,486 but you can keep going until this break statement. 103 00:04:04,266 --> 00:04:06,006 We'll take a look at how we use case switch 104 00:04:06,006 --> 00:04:07,196 in Main already, yup? 105 00:04:07,386 --> 00:04:08,786 >> How do you-- how do you handle the else cases? 106 00:04:08,786 --> 00:04:10,686 >> So how do you handle the else cases? 107 00:04:10,686 --> 00:04:12,876 So we'll take a look at that later, 108 00:04:12,876 --> 00:04:14,986 but there's basically a special case that says 109 00:04:14,986 --> 00:04:15,796 if none of these are true. 110 00:04:15,796 --> 00:04:18,066 So that's effectively our umbrella else. 111 00:04:19,246 --> 00:04:20,116 Another question over here? 112 00:04:21,026 --> 00:04:21,186 Yup? 113 00:04:21,796 --> 00:04:24,306 >> Are there curly braces for each case 114 00:04:24,496 --> 00:04:24,966 or will it [inaudible]? 115 00:04:25,346 --> 00:04:27,236 >> So that's a good question, 116 00:04:27,236 --> 00:04:28,936 are there curly braces for each case? 117 00:04:28,936 --> 00:04:31,166 So there are curly braces around the switch 118 00:04:31,166 --> 00:04:34,686 and this is definitely not like what we've seen in C before. 119 00:04:35,106 --> 00:04:37,636 So instead of curly braces you're gonna have this colon 120 00:04:37,836 --> 00:04:39,736 after the case and then you're kind 121 00:04:39,736 --> 00:04:41,616 of end curly brace is the break statement. 122 00:04:42,046 --> 00:04:43,406 So everything between a colon 123 00:04:43,406 --> 00:04:45,976 and a break is what you're gonna do in each of the cases. 124 00:04:46,516 --> 00:04:49,016 But the switch itself is enclosed in curly braces. 125 00:04:50,056 --> 00:04:52,236 So definite a little bit unlike what we've seen before, 126 00:04:52,236 --> 00:04:57,196 but it's a little bit easier to read and shorter to type. 127 00:04:57,926 --> 00:05:00,286 Other questions? 128 00:05:00,286 --> 00:05:05,066 Okay, so also written for you is this global structure. 129 00:05:05,456 --> 00:05:08,376 So in our game of 15 we had one global array 130 00:05:08,406 --> 00:05:09,926 and that just represented the board. 131 00:05:10,646 --> 00:05:13,286 Now in sudoku we could do something like that 132 00:05:13,736 --> 00:05:15,686 but we also need to keep track of some other things. 133 00:05:15,946 --> 00:05:18,336 In the game of 15, we kind of just had one board, right? 134 00:05:18,336 --> 00:05:21,646 If you typed in 15-4, you're always gonna get the same board. 135 00:05:21,996 --> 00:05:22,976 In sudoku on the other hand, 136 00:05:22,976 --> 00:05:24,656 we have a whole bunch of boards for you. 137 00:05:24,986 --> 00:05:26,476 So something like, what board am I on, 138 00:05:26,516 --> 00:05:27,656 is something you need to keep track of. 139 00:05:28,016 --> 00:05:29,386 We also need to keep track of something like, 140 00:05:29,616 --> 00:05:30,806 where is my cursor, right? 141 00:05:30,806 --> 00:05:33,066 I can move the cursor around the board and it's gonna change X 142 00:05:33,066 --> 00:05:34,686 and Y coordinates and I need to be able 143 00:05:34,686 --> 00:05:35,876 to keep track of that somewhere. 144 00:05:36,266 --> 00:05:38,636 So we could have created a bunch of global variables 145 00:05:38,636 --> 00:05:40,736 and just put all those things as a separate variable. 146 00:05:40,836 --> 00:05:43,286 But what we consider a better design is 147 00:05:43,286 --> 00:05:44,756 to use something called a struct. 148 00:05:45,756 --> 00:05:48,556 And a struct is basically a container 149 00:05:48,716 --> 00:05:49,806 for a group of variables. 150 00:05:50,396 --> 00:05:53,386 So G, this global variable G is a struct. 151 00:05:53,626 --> 00:05:56,706 Meaning inside of G, I have a bunch of different variables. 152 00:05:57,106 --> 00:05:59,516 Now, unlike arrays in which everything in my array has 153 00:05:59,516 --> 00:06:02,876 to be the same type, if I say int A it's gonna have all ints. 154 00:06:03,096 --> 00:06:05,806 Inside of a struct, I can have a bunch of different types 155 00:06:06,086 --> 00:06:07,516 which I happen to have in this struct. 156 00:06:07,516 --> 00:06:09,176 I have a couple of ints, I have an array 157 00:06:09,176 --> 00:06:10,916 of ints, maybe a string. 158 00:06:11,716 --> 00:06:14,606 So inside of G, there are a few pertinent ones, 159 00:06:15,046 --> 00:06:18,446 so Y and X are gonna be the row and the column of the cursor. 160 00:06:18,866 --> 00:06:20,556 So, unlike the game of 15 where we just say, 161 00:06:20,556 --> 00:06:21,676 "What number do you wanna move?" 162 00:06:21,906 --> 00:06:24,896 In sudoku we're gonna allow the user to move their cursor around 163 00:06:25,106 --> 00:06:26,916 and then type a number, and then wherever the cursor is, 164 00:06:26,916 --> 00:06:29,126 that's where the number is gonna go. 165 00:06:29,126 --> 00:06:31,236 So we also have to represent the board somewhere, 166 00:06:31,426 --> 00:06:32,976 so just like in the game of 15, 167 00:06:33,126 --> 00:06:34,676 our board is a two-dimensional array. 168 00:06:35,146 --> 00:06:36,686 So, it's gonna work exactly the same 169 00:06:36,686 --> 00:06:37,976 as it did in the game of 15. 170 00:06:38,986 --> 00:06:42,256 We also have the top left coordinates of the board, 171 00:06:42,336 --> 00:06:44,256 which we'll get into and then the number, 172 00:06:44,256 --> 00:06:45,896 just what game will I play in right now? 173 00:06:46,276 --> 00:06:48,546 So if your implementation works on every number except 1, 174 00:06:48,816 --> 00:06:50,226 you can find out where it's not working on, 175 00:06:50,226 --> 00:06:51,236 but hopefully that doesn't happen. 176 00:06:52,446 --> 00:06:53,556 So some other pertinent functions, 177 00:06:53,556 --> 00:06:54,626 we'll also take a look at detail. 178 00:06:54,996 --> 00:06:58,906 This restart game, so this is going to start a new game 179 00:06:59,316 --> 00:07:01,896 but restart might be a little bit of a misnomer 180 00:07:01,896 --> 00:07:04,506 because it's going to start the game that's based 181 00:07:04,506 --> 00:07:07,326 on whatever board is specified in the G dot number. 182 00:07:08,086 --> 00:07:09,336 So if I changed that struct, 183 00:07:09,566 --> 00:07:12,546 to say I want a different board now, then call restart game, 184 00:07:12,546 --> 00:07:14,056 it's not gonna reload the same board 185 00:07:14,056 --> 00:07:16,426 but it's gonna load whatever board is specified 186 00:07:16,476 --> 00:07:17,736 in that global struct. 187 00:07:17,736 --> 00:07:20,346 So we also have these four drawing functions, 188 00:07:20,346 --> 00:07:22,966 and these handle drawing different parts of the board. 189 00:07:22,966 --> 00:07:25,636 So the borders handles like the plus and the pipes 190 00:07:25,636 --> 00:07:27,106 and the minus signs and make it look pretty. 191 00:07:27,626 --> 00:07:31,936 The grid logo numbers, they're kind of self explanatory here. 192 00:07:32,856 --> 00:07:36,766 So we also have this show cursor function which we'll take a look 193 00:07:36,766 --> 00:07:38,766 at and basically what that's gonna do is it's gonna set the 194 00:07:38,766 --> 00:07:41,616 position of the cursor to somewhere in the board based 195 00:07:41,616 --> 00:07:43,736 on what you set at the cursor location 196 00:07:43,736 --> 00:07:45,036 in terms of row and column. 197 00:07:45,156 --> 00:07:48,196 You can also show a message to the user with show banner. 198 00:07:48,566 --> 00:07:49,546 This is gonna take a string 199 00:07:49,546 --> 00:07:51,606 and it's gonna display whatever message you send it. 200 00:07:51,606 --> 00:07:53,736 Now if you don't wanna display that message anymore, 201 00:07:53,936 --> 00:07:56,586 you could just hide it with hide banner. 202 00:07:56,956 --> 00:07:59,086 So let's take a look at this actual distribution code. 203 00:07:59,966 --> 00:08:03,486 So, up here, we are first including the sudoku.hfile, 204 00:08:03,916 --> 00:08:07,826 so inside of that we don't have any definitions of things, 205 00:08:07,826 --> 00:08:11,076 but if we open up sudoku.h, 206 00:08:11,616 --> 00:08:15,246 so we just have some defined statements. 207 00:08:15,246 --> 00:08:17,316 So-- you know, the colors we're using, 208 00:08:17,316 --> 00:08:21,706 you might wanna change something like author, hypothetically, 209 00:08:21,706 --> 00:08:24,496 and then just down here we're setting up, you know, 210 00:08:24,496 --> 00:08:25,556 what colors are gonna be used. 211 00:08:25,556 --> 00:08:26,696 So we don't have to keep typing 212 00:08:26,696 --> 00:08:29,096 in whatever numbers these actually represent. 213 00:08:30,216 --> 00:08:32,336 So now, we're including a bunch of library functions, 214 00:08:32,636 --> 00:08:35,376 one of which is this new one called ncurses 215 00:08:35,376 --> 00:08:37,656 which we'll take a look at a lot-- 216 00:08:37,656 --> 00:08:39,216 take a look at in more detail shortly. 217 00:08:39,776 --> 00:08:42,216 So now we're doing this super fancy defined statement, 218 00:08:42,216 --> 00:08:44,046 you don't have to worry about what the heck all that means. 219 00:08:44,286 --> 00:08:45,096 That's in a few weeks. 220 00:08:46,486 --> 00:08:48,336 And so now, here is this global struct, 221 00:08:49,096 --> 00:08:51,736 so we have the current level, the board's number, 222 00:08:51,736 --> 00:08:52,916 and here's that int board. 223 00:08:52,916 --> 00:08:55,576 So notice again it's just 9 by 9, it's a fixed size 224 00:08:55,576 --> 00:08:57,476 and this is just a two-dimensional array, 225 00:08:57,626 --> 00:08:59,316 so a grid of what our board is gonna be. 226 00:09:00,036 --> 00:09:01,576 So, let's jump down into Main. 227 00:09:01,926 --> 00:09:04,746 So here's all of our prototypes, so incase you need to remember, 228 00:09:04,746 --> 00:09:07,486 oh like is there a functions in sudoku that already exists 229 00:09:07,486 --> 00:09:08,576 or do I have to write this again? 230 00:09:08,576 --> 00:09:10,996 You might just wanna flip up to this prototype sections instead 231 00:09:10,996 --> 00:09:13,286 of going through all 600 lines of code. 232 00:09:13,286 --> 00:09:15,226 So this is just a handy-- every function we've written 233 00:09:15,226 --> 00:09:17,036 for you is listed right here. 234 00:09:18,056 --> 00:09:22,326 So here we go, so once again, just a lot of our C checking, 235 00:09:22,326 --> 00:09:24,996 the user supply the right amount of arguments, whatever, 236 00:09:25,396 --> 00:09:26,916 figure out what kind of board they wanted, 237 00:09:26,916 --> 00:09:28,306 in this case there are three levels, 238 00:09:28,636 --> 00:09:31,246 debug which is a pretty much solve board, 239 00:09:31,246 --> 00:09:33,126 [inaudible] which is kind of an easy board to solve, 240 00:09:33,126 --> 00:09:34,966 and then Leap [phonetic] which is the hardest board to solve, 241 00:09:35,276 --> 00:09:36,926 not the hardest but among the hardest, 242 00:09:37,976 --> 00:09:41,176 so again just error checking, don't have to worry about that. 243 00:09:41,176 --> 00:09:47,176 So now, what we need to do is, again, just board loading, 244 00:09:47,176 --> 00:09:50,286 nothing fancy, so this is if the user says what board they want 245 00:09:50,286 --> 00:09:52,626 and down here, well they didn't say what board we want then 246 00:09:52,626 --> 00:09:53,976 we're just gonna pick one randomly, yup? 247 00:09:53,976 --> 00:09:58,606 >> I have a question about the code that was a few lines up? 248 00:09:58,606 --> 00:09:58,706 >> Sure. 249 00:09:59,046 --> 00:10:01,826 >> It says ampersand G number ampersand C, 250 00:10:02,696 --> 00:10:03,976 I don't understand why-- why it's doing that. 251 00:10:04,666 --> 00:10:07,996 >> Sure, so what is this sscanf thing? 252 00:10:08,366 --> 00:10:10,566 So this is something that were actually used 253 00:10:10,566 --> 00:10:13,046 in GetInt or GetString. 254 00:10:13,046 --> 00:10:16,556 We're using this sscanf function and what this does is gonna say 255 00:10:16,636 --> 00:10:17,886 "I wanna take some string". 256 00:10:17,886 --> 00:10:21,786 In this case the string I'm looking at is rgv2. 257 00:10:22,536 --> 00:10:25,726 Now I wanna look for a number and a character 258 00:10:25,726 --> 00:10:30,286 and I'm gonna save those in G dot number and G dot character. 259 00:10:30,486 --> 00:10:31,966 So once this scanf is done, 260 00:10:32,306 --> 00:10:35,596 those two variables are gonna contain whatever this percent D 261 00:10:35,596 --> 00:10:36,846 and percent C turned out to be. 262 00:10:36,846 --> 00:10:38,126 So it's kind of the backwards of printf. 263 00:10:38,566 --> 00:10:40,316 In printf we said here's a percent D, 264 00:10:40,486 --> 00:10:42,946 I want you to substitute what I tell you 265 00:10:42,946 --> 00:10:45,146 for percent D. This is kind of the other way around. 266 00:10:45,146 --> 00:10:47,396 This is saying "Okay, I have some string and I wanna look 267 00:10:47,396 --> 00:10:50,336 for that first match in percent D. I'm gonna save it 268 00:10:50,336 --> 00:10:51,176 in G dot number." 269 00:10:51,586 --> 00:10:52,746 Same thing for this character 270 00:10:52,746 --> 00:10:54,366 so why do we keep looking for this character? 271 00:10:55,056 --> 00:10:56,686 Well this is kind of a cool little trick 272 00:10:56,906 --> 00:10:58,266 to make sure that it's a number. 273 00:10:58,786 --> 00:10:59,966 So if this is a number, 274 00:10:59,966 --> 00:11:01,946 then only that percent D is gonna filled. 275 00:11:02,516 --> 00:11:04,336 Five anything after it and that's gonna trigger 276 00:11:04,336 --> 00:11:08,646 that percent C. Now what sscanf returns is the number 277 00:11:08,646 --> 00:11:10,416 of things that were read in. 278 00:11:10,416 --> 00:11:13,136 So the only way to make sure that I know 279 00:11:13,136 --> 00:11:16,856 that this is a number is for only one of percent D, 280 00:11:16,856 --> 00:11:18,826 percent D to be filled-- and percent-- 281 00:11:18,956 --> 00:11:21,896 percent D, present C. So percent D is always gonna be filled 282 00:11:21,896 --> 00:11:24,656 first and if only that was red that means I typed in a number 283 00:11:24,656 --> 00:11:26,636 and there's nothing after it, like there's no decimal, 284 00:11:26,636 --> 00:11:29,076 there's no letter I have to have typed a number. 285 00:11:29,886 --> 00:11:32,516 So that s just a fancy way of checking like we do in GetInt 286 00:11:32,926 --> 00:11:35,246 to make sure that the user actually typed in a number. 287 00:11:35,526 --> 00:11:39,026 And we'll see more of what these ampersand things means this week 288 00:11:39,026 --> 00:11:41,416 in lecture and section, so yes, 289 00:11:41,416 --> 00:11:44,016 so when in doubt just comment that's literally all we're 290 00:11:44,016 --> 00:11:48,066 doing, make sure ends a number nothing else, other questions? 291 00:11:48,066 --> 00:11:48,236 Yup? 292 00:11:48,586 --> 00:11:49,586 >> What is fprintf? 293 00:11:50,476 --> 00:11:51,626 >> So what is fprintf? 294 00:11:52,166 --> 00:11:55,916 So this is unlike printf which just automatically prints 295 00:11:55,916 --> 00:11:58,926 to the terminal like the standard output it's called, 296 00:11:58,926 --> 00:11:59,956 like what the terminal is. 297 00:11:59,956 --> 00:12:01,636 This just allows you to print somewhere else. 298 00:12:01,636 --> 00:12:03,516 So this is something called standard error. 299 00:12:03,826 --> 00:12:06,386 So just instead of print it to the terminal, you're gonna print 300 00:12:06,386 --> 00:12:09,086 to some error thing that when we run our automated tests it's 301 00:12:09,086 --> 00:12:10,846 gonna look to try to read in standard error 302 00:12:10,846 --> 00:12:11,776 and see if this is printed. 303 00:12:11,776 --> 00:12:14,276 So this just says, don't print out to the screen, 304 00:12:14,276 --> 00:12:16,906 print somewhere else in this case to standard error. 305 00:12:18,186 --> 00:12:20,716 So again stuff like, this you don't necessarily need 306 00:12:20,716 --> 00:12:22,566 to totally understand in order to write sudoku, 307 00:12:23,266 --> 00:12:24,936 just take our word for it that we're kind 308 00:12:24,936 --> 00:12:25,756 of loading up the board. 309 00:12:27,116 --> 00:12:30,266 So now we're starting up ncurses 310 00:12:30,266 --> 00:12:31,806 which is this library we'll take a look at later. 311 00:12:32,386 --> 00:12:33,736 And now we're kind of getting to code 312 00:12:33,736 --> 00:12:34,976 that makes a little more sense. 313 00:12:35,666 --> 00:12:37,276 So we're calling this restart game. 314 00:12:38,256 --> 00:12:40,166 So even though a game hasn't been started yet, 315 00:12:40,556 --> 00:12:41,596 we're calling restart game 316 00:12:41,596 --> 00:12:44,556 because like I said it's gonna load the game based 317 00:12:44,556 --> 00:12:48,386 on whatever value is stored inside of G. So notice up here, 318 00:12:48,566 --> 00:12:52,246 we're storing that value inside of G dot number so now I come 319 00:12:52,246 --> 00:12:53,616 down here to restart game? 320 00:12:53,876 --> 00:12:55,546 I'm good to go to load some game 321 00:12:55,546 --> 00:12:57,626 because we specified what I want to do. 322 00:12:58,206 --> 00:13:00,446 So if this fails then we just kind of wanna shut down 323 00:13:00,586 --> 00:13:02,456 and say I-- for some reason that failed, 324 00:13:02,456 --> 00:13:03,456 I don't really know what you did. 325 00:13:04,376 --> 00:13:06,826 And then you wanna draw the game for the first time. 326 00:13:07,136 --> 00:13:09,676 So this draw all is basically just gonna take each one 327 00:13:09,676 --> 00:13:12,486 of these individual draw functions and call them. 328 00:13:12,486 --> 00:13:13,526 So instead of having to type them 329 00:13:13,526 --> 00:13:14,906 out every time we have one function 330 00:13:14,906 --> 00:13:16,406 that calls some group of functions. 331 00:13:17,236 --> 00:13:19,146 So now we're in to something that looks very much 332 00:13:19,186 --> 00:13:21,206 like what we had in the game of 15. 333 00:13:21,206 --> 00:13:25,666 So just refresh the screen make sure that everything is good 334 00:13:25,666 --> 00:13:29,016 to go, we've drawn everything and now we see this new function 335 00:13:29,016 --> 00:13:30,466 to get the user's input. 336 00:13:30,736 --> 00:13:32,216 So before we're using something 337 00:13:32,216 --> 00:13:35,066 like GetInt now we're using this getch or getchar 338 00:13:35,676 --> 00:13:38,656 and so we're just asking the user to type in some character, 339 00:13:38,796 --> 00:13:42,506 so this is defined in ncurses this graphical library. 340 00:13:42,626 --> 00:13:44,456 So this isn't something we wrote for you, 341 00:13:44,636 --> 00:13:46,416 it's something someone else wrote for you and still gave 342 00:13:46,416 --> 00:13:50,046 to you but all this is gonna do is return a single character 343 00:13:50,046 --> 00:13:51,076 that the user typed in. 344 00:13:51,366 --> 00:13:52,006 So if I type in A 345 00:13:52,006 --> 00:13:55,076 in the keyboard this is gonna return the character, a char, 346 00:13:55,526 --> 00:13:59,346 A. So now we just want to capitalize it 347 00:13:59,396 --> 00:14:01,426 so if someone is playing sudoku with their caps lock 348 00:14:01,426 --> 00:14:03,126 on because they just yelled at someone on the internet, 349 00:14:03,486 --> 00:14:05,326 then we can still allow them to play and not have to worry 350 00:14:05,326 --> 00:14:06,516 about handling lower case N 351 00:14:06,516 --> 00:14:08,396 and then handling an upper case N is being the same thing. 352 00:14:09,076 --> 00:14:10,506 So now here's the switch statement, 353 00:14:11,346 --> 00:14:13,396 so we're switching over this character. 354 00:14:13,596 --> 00:14:15,986 So in every single one of these case statements I'm gonna be 355 00:14:15,986 --> 00:14:19,866 comparing it to the CH which is again the character the user 356 00:14:19,866 --> 00:14:20,596 just typed in. 357 00:14:21,476 --> 00:14:24,806 So in the case that it's an N I'm going to start a new game. 358 00:14:25,286 --> 00:14:26,556 So here we're just setting the number, 359 00:14:26,556 --> 00:14:28,256 we're saying I want a random new game, 360 00:14:28,576 --> 00:14:29,716 make sure it's not too high 361 00:14:29,806 --> 00:14:32,666 and we're gonna restart the game based on what that number is. 362 00:14:33,296 --> 00:14:35,096 So now this break signifies that I'm done. 363 00:14:35,096 --> 00:14:37,756 After I hit an N I don't wanna do anything below this break. 364 00:14:38,726 --> 00:14:40,866 So in R you'll notice that it's pretty 365 00:14:40,866 --> 00:14:42,706 like the exact same thing except 366 00:14:42,706 --> 00:14:45,106 for what line is different or missing. 367 00:14:45,106 --> 00:14:47,036 [ Inaudible Remark ] 368 00:14:47,036 --> 00:14:49,756 >> Exactly this one that changes G dot number. 369 00:14:50,166 --> 00:14:52,546 So if I call restart game G dot number, 370 00:14:52,546 --> 00:14:54,426 the board I'm using hasn't changed, 371 00:14:54,426 --> 00:14:55,766 I'm just gonna reload the same board. 372 00:14:55,766 --> 00:14:58,156 So there is the difference between starting a new game 373 00:14:58,496 --> 00:14:59,836 and restarting the same game. 374 00:14:59,836 --> 00:15:02,256 I'm just not changing the currently loaded board 375 00:15:02,256 --> 00:15:04,706 which is based on this global structure called G. 376 00:15:05,516 --> 00:15:08,966 And finally we're using our fancy control macro 377 00:15:08,966 --> 00:15:10,606 but you don't need to worry about how that works 378 00:15:11,446 --> 00:15:13,456 and whenever the user hits control L, 379 00:15:13,456 --> 00:15:16,266 it just forces the screen to be redrawn so this can be helpful 380 00:15:16,266 --> 00:15:19,856 if you're debugging or something like that. 381 00:15:20,046 --> 00:15:22,706 So now, after we've taken the action, we just want 382 00:15:22,706 --> 00:15:25,116 to log the move for the purposes of automated tests 383 00:15:25,716 --> 00:15:31,146 and keep going until the user types in a Q. So remember 384 00:15:31,146 --> 00:15:34,366 that after all this we're just in a do while loop. 385 00:15:35,066 --> 00:15:37,256 So you can take a look at this, if you actually click that brace 386 00:15:37,516 --> 00:15:39,206 and scroll down, it will highlight the brace 387 00:15:39,206 --> 00:15:42,316 that it matches so I'm inside, so that's the end 388 00:15:42,316 --> 00:15:44,336 of my do statement and now here's the condition 389 00:15:44,336 --> 00:15:45,276 for it to keep going. 390 00:15:45,536 --> 00:15:49,196 So as soon as I type a Q this is not gonna continue to loop 391 00:15:49,196 --> 00:15:52,416 and I'm gonna break outside of the code which is down here. 392 00:15:52,986 --> 00:15:56,066 So questions on how this loop is going? 393 00:15:56,346 --> 00:15:58,806 Basically, continually asking the user for a letter, 394 00:15:59,156 --> 00:16:01,176 if that letter is a Q then we're getting out of here, 395 00:16:01,476 --> 00:16:03,586 if it's another letter then we're taking action based 396 00:16:03,586 --> 00:16:04,746 on these case statements. 397 00:16:05,016 --> 00:16:05,466 Yup? 398 00:16:05,466 --> 00:16:05,766 [ Inaudible Remark ] 399 00:16:05,766 --> 00:16:05,936 >> Right. 400 00:16:05,936 --> 00:16:06,336 [ Inaudible Remark ] 401 00:16:06,336 --> 00:16:16,876 >> Yes, so restart game, if we look up here 402 00:16:17,066 --> 00:16:23,696 into our prototypes we have bool restart game. 403 00:16:23,696 --> 00:16:27,336 So this function's gonna return a Boolean. 404 00:16:27,336 --> 00:16:29,036 It's either gonna be true or false. 405 00:16:29,796 --> 00:16:32,446 So in the case that there is some error restarting the game, 406 00:16:32,606 --> 00:16:34,776 like you deleted that bin file because you wanted 407 00:16:34,776 --> 00:16:37,576 to see what would happen, then this is going to return false 408 00:16:37,876 --> 00:16:41,756 and in the case that it returns false we just wanna send some 409 00:16:41,756 --> 00:16:43,186 error message to the user saying, 410 00:16:43,186 --> 00:16:44,846 you know, something went wrong. 411 00:16:45,526 --> 00:16:46,686 So when we say this 412 00:16:46,686 --> 00:16:49,586 if not restart game we're still calling this function. 413 00:16:49,996 --> 00:16:51,636 So everything inside of this function is going 414 00:16:51,636 --> 00:16:54,956 to get executed and then we're looking at its return value. 415 00:16:54,956 --> 00:16:56,806 It's a little less explicit 'cause you're used 416 00:16:56,806 --> 00:16:59,256 to seeing maybe like bool X equals restart game 417 00:16:59,256 --> 00:17:01,136 and then looking at X but this is just kind 418 00:17:01,136 --> 00:17:02,116 of a way of shortcutting that. 419 00:17:02,396 --> 00:17:04,576 We're gonna look at whatever this returned and then 420 00:17:04,626 --> 00:17:06,976 if it's true or false take action accordingly. 421 00:17:07,936 --> 00:17:15,036 Okay, back down here so now once the user types Q we're just 422 00:17:15,036 --> 00:17:16,726 gonna clear the screen and say thanks 423 00:17:16,726 --> 00:17:20,136 for playing, so questions on main? 424 00:17:20,626 --> 00:17:24,856 Okay, so just as a word of warning, you are gonna have 425 00:17:24,986 --> 00:17:27,526 to kind of modify main or some 426 00:17:27,526 --> 00:17:28,876 of the other functions we've written for you. 427 00:17:28,876 --> 00:17:30,756 There's no-- unlike 15 where we gave you like-- 428 00:17:30,986 --> 00:17:32,376 just write your code for in it right here 429 00:17:32,376 --> 00:17:34,096 and it's gonna work, we promise. 430 00:17:34,096 --> 00:17:37,506 You do kind of have to modify functions like main in order 431 00:17:37,506 --> 00:17:41,256 to add the functionality that we're asking you to add. 432 00:17:41,256 --> 00:17:42,996 So now we're getting into the drawing functions 433 00:17:43,796 --> 00:17:47,126 and let's take a look at the ncurses library before we try 434 00:17:47,126 --> 00:17:48,606 to wrap our heads around those. 435 00:17:49,206 --> 00:17:52,826 So before we do so because GDB is awesome we want you 436 00:17:52,826 --> 00:17:55,736 to be able to use GDB for this Pset but as soon as you fire 437 00:17:55,736 --> 00:17:58,656 up sudoku you'll notice it kind of takes over the entire screen. 438 00:17:58,956 --> 00:18:01,946 So let's just walk through really quickly how we can still 439 00:18:01,946 --> 00:18:03,636 use GDB with our program. 440 00:18:04,536 --> 00:18:09,776 So if we have our plans and we open up a terminal window 441 00:18:10,286 --> 00:18:14,416 and so notice that I'm using the full terminal not the little one 442 00:18:14,416 --> 00:18:17,786 inside of gedit, so if I see the int of my Pset 4, 443 00:18:18,516 --> 00:18:22,996 there's my sudoku, now I can run sudoku debug 1. 444 00:18:22,996 --> 00:18:27,376 So you notice this kind of took up the whole screen. 445 00:18:27,376 --> 00:18:29,486 There is no word GDB can kind of go. 446 00:18:29,966 --> 00:18:31,266 So I loaded this debug board, 447 00:18:31,266 --> 00:18:34,006 you notice there's only one space that's not solved 448 00:18:34,006 --> 00:18:35,166 because we have a single dot. 449 00:18:35,746 --> 00:18:37,676 So now let's say I wanna use GDB. 450 00:18:38,156 --> 00:18:39,876 What I can do is up in the terminal, 451 00:18:40,276 --> 00:18:42,716 go up here to File and Open Tab. 452 00:18:43,536 --> 00:18:45,876 And so just like Firefox's tab or Chrome, 453 00:18:45,876 --> 00:18:47,786 your terminal can have tabs so you don't have 454 00:18:47,786 --> 00:18:48,736 to open up a new window. 455 00:18:49,176 --> 00:18:52,896 Now over on this tab, I wanna find out where sudoku is running 456 00:18:52,896 --> 00:18:58,126 so to do that I'm gonna type in P-I-D of and then the name 457 00:18:58,126 --> 00:18:59,736 of my program, so sudoku. 458 00:19:00,436 --> 00:19:03,306 So this says there is some process running on my system. 459 00:19:03,716 --> 00:19:06,276 If you use Windows and you ever hit Control Alt Delete you can 460 00:19:06,276 --> 00:19:07,796 see that long list of processes. 461 00:19:08,056 --> 00:19:10,686 So each of one those processes has a unique ID. 462 00:19:10,686 --> 00:19:14,326 So in this case, I'm running some process called sudoku 463 00:19:14,566 --> 00:19:16,626 because I just typed in dot slash sudoku. 464 00:19:17,226 --> 00:19:20,076 So I wanna get the number that identifies that process. 465 00:19:20,606 --> 00:19:25,046 So in this case its 2220 so as long as sudoku is running, 466 00:19:25,236 --> 00:19:27,116 this number is not going to change. 467 00:19:27,656 --> 00:19:31,296 So instead of starting up a new sudoku, we wanna tell GDB, 468 00:19:31,296 --> 00:19:32,936 "Actually I just want you to attach 469 00:19:33,206 --> 00:19:34,636 to that already running process." 470 00:19:34,986 --> 00:19:38,796 So to do that, we're gonna say, GDB then sudoku 471 00:19:38,866 --> 00:19:42,146 and now we're gonna specify that process that we just got back 472 00:19:42,356 --> 00:19:48,316 from pidof so 2220, hit Enter and now we get some random text, 473 00:19:48,316 --> 00:19:50,146 don't worry about that. 474 00:19:50,146 --> 00:19:51,206 So now let's set a breakpoint. 475 00:19:51,886 --> 00:19:54,496 So we're gonna say "Break on restart game". 476 00:19:54,846 --> 00:19:57,826 So this says as soon as I hit the function restart game, 477 00:19:57,976 --> 00:20:00,606 I want you to pause so in GDB I can do things 478 00:20:00,606 --> 00:20:02,456 like printf variable and step through the code. 479 00:20:02,956 --> 00:20:06,386 So I say "break restart game" breakpoint one 480 00:20:06,386 --> 00:20:08,906 if you wanna verify that that actually worked we can say 481 00:20:08,906 --> 00:20:12,816 "info break" and you see we have one breakpoint it's located 482 00:20:12,816 --> 00:20:15,976 at restart game which happens to be defined on line 489. 483 00:20:17,266 --> 00:20:20,176 >> And so now when we ran this GDB we actually paused the 484 00:20:20,176 --> 00:20:22,266 execution of our existing sudoku program. 485 00:20:22,916 --> 00:20:27,426 So if I just type in continue, that means it's gonna be-- 486 00:20:27,426 --> 00:20:28,726 it's gonna continue to run. 487 00:20:29,216 --> 00:20:30,936 So now we're basically sitting inside 488 00:20:30,936 --> 00:20:33,246 of our do while loop inside of main and we're waiting 489 00:20:33,246 --> 00:20:34,436 for the user to type something. 490 00:20:35,176 --> 00:20:38,556 So because I put a breakpoint in restart game let's type 491 00:20:38,556 --> 00:20:40,226 in an action that's gonna restart the game, 492 00:20:40,226 --> 00:20:43,156 so let's just say N. So you notice over here 493 00:20:43,156 --> 00:20:44,606 that my text turned red for a second, 494 00:20:44,886 --> 00:20:46,246 which means there's new output in this tab. 495 00:20:46,616 --> 00:20:49,736 So if I switch over to here, we can see we're back 496 00:20:49,736 --> 00:20:52,876 into our normal GDB state, so I can see the line I'm 497 00:20:52,876 --> 00:20:55,226 about to execute, if I wanna see the source code 498 00:20:55,226 --> 00:20:58,566 around that I can say "list" and here is exactly 499 00:20:58,566 --> 00:21:02,506 where I am inside of the running sudoku program in the other tab. 500 00:21:03,266 --> 00:21:09,456 So does that make sense to everybody? 501 00:21:09,456 --> 00:21:10,056 [ Inaudible Remark ] 502 00:21:10,056 --> 00:21:11,696 >So when-- why do we say continue? 503 00:21:11,796 --> 00:21:16,266 So when I have said GDB, sudoku and then the pid that paused it. 504 00:21:16,986 --> 00:21:19,076 So before I can actually do anything I need to say, 505 00:21:19,076 --> 00:21:20,096 "Okay, keep going now." 506 00:21:21,346 --> 00:21:23,666 So that's the only reason I said continue so we wanna continue 507 00:21:23,666 --> 00:21:27,136 until we hit some breakpoint where I said break restart game 508 00:21:27,136 --> 00:21:31,196 and that's my breakpoint, other question? 509 00:21:31,196 --> 00:21:31,386 Yup? 510 00:21:31,386 --> 00:21:34,896 >> So how do you link sudoku to the other tab? 511 00:21:35,096 --> 00:21:36,886 >> So how do we link through that other tab? 512 00:21:36,886 --> 00:21:38,336 If you remember-- so let's just get out of here. 513 00:21:38,386 --> 00:21:41,006 So remember we did two things. 514 00:21:41,006 --> 00:21:45,046 We first started sudoku, then we came over to this new tab 515 00:21:45,046 --> 00:21:47,446 and we said pidof sudoku 516 00:21:47,446 --> 00:21:49,746 and this is gonna return the unique number 517 00:21:49,746 --> 00:21:52,366 that represents the sudoku program that I'm running. 518 00:21:52,986 --> 00:21:56,336 Now when I'm say GDB that number, 519 00:21:56,336 --> 00:21:59,076 that process ID 2220 that's gonna say 520 00:21:59,076 --> 00:22:00,596 "Don't run sudoku again" 521 00:22:00,786 --> 00:22:04,856 but there's an already running sudoku and it's located at 2220. 522 00:22:05,006 --> 00:22:07,726 So I want you to go and debug that rather 523 00:22:07,726 --> 00:22:08,676 than starting a new one. 524 00:22:09,056 --> 00:22:14,906 So now we're attached to this other tab, other questions? 525 00:22:15,456 --> 00:22:19,436 Okay, so really quickly, whoa. 526 00:22:20,516 --> 00:22:24,636 [ Pause ] 527 00:22:25,136 --> 00:22:27,986 >> So the problem set mentions, you know, just using GDB 528 00:22:27,986 --> 00:22:31,276 like that but there's an actual really cool feature of GDB 529 00:22:31,276 --> 00:22:32,876 that allows you to browse the source code 530 00:22:32,876 --> 00:22:33,476 as you're running it. 531 00:22:33,836 --> 00:22:36,556 So this is the TUI or Text User Interface. 532 00:22:37,086 --> 00:22:40,026 This is just a much cooler way of using GDB 533 00:22:40,386 --> 00:22:41,426 that David didn't tell you about. 534 00:22:41,866 --> 00:22:44,366 So now that you're all glad you came 535 00:22:44,366 --> 00:22:48,636 to the walkthrough I can say, GDB sudoku 2220 and add 536 00:22:48,636 --> 00:22:51,406 in this -tui for text user interface. 537 00:22:51,786 --> 00:22:57,826 Now when I hit Enter, oh-ho, oh ho ho, we have this new output 538 00:22:57,996 --> 00:23:01,016 so again it tells us to hit Enter and we do, all right. 539 00:23:01,596 --> 00:23:03,696 So now let's just say the same thing we said before 540 00:23:03,696 --> 00:23:06,636 so we can say, break restart game. 541 00:23:06,946 --> 00:23:09,696 We have our breakpoint just like we did before 542 00:23:09,696 --> 00:23:10,856 and now let's continue. 543 00:23:11,326 --> 00:23:14,516 So now again we're continuing, we're waiting 544 00:23:14,516 --> 00:23:15,666 for the user to do something. 545 00:23:16,136 --> 00:23:18,476 So we come back over to this other tab, we're gonna try 546 00:23:18,476 --> 00:23:20,836 to trigger that restart game so I'm gonna hit 547 00:23:20,836 --> 00:23:24,326 "N" there is my red, oh yeah that's cool. 548 00:23:24,766 --> 00:23:27,086 So now we can see exactly where we are 549 00:23:27,086 --> 00:23:29,536 in the code above our GDB prompt. 550 00:23:29,856 --> 00:23:35,136 So if I do something like next you can see up here 551 00:23:35,136 --> 00:23:36,496 that I'm stepping through everything. 552 00:23:36,886 --> 00:23:39,166 So now let's say I wanna go into draw numbers if I say 553 00:23:39,166 --> 00:23:42,886 "step" now I'm inside of this draw numbers program 554 00:23:42,886 --> 00:23:45,336 and this is this sodoku.c that you're working with. 555 00:23:45,896 --> 00:23:49,746 Now if I type next just keep going I'll put a couple 556 00:23:49,746 --> 00:23:52,576 of numbers you come over to this other tabs you can actually see 557 00:23:52,576 --> 00:23:56,086 we're drawing the numbers step by step. 558 00:23:56,086 --> 00:23:56,226 Yup? 559 00:23:56,226 --> 00:23:59,926 >> So what's the difference between continue 560 00:24:00,006 --> 00:24:02,746 and next just next just one by one? 561 00:24:03,046 --> 00:24:04,766 >> So what's the difference between continue and next? 562 00:24:04,766 --> 00:24:05,606 So that's a good question. 563 00:24:06,096 --> 00:24:09,316 So continue is going to keep the program going 564 00:24:09,316 --> 00:24:11,606 until you hit another breakpoint. 565 00:24:12,276 --> 00:24:13,996 So if I had another breakpoint somewhere else 566 00:24:14,106 --> 00:24:17,186 or even it came back to restart game and I said continue, 567 00:24:17,266 --> 00:24:19,486 it's only gonna stop at a breakpoint. 568 00:24:19,486 --> 00:24:25,766 If I just say next, it's only gonna go one line at a time. 569 00:24:25,766 --> 00:24:27,826 So notice here actually even though I just hit next I can 570 00:24:27,826 --> 00:24:30,556 keep hitting Enter and effectively going to next, 571 00:24:30,726 --> 00:24:31,946 well if you don't type anything 572 00:24:31,946 --> 00:24:34,356 at the GDB prompt it's gonna do the last thing 573 00:24:34,636 --> 00:24:35,386 that you told it to do. 574 00:24:35,866 --> 00:24:36,916 You know the short cut if you don't want 575 00:24:36,916 --> 00:24:37,696 to type next you can just type 576 00:24:37,766 --> 00:24:39,716 "N" it will do the same thing, question? 577 00:24:39,716 --> 00:24:43,546 >> Is the breakpoint an error in the code? 578 00:24:43,546 --> 00:24:45,556 >> So is a breakpoint in error in the code? 579 00:24:45,796 --> 00:24:48,956 So breakpoint is just a little stop sign inside of your code. 580 00:24:49,206 --> 00:24:50,856 That says when sudoku is running, 581 00:24:51,346 --> 00:24:55,246 once I hit this line I want you to stop because I want 582 00:24:55,246 --> 00:24:57,976 to be able to do things like see where I am inside 583 00:24:57,976 --> 00:24:59,976 of the source code or print out variables 584 00:24:59,976 --> 00:25:01,676 like if I wanna know what the current value 585 00:25:01,676 --> 00:25:02,886 of ice I can just say printi 586 00:25:03,596 --> 00:25:05,876 and I can know currently that I equals zero. 587 00:25:06,426 --> 00:25:07,786 Now let's see, let's find out what J is. 588 00:25:07,786 --> 00:25:12,486 So, if we print J. Now J is six and we go back over to sudoku 589 00:25:12,886 --> 00:25:14,136 that kind of makes sense. 590 00:25:14,676 --> 00:25:17,886 Because, I'm in the first row and I'm in the 0, 1, 2, 3, 4, 591 00:25:17,886 --> 00:25:21,516 5-- 0, 1, 2, 3, 4, 5 and we're about to print the sixth column. 592 00:25:22,706 --> 00:25:25,196 So breakpoint is not necessarily an error, it's just a place 593 00:25:25,196 --> 00:25:26,256 where you want to stop. 594 00:25:26,256 --> 00:25:29,406 It could be a line number or a function, question? 595 00:25:29,526 --> 00:25:29,666 Yeah? 596 00:25:29,666 --> 00:25:31,766 >> Is this a classified breakpoint 597 00:25:31,766 --> 00:25:35,546 or is that [inaudible]? 598 00:25:35,756 --> 00:25:37,776 >> So you do-- do you have to specify a breakpoint? 599 00:25:37,776 --> 00:25:40,236 So yeah, so if you don't specify any breakpoints 600 00:25:40,526 --> 00:25:42,696 and just say run, that's gonna be the equivalent 601 00:25:42,696 --> 00:25:45,666 of just running it without GDB 'cause it's not gonna have any 602 00:25:45,666 --> 00:25:46,556 place to stop. 603 00:25:46,776 --> 00:25:49,706 So until you tell the program when to stop and when to be able 604 00:25:49,706 --> 00:25:51,456 to step through the program line by line, 605 00:25:52,336 --> 00:25:53,606 it's just gonna run normally. 606 00:25:53,606 --> 00:25:55,986 So, if you wanna break on main, you can just say be-- 607 00:25:56,246 --> 00:25:57,486 create a new breakpoint on main. 608 00:25:57,856 --> 00:26:01,076 And so this is gonna say before you go anywhere immediately stop 609 00:26:01,076 --> 00:26:06,946 and let me step through line by line, other questions, yup? 610 00:26:07,896 --> 00:26:11,756 >> Can you use next without using continue? 611 00:26:11,756 --> 00:26:13,286 >> So, can you next without using continue? 612 00:26:13,446 --> 00:26:16,186 Sure, I mean if I just say next then I can go to the next line, 613 00:26:17,266 --> 00:26:20,396 right, or if I restarted-- if I restarted GDB, 614 00:26:21,066 --> 00:26:22,406 just said the same thing. 615 00:26:22,886 --> 00:26:26,176 I'm gonna break on restart game? 616 00:26:26,946 --> 00:26:30,046 'Cause now when I say continue, okay we're gonna continue 617 00:26:30,046 --> 00:26:33,776 until we hit this breakpoint and so at that point I can say next, 618 00:26:33,776 --> 00:26:34,606 next, next, next, next 619 00:26:34,606 --> 00:26:36,496 and I don't necessarily have to type continue. 620 00:26:36,496 --> 00:26:37,466 If that's what you mean. 621 00:26:38,626 --> 00:26:40,786 >> I'm sorry I'm still confused why you continue at all, 622 00:26:40,936 --> 00:26:42,116 so if you didn't put continue 623 00:26:42,116 --> 00:26:43,976 when are you gonna run off to that breakpoint? 624 00:26:44,316 --> 00:26:46,856 >> Right. So, when we run GDB and this is kind 625 00:26:46,856 --> 00:26:48,796 of a special case, it wasn't-- it didn't do this before 626 00:26:49,056 --> 00:26:50,586 but because we're doing the special thing 627 00:26:50,586 --> 00:26:52,916 where we're attaching to an already running program, 628 00:26:53,286 --> 00:26:56,096 when we say, GDB, sudoku 629 00:26:56,096 --> 00:26:57,966 and then give the pid it's pausing it. 630 00:26:58,936 --> 00:27:00,916 So, until I say continue it's paused. 631 00:27:01,646 --> 00:27:04,256 So, once I say continue it's gonna say okay, keep going now 632 00:27:04,256 --> 00:27:06,236 and all the breakpoints I've created are now active 633 00:27:06,236 --> 00:27:07,766 and they're live and they're gonna stop the code. 634 00:27:08,486 --> 00:27:10,056 So, just yeah, so before you do anything 635 00:27:10,056 --> 00:27:13,086 in this special two-tap thing just say continue. 636 00:27:13,336 --> 00:27:14,626 After you set up all your breakpoints 637 00:27:14,626 --> 00:27:16,086 and then you'll be good to go, yup? 638 00:27:17,116 --> 00:27:19,666 >> So, do you have to put the breakpoints in your source code? 639 00:27:20,856 --> 00:27:23,596 >> So, do you have to put the breakpoints in your source code? 640 00:27:23,906 --> 00:27:26,176 So, the breakpoints are defined by GDB 641 00:27:26,426 --> 00:27:28,996 so once I quit GDB which I can. 642 00:27:29,626 --> 00:27:33,566 As I quit, all of my breakpoints are now gone. 643 00:27:34,326 --> 00:27:38,336 Whoa, okay so the G-- breakpoint is something that GDB creates 644 00:27:38,406 --> 00:27:39,436 as it's running your code. 645 00:27:39,436 --> 00:27:42,866 It doesn't actually modify the dot C file itself 646 00:27:42,866 --> 00:27:43,946 and there's no way of putting 647 00:27:43,946 --> 00:27:45,596 in a breakpoint into the dot C file. 648 00:27:45,806 --> 00:27:47,786 But these are kind of thing you create on the fly 649 00:27:47,786 --> 00:27:48,976 as you're running GDB. 650 00:27:49,516 --> 00:27:53,536 Are there debugging questions, yup? 651 00:27:53,536 --> 00:27:56,776 >> Can you put a breakpoint in the dot H file? 652 00:27:57,916 --> 00:27:59,876 >> So, can you put a breakpoint in the dot H file? 653 00:28:00,286 --> 00:28:02,586 So, generally in the header files there's no 654 00:28:02,586 --> 00:28:03,696 executable code. 655 00:28:04,056 --> 00:28:05,956 It's just kind of like definitions of things 656 00:28:05,956 --> 00:28:07,636 and define statements so none 657 00:28:07,636 --> 00:28:10,426 of that is ever gonna really be executed as a line of code. 658 00:28:10,426 --> 00:28:12,056 So, typically you're only gonna put them 659 00:28:12,056 --> 00:28:18,836 in the dot C files, other questions, yup? 660 00:28:19,156 --> 00:28:22,446 >> Breakpoints will they generally always be in main? 661 00:28:22,626 --> 00:28:24,166 >> So will breakpoints always be in main? 662 00:28:24,166 --> 00:28:26,216 Not necessarily, so when we came over here, 663 00:28:26,486 --> 00:28:28,626 we created a breakpoint inside of restart game. 664 00:28:29,176 --> 00:28:31,566 So I can also put a breakpoint at an arbitrary line number 665 00:28:31,566 --> 00:28:35,376 like instead of maybe I don't wanna break let's go 666 00:28:35,376 --> 00:28:42,656 down here to-- so let's just come right here. 667 00:28:42,656 --> 00:28:44,356 So, let's just say I wanna break out this line. 668 00:28:44,866 --> 00:28:50,296 So if I say, break 168 it's gonna break at that line. 669 00:28:50,296 --> 00:28:52,956 So this isn't necessarily in main and it's not necessarily 670 00:28:52,956 --> 00:28:54,686 at the beginning of a function but I can kind 671 00:28:54,686 --> 00:28:55,936 of break wherever I want. 672 00:28:57,176 --> 00:28:58,976 If you wanna do something quick and just step 673 00:28:59,016 --> 00:29:00,246 through it immediately you don't wanna go 674 00:29:00,246 --> 00:29:01,836 to any functions you just say break main, 675 00:29:02,156 --> 00:29:05,396 that's just gonna allow you to kind of start of fresh, just, 676 00:29:05,396 --> 00:29:07,546 you know, print everything, go line by line you don't have 677 00:29:07,546 --> 00:29:09,216 to worry about jumping to functions or anything 678 00:29:09,356 --> 00:29:12,296 but you don't to have to say break main, it's just one way 679 00:29:12,296 --> 00:29:15,226 of using GDB to pause immediately. 680 00:29:15,816 --> 00:29:21,136 If that's what you wanna do, yup? 681 00:29:21,136 --> 00:29:21,286 [ Inaudible Remark ] 682 00:29:21,286 --> 00:29:24,046 >> Yeah, so the difference between next and step. 683 00:29:24,646 --> 00:29:27,066 So let's go back into restart game. 684 00:29:27,666 --> 00:29:29,906 And, again I'm gonna say continue because I paused it, 685 00:29:30,236 --> 00:29:34,446 come back over here restart the game with N and now we're here. 686 00:29:35,136 --> 00:29:38,496 So, if I say step then I'm going to jump 687 00:29:38,496 --> 00:29:40,576 into the function load board. 688 00:29:41,546 --> 00:29:44,336 So if I say right here step, 689 00:29:45,106 --> 00:29:47,766 I'm now inside the function load board. 690 00:29:48,586 --> 00:29:53,486 So now, if I say name so S printf this is just a function. 691 00:29:53,946 --> 00:29:57,406 If I say step, I'm suddenly gonna be inside of S printf. 692 00:29:58,296 --> 00:30:00,216 But for our purposes that's not very helpful, 693 00:30:00,506 --> 00:30:04,406 so if I say next instead we're gonna kind of jump 694 00:30:04,406 --> 00:30:06,736 over that function and execute it all at once. 695 00:30:07,676 --> 00:30:10,456 >> So, step says I wanna go into the function and execute 696 00:30:10,456 --> 00:30:11,756 that function line by line. 697 00:30:12,216 --> 00:30:15,856 Next says that function is just one line execute it 698 00:30:16,716 --> 00:30:20,236 and be done with it. 699 00:30:20,236 --> 00:30:24,276 Are there last GDB questions? 700 00:30:24,276 --> 00:30:25,466 [ Inaudible Remark ] 701 00:30:25,466 --> 00:30:27,606 >> So if you're inside of a do while loop when you wanna kind 702 00:30:27,606 --> 00:30:29,836 of get out of it so that's where continue comes in handy. 703 00:30:30,126 --> 00:30:31,696 So, if you have this really long while loop 704 00:30:31,696 --> 00:30:33,966 and you just wanna pause maybe at the beginning instead 705 00:30:33,966 --> 00:30:35,186 of hitting next, next, next, next, 706 00:30:35,446 --> 00:30:37,326 you can just say create a breakpoint at the beginning 707 00:30:37,326 --> 00:30:38,976 of that loop and say continue. 708 00:30:39,326 --> 00:30:40,926 And then, you can jump right back to the start 709 00:30:40,926 --> 00:30:42,656 of that while loop if that's where your breakpoint is. 710 00:30:43,036 --> 00:30:49,446 All right so let get out of GDB with Q say yes, 711 00:30:50,566 --> 00:30:52,446 and that's it for GDB. 712 00:30:52,866 --> 00:31:00,426 All right, so now let's take a look at ncurses. 713 00:31:00,796 --> 00:31:03,156 So, this is the graphical user interphase library. 714 00:31:03,206 --> 00:31:05,616 So, we're not quite at the level of web pages with buttons 715 00:31:05,616 --> 00:31:08,716 or actual programs that you would run like Microsoft word 716 00:31:09,196 --> 00:31:12,926 but this is a lot nicer than the game of 15. 717 00:31:12,926 --> 00:31:16,826 So, what basically the advantage of ncurses is that we can print 718 00:31:16,966 --> 00:31:18,436 to anywhere on the terminal. 719 00:31:19,096 --> 00:31:21,916 So, in the game of 15 when we had that function draw, 720 00:31:21,916 --> 00:31:24,156 we need to draw the board one row at a time. 721 00:31:24,756 --> 00:31:26,206 Once you're finished printing a row, 722 00:31:26,376 --> 00:31:27,986 we better hope you printed it right 'cause there's no 723 00:31:27,986 --> 00:31:28,356 going back. 724 00:31:28,746 --> 00:31:29,446 We already printed it. 725 00:31:30,166 --> 00:31:34,216 With ncurses you can say I want an X at the 10th row 726 00:31:34,216 --> 00:31:38,136 and the 70th column and it's just going to put it there. 727 00:31:38,356 --> 00:31:40,646 So ncurses, it's operating on row-- 728 00:31:40,646 --> 00:31:42,666 a row column basis which I kind of like, 729 00:31:42,746 --> 00:31:45,036 but I guess David doesn't based on the Pset. 730 00:31:45,036 --> 00:31:46,646 We're-- maybe we're used to working XY 731 00:31:46,896 --> 00:31:49,236 so just remember ncurses always row, column. 732 00:31:50,136 --> 00:31:52,276 So, a couple of good functions in ncurses, 733 00:31:52,446 --> 00:31:55,406 one is the move function, this is gonna take the cursor 734 00:31:55,406 --> 00:31:57,886 and put it to wherever you want on the terminals. 735 00:31:57,886 --> 00:32:00,786 So the first argument is the row second argument is the column. 736 00:32:01,746 --> 00:32:03,156 Now, if you wanna write something 737 00:32:03,356 --> 00:32:06,536 to the screen you're gonna use this move add stir, 738 00:32:06,536 --> 00:32:07,456 move add [inaudible]. 739 00:32:08,026 --> 00:32:11,206 This is gonna say I want the cursor to go to some location 740 00:32:11,206 --> 00:32:14,396 on the screen again my row and my column or my Y and my X 741 00:32:14,716 --> 00:32:17,906 and I want you print a single character or a single string. 742 00:32:18,546 --> 00:32:21,736 So, if I say move to you know zero, 743 00:32:21,736 --> 00:32:23,516 zero and then I wanna print-- 744 00:32:23,646 --> 00:32:27,176 print like the letter A then I could say move add stir, zero, 745 00:32:27,176 --> 00:32:29,886 zero A says "I want this character 746 00:32:29,886 --> 00:32:31,006 in this place on the screen." 747 00:32:31,126 --> 00:32:33,756 No longer do I need to printf things in order. 748 00:32:34,286 --> 00:32:38,386 So, this other function we're getting input we saw earlier 749 00:32:38,516 --> 00:32:41,256 because getch or this getch is a way 750 00:32:41,256 --> 00:32:42,876 of getting a character from the user. 751 00:32:43,276 --> 00:32:45,566 So, when they type in numbers on the screen, 752 00:32:45,566 --> 00:32:48,526 it's going to get the char representation of those numbers. 753 00:32:48,816 --> 00:32:50,656 So, a one is not going to be a one. 754 00:32:50,656 --> 00:32:52,666 It's going to be a one in those singe quotes. 755 00:32:53,336 --> 00:32:56,146 So, ncurses also build in some constants for characters 756 00:32:56,146 --> 00:32:57,956 that otherwise don't have 757 00:32:57,956 --> 00:33:00,286 like a letter representation like the arrow keys. 758 00:33:00,916 --> 00:33:03,516 So this key underscore up and the same with down left 759 00:33:03,516 --> 00:33:06,536 and right are defined constants inside of ncurses. 760 00:33:06,536 --> 00:33:10,246 And this says whenever the user types an arrow key it's the same 761 00:33:10,246 --> 00:33:11,826 as them typing one of these numbers. 762 00:33:12,276 --> 00:33:14,976 So when you say getch you can actually determine 763 00:33:15,156 --> 00:33:17,756 if they pressed an arrow key which you can't really do 764 00:33:17,756 --> 00:33:19,376 if you we're just using something like GetIint. 765 00:33:20,766 --> 00:33:23,816 And so finally, this control L not defined by ncurses 766 00:33:23,816 --> 00:33:25,596 but something we wrote ourselves. 767 00:33:26,726 --> 00:33:28,776 So, questions on how we're getting input from the user 768 00:33:28,776 --> 00:33:33,626 or how to use these, yup? 769 00:33:33,626 --> 00:33:34,236 [ Inaudible Remark ] 770 00:33:34,236 --> 00:33:38,646 >> So, if I type-- so what happens 771 00:33:38,836 --> 00:33:40,296 if I want a number and I use getch. 772 00:33:40,396 --> 00:33:41,996 So, this is going to take 773 00:33:41,996 --> 00:33:44,996 in the character representation of the number. 774 00:33:44,996 --> 00:33:47,226 So, remember that nine is different than "9". 775 00:33:47,226 --> 00:33:50,816 So, if I type in a nine into getch, 776 00:33:50,816 --> 00:33:54,976 it's gonna give me back the character nine, so character 777 00:33:54,976 --> 00:33:58,076 in this case not meaning letter but being the char data type 778 00:33:58,176 --> 00:34:01,696 in C which represents a single symbol on the computer. 779 00:34:02,686 --> 00:34:05,266 Does that make sense? 780 00:34:05,266 --> 00:34:08,886 Okay. Other questions? 781 00:34:08,886 --> 00:34:09,606 [ Inaudible Remark ] 782 00:34:09,606 --> 00:34:12,886 >> So, the single quotes you remember, 783 00:34:12,986 --> 00:34:15,286 is how we define a char, and C, or a char. 784 00:34:15,286 --> 00:34:16,876 I don't even know how to pronounce it 785 00:34:16,916 --> 00:34:19,076 but just a single character whether 786 00:34:19,076 --> 00:34:20,326 that be a letter or a number. 787 00:34:20,706 --> 00:34:24,296 So this translates to the ASCII values between zero and 127 788 00:34:24,746 --> 00:34:26,006 and just making sure we cave 789 00:34:26,006 --> 00:34:29,116 in these quotes distinguishes the ASCII value one 790 00:34:29,116 --> 00:34:32,236 which is some non-printable character and the character one 791 00:34:32,736 --> 00:34:34,106 which is the printable one. 792 00:34:34,686 --> 00:34:38,526 So this is just like in Pset 2 when you had to deal 793 00:34:38,526 --> 00:34:41,706 with converting an A to some number or some number 794 00:34:41,906 --> 00:34:43,446 to it's actual ASCII number. 795 00:34:43,946 --> 00:34:47,486 Other questions, yup? 796 00:34:47,486 --> 00:34:48,466 [ Inaudible Remark ] 797 00:34:48,466 --> 00:34:53,286 >> So, inside of sudoku if you-- 798 00:34:53,486 --> 00:34:55,626 we go back to what it looks like? 799 00:34:56,796 --> 00:35:01,756 When we run it, when we hit the arrow keys we wanna be able 800 00:35:01,756 --> 00:35:04,116 to move this letter green guy around. 801 00:35:04,596 --> 00:35:07,646 So we need to detect if the user typed in a left, or an up, 802 00:35:07,646 --> 00:35:10,846 or down, and the way we do that is we just compare it 803 00:35:10,846 --> 00:35:12,286 to these defined constants. 804 00:35:12,766 --> 00:35:17,456 So, if I call getch and the user types in an arrow key. 805 00:35:17,556 --> 00:35:20,066 It's gonna return this constant key up 806 00:35:20,306 --> 00:35:21,526 or key down left or right. 807 00:35:22,176 --> 00:35:23,756 So, we can just-- we don't even have to worry 808 00:35:23,756 --> 00:35:24,916 about what these numbers are-- 809 00:35:24,916 --> 00:35:26,496 what these constants actually represent. 810 00:35:26,666 --> 00:35:28,476 We can just say if the character is the key 811 00:35:28,476 --> 00:35:33,166 up then I wanna do something, so comparing it to these instead 812 00:35:33,166 --> 00:35:35,116 of comparing it to some number or character. 813 00:35:35,456 --> 00:35:41,186 Okay, so now we've covered the distribution code 814 00:35:41,186 --> 00:35:42,666 and the library we've been using 815 00:35:42,776 --> 00:35:45,046 so here is our to-do list for this Pset. 816 00:35:45,476 --> 00:35:47,016 You wanna be able to move the cursor 817 00:35:47,016 --> 00:35:49,406 around once we have the user be able 818 00:35:49,406 --> 00:35:51,836 to move their cursor we wanna allow them to input some number. 819 00:35:52,516 --> 00:35:54,896 After they input the number we wanna be able to tell them 820 00:35:55,036 --> 00:35:57,746 if it's definitely wrong or some illegal move in Sudoku. 821 00:35:58,546 --> 00:36:00,516 Then, once we have that working we want to allow the user 822 00:36:00,516 --> 00:36:01,466 to erase their number. 823 00:36:02,206 --> 00:36:05,546 So make sure that if they made a mistake and they wanna get rid 824 00:36:05,546 --> 00:36:06,686 of their choice they can do that. 825 00:36:06,686 --> 00:36:09,216 And finally, check if the board is one 826 00:36:09,536 --> 00:36:12,276 and once the board is one, stop the user from playing anymore. 827 00:36:12,436 --> 00:36:17,406 So, remember this function show cursor is going 828 00:36:17,406 --> 00:36:21,826 to move the cursor based on the-- based on the values of g.y 829 00:36:21,876 --> 00:36:26,706 and g.x. So, all the show cursor function does is it calls this 830 00:36:26,706 --> 00:36:29,686 ncurses move function which is pretty complicated 831 00:36:29,686 --> 00:36:31,136 when you actually look at all the math we're doing. 832 00:36:31,746 --> 00:36:34,696 But all you need to worry about is changing the Y 833 00:36:34,696 --> 00:36:37,716 and the X inside of this global struct because as soon 834 00:36:37,716 --> 00:36:40,916 as I call show cursor it's going to read those values 835 00:36:40,916 --> 00:36:43,716 that you changed and set the cursor according 836 00:36:43,966 --> 00:36:44,826 to those values. 837 00:36:45,296 --> 00:36:46,226 So you don't have worry 838 00:36:46,226 --> 00:36:48,416 about calling the move function itself. 839 00:36:48,566 --> 00:36:50,626 When I actually wrote this Pset I didn't figure this out 840 00:36:50,626 --> 00:36:52,866 and so I had all this crazy ncurses code which is terrible. 841 00:36:53,496 --> 00:36:56,516 So, instead of trying to worry about that, you just need 842 00:36:56,516 --> 00:36:58,176 to change the values inside 843 00:36:58,176 --> 00:37:00,296 of this global variable and call show cursor. 844 00:37:00,336 --> 00:37:02,706 That's gonna read those values and put the cursor back. 845 00:37:02,856 --> 00:37:06,556 So now, when you look at this board it's a little confusing 846 00:37:06,686 --> 00:37:09,506 what we mean when we say, you know, X and Y is 4. 847 00:37:10,216 --> 00:37:14,006 So, inside of our board we just have nine rows across 848 00:37:14,006 --> 00:37:15,326 and nine columns down. 849 00:37:16,226 --> 00:37:20,646 So zero, zero is not this plus sign or it's not the top 850 00:37:20,646 --> 00:37:21,496 of the terminal window. 851 00:37:21,966 --> 00:37:24,166 It's just the first number in the grid. 852 00:37:24,816 --> 00:37:28,306 So this at the end here is board 2A, row 2 column 8, 853 00:37:28,806 --> 00:37:30,356 I mean there's not that many characters in the row 854 00:37:30,356 --> 00:37:31,796 because we have spaces, we have pipes, 855 00:37:31,796 --> 00:37:32,636 and all that kind of thing. 856 00:37:32,856 --> 00:37:35,276 But as far as your board representation is concerned 857 00:37:35,636 --> 00:37:36,436 those don't exist. 858 00:37:36,436 --> 00:37:40,596 We only care about what numbers are in each of the spaces, yup? 859 00:37:40,996 --> 00:37:43,646 >> So, are the corners, the pipes and all that stuff is sort 860 00:37:43,646 --> 00:37:44,616 of outside of the array? 861 00:37:45,306 --> 00:37:46,956 >> Yes, so are these corners and pipes and stuff, 862 00:37:47,046 --> 00:37:48,956 so the array doesn't even know they exist. 863 00:37:49,376 --> 00:37:50,606 So these are gonna be drawn in one 864 00:37:50,606 --> 00:37:52,626 of those different draw functions that we looked at. 865 00:37:53,646 --> 00:37:56,296 So, similarly with the cursor if I have it in the middle 866 00:37:56,296 --> 00:37:59,796 of the board, I'm in row 4 column 4. 867 00:38:00,136 --> 00:38:02,606 Even though I have a bunch of space at the beginning 868 00:38:02,606 --> 00:38:05,686 and these minus signs so just keep in that in mind 869 00:38:05,686 --> 00:38:06,566 as you're writing your code. 870 00:38:06,936 --> 00:38:09,596 Even though we have all these pretty aesthetics as far 871 00:38:09,596 --> 00:38:12,636 as those global variables inside the structure are concerned it's 872 00:38:12,636 --> 00:38:16,316 just a 9 by 9 grid and there's no fancy aesthetics. 873 00:38:17,156 --> 00:38:19,976 So questions based on that? 874 00:38:20,086 --> 00:38:24,956 >> So it just shows the cursor in the center 875 00:38:24,956 --> 00:38:29,606 of the board to start off with? 876 00:38:29,606 --> 00:38:34,126 >> Yes. So yes, so it's starts off in the center 877 00:38:34,126 --> 00:38:37,056 of the board, other questions? 878 00:38:37,896 --> 00:38:39,586 Okay so-- yup? 879 00:38:39,586 --> 00:38:39,653 [ Inaudible Remark ] 880 00:38:39,653 --> 00:38:40,806 >> So this, so when you just fight-- 881 00:38:40,806 --> 00:38:43,216 when you do a git clone on Pset 4 and you just fire 882 00:38:43,216 --> 00:38:44,856 up sudoku, this is what you get. 883 00:38:45,496 --> 00:38:47,036 So, all of these are already done for you. 884 00:38:47,206 --> 00:38:48,976 And the way that we're displaying this is 885 00:38:48,976 --> 00:38:50,166 with the ncurses library. 886 00:38:50,556 --> 00:38:52,636 So, if you flip through all the draw functions, you'll see lots 887 00:38:52,636 --> 00:38:55,966 of moves and move ad characters and stuff like that. 888 00:38:56,556 --> 00:38:58,356 So, it's just a set of a real-- 889 00:38:58,356 --> 00:39:00,456 like a lot of functions that someone else wrote for you 890 00:39:00,596 --> 00:39:02,236 that allows you to do things 891 00:39:02,236 --> 00:39:07,116 like this a lot easier, so that's our board. 892 00:39:07,116 --> 00:39:10,006 So, now let's take a look at how we would move it. 893 00:39:11,066 --> 00:39:14,216 So in order to move the cursor, all we need to do is change 894 00:39:14,416 --> 00:39:18,686 that Y and X. So, pressing a different arrow is gonna do a 895 00:39:18,686 --> 00:39:19,556 different thing, right? 896 00:39:19,556 --> 00:39:23,956 We're gonna need to make Y go up or down or make X go up or down. 897 00:39:24,276 --> 00:39:26,056 Because we can only move in one direction at a time 898 00:39:26,056 --> 00:39:27,106 and don't worry about diagonals 899 00:39:27,106 --> 00:39:30,526 and we're only changing one of these at a time. 900 00:39:30,526 --> 00:39:33,396 So right now, if we go back to main, you'll notice 901 00:39:33,426 --> 00:39:35,146 that it only has a few cases. 902 00:39:35,696 --> 00:39:45,246 If we go too far, way too far, so here in main we have the case 903 00:39:45,946 --> 00:39:49,096 that you hit an N, the case you hit an R, 904 00:39:49,096 --> 00:39:52,086 and the case you hit a Control L. So, here is probably 905 00:39:52,086 --> 00:39:53,466 where I wanna put the case 906 00:39:53,466 --> 00:39:56,296 in which I had the key up, what do I want to do? 907 00:39:56,296 --> 00:40:00,926 So, you probably wanna write some function that says 908 00:40:01,256 --> 00:40:04,186 if I hit something that's not already defined I wanna take 909 00:40:04,186 --> 00:40:04,696 some action. 910 00:40:05,446 --> 00:40:07,576 >> So one thing to keep in mind if we don't want allow the user 911 00:40:07,576 --> 00:40:10,836 to move the cursor off the board, so that includes moving, 912 00:40:11,296 --> 00:40:14,986 you know, into the edge or moving over to the D in sudoku. 913 00:40:15,316 --> 00:40:17,546 And we just wanna make sure that the user stays 914 00:40:17,546 --> 00:40:20,126 within this 9 by 9 grid area. 915 00:40:20,616 --> 00:40:22,626 So before you just arbitrarily 916 00:40:22,626 --> 00:40:25,216 like blindly make X bigger every time you wanna make sure 917 00:40:25,216 --> 00:40:27,046 that you're still within the board before you can make 918 00:40:27,046 --> 00:40:27,926 X larger. 919 00:40:28,486 --> 00:40:33,746 So, questions on how we can go about moving the cursor, yup? 920 00:40:34,396 --> 00:40:39,446 >> You can go back one slide [inaudible]? 921 00:40:39,616 --> 00:40:41,676 >> So when we move-- when we hit some arrow key, 922 00:40:41,676 --> 00:40:45,316 we just wanna modify this global struct and change the X and Y 923 00:40:45,316 --> 00:40:47,566 and then the next time we call show cursor, 924 00:40:47,656 --> 00:40:50,036 the cursor's gonna move because that's what that function does, 925 00:40:50,036 --> 00:40:52,866 just reads those values and changes the cursor, yup? 926 00:40:52,976 --> 00:40:55,126 >> Do you have to modify the case switch so that 927 00:40:55,566 --> 00:40:57,886 if we use your [inaudible] left, right, 928 00:40:57,886 --> 00:41:02,036 up or down then the case switch automatically changes? 929 00:41:02,036 --> 00:41:05,296 >> Exactly, so we need to modify this case switch 930 00:41:05,296 --> 00:41:08,296 in adding some new cases because this, everything inside 931 00:41:08,296 --> 00:41:10,976 of this case switch is everything the user can possibly 932 00:41:10,976 --> 00:41:14,346 do which right now is NR control L. So, 933 00:41:14,346 --> 00:41:17,036 if we wanna allow the user to press some button we just need 934 00:41:17,036 --> 00:41:23,986 to add a new case and define what pressing that button does. 935 00:41:24,766 --> 00:41:29,406 Other questions on moving the cursor? 936 00:41:29,516 --> 00:41:33,546 Okay, so now let's take a look at inputting numbers. 937 00:41:34,256 --> 00:41:37,606 So, remember that we need to take the numbers 1 through 9 938 00:41:37,606 --> 00:41:40,766 as input and these are not going to be returned from getch 939 00:41:40,806 --> 00:41:43,626 as the number one, it would be returned as the character one, 940 00:41:43,626 --> 00:41:45,816 so just remind if our ASCII works. 941 00:41:46,146 --> 00:41:47,386 Quotes one is not one, 942 00:41:47,766 --> 00:41:50,716 quotes one is instead quote zero, plus one. 943 00:41:50,716 --> 00:41:53,516 So you can still do these things like add a character 944 00:41:53,516 --> 00:41:54,886 to an integer and it will work fine. 945 00:41:55,796 --> 00:41:57,656 But just remember that when the user types one, 946 00:41:57,956 --> 00:41:59,986 if you think that's gonna be the integer value one, 947 00:42:00,376 --> 00:42:04,766 then your code's gonna be little bit off. 948 00:42:04,956 --> 00:42:07,776 So, representing the board is gonna be very similar 949 00:42:07,776 --> 00:42:08,796 to what we did in 50. 950 00:42:09,256 --> 00:42:12,716 Board is going to be these two dimensional grid and inside 951 00:42:12,716 --> 00:42:16,526 of board IJ is gonna be the number at row I column J 952 00:42:16,756 --> 00:42:19,416 because ncurses works in YX not in XY. 953 00:42:20,066 --> 00:42:22,186 So, you know that the cursor is always 954 00:42:22,396 --> 00:42:28,406 at row g.y column g.x. So, if we change the value of the board 955 00:42:28,606 --> 00:42:31,846 at IJ it's gonna change the number that's displayed. 956 00:42:32,556 --> 00:42:35,406 However, if we just changed it immediately that's not actually 957 00:42:35,406 --> 00:42:37,036 gonna change what's displayed on the terminal 958 00:42:37,416 --> 00:42:40,246 because that's not changed until we explicitly call one 959 00:42:40,246 --> 00:42:41,406 of our draw functions. 960 00:42:41,866 --> 00:42:43,546 So those draw functions are just gonna look 961 00:42:43,546 --> 00:42:46,696 at what's stored inside of this board and iterate through it 962 00:42:46,696 --> 00:42:48,766 and print out whatever is there basically. 963 00:42:49,866 --> 00:42:50,806 So again, we don't need 964 00:42:50,806 --> 00:42:54,306 to use this ncurses function move add character ourselves we 965 00:42:54,306 --> 00:42:55,846 can just change the board 966 00:42:55,996 --> 00:42:58,516 and redraw it using some redraw function 967 00:42:58,656 --> 00:43:00,276 that was written for us. 968 00:43:00,936 --> 00:43:03,126 But keep in mind that as far as efficiency is concerned 969 00:43:03,126 --> 00:43:05,186 if I just a type in a number, I probably don't need 970 00:43:05,186 --> 00:43:07,006 to change all the plus signs and the minus signs. 971 00:43:07,576 --> 00:43:09,876 So just make sure you're using the right draw function 972 00:43:09,876 --> 00:43:11,016 but you can kind of look at each of them, 973 00:43:11,276 --> 00:43:13,766 they're self-explanatory just make sure you're not redrawing 974 00:43:13,806 --> 00:43:14,526 things that you don't need 975 00:43:14,526 --> 00:43:17,036 to redraw 'cause that's a little bit of a ding on efficiency. 976 00:43:17,036 --> 00:43:22,336 So, one thing we need to keep in mind is we can't allow the user 977 00:43:22,336 --> 00:43:24,486 to change the numbers that came with the board. 978 00:43:24,916 --> 00:43:26,476 Else I would just saying 1, 2, 3, 4, 5, 979 00:43:26,476 --> 00:43:28,766 6 and I'd win really fast. 980 00:43:28,766 --> 00:43:32,546 So, once the game has started we need some way of remembering 981 00:43:32,546 --> 00:43:34,766 which numbers were already on the board. 982 00:43:35,406 --> 00:43:38,576 So, if I go and try to change a number that was already 983 00:43:38,576 --> 00:43:42,086 on the board, your program says nope, can't do that. 984 00:43:43,036 --> 00:43:44,756 So just a tip, if I have some array 985 00:43:44,756 --> 00:43:47,186 like say it was called a G dot board for some reason 986 00:43:47,526 --> 00:43:49,526 and I just tried to set it equal to some other array, 987 00:43:49,836 --> 00:43:50,866 that's not going to work. 988 00:43:51,906 --> 00:43:53,016 So, you need to figure out a way 989 00:43:53,016 --> 00:43:55,576 to effectively copy your original array 990 00:43:55,576 --> 00:43:58,126 into some other array that you keep track of somehow 991 00:43:58,336 --> 00:43:59,916 and before you change any space, 992 00:44:00,296 --> 00:44:02,496 make sure that you're allowed to change it. 993 00:44:03,466 --> 00:44:04,756 So, questions on how that would work? 994 00:44:07,916 --> 00:44:12,556 Cool. So inside of our case switch statement 995 00:44:12,556 --> 00:44:14,866 to make things a little easier you can actually do something 996 00:44:14,866 --> 00:44:17,346 like this and combine cases. 997 00:44:17,736 --> 00:44:20,896 So, this says in the case of an A, or in the case of a B, 998 00:44:20,896 --> 00:44:23,526 or in the case C, I wanna take some action. 999 00:44:24,286 --> 00:44:26,616 So instead of saying case A, have some code, 1000 00:44:26,616 --> 00:44:29,346 copy paste that into case B, copy paste that into case C, 1001 00:44:29,426 --> 00:44:31,666 we can combine them just like this. 1002 00:44:31,976 --> 00:44:34,306 So this is effectively A, or B, 1003 00:44:34,306 --> 00:44:37,636 or C. So as I mentioned before we also have a special case 1004 00:44:37,636 --> 00:44:40,116 called default and that's going to be the else. 1005 00:44:40,416 --> 00:44:42,196 The if, none of these cases are true, 1006 00:44:42,196 --> 00:44:43,496 I still wanna do something. 1007 00:44:43,876 --> 00:44:46,626 It's gonna jump to this default case automatically. 1008 00:44:47,816 --> 00:44:49,906 So questions on how I'm combining these cases here? 1009 00:44:51,276 --> 00:44:52,496 You'll find this to be super helpful. 1010 00:44:52,496 --> 00:44:59,936 All right, so now just a word about design. 1011 00:45:01,006 --> 00:45:04,016 As you're designing your code, you wanna try to factor 1012 00:45:04,016 --> 00:45:05,816 out as much code as possible. 1013 00:45:05,816 --> 00:45:06,856 And what do I wanna mean by that? 1014 00:45:07,176 --> 00:45:08,556 So if you find yourself, you know, 1015 00:45:08,556 --> 00:45:11,456 writing the same three lines of code all over the place 1016 00:45:11,456 --> 00:45:14,246 which you may, you kind of wanna factor that out 1017 00:45:14,446 --> 00:45:19,656 into some function that you can reuse so instead of copying 1018 00:45:19,656 --> 00:45:22,036 and pasting code all over the place which is a very, 1019 00:45:22,036 --> 00:45:24,186 very nice temptation, what you wanna do is try 1020 00:45:24,186 --> 00:45:26,416 to design functions that are reusable 1021 00:45:26,416 --> 00:45:27,696 so I can use this function here 1022 00:45:27,826 --> 00:45:29,836 and even though this case is a little different I can still use 1023 00:45:29,836 --> 00:45:31,726 my function here because it takes some argument 1024 00:45:31,726 --> 00:45:33,286 or something like that. 1025 00:45:33,826 --> 00:45:36,386 And, also rather than going in and having all 1026 00:45:36,386 --> 00:45:39,006 of your codes stay in main you probably wanna create your 1027 00:45:39,006 --> 00:45:39,876 own functions. 1028 00:45:40,216 --> 00:45:41,596 So in 15, we did that for you. 1029 00:45:41,596 --> 00:45:43,166 We said here's the function called init, 1030 00:45:43,356 --> 00:45:44,706 it's probably a good size 1031 00:45:44,706 --> 00:45:46,336 for a single function put your code there. 1032 00:45:46,336 --> 00:45:48,656 In this case we're not really holding your hand that much 1033 00:45:49,306 --> 00:45:52,656 but what we do wanna do is take our changes and kind 1034 00:45:52,656 --> 00:45:54,736 of consolidate them into separate functions, 1035 00:45:55,106 --> 00:45:57,386 that from the existing code we can just call 1036 00:45:57,386 --> 00:46:00,466 that function instead of just adding swats of code to our main 1037 00:46:00,466 --> 00:46:02,566 or the draw numbers or whatever it is you need to modify. 1038 00:46:03,146 --> 00:46:07,666 So, questions on inputting a number, yup? 1039 00:46:09,016 --> 00:46:10,986 >> Can you go over again about the arrays 1040 00:46:10,986 --> 00:46:14,126 and why we can't use an array? 1041 00:46:14,126 --> 00:46:15,906 >> So you can't-- so you can use an array 1042 00:46:15,906 --> 00:46:17,276 and you probably want to. 1043 00:46:17,726 --> 00:46:23,126 But if I want to take array one and make a copy of array 2. 1044 00:46:23,246 --> 00:46:25,306 So, I have this existing array, array 2 1045 00:46:25,306 --> 00:46:26,876 and I wanna copy it into array 1. 1046 00:46:26,876 --> 00:46:29,326 I can't just say array 1 equals array 2 1047 00:46:30,006 --> 00:46:31,606 because this is just a pointer right? 1048 00:46:31,916 --> 00:46:33,996 So, it's just a reference to some memory address. 1049 00:46:34,286 --> 00:46:37,166 So, if I do this I just make array 1 and array 2 point 1050 00:46:37,166 --> 00:46:40,166 to the same memory address I didn't actually copy the values. 1051 00:46:40,526 --> 00:46:43,096 So, if I change array 1, array 2 is gonna change too 1052 00:46:43,096 --> 00:46:44,806 because they're just looking at the same location. 1053 00:46:45,096 --> 00:46:48,576 So you need to explicitly copy your array. 1054 00:46:50,746 --> 00:46:53,206 Other questions on inputting numbers, yup? 1055 00:46:53,756 --> 00:46:55,706 >> The user is inputting something 1056 00:46:55,706 --> 00:46:59,576 that we're thing that that's a char? 1057 00:46:59,576 --> 00:46:59,686 >> Yes. 1058 00:46:59,856 --> 00:47:02,736 >> You need to store that into the array with int array? 1059 00:47:02,736 --> 00:47:02,846 >> Yes. 1060 00:47:02,846 --> 00:47:04,756 >> So how is that working? 1061 00:47:04,886 --> 00:47:07,156 >> So we need to convert a char into an int. 1062 00:47:07,156 --> 00:47:09,886 So, this is very similar to what we did in Pset 2 1063 00:47:09,886 --> 00:47:11,236 with our [inaudible], we needed 1064 00:47:11,236 --> 00:47:13,696 to convert some char into an int. 1065 00:47:14,256 --> 00:47:15,456 So we're gonna do the same thing here. 1066 00:47:15,456 --> 00:47:18,896 The user types in a 1, we need to actually store a 1 inside 1067 00:47:18,896 --> 00:47:20,926 of our board not ASCII value of 1. 1068 00:47:21,346 --> 00:47:25,286 Other questions, yup? 1069 00:47:25,596 --> 00:47:28,226 >> Will you use the A-tui [phonetic] function to do that? 1070 00:47:28,226 --> 00:47:30,586 >> So, would you use the -tui function to do that? 1071 00:47:30,586 --> 00:47:34,086 So, A-tui takes some string, returns an integer 1072 00:47:34,496 --> 00:47:37,306 so we're not taking strings, we're taking single characters 1073 00:47:38,186 --> 00:47:40,306 so we basically need to look at the ASCII table and say, 1074 00:47:40,306 --> 00:47:43,256 "what value do I need to add or subtract in order to get 1075 00:47:43,336 --> 00:47:46,076 from quote zero to just the number zero?" 1076 00:47:46,526 --> 00:47:51,386 Other questions on inputting numbers? 1077 00:47:51,916 --> 00:47:57,546 Okay, so now for kind of the meat of the problem set. 1078 00:47:58,176 --> 00:48:03,096 Determining if a move is legal so in this case, after we-- 1079 00:48:03,096 --> 00:48:06,096 and we enter any number, we need to check if that's a legal move. 1080 00:48:06,726 --> 00:48:10,076 And if it's not a legal move we wanna use this show better 1081 00:48:10,076 --> 00:48:11,876 function and say this is wrong. 1082 00:48:11,876 --> 00:48:15,206 So, just-- to avoid some confusion if I type 1083 00:48:15,206 --> 00:48:18,106 in a wrong move and I show the banner it's wrong 1084 00:48:18,236 --> 00:48:20,686 and then I type in a right move, my banner is gone. 1085 00:48:21,216 --> 00:48:22,586 And a few set makes this very explicit, 1086 00:48:22,586 --> 00:48:23,726 it doesn't need to persist. 1087 00:48:24,016 --> 00:48:26,596 But every time there is an illegal move, so the banner 1088 00:48:27,016 --> 00:48:29,296 and it just on it's like consider move by move. 1089 00:48:29,296 --> 00:48:30,236 You don't need to look at it 1090 00:48:30,236 --> 00:48:32,016 if there's still an illegal move on the board. 1091 00:48:32,476 --> 00:48:34,056 Just if it's a legal move show the banner 1092 00:48:34,236 --> 00:48:38,436 if it's not a legal move, don't show the banner. 1093 00:48:38,536 --> 00:48:40,006 So here are the three rules again 1094 00:48:40,166 --> 00:48:41,516 to make sure the move to be legal. 1095 00:48:42,096 --> 00:48:44,446 The number doesn't already exist in the same row, 1096 00:48:44,846 --> 00:48:46,906 the number doesn't already exist in the same column, 1097 00:48:47,166 --> 00:48:50,586 and the number doesn't already exist in the same 3 by 3 block. 1098 00:48:51,066 --> 00:48:53,336 So we need to check each of these cases. 1099 00:48:53,726 --> 00:48:56,006 There might be a temptation to get a little fancy here. 1100 00:48:56,116 --> 00:48:58,126 My advice is you don't because there a lot of things 1101 00:48:58,126 --> 00:49:00,536 that you're like, "Oh this probably works, right?" 1102 00:49:00,536 --> 00:49:02,606 And it probably doesn't unfortunately. 1103 00:49:02,816 --> 00:49:06,256 There are very few fancy ways of doing this so I'd advice you 1104 00:49:06,256 --> 00:49:08,676 to actually check each of these cases exclusively. 1105 00:49:08,936 --> 00:49:10,756 There isn't some mysterious design thing 1106 00:49:10,756 --> 00:49:11,796 that you should be picking up on. 1107 00:49:11,796 --> 00:49:13,166 You need to check all these cases. 1108 00:49:13,166 --> 00:49:17,326 So let's take a look at the row and the column case. 1109 00:49:17,966 --> 00:49:20,876 So we know that a user just inputted a number 1110 00:49:20,876 --> 00:49:24,326 into G dot board, g.y, g.x 'cause that the row 1111 00:49:24,326 --> 00:49:25,326 and the column of a cursor. 1112 00:49:25,686 --> 00:49:27,016 So whenever we make a change, 1113 00:49:27,416 --> 00:49:28,726 that's where the change just happened. 1114 00:49:29,236 --> 00:49:33,786 So in order to check everything in the same row and everything 1115 00:49:33,786 --> 00:49:37,106 in the same column, we just need to have some iterator 1116 00:49:37,136 --> 00:49:39,036 over the row and over the column. 1117 00:49:39,576 --> 00:49:42,796 So, we need to check if we just inputted something into zero, 1118 00:49:42,796 --> 00:49:46,906 zero, we need to check 0, 0, 0, 1, 0, 2, 0, 3, 0, 1119 00:49:46,906 --> 00:49:49,456 4 and similarly in the other direction. 1120 00:49:50,406 --> 00:49:53,596 So if the number is already found we know the move 1121 00:49:53,596 --> 00:49:54,426 is illegal. 1122 00:49:54,986 --> 00:49:58,676 So questions on what I mean by legality here? 1123 00:49:58,676 --> 00:50:00,996 So just if it's already in the row or it's already 1124 00:50:00,996 --> 00:50:03,416 in the column and we know the row in the column 1125 00:50:03,576 --> 00:50:06,366 that these are inputted then we know it's an illegal move 1126 00:50:06,366 --> 00:50:06,936 and we need to show the banner. 1127 00:50:08,096 --> 00:50:10,226 >> So, here's what I mean by that. 1128 00:50:10,426 --> 00:50:13,836 So if I just inputted this dot, here is my row everything 1129 00:50:13,836 --> 00:50:16,656 in row zero and the column is going from zero to 8 and inside 1130 00:50:16,656 --> 00:50:19,766 of my column, that second part of my array stays the same 1131 00:50:19,766 --> 00:50:22,126 and my rows are going again from zero to 8. 1132 00:50:22,126 --> 00:50:25,496 Does that make sense? 1133 00:50:25,536 --> 00:50:28,606 So, a harder one is the 3 by 3 block. 1134 00:50:29,056 --> 00:50:32,576 So notice that the board is divided into these contiguous 3 1135 00:50:32,576 --> 00:50:34,126 by 3 blocks so there are 9 of them. 1136 00:50:34,496 --> 00:50:37,896 So, if I input something onto this first block I only need 1137 00:50:37,896 --> 00:50:38,916 to check this first block. 1138 00:50:38,916 --> 00:50:40,866 I don't need to come down here, if I inputted something 1139 00:50:40,866 --> 00:50:41,726 on the top left corner. 1140 00:50:42,496 --> 00:50:44,566 So, the way that we're gonna check that block, 1141 00:50:45,586 --> 00:50:48,216 is we need to figure out where that blocks starts. 1142 00:50:48,636 --> 00:50:50,136 So let's say that I-- we just know 1143 00:50:50,136 --> 00:50:51,616 that let's say I inputted something in the middle. 1144 00:50:51,686 --> 00:50:54,636 I can't just go 3 columns over, 1145 00:50:54,636 --> 00:50:58,046 3 rows down because then we'd be kind of combining blocks here. 1146 00:50:58,086 --> 00:50:59,216 So, even though it's a 3 1147 00:50:59,216 --> 00:51:02,226 by 3 block it is not one of the 3 by 3 blocks. 1148 00:51:02,866 --> 00:51:06,496 So in order to do that, we need to determine where each of the 3 1149 00:51:06,496 --> 00:51:09,276 by 3 block starts which sounds like a job 1150 00:51:09,276 --> 00:51:12,496 for division very similar to what we did 1151 00:51:12,496 --> 00:51:14,006 in Pset 1 with making change. 1152 00:51:14,756 --> 00:51:17,606 So, after we determine the top left of the block then 1153 00:51:17,606 --> 00:51:20,946 at that point we can just go 3 columns over, 3 rows down, 1154 00:51:21,906 --> 00:51:23,536 and just look for that numbers. 1155 00:51:23,536 --> 00:51:25,976 So we need to actually iterate through that 3 by 3 block 1156 00:51:26,216 --> 00:51:27,466 and look at 9 numbers and look 1157 00:51:27,466 --> 00:51:28,966 if there's something that's already inputted. 1158 00:51:30,256 --> 00:51:36,386 So, questions on how we can do that, yup? 1159 00:51:36,386 --> 00:51:36,816 [ Inaudible Remark ] 1160 00:51:36,816 --> 00:51:36,896 >> Yeah. 1161 00:51:38,206 --> 00:51:42,196 >> What did you mean by that? 1162 00:51:42,586 --> 00:51:44,696 >> So just-- let's say that I inputted, 1163 00:51:44,696 --> 00:51:47,166 let's say that this board was totally blank, 1164 00:51:47,566 --> 00:51:49,526 or there are just a few numbers and I make a move. 1165 00:51:49,586 --> 00:51:51,926 And that could be at that point, it could be a legal move. 1166 00:51:52,906 --> 00:51:55,966 But it could be the wrong move like I later find out that, 1167 00:51:55,966 --> 00:51:57,156 that 6, was supposed to be a 5 1168 00:51:57,206 --> 00:51:58,806 but at the time 6 was still legal. 1169 00:51:59,316 --> 00:52:02,116 So you're not checking if it's wrong, you're only checking 1170 00:52:02,116 --> 00:52:04,516 if it's illegal or comp, you know, obviously wrong. 1171 00:52:05,186 --> 00:52:08,286 So just a subtle distinction there that because in order 1172 00:52:08,286 --> 00:52:09,856 to check if something's wrong, you actually need 1173 00:52:09,856 --> 00:52:11,976 to solve the board which is the hacker Pset, 1174 00:52:12,296 --> 00:52:13,516 so unless you wanna trick yourself 1175 00:52:13,516 --> 00:52:22,206 into doing a hacker Pset, just remember what that means, yup? 1176 00:52:22,206 --> 00:52:22,273 [ Inaudible Remark ] 1177 00:52:22,273 --> 00:52:25,136 >> So, inside of-- so G is our global structure 1178 00:52:25,286 --> 00:52:28,686 so the structure has a container for multiple variables so one 1179 00:52:28,686 --> 00:52:31,236 of those variables is board, just a two dimensional array 1180 00:52:31,236 --> 00:52:35,326 and two other integers, separate integers Y and X. And, 1181 00:52:35,326 --> 00:52:37,856 g.y is always the position of the cursor, 1182 00:52:37,856 --> 00:52:41,206 that row of the cursor and g.x is always the column 1183 00:52:41,206 --> 00:52:41,786 of the cursor. 1184 00:52:42,376 --> 00:52:44,466 So, after you implement moving the cursor, you're gonna make-- 1185 00:52:44,466 --> 00:52:46,806 you wanna make sure that those values always contain 1186 00:52:46,806 --> 00:52:47,686 where the cursor is. 1187 00:52:47,996 --> 00:52:49,226 And so now, that's how I can figure 1188 00:52:49,226 --> 00:52:52,606 out what value the user just changed or value I need 1189 00:52:52,606 --> 00:52:54,006 to change on the board, yup? 1190 00:52:54,736 --> 00:52:57,976 >> So, every time the user moves a cursor we think 1191 00:52:58,606 --> 00:53:02,216 that they're actually inputting a number? 1192 00:53:02,296 --> 00:53:03,206 >> So not necessarily. 1193 00:53:03,206 --> 00:53:05,906 So the user can-- moving the cursor is different 1194 00:53:05,906 --> 00:53:06,826 than inputting a number. 1195 00:53:07,586 --> 00:53:11,086 When I move the cursor I wanna change this g.y and this g.x. 1196 00:53:11,476 --> 00:53:13,536 When I input a number I don't wanna change 1197 00:53:13,536 --> 00:53:17,116 where the cursor is, I instead wanna change the board based 1198 00:53:17,116 --> 00:53:18,996 on where the cursor currently is. 1199 00:53:19,856 --> 00:53:22,236 So depending on if they entered in a number 1200 00:53:22,236 --> 00:53:24,366 or hit an arrow key we wanna do two different things, 1201 00:53:24,926 --> 00:53:26,266 both modifying the struct 1202 00:53:26,686 --> 00:53:32,146 but modifying different parts of the struct. 1203 00:53:32,786 --> 00:53:35,816 Other questions? 1204 00:53:36,336 --> 00:53:41,426 Okay. So, that's move legality so we also wanna allow the user 1205 00:53:41,646 --> 00:53:44,586 to remove their number especially if you're 1206 00:53:44,586 --> 00:53:45,596 as bad as sudoku as I am. 1207 00:53:46,276 --> 00:53:48,456 So, the problem said specs, problem said specs says, 1208 00:53:48,456 --> 00:53:51,046 we wanna be able to delete the number if we hit the backspace, 1209 00:53:51,046 --> 00:53:52,796 the delete key, the dot, or the zero. 1210 00:53:53,436 --> 00:53:56,036 So, again ncurses comes in with these fancy constants. 1211 00:53:56,636 --> 00:54:00,616 Key backspace, Key DC for delete dot or the number zero 1212 00:54:00,616 --> 00:54:03,666 so it just as a note as your-- right in your palm set, 1213 00:54:03,666 --> 00:54:06,106 and you notice that "Oh, my key DC doesn't work", 1214 00:54:06,106 --> 00:54:06,886 or something like that. 1215 00:54:07,176 --> 00:54:09,096 Don't worry about it it's just your computer 1216 00:54:09,096 --> 00:54:11,006 and cursors isn't ready for your computer yet. 1217 00:54:11,446 --> 00:54:14,146 The Pset mentions this in a footnote but if you just-- 1218 00:54:14,146 --> 00:54:16,356 just make sure you look at all four of these cases in order 1219 00:54:16,356 --> 00:54:18,086 for deleting a number and don't worry if something 1220 00:54:18,086 --> 00:54:19,186 like Key DC doesn't work. 1221 00:54:19,416 --> 00:54:22,866 Zero and period should definitely work though. 1222 00:54:23,076 --> 00:54:26,676 And so you notice you probably wanna do the same thing based 1223 00:54:26,676 --> 00:54:27,726 on multiple cases again. 1224 00:54:28,036 --> 00:54:30,316 Unlike we saw before, we can combine these cases 1225 00:54:30,316 --> 00:54:33,436 and only take one action instead of saying case key backspace, 1226 00:54:33,536 --> 00:54:36,836 copy paste, case key DC, copy paste and stuff like that. 1227 00:54:37,726 --> 00:54:39,706 So inside of draw numbers you'll notice 1228 00:54:39,706 --> 00:54:41,886 that a blank is represented by a zero, 1229 00:54:42,626 --> 00:54:44,366 so when we delete a key all we need 1230 00:54:44,366 --> 00:54:46,696 to do is set the board not equal 1231 00:54:46,696 --> 00:54:50,566 to whatever the user typed but a zero. 1232 00:54:50,786 --> 00:54:52,456 So, questions on blanks? 1233 00:54:53,026 --> 00:54:56,246 So again, just remember we can't delete numbers 1234 00:54:56,626 --> 00:54:58,106 that we came with-- that came with the board. 1235 00:54:58,476 --> 00:55:00,256 Now, remember I said factoring a common code, 1236 00:55:00,256 --> 00:55:01,776 this is something you need to do in two cases, 1237 00:55:01,776 --> 00:55:04,036 the user inputs a number and then makes sure 1238 00:55:04,036 --> 00:55:04,806 that I'm allowed to change it. 1239 00:55:05,116 --> 00:55:05,976 User inputs a blank. 1240 00:55:06,056 --> 00:55:07,826 I didn't make sure I'm allowed to change it. 1241 00:55:08,126 --> 00:55:11,436 So writing a reusable function here is gonna make our code much 1242 00:55:11,486 --> 00:55:12,176 better designed. 1243 00:55:12,476 --> 00:55:15,126 We're doing the same thing in two pretty different moves, 1244 00:55:15,126 --> 00:55:16,286 deleting a number and adding a number? 1245 00:55:16,336 --> 00:55:17,596 We still need to do the same thing 1246 00:55:17,856 --> 00:55:19,866 so we can call the same function. 1247 00:55:19,866 --> 00:55:22,596 So just a couple of lot of other questions, 1248 00:55:22,596 --> 00:55:24,966 is inputting a blank always legal, is it necessary check 1249 00:55:24,966 --> 00:55:27,816 for legality, and can I do need to check as the game as one 1250 00:55:27,816 --> 00:55:28,896 if I just removed the number. 1251 00:55:29,516 --> 00:55:31,946 So things like that, okay you think about efficiency. 1252 00:55:32,536 --> 00:55:34,456 I'll leave the answers to those to you. 1253 00:55:35,216 --> 00:55:37,096 So that's how we need to input a blank. 1254 00:55:37,806 --> 00:55:39,506 So any questions on what we need to do there? 1255 00:55:39,506 --> 00:55:42,116 >> It's always the last one? 1256 00:55:42,116 --> 00:55:42,386 [ Inaudible Remark ] 1257 00:55:42,386 --> 00:55:47,836 >> Right. So just-- this thing about efficiency like do I need 1258 00:55:47,836 --> 00:55:49,076 to necessarily check things? 1259 00:55:49,146 --> 00:55:51,306 If I just removed a number do I need to necessarily check 1260 00:55:51,306 --> 00:55:52,216 if the game is one now? 1261 00:55:52,846 --> 00:55:57,646 Just things like that to make your code a little bit 1262 00:55:58,126 --> 00:55:59,586 more efficient. 1263 00:55:59,586 --> 00:55:59,796 [ Inaudible Remark ] 1264 00:55:59,796 --> 00:56:03,226 >> Well no, what I'm saying is let's say that as a user, 1265 00:56:03,486 --> 00:56:05,156 I just typed in a blank. 1266 00:56:05,796 --> 00:56:05,956 >> Yeah. 1267 00:56:06,056 --> 00:56:08,776 >> As the program, did the user-- 1268 00:56:08,776 --> 00:56:09,996 it did-- by inputting a blank. 1269 00:56:09,996 --> 00:56:13,076 Did the user just win? 1270 00:56:13,276 --> 00:56:15,666 Definitely not because the board needs to be filled, 1271 00:56:15,666 --> 00:56:18,926 so just little efficiency things like that like if I just-- 1272 00:56:18,926 --> 00:56:21,126 if I just deleted the number, I definitely didn't win. 1273 00:56:21,416 --> 00:56:22,566 But if I just input a number, 1274 00:56:22,566 --> 00:56:23,876 I might have just input the last number. 1275 00:56:24,616 --> 00:56:27,126 And when I'm inputting a blank, I definitely didn't just-- 1276 00:56:27,126 --> 00:56:28,006 that was at my last move. 1277 00:56:29,336 --> 00:56:32,946 So just things little efficiency things like that, not necessary 1278 00:56:32,946 --> 00:56:35,416 to correctness but they might be handy for design. 1279 00:56:35,916 --> 00:56:38,766 Other questions? 1280 00:56:39,326 --> 00:56:45,516 So finally, we wanna check to see if the game is won. 1281 00:56:45,706 --> 00:56:47,236 And in this case, you wanna freeze the game 1282 00:56:47,236 --> 00:56:49,466 and don't allow the user to make anymore moves except 1283 00:56:49,466 --> 00:56:52,276 for starting a new game-- quitting. 1284 00:56:52,836 --> 00:56:55,046 So the game is won under these four conditions: 1285 00:56:55,456 --> 00:56:58,756 if every square is filled in and every row contains one 1286 00:56:58,756 --> 00:57:01,306 of each number, every column contains one of each number 1287 00:57:01,426 --> 00:57:04,066 and every three by three block contains one of each number. 1288 00:57:05,526 --> 00:57:08,866 So, every time the user makes a move, it's then time 1289 00:57:08,866 --> 00:57:10,266 to check if the game is won. 1290 00:57:10,266 --> 00:57:15,436 So, when you're thinking about how you're gonna implement this 1291 00:57:15,436 --> 00:57:17,406 and efficiency, you only need to look 1292 00:57:17,406 --> 00:57:19,106 at every row and column once. 1293 00:57:19,616 --> 00:57:21,466 There's no need to look at the same column twice 1294 00:57:21,466 --> 00:57:23,366 if you've already verified that that column is okay. 1295 00:57:24,186 --> 00:57:25,546 So there are couple ways you could do this. 1296 00:57:25,936 --> 00:57:28,446 You could check to see if you found every number. 1297 00:57:28,536 --> 00:57:29,846 You now, have something like in array 1298 00:57:29,846 --> 00:57:30,996 of numbers, zero through nine. 1299 00:57:31,346 --> 00:57:34,216 And every time I-- yeah, zero through nine or one-- 1300 00:57:34,216 --> 00:57:35,596 zero through eight or one through nine, 1301 00:57:35,836 --> 00:57:37,636 depend on how you set it up and just say, "Okay. 1302 00:57:37,636 --> 00:57:39,116 I found a one, that's a check mark. 1303 00:57:39,116 --> 00:57:40,316 I found the two, check that off." 1304 00:57:40,676 --> 00:57:41,926 Then once you've gone through the column, 1305 00:57:41,926 --> 00:57:44,996 see if you've check off every number or you could do something 1306 00:57:44,996 --> 00:57:47,276 like see how many times you see each number. 1307 00:57:47,276 --> 00:57:49,066 And if you ever see a number twice then it's definitely 1308 00:57:49,066 --> 00:57:49,446 not won. 1309 00:57:49,446 --> 00:57:51,986 So there are bunch of different ways to do this but it all boils 1310 00:57:51,986 --> 00:57:55,276 down to keeping track of what you've seen in a single row 1311 00:57:55,276 --> 00:57:57,146 or column and making sure that that's good 1312 00:57:57,146 --> 00:57:59,446 to go before you move on to the next row or column. 1313 00:57:59,446 --> 00:58:02,176 So using an array here is probably a good way 1314 00:58:02,176 --> 00:58:02,866 to approach this. 1315 00:58:03,206 --> 00:58:04,656 And again, this is where you have the tendency 1316 00:58:04,656 --> 00:58:06,986 to maybe I can get fancy here, don't. 1317 00:58:08,256 --> 00:58:10,756 Similarly, we only need to check every three 1318 00:58:10,756 --> 00:58:11,566 by three square once. 1319 00:58:11,646 --> 00:58:13,266 So there's no need to keep checking one 1320 00:58:13,266 --> 00:58:15,836 if you've already looked at that square, so you notice 1321 00:58:15,836 --> 00:58:17,566 that we we're thinking about move legality, 1322 00:58:17,566 --> 00:58:20,386 we probably already wrote a function to see if there's 1323 00:58:20,626 --> 00:58:23,616 about like having a given three by three block is valid. 1324 00:58:23,686 --> 00:58:25,406 So that's just one way of thinking 1325 00:58:25,406 --> 00:58:26,426 about designing your code. 1326 00:58:26,426 --> 00:58:28,986 I'm doing similar things and checking if the move is legal 1327 00:58:29,276 --> 00:58:31,036 and checking if the board is won. 1328 00:58:31,486 --> 00:58:33,696 So, design your functions to be reusable. 1329 00:58:34,156 --> 00:58:37,036 And so, just another efficiency question, 1330 00:58:37,036 --> 00:58:38,876 you notice we have these four conditions. 1331 00:58:38,876 --> 00:58:41,426 Do we really need to check the first one 1332 00:58:41,426 --> 00:58:42,666 if the last three are true? 1333 00:58:43,496 --> 00:58:45,306 I don't know. 1334 00:58:46,516 --> 00:58:51,096 So just-- lest you forget, reuse as much code as possible. 1335 00:58:51,096 --> 00:58:54,386 It'll make your Pset much more elegant and better designed. 1336 00:58:54,636 --> 00:58:58,036 And you'll get more points and we'll be happy. 1337 00:58:58,036 --> 00:59:00,726 So any questions on checking if the board is won? 1338 00:59:01,236 --> 00:59:01,366 Yup? 1339 00:59:03,996 --> 00:59:07,926 >> Should we be checking like every move or should we wait 1340 00:59:08,516 --> 00:59:09,876 until the whole board is-- ? 1341 00:59:09,996 --> 00:59:11,806 >> So should we be checking every move or shall we wait 1342 00:59:11,806 --> 00:59:12,756 for the whole board to be filled. 1343 00:59:12,756 --> 00:59:14,496 That's a question for you unfortunately. 1344 00:59:14,496 --> 00:59:16,926 You know, which-- which way do you think is more efficient, 1345 00:59:16,926 --> 00:59:18,516 or which way is the code more elegant, 1346 00:59:18,736 --> 00:59:20,866 which way is gonna run more efficiently, you know, 1347 00:59:21,606 --> 00:59:22,976 determine when your one is checked. 1348 00:59:23,646 --> 00:59:25,736 Okay, so just to recap, the question was do we need 1349 00:59:25,736 --> 00:59:28,726 to only check if one after every move for or do we need to-- 1350 00:59:28,726 --> 00:59:30,776 or can we just wait until we know every square is filled in? 1351 00:59:30,776 --> 00:59:32,056 That's kind of a question for you. 1352 00:59:32,056 --> 00:59:34,266 Which of those ends up to be more efficient based 1353 00:59:34,266 --> 00:59:35,766 on your code, is it more efficient to look 1354 00:59:35,766 --> 00:59:38,536 at every square and then see if it's won or is it more efficient 1355 00:59:38,536 --> 00:59:40,916 to every time you make a move even if it's the first move, 1356 00:59:40,916 --> 00:59:41,746 look at every single square. 1357 00:59:42,486 --> 00:59:43,296 So that's up to you. 1358 00:59:43,296 --> 00:59:44,556 And as you run your code, you know, 1359 00:59:44,556 --> 00:59:45,596 you'll probably make a decision, 1360 00:59:45,596 --> 00:59:48,666 oh this one is way better, I'm gonna do that. 1361 00:59:48,886 --> 00:59:50,396 Other questions on the Pset as a whole? 1362 00:59:50,396 --> 00:59:50,606 Yup? 1363 00:59:51,076 --> 00:59:53,896 >> You said checking every numbers like doing a search 1364 00:59:53,956 --> 00:59:54,926 and you said don't be fancy. 1365 00:59:55,266 --> 00:59:57,456 So, when you're looking at efficiency, you wanna see 1366 00:59:57,456 --> 00:59:59,216 like really efficient searches or-- 1367 00:59:59,216 --> 01:00:03,676 or can you really just be like looking 1368 01:00:03,676 --> 01:00:03,976 through like [inaudible]? 1369 01:00:04,046 --> 01:00:05,266 >> So what do I mean by don't get fancy? 1370 01:00:05,266 --> 01:00:07,466 So I do mean-- so I don't mean like trying 1371 01:00:07,466 --> 01:00:08,686 to binary search the sudoku. 1372 01:00:08,686 --> 01:00:10,266 That's not what we mean by efficient. 1373 01:00:10,806 --> 01:00:13,616 But things like I'm gonna multiply every number 1374 01:00:13,616 --> 01:00:14,646 and see if it equals this. 1375 01:00:14,916 --> 01:00:16,446 That's like a fancy thing. 1376 01:00:16,856 --> 01:00:19,896 That's not gonna work, so don't do that. 1377 01:00:19,896 --> 01:00:22,796 So, just stick to these-- stick to those three rules. 1378 01:00:22,796 --> 01:00:24,546 Let's say you're doing fancy like actually check 1379 01:00:24,546 --> 01:00:25,566 if every number is there. 1380 01:00:25,806 --> 01:00:27,836 >> Okay. So efficiency isn't necessary if you 1381 01:00:28,036 --> 01:00:28,996 like smart researchers or everything 1382 01:00:28,996 --> 01:00:30,906 and like binary [inaudible]? 1383 01:00:33,346 --> 01:00:34,536 >> Right. So I mean in this case, 1384 01:00:34,536 --> 01:00:35,936 we can't really binary search it right? 1385 01:00:35,936 --> 01:00:38,696 It just doesn't really apply to this problem and so, yes. 1386 01:00:38,696 --> 01:00:40,296 So based on this problem, 1387 01:00:40,516 --> 01:00:41,956 the most efficient way we can do this is 1388 01:00:41,956 --> 01:00:43,176 to actually look at every square. 1389 01:00:44,516 --> 01:00:44,906 >> Okay. 1390 01:00:44,906 --> 01:00:47,386 >> Instead of trying to do some like I just discovered this 1391 01:00:47,386 --> 01:00:49,156 and I made a breakthrough in sudoku algorithm. 1392 01:00:49,856 --> 01:00:51,796 Just look at every single one. 1393 01:00:53,886 --> 01:00:55,866 Other questions on the piece that has a whole? 1394 01:00:56,266 --> 01:00:56,366 Yup? 1395 01:00:56,956 --> 01:00:59,376 >> You recommend implementing each of these features 1396 01:00:59,456 --> 01:01:01,046 in the order that you listed them? 1397 01:01:01,716 --> 01:01:02,316 >> Yes, I do. 1398 01:01:02,316 --> 01:01:03,876 And in fact that's why I listed them in that order. 1399 01:01:03,876 --> 01:01:06,546 I do recommend [laughter] implementing them in this order 1400 01:01:06,546 --> 01:01:07,606 and that should be a numbered list. 1401 01:01:07,606 --> 01:01:08,316 That's actually my fault. 1402 01:01:08,646 --> 01:01:10,456 So yes, so, implementing in this order is kind 1403 01:01:10,456 --> 01:01:12,096 of just a logical way of stepping through it 1404 01:01:12,286 --> 01:01:14,476 and the functions that you wrote in the beginning steps, 1405 01:01:14,826 --> 01:01:15,806 you'll probably end up using 1406 01:01:15,806 --> 01:01:17,486 in the functions you wrote in the later steps. 1407 01:01:18,866 --> 01:01:21,986 So, reusable code is kind of our goal with this Pset. 1408 01:01:23,896 --> 01:01:25,816 So just before-- you don't-- 1409 01:01:25,816 --> 01:01:27,226 remember that you need to implement one 1410 01:01:27,226 --> 01:01:29,186 of these additional features which I've listed here 1411 01:01:29,186 --> 01:01:30,736 and won't read to you 'cause you can read-- 1412 01:01:31,486 --> 01:01:33,476 just make sure you do at least one of these. 1413 01:01:33,736 --> 01:01:35,896 If you wanna do more than one, go for it. 1414 01:01:36,066 --> 01:01:40,356 Become your TF's favorite student 1415 01:01:41,296 --> 01:01:47,126 but last questions on sudoku. 1416 01:01:47,346 --> 01:01:47,446 Yup? 1417 01:01:47,446 --> 01:01:47,513 [ Inaudible Remark ] 1418 01:01:47,513 --> 01:01:51,546 >> Sure. So, when you input a number, so, could we just go 1419 01:01:51,546 --> 01:01:54,456 like back to how we can reuse code and something 1420 01:01:54,456 --> 01:01:55,966 like checking or inputting a blank? 1421 01:01:56,666 --> 01:01:58,046 So, when we inputted number. 1422 01:01:58,606 --> 01:02:01,056 We need to make sure that the number that we're trying to-- 1423 01:02:01,056 --> 01:02:03,786 the space we're trying to change did not come with the board. 1424 01:02:04,606 --> 01:02:07,156 Now when we input a blank, we need to make sure 1425 01:02:07,156 --> 01:02:07,956 that the number we're trying 1426 01:02:07,956 --> 01:02:10,026 to delete did not come with the board. 1427 01:02:10,536 --> 01:02:13,796 So if you just have some generic function that said, "Does this-- 1428 01:02:13,856 --> 01:02:15,626 did the space come with the board?" 1429 01:02:16,326 --> 01:02:18,766 Then you can reuse that in the multiple-- 1430 01:02:18,766 --> 01:02:21,386 multiple parts of the problem that you're trying to solve. 1431 01:02:21,386 --> 01:02:23,106 So that's what I mean by a reuse code. 1432 01:02:23,106 --> 01:02:25,606 Write some function once and use it as much 1433 01:02:25,606 --> 01:02:26,316 as your heart desires. 1434 01:02:26,856 --> 01:02:30,236 Are there questions on anything sudoku? 1435 01:02:30,236 --> 01:02:35,736 All right, then that's it for the walkthrough 1436 01:02:35,736 --> 01:02:36,886 and good luck with Pset 4.