1 00:00:01,550 --> 00:00:03,920 The following content is provided under a Creative 2 00:00:03,920 --> 00:00:05,310 Commons license. 3 00:00:05,310 --> 00:00:07,520 Your support will help MIT OpenCourseWare 4 00:00:07,520 --> 00:00:11,610 continue to offer high quality educational resources for free. 5 00:00:11,610 --> 00:00:14,180 To make a donation or to view additional materials 6 00:00:14,180 --> 00:00:18,140 from hundreds of MIT courses, visit MIT OpenCourseWare 7 00:00:18,140 --> 00:00:19,026 at ocw.mit.edu. 8 00:00:22,140 --> 00:00:27,390 INSTRUCTOR: So today, we start on project 4, which is, 9 00:00:27,390 --> 00:00:29,640 as you know, the big project. 10 00:00:29,640 --> 00:00:35,430 And Helen is going to do a walkthrough of the project, 11 00:00:35,430 --> 00:00:37,920 and the code, and the organization, 12 00:00:37,920 --> 00:00:41,400 because this is a pretty big sized project. 13 00:00:41,400 --> 00:00:44,400 It's got about 4,500 lines of code. 14 00:00:44,400 --> 00:00:50,460 And it's not code that is kind of like simple code. 15 00:00:50,460 --> 00:00:53,070 It's all content-bearing code. 16 00:00:53,070 --> 00:00:57,630 So I think having a bit of an orientation to it, 17 00:00:57,630 --> 00:00:59,910 more than we give for the other codes that you work, 18 00:00:59,910 --> 00:01:03,670 on which are pretty small, this will be great. 19 00:01:03,670 --> 00:01:05,650 So, Helen, take it away. 20 00:01:05,650 --> 00:01:07,900 HELEN XU: Hi, everyone. 21 00:01:07,900 --> 00:01:09,445 Can you hear me? 22 00:01:09,445 --> 00:01:11,820 Awesome, so today we're going to be doing the walkthrough 23 00:01:11,820 --> 00:01:12,750 for the final project. 24 00:01:12,750 --> 00:01:16,050 You can look at the code and clone it publicly here. 25 00:01:16,050 --> 00:01:19,110 And please remember to fill up your team's by 7:00 PM today, 26 00:01:19,110 --> 00:01:23,380 so we can populate the list and get your repos. 27 00:01:23,380 --> 00:01:25,530 Yeah, and if there are any issues accessing this, 28 00:01:25,530 --> 00:01:26,800 just let me know. 29 00:01:26,800 --> 00:01:30,570 Or put it on Piazza and then we can fix it. 30 00:01:30,570 --> 00:01:33,270 So we just had a game of Lesierchess. 31 00:01:33,270 --> 00:01:34,860 But in case you missed it, we'll go 32 00:01:34,860 --> 00:01:37,630 into more details about what the game actually does. 33 00:01:37,630 --> 00:01:40,290 So first, we're going to go through the game rules. 34 00:01:40,290 --> 00:01:42,960 So you saw that there are these pieces. 35 00:01:42,960 --> 00:01:44,030 There's these triangles. 36 00:01:44,030 --> 00:01:44,780 And there's kings. 37 00:01:44,780 --> 00:01:46,440 So the triangles are pawns. 38 00:01:46,440 --> 00:01:48,320 And the kings, they look like crowns. 39 00:01:48,320 --> 00:01:49,320 And there are two teams. 40 00:01:49,320 --> 00:01:52,050 There's orange and lavender, or tangerine and lavender. 41 00:01:52,050 --> 00:01:55,830 And each side starts out with seven pawns and one king. 42 00:01:55,830 --> 00:01:57,280 And this is the starting position. 43 00:01:57,280 --> 00:01:59,280 So you can see like the kings are in the corner. 44 00:01:59,280 --> 00:02:02,040 And they're just lined up like in the middle. 45 00:02:02,040 --> 00:02:04,600 And each piece has four orientations. 46 00:02:04,600 --> 00:02:09,880 So you can see that the pawn is up, down, left, right. 47 00:02:09,880 --> 00:02:12,510 And then the king is also like that. 48 00:02:12,510 --> 00:02:18,600 And in general, the game starts with tangerine moving first. 49 00:02:18,600 --> 00:02:21,090 And then the play alternates between the two players. 50 00:02:21,090 --> 00:02:23,613 Each piece moves the same, whether it's king or pawn. 51 00:02:23,613 --> 00:02:24,780 And each turn has two parts. 52 00:02:24,780 --> 00:02:26,050 So you saw the demo. 53 00:02:26,050 --> 00:02:27,582 But you move first. 54 00:02:27,582 --> 00:02:29,790 When you pick one of your pieces, and you move first. 55 00:02:29,790 --> 00:02:32,850 And then at the end, your King has to fire the laser. 56 00:02:32,850 --> 00:02:35,280 And the laser reflects off the long edge of the pawn. 57 00:02:35,280 --> 00:02:38,220 And they'll kill the pawn if it shoots the short edges. 58 00:02:38,220 --> 00:02:40,470 And one side wins when the king gets shot, 59 00:02:40,470 --> 00:02:43,800 or when the opposing king gets shot, whether by themselves 60 00:02:43,800 --> 00:02:47,107 or by your own king. 61 00:02:47,107 --> 00:02:48,690 And so I talked a little about moving. 62 00:02:48,690 --> 00:02:51,510 And at the beginning of each turn, the player to move 63 00:02:51,510 --> 00:02:53,340 chooses a piece to move. 64 00:02:53,340 --> 00:02:55,475 And you can move your King or any of your pawns. 65 00:02:55,475 --> 00:02:56,850 And there are two types of moves. 66 00:02:56,850 --> 00:03:00,210 There's basic moves, and swat moves. 67 00:03:00,210 --> 00:03:03,720 And basic moves are just, basically, shifts or rotations. 68 00:03:03,720 --> 00:03:07,990 So in the example, you can rotate 90, 180, or 270 degrees. 69 00:03:07,990 --> 00:03:10,340 So in the top, row you just rotate. 70 00:03:10,340 --> 00:03:11,920 This is the example of moving a pawn. 71 00:03:11,920 --> 00:03:13,290 So you rotate your pawn. 72 00:03:13,290 --> 00:03:15,390 Or you can move to an empty adjacent square. 73 00:03:15,390 --> 00:03:16,800 So those are the bottom two rows. 74 00:03:16,800 --> 00:03:19,300 And there are eight adjacent squares in this example. 75 00:03:19,300 --> 00:03:20,513 So there are eight shifts. 76 00:03:20,513 --> 00:03:21,930 But there would be less than eight 77 00:03:21,930 --> 00:03:26,130 if you were, for example, like at the edge of the board. 78 00:03:26,130 --> 00:03:29,203 And on a move, you can either shift or rotate. 79 00:03:29,203 --> 00:03:30,120 But you can't do both. 80 00:03:32,840 --> 00:03:34,500 There are also these swap loops. 81 00:03:34,500 --> 00:03:38,668 So if you're adjacent to an opposing piece, 82 00:03:38,668 --> 00:03:39,710 you can switch with them. 83 00:03:39,710 --> 00:03:41,543 And then you have to make another basic move 84 00:03:41,543 --> 00:03:43,190 after that, that is not a swap. 85 00:03:43,190 --> 00:03:45,518 So, basically, you can either-- 86 00:03:45,518 --> 00:03:47,060 and it has to be with that same piece 87 00:03:47,060 --> 00:03:48,200 that you just swapped with. 88 00:03:48,200 --> 00:03:51,380 So you just either shift or rotate. 89 00:03:51,380 --> 00:03:52,630 Is everyone good on the rules? 90 00:03:56,570 --> 00:03:58,040 Just a couple more things. 91 00:03:58,040 --> 00:03:59,600 So there's this Ko rule, which is 92 00:03:59,600 --> 00:04:02,240 from Go, which ensures that the game makes progress. 93 00:04:02,240 --> 00:04:06,258 So it makes a move illegal if it undoes the opponent's most 94 00:04:06,258 --> 00:04:08,550 recent move by just moving back to where you just were. 95 00:04:11,223 --> 00:04:12,140 So this is an example. 96 00:04:12,140 --> 00:04:13,820 Let's say you're tangerine. 97 00:04:13,820 --> 00:04:16,070 And you swapped with the purple one right next to you. 98 00:04:16,070 --> 00:04:21,740 And then you shifted left and bottom. 99 00:04:21,740 --> 00:04:26,360 And so lavender can return by swapping back 100 00:04:26,360 --> 00:04:29,930 with your orange piece, and shifting again. 101 00:04:29,930 --> 00:04:32,180 But this is actually, illegal because now 102 00:04:32,180 --> 00:04:34,880 you just got to your original position. 103 00:04:34,880 --> 00:04:37,520 So you're not allowed to just keep cycling back and forth. 104 00:04:41,520 --> 00:04:44,850 And so a draw occurs if there have been 50 moves by each side 105 00:04:44,850 --> 00:04:47,730 without a pawn being zapped, the same position 106 00:04:47,730 --> 00:04:49,632 repeats itself by the side on move, 107 00:04:49,632 --> 00:04:51,090 or the two players agree to a draw. 108 00:04:56,140 --> 00:04:58,040 So just kind of like in chess, a chess clock 109 00:04:58,040 --> 00:05:00,457 limits the amount of time the players have to make a move. 110 00:05:00,457 --> 00:05:02,500 So you can't just keep competing indefinitely. 111 00:05:02,500 --> 00:05:04,810 When it's your moves, your clock counts down. 112 00:05:04,810 --> 00:05:07,780 When it's your opponent's moves, your clock stops. 113 00:05:07,780 --> 00:05:09,097 So it's not counting your time. 114 00:05:09,097 --> 00:05:10,430 And we used Fisher time control. 115 00:05:10,430 --> 00:05:12,013 There's a picture of Bobby Fisher, who 116 00:05:12,013 --> 00:05:15,970 made it, up which used an initial time budget and a time 117 00:05:15,970 --> 00:05:16,600 increment. 118 00:05:16,600 --> 00:05:20,212 So in this example, there's fis60 and 0.5, 119 00:05:20,212 --> 00:05:21,670 which means that, in the beginning, 120 00:05:21,670 --> 00:05:23,840 each player has 60 seconds. 121 00:05:23,840 --> 00:05:26,050 And you get to use the 60 seconds however you want. 122 00:05:26,050 --> 00:05:30,520 And when you end your move, you get 0.5 extra seconds. 123 00:05:30,520 --> 00:05:34,152 But the 60 and 0.5 could be anything. 124 00:05:34,152 --> 00:05:35,110 That's just an example. 125 00:05:38,572 --> 00:05:40,530 So we'll go into an example of how you actually 126 00:05:40,530 --> 00:05:41,520 play this game. 127 00:05:41,520 --> 00:05:43,290 For a king to zap the enemy king, 128 00:05:43,290 --> 00:05:46,020 it risks opening itself to counter-attack. 129 00:05:46,020 --> 00:05:47,730 So look at this example. 130 00:05:47,730 --> 00:05:51,370 And how can tangerine zap the lavender pawn in F5, 131 00:05:51,370 --> 00:05:52,650 by moving one of its pieces? 132 00:06:03,430 --> 00:06:05,140 AUDIENCE: [INAUDIBLE] 133 00:06:06,800 --> 00:06:07,550 HELEN XU: Move C4. 134 00:06:11,410 --> 00:06:13,690 AUDIENCE: Tangerine, that's lavender. 135 00:06:13,690 --> 00:06:16,440 HELEN XU: You're tangerine in this example. 136 00:06:16,440 --> 00:06:18,580 And you're trying to zap the one on F5. 137 00:06:26,060 --> 00:06:27,990 Yep? 138 00:06:27,990 --> 00:06:33,290 AUDIENCE: You move the tangerine piece at E22 to F1. 139 00:06:33,290 --> 00:06:34,235 HELEN XU: E2 to F1. 140 00:06:41,120 --> 00:06:43,500 Oh, sorry, by zap, it means shoot the backside. 141 00:06:46,290 --> 00:06:49,960 That would shoot the long side. 142 00:06:49,960 --> 00:06:52,450 Good point. 143 00:06:52,450 --> 00:06:56,348 Yeah, so you're trying to kill the piece on F5. 144 00:06:56,348 --> 00:06:59,330 AUDIENCE: [INAUDIBLE] 145 00:06:59,330 --> 00:07:01,060 HELEN XU: Yeah, exactly. 146 00:07:01,060 --> 00:07:07,090 So in this, you can move C2 to B1, as you just said. 147 00:07:07,090 --> 00:07:09,210 And then you draw the path. 148 00:07:09,210 --> 00:07:14,190 And you can see that you've just killed-- 149 00:07:14,190 --> 00:07:17,460 or if you're tangerine, you've just killed the piece at F5. 150 00:07:17,460 --> 00:07:18,930 Now, how can lavender counter? 151 00:07:18,930 --> 00:07:21,660 By counter, we mean lavender can win 152 00:07:21,660 --> 00:07:22,860 the game from this position. 153 00:07:29,210 --> 00:07:30,875 AUDIENCE: Is it A4 to A3? 154 00:07:35,460 --> 00:07:36,280 HELEN XU: A4 to A3. 155 00:07:40,680 --> 00:07:42,570 No, I don't think so. 156 00:07:42,570 --> 00:07:43,706 Yep? 157 00:07:43,706 --> 00:07:46,580 AUDIENCE: [INAUDIBLE] 158 00:07:46,580 --> 00:07:48,640 HELEN XU: Sorry, what? 159 00:07:48,640 --> 00:07:52,135 King, like the orange one? 160 00:07:52,135 --> 00:07:53,010 Oh, the lavender one. 161 00:07:57,120 --> 00:07:59,030 You're trying to shoot the orange king. 162 00:08:02,720 --> 00:08:05,190 Oh, yes, you're right. 163 00:08:05,190 --> 00:08:08,180 You can, actually. 164 00:08:08,180 --> 00:08:10,490 Yes, good, that's not the one that we had, 165 00:08:10,490 --> 00:08:13,080 but apparently there are two ways. 166 00:08:13,080 --> 00:08:14,540 Good. 167 00:08:14,540 --> 00:08:16,060 So if you notice you could also-- 168 00:08:16,060 --> 00:08:17,360 that's another way to get that path. 169 00:08:17,360 --> 00:08:18,985 But you can also move one of the pawns. 170 00:08:21,570 --> 00:08:26,830 Cool, so this is just pointing out 171 00:08:26,830 --> 00:08:29,440 one of the subtleties of the game, which is you 172 00:08:29,440 --> 00:08:33,309 should watch out for just naively killing 173 00:08:33,309 --> 00:08:35,559 all the pieces you can, because that might open you up 174 00:08:35,559 --> 00:08:39,520 to the opponent. 175 00:08:39,520 --> 00:08:41,159 Yeah? 176 00:08:41,159 --> 00:08:42,890 AUDIENCE: [INAUDIBLE] 177 00:08:42,890 --> 00:08:45,233 HELEN XU: Yes, it can be from any direction. 178 00:08:45,233 --> 00:08:46,900 But the pawns only die if you shoot them 179 00:08:46,900 --> 00:08:48,570 from not on the long edge. 180 00:08:48,570 --> 00:08:49,450 Yep? 181 00:08:49,450 --> 00:08:52,750 AUDIENCE: What if you shoot your own block? 182 00:08:52,750 --> 00:08:54,550 HELEN XU: By block, you mean your own pawn? 183 00:08:54,550 --> 00:08:55,120 AUDIENCE: Yeah. 184 00:08:55,120 --> 00:08:55,995 HELEN XU: You'll die. 185 00:08:55,995 --> 00:08:57,435 AUDIENCE: Oh. 186 00:08:57,435 --> 00:08:58,060 HELEN XU: Yeah? 187 00:09:00,590 --> 00:09:02,238 AUDIENCE: [INAUDIBLE] 188 00:09:07,000 --> 00:09:09,880 HELEN XU: Yes, but only one piece can be on each square. 189 00:09:09,880 --> 00:09:13,450 But you can have as many near you. 190 00:09:13,450 --> 00:09:16,120 But do you have a question? 191 00:09:16,120 --> 00:09:20,120 AUDIENCE: Can you make it impossible to kill your person? 192 00:09:20,120 --> 00:09:21,990 HELEN XU: Like your King? 193 00:09:21,990 --> 00:09:24,510 Like if you barricaded it by pawns. 194 00:09:24,510 --> 00:09:27,080 But then the opponent can come in and swap with them, 195 00:09:27,080 --> 00:09:30,990 so it will open your barricade. 196 00:09:30,990 --> 00:09:33,610 AUDIENCE: Can the purple king shoot upward? 197 00:09:33,610 --> 00:09:35,018 HELEN XU: If it wanted to. 198 00:09:35,018 --> 00:09:37,435 But then in this example, it would shoot up off the board, 199 00:09:37,435 --> 00:09:38,477 and nothing would happen. 200 00:09:38,477 --> 00:09:39,703 Yeah? 201 00:09:39,703 --> 00:09:41,620 AUDIENCE: When you kill a pawn, does the laser 202 00:09:41,620 --> 00:09:44,427 stop at the place where the pawn is or does it 203 00:09:44,427 --> 00:09:45,260 go through the pawn? 204 00:09:45,260 --> 00:09:49,110 HELEN XU: No, it just shoots one. 205 00:09:49,110 --> 00:09:52,445 Good questions. 206 00:09:52,445 --> 00:09:53,320 Everyone good so far? 207 00:09:56,550 --> 00:09:57,690 OK, great. 208 00:09:57,690 --> 00:10:00,330 PROFESSOR: This year, it shoots only one. 209 00:10:00,330 --> 00:10:03,854 Last year, it kept shooting. 210 00:10:03,854 --> 00:10:05,967 AUDIENCE: Can the king shoot itself? 211 00:10:05,967 --> 00:10:06,550 HELEN XU: Yes. 212 00:10:09,330 --> 00:10:10,788 It should try not to, but it can. 213 00:10:10,788 --> 00:10:11,830 So you should be careful. 214 00:10:21,890 --> 00:10:26,150 So moving on-- we use force Fosythe-Edwards Notation, 215 00:10:26,150 --> 00:10:30,290 which is a representation of a chess position using a string. 216 00:10:30,290 --> 00:10:33,860 So you can see an example of the starting position. 217 00:10:33,860 --> 00:10:35,888 And the bottom includes the string 218 00:10:35,888 --> 00:10:37,430 that describes the starting position. 219 00:10:40,610 --> 00:10:42,670 If you look at the representation, 220 00:10:42,670 --> 00:10:45,310 the arrow corresponds to one of the rows. 221 00:10:45,310 --> 00:10:50,860 And that points to the substring that has a bubble over it. 222 00:10:50,860 --> 00:10:55,360 So in this row, there is one purple pawn at B3, 223 00:10:55,360 --> 00:10:59,470 and two orange ones at F3 and G3. 224 00:10:59,470 --> 00:11:01,170 So this is row three. 225 00:11:01,170 --> 00:11:04,090 And the slashes separate the rows in the string. 226 00:11:04,090 --> 00:11:06,190 And the one represents there's an empty space. 227 00:11:06,190 --> 00:11:07,990 And then there's a pawn facing southeast. 228 00:11:07,990 --> 00:11:10,690 And then there's three empty spaces, and one facing 229 00:11:10,690 --> 00:11:13,090 northwest, and then one facing southeast, and then 230 00:11:13,090 --> 00:11:14,806 an empty space. 231 00:11:14,806 --> 00:11:16,740 AUDIENCE: [INAUDIBLE] 232 00:11:16,740 --> 00:11:19,382 HELEN XU: Oh, yeah, it's animated. 233 00:11:25,990 --> 00:11:26,890 What do you mean? 234 00:11:30,710 --> 00:11:34,560 Yeah, so at the end of the string, there's also a-- 235 00:11:34,560 --> 00:11:37,547 it just tells you which side's move it is. 236 00:11:37,547 --> 00:11:38,880 So this is the opening position. 237 00:11:38,880 --> 00:11:42,550 But you can use any position in this notation. 238 00:11:42,550 --> 00:11:44,010 And this is useful for debugging, 239 00:11:44,010 --> 00:11:46,110 because if you, for example, you're running a bot, 240 00:11:46,110 --> 00:11:47,527 and it crashes at some position. 241 00:11:47,527 --> 00:11:49,110 And you can get back to that position. 242 00:11:49,110 --> 00:11:50,250 You can start up the game and just 243 00:11:50,250 --> 00:11:52,708 go there without having to make all the moves to get there. 244 00:11:59,783 --> 00:12:01,450 And this is how you represent the games. 245 00:12:01,450 --> 00:12:03,760 So each of these is one move. 246 00:12:03,760 --> 00:12:07,330 And the left column is tangerine. 247 00:12:07,330 --> 00:12:10,780 And the right column is lavender. 248 00:12:10,780 --> 00:12:13,090 And an example, you can see E6, E7, 249 00:12:13,090 --> 00:12:17,340 means they moved a piece from E6 to E7. 250 00:12:17,340 --> 00:12:22,390 B3L, so you rotated the piece on B3 left. 251 00:12:22,390 --> 00:12:25,780 There's D5, E4, F5, which means that you swapped. 252 00:12:25,780 --> 00:12:28,180 So your original piece was on D5. 253 00:12:28,180 --> 00:12:29,590 You swapped with the one at E4. 254 00:12:29,590 --> 00:12:33,130 And now you moved that piece to F5. 255 00:12:33,130 --> 00:12:36,240 So the one that was E4 is now on F5. 256 00:12:36,240 --> 00:12:39,070 And the opposing piece is now on D5, because you swapped. 257 00:12:41,900 --> 00:12:43,490 You can swap and then rotate. 258 00:12:43,490 --> 00:12:46,160 So instead of just having a third square, 259 00:12:46,160 --> 00:12:48,620 you would just have a rotation. 260 00:12:48,620 --> 00:12:50,280 And at the end, you could see who won. 261 00:12:50,280 --> 00:12:53,560 So in this one, lavender one because it's 0-1. 262 00:12:53,560 --> 00:12:55,393 But 1-0 would mean tangerine wins. 263 00:12:55,393 --> 00:12:56,810 And half and half would be a draw. 264 00:12:59,660 --> 00:13:02,450 So you can look at the logs for your games. 265 00:13:02,450 --> 00:13:03,189 Yes? 266 00:13:03,189 --> 00:13:05,145 AUDIENCE: [INAUDIBLE] 267 00:13:07,983 --> 00:13:09,900 HELEN XU: There's a rotate up and rotate down. 268 00:13:12,545 --> 00:13:15,300 AUDIENCE: [INAUDIBLE] do a U-turn? 269 00:13:15,300 --> 00:13:16,800 HELEN XU: Oh, is that what U is? 270 00:13:16,800 --> 00:13:19,405 AUDIENCE: Yeah, U-turn. 271 00:13:19,405 --> 00:13:21,780 HELEN XU: Oh I, see because there's only three rotations. 272 00:13:21,780 --> 00:13:24,200 Yes, sorry, so left is 90. 273 00:13:24,200 --> 00:13:25,320 Then right is 270. 274 00:13:25,320 --> 00:13:27,680 And U is 180, because you flip it. 275 00:13:34,420 --> 00:13:36,193 Is everyone good on the notation? 276 00:13:36,193 --> 00:13:37,860 This is just how you describe the games, 277 00:13:37,860 --> 00:13:39,318 if you wanted to look at your logs, 278 00:13:39,318 --> 00:13:40,620 and if there are some issues. 279 00:13:43,758 --> 00:13:46,050 So you can test your bot with other teams in the class, 280 00:13:46,050 --> 00:13:48,420 as well as with staff bots on the scrimmage server. 281 00:13:48,420 --> 00:13:51,900 And we have a reference, which is here, which 282 00:13:51,900 --> 00:13:53,820 is just the additional release. 283 00:13:53,820 --> 00:13:56,595 But we will be optimizing our bots while we're 284 00:13:56,595 --> 00:13:57,470 optimizing your bots. 285 00:13:57,470 --> 00:13:59,970 And we'll release a reference plus, and maybe an even better 286 00:13:59,970 --> 00:14:02,680 one later, which you can play with on the scrimmage sever. 287 00:14:02,680 --> 00:14:04,930 So I'll just do a really quick demo. 288 00:14:04,930 --> 00:14:09,030 So right now, since we haven't done the team formation yet, 289 00:14:09,030 --> 00:14:10,905 you are not able to log into this. 290 00:14:10,905 --> 00:14:12,780 But once you do your team formation, probably 291 00:14:12,780 --> 00:14:15,000 by tomorrow, you'll be able to log in. 292 00:14:15,000 --> 00:14:17,260 And, basically, you can see the general functionality. 293 00:14:17,260 --> 00:14:19,680 So this updates your player, pulls your player 294 00:14:19,680 --> 00:14:23,380 from your repo, whatever's on the master branch. 295 00:14:23,380 --> 00:14:26,160 And then right now, there's only reference, 296 00:14:26,160 --> 00:14:28,310 and reference plus, and reference TAs. 297 00:14:28,310 --> 00:14:30,480 And here's a team with me and Jess. 298 00:14:30,480 --> 00:14:33,030 But later on, we'll populate this list 299 00:14:33,030 --> 00:14:34,180 with everyone in the class. 300 00:14:34,180 --> 00:14:35,310 And then you can challenge anybody else 301 00:14:35,310 --> 00:14:36,910 in the class to see how you do. 302 00:14:36,910 --> 00:14:38,740 You can also challenge us. 303 00:14:38,740 --> 00:14:41,080 So you would just pick, for example, 304 00:14:41,080 --> 00:14:43,020 let's say I wanted to challenge reference. 305 00:14:43,020 --> 00:14:45,300 And then a hit send challenge. 306 00:14:45,300 --> 00:14:48,220 Now, you can see that there's some new matches spawned. 307 00:14:48,220 --> 00:14:51,030 And this is how I look at all the matches that I've played. 308 00:14:51,030 --> 00:14:52,793 So each time you hit send challenge, 309 00:14:52,793 --> 00:14:54,960 it spawns off two games, one where you're tangerine, 310 00:14:54,960 --> 00:14:55,960 and one you're lavender. 311 00:14:58,270 --> 00:15:00,660 So that's how you can watch the matches on the scrimmage 312 00:15:00,660 --> 00:15:01,160 server. 313 00:15:03,467 --> 00:15:04,050 Everyone good? 314 00:15:11,683 --> 00:15:13,600 I'm going to move on so don't run out of town. 315 00:15:16,120 --> 00:15:18,500 You can watch them later. 316 00:15:18,500 --> 00:15:19,840 And you can even play your own. 317 00:15:30,270 --> 00:15:30,770 OK. 318 00:15:34,120 --> 00:15:35,870 And, in addition to the scrimmage server-- 319 00:15:35,870 --> 00:15:36,860 so the scrimmage server, you can only 320 00:15:36,860 --> 00:15:38,068 spawn off one game at a time. 321 00:15:38,068 --> 00:15:39,140 But you can do more. 322 00:15:39,140 --> 00:15:42,290 And you don't have to necessarily do it 323 00:15:42,290 --> 00:15:45,290 on your master branch, or against opposing teams 324 00:15:45,290 --> 00:15:46,160 in the class. 325 00:15:46,160 --> 00:15:48,860 So there's something called the Cloud autotester, which you can 326 00:15:48,860 --> 00:15:50,443 run by going to your Athena. 327 00:15:50,443 --> 00:15:51,860 And then you type in this command. 328 00:15:51,860 --> 00:15:52,970 You do autotest run. 329 00:15:52,970 --> 00:15:55,388 And then you do the time control. 330 00:15:55,388 --> 00:15:57,680 And you give it a number of games that you want to run. 331 00:15:57,680 --> 00:15:59,630 And then you give it a list of binaries. 332 00:15:59,630 --> 00:16:01,590 So I'll go into each of these in more detail. 333 00:16:01,590 --> 00:16:04,490 So the time control is just what I talked about earlier, which 334 00:16:04,490 --> 00:16:07,550 is if you use Fisher time control, these are some set, 335 00:16:07,550 --> 00:16:08,510 preset things. 336 00:16:08,510 --> 00:16:10,427 So you would type in one of the preset things. 337 00:16:10,427 --> 00:16:14,630 So you would talk in blitz to do 60 and 0.5, for example. 338 00:16:14,630 --> 00:16:17,780 And the number of games is just whatever you want to do. 339 00:16:17,780 --> 00:16:19,310 And the list of binaries-- so let's 340 00:16:19,310 --> 00:16:21,800 say you had a reference invalidation, 341 00:16:21,800 --> 00:16:23,120 and then you made some change. 342 00:16:23,120 --> 00:16:25,670 So I called it Lesierchess with changes. 343 00:16:25,670 --> 00:16:27,800 And then you would just put those 344 00:16:27,800 --> 00:16:30,165 after the number of games, separated by spaces. 345 00:16:30,165 --> 00:16:31,790 And then it would upload your binaries, 346 00:16:31,790 --> 00:16:34,130 and play them in the cloud auto tester. 347 00:16:34,130 --> 00:16:37,520 And once you submit your job, you get a link. 348 00:16:37,520 --> 00:16:39,200 And you follow the link in your browser. 349 00:16:39,200 --> 00:16:40,993 And you can view the game running. 350 00:16:40,993 --> 00:16:42,410 And then after the games are done, 351 00:16:42,410 --> 00:16:45,950 you will get some output saying like, which bot, one more? 352 00:16:45,950 --> 00:16:50,950 And how many times have won, and some rankings. 353 00:16:50,950 --> 00:16:52,181 Yep? 354 00:16:52,181 --> 00:16:54,830 AUDIENCE: How fast do they run? 355 00:16:54,830 --> 00:16:57,200 HELEN XU: How fast do they run? 356 00:16:57,200 --> 00:16:58,427 AUDIENCE: [INAUDIBLE] 357 00:17:04,550 --> 00:17:06,819 HELEN XU: So it depends on how many other games are 358 00:17:06,819 --> 00:17:07,819 queued at the same time. 359 00:17:07,819 --> 00:17:09,579 So if a lot of people are running tests, 360 00:17:09,579 --> 00:17:10,579 it might take some time. 361 00:17:10,579 --> 00:17:13,732 But blitz is just how long the game itself will take. 362 00:17:13,732 --> 00:17:15,440 And it might take longer than 60 seconds, 363 00:17:15,440 --> 00:17:19,819 because if you use less than 0.5 seconds in your move, 364 00:17:19,819 --> 00:17:22,190 and then you add 0.5 seconds at the end of the move, 365 00:17:22,190 --> 00:17:25,579 then you would increase your time. 366 00:17:25,579 --> 00:17:29,630 But 60 is just the time control. 367 00:17:29,630 --> 00:17:31,465 Each side starts with 60 seconds. 368 00:17:31,465 --> 00:17:33,840 And depending on how they use it, they have more or less. 369 00:17:33,840 --> 00:17:34,820 Good question. 370 00:17:40,220 --> 00:17:41,137 Well, I'll keep going. 371 00:17:41,137 --> 00:17:43,762 And if there's time at the end, I'll do a demo of this one too. 372 00:17:43,762 --> 00:17:46,190 But it basically looks the same as the scrimmage server. 373 00:17:46,190 --> 00:17:48,148 Like, you just watch the games in the same way. 374 00:17:50,530 --> 00:17:53,030 So now, I'm going to go into the project organization, which 375 00:17:53,030 --> 00:17:54,613 is the organization of the directories 376 00:17:54,613 --> 00:17:56,850 that we handed out in this repo. 377 00:17:56,850 --> 00:17:58,100 So there are some directories. 378 00:17:58,100 --> 00:17:59,850 The first one is doc, which just includes 379 00:17:59,850 --> 00:18:02,760 the rules and documentation for the interface. 380 00:18:02,760 --> 00:18:05,840 There's the auto tester, which is the Java local auto tester. 381 00:18:05,840 --> 00:18:08,000 So if the cloud-- 382 00:18:08,000 --> 00:18:10,740 we recommend that you run tests using the cloud auto tester. 383 00:18:10,740 --> 00:18:15,730 But if there's some small change, or if you think that-- 384 00:18:15,730 --> 00:18:18,560 if the cue is too long, then you can do local tests. 385 00:18:18,560 --> 00:18:21,530 And you can also run these overnight. 386 00:18:21,530 --> 00:18:23,990 There's pgnstates, which just parses your statistics 387 00:18:23,990 --> 00:18:26,420 from the auto test results, like how many times you won, 388 00:18:26,420 --> 00:18:27,860 stuff like that. 389 00:18:27,860 --> 00:18:30,230 There's tests, which is how you specify tests. 390 00:18:30,230 --> 00:18:34,627 And I'll go into more detail about how you define this. 391 00:18:34,627 --> 00:18:36,710 There's the player, which is where you're actually 392 00:18:36,710 --> 00:18:37,668 going to be optimizing. 393 00:18:37,668 --> 00:18:39,860 So player is the code that actually 394 00:18:39,860 --> 00:18:41,540 runs the bot to play the game. 395 00:18:41,540 --> 00:18:44,960 And the webgui is a local webgui where you can watch the game 396 00:18:44,960 --> 00:18:45,500 and play it. 397 00:18:45,500 --> 00:18:49,100 So in the webgui, you can even play it yourself as a human 398 00:18:49,100 --> 00:18:51,270 so you can get a better sense of how the game works. 399 00:18:54,027 --> 00:18:56,110 To go into more detail, the Java local auto tester 400 00:18:56,110 --> 00:18:57,080 is an auto tester. 401 00:19:00,107 --> 00:19:02,690 You can make your changes, and then you can test your changes. 402 00:19:02,690 --> 00:19:06,270 And the test directory, which is parallel, holds configurations. 403 00:19:06,270 --> 00:19:09,260 So you can specify the number of games and the bots 404 00:19:09,260 --> 00:19:11,270 that you want to use, and the time control, 405 00:19:11,270 --> 00:19:12,830 and other things too. 406 00:19:12,830 --> 00:19:14,600 So this an example of the configuration 407 00:19:14,600 --> 00:19:16,670 file that you would use to run your auto tester. 408 00:19:16,670 --> 00:19:19,292 So this is saying that you run it on 12 CPUs. 409 00:19:19,292 --> 00:19:20,750 And book means that you're pointing 410 00:19:20,750 --> 00:19:23,640 to open a book, which I'll talk about later. 411 00:19:23,640 --> 00:19:26,140 Game rounds is how many games you're going to spawn off. 412 00:19:26,140 --> 00:19:28,840 Title is just the title of the test that you're running. 413 00:19:28,840 --> 00:19:30,840 And after that, you have the player definitions. 414 00:19:30,840 --> 00:19:33,860 So player reference is just the binary. 415 00:19:33,860 --> 00:19:37,250 And invoke is the path to the binary. 416 00:19:37,250 --> 00:19:39,770 And then fis is the time control. 417 00:19:39,770 --> 00:19:42,042 And the next one is just a second binary, 418 00:19:42,042 --> 00:19:44,000 if you made a change and you want to test them. 419 00:19:47,470 --> 00:19:48,470 Yeah, that's the binary. 420 00:19:52,600 --> 00:19:54,510 To interface with auto tester, Lesierchess 421 00:19:54,510 --> 00:19:57,730 uses the universal chest interface, or UCI, 422 00:19:57,730 --> 00:20:00,010 which is a communication protocol for automatic games. 423 00:20:00,010 --> 00:20:03,100 And you pass information between the auto tester and your bot. 424 00:20:03,100 --> 00:20:05,530 And it allows the programmer or the auto tester 425 00:20:05,530 --> 00:20:07,590 to enter moves to the game engine. 426 00:20:07,590 --> 00:20:10,060 So you could use UCI to start up your bot. 427 00:20:10,060 --> 00:20:11,860 And then you type in the moves that you 428 00:20:11,860 --> 00:20:14,290 want to make to see the changes in the state. 429 00:20:14,290 --> 00:20:16,420 And you could use this to debug to get to a state 430 00:20:16,420 --> 00:20:17,462 that you want to look at. 431 00:20:21,570 --> 00:20:23,790 We'll measure the bots using Elo ratings. 432 00:20:23,790 --> 00:20:26,880 So Elo is a rating system that measures relative skill 433 00:20:26,880 --> 00:20:29,010 level in zero sum games. 434 00:20:29,010 --> 00:20:32,550 The Elo rating depends on the Elo rating of your opponents. 435 00:20:32,550 --> 00:20:35,550 And on the bottom, you can see an example output. 436 00:20:35,550 --> 00:20:38,040 So I had three binaries. 437 00:20:38,040 --> 00:20:41,100 And I ran about 100 games. 438 00:20:41,100 --> 00:20:43,710 And you can see that the Elo of the top one 439 00:20:43,710 --> 00:20:45,360 is much higher than the other ones. 440 00:20:45,360 --> 00:20:47,940 And so higher Elo is good. 441 00:20:47,940 --> 00:20:50,490 And we'll be comparing the performance. 442 00:20:50,490 --> 00:20:53,100 We'll be comparing the Elo of your bot against our reference, 443 00:20:53,100 --> 00:20:56,520 and improved reference implementations. 444 00:20:56,520 --> 00:20:59,730 So notice that this is not, as before, 445 00:20:59,730 --> 00:21:01,680 just a straight measure of time. 446 00:21:01,680 --> 00:21:03,750 So like before, in previous projects, 447 00:21:03,750 --> 00:21:07,170 if you used less time, than you would get a higher 448 00:21:07,170 --> 00:21:08,935 grade or better performance. 449 00:21:08,935 --> 00:21:10,560 In general, I'll show you a graph later 450 00:21:10,560 --> 00:21:12,477 that actually shows if you searched the higher 451 00:21:12,477 --> 00:21:15,250 depth, which means that you are faster, you do improve. 452 00:21:15,250 --> 00:21:17,230 But it's not an exact correlation. 453 00:21:17,230 --> 00:21:19,290 And you can look at the nodes per second 454 00:21:19,290 --> 00:21:22,380 that you search using the UCI. 455 00:21:25,730 --> 00:21:28,700 And just above here, to local webgui lets you watch a game, 456 00:21:28,700 --> 00:21:31,100 or play one, without sending it to the scrimmage server. 457 00:21:31,100 --> 00:21:32,767 So if you wanted to play one as a human, 458 00:21:32,767 --> 00:21:34,550 you would use the local webgui. 459 00:21:34,550 --> 00:21:38,610 And you can run it using the commands in the readme. 460 00:21:38,610 --> 00:21:41,128 OK, so is everyone good so far? 461 00:21:41,128 --> 00:21:43,670 Now, I'm going to go into more details about how you actually 462 00:21:43,670 --> 00:21:44,253 play the game. 463 00:21:49,580 --> 00:21:52,843 So first, every player, or every bot, 464 00:21:52,843 --> 00:21:54,260 needs to generate the moves, which 465 00:21:54,260 --> 00:21:55,970 means that once you have a position, 466 00:21:55,970 --> 00:21:58,810 you need to look at the moves that you can do. 467 00:21:58,810 --> 00:22:01,070 And to do that, you need a board representation, which 468 00:22:01,070 --> 00:22:03,380 is to represent what pieces are on the board, 469 00:22:03,380 --> 00:22:06,290 and how big the board is, and where the pieces are. 470 00:22:06,290 --> 00:22:09,500 And the reference implantation uses a 16 by 16 board 471 00:22:09,500 --> 00:22:11,300 to store an 8 by 8 board. 472 00:22:11,300 --> 00:22:14,300 So you can see that the inner squares is actually the board. 473 00:22:14,300 --> 00:22:16,940 And the outer dark square is sentinels. 474 00:22:16,940 --> 00:22:18,380 So you use sentinels to keep track 475 00:22:18,380 --> 00:22:19,855 of when you go off the board. 476 00:22:19,855 --> 00:22:21,980 And then the inner square is just the actual board. 477 00:22:24,980 --> 00:22:26,870 We store the position using this struct. 478 00:22:26,870 --> 00:22:31,010 So you can see the fields in the position, which are the board. 479 00:22:31,010 --> 00:22:32,900 And the array size is just representing 480 00:22:32,900 --> 00:22:34,730 the board, plus the sentinels. 481 00:22:34,730 --> 00:22:36,450 And there's the history of the position, 482 00:22:36,450 --> 00:22:38,060 which is, how did we get here? 483 00:22:38,060 --> 00:22:40,960 And there's a key, which is a hash key for this position. 484 00:22:40,960 --> 00:22:43,550 There is ply, which tells you what side it is. 485 00:22:43,550 --> 00:22:44,840 So even means white. 486 00:22:44,840 --> 00:22:46,282 And odd means black. 487 00:22:46,282 --> 00:22:47,990 There is, what was the last move that was 488 00:22:47,990 --> 00:22:49,930 made to get to this position? 489 00:22:49,930 --> 00:22:52,790 There's a victim struct, which is the pieces destroyed 490 00:22:52,790 --> 00:22:55,030 by when you shot the laser. 491 00:22:55,030 --> 00:22:58,310 And there is the location of the kings. 492 00:22:58,310 --> 00:23:00,102 The position struct and Lesierchess struct 493 00:23:00,102 --> 00:23:02,060 stores the border presentation and other things 494 00:23:02,060 --> 00:23:03,102 that I just went through. 495 00:23:07,870 --> 00:23:13,030 So I talked about this move, which means just like a move 496 00:23:13,030 --> 00:23:14,990 that you make for one of your pieces. 497 00:23:14,990 --> 00:23:16,750 And I'll go into how it's represented. 498 00:23:16,750 --> 00:23:19,390 So right now, we already do the packing for you. 499 00:23:19,390 --> 00:23:21,190 So we use 28 bits. 500 00:23:21,190 --> 00:23:25,420 And the first two are the piece type. 501 00:23:25,420 --> 00:23:28,930 So there's a number of moves that you can make. 502 00:23:28,930 --> 00:23:31,300 And the first two bits represents the piece type, 503 00:23:31,300 --> 00:23:35,212 which is empty, pawn, king, or invalid. 504 00:23:35,212 --> 00:23:36,670 The orientation of the piece, which 505 00:23:36,670 --> 00:23:39,910 is just how you rotated it. 506 00:23:39,910 --> 00:23:44,177 The from square, which is where your piece already started. 507 00:23:44,177 --> 00:23:45,760 There's the intermediate square, which 508 00:23:45,760 --> 00:23:48,220 is used when you do a swap. 509 00:23:48,220 --> 00:23:50,770 And there's a two square, which is the final position 510 00:23:50,770 --> 00:23:52,990 that your piece will end up in. 511 00:23:52,990 --> 00:23:55,780 So if you're not doing a swap, then the intermediate and from 512 00:23:55,780 --> 00:23:56,892 should be the same. 513 00:23:56,892 --> 00:23:58,600 But if you are doing a swap, then there's 514 00:23:58,600 --> 00:23:59,830 some skipping that happens. 515 00:24:03,050 --> 00:24:04,940 At each turn, you need to see what 516 00:24:04,940 --> 00:24:06,410 moves you could possibly make. 517 00:24:06,410 --> 00:24:10,520 And in move gen, which is one of the files in the handout, 518 00:24:10,520 --> 00:24:12,440 we generate all the moves, given a position, 519 00:24:12,440 --> 00:24:13,690 depending on whose turn it is. 520 00:24:13,690 --> 00:24:15,065 So depending on whose turn it is, 521 00:24:15,065 --> 00:24:16,333 you can make different moves. 522 00:24:16,333 --> 00:24:17,750 And in the reference implantation, 523 00:24:17,750 --> 00:24:19,550 we iterate through the entire board. 524 00:24:19,550 --> 00:24:22,430 And once we find a piece, we generate all the moves 525 00:24:22,430 --> 00:24:23,210 from that piece. 526 00:24:26,790 --> 00:24:28,560 You can also debug using move generation. 527 00:24:28,560 --> 00:24:31,710 So there's something called perft, 528 00:24:31,710 --> 00:24:33,600 which is a debugging function that enumerates 529 00:24:33,600 --> 00:24:35,220 all moves at a certain depth. 530 00:24:35,220 --> 00:24:37,830 So use perft to make sure that if you make changes to the move 531 00:24:37,830 --> 00:24:39,205 generation that you're generating 532 00:24:39,205 --> 00:24:41,080 the same number of moves. 533 00:24:41,080 --> 00:24:42,763 And if you modify the move generated, 534 00:24:42,763 --> 00:24:44,430 just make sure that it returns the same, 535 00:24:44,430 --> 00:24:46,110 because regardless of what optimizations 536 00:24:46,110 --> 00:24:48,735 you do, you still should see the same moves from each position 537 00:24:48,735 --> 00:24:49,860 that you can possibly make. 538 00:24:58,500 --> 00:25:01,200 OK, so now that we talked about move generation, 539 00:25:01,200 --> 00:25:03,960 I'll talk about how you tell that a move is good. 540 00:25:03,960 --> 00:25:07,350 And for that, we use something called static evaluation. 541 00:25:07,350 --> 00:25:09,505 So we use static evaluation to determine 542 00:25:09,505 --> 00:25:11,130 which positions are better than others, 543 00:25:11,130 --> 00:25:13,230 and which moves that we should make. 544 00:25:13,230 --> 00:25:16,590 And the function eval, which is in eval.c, 545 00:25:16,590 --> 00:25:18,450 generate a score based on a position, 546 00:25:18,450 --> 00:25:20,280 using some heuristics. 547 00:25:20,280 --> 00:25:23,203 And at first, we suggest, instead of making up 548 00:25:23,203 --> 00:25:24,870 your own heuristics, we suggest focusing 549 00:25:24,870 --> 00:25:28,290 on optimizing the existing structs and evaluation 550 00:25:28,290 --> 00:25:30,150 heuristics before coming up with new ones, 551 00:25:30,150 --> 00:25:31,890 because it's kind of hard to come up with new ones. 552 00:25:31,890 --> 00:25:33,420 And there's a lot of optimizations 553 00:25:33,420 --> 00:25:35,045 that you can make to the existing ones. 554 00:25:39,460 --> 00:25:41,410 So I've just grouped these into categories. 555 00:25:41,410 --> 00:25:43,193 So there's a few regarding the king. 556 00:25:43,193 --> 00:25:44,610 So there's one called KFACE, which 557 00:25:44,610 --> 00:25:47,220 is a bonus for your king facing the enemy king. 558 00:25:47,220 --> 00:25:48,720 There's KAGGRESSIVE, which gives you 559 00:25:48,720 --> 00:25:50,550 a bonus for if your King is closer 560 00:25:50,550 --> 00:25:51,870 to the center of the board. 561 00:25:51,870 --> 00:25:54,190 And there's MOBILITY, which counts up, basically, 562 00:25:54,190 --> 00:25:57,840 how many squares around your king are free. 563 00:25:57,840 --> 00:26:02,195 You want to be able to move your king freely. 564 00:26:02,195 --> 00:26:03,570 And there's some regarding pawns. 565 00:26:03,570 --> 00:26:07,330 So there's PCENTRAL, which gives you a bonus if your pawns are 566 00:26:07,330 --> 00:26:08,520 in the center of the board. 567 00:26:08,520 --> 00:26:11,550 And there's PBETWEEN, which basically draw a bounding box 568 00:26:11,550 --> 00:26:13,110 with both kings at the corner. 569 00:26:13,110 --> 00:26:14,805 And then you count how many pawns 570 00:26:14,805 --> 00:26:15,930 are in the center of those. 571 00:26:19,400 --> 00:26:22,520 And then there's points based on distance. 572 00:26:22,520 --> 00:26:25,460 So there's LCOVERAGE, which means laser coverage, which 573 00:26:25,460 --> 00:26:28,460 is basically you make all the possible moves that you 574 00:26:28,460 --> 00:26:29,630 can make from your position. 575 00:26:29,630 --> 00:26:31,880 And then you draw the laser path. 576 00:26:31,880 --> 00:26:34,640 And then you do some scaling to determine 577 00:26:34,640 --> 00:26:37,608 how well you can possibly cover the board, 578 00:26:37,608 --> 00:26:38,900 based on your current position. 579 00:26:41,970 --> 00:26:44,800 So that's basically how you tell if a position is good or not, 580 00:26:44,800 --> 00:26:46,861 with these heuristics. 581 00:26:50,020 --> 00:26:53,590 So I'll just go through the high level of how you actually 582 00:26:53,590 --> 00:26:54,850 play the game using search. 583 00:26:57,640 --> 00:26:59,260 So at the very highest level, there's 584 00:26:59,260 --> 00:27:01,120 something called game search trees, which 585 00:27:01,120 --> 00:27:02,873 is we've invented in search.c. 586 00:27:02,873 --> 00:27:04,540 But, basically, this is a representation 587 00:27:04,540 --> 00:27:06,400 of how you play the game. 588 00:27:06,400 --> 00:27:08,050 At the top, there's an orange square, 589 00:27:08,050 --> 00:27:10,480 which is the orange side, which is the opening 590 00:27:10,480 --> 00:27:13,900 position, and then the arrows. 591 00:27:13,900 --> 00:27:16,000 So the top square-- 592 00:27:16,000 --> 00:27:19,180 actually, all the nodes are positions in the tree. 593 00:27:19,180 --> 00:27:21,760 And you use move generation that I just talked about, 594 00:27:21,760 --> 00:27:25,690 to enumerate all the possible moves from a single position. 595 00:27:25,690 --> 00:27:27,910 And each edge is a move. 596 00:27:27,910 --> 00:27:30,790 So to get from position to position, you do moves. 597 00:27:30,790 --> 00:27:34,870 And you can see that circle is the position 598 00:27:34,870 --> 00:27:37,450 after you've made the move. 599 00:27:37,450 --> 00:27:40,690 And you do this tree to some depth d. 600 00:27:40,690 --> 00:27:45,000 And then you do static evaluation of the leaves. 601 00:27:45,000 --> 00:27:48,062 So this is at a really high level how game playing programs 602 00:27:48,062 --> 00:27:49,020 actually play the game. 603 00:27:49,020 --> 00:27:50,750 They enumerate all the possible moves. 604 00:27:50,750 --> 00:27:52,000 And then they have a position. 605 00:27:52,000 --> 00:27:54,450 And then they pick which one is best, based on evaluation. 606 00:27:54,450 --> 00:27:56,358 But you can see that there's a lot of nodes. 607 00:27:56,358 --> 00:27:57,900 Like, if you do this naively, there'd 608 00:27:57,900 --> 00:28:03,060 be number of moves raised to d, which is a huge number, 609 00:28:03,060 --> 00:28:04,357 and too many to generate. 610 00:28:04,357 --> 00:28:06,690 So we're going to talk about how you reduce those later. 611 00:28:09,720 --> 00:28:12,293 There's something that you have to do on search series, which 612 00:28:12,293 --> 00:28:13,710 is called Quiescence search, which 613 00:28:13,710 --> 00:28:17,400 is if you fix your depth-- 614 00:28:17,400 --> 00:28:22,430 let's say you fix depth, and then you go down to the leaves, 615 00:28:22,430 --> 00:28:24,762 and you just captured a piece. 616 00:28:24,762 --> 00:28:26,970 But it's dangerous to just stop there at fixed depth, 617 00:28:26,970 --> 00:28:29,510 because maybe if you searched one level deeper, 618 00:28:29,510 --> 00:28:32,010 you would see that the opponent would capture your piece. 619 00:28:32,010 --> 00:28:34,590 And so if you do your search, and you 620 00:28:34,590 --> 00:28:36,493 see that you capture a piece at the leaves, 621 00:28:36,493 --> 00:28:38,910 or your opponent captures the piece at the leaves, we say, 622 00:28:38,910 --> 00:28:39,618 that's not quiet. 623 00:28:39,618 --> 00:28:41,610 And you keep searching the tree until there 624 00:28:41,610 --> 00:28:42,762 are no more captures. 625 00:28:42,762 --> 00:28:44,220 So that's called Quiescence search, 626 00:28:44,220 --> 00:28:46,037 because you quiet the position. 627 00:28:46,037 --> 00:28:47,870 And that's implemented in the search column. 628 00:28:51,190 --> 00:28:53,590 So this is a graph that I generated 629 00:28:53,590 --> 00:28:56,860 by doing the reference spot to different depths. 630 00:28:56,860 --> 00:28:59,500 And you can see that the Elo increases as you 631 00:28:59,500 --> 00:29:01,420 increase the search depth. 632 00:29:01,420 --> 00:29:03,420 So you just search the search tree. 633 00:29:03,420 --> 00:29:06,955 And so if you optimize your bot to make it faster, 634 00:29:06,955 --> 00:29:09,330 you can search deeper, which means that you'll do better. 635 00:29:16,320 --> 00:29:21,220 So next, I'll talk about min-max search, which 636 00:29:21,220 --> 00:29:26,380 is a more complex version of searching 637 00:29:26,380 --> 00:29:30,520 that can improve the amount of nodes you have to evaluate. 638 00:29:30,520 --> 00:29:34,063 So at a high level, there's two players, max and min. 639 00:29:34,063 --> 00:29:35,980 And in our example, there's orange and purple. 640 00:29:35,980 --> 00:29:37,570 And orange is a square. 641 00:29:37,570 --> 00:29:38,710 And purple is a circle. 642 00:29:38,710 --> 00:29:40,690 And the game trees represents all moves 643 00:29:40,690 --> 00:29:44,872 from the current position from a given ply, which means depth. 644 00:29:44,872 --> 00:29:46,330 And if the leaves, like I said, you 645 00:29:46,330 --> 00:29:48,190 play a static evaluation function. 646 00:29:48,190 --> 00:29:50,860 And max chooses the maximum score among its children. 647 00:29:50,860 --> 00:29:52,277 And min chooses the minimum score. 648 00:29:52,277 --> 00:29:53,693 So one side is trying to maximize, 649 00:29:53,693 --> 00:29:55,353 and one side is trying to minimize. 650 00:29:58,460 --> 00:30:01,100 To evaluate the search try, I'll first 651 00:30:01,100 --> 00:30:03,200 talk about an algorithm called alpha beta, which 652 00:30:03,200 --> 00:30:06,440 is that each search from a node has a window alpha beta. 653 00:30:06,440 --> 00:30:08,780 And if the value of the search falls below alpha, 654 00:30:08,780 --> 00:30:11,260 the move is not good enough, and you keep searching. 655 00:30:11,260 --> 00:30:13,878 And if the value falls within alpha and beta, 656 00:30:13,878 --> 00:30:16,170 then you increase your alpha, which is the lower bound, 657 00:30:16,170 --> 00:30:17,270 and you keep searching, because you know 658 00:30:17,270 --> 00:30:18,890 you can do at least that well. 659 00:30:18,890 --> 00:30:22,430 And if the value of the search falls above beta, 660 00:30:22,430 --> 00:30:24,440 than you generate a beta cut off in return. 661 00:30:24,440 --> 00:30:26,870 Beta basically means one side is trying to maximize, 662 00:30:26,870 --> 00:30:28,328 and one side is trying to minimize. 663 00:30:28,328 --> 00:30:30,950 So beta is basically saying, the opponent 664 00:30:30,950 --> 00:30:33,620 would never let you do that move, because it'd be too good. 665 00:30:33,620 --> 00:30:35,995 So you don't need to keep searching there, because you're 666 00:30:35,995 --> 00:30:38,930 not going to get there anyway. 667 00:30:38,930 --> 00:30:40,410 So I'll do an example. 668 00:30:40,410 --> 00:30:41,840 Let's say you have this tree. 669 00:30:41,840 --> 00:30:46,253 And if max discovered a move that min wouldn't 670 00:30:46,253 --> 00:30:47,670 let you do, because it's too good, 671 00:30:47,670 --> 00:30:49,170 then max's other children don't need 672 00:30:49,170 --> 00:30:51,640 to be searched, which is what a beta cut off is. 673 00:30:51,640 --> 00:30:53,780 So you'd start at the root. 674 00:30:53,780 --> 00:30:57,650 And then you go down to the lowest left leaf. 675 00:30:57,650 --> 00:31:00,060 And you see that it's three. 676 00:31:00,060 --> 00:31:01,648 So you propagate three up. 677 00:31:01,648 --> 00:31:03,440 And then you can see that in this sub-tree, 678 00:31:03,440 --> 00:31:06,200 you can do at least three. 679 00:31:06,200 --> 00:31:08,390 And then you keep searching your children. 680 00:31:08,390 --> 00:31:10,130 And then you see six. 681 00:31:10,130 --> 00:31:12,440 And then you say, OK, now you update your alpha value 682 00:31:12,440 --> 00:31:14,902 to be six. 683 00:31:14,902 --> 00:31:16,330 Now, you search four. 684 00:31:16,330 --> 00:31:18,555 But four is worse than six. 685 00:31:18,555 --> 00:31:19,930 So you don't have to do anything. 686 00:31:19,930 --> 00:31:22,960 So you first search the leftmost subtree. 687 00:31:22,960 --> 00:31:25,210 And then you see the best move that you could possibly 688 00:31:25,210 --> 00:31:27,760 make there. 689 00:31:27,760 --> 00:31:31,810 So you propagate six up to the root. 690 00:31:31,810 --> 00:31:34,700 And then you search your other subtrees. 691 00:31:34,700 --> 00:31:36,190 But now, you have this value of six 692 00:31:36,190 --> 00:31:38,780 that you basically use in the other subtrees. 693 00:31:38,780 --> 00:31:40,457 So you look at two. 694 00:31:40,457 --> 00:31:42,040 And you see that two is less than six. 695 00:31:42,040 --> 00:31:44,190 So you propagate it up. 696 00:31:44,190 --> 00:31:45,520 But now, you look at nine. 697 00:31:45,520 --> 00:31:48,880 And you see that nine is greater than six. 698 00:31:48,880 --> 00:31:52,780 So you say that this subtree would let purple do nine, 699 00:31:52,780 --> 00:31:54,520 which is greater than six. 700 00:31:54,520 --> 00:32:00,100 And so that would be too good, because orange would never 701 00:32:00,100 --> 00:32:01,420 let purple do that well. 702 00:32:01,420 --> 00:32:04,090 So you don't have to evaluate five anymore. 703 00:32:04,090 --> 00:32:06,235 So you cut off five. 704 00:32:06,235 --> 00:32:07,110 Does that make sense? 705 00:32:11,140 --> 00:32:13,580 OK, so, basically, now you apply the same thing 706 00:32:13,580 --> 00:32:15,003 to the regular subtree. 707 00:32:15,003 --> 00:32:15,920 And you look at seven. 708 00:32:15,920 --> 00:32:18,150 And you see that seven is greater than six. 709 00:32:18,150 --> 00:32:19,208 So you propagate that up. 710 00:32:19,208 --> 00:32:21,500 And now you're done, because seven is greater than six. 711 00:32:21,500 --> 00:32:24,810 So you don't have to search the rest of the subtree. 712 00:32:24,810 --> 00:32:27,830 So that's how you evaluate fewer moves than the entire tree. 713 00:32:35,290 --> 00:32:38,280 And there's a theorem that says for a game tree 714 00:32:38,280 --> 00:32:41,220 with branching factor b and depth d, and alpha beta search 715 00:32:41,220 --> 00:32:43,140 with moves searched in best-first order 716 00:32:43,140 --> 00:32:46,470 examines exactly b raised to the d over 2, 717 00:32:46,470 --> 00:32:50,580 plus b raised to the d over 2 minus 1 nodes apply d. 718 00:32:50,580 --> 00:32:53,760 So best first order means that you sorted the moves in terms 719 00:32:53,760 --> 00:32:55,273 of your static evaluation. 720 00:32:58,340 --> 00:33:00,680 The naive algorithm examines b to the d nodes. 721 00:33:00,680 --> 00:33:04,190 And in the example I did, you can see how you prune. 722 00:33:04,190 --> 00:33:06,427 And for the same work, the search stuff is doubled. 723 00:33:06,427 --> 00:33:08,510 And for the same depth, the work is square rooted. 724 00:33:08,510 --> 00:33:13,846 So this is a huge benefit over the naive evaluation. 725 00:33:13,846 --> 00:33:15,240 Is everyone good on alpha beta? 726 00:33:19,890 --> 00:33:23,210 Great, so the code is pretty short. 727 00:33:23,210 --> 00:33:25,610 So I'll just go through some pseudocode for it. 728 00:33:25,610 --> 00:33:28,443 Basically, the main point is that at line 11, 729 00:33:28,443 --> 00:33:30,235 one side is trying to minimize and one side 730 00:33:30,235 --> 00:33:31,152 is trying to maximize. 731 00:33:31,152 --> 00:33:33,080 But if you negate, then that's just the same 732 00:33:33,080 --> 00:33:34,880 as minimizing and maximizing. 733 00:33:34,880 --> 00:33:38,360 And you get all the possible moves 734 00:33:38,360 --> 00:33:40,550 that you could possibly make using gen moves. 735 00:33:40,550 --> 00:33:42,920 And you go through the entire move list. 736 00:33:42,920 --> 00:33:44,720 And then you make each of the children. 737 00:33:44,720 --> 00:33:47,480 And you search for the score. 738 00:33:47,480 --> 00:33:49,820 And then you see whether you had a beta cut off. 739 00:33:49,820 --> 00:33:52,195 And then you don't need to search the subtree If you did. 740 00:34:00,160 --> 00:34:02,080 So that was basic alpha beta. 741 00:34:02,080 --> 00:34:04,630 And we actually implement a variation of alpha beta called 742 00:34:04,630 --> 00:34:06,072 principle variation search. 743 00:34:06,072 --> 00:34:08,530 And the main idea is that you assume that the first move is 744 00:34:08,530 --> 00:34:09,639 the best one. 745 00:34:09,639 --> 00:34:13,739 And you run scout search, which is also called zero window 746 00:34:13,739 --> 00:34:16,840 search, on the remaining moves to verify that they're worse. 747 00:34:16,840 --> 00:34:19,880 So in this example, you, again, search the most leftmost 748 00:34:19,880 --> 00:34:20,380 subtree. 749 00:34:20,380 --> 00:34:23,420 And you see that the best you can do in the left-most subtree 750 00:34:23,420 --> 00:34:24,610 is three. 751 00:34:24,610 --> 00:34:27,030 And you evaluate the ones to the right 752 00:34:27,030 --> 00:34:31,750 of it using scout search, which is not a full search. 753 00:34:31,750 --> 00:34:33,340 You're basically assuming that you 754 00:34:33,340 --> 00:34:35,139 can do no better than three. 755 00:34:35,139 --> 00:34:38,080 And then now you're kind of doing an initial search to see 756 00:34:38,080 --> 00:34:40,489 whether or not that's true. 757 00:34:40,489 --> 00:34:43,230 And see you see that some of them are-- 758 00:34:43,230 --> 00:34:46,532 the one after that is seven. 759 00:34:46,532 --> 00:34:47,949 The first one after that is seven. 760 00:34:47,949 --> 00:34:50,215 And the one after that in the other subtree is six. 761 00:34:54,600 --> 00:34:59,255 So then you can prune them, because those are better-- 762 00:34:59,255 --> 00:35:00,630 because you know already in those 763 00:35:00,630 --> 00:35:02,430 subtrees that you can do better than three. 764 00:35:02,430 --> 00:35:06,120 So you don't have to keep evaluating them. 765 00:35:06,120 --> 00:35:08,364 And you don't have to-- yeah? 766 00:35:08,364 --> 00:35:10,930 AUDIENCE: How do we know the score of the subtree 767 00:35:10,930 --> 00:35:14,430 before we evaluate? 768 00:35:14,430 --> 00:35:17,340 How can we prune something? 769 00:35:20,020 --> 00:35:21,920 HELEN XU: So you actually had to find seven. 770 00:35:21,920 --> 00:35:23,212 Like, zero and eight are there. 771 00:35:23,212 --> 00:35:25,990 But you haven't found them yet. 772 00:35:25,990 --> 00:35:29,430 So, basically, if you thought about doing it serially, 773 00:35:29,430 --> 00:35:32,790 you do the leftmost subtree, which has 2, 3, and 0. 774 00:35:32,790 --> 00:35:34,220 And then you would find seven. 775 00:35:34,220 --> 00:35:35,970 And that would be a cut off, because seven 776 00:35:35,970 --> 00:35:36,900 is bigger than three. 777 00:35:39,570 --> 00:35:41,490 So you're not actually finding zero and eight. 778 00:35:48,260 --> 00:35:50,390 The point is that you wouldn't get to that subtree, 779 00:35:50,390 --> 00:35:54,323 because the opponent wouldn't let you get there, 780 00:35:54,323 --> 00:35:55,490 because you can do too well. 781 00:35:55,490 --> 00:36:00,590 So they would just not let you go down that path. 782 00:36:00,590 --> 00:36:04,160 Like, let's say you were purple, and the opponent is orange. 783 00:36:04,160 --> 00:36:06,500 And you want to get 7 and 8. 784 00:36:06,500 --> 00:36:08,615 But the opponent can also search that, and see 785 00:36:08,615 --> 00:36:09,740 that you would get 7 and 8. 786 00:36:09,740 --> 00:36:12,320 So they would prefer you to do something like two or three. 787 00:36:19,700 --> 00:36:21,320 AUDIENCE: So what do you do instead? 788 00:36:26,620 --> 00:36:29,170 HELEN XU: You're not always making the best move that you 789 00:36:29,170 --> 00:36:32,690 could possibly do, because-- 790 00:36:32,690 --> 00:36:35,320 like, if you just searched without this pruning, 791 00:36:35,320 --> 00:36:37,150 and you just picked-- 792 00:36:37,150 --> 00:36:40,420 let's say you wanted to make the best move. 793 00:36:40,420 --> 00:36:42,833 Like, if you don't take into account the opponent, 794 00:36:42,833 --> 00:36:44,500 then you're never going to get to there. 795 00:36:44,500 --> 00:36:45,940 So you're basically trying to find a move 796 00:36:45,940 --> 00:36:47,398 that the opponent would let you get 797 00:36:47,398 --> 00:36:53,080 to that's also good for you, because you switch off. 798 00:36:59,056 --> 00:37:00,550 Yes? 799 00:37:00,550 --> 00:37:02,542 AUDIENCE: [INAUDIBLE] 800 00:37:06,050 --> 00:37:10,120 HELEN XU: I guess in this example, you're purple. 801 00:37:10,120 --> 00:37:13,760 No, sorry, you're orange, because you're cutting off-- 802 00:37:13,760 --> 00:37:15,590 no, you're purple, because you're 803 00:37:15,590 --> 00:37:18,513 trying to maximize what you get at the leaves. 804 00:37:18,513 --> 00:37:20,395 AUDIENCE: [INAUDIBLE] 805 00:37:20,395 --> 00:37:20,978 HELEN XU: Yes. 806 00:37:33,310 --> 00:37:36,368 The main point of-- sorry. 807 00:37:36,368 --> 00:37:36,910 AUDIENCE: Oh. 808 00:37:41,502 --> 00:37:42,960 We're trying to minimize the score. 809 00:37:46,270 --> 00:37:47,470 HELEN XU: Yes. 810 00:37:47,470 --> 00:37:49,490 So orange is trying to minimize the score. 811 00:37:49,490 --> 00:37:51,282 And purple is trying to maximize the score. 812 00:37:53,950 --> 00:37:55,450 AUDIENCE: So we're cutting that off, 813 00:37:55,450 --> 00:37:58,932 you're saying you don't need to search this because we already 814 00:37:58,932 --> 00:38:01,680 know they're the same here. 815 00:38:01,680 --> 00:38:03,535 So we shouldn't go down this path anyway. 816 00:38:11,790 --> 00:38:13,860 HELEN XU: Does anyone have questions? 817 00:38:13,860 --> 00:38:14,850 Does that make sense? 818 00:38:14,850 --> 00:38:16,558 Yeah, it's basically exactly as you said. 819 00:38:16,558 --> 00:38:22,710 So there's kind of this balance between one side trying-- 820 00:38:22,710 --> 00:38:24,235 both sides are just trying to make-- 821 00:38:24,235 --> 00:38:25,610 you're trying to make good moves. 822 00:38:25,610 --> 00:38:27,960 But you're also trying to make the opponent make 823 00:38:27,960 --> 00:38:30,850 not good moves, if that makes sense. 824 00:38:30,850 --> 00:38:33,530 So you're not only searching for your maximum. 825 00:38:33,530 --> 00:38:37,550 But you're also searching to minimize the opponent. 826 00:38:37,550 --> 00:38:38,534 Good question. 827 00:38:44,974 --> 00:38:46,555 AUDIENCE: [INAUDIBLE] 828 00:38:58,180 --> 00:39:00,580 HELEN XU: Sorry? 829 00:39:00,580 --> 00:39:02,150 AUDIENCE: So we don't want to choose 830 00:39:02,150 --> 00:39:04,220 either of those orange ones. 831 00:39:04,220 --> 00:39:06,090 We don't want to let-- 832 00:39:06,090 --> 00:39:06,860 I think it's OK. 833 00:39:06,860 --> 00:39:08,180 I think you can move on. 834 00:39:08,180 --> 00:39:10,860 HELEN XU: Oh, OK. 835 00:39:10,860 --> 00:39:11,775 Yes? 836 00:39:11,775 --> 00:39:13,400 AUDIENCE: What if you and your opponent 837 00:39:13,400 --> 00:39:15,870 have different reward criteria? 838 00:39:15,870 --> 00:39:19,100 Like, you guys evaluate-- 839 00:39:19,100 --> 00:39:21,140 HELEN XU: That's OK. 840 00:39:21,140 --> 00:39:23,145 It's fine. 841 00:39:23,145 --> 00:39:24,770 The actual evaluation, like what number 842 00:39:24,770 --> 00:39:28,070 you assign to each position, is not exposed to the opponent. 843 00:39:28,070 --> 00:39:30,710 The main point is that, at the end of each move, you pick one. 844 00:39:30,710 --> 00:39:34,398 And they can do with it what they want. 845 00:39:34,398 --> 00:39:36,440 Like, that may not have been the one they picked. 846 00:39:36,440 --> 00:39:37,050 But it's OK. 847 00:39:51,420 --> 00:39:54,560 Sorry, I think you're orange in this one, 848 00:39:54,560 --> 00:39:57,370 because the root is orange. 849 00:39:57,370 --> 00:39:58,590 AUDIENCE: [INAUDIBLE] 850 00:40:21,100 --> 00:40:22,470 HELEN XU: So let's start over. 851 00:40:22,470 --> 00:40:25,770 So I think that we are orange. 852 00:40:25,770 --> 00:40:28,290 So remember that each edge is a move. 853 00:40:28,290 --> 00:40:30,030 And each node is a position. 854 00:40:30,030 --> 00:40:31,020 And so you're orange. 855 00:40:31,020 --> 00:40:32,580 And you start at the root. 856 00:40:32,580 --> 00:40:35,370 And now you, for example, make the move left. 857 00:40:35,370 --> 00:40:39,300 And purple now can make moves whatever three after that. 858 00:40:39,300 --> 00:40:40,590 And now, you're orange again. 859 00:40:40,590 --> 00:40:42,215 And then you can make moves after that. 860 00:40:42,215 --> 00:40:45,120 And now, you evaluate the position after that as a leaf. 861 00:40:48,700 --> 00:40:51,190 And so, basically, you're searching 862 00:40:51,190 --> 00:40:53,680 past like the second level of orange. 863 00:40:53,680 --> 00:40:57,732 And you are cutting off if you see that you would do better, 864 00:40:57,732 --> 00:40:59,440 because you think that purple would never 865 00:40:59,440 --> 00:41:02,620 let you get to that orange node right above. 866 00:41:02,620 --> 00:41:03,417 Yes? 867 00:41:03,417 --> 00:41:05,310 AUDIENCE: [INAUDIBLE] 868 00:41:08,867 --> 00:41:10,950 HELEN XU: Yeah, I guess that's the score that you, 869 00:41:10,950 --> 00:41:13,420 as orange would receive. 870 00:41:13,420 --> 00:41:14,594 Yes? 871 00:41:14,594 --> 00:41:17,700 AUDIENCE: [INAUDIBLE] 872 00:41:24,520 --> 00:41:27,317 HELEN XU: You're not trying to give-- 873 00:41:27,317 --> 00:41:29,650 it's not so much like you're trying to give purple zero, 874 00:41:29,650 --> 00:41:33,000 as you think that purple would not give you seven and eight, 875 00:41:33,000 --> 00:41:35,332 because purple would have to go down the left subtree 876 00:41:35,332 --> 00:41:36,040 to give you that. 877 00:41:46,798 --> 00:41:47,940 Any other questions? 878 00:41:52,660 --> 00:41:54,160 I'm going to move on with the search 879 00:41:54,160 --> 00:41:58,192 then, if there are no questions. 880 00:41:58,192 --> 00:41:59,800 [INTERPOSING VOICES] 881 00:42:11,510 --> 00:42:14,420 HELEN XU: Is everyone good? 882 00:42:14,420 --> 00:42:16,620 Can I keep going? 883 00:42:16,620 --> 00:42:22,600 OK, so just going back to principal variations pruning, 884 00:42:22,600 --> 00:42:25,870 the main idea is that you go down 885 00:42:25,870 --> 00:42:28,300 the first path on the left side, thinking 886 00:42:28,300 --> 00:42:31,330 that that's the best path. 887 00:42:31,330 --> 00:42:33,247 And then you're basically doing initial passes 888 00:42:33,247 --> 00:42:35,497 through the trees to make sure that your assumption is 889 00:42:35,497 --> 00:42:36,040 correct. 890 00:42:36,040 --> 00:42:37,030 And if they're not correct, then you 891 00:42:37,030 --> 00:42:38,590 have to search the entire subtree. 892 00:42:38,590 --> 00:42:40,360 But if they are correct, then you kind of 893 00:42:40,360 --> 00:42:44,350 fail, you early exit. 894 00:42:44,350 --> 00:42:47,230 So you search down the left subtree. 895 00:42:47,230 --> 00:42:50,007 And you find three in the leftmost subtree. 896 00:42:50,007 --> 00:42:52,090 And now, you search the ones to the right of that. 897 00:42:52,090 --> 00:42:53,530 And those are seven and eight. 898 00:42:53,530 --> 00:42:56,500 So those produce a cutoff, because seven and eight 899 00:42:56,500 --> 00:42:57,513 is higher than three. 900 00:42:57,513 --> 00:42:58,930 So you think that purple would not 901 00:42:58,930 --> 00:43:00,097 let you get to that subtree. 902 00:43:03,040 --> 00:43:08,640 And now, you do a scout search again on the middle subtree. 903 00:43:08,640 --> 00:43:11,630 And then you see that-- 904 00:43:11,630 --> 00:43:14,280 you find this first node of each one of those subtrees 905 00:43:14,280 --> 00:43:15,660 underneath the middle subtree. 906 00:43:15,660 --> 00:43:18,300 And you see that they're all higher than three. 907 00:43:18,300 --> 00:43:24,990 So it turns out that you failed to prove that you 908 00:43:24,990 --> 00:43:26,603 can do no better than three. 909 00:43:26,603 --> 00:43:28,020 The main point of the scout search 910 00:43:28,020 --> 00:43:29,970 is that you assume that your first move that you search 911 00:43:29,970 --> 00:43:31,170 is the best you can do. 912 00:43:31,170 --> 00:43:34,530 And then you do initial passes to verify that assumption. 913 00:43:34,530 --> 00:43:37,375 And if you search later subtrees, and you find that-- 914 00:43:37,375 --> 00:43:39,000 for example, in this one in the middle, 915 00:43:39,000 --> 00:43:40,292 they're all higher than threes. 916 00:43:40,292 --> 00:43:41,650 So your assumption is not true. 917 00:43:41,650 --> 00:43:43,320 So now you have to do a full search 918 00:43:43,320 --> 00:43:46,765 of that entire middle subtree. 919 00:43:46,765 --> 00:43:48,745 Is that OK? 920 00:43:48,745 --> 00:43:50,725 Are there questions? 921 00:43:56,170 --> 00:44:00,280 So once you find that you have to actually search 922 00:44:00,280 --> 00:44:02,950 the middle subtree, you can recursively apply scout search. 923 00:44:02,950 --> 00:44:05,530 So you have to search the left subtree in the middle. 924 00:44:05,530 --> 00:44:09,610 But now, you apply scout search to the lower middle 925 00:44:09,610 --> 00:44:11,867 and the lower right. 926 00:44:11,867 --> 00:44:13,450 And you do a zero window search there. 927 00:44:13,450 --> 00:44:16,210 And, again, you assume that you can do no better than six. 928 00:44:16,210 --> 00:44:17,918 And now, you're trying to verify that you 929 00:44:17,918 --> 00:44:19,570 can do better than six. 930 00:44:19,570 --> 00:44:20,620 But you actually can. 931 00:44:20,620 --> 00:44:23,780 So you have to search them. 932 00:44:23,780 --> 00:44:27,320 And then you apply the same thing again to the subtree. 933 00:44:27,320 --> 00:44:29,450 And you see that you can do better than six 934 00:44:29,450 --> 00:44:30,640 on the left one. 935 00:44:30,640 --> 00:44:34,660 But you do worse than six on the right one. 936 00:44:34,660 --> 00:44:38,510 And you cut off two, because the middle subtree already gave you 937 00:44:38,510 --> 00:44:40,660 two. 938 00:44:40,660 --> 00:44:43,220 And so you don't have to search that one. 939 00:44:43,220 --> 00:44:46,822 So in this example, there were 13 leaves pruned. 940 00:44:46,822 --> 00:44:48,530 And the point of scout search is that you 941 00:44:48,530 --> 00:44:51,340 can improve pruning a little bit over alpha beta, 942 00:44:51,340 --> 00:44:53,090 and that you process most of the game tree 943 00:44:53,090 --> 00:44:54,507 with zero window searches. 944 00:44:54,507 --> 00:44:56,840 The main point is that it reduces your work, because you 945 00:44:56,840 --> 00:44:57,770 have to process less. 946 00:45:02,234 --> 00:45:03,226 Questions? 947 00:45:08,700 --> 00:45:11,430 So now we're going to talk about-- so I kind of glossed 948 00:45:11,430 --> 00:45:12,870 over how you order the moves. 949 00:45:12,870 --> 00:45:15,660 So the ordering determines which order 950 00:45:15,660 --> 00:45:18,360 you explore the subtrees in. 951 00:45:18,360 --> 00:45:20,360 Alpha-beta search and principal variation search 952 00:45:20,360 --> 00:45:22,320 depend on putting the best moves in the front 953 00:45:22,320 --> 00:45:24,240 to trigger an early cut off. 954 00:45:24,240 --> 00:45:25,990 And the main question is, how do we 955 00:45:25,990 --> 00:45:27,630 determine moves, which moves are good, 956 00:45:27,630 --> 00:45:29,588 without doing static evaluation at every level? 957 00:45:29,588 --> 00:45:31,650 Like, for example, we only did static evaluation 958 00:45:31,650 --> 00:45:32,790 with the leaves. 959 00:45:32,790 --> 00:45:34,590 And we can't get sortable move list, 960 00:45:34,590 --> 00:45:36,510 which is a function in search. 961 00:45:36,510 --> 00:45:40,043 And sortable move lists, kind of talk 962 00:45:40,043 --> 00:45:41,460 about how you populate that later. 963 00:45:45,060 --> 00:45:47,410 As I said before, moves are represented in 128 bits. 964 00:45:47,410 --> 00:45:49,260 So you can use it in 32. 965 00:45:49,260 --> 00:45:51,760 And to make them sortable, you store a sort key 966 00:45:51,760 --> 00:45:54,510 in the upper 32 bits in 64. 967 00:45:54,510 --> 00:45:58,060 And then you sort, based on that key. 968 00:45:58,060 --> 00:45:58,820 That make sense? 969 00:46:05,940 --> 00:46:09,420 So I'll just go over some search optimizations that you can do. 970 00:46:09,420 --> 00:46:10,920 We actually implement these already. 971 00:46:10,920 --> 00:46:11,940 So I'm just going to go through them 972 00:46:11,940 --> 00:46:14,640 so it's not super confusing when you look at the code. 973 00:46:14,640 --> 00:46:17,940 The most important one is called the transposition table. 974 00:46:17,940 --> 00:46:20,070 The main idea in the transposition table 975 00:46:20,070 --> 00:46:22,650 is that chess programs often encounter the same positions 976 00:46:22,650 --> 00:46:24,450 repeatedly during a search. 977 00:46:24,450 --> 00:46:27,150 And you can store those results in a transposition table 978 00:46:27,150 --> 00:46:29,642 to avoid unnecessary feature searches. 979 00:46:29,642 --> 00:46:31,350 And I've listed where you can find those. 980 00:46:35,590 --> 00:46:37,370 There's something called Zobrist hashing, 981 00:46:37,370 --> 00:46:39,760 which is a technique for hashing a board position which 982 00:46:39,760 --> 00:46:42,142 you use to index the transmission table. 983 00:46:42,142 --> 00:46:44,350 And it's a table of random numbers, indexed by piece, 984 00:46:44,350 --> 00:46:45,700 orientation, and square. 985 00:46:45,700 --> 00:46:49,948 So each position has a unique hash. 986 00:46:49,948 --> 00:46:51,490 And it produces the hash by exporting 987 00:46:51,490 --> 00:46:53,560 all of these random numbers together. 988 00:46:53,560 --> 00:46:55,660 And the advantage of Zobrist hashing 989 00:46:55,660 --> 00:46:58,330 is that the hash function can be updated incrementally, which 990 00:46:58,330 --> 00:47:00,670 is like if you move a position-- if you move a piece, 991 00:47:00,670 --> 00:47:01,630 you just xor it out. 992 00:47:01,630 --> 00:47:03,670 And then you xor the new one, so you 993 00:47:03,670 --> 00:47:06,244 don't have to recompute the hash each time. 994 00:47:11,330 --> 00:47:14,660 So the transposition table saves you a lot of work 995 00:47:14,660 --> 00:47:17,697 by preventing you from researching things. 996 00:47:17,697 --> 00:47:20,030 And there's also something called the killer move table. 997 00:47:20,030 --> 00:47:21,613 So the transposition table is like how 998 00:47:21,613 --> 00:47:25,430 you determine how to do sorting at things 999 00:47:25,430 --> 00:47:27,860 that are not the leaves, and also the killing moves table. 1000 00:47:27,860 --> 00:47:29,770 So the killer moves people stores 1001 00:47:29,770 --> 00:47:32,270 moves that are really good so that the opponent wouldn't let 1002 00:47:32,270 --> 00:47:34,160 you go down that path, so you have to keep 1003 00:47:34,160 --> 00:47:36,410 recomputing the same values. 1004 00:47:36,410 --> 00:47:38,480 And the table is indexed by ply, because you 1005 00:47:38,480 --> 00:47:41,960 tend to see the same moves at the same depth. 1006 00:47:41,960 --> 00:47:44,180 So the killer move table, basically, just stores 1007 00:47:44,180 --> 00:47:46,870 move that trigger the beta cut off before in your search. 1008 00:47:53,270 --> 00:47:55,967 There's a best move table, which is stored 1009 00:47:55,967 --> 00:47:57,050 at the root of the search. 1010 00:47:57,050 --> 00:48:00,230 And it is the move that got the maximum score 1011 00:48:00,230 --> 00:48:01,820 in your evaluation. 1012 00:48:01,820 --> 00:48:04,040 And the best move table is indexed by color, 1013 00:48:04,040 --> 00:48:06,560 piece, square, and orientation. 1014 00:48:06,560 --> 00:48:09,715 And there's a history table in the code. 1015 00:48:09,715 --> 00:48:11,090 So these are all, basically, just 1016 00:48:11,090 --> 00:48:12,757 things to help you optimize your search, 1017 00:48:12,757 --> 00:48:14,400 and produce early cut offs. 1018 00:48:17,862 --> 00:48:20,070 And there's something called null-move pruning, which 1019 00:48:20,070 --> 00:48:22,463 tries to reduce your search space by first 1020 00:48:22,463 --> 00:48:24,630 not moving, and then doing a shallower search to see 1021 00:48:24,630 --> 00:48:26,760 if this subtree is worth further exploring. 1022 00:48:29,318 --> 00:48:31,110 Basically, it says, don't move, and then do 1023 00:48:31,110 --> 00:48:32,830 a little bit of evaluation. 1024 00:48:32,830 --> 00:48:35,520 And if you're still doing really well, 1025 00:48:35,520 --> 00:48:37,350 even if you didn't move in the subtree, 1026 00:48:37,350 --> 00:48:39,642 then it's not worth exploring, because the opponent 1027 00:48:39,642 --> 00:48:41,850 would never let you go there, because the position is 1028 00:48:41,850 --> 00:48:42,350 too good. 1029 00:48:45,890 --> 00:48:47,990 There's futility pruning, which explores 1030 00:48:47,990 --> 00:48:51,050 moves that only have the potential to increase alpha. 1031 00:48:51,050 --> 00:48:52,550 And it calculates that possibility 1032 00:48:52,550 --> 00:48:54,320 by adding a futility margin, which 1033 00:48:54,320 --> 00:48:57,770 is the most you could possibly gain from going there, and then 1034 00:48:57,770 --> 00:48:59,380 evaluating a little bit. 1035 00:48:59,380 --> 00:49:01,380 And if the result does not go higher than alpha, 1036 00:49:01,380 --> 00:49:03,298 then you skip it, because there's 1037 00:49:03,298 --> 00:49:05,090 no point in even going that way, because it 1038 00:49:05,090 --> 00:49:06,298 wouldn't increase your alpha. 1039 00:49:11,410 --> 00:49:13,600 There's late move reduction, which 1040 00:49:13,600 --> 00:49:15,880 is after you order the moves at a position, 1041 00:49:15,880 --> 00:49:19,090 you explore the-- the-- ones in front are likely to be better. 1042 00:49:19,090 --> 00:49:20,890 So you explore those in higher depth. 1043 00:49:20,890 --> 00:49:24,102 And then you explore the ones later with shallower depth, 1044 00:49:24,102 --> 00:49:25,810 because those are less likely to be good. 1045 00:49:29,770 --> 00:49:33,340 And some things that you can optimize 1046 00:49:33,340 --> 00:49:37,480 are implementing a better opening book. 1047 00:49:37,480 --> 00:49:40,000 I think we have produced a very basic opening 1048 00:49:40,000 --> 00:49:41,365 book in the handout. 1049 00:49:41,365 --> 00:49:43,240 But this is something that you can definitely 1050 00:49:43,240 --> 00:49:44,710 work on, and make better, because it doesn't have 1051 00:49:44,710 --> 00:49:46,450 many positions in it right now. 1052 00:49:46,450 --> 00:49:47,500 And the main point of an opening book 1053 00:49:47,500 --> 00:49:49,540 is that you store the positions at the beginning of the game 1054 00:49:49,540 --> 00:49:51,052 that you've already pre-computed. 1055 00:49:51,052 --> 00:49:53,260 And that saves time and search, and can store results 1056 00:49:53,260 --> 00:49:54,670 to a higher depth. 1057 00:49:54,670 --> 00:49:57,310 And the KM75 theorem implies it's better 1058 00:49:57,310 --> 00:50:00,220 to keep separate opening books than to keep the same opening 1059 00:50:00,220 --> 00:50:01,570 book for both sides. 1060 00:50:01,570 --> 00:50:03,070 So opening books are really helpful, 1061 00:50:03,070 --> 00:50:05,650 because in the beginning, there's a huge number of moves 1062 00:50:05,650 --> 00:50:06,910 that you could possibly make. 1063 00:50:06,910 --> 00:50:08,720 And searching those takes a lot of time. 1064 00:50:08,720 --> 00:50:11,710 But if you pre-compute them, you can save them for later. 1065 00:50:14,930 --> 00:50:16,705 And another useful table you can keep 1066 00:50:16,705 --> 00:50:18,080 is an end game database, which is 1067 00:50:18,080 --> 00:50:21,710 a table for guiding your chess program through the end game. 1068 00:50:21,710 --> 00:50:24,050 For end game positions, the distance from the end 1069 00:50:24,050 --> 00:50:26,060 might be too far to search entirely. 1070 00:50:26,060 --> 00:50:27,570 So you can pre-compute them. 1071 00:50:27,570 --> 00:50:29,570 And then you store who will win, and how far you 1072 00:50:29,570 --> 00:50:31,130 are from the end of the game. 1073 00:50:31,130 --> 00:50:34,960 And we've given you a c file that you can implement it in. 1074 00:50:44,270 --> 00:50:46,400 OK, so I'll just go through some guidelines, 1075 00:50:46,400 --> 00:50:48,950 some tips for the project. 1076 00:50:48,950 --> 00:50:50,960 I was giving links at most of the bottom 1077 00:50:50,960 --> 00:50:54,770 of the slides for where you can read up more on these topics. 1078 00:50:54,770 --> 00:50:56,550 But there's a chess programming wiki. 1079 00:50:56,550 --> 00:51:00,170 The link is there, which has many more pages about reading 1080 00:51:00,170 --> 00:51:03,933 about chess playing programs. 1081 00:51:03,933 --> 00:51:05,600 Just in general, it's a really good idea 1082 00:51:05,600 --> 00:51:07,142 to test your code often, because it's 1083 00:51:07,142 --> 00:51:09,290 easy to make a mistake with your optimizations. 1084 00:51:09,290 --> 00:51:12,320 And it doesn't appear when you search to fixed depth. 1085 00:51:12,320 --> 00:51:15,470 So if you start up your bot, you can say, like, 1086 00:51:15,470 --> 00:51:17,700 search to depth 5, for example. 1087 00:51:17,700 --> 00:51:20,628 And then it will tell you like how many nodes per seconds 1088 00:51:20,628 --> 00:51:21,170 you searched. 1089 00:51:21,170 --> 00:51:24,320 And then I'll tell you the best move at the end of that search. 1090 00:51:24,320 --> 00:51:27,298 But you should test full games using 1091 00:51:27,298 --> 00:51:29,090 the auto tester, and the cloud auto tester, 1092 00:51:29,090 --> 00:51:32,090 and the script server, just to watch your bot 1093 00:51:32,090 --> 00:51:34,280 to make sure that it doesn't do anything weird. 1094 00:51:34,280 --> 00:51:36,950 And the testing methodology, I went through some of it. 1095 00:51:36,950 --> 00:51:37,730 There's a webgui. 1096 00:51:37,730 --> 00:51:38,870 There's a Java autotester. 1097 00:51:38,870 --> 00:51:40,343 There's a cloud autotester. 1098 00:51:40,343 --> 00:51:42,260 And you can do node counts, which is basically 1099 00:51:42,260 --> 00:51:44,960 just counting the number of nodes in the tree 1100 00:51:44,960 --> 00:51:45,740 that you searched. 1101 00:51:45,740 --> 00:51:47,407 And there's function comparison testing, 1102 00:51:47,407 --> 00:51:49,160 which is, if you optimize a function, 1103 00:51:49,160 --> 00:51:51,290 you should save the old version, and then 1104 00:51:51,290 --> 00:51:52,370 just compare the results. 1105 00:51:55,990 --> 00:52:01,710 PROFESSOR: Let me make a comment about testing. 1106 00:52:01,710 --> 00:52:03,750 I can't tell you how often in this class 1107 00:52:03,750 --> 00:52:09,090 we've had student groups who discover that they've 1108 00:52:09,090 --> 00:52:11,610 made a whole bunch of changes. 1109 00:52:11,610 --> 00:52:14,700 And then there's something wrong with their bot. 1110 00:52:14,700 --> 00:52:17,310 And they can't get back to a stable place 1111 00:52:17,310 --> 00:52:18,420 when things were correct. 1112 00:52:18,420 --> 00:52:20,100 They discover the problem. 1113 00:52:20,100 --> 00:52:23,430 But they've made 30 changes. 1114 00:52:23,430 --> 00:52:27,130 And now, which of those 30 is responsible for the problem? 1115 00:52:27,130 --> 00:52:32,010 So it's really important to test, 1116 00:52:32,010 --> 00:52:33,780 and have a good test infrastructure 1117 00:52:33,780 --> 00:52:34,803 for this project. 1118 00:52:34,803 --> 00:52:36,720 If you have a really good test infrastructure, 1119 00:52:36,720 --> 00:52:40,290 it's really easy to be innovative in the kinds 1120 00:52:40,290 --> 00:52:42,870 of optimizations that you do, because then you 1121 00:52:42,870 --> 00:52:45,055 know that what you're doing is right. 1122 00:52:45,055 --> 00:52:46,680 And then you can make forward progress. 1123 00:52:46,680 --> 00:52:50,400 Otherwise, you'll find yourself self debugging like crazy, 1124 00:52:50,400 --> 00:52:53,130 and not being able to find the bugs. 1125 00:52:53,130 --> 00:52:57,060 Some other tips are, especially when 1126 00:52:57,060 --> 00:52:58,650 we get to the parallel part, it's 1127 00:52:58,650 --> 00:53:02,220 non-deterministic programming. 1128 00:53:02,220 --> 00:53:03,690 And the reason is because as you're 1129 00:53:03,690 --> 00:53:07,350 executing you're going to be looking up things 1130 00:53:07,350 --> 00:53:10,620 in transposition table that you're going to want to share, 1131 00:53:10,620 --> 00:53:15,060 so that if one branch discovers a value then 1132 00:53:15,060 --> 00:53:18,450 another branch can use that. 1133 00:53:18,450 --> 00:53:20,520 So it's really important to be able to turn that 1134 00:53:20,520 --> 00:53:23,880 off so that you're, for example, able to search 1135 00:53:23,880 --> 00:53:25,920 without a transposition table to get all 1136 00:53:25,920 --> 00:53:29,040 the searching stuff right, and be able to turn that 1137 00:53:29,040 --> 00:53:30,220 on independently. 1138 00:53:30,220 --> 00:53:34,360 So that's another really important place to do it. 1139 00:53:34,360 --> 00:53:38,670 Another thing is that when you do timed searches, 1140 00:53:38,670 --> 00:53:42,120 the time it takes to do the search will vary. 1141 00:53:42,120 --> 00:53:44,070 And what you'll end up exploring varies. 1142 00:53:44,070 --> 00:53:49,020 So as much as possible, you wanted to fix depth searches. 1143 00:53:49,020 --> 00:53:52,980 Search to five ply to test something, 1144 00:53:52,980 --> 00:53:56,670 rather than searching for a minute, 1145 00:53:56,670 --> 00:53:59,190 or whatever the amount of time is, 1146 00:53:59,190 --> 00:54:01,800 because when you start searching for time, 1147 00:54:01,800 --> 00:54:04,290 that's, in fact, what you're going to end up doing. 1148 00:54:04,290 --> 00:54:08,580 But you can't repeat what just happened if you end up 1149 00:54:08,580 --> 00:54:10,020 searching for that amount of time 1150 00:54:10,020 --> 00:54:14,220 again, because the machines are not deterministic. 1151 00:54:14,220 --> 00:54:16,380 And there may be something else going 1152 00:54:16,380 --> 00:54:21,000 on that causes the amount of time to be different. 1153 00:54:21,000 --> 00:54:26,130 And so, for example, if you're making a change that 1154 00:54:26,130 --> 00:54:28,410 doesn't affect the logic of the program, 1155 00:54:28,410 --> 00:54:31,710 it's just strictly an optimization, 1156 00:54:31,710 --> 00:54:33,750 you should get exactly the same result 1157 00:54:33,750 --> 00:54:36,930 if you do a five ply search, for example. 1158 00:54:36,930 --> 00:54:39,660 Shouldn't have changed the five ply search. 1159 00:54:39,660 --> 00:54:42,512 Just a five ply search should be faster. 1160 00:54:42,512 --> 00:54:44,470 And so that's a good way-- as much as possible, 1161 00:54:44,470 --> 00:54:48,300 you want to check things that are deterministic and so forth. 1162 00:54:48,300 --> 00:54:52,680 And, really, as I say, I can't emphasize this enough, 1163 00:54:52,680 --> 00:54:54,750 how having a good test infrastructure, 1164 00:54:54,750 --> 00:54:58,410 the ability to control turn off non-determinism, 1165 00:54:58,410 --> 00:55:03,160 the ability to test various parts of this program, 1166 00:55:03,160 --> 00:55:05,430 this is a pretty big piece of code 1167 00:55:05,430 --> 00:55:09,300 for a project of this nature. 1168 00:55:09,300 --> 00:55:11,430 And you'll feel pretty overwhelmed by it 1169 00:55:11,430 --> 00:55:12,540 to begin with. 1170 00:55:12,540 --> 00:55:14,580 Once you settle, you'll discover, 1171 00:55:14,580 --> 00:55:17,970 it's this wonderful thing, where by the end of the project 1172 00:55:17,970 --> 00:55:21,420 everybody feels really confident about their ability to handle 1173 00:55:21,420 --> 00:55:23,243 a decent sized piece of code. 1174 00:55:23,243 --> 00:55:25,660 But when you first get into it, it's like, oh my goodness. 1175 00:55:25,660 --> 00:55:26,577 There's move ordering. 1176 00:55:26,577 --> 00:55:28,050 And there's static evaluation. 1177 00:55:28,050 --> 00:55:29,310 And there's the search. 1178 00:55:29,310 --> 00:55:31,770 And what's going on with that transposition table? 1179 00:55:31,770 --> 00:55:34,200 Because every one of these things has got 1180 00:55:34,200 --> 00:55:35,910 cleverness in it. 1181 00:55:35,910 --> 00:55:39,240 OK, so it's really hard code to deal with. 1182 00:55:39,240 --> 00:55:41,490 But you guys are going to just fine. 1183 00:55:41,490 --> 00:55:48,240 HELEN XU: So this is the eval.c file in the handout. 1184 00:55:48,240 --> 00:55:51,430 So this in 32 here is the evaluation score. 1185 00:55:51,430 --> 00:55:54,510 And the main function is called eval. 1186 00:55:54,510 --> 00:55:56,430 And it takes in a position. 1187 00:55:56,430 --> 00:56:01,020 And it outputs two scores, one for white and one for black. 1188 00:56:03,720 --> 00:56:05,280 And right now, it does-- 1189 00:56:08,720 --> 00:56:10,920 I guess it does counts of the number of pawns. 1190 00:56:10,920 --> 00:56:15,220 OK, so I was talking before about, p between and p central, 1191 00:56:15,220 --> 00:56:17,050 which are you pawn heuristics. 1192 00:56:17,050 --> 00:56:18,730 And so basically, right now, it iterates 1193 00:56:18,730 --> 00:56:20,440 through the entire board. 1194 00:56:20,440 --> 00:56:23,680 You can see for rank and file are just row and column. 1195 00:56:23,680 --> 00:56:26,890 And it looks at each square in the iteration. 1196 00:56:26,890 --> 00:56:30,190 And then it looks at the piece and the color of the piece. 1197 00:56:30,190 --> 00:56:33,152 And based on the type of the piece, it does some evaluation. 1198 00:56:33,152 --> 00:56:35,110 So if it's a pawn, it does the pawn heuristics. 1199 00:56:35,110 --> 00:56:38,380 If it's a fits king, it does these king heuristics. 1200 00:56:38,380 --> 00:56:40,860 And otherwise, or both-- 1201 00:56:40,860 --> 00:56:43,900 or not otherwise, I guess-- 1202 00:56:43,900 --> 00:56:47,122 yeah, in both cases it'll do-- 1203 00:56:47,122 --> 00:56:48,080 this is an old version. 1204 00:56:48,080 --> 00:56:49,163 So it's not there anymore. 1205 00:56:49,163 --> 00:56:51,430 But this is laser coverage, which 1206 00:56:51,430 --> 00:56:55,030 we talked about earlier, which doesn't 1207 00:56:55,030 --> 00:56:56,690 depend on what piece it is. 1208 00:56:56,690 --> 00:57:01,570 This is after you iterate through the entire board. 1209 00:57:01,570 --> 00:57:04,350 And then this isn't here anymore either. 1210 00:57:04,350 --> 00:57:06,100 But we can look at each of these in depth. 1211 00:57:06,100 --> 00:57:07,517 So right now, for example, there's 1212 00:57:07,517 --> 00:57:18,500 p between, which goes through every single pawn 1213 00:57:18,500 --> 00:57:19,280 in your iteration. 1214 00:57:19,280 --> 00:57:21,230 And then it will determine whether or not 1215 00:57:21,230 --> 00:57:26,300 it's between both kings, and the return slide. 1216 00:57:26,300 --> 00:57:30,980 So it will add it to the score, if you find that it's true. 1217 00:57:30,980 --> 00:57:38,920 And there's p central, which takes in a rank and a file. 1218 00:57:38,920 --> 00:57:41,913 And, basically, it increments something, 1219 00:57:41,913 --> 00:57:43,330 or it gives you a bonus, depending 1220 00:57:43,330 --> 00:57:46,863 on how close you are to the center of the board. 1221 00:57:46,863 --> 00:57:47,530 So look at this. 1222 00:57:47,530 --> 00:57:49,630 There's a board with-- 1223 00:57:49,630 --> 00:57:51,740 and F as your file. 1224 00:57:51,740 --> 00:57:52,600 And R is your rank. 1225 00:57:56,860 --> 00:57:59,380 PROFESSOR: I think you have a slightly older version. 1226 00:57:59,380 --> 00:58:01,740 HELEN XU: Potentially. 1227 00:58:01,740 --> 00:58:04,530 PROFESSOR: It's correct on the screen. 1228 00:58:04,530 --> 00:58:06,125 HELEN XU: Is correct in this one? 1229 00:58:06,125 --> 00:58:06,750 AUDIENCE: Yeah. 1230 00:58:25,930 --> 00:58:28,310 HELEN XU: OK, so this is just the-- 1231 00:58:28,310 --> 00:58:29,810 I guess is the most updated version. 1232 00:58:29,810 --> 00:58:31,070 The first one is p central. 1233 00:58:31,070 --> 00:58:33,680 So this just count the difference 1234 00:58:33,680 --> 00:58:35,930 between where you are and the center of the board. 1235 00:58:35,930 --> 00:58:38,750 And it gives you some bonus, depending on how far 1236 00:58:38,750 --> 00:58:40,430 you are from the center. 1237 00:58:40,430 --> 00:58:42,750 And this one is between. 1238 00:58:42,750 --> 00:58:45,472 Yeah, so this is between, which is a helper for p between. 1239 00:58:45,472 --> 00:58:47,180 And it tells you whether or not your pawn 1240 00:58:47,180 --> 00:58:51,200 is in the bounding box determined by the kings. 1241 00:58:51,200 --> 00:58:57,580 And this one is k face, which is given a king, 1242 00:58:57,580 --> 00:59:00,020 you look at its orientation. 1243 00:59:00,020 --> 00:59:02,240 And then you give it a bonus, depending 1244 00:59:02,240 --> 00:59:05,840 on which way you're facing, and how far you 1245 00:59:05,840 --> 00:59:07,730 are from the center, I think-- 1246 00:59:07,730 --> 00:59:10,250 no, how far you are from the opponent. 1247 00:59:10,250 --> 00:59:12,140 So f and r where you are. 1248 00:59:12,140 --> 00:59:18,140 And now it does the delta between you and the opposing 1249 00:59:18,140 --> 00:59:20,520 king. 1250 00:59:20,520 --> 00:59:23,300 And then you do some scaling, depending on which direction 1251 00:59:23,300 --> 00:59:23,960 you're facing. 1252 00:59:23,960 --> 00:59:25,668 So this is just your orientation. 1253 00:59:28,360 --> 00:59:30,790 And then this is k aggressive, which 1254 00:59:30,790 --> 00:59:33,070 gives you a bonus for how far you 1255 00:59:33,070 --> 00:59:35,380 are from the edge of the board. 1256 00:59:35,380 --> 00:59:41,740 So you can see here op square is where do the opposing king is. 1257 00:59:41,740 --> 00:59:47,020 And delta file and delta rank are how far 1258 00:59:47,020 --> 00:59:49,150 you are from the opposing king. 1259 00:59:49,150 --> 00:59:54,130 And then you add the bonus, depending on which case 1260 00:59:54,130 --> 00:59:55,400 the deltas fall into. 1261 00:59:59,700 --> 01:00:04,180 And this gives you a bonus if you're farther 1262 01:00:04,180 --> 01:00:07,180 from the edge of the board. 1263 01:00:07,180 --> 01:00:12,520 Yeah, and there's l coverage, which 1264 01:00:12,520 --> 01:00:15,970 is the most complicated one, probably. 1265 01:00:15,970 --> 01:00:19,090 And, basically, what laser coverage does is that, 1266 01:00:19,090 --> 01:00:20,560 basically, it takes a position. 1267 01:00:20,560 --> 01:00:22,120 And depending on what side you are, 1268 01:00:22,120 --> 01:00:24,203 it generates all the moves that you could possibly 1269 01:00:24,203 --> 01:00:25,300 make from that position. 1270 01:00:25,300 --> 01:00:30,310 So you generate all with color, which 1271 01:00:30,310 --> 01:00:31,720 means that, given your color, you 1272 01:00:31,720 --> 01:00:34,030 generate all the possible moves that you can make. 1273 01:00:34,030 --> 01:00:35,260 And you get a list of moves. 1274 01:00:35,260 --> 01:00:37,060 And you iterate through it. 1275 01:00:37,060 --> 01:00:38,890 And then you make each of them. 1276 01:00:38,890 --> 01:00:40,510 And you draw a laser path. 1277 01:00:40,510 --> 01:00:43,990 And what the laser path does is, basically, it 1278 01:00:43,990 --> 01:00:45,760 bounces off some pause. 1279 01:00:45,760 --> 01:00:49,240 And for each square, you increment the distance, 1280 01:00:49,240 --> 01:00:51,410 basically, along the path. 1281 01:00:51,410 --> 01:00:54,163 And if it takes the minimum distance 1282 01:00:54,163 --> 01:00:56,080 over all these possible paths for each square. 1283 01:00:56,080 --> 01:00:59,290 And if it doesn't touch a square, then it's just 0. 1284 01:00:59,290 --> 01:01:00,710 And it divides it. 1285 01:01:00,710 --> 01:01:01,870 I can go into this. 1286 01:01:04,620 --> 01:01:08,390 So it draws the path through this while true. 1287 01:01:11,970 --> 01:01:14,100 Or this is just changing the orientation 1288 01:01:14,100 --> 01:01:16,290 if you need to bounce off a pawn. 1289 01:01:16,290 --> 01:01:19,990 But this one is setting the-- 1290 01:01:19,990 --> 01:01:21,000 you keep a laser map. 1291 01:01:21,000 --> 01:01:23,670 And you keep the minimum path of a laser 1292 01:01:23,670 --> 01:01:26,250 that would possibly touch that. 1293 01:01:26,250 --> 01:01:31,290 And, no, this is just changing the orientation. 1294 01:01:34,117 --> 01:01:36,450 So then you generate this map for all the possible moves 1295 01:01:36,450 --> 01:01:37,680 that you could do. 1296 01:01:37,680 --> 01:01:39,660 And then you do some scaling. 1297 01:01:39,660 --> 01:01:44,350 So, depending on the distance from the opposing king, 1298 01:01:44,350 --> 01:01:46,350 you iterate through the entire board. 1299 01:01:46,350 --> 01:01:52,110 And you divide the minimum distance 1300 01:01:52,110 --> 01:01:54,670 by the actual distance from the laser. 1301 01:01:54,670 --> 01:01:58,710 So the maximum that this ratio can be is 1. 1302 01:01:58,710 --> 01:02:06,000 And then you multiply it by 1 over the distance. 1303 01:02:08,583 --> 01:02:10,000 So this one is really complicated. 1304 01:02:10,000 --> 01:02:11,790 And there's a lot to optimize here. 1305 01:02:11,790 --> 01:02:13,740 For example, you probably don't have 1306 01:02:13,740 --> 01:02:15,700 to iterate through the entire board 1307 01:02:15,700 --> 01:02:23,280 each time, because even in eval, like here, you 1308 01:02:23,280 --> 01:02:25,290 have to iterate through the entire board 1309 01:02:25,290 --> 01:02:27,092 to find each piece. 1310 01:02:27,092 --> 01:02:28,800 And if you start a better representation, 1311 01:02:28,800 --> 01:02:30,360 you might not have to do that, like if you just 1312 01:02:30,360 --> 01:02:32,010 kept track of where the pawns were, 1313 01:02:32,010 --> 01:02:34,538 because you already keep track of the king separately. 1314 01:02:34,538 --> 01:02:35,830 So that's one thing you can do. 1315 01:02:40,080 --> 01:02:42,000 PROFESSOR: There are two basic strategies 1316 01:02:42,000 --> 01:02:44,820 for changing the representation of the board. 1317 01:02:44,820 --> 01:02:46,740 And maybe there are more. 1318 01:02:46,740 --> 01:02:49,770 But the two basic ones are, instead 1319 01:02:49,770 --> 01:02:55,590 of keeping the whole board with a piece on each square, 1320 01:02:55,590 --> 01:02:58,890 and then having to go and search for where the pieces are, 1321 01:02:58,890 --> 01:03:02,400 you can keep just a list of where the pawns are, 1322 01:03:02,400 --> 01:03:05,010 and what the locations of the kings are, 1323 01:03:05,010 --> 01:03:06,670 so that when you want to make a move, 1324 01:03:06,670 --> 01:03:09,690 you can just go through where they are, 1325 01:03:09,690 --> 01:03:12,420 rather than having to search through all 64 squares 1326 01:03:12,420 --> 01:03:13,800 on the board. 1327 01:03:13,800 --> 01:03:15,570 Then the other strategy that you can do 1328 01:03:15,570 --> 01:03:18,150 is use what's called bit boards, where 1329 01:03:18,150 --> 01:03:27,480 you have a 64-bit word for which, if there's 1330 01:03:27,480 --> 01:03:32,460 a pawn in a given position, you set that bit. 1331 01:03:32,460 --> 01:03:35,970 And so there are different ways of representing 1332 01:03:35,970 --> 01:03:41,860 things that could possibly be, definitely be, more efficient. 1333 01:03:41,860 --> 01:03:43,440 But you have some choices there. 1334 01:03:43,440 --> 01:03:46,260 And also, one of the complexities of this 1335 01:03:46,260 --> 01:03:48,630 is that to change the representation, 1336 01:03:48,630 --> 01:03:50,940 there's going to be places in the code you 1337 01:03:50,940 --> 01:03:56,700 need to find out where they're assuming that things are. 1338 01:03:56,700 --> 01:03:59,310 So you say, oh, I'll change the board representation. 1339 01:03:59,310 --> 01:04:01,530 Oh, I didn't realize that over here, there's 1340 01:04:01,530 --> 01:04:04,410 another place that it's using the board representation, 1341 01:04:04,410 --> 01:04:05,340 and so forth. 1342 01:04:05,340 --> 01:04:08,820 A good strategy for changing board representation 1343 01:04:08,820 --> 01:04:15,720 is to actually keep both representations around 1344 01:04:15,720 --> 01:04:18,600 while you migrate functionality from the old one 1345 01:04:18,600 --> 01:04:20,940 to the new one. 1346 01:04:20,940 --> 01:04:25,620 And then the advantage of that is that you can actually 1347 01:04:25,620 --> 01:04:28,560 then use assertions to say, you know, 1348 01:04:28,560 --> 01:04:32,860 the old one and the new one are the same. 1349 01:04:32,860 --> 01:04:38,385 So implementing conversion functions is really good. 1350 01:04:38,385 --> 01:04:39,760 For example, if you decide you're 1351 01:04:39,760 --> 01:04:42,460 going to use a bit board representation, 1352 01:04:42,460 --> 01:04:45,700 have a function that converts the bit board 1353 01:04:45,700 --> 01:04:50,050 to the standard board so that then you 1354 01:04:50,050 --> 01:04:55,660 can compare whether you've got the same thing. 1355 01:04:55,660 --> 01:05:00,678 And, eventually, you'll want to get rid of that. 1356 01:05:00,678 --> 01:05:02,470 And, of course, that'll slow down you down, 1357 01:05:02,470 --> 01:05:04,480 because you're doing more things. 1358 01:05:04,480 --> 01:05:06,640 But it will allow you to get it correct 1359 01:05:06,640 --> 01:05:08,880 with a new representation. 1360 01:05:08,880 --> 01:05:11,290 And once you've got it correct with a new representation 1361 01:05:11,290 --> 01:05:14,710 with the old one gone, that's when you have a chance 1362 01:05:14,710 --> 01:05:17,320 to make things go fast. 1363 01:05:17,320 --> 01:05:21,430 But it kind of is taking two steps backwards 1364 01:05:21,430 --> 01:05:23,260 to take five steps forward. 1365 01:05:23,260 --> 01:05:27,640 I say not one step and two steps, because really, often, 1366 01:05:27,640 --> 01:05:31,870 you really are slowing things down considerably in order 1367 01:05:31,870 --> 01:05:35,350 to convert from one representation to another. 1368 01:05:35,350 --> 01:05:38,560 The most important thing is you maintain the invariant 1369 01:05:38,560 --> 01:05:41,235 of correctness in your code. 1370 01:05:41,235 --> 01:05:42,610 You do not want to make something 1371 01:05:42,610 --> 01:05:45,340 that goes faster, but is wrong, and have 1372 01:05:45,340 --> 01:05:47,620 to debug the correctness. 1373 01:05:47,620 --> 01:05:52,262 You'd much rather ensure that things are correct, 1374 01:05:52,262 --> 01:05:54,220 are moving to the place that you want to do it. 1375 01:05:54,220 --> 01:05:58,600 And then you can optimize for performance. 1376 01:05:58,600 --> 01:06:00,250 So the most important thing is keep 1377 01:06:00,250 --> 01:06:02,122 that invariant of correctness. 1378 01:06:02,122 --> 01:06:03,580 And that's where the testing and so 1379 01:06:03,580 --> 01:06:06,700 forth comes in, having good test infrastructure, 1380 01:06:06,700 --> 01:06:09,400 and having assertions littered throughout your code. 1381 01:06:09,400 --> 01:06:12,820 HELEN XU: And then we can go through the [INAUDIBLE].. 1382 01:06:17,010 --> 01:06:20,760 Actually, OK, so, just as an example 1383 01:06:20,760 --> 01:06:23,610 of how you would possibly, one way 1384 01:06:23,610 --> 01:06:27,000 of determining whether or not you state correct-- 1385 01:06:27,000 --> 01:06:31,560 so this is an example of a place where I compiled the code. 1386 01:06:31,560 --> 01:06:33,857 See the binary code is called Lesierchess. 1387 01:06:33,857 --> 01:06:35,940 And if you look at help, it gives you some options 1388 01:06:35,940 --> 01:06:37,596 for what you can do. 1389 01:06:40,490 --> 01:06:41,890 For example, there's display. 1390 01:06:41,890 --> 01:06:43,430 And that's the opening position. 1391 01:06:43,430 --> 01:06:45,410 And let's say I want to search. 1392 01:06:45,410 --> 01:06:49,460 So I do a fixed depth, and go depth three. 1393 01:06:49,460 --> 01:06:52,910 And it tells me the number of nodes 1394 01:06:52,910 --> 01:06:55,790 that I searched at each depth. 1395 01:06:55,790 --> 01:06:59,660 And so if you make changes, if they are deterministic, 1396 01:06:59,660 --> 01:07:01,752 these node counts should stay the same. 1397 01:07:01,752 --> 01:07:02,960 So that's one way of telling. 1398 01:07:02,960 --> 01:07:04,335 So you should keep track of this, 1399 01:07:04,335 --> 01:07:05,960 and make sure that they're the same. 1400 01:07:05,960 --> 01:07:09,020 And also, you can do perft, which 1401 01:07:09,020 --> 01:07:12,680 gives you the number of possible moves you can make. 1402 01:07:12,680 --> 01:07:16,270 And that should be the same, no matter what you do. 1403 01:07:19,312 --> 01:07:20,520 So that's one way of testing. 1404 01:07:20,520 --> 01:07:23,150 There's other ways. 1405 01:07:23,150 --> 01:07:27,150 So if you go to higher depth, you'll get more node counts. 1406 01:07:30,600 --> 01:07:35,430 And here, this is nodes that you searched at this depth. 1407 01:07:35,430 --> 01:07:37,150 And this is nodes per second. 1408 01:07:37,150 --> 01:07:38,650 So you want to make this one faster. 1409 01:07:47,638 --> 01:07:48,930 So that's how you run the code. 1410 01:07:52,220 --> 01:07:55,100 And I was supposed to do a demo for the auto tester. 1411 01:07:57,790 --> 01:07:59,210 So let's say I wanted to do-- 1412 01:08:02,010 --> 01:08:05,325 so when I made it, it's in a binary called Lesierchess. 1413 01:08:08,620 --> 01:08:11,390 And then here, you can type in commands. 1414 01:08:11,390 --> 01:08:13,710 So you're basically just typing commands from this. 1415 01:08:13,710 --> 01:08:16,470 Like, you run your binary. 1416 01:08:16,470 --> 01:08:20,310 PROFESSOR: This is the UCI interface that we talked about. 1417 01:08:20,310 --> 01:08:25,240 And in Lesierchess.c is the implementation of that. 1418 01:08:25,240 --> 01:08:29,670 And so if you want to add your commands to it to help debug, 1419 01:08:29,670 --> 01:08:32,550 you can enter-- if we go into Lesierchess.c, 1420 01:08:32,550 --> 01:08:34,350 you can see the table. 1421 01:08:39,941 --> 01:08:41,399 What I want to do is show the table 1422 01:08:41,399 --> 01:08:45,270 of all the options, which is-- 1423 01:08:45,270 --> 01:08:46,560 there we go, OK. 1424 01:08:46,560 --> 01:08:48,350 HELEN XU: This is just the heuristics. 1425 01:08:48,350 --> 01:08:51,149 PROFESSOR: So these are tables of heuristics 1426 01:08:51,149 --> 01:08:56,460 and so forth, which allow you to set 1427 01:08:56,460 --> 01:09:02,939 the values of the various things, 1428 01:09:02,939 --> 01:09:05,729 and to say, how much is this heuristic 1429 01:09:05,729 --> 01:09:08,069 worth to the static evaluation? 1430 01:09:10,950 --> 01:09:12,600 And through these, all these can be 1431 01:09:12,600 --> 01:09:15,569 set, so you don't have to recompile 1432 01:09:15,569 --> 01:09:20,100 the binary if you want to try out things with different-- 1433 01:09:20,100 --> 01:09:22,830 if you want to auto test with, let 1434 01:09:22,830 --> 01:09:25,229 me count this as worth a third of a pawn. 1435 01:09:25,229 --> 01:09:29,580 Let me count this as worth half a pawn, or whatever. 1436 01:09:29,580 --> 01:09:32,790 You can just enter it through the UCI interface. 1437 01:09:32,790 --> 01:09:35,383 And in the auto tester, you can specify that. 1438 01:09:35,383 --> 01:09:37,800 So it will just test those without you having to recompile 1439 01:09:37,800 --> 01:09:40,710 binaries for every one of them. 1440 01:09:40,710 --> 01:09:43,600 And so there's a table here which basically says, 1441 01:09:43,600 --> 01:09:45,210 what's the name of the heuristic? 1442 01:09:45,210 --> 01:09:48,330 What's the variable that is going to be 1443 01:09:48,330 --> 01:09:52,109 set what the default value is? 1444 01:09:52,109 --> 01:09:55,770 And pawn ev value is the value of a pawn. 1445 01:09:55,770 --> 01:09:59,790 And if there's any restrictions on the range of those values, 1446 01:09:59,790 --> 01:10:01,440 what's the smallest it can be? 1447 01:10:01,440 --> 01:10:03,990 What's the largest it can be? 1448 01:10:03,990 --> 01:10:07,470 So you can edit this table, and so forth. 1449 01:10:07,470 --> 01:10:11,570 And as I say, you can set it through the UCI interface. 1450 01:10:11,570 --> 01:10:14,730 So it's really a very flexible way 1451 01:10:14,730 --> 01:10:18,630 of getting access to anything that you want to do. 1452 01:10:18,630 --> 01:10:21,360 You can put your own commands in there, 1453 01:10:21,360 --> 01:10:24,030 including new heuristics, or whatever. 1454 01:10:27,870 --> 01:10:29,430 And there's some things in there. 1455 01:10:29,430 --> 01:10:32,370 For example, if we go to the other part 1456 01:10:32,370 --> 01:10:41,500 where they actually are passing the UCI stuff, 1457 01:10:41,500 --> 01:10:43,090 so it basically takes it. 1458 01:10:43,090 --> 01:10:45,760 It parses it, figures out what the command is, and then 1459 01:10:45,760 --> 01:10:47,080 implements the command. 1460 01:10:47,080 --> 01:10:50,220 So all that kind of stuff, you have control over. 1461 01:10:50,220 --> 01:10:55,970 So that that will help you in choosing to do other things. 1462 01:10:55,970 --> 01:10:59,030 So, for example, if you search for perft or something 1463 01:10:59,030 --> 01:10:59,530 in there-- 1464 01:11:02,500 --> 01:11:04,630 so if you have perft, here's what 1465 01:11:04,630 --> 01:11:06,220 the correct outputs should be. 1466 01:11:06,220 --> 01:11:09,910 And now, here's the code that it executes. 1467 01:11:09,910 --> 01:11:11,682 And perft is in a different file. 1468 01:11:11,682 --> 01:11:13,390 I think it's in the move generation file. 1469 01:11:21,262 --> 01:11:24,070 HELEN XU: Do I have the wrong output? 1470 01:11:24,070 --> 01:11:26,080 PROFESSOR: That may be for the older game, yeah. 1471 01:11:26,080 --> 01:11:28,420 I actually noticed a couple of other bugs in there 1472 01:11:28,420 --> 01:11:31,960 that hadn't been fixed. 1473 01:11:31,960 --> 01:11:34,450 So we will make sure that those are-- 1474 01:11:34,450 --> 01:11:36,810 basically, it's just dead code, is what's in there. 1475 01:11:36,810 --> 01:11:38,560 We need to clean up some of the dead code. 1476 01:11:38,560 --> 01:11:40,030 Some of the code is from last year. 1477 01:11:40,030 --> 01:11:41,830 And we changed the game. 1478 01:11:41,830 --> 01:11:43,900 And not all the dead code got eliminated. 1479 01:11:43,900 --> 01:11:46,150 HELEN XU: That'll be fixed for when I make the repost. 1480 01:11:46,150 --> 01:11:46,817 PROFESSOR: Yeah. 1481 01:11:49,660 --> 01:11:53,530 So we're just finishing up some-- 1482 01:11:53,530 --> 01:11:56,710 right now, I think it's all cleanliness. 1483 01:11:56,710 --> 01:11:59,080 But if you find any bugs like that, let us know. 1484 01:11:59,080 --> 01:12:02,080 We'll fix them, and so forth. 1485 01:12:02,080 --> 01:12:08,260 Appreciate if you do see other inconsistencies, 1486 01:12:08,260 --> 01:12:09,374 or what have you. 1487 01:12:13,110 --> 01:12:18,360 Good, so great project, this is like lots of fun. 1488 01:12:18,360 --> 01:12:21,005 Next month is going to be lots of fun for all of you. 1489 01:12:21,005 --> 01:12:23,130 You may not think it's fun every minute of the day. 1490 01:12:23,130 --> 01:12:26,310 But you'll have a good time. 1491 01:12:26,310 --> 01:12:28,160 It is fun.