1 00:00:00,070 --> 00:00:01,670 The following content is provided 2 00:00:01,670 --> 00:00:03,800 under a Creative Commons license. 3 00:00:03,800 --> 00:00:06,540 Your support will help MIT OpenCourseWare continue 4 00:00:06,540 --> 00:00:10,140 to offer high quality educational resources for free. 5 00:00:10,140 --> 00:00:12,680 To make a donation or to view additional materials 6 00:00:12,680 --> 00:00:16,590 from hundreds of MIT courses, visit MIT OpenCourseWare 7 00:00:16,590 --> 00:00:17,297 at ocw.mit.edu. 8 00:00:27,560 --> 00:00:29,970 CORY: I guess I'll start now since I think 9 00:00:29,970 --> 00:00:32,220 this might be the crowd since most people are probably 10 00:00:32,220 --> 00:00:36,330 sleeping after the sprint submission deadline. 11 00:00:36,330 --> 00:00:39,210 Were most people up at 6:00 AM? 12 00:00:39,210 --> 00:00:39,960 Most? 13 00:00:39,960 --> 00:00:41,590 Most if not all. 14 00:00:41,590 --> 00:00:45,030 Alright, so, my name is Cory. 15 00:00:45,030 --> 00:00:47,460 I'm from the winning team last year 16 00:00:47,460 --> 00:00:49,380 and what I really want to do today 17 00:00:49,380 --> 00:00:52,560 is kind of give a complete information dump. 18 00:00:52,560 --> 00:00:56,020 So this lecture will almost seem like a stream of conscious, 19 00:00:56,020 --> 00:00:59,630 but these are the things that throughout all 20 00:00:59,630 --> 00:01:01,830 of our years at battle code are the things we really 21 00:01:01,830 --> 00:01:04,989 wish we'd got in lecture but never actually got. 22 00:01:04,989 --> 00:01:10,070 So my goal is hopefully to give the most relevant-- hopefully 23 00:01:10,070 --> 00:01:12,950 like the most applicable lecture to the nitty 24 00:01:12,950 --> 00:01:15,210 gritty details of the day to day. 25 00:01:15,210 --> 00:01:16,710 Things that you're doing battle code 26 00:01:16,710 --> 00:01:18,376 in order to make your bot better and try 27 00:01:18,376 --> 00:01:21,190 to improve your performance against the other teams. 28 00:01:21,190 --> 00:01:24,330 So whatever competitive edge you can glean from this hopefully 29 00:01:24,330 --> 00:01:27,060 propel yourself to the top of the ladder. 30 00:01:27,060 --> 00:01:31,840 So just to give a little bit of background about myself, 31 00:01:31,840 --> 00:01:34,730 I've been in three teams since 2010. 32 00:01:34,730 --> 00:01:37,270 The first two years where we're kind of meh. 33 00:01:37,270 --> 00:01:42,410 But in 2012 we were finally able to win the entire thing 34 00:01:42,410 --> 00:01:46,230 with my teammates, Yanping, Haitao and Justin. 35 00:01:46,230 --> 00:01:49,727 And in each year was quite different because of the people 36 00:01:49,727 --> 00:01:50,310 you work with. 37 00:01:50,310 --> 00:01:55,210 So what I want to do is give a lot about our 2012 experiences, 38 00:01:55,210 --> 00:01:58,100 and kind of explain the various choices we did. 39 00:01:58,100 --> 00:02:00,210 The tricks and techniques we did in order 40 00:02:00,210 --> 00:02:02,900 to give ourselves an edge over the other team. 41 00:02:02,900 --> 00:02:05,890 And I also want to give special thanks to these four 42 00:02:05,890 --> 00:02:08,699 teams in particular, Gunface, My Archon Died Bellmanfording 43 00:02:08,699 --> 00:02:11,270 the Stream, Drunkasaurus and Toothless. 44 00:02:11,270 --> 00:02:13,600 Just know that battle code is not done in a vacuum, 45 00:02:13,600 --> 00:02:15,670 and you learned from all the other teams. 46 00:02:15,670 --> 00:02:17,820 And so these teams were particularly helpful 47 00:02:17,820 --> 00:02:21,090 that our team learned from, that our team collaborated with. 48 00:02:21,090 --> 00:02:22,940 That we were able to share code bases 49 00:02:22,940 --> 00:02:25,670 and learn from each other, et cetera. 50 00:02:25,670 --> 00:02:29,380 So just to preface everything, we're the one's, fun gamers, 51 00:02:29,380 --> 00:02:31,650 is the one responsible for the spec this year. 52 00:02:31,650 --> 00:02:33,720 So if any of you guys have problems with it, 53 00:02:33,720 --> 00:02:37,190 you can't really blame Max or Stephen, you have to blame us. 54 00:02:37,190 --> 00:02:41,960 So any cries for like nerfing, OP, whatever, it comes to us. 55 00:02:41,960 --> 00:02:43,729 We made a lot of huge changes this year 56 00:02:43,729 --> 00:02:46,020 just because we wanted to mix up the game a little bit. 57 00:02:46,020 --> 00:02:48,760 And also we wanted to make it a little bit easier for people 58 00:02:48,760 --> 00:02:52,345 to start off code bases and get running players. 59 00:02:52,345 --> 00:02:53,720 I don't know how many of you guys 60 00:02:53,720 --> 00:02:58,060 played in 2010 or even 2011, but the amount 61 00:02:58,060 --> 00:03:00,770 of code required to get even a simple bot up and running 62 00:03:00,770 --> 00:03:02,160 was enormous. 63 00:03:02,160 --> 00:03:04,710 So in 2010, because you couldn't actually 64 00:03:04,710 --> 00:03:07,590 attack a unit until you had equipped a gun on a robot, 65 00:03:07,590 --> 00:03:10,320 it took almost one to two days worth of code base 66 00:03:10,320 --> 00:03:13,130 before you could even get a robot moving and attacking 67 00:03:13,130 --> 00:03:14,490 simultaneously. 68 00:03:14,490 --> 00:03:16,610 So what we did a lot was simplify 69 00:03:16,610 --> 00:03:20,610 a huge number of things to make it a lot more higher 70 00:03:20,610 --> 00:03:21,860 level strategic control. 71 00:03:21,860 --> 00:03:25,040 So no walls, attacking is completely automatic, 72 00:03:25,040 --> 00:03:26,124 we removed directionality. 73 00:03:26,124 --> 00:03:28,248 I don't know how many of you guys played last year, 74 00:03:28,248 --> 00:03:29,690 but this one's pretty big. 75 00:03:29,690 --> 00:03:32,210 There's no robot directionality. 76 00:03:32,210 --> 00:03:34,500 We added in shared vision, global broadcasting, 77 00:03:34,500 --> 00:03:36,150 and a known map. 78 00:03:36,150 --> 00:03:40,300 So do most people enjoy these changes? 79 00:03:40,300 --> 00:03:43,074 Or at least people who have played it in previous years? 80 00:03:43,074 --> 00:03:44,770 Yeah? 81 00:03:44,770 --> 00:03:46,800 We're really excited, at least, about, 82 00:03:46,800 --> 00:03:50,280 in particular, having the map completely known 83 00:03:50,280 --> 00:03:52,820 and the global broadcasting, because it allows 84 00:03:52,820 --> 00:03:55,700 an unprecedented level of robot communication this year. 85 00:03:55,700 --> 00:03:58,360 So you can now, instead of having 86 00:03:58,360 --> 00:04:00,400 a bunch of almost completely autonomous robots 87 00:04:00,400 --> 00:04:02,159 with very limited broadcasting, you 88 00:04:02,159 --> 00:04:03,325 can have coordinate attacks. 89 00:04:03,325 --> 00:04:04,400 You know the map. 90 00:04:04,400 --> 00:04:07,390 You can design your strategy based on the map. 91 00:04:07,390 --> 00:04:10,970 Rather than wandering around for 100 to 1000 rounds, 92 00:04:10,970 --> 00:04:15,290 not knowing where to go, getting stuck behind voids, et cetera. 93 00:04:15,290 --> 00:04:17,250 The no walls is also very interesting. 94 00:04:17,250 --> 00:04:20,360 What we found in previous years is contestants 95 00:04:20,360 --> 00:04:23,400 will sometimes, if the math is really stupid or really 96 00:04:23,400 --> 00:04:25,480 retarded, what'll end up happening is you just 97 00:04:25,480 --> 00:04:28,160 watch for 3,000 rounds both people stuck 98 00:04:28,160 --> 00:04:30,600 in their base because of this really interesting concave 99 00:04:30,600 --> 00:04:32,740 of walls that prevents the people from getting 100 00:04:32,740 --> 00:04:35,030 out and actually engaging each other. 101 00:04:35,030 --> 00:04:36,890 So with no walls you can actually 102 00:04:36,890 --> 00:04:38,670 basically control the battlefield. 103 00:04:38,670 --> 00:04:41,160 You can defuse mines, you can add your own walls, 104 00:04:41,160 --> 00:04:43,160 you can prevent your enemies from attacking. 105 00:04:43,160 --> 00:04:48,497 You can create kind of-- you can bend the battlefield 106 00:04:48,497 --> 00:04:51,080 to your will, which we thought was really exciting, especially 107 00:04:51,080 --> 00:04:53,431 because you're no longer completely screwed over 108 00:04:53,431 --> 00:04:54,930 if the map wasn't what you expected. 109 00:04:58,040 --> 00:05:01,520 So to begin, I want to emphasize that battle code is 110 00:05:01,520 --> 00:05:02,920 a trade off of time. 111 00:05:02,920 --> 00:05:07,730 So this is what battle code ultimately comes down to. 112 00:05:07,730 --> 00:05:10,805 You have three to four weeks to basically implement 113 00:05:10,805 --> 00:05:12,240 an entire bot. 114 00:05:12,240 --> 00:05:13,790 And in these three to four weeks, 115 00:05:13,790 --> 00:05:16,140 you have to decide what is most important. 116 00:05:16,140 --> 00:05:18,770 If you spend your time on the wrong thing you will not win. 117 00:05:18,770 --> 00:05:21,360 You have to spend your time where it matters. 118 00:05:21,360 --> 00:05:24,050 And, in particular, I want to say that results to effort 119 00:05:24,050 --> 00:05:26,730 vary very highly between what you 120 00:05:26,730 --> 00:05:28,395 choose to spend your time on. 121 00:05:28,395 --> 00:05:30,770 So one of the most important things to spend your time on 122 00:05:30,770 --> 00:05:32,420 is attack micro. 123 00:05:32,420 --> 00:05:35,070 If you can win every engagement you will win the game. 124 00:05:35,070 --> 00:05:37,410 It doesn't matter if they're higher level strategy, 125 00:05:37,410 --> 00:05:39,360 if you always win the engagement you will beat 126 00:05:39,360 --> 00:05:41,110 their army straight up, no matter what. 127 00:05:41,110 --> 00:05:41,930 OK? 128 00:05:41,930 --> 00:05:43,140 Next is swarm code. 129 00:05:43,140 --> 00:05:45,400 If you're swarm moves together you'll 130 00:05:45,400 --> 00:05:46,602 usually win the engagement. 131 00:05:46,602 --> 00:05:48,560 If you have better swarm code your attack micro 132 00:05:48,560 --> 00:05:50,060 can be a little bit off. 133 00:05:50,060 --> 00:05:52,370 But you'll still end up engaging with larger numbers 134 00:05:52,370 --> 00:05:53,470 and winning the fight. 135 00:05:53,470 --> 00:05:55,190 And winning fights wins games. 136 00:05:55,190 --> 00:05:57,350 The navigation code that allows you to actually get 137 00:05:57,350 --> 00:05:59,040 to the enemy swarm and defeat them. 138 00:05:59,040 --> 00:06:00,810 And then there is some high level strategy 139 00:06:00,810 --> 00:06:02,890 that you can't make completely wrong choices. 140 00:06:02,890 --> 00:06:05,872 But, once again, if you have good attack micro, 141 00:06:05,872 --> 00:06:07,830 you can make questionable high level strategies 142 00:06:07,830 --> 00:06:09,854 but still win every engagement. 143 00:06:09,854 --> 00:06:11,770 So the way I'm going to structure this lecture 144 00:06:11,770 --> 00:06:15,520 is I'll have various tags. 145 00:06:15,520 --> 00:06:18,060 There are certain things that apply to novices. 146 00:06:18,060 --> 00:06:21,295 There are certain things that apply to advanced players. 147 00:06:21,295 --> 00:06:22,670 And then there are certain things 148 00:06:22,670 --> 00:06:24,530 that apply to expert players. 149 00:06:24,530 --> 00:06:26,480 This also comes down to a trade off of time. 150 00:06:26,480 --> 00:06:28,840 If you have four people, maybe you 151 00:06:28,840 --> 00:06:31,230 want to consider doing some of the more advanced tricks 152 00:06:31,230 --> 00:06:32,110 and tactics. 153 00:06:32,110 --> 00:06:34,185 But if you only have say, if you're working solo 154 00:06:34,185 --> 00:06:36,080 or you only have two people, you want 155 00:06:36,080 --> 00:06:38,230 to spend your time where it matters. 156 00:06:38,230 --> 00:06:41,470 So don't spend time implementing things that give you 157 00:06:41,470 --> 00:06:44,460 very tiny marginal advantages when you could, say, be 158 00:06:44,460 --> 00:06:46,270 focusing on your attack micro. 159 00:06:46,270 --> 00:06:48,740 And win all the battles rather than saving maybe 160 00:06:48,740 --> 00:06:50,505 like one or two bite codes per iteration. 161 00:06:53,890 --> 00:06:59,800 So first off, to do well in battle code you really 162 00:06:59,800 --> 00:07:01,010 have to know the spec. 163 00:07:01,010 --> 00:07:04,720 And I know we've been really bad at keeping the specs up 164 00:07:04,720 --> 00:07:05,990 to date, there've been typos. 165 00:07:05,990 --> 00:07:09,220 But hopefully by now everything has mostly 166 00:07:09,220 --> 00:07:12,300 been standardized and corrected, and all the typos. 167 00:07:12,300 --> 00:07:15,220 And then you guys didn't really like our the diffusion/defusion 168 00:07:15,220 --> 00:07:15,720 joke. 169 00:07:15,720 --> 00:07:19,169 So we changed the word defusion to diffusion 170 00:07:19,169 --> 00:07:20,960 so that you guys didn't think it was a typo 171 00:07:20,960 --> 00:07:22,760 and that we were stupid. 172 00:07:22,760 --> 00:07:26,270 So quick quiz, what's the base spawn rate? 173 00:07:26,270 --> 00:07:28,630 Someone call it out. 174 00:07:28,630 --> 00:07:29,130 Ten. 175 00:07:29,130 --> 00:07:30,450 Alright, nice. 176 00:07:30,450 --> 00:07:33,406 What's the cost for three suppliers? 177 00:07:33,406 --> 00:07:33,905 Cumulative? 178 00:07:37,000 --> 00:07:38,690 What was that? 179 00:07:38,690 --> 00:07:40,350 I think I heard it over there. 180 00:07:40,350 --> 00:07:40,850 60. 181 00:07:40,850 --> 00:07:41,350 Right. 182 00:07:41,350 --> 00:07:44,390 Because it starts off with 10 for the first supplier, 183 00:07:44,390 --> 00:07:46,770 then the cost is the additive. 184 00:07:46,770 --> 00:07:49,430 So 20 and then 30 and to 60, 60 the total cost 185 00:07:49,430 --> 00:07:50,590 for three suppliers. 186 00:07:50,590 --> 00:07:52,515 What is the spawn rate with three suppliers? 187 00:07:56,546 --> 00:07:57,940 It's 8. 188 00:07:57,940 --> 00:08:02,920 So total cost of three suppliers is-- the spawn rate of three 189 00:08:02,920 --> 00:08:08,050 suppliers is 8 per round because it is kind of a curve. 190 00:08:08,050 --> 00:08:09,932 The first supplier will get you down to 9. 191 00:08:09,932 --> 00:08:11,890 The second supplier will get you down to eight. 192 00:08:11,890 --> 00:08:14,150 And the third supplier is actually the first supplier 193 00:08:14,150 --> 00:08:16,140 that doesn't bring you down another point 194 00:08:16,140 --> 00:08:18,870 because it's rounded to the nearest integer. 195 00:08:18,870 --> 00:08:19,740 Even. 196 00:08:19,740 --> 00:08:21,762 So in terms of unit spawn, at out what round 197 00:08:21,762 --> 00:08:23,220 does the first supplier break even? 198 00:08:28,430 --> 00:08:30,269 So these are all like critical numbers 199 00:08:30,269 --> 00:08:31,810 that if you know you can kind of gain 200 00:08:31,810 --> 00:08:32,935 the spec to your advantage. 201 00:08:36,450 --> 00:08:37,909 Close. 202 00:08:37,909 --> 00:08:41,289 The first supplier breaks even at what round? 203 00:08:41,289 --> 00:08:45,570 If I get one supplier, I have one turn 204 00:08:45,570 --> 00:08:48,340 spawn reduction, which means I break even, 205 00:08:48,340 --> 00:08:50,760 in terms of units, at what round? 206 00:08:50,760 --> 00:08:53,330 I sacrifice one unit to get the supplier, 207 00:08:53,330 --> 00:08:54,890 so I'll break even when I get back 208 00:08:54,890 --> 00:08:56,880 that extra unit, which is at 90 rounds. 209 00:09:00,030 --> 00:09:03,530 So the first supplier breaks even at 90 rounds. 210 00:09:03,530 --> 00:09:05,796 So these are key numbers. 211 00:09:05,796 --> 00:09:07,170 They maybe tweaked in the future, 212 00:09:07,170 --> 00:09:10,060 but if you always have a sense of all these numbers, 213 00:09:10,060 --> 00:09:12,370 you can kind of make good high level decisions 214 00:09:12,370 --> 00:09:13,930 about what you should be building 215 00:09:13,930 --> 00:09:16,040 and what you shouldn't be building 216 00:09:16,040 --> 00:09:18,500 at the beginning of the game. 217 00:09:18,500 --> 00:09:20,900 So the beginning of the game is very key. 218 00:09:20,900 --> 00:09:23,831 What we did was you have an excess of energy. 219 00:09:23,831 --> 00:09:26,080 So you have a choice, like in Max's lecture yesterday, 220 00:09:26,080 --> 00:09:28,160 whether to build generators or suppliers. 221 00:09:28,160 --> 00:09:30,910 And if you know roughly at what time these things break even, 222 00:09:30,910 --> 00:09:34,260 or at what time you gain that the marginal advantage, 223 00:09:34,260 --> 00:09:37,620 you can decide when to attack or when not to attack. 224 00:09:37,620 --> 00:09:42,050 So know the specs, that's very key. 225 00:09:42,050 --> 00:09:45,570 Second, I want to say testing is probably 226 00:09:45,570 --> 00:09:48,430 the most important thing, second from spending 227 00:09:48,430 --> 00:09:50,492 your time in the correct place. 228 00:09:50,492 --> 00:09:52,200 Because you don't actually know if you're 229 00:09:52,200 --> 00:09:53,825 spending your time in the correct place 230 00:09:53,825 --> 00:09:56,270 unless you're actually testing the code. 231 00:09:56,270 --> 00:10:00,960 So as a high level, you want to write multiple distinct bots. 232 00:10:00,960 --> 00:10:04,660 So I know a lot of teams maybe just have a single bot lineage. 233 00:10:04,660 --> 00:10:09,340 But our team we wrote like 10 to 12 different bots, each one 234 00:10:09,340 --> 00:10:11,070 with different strategies. 235 00:10:11,070 --> 00:10:13,430 And sometimes we wrote bots completely from scratch 236 00:10:13,430 --> 00:10:15,570 when we thought we had a really cool strategy. 237 00:10:15,570 --> 00:10:18,800 So last year there were flying units. 238 00:10:18,800 --> 00:10:21,210 So we thought, well it would be kind of cool maybe 239 00:10:21,210 --> 00:10:24,140 if we could have units that only-- 240 00:10:24,140 --> 00:10:26,890 or if we had a base that only spawned flying units. 241 00:10:26,890 --> 00:10:29,340 And we did a little bit of theory crafting our head 242 00:10:29,340 --> 00:10:31,710 and it turned out the DPS was marginally higher. 243 00:10:31,710 --> 00:10:34,120 But the problem is once we tried to implement it, 244 00:10:34,120 --> 00:10:37,500 we found out the actual problems with the flyer strategy 245 00:10:37,500 --> 00:10:41,450 was that we couldn't sustain the units because of the way 246 00:10:41,450 --> 00:10:43,480 that energy transfer was done last year. 247 00:10:43,480 --> 00:10:46,280 And we weren't actually able to coordinate the attack well 248 00:10:46,280 --> 00:10:48,870 enough to gain that theoretical DPS. 249 00:10:48,870 --> 00:10:51,280 So testing is extremely important. 250 00:10:51,280 --> 00:10:53,550 Wins, of course, beat theory crafting. 251 00:10:53,550 --> 00:10:56,960 So even knowing the specs and knowing the break off times, 252 00:10:56,960 --> 00:10:59,140 you have to be able to implement them in practice, 253 00:10:59,140 --> 00:11:00,980 otherwise the theory doesn't pay off. 254 00:11:00,980 --> 00:11:03,140 The scrimmage server is your ally in testing. 255 00:11:03,140 --> 00:11:05,910 And then you always want to prioritize writing behaviors 256 00:11:05,910 --> 00:11:08,219 over spending a lot of time doing framework code. 257 00:11:08,219 --> 00:11:09,760 Because the behaviors are what you're 258 00:11:09,760 --> 00:11:13,340 actually testing, not the framework. 259 00:11:13,340 --> 00:11:17,340 One thing that novices make the mistake of is they're 260 00:11:17,340 --> 00:11:19,100 always afraid of ranked games. 261 00:11:19,100 --> 00:11:22,680 So has everyone in here played at least one ranked game? 262 00:11:22,680 --> 00:11:23,430 Yes? 263 00:11:23,430 --> 00:11:27,290 So what I want to say is it's really 264 00:11:27,290 --> 00:11:29,730 a problem more with novices than with the people who 265 00:11:29,730 --> 00:11:31,630 have been doing battle code for a long time. 266 00:11:31,630 --> 00:11:34,410 And the reason this is, is because sometimes you 267 00:11:34,410 --> 00:11:37,430 submit a bot and you're afraid that it's maybe not so good. 268 00:11:37,430 --> 00:11:39,010 Or there's some problems with it. 269 00:11:39,010 --> 00:11:40,957 Or that your code is going to do badly 270 00:11:40,957 --> 00:11:42,290 and you're going to lose points. 271 00:11:42,290 --> 00:11:45,030 But what it gains you is by scrimmaging often 272 00:11:45,030 --> 00:11:47,910 you will always know what the top teams are up to. 273 00:11:47,910 --> 00:11:49,480 And the thing is, if you do unranked, 274 00:11:49,480 --> 00:11:52,260 top teams actually have no incentive to accept your match, 275 00:11:52,260 --> 00:11:54,540 and you'll never know what they're actually doing. 276 00:11:54,540 --> 00:11:59,010 So the trade off is a top team, if they beat you 277 00:11:59,010 --> 00:12:00,560 in a ranked game, they'll actually 278 00:12:00,560 --> 00:12:01,630 gain [? ELOW ?] points. 279 00:12:01,630 --> 00:12:03,490 But you actually gain something from that. 280 00:12:03,490 --> 00:12:07,240 You gain the understanding of how the top team is micro-ing. 281 00:12:07,240 --> 00:12:09,840 The kind of high level strategy the top team is doing. 282 00:12:09,840 --> 00:12:12,890 And also any tips or tricks or small things 283 00:12:12,890 --> 00:12:15,520 that you can glean from those games 284 00:12:15,520 --> 00:12:18,370 to perform better in your next bot iteration. 285 00:12:18,370 --> 00:12:22,180 Actually if you send an unranked game to one of the top teams, 286 00:12:22,180 --> 00:12:24,230 it's actually a lose-lose situation for them. 287 00:12:24,230 --> 00:12:26,140 Because A they have the probability 288 00:12:26,140 --> 00:12:28,170 of losing a lot of points to you. 289 00:12:28,170 --> 00:12:31,030 And B they're also giving away their high level strategy. 290 00:12:31,030 --> 00:12:35,532 So for the top five teams, at least in years past, 291 00:12:35,532 --> 00:12:36,990 if you sent them an unranked match, 292 00:12:36,990 --> 00:12:39,170 they'd cancel it and send you back a ranked match. 293 00:12:39,170 --> 00:12:41,040 Because there's almost no advantage for them 294 00:12:41,040 --> 00:12:42,810 to accept these unranked matches. 295 00:12:42,810 --> 00:12:44,960 So don't be afraid of sending ranked games, 296 00:12:44,960 --> 00:12:46,850 especially against top teams, because that's 297 00:12:46,850 --> 00:12:49,560 where you're going to learn the most about how 298 00:12:49,560 --> 00:12:50,640 you can improve your bot. 299 00:12:54,440 --> 00:12:57,100 Another thing that sometimes beginners get wrong 300 00:12:57,100 --> 00:13:00,520 is that your code base is actually more than your bot. 301 00:13:00,520 --> 00:13:03,300 There is a huge infrastructure that we 302 00:13:03,300 --> 00:13:05,430 built, at least around our bot last year, 303 00:13:05,430 --> 00:13:10,420 that was not just the simple-- that was not just robot player 304 00:13:10,420 --> 00:13:12,296 and everything surrounding robot player. 305 00:13:12,296 --> 00:13:13,920 So one of the easiest things you can do 306 00:13:13,920 --> 00:13:15,500 is you can make custom maps. 307 00:13:15,500 --> 00:13:18,310 Every year when we start battle code, we always 308 00:13:18,310 --> 00:13:20,790 make this map on the right, we call it plains, 309 00:13:20,790 --> 00:13:23,270 because there's absolutely nothing on it. 310 00:13:23,270 --> 00:13:27,310 The plains for this year, we have a few encampments 311 00:13:27,310 --> 00:13:30,560 in the middle just to test like basic encampment capture code. 312 00:13:30,560 --> 00:13:33,010 But what plains really allows you 313 00:13:33,010 --> 00:13:35,770 to do is it allows you to perfect your attack micro 314 00:13:35,770 --> 00:13:38,920 and make it so that you're not worrying about like advance 315 00:13:38,920 --> 00:13:41,880 path finding, you're just making sure you can win engagements. 316 00:13:41,880 --> 00:13:44,160 Because, as I said, attack micro is so important. 317 00:13:44,160 --> 00:13:46,740 Winning engagements wins games. 318 00:13:46,740 --> 00:13:50,079 So spend time, actually, making custom maps. 319 00:13:50,079 --> 00:13:52,370 I know we don't really have a map editor out this year. 320 00:13:52,370 --> 00:13:55,370 So if you make a map editor, too, 321 00:13:55,370 --> 00:13:57,210 make a bunch of custom maps. 322 00:13:57,210 --> 00:13:59,270 Test your path finding, test your attack micro. 323 00:13:59,270 --> 00:14:01,400 There's so many small things you can 324 00:14:01,400 --> 00:14:06,120 do to test your bot very fast. 325 00:14:06,120 --> 00:14:08,560 A few small things that you guys may have also not known 326 00:14:08,560 --> 00:14:11,320 is with custom maps you can actually 327 00:14:11,320 --> 00:14:14,500 declare units to be pre-spawned on the map. 328 00:14:14,500 --> 00:14:17,790 So in the top right you're allowed to declare symbols. 329 00:14:17,790 --> 00:14:19,850 You can actually set up unit formations 330 00:14:19,850 --> 00:14:22,080 to quickly test different scenarios. 331 00:14:22,080 --> 00:14:24,810 And just by hitting play and repeatedly running it, 332 00:14:24,810 --> 00:14:26,686 you can tweak whatever heuristics 333 00:14:26,686 --> 00:14:29,310 you're running in order to make sure that your code is actually 334 00:14:29,310 --> 00:14:30,420 running correctly. 335 00:14:30,420 --> 00:14:31,890 And then making custom maps is also 336 00:14:31,890 --> 00:14:34,040 extremely good for testing path finding. 337 00:14:34,040 --> 00:14:37,220 So you can spawn a map with a unit already in the center, 338 00:14:37,220 --> 00:14:41,940 and then just hard code in an endpoint to Nav2. 339 00:14:41,940 --> 00:14:43,627 And then see if your navigation is 340 00:14:43,627 --> 00:14:45,210 running any better than it was before. 341 00:14:47,780 --> 00:14:49,930 This is kind of a little expert thing 342 00:14:49,930 --> 00:14:54,110 but we spent a lot last year trying 343 00:14:54,110 --> 00:14:57,020 to gain the scrimmage server a little bit. 344 00:14:57,020 --> 00:15:00,940 So Justin wrote kind of a scraper that 345 00:15:00,940 --> 00:15:04,470 scrapes the rankings every five minutes 346 00:15:04,470 --> 00:15:08,060 and determines who's winning to who. 347 00:15:08,060 --> 00:15:09,510 If you guys are just starting out 348 00:15:09,510 --> 00:15:10,843 don't worry about this too much. 349 00:15:10,843 --> 00:15:12,830 But what this allowed us to do, actually, 350 00:15:12,830 --> 00:15:16,860 was it allowed us to know which teams were actually 351 00:15:16,860 --> 00:15:20,100 rising quickly, which teams had maybe changed their strategy. 352 00:15:20,100 --> 00:15:24,780 And it allowed us to kind of target our ranked matches. 353 00:15:24,780 --> 00:15:26,470 Because we would see oh this team 354 00:15:26,470 --> 00:15:28,600 won three games in rapid succession, 355 00:15:28,600 --> 00:15:30,230 we want to see what they're doing. 356 00:15:30,230 --> 00:15:33,170 Or oh this team maybe dropped four games 357 00:15:33,170 --> 00:15:35,260 and we probably don't really need 358 00:15:35,260 --> 00:15:37,490 to send them a ranked match because they're probably 359 00:15:37,490 --> 00:15:39,230 not doing anything different than what 360 00:15:39,230 --> 00:15:41,230 they used to be doing. 361 00:15:41,230 --> 00:15:43,620 But, once again, this is a custom tool 362 00:15:43,620 --> 00:15:46,270 that was written outside of the framework of just 363 00:15:46,270 --> 00:15:48,390 our eclipse project with our battle code bot that 364 00:15:48,390 --> 00:15:51,400 allowed us to gain a small competitive edge over everyone 365 00:15:51,400 --> 00:15:53,330 else. 366 00:15:53,330 --> 00:15:55,770 The current ladder stats ranking system is actually-- 367 00:15:55,770 --> 00:15:57,550 I think Justin posted about in the forums, 368 00:15:57,550 --> 00:15:58,860 he's actually running it publicly for you 369 00:15:58,860 --> 00:15:59,850 guys this year. 370 00:15:59,850 --> 00:16:04,460 So if you want to take a peek and just use his code-- 371 00:16:04,460 --> 00:16:08,330 Our old one actually recorded [? ELOW ?] gains and losses. 372 00:16:08,330 --> 00:16:11,830 So we could see whether a team gained 1 point 373 00:16:11,830 --> 00:16:13,090 or whether they gained 10. 374 00:16:13,090 --> 00:16:15,200 So if a team gained 30 points in a single match, 375 00:16:15,200 --> 00:16:16,440 that's like a warning bell, alright? 376 00:16:16,440 --> 00:16:19,023 Because it means they're doing something drastically different 377 00:16:19,023 --> 00:16:21,790 and you want to know what they're up to. 378 00:16:21,790 --> 00:16:26,040 This tool was another tool we borrowed from Gunface 379 00:16:26,040 --> 00:16:27,820 from 2011. 380 00:16:27,820 --> 00:16:30,060 It's basically a mass scrim tester. 381 00:16:30,060 --> 00:16:33,630 So the scrimmage server actually is not the only place 382 00:16:33,630 --> 00:16:34,630 that you can mass scrim. 383 00:16:34,630 --> 00:16:36,670 You can also build your own custom mass 384 00:16:36,670 --> 00:16:39,110 scrimming framework, which is what Gunface did in 2011 385 00:16:39,110 --> 00:16:41,479 and what we co-opted from them in 2012. 386 00:16:41,479 --> 00:16:43,020 So what this actually allows us to do 387 00:16:43,020 --> 00:16:46,410 is it allows us to test in house our own bots 388 00:16:46,410 --> 00:16:47,670 against each other. 389 00:16:47,670 --> 00:16:51,571 So you know how I said we wrote like 10 to 12 distinct bots? 390 00:16:51,571 --> 00:16:53,320 Well what we would do is we could actually 391 00:16:53,320 --> 00:16:54,820 characterize which one was strictly 392 00:16:54,820 --> 00:16:57,800 superior to all the other bots by pitting them 393 00:16:57,800 --> 00:16:59,850 against each other in thousands of matches. 394 00:16:59,850 --> 00:17:02,310 So if you'll see here, what this did 395 00:17:02,310 --> 00:17:05,250 was we had a total win counter. 396 00:17:05,250 --> 00:17:08,390 So we could submit jobs to our queue server. 397 00:17:08,390 --> 00:17:11,609 The queue would run like 50-60 matches on every single known 398 00:17:11,609 --> 00:17:13,839 map in the scrimmage ranking. 399 00:17:13,839 --> 00:17:16,430 And then, of course, it takes some time to compute. 400 00:17:16,430 --> 00:17:19,369 We actually borrowed a bunch of xVM machines 401 00:17:19,369 --> 00:17:21,740 to continuously run this in the background. 402 00:17:21,740 --> 00:17:26,119 But you'll see here every single one of our tagged releases, 403 00:17:26,119 --> 00:17:28,319 we're actually pitting it against each other. 404 00:17:28,319 --> 00:17:30,750 Last year we would consider a bot good 405 00:17:30,750 --> 00:17:36,700 if we could beat our older iterations 90% of the time. 406 00:17:36,700 --> 00:17:39,240 And until we could get kind of that 90% mark 407 00:17:39,240 --> 00:17:41,150 we would consider them about to be equal. 408 00:17:41,150 --> 00:17:43,675 Because some small change, in maybe like the random number 409 00:17:43,675 --> 00:17:45,050 generator, whatever, would affect 410 00:17:45,050 --> 00:17:46,600 the outcome of the match. 411 00:17:46,600 --> 00:17:48,740 But, again, the most drastic improvements-- 412 00:17:48,740 --> 00:17:53,300 when you see 31-0, those are from usually 413 00:17:53,300 --> 00:17:55,741 from micro improvements where one bot will just-- 414 00:17:55,741 --> 00:17:58,240 the two armies will collide and one bot will just obliterate 415 00:17:58,240 --> 00:18:01,050 the other one, even with equal numbers. 416 00:18:01,050 --> 00:18:03,850 But these sort of things, running the mass scrim, 417 00:18:03,850 --> 00:18:07,210 you can really, really get a sense of. 418 00:18:07,210 --> 00:18:09,330 This is an expert level kind of thing. 419 00:18:09,330 --> 00:18:11,080 If you don't have-- if you have one person 420 00:18:11,080 --> 00:18:12,950 you're not going to blow your time 421 00:18:12,950 --> 00:18:15,430 writing a scrimmage based system. 422 00:18:15,430 --> 00:18:17,650 But if you have maybe three or four people 423 00:18:17,650 --> 00:18:19,840 you could take a day or so to maybe 424 00:18:19,840 --> 00:18:22,360 try to repurpose the old 2012 mass scrim tester, which 425 00:18:22,360 --> 00:18:29,880 is on GitHub, by the way, to get it working with the 2013 game. 426 00:18:29,880 --> 00:18:35,770 One thing that hasn't really been covered ever, I think, 427 00:18:35,770 --> 00:18:39,560 is kind of the byte code system in detail, 428 00:18:39,560 --> 00:18:41,040 I think in battle code. 429 00:18:41,040 --> 00:18:43,580 And this is a very key part of battle code 430 00:18:43,580 --> 00:18:45,870 and yet it's always kind of glossed over. 431 00:18:45,870 --> 00:18:49,490 You'll hear the lecturer say you should use less byte codes. 432 00:18:49,490 --> 00:18:52,590 Or the less byte codes you use the more units you can have. 433 00:18:52,590 --> 00:18:55,170 But what does that actually mean and how 434 00:18:55,170 --> 00:18:59,390 does that actually translate into implementation? 435 00:18:59,390 --> 00:19:04,630 So I'll skip ahead and just give a brief overview of the JVM 436 00:19:04,630 --> 00:19:06,810 for people who are unfamiliar with it. 437 00:19:06,810 --> 00:19:09,770 So the Java Virtual Machine is a stack based system. 438 00:19:09,770 --> 00:19:12,432 So what it basically means is if you're familiar with x86 439 00:19:12,432 --> 00:19:13,890 or whatever, there are no registers 440 00:19:13,890 --> 00:19:15,680 is just a giant stack. 441 00:19:15,680 --> 00:19:20,530 And you can imagine it as values get pushed on the stack 442 00:19:20,530 --> 00:19:25,160 and popped off of the stack, and that's how computation is done. 443 00:19:25,160 --> 00:19:27,360 Byte codes are-- when you write your Java 444 00:19:27,360 --> 00:19:29,470 it gets compiled into something called byte codes. 445 00:19:29,470 --> 00:19:31,490 And byte codes are very similar to assembly, 446 00:19:31,490 --> 00:19:34,190 except they work on this stacked based system. 447 00:19:34,190 --> 00:19:35,580 And the way this stack is, is you 448 00:19:35,580 --> 00:19:39,210 have this operand stack which is your current stack of values. 449 00:19:39,210 --> 00:19:44,000 So if you imagine like a prefix operations 450 00:19:44,000 --> 00:19:45,820 I can push-- or postfix operations, 451 00:19:45,820 --> 00:19:48,360 I can push to values on the stack, I can call add 452 00:19:48,360 --> 00:19:50,140 and it would pop off the result, right? 453 00:19:50,140 --> 00:19:54,010 So if you imagine the JVM is kind of working like that, 454 00:19:54,010 --> 00:19:55,740 it's very similar. 455 00:19:55,740 --> 00:19:59,880 But there's also an array of local variables up top 456 00:19:59,880 --> 00:20:03,260 and these are indexed by a number. 457 00:20:03,260 --> 00:20:07,930 So, actually, stack operands can operate directly 458 00:20:07,930 --> 00:20:12,500 onto the array of variables that are globally accessible. 459 00:20:12,500 --> 00:20:14,850 And then there's also a global constants pool 460 00:20:14,850 --> 00:20:19,320 that byte codes can operate on. 461 00:20:19,320 --> 00:20:21,490 So this is just an example online. 462 00:20:21,490 --> 00:20:24,200 And if you want to read more there's a URL down here. 463 00:20:24,200 --> 00:20:26,510 But what happens is you compile your Java, 464 00:20:26,510 --> 00:20:30,060 it gets turned into byte codes, and each byte code is actually 465 00:20:30,060 --> 00:20:32,840 stepped through by our instrumentation engine. 466 00:20:32,840 --> 00:20:34,990 And that's what you're getting counted on. 467 00:20:34,990 --> 00:20:37,140 So when someone says you're using 10 byte codes, 468 00:20:37,140 --> 00:20:38,890 it actually means that the high level Java 469 00:20:38,890 --> 00:20:41,890 call you made is being turned into 10 470 00:20:41,890 --> 00:20:46,650 individual atomic steps on the JVM. 471 00:20:46,650 --> 00:20:50,420 And you're getting penalized for each one of these atomic steps. 472 00:20:50,420 --> 00:20:53,530 This leads to a lot of interesting things. 473 00:20:53,530 --> 00:20:57,210 So there's a very classic kind of loop structure 474 00:20:57,210 --> 00:20:58,480 in battle code. 475 00:20:58,480 --> 00:21:00,150 I hear this is so classic, actually, 476 00:21:00,150 --> 00:21:04,010 that Dropbox's code base is littered with this structure. 477 00:21:04,010 --> 00:21:06,275 So it looks like kind of a normal for loop, 478 00:21:06,275 --> 00:21:08,650 but if you look closely, you'll notice that we don't even 479 00:21:08,650 --> 00:21:10,220 have a third parameter. 480 00:21:10,220 --> 00:21:13,110 What this says is that for i is equal to the length 481 00:21:13,110 --> 00:21:16,920 of the ray, decrement until you're greater than zero. 482 00:21:16,920 --> 00:21:20,090 And it's reversed from maybe the way normal computer 483 00:21:20,090 --> 00:21:21,950 science would teach it to you. 484 00:21:21,950 --> 00:21:24,630 But there's a particular reason we do it this way. 485 00:21:24,630 --> 00:21:27,070 And that's because we're actually byte code hacking. 486 00:21:27,070 --> 00:21:35,230 So what happens is Java is similar-- kind of like there's 487 00:21:35,230 --> 00:21:39,210 legacy in computers testing again zero 488 00:21:39,210 --> 00:21:42,510 is actually an operation that comes up very often. 489 00:21:42,510 --> 00:21:47,177 In most branch conditions you're testing against zero. 490 00:21:47,177 --> 00:21:49,260 Like Booleans are testing against zero, et cetera. 491 00:21:49,260 --> 00:21:50,884 So there's actually a special byte code 492 00:21:50,884 --> 00:21:51,940 for testing against zero. 493 00:21:51,940 --> 00:21:55,230 And then, also, when you're doing the comparison 494 00:21:55,230 --> 00:21:56,960 you don't want to be recomputing, 495 00:21:56,960 --> 00:21:59,520 say, msgs.length every single time. 496 00:21:59,520 --> 00:22:01,850 So this actually has a net effect 497 00:22:01,850 --> 00:22:04,011 of saving byte codes because you can actually 498 00:22:04,011 --> 00:22:05,510 write the byte codes out but you can 499 00:22:05,510 --> 00:22:08,270 predict what the compiler will spit out. 500 00:22:08,270 --> 00:22:11,050 And because battle code is not run as just 501 00:22:11,050 --> 00:22:12,980 in time compilation, actually, the byte code 502 00:22:12,980 --> 00:22:16,330 steps through exactly as its outputted. 503 00:22:16,330 --> 00:22:20,370 This ends up with a net savings of a few byte codes. 504 00:22:20,370 --> 00:22:22,900 So if you'll see down here, this is like the classic way 505 00:22:22,900 --> 00:22:24,441 you would write a loop that you might 506 00:22:24,441 --> 00:22:26,090 learn in intro to computer science. 507 00:22:26,090 --> 00:22:27,990 For i is equal to zero, i is less 508 00:22:27,990 --> 00:22:31,660 than your terminating condition, increment i. 509 00:22:31,660 --> 00:22:33,860 What happens here is because you want 510 00:22:33,860 --> 00:22:37,390 to compare i every round to msgs.length. 511 00:22:37,390 --> 00:22:40,240 Computing msgs.length is actually 512 00:22:40,240 --> 00:22:43,950 a separate compare operation with loading the actual object, 513 00:22:43,950 --> 00:22:45,840 loading the actual array object. 514 00:22:45,840 --> 00:22:49,310 Whereas in our initial version what we've done here 515 00:22:49,310 --> 00:22:54,970 is we've set the index variable actually to the final value. 516 00:22:54,970 --> 00:22:56,510 And we're comparing against zero, 517 00:22:56,510 --> 00:22:58,580 which is a single byte code operation. 518 00:22:58,580 --> 00:23:01,030 So what happens is that this is a net savings 519 00:23:01,030 --> 00:23:03,790 of two byte codes. 520 00:23:03,790 --> 00:23:06,560 Two byte codes actually might not seem like a lot, 521 00:23:06,560 --> 00:23:09,100 but if you're, say, looping through 100 objects 522 00:23:09,100 --> 00:23:11,910 that that's 200 byte codes saved in the entire loop. 523 00:23:11,910 --> 00:23:13,800 And that's two whole sense functions. 524 00:23:13,800 --> 00:23:16,530 So you could send-- that's two whole global sense functions, 525 00:23:16,530 --> 00:23:18,780 with the radius and the location. 526 00:23:18,780 --> 00:23:20,440 That's actually pretty big. 527 00:23:20,440 --> 00:23:24,400 So saving 200 byte codes can mean 528 00:23:24,400 --> 00:23:27,150 that you might have additional data on the battlefield. 529 00:23:27,150 --> 00:23:29,550 Or you can loop through one additional object when you're 530 00:23:29,550 --> 00:23:32,490 trying to compute a heuristic for map locations 531 00:23:32,490 --> 00:23:33,960 or for army positions. 532 00:23:33,960 --> 00:23:37,230 And this actually gives you a small marginal competitive edge 533 00:23:37,230 --> 00:23:38,300 over the other team. 534 00:23:38,300 --> 00:23:40,090 Especially this year when byte codes also 535 00:23:40,090 --> 00:23:41,690 translates to energy. 536 00:23:41,690 --> 00:23:45,380 So saving byte codes gives you back more energy. 537 00:23:45,380 --> 00:23:47,420 More energy translates to more units. 538 00:23:47,420 --> 00:23:50,910 If all your units are saving 500 byte codes per turn 539 00:23:50,910 --> 00:23:54,480 that adds up over time, especially with the decay rate. 540 00:23:57,170 --> 00:24:01,200 So with byte codes you'll also end up 541 00:24:01,200 --> 00:24:03,980 wanting to implement your own data structures. 542 00:24:03,980 --> 00:24:10,150 So I don't know if you guys have tried using the native Java 543 00:24:10,150 --> 00:24:14,130 data structures like hashset, array q set, et cetera. 544 00:24:14,130 --> 00:24:17,250 But we actually penalize you for the internal calls 545 00:24:17,250 --> 00:24:20,110 that Java makes in those data sets. 546 00:24:20,110 --> 00:24:23,250 So if Java-- Java likes to be very safe. 547 00:24:23,250 --> 00:24:24,960 So a lot of the thread safe code we'll 548 00:24:24,960 --> 00:24:26,770 check to make sure another thread is not 549 00:24:26,770 --> 00:24:29,710 trying to mutate the data, or that there's 550 00:24:29,710 --> 00:24:31,934 on a lock on the data, et cetera. 551 00:24:31,934 --> 00:24:33,600 So the thread safe code actually ends up 552 00:24:33,600 --> 00:24:34,850 hurting you a lot, because there's 553 00:24:34,850 --> 00:24:36,690 a lot of excess byte codes that gets called. 554 00:24:36,690 --> 00:24:40,190 So, for instance, a single hashset.iterator.getnext 555 00:24:40,190 --> 00:24:42,500 getting a value from a hashset, worst case 556 00:24:42,500 --> 00:24:46,300 is 2k byte codes for a single call, which is absurd. 557 00:24:46,300 --> 00:24:48,980 Because you can implement a hashset yourself with an array 558 00:24:48,980 --> 00:24:52,947 and maybe like 200-300 byte codes if you custom write it. 559 00:24:52,947 --> 00:24:54,780 So what ends up happening is a lot of people 560 00:24:54,780 --> 00:24:56,404 will make what's called fast data sets. 561 00:24:56,404 --> 00:25:00,690 So we wrote a fast hashset, a fast arraylist. 562 00:25:00,690 --> 00:25:03,360 And these are all custom based on arrays 563 00:25:03,360 --> 00:25:05,920 that we could index directly into and pay 564 00:25:05,920 --> 00:25:08,060 a very minimal byte code cost in order 565 00:25:08,060 --> 00:25:12,060 to get very complex data structures back. 566 00:25:12,060 --> 00:25:15,620 Same thing goes for algorithms. 567 00:25:15,620 --> 00:25:19,877 You may think that-- a lot of beginners 568 00:25:19,877 --> 00:25:21,710 will start off trying to implement something 569 00:25:21,710 --> 00:25:26,310 like [? astar ?] or a flood fill algorithm just to do 570 00:25:26,310 --> 00:25:26,860 navigation. 571 00:25:26,860 --> 00:25:27,360 Yes? 572 00:25:30,236 --> 00:25:33,640 Right, this is an example from-- 573 00:25:33,640 --> 00:25:35,840 I'll explain what exactly this one is. 574 00:25:35,840 --> 00:25:40,134 But just an overview, most n squared 575 00:25:40,134 --> 00:25:42,300 algorithms are completely untenable in the byte code 576 00:25:42,300 --> 00:25:43,060 system. 577 00:25:43,060 --> 00:25:44,670 So if you see an n squared algorithm 578 00:25:44,670 --> 00:25:47,110 it's not going to work unless you do something to it. 579 00:25:47,110 --> 00:25:48,830 So there are multiple ways. 580 00:25:48,830 --> 00:25:51,150 You can distribute it among multiple robots, 581 00:25:51,150 --> 00:25:53,100 which is actually very hard. 582 00:25:53,100 --> 00:25:56,910 You can break up the computation into multiple steps 583 00:25:56,910 --> 00:25:59,410 and run a piece each turn, which is hard 584 00:25:59,410 --> 00:26:01,050 depending on the algorithm. 585 00:26:01,050 --> 00:26:06,752 And then you can also just run a completely different algorithm. 586 00:26:06,752 --> 00:26:08,210 So the one I actually have up here, 587 00:26:08,210 --> 00:26:11,470 this is a cute little example from our old code base. 588 00:26:11,470 --> 00:26:13,190 It's not the actual implementation 589 00:26:13,190 --> 00:26:14,830 but it's the algorithm itself. 590 00:26:14,830 --> 00:26:17,150 This is called a multiply with carry. 591 00:26:17,150 --> 00:26:20,870 It's actually a pseudo random number generator. 592 00:26:20,870 --> 00:26:24,392 There's a period-- there's like a period of 2 to the 60th. 593 00:26:24,392 --> 00:26:25,850 But for all intents and purposes it 594 00:26:25,850 --> 00:26:27,650 is a random number generator. 595 00:26:27,650 --> 00:26:29,920 We actually implemented this because we 596 00:26:29,920 --> 00:26:33,890 noticed that math.random on seeding pays 144 byte codes. 597 00:26:33,890 --> 00:26:37,870 And then each subsequent getnextinteger call is 80. 598 00:26:37,870 --> 00:26:40,370 And we actually wrote our own custom random number generator 599 00:26:40,370 --> 00:26:44,820 to save 40 byte codes per call to get nextint. 600 00:26:44,820 --> 00:26:47,980 And so this is the algorithm actually pulled from Wikipedia, 601 00:26:47,980 --> 00:26:49,450 we changed a little bit. 602 00:26:49,450 --> 00:26:52,019 But, in essence, it's a bunch of bit operators 603 00:26:52,019 --> 00:26:53,560 that gives you a pseudo random number 604 00:26:53,560 --> 00:26:55,540 generator to save on byte codes. 605 00:26:55,540 --> 00:26:58,250 And if you have an algorithm that 606 00:26:58,250 --> 00:27:00,580 relies on a lot of random numbers 607 00:27:00,580 --> 00:27:03,440 the 40 per getnextinteger actually adds up. 608 00:27:06,560 --> 00:27:08,870 There's actually a tool, a really nice tool, 609 00:27:08,870 --> 00:27:12,505 that we used a lot last year call doctor garbage visualizer. 610 00:27:12,505 --> 00:27:14,880 I don't know why it's called doctor garbage, because it's 611 00:27:14,880 --> 00:27:16,360 one of the best tools ever. 612 00:27:16,360 --> 00:27:21,460 But what it does is it actually decompiles your class 613 00:27:21,460 --> 00:27:23,260 into the actual byte codes. 614 00:27:23,260 --> 00:27:25,682 And then it shows the control flow graph on the right. 615 00:27:25,682 --> 00:27:28,140 So the control flow graph will actually allow you to reason 616 00:27:28,140 --> 00:27:30,100 about where your short circuits are happening, 617 00:27:30,100 --> 00:27:31,850 because if you short circuit a code block, 618 00:27:31,850 --> 00:27:33,230 you're not actually paying the byte code for what 619 00:27:33,230 --> 00:27:34,385 you don't execute, right? 620 00:27:34,385 --> 00:27:35,760 So you'll want to terminate loops 621 00:27:35,760 --> 00:27:38,330 end-- you'll want to terminate loops early. 622 00:27:38,330 --> 00:27:42,910 You'll want to try to avoid code that 623 00:27:42,910 --> 00:27:45,140 doesn't have to be computed multiple times 624 00:27:45,140 --> 00:27:48,060 in order to reduce your total byte code count. 625 00:27:48,060 --> 00:27:50,636 So by having the control flow graph on the right, 626 00:27:50,636 --> 00:27:52,010 it's actually very easy to reason 627 00:27:52,010 --> 00:27:55,010 about how to save byte codes, especially when 628 00:27:55,010 --> 00:27:57,780 you'll see the control flow graph, plus the instruction, 629 00:27:57,780 --> 00:28:00,910 plus kind of a small comment about what the variable is 630 00:28:00,910 --> 00:28:03,470 or what the method call is or what the constant is. 631 00:28:09,970 --> 00:28:14,140 So that's enough for-- So, ultimately, with byte codes, 632 00:28:14,140 --> 00:28:17,910 the last thing I'll say is if you're not sure, test it. 633 00:28:17,910 --> 00:28:21,030 We give you a function called getbytecodesnum 634 00:28:21,030 --> 00:28:22,980 and this allows you to see what byte 635 00:28:22,980 --> 00:28:25,190 code number you're currently executing. 636 00:28:25,190 --> 00:28:27,690 So if I want to profile a particular function 637 00:28:27,690 --> 00:28:29,290 call or a particular algorithm, just 638 00:28:29,290 --> 00:28:32,830 surround it with two system.out print line getbytecodenum. 639 00:28:32,830 --> 00:28:35,150 And this will tell you the total number of byte codes 640 00:28:35,150 --> 00:28:36,960 that your algorithm took to execute. 641 00:28:36,960 --> 00:28:38,960 And you can use this to kind of profile it down. 642 00:28:38,960 --> 00:28:40,590 You can try different things but ultimately 643 00:28:40,590 --> 00:28:42,030 whatever gets that number smallest 644 00:28:42,030 --> 00:28:46,910 is what helps you bot when you're optimizing algorithms. 645 00:28:46,910 --> 00:28:51,222 We actually, at the bottom, this is a little loop 646 00:28:51,222 --> 00:28:52,680 that-- or this is a little function 647 00:28:52,680 --> 00:28:55,810 call that I've added at least every year. 648 00:28:55,810 --> 00:28:57,215 At the end of every robot's round 649 00:28:57,215 --> 00:28:58,674 it actually checks the round number 650 00:28:58,674 --> 00:29:00,298 and the current byte code number to see 651 00:29:00,298 --> 00:29:01,650 if it went over byte codes. 652 00:29:01,650 --> 00:29:05,950 And it will actually emit a warning to the system console 653 00:29:05,950 --> 00:29:07,180 that it went over byte codes. 654 00:29:07,180 --> 00:29:09,780 So actually it's really annoying but it's really helpful 655 00:29:09,780 --> 00:29:11,950 that if every time a robot goes over byte codes 656 00:29:11,950 --> 00:29:13,020 it yells at you. 657 00:29:13,020 --> 00:29:16,382 Because then you can play match if you're not actually 658 00:29:16,382 --> 00:29:18,340 profiling something-- or if you're not actually 659 00:29:18,340 --> 00:29:20,210 explicitly saying that, you can sometimes 660 00:29:20,210 --> 00:29:22,415 ignore it because the byte code number is just 661 00:29:22,415 --> 00:29:24,790 in the top right of the client and you'll kind of miss it 662 00:29:24,790 --> 00:29:25,730 sometimes. 663 00:29:25,730 --> 00:29:28,190 You'll see like, oh, maybe it's like 10k or whatever. 664 00:29:28,190 --> 00:29:32,500 But if your robot is yelling at you every time it goes over 10k 665 00:29:32,500 --> 00:29:34,231 and your entire army just screens 666 00:29:34,231 --> 00:29:35,980 in the middle of battle, there's something 667 00:29:35,980 --> 00:29:39,210 that has to be changed in order to make it so that you're not 668 00:29:39,210 --> 00:29:40,700 missing an attack-- or you're not 669 00:29:40,700 --> 00:29:43,890 missing a movement every turn that you could be moving. 670 00:29:43,890 --> 00:29:46,080 So this year, actually, it's even more critical 671 00:29:46,080 --> 00:29:47,413 because there are no cool downs. 672 00:29:47,413 --> 00:29:49,450 Every robot, every turn, can move. 673 00:29:49,450 --> 00:29:51,550 So if you go over byte codes once, 674 00:29:51,550 --> 00:29:53,100 that's a lost movement, which could 675 00:29:53,100 --> 00:29:55,360 translate to a lost attack. 676 00:29:55,360 --> 00:29:57,510 So it's very critical in battle situations 677 00:29:57,510 --> 00:29:59,210 that you do not go over byte code 678 00:29:59,210 --> 00:30:01,740 so you can get your movement. 679 00:30:01,740 --> 00:30:05,730 And I'll show you why in a bit especially in micro situations. 680 00:30:05,730 --> 00:30:08,350 So micro is really important, attack micro, 681 00:30:08,350 --> 00:30:10,320 I've been emphasizing this over and over. 682 00:30:10,320 --> 00:30:13,000 You should know the execution order of the robots. 683 00:30:13,000 --> 00:30:14,900 But you should know what happens when. 684 00:30:14,900 --> 00:30:16,440 So when do attacks happen. 685 00:30:16,440 --> 00:30:19,030 So when do attacks happen? 686 00:30:19,030 --> 00:30:21,000 At the end of the round, right. 687 00:30:21,000 --> 00:30:24,279 You should understand the discrete nature of the map 688 00:30:24,279 --> 00:30:26,820 and you should know that micro's better than everything else. 689 00:30:26,820 --> 00:30:28,486 So I don't know if Max has covered this, 690 00:30:28,486 --> 00:30:31,731 but in two robots which robot actually wins the one v one 691 00:30:31,731 --> 00:30:32,230 engagement? 692 00:30:37,140 --> 00:30:42,400 It is-- yes, it's the one who closes the gap first, 693 00:30:42,400 --> 00:30:44,430 is the one who wins the engagement. 694 00:30:44,430 --> 00:30:48,070 So if I have two robots, two squares apart, right now 695 00:30:48,070 --> 00:30:49,660 it's a stalemate. 696 00:30:49,660 --> 00:30:53,390 But if red makes the mistake to move in, what happens is blue 697 00:30:53,390 --> 00:30:56,610 closes the distance and gets the attack off first. 698 00:30:56,610 --> 00:31:00,060 And, all things being equal, red will attack second. 699 00:31:00,060 --> 00:31:02,780 But blue has already done the initial damage, which 700 00:31:02,780 --> 00:31:05,752 means on blue's turn where he kills red, 701 00:31:05,752 --> 00:31:07,710 red will not deal back the corresponding damage 702 00:31:07,710 --> 00:31:08,251 to kill blue. 703 00:31:08,251 --> 00:31:09,420 Blue will win. 704 00:31:09,420 --> 00:31:11,670 So blue will have one more robot in the next upcoming 705 00:31:11,670 --> 00:31:13,320 engagement and therefore higher DPS 706 00:31:13,320 --> 00:31:15,650 and will win the next battle. 707 00:31:15,650 --> 00:31:17,380 This situation is also particularly bad 708 00:31:17,380 --> 00:31:19,600 because red can't actually retreat. 709 00:31:19,600 --> 00:31:24,810 If red moves back, blue can still close the gap next turn. 710 00:31:24,810 --> 00:31:28,070 So understanding how the micro works in this game 711 00:31:28,070 --> 00:31:30,950 is actually very key to winning engagements. 712 00:31:30,950 --> 00:31:34,220 So in a one v one situation the gap closer 713 00:31:34,220 --> 00:31:37,150 always has the advantage. 714 00:31:37,150 --> 00:31:38,960 Just a straight up. 715 00:31:38,960 --> 00:31:42,460 So you will want to write code that takes this into account, 716 00:31:42,460 --> 00:31:45,460 so that you can actually win engagements. 717 00:31:45,460 --> 00:31:48,050 In a two v two situation, it's a little bit more complex. 718 00:31:48,050 --> 00:31:49,880 So what happens in two v two? 719 00:31:49,880 --> 00:31:51,900 So red can move forward. 720 00:31:51,900 --> 00:31:54,825 Blue can close the gap, but red can close the gap 721 00:31:54,825 --> 00:31:55,700 with the second unit. 722 00:31:55,700 --> 00:31:57,530 And now he's dealing twice DPS that blue 723 00:31:57,530 --> 00:32:00,370 has and will eventually win. 724 00:32:00,370 --> 00:32:02,970 Blue can actually-- if blue is clever, 725 00:32:02,970 --> 00:32:05,750 blue can actually micro to focus fire on a single unit, 726 00:32:05,750 --> 00:32:09,560 because damage is split evenly across all enemy robots. 727 00:32:09,560 --> 00:32:11,570 So blue can actually try to micro little bit 728 00:32:11,570 --> 00:32:16,810 to kill the bottom red unit, if red makes a mistake. 729 00:32:16,810 --> 00:32:22,610 But red will actually-- can move down and continuously 730 00:32:22,610 --> 00:32:26,310 attack blue until the blue robot is dead. 731 00:32:26,310 --> 00:32:27,790 And the two v one will win. 732 00:32:27,790 --> 00:32:32,600 And if red micros correctly he won't lose a single unit. 733 00:32:32,600 --> 00:32:35,500 So in a large flight-- in larger fights, 734 00:32:35,500 --> 00:32:37,190 the larger army has the advantage 735 00:32:37,190 --> 00:32:39,130 given correct positioning. 736 00:32:39,130 --> 00:32:43,040 Because you could assume in this sort of scenario blue 737 00:32:43,040 --> 00:32:45,510 can actually reduce this to a one v one flight 738 00:32:45,510 --> 00:32:50,560 if red does not make the correct choices in the subsequent five 739 00:32:50,560 --> 00:32:51,760 or six moves. 740 00:32:51,760 --> 00:32:55,580 So blue ball will move up and attack red and reduce it 741 00:32:55,580 --> 00:32:59,370 to a one v one scenario unless the red robot can 742 00:32:59,370 --> 00:33:02,800 retreat backwards while still attacking blue 743 00:33:02,800 --> 00:33:07,080 towards the bottom red unit and continue fighting so that they 744 00:33:07,080 --> 00:33:10,910 can turn the one v one into a two v one engagement. 745 00:33:10,910 --> 00:33:15,030 But these small, discrete steps are what you should actually 746 00:33:15,030 --> 00:33:17,030 be thinking about when you're writing microcode. 747 00:33:17,030 --> 00:33:21,600 It's very critical that you don't get indefinitely kited. 748 00:33:21,600 --> 00:33:25,480 It's very critical you do not write code that ends up 749 00:33:25,480 --> 00:33:27,114 in this scenario where you're attacking 750 00:33:27,114 --> 00:33:29,030 and you try to retreat, but you can't actually 751 00:33:29,030 --> 00:33:31,860 retreat in this game, because the opponent will 752 00:33:31,860 --> 00:33:32,800 close the distance. 753 00:33:32,800 --> 00:33:34,930 So there's only two scenarios in which you can retreat. 754 00:33:34,930 --> 00:33:36,700 You can retreat if there's an army behind you 755 00:33:36,700 --> 00:33:37,680 willing to back you up. 756 00:33:37,680 --> 00:33:39,821 Or you can treat if you're retreating over a mine. 757 00:33:39,821 --> 00:33:40,820 That gives you more DPS. 758 00:33:45,600 --> 00:33:48,217 So there's some team dynamics things 759 00:33:48,217 --> 00:33:49,300 that I just want to cover. 760 00:33:49,300 --> 00:33:52,300 This is mostly geared towards the novices in the room. 761 00:33:52,300 --> 00:33:54,850 But make sure you guys are using source control management. 762 00:33:54,850 --> 00:33:56,380 I think this goes without saying, 763 00:33:56,380 --> 00:33:58,880 every MIT class now emphasizes the importance 764 00:33:58,880 --> 00:34:00,160 of source control management. 765 00:34:00,160 --> 00:34:02,640 And I'll even say you should just use hosted source control 766 00:34:02,640 --> 00:34:03,440 management. 767 00:34:03,440 --> 00:34:05,970 So if you're using Git, if you're using Mercurial, 768 00:34:05,970 --> 00:34:11,750 you should just throw it up on one of these free hosted SCMs 769 00:34:11,750 --> 00:34:13,320 just because you don't want to deal 770 00:34:13,320 --> 00:34:14,445 with the server going down. 771 00:34:14,445 --> 00:34:17,780 So my first year we made the terrible mistake 772 00:34:17,780 --> 00:34:22,989 of hosting our own SVN server on an xVM machine 773 00:34:22,989 --> 00:34:24,040 from [INAUDIBLE]. 774 00:34:24,040 --> 00:34:27,760 And then randomly there was some down time that was uncontrolled 775 00:34:27,760 --> 00:34:31,060 and we didn't have access to our code base for like two days. 776 00:34:31,060 --> 00:34:32,170 So it was terrible. 777 00:34:32,170 --> 00:34:36,510 So just-- GitHub, these guys are paid to keep your source up, 778 00:34:36,510 --> 00:34:37,280 OK? 779 00:34:37,280 --> 00:34:40,699 So [INAUDIBLE] is not paid to maintain that your battle code 780 00:34:40,699 --> 00:34:42,250 source does not go down. 781 00:34:42,250 --> 00:34:44,845 So trust these large source control guys. 782 00:34:44,845 --> 00:34:47,379 And especially trust distributed source control, 783 00:34:47,379 --> 00:34:48,420 if you guys are familiar. 784 00:34:48,420 --> 00:34:53,739 I think Max gave a lecture on Git, so use it effectively. 785 00:34:53,739 --> 00:34:56,940 And also figure out your SCM-- your source control strategy. 786 00:34:56,940 --> 00:34:58,510 So this is actually a big one. 787 00:34:58,510 --> 00:35:02,584 Every team does they're kind of release cycle or, I would say, 788 00:35:02,584 --> 00:35:05,000 release cycle but you're like releasing bots, a little bit 789 00:35:05,000 --> 00:35:05,830 differently. 790 00:35:05,830 --> 00:35:07,680 So I'll explain the way we did it. 791 00:35:07,680 --> 00:35:09,470 We had a single package called Ducks, 792 00:35:09,470 --> 00:35:11,470 just because we really like ducks. 793 00:35:11,470 --> 00:35:12,480 Don't ask. 794 00:35:12,480 --> 00:35:16,700 We forked off a bot every time we release it. 795 00:35:16,700 --> 00:35:19,190 So in our mainline Ducks package, 796 00:35:19,190 --> 00:35:22,022 when we get to a state, we're saying this bot's reasonable. 797 00:35:22,022 --> 00:35:23,480 We want to submit it to the server. 798 00:35:23,480 --> 00:35:25,590 We'll actually copy the Ducks package, 799 00:35:25,590 --> 00:35:27,920 rename it to our kind of bot naming scheme, which 800 00:35:27,920 --> 00:35:32,780 is based on SC2AI levels, if you guys play Starcraft. 801 00:35:32,780 --> 00:35:35,380 And so we started off with a medium player. 802 00:35:35,380 --> 00:35:39,510 So we'll copy the Duck's package into the medium player package. 803 00:35:39,510 --> 00:35:41,340 And what this allows you to do is always 804 00:35:41,340 --> 00:35:44,040 have a copy of the medium player in your repository. 805 00:35:44,040 --> 00:35:46,490 So you can always pit your mainline bot 806 00:35:46,490 --> 00:35:48,070 against any of the other heads you've 807 00:35:48,070 --> 00:35:50,504 cut off from the repository. 808 00:35:50,504 --> 00:35:52,170 So some teams like to do it differently. 809 00:35:52,170 --> 00:35:58,482 I know Gunface in 2011 liked to use source control tagging. 810 00:35:58,482 --> 00:35:59,940 So what this allowed them to do was 811 00:35:59,940 --> 00:36:02,740 they could update to any version in the source control. 812 00:36:02,740 --> 00:36:03,920 And they could recompile it. 813 00:36:03,920 --> 00:36:05,490 But the issue with that is if you 814 00:36:05,490 --> 00:36:08,150 update you have to update your entire mainline package 815 00:36:08,150 --> 00:36:08,845 backwards. 816 00:36:08,845 --> 00:36:10,220 You have to recompile it, and you 817 00:36:10,220 --> 00:36:13,386 have to keep the class files around so that you can pit them 818 00:36:13,386 --> 00:36:14,760 against your current bot once you 819 00:36:14,760 --> 00:36:16,727 re-update to the current head. 820 00:36:16,727 --> 00:36:18,060 This gets a little bit annoying. 821 00:36:18,060 --> 00:36:20,480 And for us it was just simpler to persist 822 00:36:20,480 --> 00:36:23,250 like 30-40 copies of the same file just 823 00:36:23,250 --> 00:36:24,480 in different packages. 824 00:36:24,480 --> 00:36:26,210 Because it saves on time. 825 00:36:26,210 --> 00:36:28,690 It's not elegant, but elegance doesn't really 826 00:36:28,690 --> 00:36:30,300 matter that much when you're trying 827 00:36:30,300 --> 00:36:34,484 to finish a bot in the short amount of time that you have. 828 00:36:34,484 --> 00:36:35,900 We actually went one step further. 829 00:36:35,900 --> 00:36:37,774 This is technically part of the custom tools, 830 00:36:37,774 --> 00:36:39,980 but we actually had One touch deploy system. 831 00:36:39,980 --> 00:36:41,680 So we had a single script that was 832 00:36:41,680 --> 00:36:44,840 responsible for building the release, tagging the release, 833 00:36:44,840 --> 00:36:47,982 testing the release on our automated mass testing system. 834 00:36:47,982 --> 00:36:49,690 And then cutting the branch from mainline 835 00:36:49,690 --> 00:36:51,820 and pushing it back to the repository. 836 00:36:51,820 --> 00:36:53,970 This is very key, actually, if you're 837 00:36:53,970 --> 00:36:56,060 doing what some of you guys may have been doing 838 00:36:56,060 --> 00:36:58,280 last night in trying to submit like 20 seconds 839 00:36:58,280 --> 00:36:59,470 before the deadline. 840 00:36:59,470 --> 00:37:03,460 Because if something goes wrong you're completely screwed. 841 00:37:03,460 --> 00:37:06,230 So if you have a tool that you know works 842 00:37:06,230 --> 00:37:08,230 and you know roughly the amount of time it takes 843 00:37:08,230 --> 00:37:10,130 for it to work, it's standardized 844 00:37:10,130 --> 00:37:12,560 and you're less prone to human error. 845 00:37:12,560 --> 00:37:13,660 So we ran the script. 846 00:37:13,660 --> 00:37:14,450 Everything's done. 847 00:37:14,450 --> 00:37:15,160 We have a jar. 848 00:37:15,160 --> 00:37:15,910 We upload the jar. 849 00:37:15,910 --> 00:37:16,960 We're done. 850 00:37:16,960 --> 00:37:19,371 And this is reliable that we're not manually 851 00:37:19,371 --> 00:37:20,620 trying to create the zip file. 852 00:37:20,620 --> 00:37:22,560 I know some people have been having 853 00:37:22,560 --> 00:37:24,670 issues with bots randomly exploding. 854 00:37:24,670 --> 00:37:27,159 Or sometimes a submission works or sometimes a submission 855 00:37:27,159 --> 00:37:27,700 doesn't work. 856 00:37:27,700 --> 00:37:29,230 If the whole thing is automated it's 857 00:37:29,230 --> 00:37:31,640 going to work barring some catastrophic failure. 858 00:37:34,760 --> 00:37:36,762 This is also a random cute little tip. 859 00:37:36,762 --> 00:37:38,220 Sorry for this stream of conscious, 860 00:37:38,220 --> 00:37:41,120 but I'm just trying to mind up as much useful information 861 00:37:41,120 --> 00:37:43,320 on to you. 862 00:37:43,320 --> 00:37:45,160 This one I'm actually really surprised, 863 00:37:45,160 --> 00:37:47,170 I couldn't figure this out for like three years. 864 00:37:47,170 --> 00:37:49,080 How to deal with shared debugging. 865 00:37:49,080 --> 00:37:51,350 So for those of you guys working in teams, 866 00:37:51,350 --> 00:37:53,600 you'll have print lines, you'll have indicator strings 867 00:37:53,600 --> 00:37:56,015 that one day you'll be testing something 868 00:37:56,015 --> 00:37:58,340 and you'll merge in someone else's pull. 869 00:37:58,340 --> 00:38:01,267 And then you'll be like who overwrote my indicator strings? 870 00:38:01,267 --> 00:38:03,100 Because now I don't know what I'm debugging. 871 00:38:03,100 --> 00:38:05,480 Have any of you guys had this issue? 872 00:38:05,480 --> 00:38:08,456 So you'll have-- you're debugging nav 873 00:38:08,456 --> 00:38:10,080 and you're printing out the current Nav 874 00:38:10,080 --> 00:38:12,857 state-- your current state machine's navigation position, 875 00:38:12,857 --> 00:38:14,940 and all the sudden the guy working on attack micro 876 00:38:14,940 --> 00:38:17,740 has overwrote your indicator strings with current number 877 00:38:17,740 --> 00:38:20,070 of robots attacking you, or whatever. 878 00:38:20,070 --> 00:38:22,460 And this gets really frustrating really fast. 879 00:38:22,460 --> 00:38:24,622 Because then you end up with merge conflicts, 880 00:38:24,622 --> 00:38:26,830 when people try change each others indicator strings. 881 00:38:26,830 --> 00:38:29,413 The guy working on nav will con out the attack guy's indicator 882 00:38:29,413 --> 00:38:29,940 strings. 883 00:38:29,940 --> 00:38:31,270 And then you'll end up with a merge conflict 884 00:38:31,270 --> 00:38:32,590 and then you guys will screw up the merge conflict. 885 00:38:32,590 --> 00:38:34,580 And stuff will just go to hell. 886 00:38:34,580 --> 00:38:40,120 So what we did was the bots can actually 887 00:38:40,120 --> 00:38:45,630 read from the Java bc.config. 888 00:38:45,630 --> 00:38:48,570 And actually what we built was this custom system, this custom 889 00:38:48,570 --> 00:38:52,290 debug system, that allowed us to specify 890 00:38:52,290 --> 00:38:55,720 who was running the bot based on the current eclipse launch 891 00:38:55,720 --> 00:38:57,890 profile, and only print out indicator strings 892 00:38:57,890 --> 00:39:00,820 from the person watching it. 893 00:39:00,820 --> 00:39:04,320 So you'll see on the left we made four custom launch 894 00:39:04,320 --> 00:39:04,820 profiles. 895 00:39:04,820 --> 00:39:07,380 One for me, one for Justin, one for Haitao, one for YP. 896 00:39:07,380 --> 00:39:09,610 And when you ran your custom launch profile, 897 00:39:09,610 --> 00:39:12,846 it would only display debug information from your bot. 898 00:39:12,846 --> 00:39:14,470 So you'd only see your own print lines. 899 00:39:14,470 --> 00:39:15,810 You'd only see your own indicator strings. 900 00:39:15,810 --> 00:39:17,515 And then we never had a merge conflict. 901 00:39:17,515 --> 00:39:18,890 Well, we did have merge conflicts 902 00:39:18,890 --> 00:39:22,010 but not related to indicator string setting. 903 00:39:22,010 --> 00:39:24,340 So this is just a small little trick 904 00:39:24,340 --> 00:39:26,610 that just saves a lot of time. 905 00:39:26,610 --> 00:39:32,622 Because stuff will add up across your total bot's 906 00:39:32,622 --> 00:39:33,330 development time. 907 00:39:33,330 --> 00:39:37,780 You don't want to spend time arguing about people-- 908 00:39:37,780 --> 00:39:39,324 I know some teams will say, OK, you 909 00:39:39,324 --> 00:39:40,740 can only use indicator string one. 910 00:39:40,740 --> 00:39:42,920 I'll only use indicator string two. 911 00:39:42,920 --> 00:39:45,610 But someone will need two lines of information. 912 00:39:45,610 --> 00:39:49,430 Then you guys will fight over it and it's really stupid. 913 00:39:49,430 --> 00:39:52,780 Other general, useful advice. 914 00:39:52,780 --> 00:39:56,510 All the past teams have actually put a lot of information on. 915 00:39:56,510 --> 00:39:59,430 So there's a lot of stuff that I don't need to reiterate. 916 00:39:59,430 --> 00:40:02,000 So how many of you guys actually read the blog post 917 00:40:02,000 --> 00:40:04,420 that I put on hacker news? 918 00:40:04,420 --> 00:40:07,630 Yeah, nice. 919 00:40:07,630 --> 00:40:12,110 From 2012 to 2009, actually, all the old strategy reports, 920 00:40:12,110 --> 00:40:14,550 all the winning teams, are actually online. 921 00:40:14,550 --> 00:40:16,920 So I have the bug post from our team, 922 00:40:16,920 --> 00:40:18,360 but there's also a strategy report 923 00:40:18,360 --> 00:40:21,490 that corresponds to that, to our bot, that's in our repository. 924 00:40:21,490 --> 00:40:23,850 The 2011 post-mortem is actually an excellent 925 00:40:23,850 --> 00:40:27,380 write up by Steve Arcangeli, who wrote the massive scrim 926 00:40:27,380 --> 00:40:29,870 tester about various other tricks 927 00:40:29,870 --> 00:40:32,640 you can do to save byte codes. 928 00:40:32,640 --> 00:40:36,500 2010 is by Spencer Skates on finding the shortest 929 00:40:36,500 --> 00:40:37,190 path to victory. 930 00:40:37,190 --> 00:40:40,830 It's kind of their whole like Bellman Ford pun team thing 931 00:40:40,830 --> 00:40:42,210 that they had going on. 932 00:40:42,210 --> 00:40:45,010 They detail a lot of high level mechanics 933 00:40:45,010 --> 00:40:48,390 that help you when you're in combat. 934 00:40:48,390 --> 00:40:51,230 They also-- Spencer Skates and Steve Bartell also won 935 00:40:51,230 --> 00:40:55,980 in '09 and they were called G2G Ice Skating Lessons, 936 00:40:55,980 --> 00:40:59,560 which was-- it was like an inside joke that none of us 937 00:40:59,560 --> 00:41:00,200 got. 938 00:41:00,200 --> 00:41:04,880 But they wrote about their 2009 experiences as well. 939 00:41:04,880 --> 00:41:08,650 They actually set the trend of the winning team usually ending 940 00:41:08,650 --> 00:41:11,300 up writing the best strategy reports, which 941 00:41:11,300 --> 00:41:12,940 is a trend you guys should continue. 942 00:41:15,670 --> 00:41:17,280 Some other random tips. 943 00:41:17,280 --> 00:41:18,420 Messaging. 944 00:41:18,420 --> 00:41:20,680 I'm really excited about the new changes this year, 945 00:41:20,680 --> 00:41:22,630 because messaging is global. 946 00:41:22,630 --> 00:41:25,720 So what this allows you to do is you no longer 947 00:41:25,720 --> 00:41:27,800 have to have robots really close together. 948 00:41:27,800 --> 00:41:30,005 So if you guys are familiar with the 2011 game, what 949 00:41:30,005 --> 00:41:32,630 you would have to do is, because you could only broadcast eight 950 00:41:32,630 --> 00:41:38,580 squares away, you had to set up a relay network of robots that 951 00:41:38,580 --> 00:41:40,302 would propagate information outwards. 952 00:41:40,302 --> 00:41:42,510 And it was a whole amount of overhead just associated 953 00:41:42,510 --> 00:41:44,210 with writing the relay network that 954 00:41:44,210 --> 00:41:47,630 could get a message from robot a to your entire army. 955 00:41:47,630 --> 00:41:49,470 That was at least a day's worth of work. 956 00:41:49,470 --> 00:41:51,000 Setting up the re-broadcasting. 957 00:41:51,000 --> 00:41:52,340 Setting up the hashing. 958 00:41:52,340 --> 00:41:54,090 Setting up all that code. 959 00:41:54,090 --> 00:41:58,270 This year, because everything is a global message board, 960 00:41:58,270 --> 00:42:01,490 it makes it easier to broadcast very important information very 961 00:42:01,490 --> 00:42:02,710 fast to all your robots. 962 00:42:02,710 --> 00:42:04,750 But what this also does is battle code 963 00:42:04,750 --> 00:42:07,750 has a huge history of message based attacks. 964 00:42:07,750 --> 00:42:09,380 So it also makes the message based 965 00:42:09,380 --> 00:42:12,940 attacks more interesting because now the enemy very easily can 966 00:42:12,940 --> 00:42:17,370 see everything you're writing to the board. 967 00:42:17,370 --> 00:42:19,220 So some of the more famous message attacks 968 00:42:19,220 --> 00:42:25,220 have been one year-- you guys are familiar that the robot VM 969 00:42:25,220 --> 00:42:26,835 limit is eight megs, right? 970 00:42:26,835 --> 00:42:28,460 So if you exceed eight megs, your robot 971 00:42:28,460 --> 00:42:29,910 actually automatically uploads. 972 00:42:29,910 --> 00:42:32,410 So one year, a team went around just broadcasting eight megs 973 00:42:32,410 --> 00:42:33,360 arrays. 974 00:42:33,360 --> 00:42:36,250 So the enemy team would either get it, try to process, 975 00:42:36,250 --> 00:42:37,605 and completely freeze. 976 00:42:37,605 --> 00:42:38,980 They'd get it, try to process it, 977 00:42:38,980 --> 00:42:40,680 and explode immediately, because they 978 00:42:40,680 --> 00:42:42,820 loaded into memory or something stupid like that. 979 00:42:42,820 --> 00:42:46,390 Or they would just stop moving because they constantly 980 00:42:46,390 --> 00:42:49,300 exceed their byte code limit. 981 00:42:49,300 --> 00:42:54,060 Then, I think in like '07, teams were trying to exploit 982 00:42:54,060 --> 00:42:56,870 the fixed cost of array.hashcode. 983 00:42:56,870 --> 00:43:00,340 So array.hashcode used to be a single byte code. 984 00:43:00,340 --> 00:43:05,130 We used to-- there is a package in your distributable battle 985 00:43:05,130 --> 00:43:07,630 code installer called method costs, 986 00:43:07,630 --> 00:43:12,480 and that explains the cost of every single method that we 987 00:43:12,480 --> 00:43:14,040 don't explicitly list a cost for-- 988 00:43:14,040 --> 00:43:15,900 Or if a method is not listed in there 989 00:43:15,900 --> 00:43:19,800 it's free unless it's in one of the restricted packages. 990 00:43:19,800 --> 00:43:22,364 But what happened was array.hashcodes was free. 991 00:43:22,364 --> 00:43:24,280 So teams thought they were being really clever 992 00:43:24,280 --> 00:43:28,200 by using the o of one hashcode cost 993 00:43:28,200 --> 00:43:30,640 to basically do an o of n algorithm 994 00:43:30,640 --> 00:43:33,860 to get entire hashcode and secure their messages that way. 995 00:43:33,860 --> 00:43:36,290 But then one team just took the fact 996 00:43:36,290 --> 00:43:38,590 that every team was using array.hashcode 997 00:43:38,590 --> 00:43:41,030 and he could mutate the array without changing 998 00:43:41,030 --> 00:43:43,960 the value of the final hash. 999 00:43:43,960 --> 00:43:46,350 And then he would send that back to the robot 1000 00:43:46,350 --> 00:43:48,551 and all their robots would just completely mess up. 1001 00:43:48,551 --> 00:43:50,300 Because they thought the hash was correct, 1002 00:43:50,300 --> 00:43:52,420 but the data was completely garbled, 1003 00:43:52,420 --> 00:43:56,120 which which was a really interesting messaging attack. 1004 00:43:56,120 --> 00:44:01,690 So you need to make sure when your messaging to check 1005 00:44:01,690 --> 00:44:06,010 the integrity of the data and make sure that the data-- check 1006 00:44:06,010 --> 00:44:07,389 the validity of the data and also 1007 00:44:07,389 --> 00:44:08,930 make sure that the data actually gets 1008 00:44:08,930 --> 00:44:11,060 to where it's supposed to go. 1009 00:44:11,060 --> 00:44:14,220 So, this year the most obvious attack, of course, 1010 00:44:14,220 --> 00:44:16,090 is to wipe the entire board. 1011 00:44:16,090 --> 00:44:19,660 And you can do this every round if you have some obscene number 1012 00:44:19,660 --> 00:44:21,830 of generators, like 30 or so. 1013 00:44:21,830 --> 00:44:23,990 But the thing is, you can pool energy this year. 1014 00:44:23,990 --> 00:44:26,050 So actually a team that, say, just wants 1015 00:44:26,050 --> 00:44:28,640 to wipe the message board during critical situations, 1016 00:44:28,640 --> 00:44:32,250 like during an engagement, can actually pool enough energy 1017 00:44:32,250 --> 00:44:35,170 so that they can wipe the entire message board in one go. 1018 00:44:35,170 --> 00:44:37,150 So you can't actually assume that what 1019 00:44:37,150 --> 00:44:38,850 you wrote into the message board one round will actually 1020 00:44:38,850 --> 00:44:40,930 be their the next round, or even between rounds. 1021 00:44:40,930 --> 00:44:43,650 Because a robot-- The enemy robot who executed between you 1022 00:44:43,650 --> 00:44:46,330 could have wiped it. 1023 00:44:46,330 --> 00:44:50,730 So make sure that whatever messaging scheme you use, 1024 00:44:50,730 --> 00:44:52,910 there's a way to check the validity either 1025 00:44:52,910 --> 00:44:56,930 by hashing and storing maybe the top four bytes as your hash. 1026 00:44:56,930 --> 00:44:59,440 Or by duplicating the information in multiple places 1027 00:44:59,440 --> 00:45:02,390 and checking that all the information matches 1028 00:45:02,390 --> 00:45:04,280 with each other. 1029 00:45:04,280 --> 00:45:08,690 But as long as you can reliably get important information over. 1030 00:45:08,690 --> 00:45:11,960 Like if you had a retreat signal, or an all out attack 1031 00:45:11,960 --> 00:45:13,830 signal, just make sure it's secured 1032 00:45:13,830 --> 00:45:16,700 and it's safely propagated to all your robots. 1033 00:45:19,550 --> 00:45:21,980 Here's a random piece of advice. 1034 00:45:21,980 --> 00:45:24,060 Keep your frameworks lean, especially 1035 00:45:24,060 --> 00:45:25,640 with the byte code limit. 1036 00:45:25,640 --> 00:45:29,860 You don't want to create this beautiful hierarchy 1037 00:45:29,860 --> 00:45:32,750 of abstract interfaces that just has 1038 00:45:32,750 --> 00:45:36,020 a ton of intermediate layers before you actually 1039 00:45:36,020 --> 00:45:37,740 get to the nitty gritty code. 1040 00:45:37,740 --> 00:45:40,520 Because for every additional layer of abstraction, 1041 00:45:40,520 --> 00:45:42,160 you're increasing the byte code cost. 1042 00:45:42,160 --> 00:45:45,110 So actually one of the cool things that the byte code 1043 00:45:45,110 --> 00:45:49,490 limitation actually enforces is it enforces really lean code, 1044 00:45:49,490 --> 00:45:52,140 which is not something you typically see in Java. 1045 00:45:52,140 --> 00:45:54,880 So if you'll actually look at our class structure, 1046 00:45:54,880 --> 00:45:58,460 this is from our 2012 bot, we have a very, very flat class 1047 00:45:58,460 --> 00:45:59,020 hierarchy. 1048 00:45:59,020 --> 00:46:01,686 One, because we just didn't want to deal with extra subpackages. 1049 00:46:03,590 --> 00:46:05,610 And two, because there's really not 1050 00:46:05,610 --> 00:46:08,950 too much to be gained from really elegant architecture 1051 00:46:08,950 --> 00:46:10,690 other than just wasting time. 1052 00:46:10,690 --> 00:46:13,330 Because the behavior code is ultimately what matters. 1053 00:46:13,330 --> 00:46:16,230 So we wrote extremely lean frameworks. 1054 00:46:16,230 --> 00:46:18,550 So this is actually our main run loop. 1055 00:46:18,550 --> 00:46:22,880 You'll see here all we do is we reset our internal timers. 1056 00:46:22,880 --> 00:46:25,500 We update a few key round variables, 1057 00:46:25,500 --> 00:46:27,950 like the current time, and my current energy, 1058 00:46:27,950 --> 00:46:32,460 and the current position of all the bases. 1059 00:46:32,460 --> 00:46:34,660 And then we run our message system. 1060 00:46:34,660 --> 00:46:40,030 We actually run the main run call, which would basically 1061 00:46:40,030 --> 00:46:42,210 be a giant state machine, probably like 1062 00:46:42,210 --> 00:46:44,124 500, 600 to 1,000 lines long of just 1063 00:46:44,124 --> 00:46:46,540 completely messy code that determines what the robot wants 1064 00:46:46,540 --> 00:46:48,110 to do and does it. 1065 00:46:48,110 --> 00:46:51,447 And then we actually abstracted movement out. 1066 00:46:51,447 --> 00:46:53,530 This was probably the biggest piece of abstraction 1067 00:46:53,530 --> 00:46:55,220 that we did, was we moved a movement out 1068 00:46:55,220 --> 00:46:59,330 to a separate position where we knew that each robot was 1069 00:46:59,330 --> 00:47:01,450 reliably moving every single round, 1070 00:47:01,450 --> 00:47:04,790 because it's very key that you always move because that 1071 00:47:04,790 --> 00:47:08,050 is an impact on your total damage per second. 1072 00:47:08,050 --> 00:47:10,050 And then we did some generic things. 1073 00:47:10,050 --> 00:47:12,190 And we also have this cute little thing down here 1074 00:47:12,190 --> 00:47:15,150 at the bottom which is if we had some spare byte codes we would 1075 00:47:15,150 --> 00:47:17,620 use the extra byte codes for computation. 1076 00:47:17,620 --> 00:47:20,080 So navigation last year was-- because there 1077 00:47:20,080 --> 00:47:21,512 were walls, the algorithms you had 1078 00:47:21,512 --> 00:47:23,470 to use last year were actually quite different. 1079 00:47:26,580 --> 00:47:29,140 Most teams would write something called bugnav, 1080 00:47:29,140 --> 00:47:33,370 which-- you guys from the navigation lecture, 1081 00:47:33,370 --> 00:47:36,062 I suppose you discussed a little bit, where you see an obstacle, 1082 00:47:36,062 --> 00:47:38,520 you hit the obstacle, you try to trace around the obstacle, 1083 00:47:38,520 --> 00:47:41,340 and then once you're free of the obstacle you keep moving. 1084 00:47:41,340 --> 00:47:43,757 But the more advanced teams would actually 1085 00:47:43,757 --> 00:47:45,590 write a more complex version of bugnav which 1086 00:47:45,590 --> 00:47:48,570 is called tangentbug, which is-- you basically can project 1087 00:47:48,570 --> 00:47:51,510 a virtual bug and if you see you've rounded a corner, 1088 00:47:51,510 --> 00:47:53,750 instead of going forward, hitting the wall, 1089 00:47:53,750 --> 00:47:56,310 and going around it, you can just cut the corner. 1090 00:47:56,310 --> 00:47:58,440 And we actually used our extra byte codes 1091 00:47:58,440 --> 00:48:01,750 to pre-compute steps of tangentbug in order 1092 00:48:01,750 --> 00:48:05,970 to make our navigation maybe five or six squares better. 1093 00:48:05,970 --> 00:48:09,770 But that better means you get to the enemy two rounds faster 1094 00:48:09,770 --> 00:48:11,250 because you cut a corner. 1095 00:48:11,250 --> 00:48:15,320 And then two rounds faster means you have extra DPS on the enemy 1096 00:48:15,320 --> 00:48:19,460 and so you win that initial engagement. 1097 00:48:19,460 --> 00:48:23,360 This year because there are no permanent walls, 1098 00:48:23,360 --> 00:48:25,590 bugnav and tangentbug may not actually 1099 00:48:25,590 --> 00:48:28,060 be some of the best algorithms. 1100 00:48:28,060 --> 00:48:30,450 Haitao and I have kind of a little bet running 1101 00:48:30,450 --> 00:48:33,184 on what the best nav will be. 1102 00:48:33,184 --> 00:48:34,600 We're thinking it's probably going 1103 00:48:34,600 --> 00:48:37,830 to be some sort of very discretized floodfill algorithm 1104 00:48:37,830 --> 00:48:41,280 or Astar algorithm that doesn't try to compute every square 1105 00:48:41,280 --> 00:48:44,130 but actually breaks everything up into discrete segments. 1106 00:48:44,130 --> 00:48:46,310 So you want to be able to rush to the enemy base 1107 00:48:46,310 --> 00:48:48,430 if they're just a straight up nuke bot. 1108 00:48:48,430 --> 00:48:51,750 We guarantee you a round-- we guarantee you 1109 00:48:51,750 --> 00:48:54,144 a minimum of 200 rounds if you follow the optimal path. 1110 00:48:54,144 --> 00:48:56,060 But you have to know what that optimal path is 1111 00:48:56,060 --> 00:48:58,510 or you won't get there in time. 1112 00:48:58,510 --> 00:49:00,530 Maximum of 200 rounds. 1113 00:49:00,530 --> 00:49:05,440 So our bets are actually on the most advanced teams 1114 00:49:05,440 --> 00:49:07,980 writing kind of an Astar algorithm 1115 00:49:07,980 --> 00:49:10,170 or a floodfill algorithm that takes the map, 1116 00:49:10,170 --> 00:49:12,490 divides it into discrete chunks so it doesn't consider 1117 00:49:12,490 --> 00:49:15,230 every individual square, and then it kind of picks 1118 00:49:15,230 --> 00:49:18,490 sort of roughly the best path to take. 1119 00:49:18,490 --> 00:49:21,160 So you can avoid areas with more or less mines 1120 00:49:21,160 --> 00:49:22,625 than the other areas. 1121 00:49:22,625 --> 00:49:25,250 And then this will still get you to the nuke bot in enough time 1122 00:49:25,250 --> 00:49:27,300 without having to blow the entire cost 1123 00:49:27,300 --> 00:49:30,940 of the complete Astar algorithm. 1124 00:49:30,940 --> 00:49:34,140 So Astar, in maybe like an eight by eight or ten by ten 1125 00:49:34,140 --> 00:49:36,010 is tenable, but it's not tenable in twenty 1126 00:49:36,010 --> 00:49:39,740 by twenty or a hundred by a hundred situations. 1127 00:49:42,830 --> 00:49:44,420 This is kind of a big one. 1128 00:49:44,420 --> 00:49:45,990 Don't be afraid to write messy code. 1129 00:49:48,866 --> 00:49:52,020 I think it speaks for itself, but in case 1130 00:49:52,020 --> 00:49:54,880 you guys are like spending a lot of time trying 1131 00:49:54,880 --> 00:49:56,440 to make beautiful code, the thing 1132 00:49:56,440 --> 00:49:59,350 is what you ship is ultimately-- what 1133 00:49:59,350 --> 00:50:01,980 you ship that changes your bot's performance is ultimately 1134 00:50:01,980 --> 00:50:02,847 what matters. 1135 00:50:02,847 --> 00:50:04,430 And a lot of beginners have this issue 1136 00:50:04,430 --> 00:50:06,430 where they're afraid to just hack something 1137 00:50:06,430 --> 00:50:09,510 together, or hack a one off bot to test. 1138 00:50:09,510 --> 00:50:12,590 But it's so key that you kind of overcome this fear 1139 00:50:12,590 --> 00:50:15,160 to write messy code, write stuff that works, 1140 00:50:15,160 --> 00:50:18,780 just get something hacked out that's working. 1141 00:50:18,780 --> 00:50:20,710 And then use that to gain yourself 1142 00:50:20,710 --> 00:50:22,340 an advantage in what matters, which 1143 00:50:22,340 --> 00:50:25,280 is the actual scrimmage, the tournament matches, et cetera. 1144 00:50:25,280 --> 00:50:28,070 So we actually have code that's terrible. 1145 00:50:28,070 --> 00:50:30,880 Our navigation code actually is completely-- 1146 00:50:30,880 --> 00:50:33,950 is not understandable by the person who wrote it anymore 1147 00:50:33,950 --> 00:50:36,270 because it's so messy. 1148 00:50:36,270 --> 00:50:38,400 Like you can imagine, bugnav, for anyone 1149 00:50:38,400 --> 00:50:41,194 who's tried to implement bugnav it sounds really simple, 1150 00:50:41,194 --> 00:50:43,360 but there are actually like 100s or so of edge cases 1151 00:50:43,360 --> 00:50:45,130 that you have to account for. 1152 00:50:45,130 --> 00:50:48,150 So if you end up bugging around another robot or you end up 1153 00:50:48,150 --> 00:50:49,853 in some sort of infinite loop bug, 1154 00:50:49,853 --> 00:50:52,910 there's a lot of extra edge conditions that you have 1155 00:50:52,910 --> 00:50:55,950 to account for that none of the previous lecturers have 1156 00:50:55,950 --> 00:51:02,100 actually talked about from '09 or 2010 or 2011. 1157 00:51:02,100 --> 00:51:04,040 They'll just say oh yeah, it's bugnav, 1158 00:51:04,040 --> 00:51:05,290 just go around the thing. 1159 00:51:05,290 --> 00:51:07,550 But what happens if you have two units bugging 1160 00:51:07,550 --> 00:51:10,420 around the same wall and then they hit each other, 1161 00:51:10,420 --> 00:51:12,000 then one unit has to go around. 1162 00:51:12,000 --> 00:51:14,606 But if one unit goes around and the unit on top moves, 1163 00:51:14,606 --> 00:51:15,980 all of the sudden you have a unit 1164 00:51:15,980 --> 00:51:17,560 who's no longer next to a wall but though he 1165 00:51:17,560 --> 00:51:18,643 was bugging around a wall. 1166 00:51:18,643 --> 00:51:20,685 But he doesn't see any walls next to him anymore. 1167 00:51:20,685 --> 00:51:22,226 And then you're states get messed up. 1168 00:51:22,226 --> 00:51:23,750 And everything just goes to hell. 1169 00:51:23,750 --> 00:51:26,090 So don't be afraid to just write edge case 1170 00:51:26,090 --> 00:51:28,240 code that deals with that, gets your bot up 1171 00:51:28,240 --> 00:51:31,340 and running so you can test the frameworks, and the strategies, 1172 00:51:31,340 --> 00:51:34,350 and everything that matters. 1173 00:51:34,350 --> 00:51:38,630 There's also-- last minute hacks actually win games. 1174 00:51:38,630 --> 00:51:41,070 So I don't know if you guys are familiar with our 2011-- 1175 00:51:41,070 --> 00:51:43,390 or 2012 championship. 1176 00:51:43,390 --> 00:51:45,870 But what we did was on the very last day 1177 00:51:45,870 --> 00:51:47,510 we were scrimmaging on the server 1178 00:51:47,510 --> 00:51:53,910 and we found out that the second place scrim team, team 16, 1179 00:51:53,910 --> 00:51:56,157 had modified his attack code, that it was actually 1180 00:51:56,157 --> 00:51:57,240 slightly better than ours. 1181 00:51:57,240 --> 00:51:59,770 And because having better attack code 1182 00:51:59,770 --> 00:52:04,430 means you win the engagement, it means he beat our bot actually 1183 00:52:04,430 --> 00:52:06,740 three times out of four. 1184 00:52:06,740 --> 00:52:10,030 So we got, actually, really scared about this. 1185 00:52:10,030 --> 00:52:11,730 And don't forget we scrimmed this 1186 00:52:11,730 --> 00:52:13,550 the day of the final submissions. 1187 00:52:13,550 --> 00:52:16,350 So an hour before the deadline, me, Haitao, and YP 1188 00:52:16,350 --> 00:52:18,790 are just thinking about well what should we actually do? 1189 00:52:18,790 --> 00:52:23,010 So our ultimate hack was we actually figure out 1190 00:52:23,010 --> 00:52:25,870 what the team is by the characteristic of their message 1191 00:52:25,870 --> 00:52:26,865 broadcasting. 1192 00:52:26,865 --> 00:52:28,740 So you're not actually given the team number. 1193 00:52:28,740 --> 00:52:30,390 But if you look at what kind of messages they're sending, 1194 00:52:30,390 --> 00:52:32,060 you can kind of guess, right? 1195 00:52:32,060 --> 00:52:37,150 And throughout the whole battle code 2012 1196 00:52:37,150 --> 00:52:40,060 we had been kind of on the side just curious, 1197 00:52:40,060 --> 00:52:42,680 looking at the structure of other teams messages. 1198 00:52:42,680 --> 00:52:46,200 And so an hour before the deadline submission 1199 00:52:46,200 --> 00:52:47,910 we wrote something that determined 1200 00:52:47,910 --> 00:52:50,750 whether the team we were playing against was team 16. 1201 00:52:50,750 --> 00:52:52,990 And we would change our strategy. 1202 00:52:52,990 --> 00:52:54,310 And this was an hour before. 1203 00:52:54,310 --> 00:52:55,891 And it was completely untested code. 1204 00:52:55,891 --> 00:52:57,640 But we had been thinking about it, kind of 1205 00:52:57,640 --> 00:53:00,130 in the back of our mind, and we just threw this together. 1206 00:53:00,130 --> 00:53:01,330 We uploaded it. 1207 00:53:01,330 --> 00:53:04,570 And if you were at the finals it was a pretty tense match 1208 00:53:04,570 --> 00:53:07,280 where we actually had a bug in that code that 1209 00:53:07,280 --> 00:53:10,380 triggered once and would not trigger a second time. 1210 00:53:10,380 --> 00:53:14,840 But the one time it did trigger was the very last match, 1211 00:53:14,840 --> 00:53:17,840 and so we ultimately won the final tournament. 1212 00:53:17,840 --> 00:53:22,880 But this is like a piece of code, incredibly critical. 1213 00:53:22,880 --> 00:53:25,459 It's like three or four lines, but it 1214 00:53:25,459 --> 00:53:27,500 was the difference between first or second place. 1215 00:53:27,500 --> 00:53:31,240 So once again, spending time where it matters is really key. 1216 00:53:31,240 --> 00:53:33,970 You can probably do these sort of hacks this year. 1217 00:53:33,970 --> 00:53:36,460 Determining what the team is based on the message structure 1218 00:53:36,460 --> 00:53:37,550 is a little bit harder. 1219 00:53:37,550 --> 00:53:40,305 Because last year people would send discrete message objects. 1220 00:53:40,305 --> 00:53:41,930 And so you could count the total number 1221 00:53:41,930 --> 00:53:44,159 of integers, the total number of map locations. 1222 00:53:44,159 --> 00:53:45,700 Whether there's a secret key and then 1223 00:53:45,700 --> 00:53:48,010 you could correlate the secret keys. 1224 00:53:48,010 --> 00:53:51,099 This year you'll have to see how they channel hop 1225 00:53:51,099 --> 00:53:52,890 or what they store on the various channels, 1226 00:53:52,890 --> 00:53:57,260 or the channel distribution of the different messages. 1227 00:53:57,260 --> 00:53:58,720 But it's still possible. 1228 00:53:58,720 --> 00:54:01,289 So last minute hacks do win games. 1229 00:54:01,289 --> 00:54:02,580 This is also another small one. 1230 00:54:02,580 --> 00:54:05,073 You guys should all-- if you're not already using IRC, 1231 00:54:05,073 --> 00:54:07,830 you should use IRC, because all the devs are on IRC, 1232 00:54:07,830 --> 00:54:11,120 especially us who are remote. 1233 00:54:11,120 --> 00:54:14,830 I was the only person working on engine who was actually 1234 00:54:14,830 --> 00:54:17,700 willing to fly out six hours to give this talk. 1235 00:54:17,700 --> 00:54:18,894 So everyone else is on IRC. 1236 00:54:18,894 --> 00:54:20,810 If you have any questions you should go on IRC 1237 00:54:20,810 --> 00:54:23,480 and you should actually ask your question. 1238 00:54:23,480 --> 00:54:26,230 So, for those of you who don't know, there's a web client. 1239 00:54:26,230 --> 00:54:28,160 Just use the freenode web client, 1240 00:54:28,160 --> 00:54:30,140 connect to channel battle code, ask 1241 00:54:30,140 --> 00:54:31,680 whatever questions you have. 1242 00:54:31,680 --> 00:54:35,760 We'll answer them pretty fast. 1243 00:54:35,760 --> 00:54:37,760 If you guys are feeling a little more advanced, 1244 00:54:37,760 --> 00:54:39,230 you should use IRC better. 1245 00:54:39,230 --> 00:54:41,000 If you actually parsesys in the channel 1246 00:54:41,000 --> 00:54:44,425 there's a lot of banter that goes on regarding game balance. 1247 00:54:44,425 --> 00:54:46,770 Or teams will discuss strategies or whatever. 1248 00:54:46,770 --> 00:54:49,090 So if you actually get a good IRC client 1249 00:54:49,090 --> 00:54:52,410 and stay in the channel, you'll actually learn a lot. 1250 00:54:52,410 --> 00:54:56,520 Because sometimes some of the old battle code champions 1251 00:54:56,520 --> 00:54:58,984 will just come in, just talk a little bit about strategy. 1252 00:54:58,984 --> 00:55:00,650 Or people will just discuss what they've 1253 00:55:00,650 --> 00:55:02,066 been doing on the bots, et cetera. 1254 00:55:02,066 --> 00:55:05,120 And so just use a good IRC chat client. 1255 00:55:05,120 --> 00:55:06,520 If you were to use pigeon, pigeon 1256 00:55:06,520 --> 00:55:07,603 has a built-in IRC client. 1257 00:55:07,603 --> 00:55:10,110 There's no reason to not connect to it. 1258 00:55:10,110 --> 00:55:12,660 Talk to the devs, ask questions. 1259 00:55:12,660 --> 00:55:15,220 There's just been a lot of very simple questions, 1260 00:55:15,220 --> 00:55:17,380 but we're more than happy to answer. 1261 00:55:17,380 --> 00:55:19,870 So questions about round number, or if you 1262 00:55:19,870 --> 00:55:21,340 have an issue with your bot, it's 1263 00:55:21,340 --> 00:55:23,089 much faster than the forums, because we'll 1264 00:55:23,089 --> 00:55:25,640 answer the IRC probably in minutes 1265 00:55:25,640 --> 00:55:29,110 rather than hours on the forum. 1266 00:55:29,110 --> 00:55:31,530 And, most of all, you guys should just have fun. 1267 00:55:31,530 --> 00:55:35,370 Battle code, at least for us, was a very fun experience. 1268 00:55:35,370 --> 00:55:37,180 We worked hard on it. 1269 00:55:37,180 --> 00:55:40,100 But we also-- we goofed off a lot. 1270 00:55:40,100 --> 00:55:44,506 We probably spent more than 40 hours playing Civ 5. 1271 00:55:44,506 --> 00:55:45,880 And before the sprint tournament, 1272 00:55:45,880 --> 00:55:50,320 or before the Qualls tournament, this is usually a bad idea. 1273 00:55:50,320 --> 00:55:53,450 But it's about-- this is IP, it's about having fun. 1274 00:55:53,450 --> 00:55:56,220 So work hard, but also have fun. 1275 00:55:56,220 --> 00:55:58,370 And also I have a few requests. 1276 00:55:58,370 --> 00:56:03,420 So there may potentially be the 2013 winner in this group. 1277 00:56:03,420 --> 00:56:07,190 So, if it is one of you guys, just a few requests. 1278 00:56:07,190 --> 00:56:09,107 You guys should write a good strategy report, 1279 00:56:09,107 --> 00:56:10,940 because battle code is not done in a vacuum. 1280 00:56:10,940 --> 00:56:12,440 We learned from the teams before us. 1281 00:56:12,440 --> 00:56:15,280 The teams before us learned from the teams before them. 1282 00:56:15,280 --> 00:56:17,949 This information really needs to be more out and open, 1283 00:56:17,949 --> 00:56:19,740 which is why I'm giving you kind of a brain 1284 00:56:19,740 --> 00:56:22,386 dump of a lot of the very small tricks 1285 00:56:22,386 --> 00:56:24,760 and tips that we did in order to gain a competitive edge. 1286 00:56:24,760 --> 00:56:27,630 So write a good strategy report, help your fellow competitors. 1287 00:56:27,630 --> 00:56:30,860 This is a friendly competition, it's not cutthroat. 1288 00:56:30,860 --> 00:56:33,350 You guys can make fun of all the other lesser competitions, 1289 00:56:33,350 --> 00:56:36,120 but within battle code keep it a good family. 1290 00:56:36,120 --> 00:56:39,730 And then join the devs if you guys win, 1291 00:56:39,730 --> 00:56:41,440 because we need good desks. 1292 00:56:41,440 --> 00:56:43,154 So thanks. 1293 00:56:43,154 --> 00:56:52,420 [APPLAUSE] 1294 00:56:52,420 --> 00:56:56,440 CORY: So any general questions or whatever? 1295 00:56:56,440 --> 00:56:59,360 Once again, yeah, it's our fault if you guys really 1296 00:56:59,360 --> 00:57:04,580 hate nuke you should say it now. 1297 00:57:04,580 --> 00:57:06,950 Yes? 1298 00:57:06,950 --> 00:57:08,581 [INAUDIBLE] 1299 00:57:08,581 --> 00:57:10,205 AUDIENCE: It changes from year to year. 1300 00:57:10,205 --> 00:57:14,250 So how did you choose your team? 1301 00:57:14,250 --> 00:57:16,472 CORY: The 2012 team was all Star League people. 1302 00:57:16,472 --> 00:57:18,180 So there's also another Star League team. 1303 00:57:18,180 --> 00:57:21,850 I have some high hopes for the Star League guys. 1304 00:57:21,850 --> 00:57:24,840 First year I did it with people from my high school. 1305 00:57:24,840 --> 00:57:27,260 Second year I did it, I did it with Star League people. 1306 00:57:27,260 --> 00:57:29,870 The third year was also all Star League people as well. 1307 00:57:29,870 --> 00:57:32,203 You guys should go to Star League if you like Starcraft. 1308 00:57:32,203 --> 00:57:32,930 That's a pitch. 1309 00:57:32,930 --> 00:57:37,270 Every Friday at 7:00 o'clock for 253. 1310 00:57:37,270 --> 00:57:38,750 Go play Starcraft 1311 00:57:38,750 --> 00:57:41,960 It'll make your meta game analysis better. 1312 00:57:44,817 --> 00:57:45,650 Any other questions? 1313 00:57:45,650 --> 00:57:47,370 Balance? 1314 00:57:47,370 --> 00:57:50,320 General comments? 1315 00:57:50,320 --> 00:57:52,187 So I'll be here afterwards if you guys 1316 00:57:52,187 --> 00:57:53,270 want to ask any questions. 1317 00:57:53,270 --> 00:57:54,936 If you want to look through our old bot. 1318 00:57:54,936 --> 00:57:57,400 At some point I will write out a code 1319 00:57:57,400 --> 00:57:59,770 walk through of our 2012 bot. 1320 00:57:59,770 --> 00:58:02,280 But until then just ask, or we'll 1321 00:58:02,280 --> 00:58:03,960 be in the IRC channel or whatever. 1322 00:58:03,960 --> 00:58:06,566 So hopefully this was useful to you guys. 1323 00:58:06,566 --> 00:58:08,420 So thanks. 1324 00:58:08,420 --> 00:58:09,970 [APPLAUSE]