In the first episode of the season, Kevin and Andrew bring you on the journey of learning about Battlesnake by building an (arguably) capable autonomous snake based on Node.js.
Speaker 0: Hello, everyone, and welcome to Ready, Set, Battlesnake. I am so thrilled for this season to be happening, bringing together a few of my interests all at the same time, including hanging out with my good friend, Andrew. Hello, Andrew.
Speaker 1: Hey, Kevin. How are you?
Speaker 0: I am all the better for seeing you. Would you like to tell us what the hell we're gonna be doing for the next 4 episodes?
Speaker 1: Yeah. That's a great question. So we are gonna be exploring the wonderful world of Battlesnake. More on that in just a minute. We're gonna be looking at how Battlesnake works.
We're gonna be looking at how Battlesnake integrates with some other really cool technologies out there. And, hopefully, by the end of this 4 week series, you'll have a Battlesnake or 4 episode series. You'll have a Battlesnake that is ready to go and to jump in and start, yeah, start competing and playing around and learning some new technologies.
Speaker 0: Or you can just watch us fumbling around. That's also totally fine too. Also very No. I think what might be good is let's talk about what Battlesnake is and then talk about, like, our affiliations with Battlesnake. Probably feels like a good thing to throw out there.
But let's start because we've said the phrase Battlesnake one too many times to not jump into what it is. What is Battlesnake, Andrew?
Speaker 1: Alright. So if you have ever heard of the old classic game Snake, like that old Nokia snake game where you, sort of control the snake to go around on a screen and eat little berries and get longer, and you try to avoid yourself and avoid the walls and avoid other snakes if they're on the board. Well, Battlesnake is that same idea, but moved around a little bit into the developer space. So it's a really cool way for developers to explore new technologies, new frameworks in this kind of technology agnostic way. So you actually, create a web server that responds to the Battlesnake API, and you can crawl control a snake using code to battle or compete against other snakes in that kind of same gamified way, but, in kind of way more fun for developers.
Speaker 0: And a few interesting notes here. So firstly, unlike snake on your Nokia, multiple snakes on the board at once, and you're basically trying to outlive everyone else. You die in the same ways, but there are multiple snakes just like this on the screen now. And because what you're doing is implementing an API, it means it's pretty technology agnostic as long as you can host a web server that can have a couple of specific endpoints that accept requests and then responds in a specific way. It almost doesn't matter what technology you use, which is pretty cool.
And so we're going to be building this over a few episodes. Today, we're just gonna be focusing on, like, the vanilla Node. Js starter snake and challenges so we can introduce you to this wonderful world. You're gonna love it. And then we'll play around with, like, running Battlesnake in a director's project with directors automate, which should be really fun.
And then, towards the end, we're going to also integrate dev cycle, which brings me on to a probably good point here, affiliations. Andrew, do you wanna start with, like, your history with this project?
Speaker 1: Yeah. Sure. So so I actually started with Battlesink back in 2020. So I joined fairly early on in in the the official Battlesink company. BattleState had been around for about 5 years before I joined the team, and it started out as a community project here on the West Coast of Canada.
It was a big sort of hackathon event that happened here where a bunch of people have gotten to a room for a couple of days and built battle stakes and competed in sort of live events. I joined the team in 2020 as sort of their first community manager as we were kind of transitioning, as many were in 2020, into that online world. And so we sort of transitioned the whole kind of BattleState concept into an online platform that folks could engage with around the world. In 2023, Battlesnake, was acquired by another Canadian startup called Dev Cycle, where I currently work as their developer advocate. And so I still get to play around with Battlesnake a lot and work with a lot of the great people that were on the Battlesnake team.
And and it's actually like the the pre dev cycle times that, Kevin, you and I met, even though technically, we never met in person until Not
Speaker 0: in person yet. Mhmm. Absolutely. And then, I, Battlesnake as part of going online, run a bunch of livestream series. It was a really good is still, but was really then in its peak, like, peak pandemic.
We're doing everything online, ton of live stream series, including the competitive leagues, shows which discuss different algorithms that can be implemented. And this one show called Coding Badly, which was run with me and my friend, Joe. And this is kind of a spiritual successor to Coding Badly, I think. No offense, Andrew. I think that's probably gonna be the vibe the vibe we go for.
So I love Battlesnake. And what's really cool about and we'll discover throughout today is at the very core, you know, there are some very simple rules. Don't hit into walls, don't hit yourself, Don't hit other snakes. Don't run out of life like it. Get food when you need it.
But once you start to get options, you can really make some choices here. You know, you can say if left and right are both viable options, is there an algorithmically, beneficial way based on certain strategies to go? Do I box myself off, but now we only have so much life? Do I try and find food as quickly as possible at all cost to also starve out other snakes and so on? So all of this is implemented in code, and then when the games actually happen, your hands off.
You know, your your algorithm takes over and makes decisions. So, yeah, I think that's that I I think that's most of Battlesnake. Any other thoughts, Andrew, before we crack on?
Speaker 1: I mean, let's, I mean, let's jump into the let's jump into the docs because I think they're gonna give us a good idea of kind of the some of the things that maybe we missed. And I think, actually, I'm I'm not a 100% sure. I haven't been in the docs in a while. I may still be featured in, like, the what the heck is Battlesnake doc. So I'm very interested to see if we
Speaker 0: can get it. Shortly.
Speaker 1: Am I there? The real question. I'm not oh, wait. No. Hold on.
Quick start? There I am. I'm definitely I'm definitely in the quick start. I know this. Am I still here?
Speaker 0: We'll we'll throw this video into the resources that accompany this video on Directus TV if you wanna go and watch it in full. Awesome. Yeah. So when you click on that,
Speaker 1: what is dev cycle, it brings you over to the dev cycle documentation, and this documentation is fantastic. One of the things that Kevin was talking about, a lot of those sort of specific things that you can and can't do, if you wanna kinda figure out what that's all about, you can really a great place to go is actually checking out the game rules. And so this is where we start to look at things like this collision idea. So, like, self collisions and body collisions and head to head and who wins in these different situations, and then also giving information about some other things that are really important in this kind of gameplay. So you have a starting position in the game.
We'll talk a little bit more about what that looks like kind of as we go through. You have health. That's a dynamic in this game as well. There's food spawns and hazards, and we're not going to get to a lot of that stuff necessarily today. We're gonna see that kind of as we go on.
Yeah. But checking out this kind of game rule section is a great way to, like, get a a solid understanding of the idiosyncrasies, I guess, that exist in Battlesnake over sort of the, the the traditional snake game. The other great thing is this rules repository. So, like, all of these rules are actually in, an awesome GitHub repository called Battlesnake Rules. And so if you would rather not watch a video or if you'd rather just do, like, a different kind of deep dive, you can actually, like, jump into the rules repository, which is public, and you can go through and kinda discover a lot of these things yourself.
It's all built out in Go. So if you're not a Go developer, then maybe not for you, but it's a useful place to kinda check out all of this written in code.
Speaker 0: And, yeah, and that was gonna be my clarifying point. This isn't pros. This isn't written out rules. But this is codified rules that actually run within the Battlesnake engine. So you can get right in there and understand again the intricacies of how it all works, which is really cool.
I remember possibly in a coding badly episode, definitely in a battlesnake stream in the past generating, battlesnakes that that, like, actively hook into this rule logic very directly, something like that. Okay. So how do we get started? I think we're gonna stick with node. Doesn't matter what language you you use in the real, but, you know, given that directives is all JavaScript view node, and that's at least what I know.
That feels like a good place to start.
Speaker 1: Yeah. I'm with you. 100%. So couple places you can go. Obviously, the quick start that is here.
So, basically, anywhere you go in the documentation, you'll find the quick start. This one is set up in Python. So, like, if you watch the video and you've never programmed in Python, it's still kind of valuable, and this will kind of walk you through the game logic. But it also does, in this kind of quick start area, let you choose from different snakes. So I highly recommend if you're just getting started with Battlesnake, click on that quick start, and you'll get the kind of fundamental understanding here.
So when we say you are building a web server server that is kind of serving as your battle snake and it's it's interacting with the battle snake API, this is exactly what's actually happening here in this sort of representation here. So, the game engine is querying your web server where your battlesnake is, and your battlesnake server is returning a response. That response can only be 1 of 4 things, up, down, left, or right. That's right. Right.
That you received from the game engine, and then you just are kinda repeating this process over and over and over again. So game engine is sending something to your server. Your server is sending something back to the game engine over and over and over again. And, I guess one of the the kind of gotchas here is, the web servers only have 500 milliseconds to respond. And so if you are sort of some people run these on Raspberry Pis and some people or some people run them on you still run them on Heroku servers.
And so one of the things that we would tell people is make sure you go and, like, do something on your Heroku server or your
Speaker 0: Just to see how the code stop at the beginning.
Speaker 1: Yeah. Exactly. But, but yeah. And and, Kevin, I don't know if I ever told you. Do you know what are the reasons why this 500 millisecond rule was implemented?
Have you ever heard this story?
Speaker 0: No. Sorry. I just realized. I don't think you can see me. So I I'm doing a No.
Speaker 1: I can. No. No.
Speaker 0: I can
Speaker 1: see that. I'm, like, down here. No. I can't. So so I, so in one of the early kind of days of the battle sync competition, before they had this 500 millisecond, like, response time that was there, somebody realized that it was actually faster to respond with a physical keyboard or a game controller than it was to send code back.
Love. And so somebody actually went and built a Battlesnake that was hand controlled, and then they would respond in real time. And it's interesting because I think they did fairly well. And at the end of it, it wasn't like, no. You did the wrong thing.
It was like, great. You kind of you broke the rule, and now we or or or, like, defined the new rule for us. And so
Speaker 0: That's funny.
Speaker 1: I think you could technically still do it, but, you'd have to have some pretty fast thumbs.
Speaker 0: In planning for this series, not to spoil it, but we have spoken about what it might mean to change strategy, like, mid game. You know, there are there are ways we can achieve this. It was not real time. That's really funny. And the interesting thing about that limit is it really forces you to be computationally efficient as you start to build more complex things.
At the beginning, literally, it doesn't matter. You're as long as your server can physically respond in that time, you know, it it doesn't matter. But what you can do with things like at the beginning of a game, spin up some kind of machine learning or artificial intelligence resource, and then per move, you can call on it, but you have to do it very efficiently. So are we gonna start with a starter snake, or are we gonna start from 0?
Speaker 1: No. No. I think we're I think I think let's start with a starter snake because that's what I think most people are gonna do here. Perfect. And so we'll go to kind of the first step.
We're gonna choose our starter project. I'll just open this up in a new tab here. And what I kinda love here is, and I was talking to Kevin before the the show started, is like, so I'm running on a Chromebook right now. So if you're sort of a newer software developer, and you're, like, just getting exposed to this world, and you're, like, I don't have a device that can run this. If you can run a Chrome browser, you can run this.
Speaker 0: Absolutely.
Speaker 1: I mean, if you wanna have, like, a crazy setup, like, some people have, like, stand alone servers that run their state, You totally can, but you definitely do not need to do that to kinda get started with this.
Speaker 0: No. Yeah. Not at all.
Speaker 1: And so what's also great here too is so you can see these are the official starter stakes that are up on the screen. Yes. They are up on the screen. I'm gonna zoom in a little bit. I'm gonna try and zoom in a little bit.
I'm so used to, like, the Mac keys, so I always click the I've used a Windows keyboard on a Mac device, so I'm always hitting the Windows key. Anyways, so You can
Speaker 0: you can remap them. That's what I had to do. I have a German keyboard on my physical MacBook. I'll just remap the keys in it. Just a few keys on as they're printed, but you just get used to it.
Oh, I like that.
Speaker 1: I should do it. I feel like I've tried it before and it just didn't work. Anyways, not important. So, 5 starter snakes you can start with, which are, like, officially supported starter snakes. So Python, Go, Rust, TypeScript, and then the last one there, JavaScript is what we're gonna look at today.
But if you're like, I really wanna do an f sharp snake, there is an f sharp snake for you there. And there's some really cool ones that have been defined in, like, some really, like, interesting languages and setups. Totally worth checking out. But today, we're gonna jump into the JavaScript official snake.
Speaker 0: Lovely.
Speaker 1: And what's awesome about these is so you can run these on your own infrastructure. So these are all templates that are set up on there. So you're welcome to run them on there. But we do have these set up ideally if everything works out still. I have not run one of these starter stakes in a while.
Speaker 0: That makes sense. See if
Speaker 1: everything works well, is you can just run on Replit. It's just a really simple Node. Js and express server, and, like, there's Docker files for external things, but everything runs right out of the box if everything goes according to plan, which it almost never does. So shall we click the button to show you what?
Speaker 0: Why would you say that? Now it's all gonna go pear shaped.
Speaker 1: I know. You say that. No. See, now it goes perfect. You gotta call it out.
Right? You gotta call out to that
Speaker 0: You gotta manifest it. And this is gonna be we're gonna nail it. There's not gonna be any any any errors. And I'll Well Battle Snake's gonna win the league.
Speaker 1: What's that saying, though? It's like break a leg. Right? You say break a leg before they go on the stage because you're, like, saying the bad thing that might happen. I feel like it's the same thing here.
If you just say, like, this is not gonna work at all, it works perfectly.
Speaker 0: Allegedly. Let's find out. We're gonna see what happens.
Speaker 1: Alright. So we're gonna click here. We'll see if I'm logged in. I have a feeling that I'm not.
Speaker 0: You're not.
Speaker 1: I'm not. But I don't think it really mat I think it'll still spin up if I'm not logged in. We'll find out.
Speaker 0: We'll see
Speaker 1: what happens. Nope. I have to log in. That's all good. We've follow look at that.
I didn't even know we had followers right now.
Speaker 0: Alright. I'm gonna close you
Speaker 1: because we don't need you right now. I'm gonna close you. Yeah.
Speaker 0: And then when we when we get into REPL, it will bump the font size up significantly, I think. Yeah.
Speaker 1: So, yeah, it's this easy. So we're literally just clicking on that fork. We're gonna do an auth zero sign in. Hopefully, we can skip past the stage where I'm gonna put my password. Let's go.
I think Toby Flender snake is still on Replit 2, which is my which is my battle snake.
Speaker 0: Oh. This is what this is what
Speaker 1: I knew was gonna happen.
Speaker 0: Alright. But you're log but you're wait. You're not logged in. It it hasn't logged you in.
Speaker 1: Oh, weird. That's weird. Alright. Let's log in again. Let's go log in.
Oh, I love it. All the errors, even at the authentication stage, we're running. This does not bode well. Oh, you know what it is? I think it's because I'm like, I need to auth with GitHub.
That's probably what it is. I do have it on that email, but I'm not auth with GitHub. So let's go do that.
Speaker 0: Oh, I hate that sometimes when you log in with, like, an SSO provider, but your email address is the same with that SSO provider and you're like, I don't I don't know which which system. Did it work this time? There we go. Okay.
Speaker 1: Okay. So let's go. So we're in here, and I probably got a bunch of snakes in here. We'll go back over, and we'll jump into our starter projects again. We'll jump back into our JavaScript snake.
And so I've logged in now. Don't need to worry about billing, but this should be a much more straightforward process. I love I said everything is gonna go incredibly terribly. And even at the auth stage, I definitely have jinxed this.
Speaker 0: I'm not saying I told you so, but I'm certainly thinking it.
Speaker 1: Alright. So here we go.
Speaker 0: So this is the this is
Speaker 1: the snake. I mean, let's get it in the template right now. Yeah. What do we wanna call this snake?
Speaker 0: We're gonna call this when you call it something does does the dev cycle mascot have a name? His name's ToggleBot. So I don't know. Do we
Speaker 1: call it, like, we could call it ToggleBot. We could also call it, like, coding badly rebirth. We could call it, we could call it, let's
Speaker 0: call it let's call it ready, set, battlesnake.
Speaker 1: Ready, set, battlesnake. Alright. Let's see.
Speaker 0: I was worried you're gonna be, like, does the does the rabbit have a name? Does the director's rabbit have a name? As far as I'm aware, it doesn't. So set myself in a losing battle there. Let's use the template.
Speaker 1: I'm very disappointed. To you.
Speaker 0: Could be right. Could be right.
Speaker 1: Here we go. So it's forking. If you've never used Replit before, by the way, amazing cloud based IDE, super powerful, integrates with all of the things that you're already using, but also has a lot of inbuilt features. If you've used things like so if you've used Gitpod, which is, or Codespaces, which are sort of in
Speaker 0: the Code sandbox is another. Code sandbox.
Speaker 1: Yes. Code sandbox. I find, somebody described it to me recently though that Replit is kind of like the Google Docs or, like, Google Suite of, like, cloud IDEs. It's just, like, very accessible. Mhmm.
Speaker 0: Yeah. Bump your font size up. Let let's let's make that text more accessible because I can't read the damn thing.
Speaker 1: Alright. And I already broke stuff. There we go. Let's zoom in. Wonderful.
Alright. So let's look at the files that we have here before we start messing around with anything. So it immediately brings us into our index dotjs file. The only other two things that we have in here, ignoring, like, our our package and all the rest
Speaker 0: of that stuff,
Speaker 1: are our readme, which is gonna kinda give you, like, things to do, which we're gonna be looking at in that sort of quick start. And then we've got our server dotjs, And this is basically, doing what we described earlier with those different responses that you can do to the Battlesnake API. So there is the just sort of, like, base level. And what what do you call that? Like, the standard with nothing else out of it?
Speaker 0: The site.
Speaker 1: There you go. No. No. I mean, like, the the actual just like a slash. Like, no additional
Speaker 0: Oh, sorry. Sorry. You're referring to that. I would call that the root route.
Speaker 1: Boom. Root route. So, like, your root route, and we'll talk about kind of what all these things do in a minute. And then you've got your start post route. You've got your move, your end, and then we've got a bunch of other little stuff here, including a console log that actually says your battle tank is running.
Speaker 0: And if I may just kind of embellish this a little bit. So this main endpoint that we care about is this move endpoint. That is the endpoint that will receive board states and ultimately has to respond with a direction. You'll notice there are these other ones. So this route endpoint handler, route handler there, that will respond with information about your snake.
We'll do that in due course. But the start and end are interesting. We mentioned earlier about provisioning resource. That's basically where you would do that. Right?
Because I think you get a small grace period between the start endpoint being hit and the first time the move endpoint is hit in any given game. And then your snake can be entered into many games.
Speaker 1: Yep. Yep. Absolutely. And then yeah. There there's a bunch of stuff.
We'll we'll kinda look at some of these and see what they do, but but but Kevin's absolutely right. Like, move is really what matters, and that's where you need to return sort of up down left or right. So the other thing just to look in here, especially for the snake, is just kinda looking at these, like, what you have in this basic package dot JSON file. There's really nothing there. This is a super
Speaker 0: I think.
Speaker 1: Super, super light template. And you can go crazy with this, but this is a very, very light template.
Speaker 0: Mhmm.
Speaker 1: Okay. So, do we wanna do we wanna run this or should we look through first or should we head back over to the quick start? What do you think, Kevin?
Speaker 0: I think I think we could do a little less with the quick start because you and I have both like, we should I think we should refer to it as and when it's needed. I say let's get the let's go to the Battlesnake platform. Let's take this basic snake, which I think what what if you scroll down this file, what does the move endpoint do at the moment? Oh, there is some there is some logic there. Yeah.
We'll talk we'll talk a little bit about that, but it does do stuff. So let's let's set up this snake and get one game running so we can kinda get to grips with how that code becomes a battle snake in a game. I think that that feels about
Speaker 1: Kevin, I have one question for you, though. What do you think I mean, Replen is trying to tell us to do this desperately, and we haven't done it yet. What is the thing that we need to do?
Speaker 0: Oh, I wonder if there's one call to action on this page that is significantly brighter than the oh, okay. Alright. Yeah. There was no mystery. We're hitting run.
Speaker 1: Awesome. And so this is the piece here. So this is the piece that tells you that your Battlesnake is running, is you're gonna see this API response here. So you're gonna see this API version, the author, color, head, tail. And then in your console, if it's running, you're gonna see this running battle snake at whatever the server, domain is and, or server address is and then info.
Now because of the nature of Battlesnake, you need to have a public, URL that you can share with the platform. This is new. They used to all be public and has since shifted. So I think we need to deploy our app. No.
We don't need to deploy our app. So we're gonna see what happens. We're gonna see if we can use just this. Yeah. Let's go to new tab.
And then I yeah. So it'll be like this, and let me bump this up as well. We'll see how much it bumps up actually. There we go. So this is the same thing that we're seeing here.
And then in our, in our navigation bar, we have this, like, replit.dev link, and so that's what we're gonna put over into the Battlesleep platform. It used to show up right here. I don't know why it doesn't anymore. I wonder if it should
Speaker 0: I imagine I imagine it got a bit unwieldy as you build more complex URLs
Speaker 1: by that. That's right. That must be it.
Speaker 0: And that's probably more useful as a developer just to see the the path, but who knows?
Speaker 1: You know what, though? I have a feeling with a lot of these platforms, it might also be. Yeah. You know what? So the what you can do is if you just, like, right click on this, like, 0.0.0.08 1,000, similar to other platforms, it'll actually convert it to whatever that public URL is.
Speaker 0: Oh, that's interesting. So it
Speaker 1: can actually just copy that over there. Okay. So that's working. So let's head back over to play.battlesnake.com.
Speaker 0: I'm so excited. Play. Play. Tailwind is a very nice little very nice little playground.
Speaker 1: It is a very nice playground. This is like this Chromebook has become my central development, tool. And so, like, I have so many, like, interesting things on here. I never thought a Chromebook would be my daily driver. Alright.
So over on the battle 6 site, auth with GitHub, highly recommend. Not that you need to, but, we're gonna auth there. Oh, look at that. Inclusive waffle. Good.
Okay. So I'm logged in with my personal account. So here's what I love. I used to so I'm a teacher. If you didn't know that, what you
Speaker 0: Oh, really? You have absolutely no mannerisms that would give that away. Like, what should we press on the screen now? Is it the green button?
Speaker 1: But I I I introduced, my, like, middle schoolers to, to Battlesnake a couple of years ago. And, like, all their snakes are still in here, which I kind
Speaker 0: of That's fun. Some of
Speaker 1: these are That's Toby still mine, though, runs on node, on Node
Speaker 0: RED. On Node RED.
Speaker 1: That is a stellar platform, if you are looking at, having a stake. And actually, funny enough now now that I think about doing a directus snake
Speaker 0: I was just about to say it. Yeah. Yeah. So so we have, directors automate as part of that. We have flows, which is a low code automation builder.
And, yeah, if I whenever I actually describe it to developers, I ask if they've seen Node RED because I think it's very comparable. You know, you have automation builders that are very much like Zapier, and then you have ones which are more like Node RED. And this is more like that where you're wiring together these these these operations. But, yeah, we'll get to that.
Speaker 1: I love it. Alright. So, we gotta add a snake in here. Now if you're new in your account, I think it prompts you where to add your new snake. I haven't done this in a little bit, so we're gonna see.
I have a feeling
Speaker 0: I actually need to go into my battlesnakes.
Speaker 1: Yeah. We're gonna find out. There we go. And here we go. So we got all of our snakes that are currently in here.
We're gonna create a new one. We're gonna call this one ready, set, Battlesnake. We're gonna drop our server URL in there that we copied over from do we still have it? Yeah. There it is.
I think that's
Speaker 0: And specifically without anything after the slash. We have to increment those, but that's correct. Yeah. So this is what
Speaker 1: you're gonna see, something that looks a little bit like this. If you wanna try and copy this and use my snake, go nuts, or use our snake. And then the next thing you choose here is your engine region. And so I highly recommend that when you're getting started, you don't worry too much about which engine region that you're using. There's a good, like, kind of breakdown on why you would use a different engine region.
I'm based in in in North America, so and I'm kinda closer to Oregon, so I'm gonna set the state there. Kevin might wanna set it up based in the Netherlands, but it really, really doesn't matter at
Speaker 0: kind of the base level of Battlesnake. It it matters when you're squeezing out those milliseconds worth of worth of performance, but we're simply not.
Speaker 1: Exactly. And then, again, description you can add, same with programming language. This is just fun. It gives it a little bit of flair. So you can add a JavaScript, and then we can say this is
Speaker 0: Platform. We need to we need to do some work here. By the next time we record, we're gonna be doing some work to this list because we'll be we'll be moving we'll be moving our snake over.
Speaker 1: I love it. Alright. So let's go. And what are we gonna find? What are we hosting on right now?
We're hosting on Replit, so we should have Replit there. And what I love about this list too is you can actually see, like, here are all the different places that you could host a snake. Now some of these I highly would not recommend. Like, get out Codespaces. I don't think you can actually keep a long running server going.
But Interesting.
Speaker 0: No. Yeah. Yeah. You have to have the Codespace, and then they go to sleep.
Speaker 1: Yeah. But lots of different cool options here. And then the other thing you can do is you can set it so that other people can interact with your snake. And so the upside here is that you can allow other people to kind of play around with it. The downside is you can have people that decide to challenge while you're using your snake for some other thing, and then you're having to deal with all the compute costs.
And if you're running on, like, AWS or something that charges you for all of those compute hours, definitely challenging.
Speaker 0: It's not just that. It's every request you get in relation to a single game has an ID of that game. But at basic levels, you're unlikely to be segmenting game logic. And if you're doing, you know, basic battle snakes, we'll just look at a single board and make a single response based on the heuristics of your code, the algorithm you create. But if you're doing something a little more clever way, you're looking over multiple turns, it screws you.
But by that point, I suppose you are you are using that ID, but that's worth considering as well.
Speaker 1: Yeah. Absolutely. Okay. So let's jump in here. So we'll leave it as private.
We'll save this battle snake. So you'll know once you save right away if your battle is actually there because it'll show up with the name, obviously, that you set it here. If you don't, though, you won't get any response here in this ping. So you might put, it used to be that if you started a snake on a service, it wouldn't automatically go. And so you might have to run this ping just to kinda see.
And you can see here, if we do this ping, we were talking about that 500 millisecond response time. You can see that Replit is really up their, like, their timing. It used to be
Speaker 0: They didn't. They didn't. That first response was a few hundred. So that must be like a cold start kind of like now it's middling around 40, 50, 60, which is great, but it was multiple 100 the first time you, the first time it was there before you hit ping again out of interest.
Speaker 1: Yeah. That's true.
Speaker 0: So But then that's what you're starting to see.
Speaker 1: A good idea. Yeah. Yeah. Okay. So we've got we've got ready set battlesync in there.
You'll also see you kinda get the flare that's related to the the language and and sort of hosting service that you're using. And so now, our Battlesnake is in there and is ready to go. So, do we wanna make our Battlesnake look good before we bring it into the game or do we wanna bring it into the game?
Speaker 0: Let let's jump into it and maybe we'll see if the the Battlesnake elders allow this. We might see if we can do some custom customization during the the act of us recording 4 episodes. But for now, let's just leave our our snake a slightly boring gray. We can come back to it. When when we come and update the platform to direct us, that's where we'll do the customization.
That'll be next time.
Speaker 1: I love it. Alright. So, we're gonna go in here. You can choose. So, well, in the traditional Battlesnake game, or traditional snake game, I guess, it's kind of a standard map.
No hazards. It's kind of just food pops up and things like that. So we're going to choose just the standard mode and a standard board size of 11 by 11. And we're just going to add ready, set, Battlesnake onto the board. We're not going to add any other snakes in there.
You can add some bots. These bots are always running that have, like, some set sort of modes, but we're just looking to see if our snake is ready to go. So let's go ahead and see, how ready set Battlesnake runs. Alright. We're in.
Okay. We're here. Should we have it now? You have to.
Speaker 0: Oh, yeah. Yeah. Come on. Let's do that. You ready?
I'm so thrilled. No. I'm good. Alright. You ready?
Yeah. Ready. Oh, no. No. We have a we we we get a catchphrase for this show.
What? If Reggie said that Oh, my goodness.
Speaker 1: Yes. Okay. Here we go. Okay. Of course.
Alright. Let's go. Ready. Ready. Set.
Battle snake.
Speaker 0: That was thoroughly underwhelming. I'm gonna be honest. But but we are watching the snake. We got So this is what we got. So you see the ping?
You saw the ping going on the right. So it was still around that 40 millisecond mark. There were 47 turns that happened before our snake died. Why did it die? And the nice thing about this editor, this player, of course, is you can step through your turns.
So it was performing kind of a slightly eclectic set of moves, which is great. But what eventually happened to it? So it was at the bottom and it went off the board. It went down. So that was that's that's what our snake did.
Now just to be clear, we'll look into the logic of our battle snake next, but we don't quite know why let's look at our code. And now we're at the point where we can start customizing this, this battle snake.
Speaker 1: Alright. So we're gonna jump back over to Remplit. And so all of the things that you need to know for this snake when you're getting started are all gonna live here. And the other thing that's really cool here that I guess we didn't talk about earlier and maybe you didn't see here because we didn't go that far down in the code is we're actually returning into the console every move. So you can see why it moved or not why it moved in that direction, but you can see what happened.
So this in this game start move 0, move 1, all of these commands that are happening are in here. But and this is sort of included in the base snake that you get here. And you can return lots of things in there. Like, you can return, like, what's leading into that. You can return logic.
You can return things like shouts, which are just like little statements that are in your code. We kinda got rid of them. It used to be that you could do custom shouts that were displayed on the board of the games, which was very cool, but, they kinda disappeared. But, okay. Where where do we wanna start, Kevin?
Speaker 0: Well, the nice thing about this starter snake for learning is it talks us through some steps. But before we do that, why don't we look at the code of what our battlesnake did? So it didn't just go in the same direction nonstop. Oh, that's another note. If your sync doesn't respond within 500 milliseconds or responds in an invalid way, it will continue to take the last direction There are a couple of variables here just to help us out.
One that tells us where our head position is, and that'll give you an x y position coordinates and our neck, which is the second piece of your body. It's not all of them. It's just your head and your neck. There's a reason why your neck is important. We'll talk about that in a moment.
And all we're doing here is oh, it's actually a lovely lovely and commented here. You can turn back into yourself. So if you're going straight up, you can go down, but you die immediately because you collide with your body. So all this logic is doing is saying don't hit the neck. Like, don't go back into the last space I was in, which is always the second position of the body.
Now another thing that's interesting, if I may just kind of embellish kind of what's here, is we're starting to see the data structure play out a bit here. So this move function has an argument called game state. We see on lines 53 and 54 that inside of game state, there is an object called you. And inside of that, there is an array called body. And we can immediately assume that they're full of x, y coordinates.
And in fact, that's that's made clear on line 56 where my neck and my head both have an x property. Before we continue, what might be interesting oh, I'm sorry. And so so the rest of the logic here is turn up, down, left, or right in that in that array, in that, object at the top, make them force if it means I'm gonna collide with my neck. Remove that as an option. And then I believe what it does is it basically, yeah, randomly picks 1 on line 87 and then returns the randomly selected valid move of which just doesn't collide with your neck.
It does nothing else that's fancy. That's what we'll be doing today. Before we continue on this, can I make one recommendation that we do go back over to the docs and look at the game object so we understand what else we have at our disposal? Because I think it's important. Sorry.
Not the get yeah. The game object. The board?
Speaker 1: Yeah. It's the board object.
Speaker 0: The board. The board. Perfect. Bottom left is 0. That's we're calling that out because when you draw on screen, sometimes 0 is the top left.
If you do math, it's in the bottom left. So just note, 0 zero bottom left. That one screws me every time. This is what the object looks like. Could you zoom in a couple of sets by any any chance?
Cool. Yep. So we have a height and a width. That's the size of the board. That is obviously important to know.
We have the position of all the food, the position of all the hazards, which we're not playing within the classic game style. But if you hit hazards, I does your health go down or do you die?
Speaker 1: You die if you hit a hazard. Or well, depends on it depends on the game mode, but a lot of time you'll die.
Speaker 0: Fine. And then you have an array of snakes. Each snake has the idea of the snake, but it also has look at that. That was that was good teamwork there. It also has its health, all of its body parts, a convenience, which is an object called the head, which is always the first option in the body.
So that's just a convenience there. They're always the same. The length, any customizations. But really what we care about for logic realistically is the body array and the head as a convenience. But we could get most of what we need from the body and the board collectively.
What else is there here? Rule set, the game itself, but I don't think we care too much about those in this very moment. Yeah. Yeah. And I
Speaker 1: think the only other thing that's kind of in here that's, I mean, less it's less valuable. This is more like you you can see. Like, imagine that if you're in this game, your snake can see everything about the other snakes. So, you're also sending all this information about your snake to all other snakes on the board. So
Speaker 0: Yeah. You could stock out snakes that are low on health.
Speaker 1: Yeah. Yeah. And some people even decide, like, I don't wanna ever, I don't ever wanna attack a purple snake or a pink snake, and they'll just decide, like, I'm gonna avoid all of those snakes. Just and you have the ability to do like that. These weird kind of logic pieces, which I think is kinda fun.
Speaker 0: Yeah. Sure. Cool. So that is the shape of the object, which I think was important to dig into as we were starting to get a sense of what it looked like. So we know that we've got a board.
We know we've got, we know we've got, sorry, a game. We've got boards. Boards have all the snakes and the board state itself. Snakes have a head and a body. So I think that's basically all we need to work through here.
So all this snake does right now is avoid its neck. That is all it does. So Yep. What is the step one suggestion?
Speaker 1: So step 1 is to prevent our Battlesnake from doing exactly what it did by moving out of bounds.
Speaker 0: Okay. So this I mean, logically I mean, you and I have both done this kind of more simple battlesnake a a ton. But, you know, we will run through it kind of, you know, we come with a little bit more confidence in the approach, so we'll talk about it. But just know that in this little bit, there'll be a little less trial and error. Just so don't feel bad if if you're working through this and it's taking you a little longer.
We just we just happen to know these first few steps like the back of our hand. So right here, there are a couple of comments that will go into that nested object and create a couple of variables for us, board width and board height. In this game, 11:11, but they can be smaller. They can be larger. And all we wanna do is say sorry.
Go ahead.
Speaker 1: No. I'm just gonna say, my eyes my eyes are burning right now. Do we see a do we see a dark mode?
Speaker 0: It will exist. It has to exist. This is shocking. Our confidence. It it has to exist.
Do you need to save save the snake or does it autosave or something?
Speaker 1: No. No. So everything auto saves. Okay.
Speaker 0: I recognize it.
Speaker 1: I'm just, like, I'm motivated for dark mode, but I also
Speaker 0: Does it take your does it take your, like, theme of your
Speaker 1: Oh, look at you. Look at you, Kevin. Look at you figuring out the smart thing. I bet you it does. That's the wrong one that I want to turn.
Where's my dark mode? Mode? I wanna click
Speaker 0: on it
Speaker 1: here, and then I wanna set it on dark theme. And then I bet you if I refresh this, it's gonna be dark.
Speaker 0: Yeah. Okay.
Speaker 1: I'm very confident that that's going to happen, but it may
Speaker 0: not Oh, did I say I'm really confident? That's where it all falls apart. Yeah. We've already learned that that that's how it works.
Speaker 1: Nope. Did not happen. Here we are. At least it's dark in some places. Is it
Speaker 0: in your user settings?
Speaker 1: It might be. It's odd that it's not actually, like
Speaker 0: Like, here in the editor itself. Yeah. Maybe in your account, that you set up, like, your your default editor settings.
Speaker 1: Let's see. Let's see. Billing, account, themes?
Speaker 0: None of this. Themes. Themes. You know what? I wonder if that editor has, like, a command palette.
Speaker 1: Oh, how
Speaker 0: do I do that? Boom.
Speaker 1: Beautiful. Are you gonna catch it here? Do I gotta refresh again? Oh, you're gonna make me refresh again. Alright.
I see you. I see you.
Speaker 0: There we go.
Speaker 1: Beautiful. Oh, look at that. We got some dark mode battle snake as well. But oh, actually, does this still exist? There used to be.
Yeah. You can. Dark theme. There we go. Nice.
Speaker 0: All dark Okay.
Speaker 1: All the time.
Speaker 0: So let's go back to our code editor then. Sometimes in dark mode, things are just slightly less legible. So maybe let's just do one more step up on the font size, if that's alright. Yep. Lovely.
And right. So we've got the board width, the board height. So real realistically, this code is gonna run every single turn. We're gonna know the size of the board based on these values, and we're gonna know our own heads x y position. And all we wanna do is the very pragmatic, am I on the very far right of the board?
Yeah. I can no longer go right, left, up, and down. So that's the logic. We kinda have logic that looks similar to this above, but we can write it from scratch. That's also cool.
Take it away, mister McLean. No. We're gonna see.
Speaker 1: So you say we're gonna write it from scratch. I, I fundamentally disagree with you, sir. I feel like if we're provided with this code, I feel like we should use it. Alright. Here we go.
So here, we were looking if your neck was less than your head, then you didn't wanna move left. So we're gonna remove some of these comments, but it's gonna be the same kind of concept that we're doing here. And so let's look at our let's look at our head. So we wanna get our board width is gonna be important in a minute, but let's get our head. So my head x, and then we want our head x if it's less than or equal to or greater than or equal to.
Speaker 0: Well, hang on. Fin finish the thought. What what direction are we doing here? Left?
Speaker 1: Yes. So we're doing so we're doing x. So we're doing the x axis.
Speaker 0: If it's
Speaker 1: So we wanted to
Speaker 0: 0. If it's 0, it's on if it's 0, it's on the far left of the board.
Speaker 1: Yep. So that's
Speaker 0: all we need to check. If it's left, remove left trim. There is no minus one. You just die. So, double double equals double equals for for a comparison.
Nice. So
Speaker 1: that's our head x. So let's do our head y now. So if our head y equals our board height
Speaker 0: So we're doing the top now. We're going clockwise. We're doing it. We're doing
Speaker 1: the top now. But the thing here is because you're gonna get your board height, but then you need to be minus 1. So, like, your board
Speaker 0: height because it's 0 indexed.
Speaker 1: Exactly. So you're gonna do your board height minus 1. So this is basically saying if my oh, and not my neck. We want that to be my head.
Speaker 0: Oh, yeah.
Speaker 1: So if my head y is equal to the board height minus 1, then we're gonna set up to be false. Yeah. Alright. So let's do our next one. So that means that we're not gonna go off to the left of the board too far.
It also means we're not gonna go up too far, so let's keep going around. So let's do else if my head my head, and let's go x again, and let's go we'll figure out what the in between is gonna be, but let's do board width minus 1 and is going to be
Speaker 0: It's it's the same. It's just a double equals. The I I literally cannot get behind you doing this clockwise. It's driving me nuts, but we're here now.
Speaker 1: We're here now.
Speaker 0: It's so funny. I would I would have gone left, right, up, down, but I think that's because that's, like, how CSS rules are structured. Left, right, up, down. But yeah. Isn't that yeah.
That's why I was like, what are you doing? Yeah. So this last one is gonna be, down. Right?
Speaker 1: Yep. And so this one's gonna be my head y equals equals 0 and get rid of that. And this one's going to be, down is false, and then we actually need to change this one to right is false. And so this logic here, if you haven't been following along, is going to be if your head is equal to 0, you can no longer go left. Type of.
Did I type
Speaker 0: Hit backspace.
Speaker 1: Oh, right. Hit backspace. Is move safe right. Yes. So here, if your head is at x is at 0 sorry.
Your head x is at 0, then you are not gonna be able to go left. If your head y is at the top of the board, you're not gonna be able to go up. If your head x is at the far right hand side of the board, you're not gonna be able to go right anymore. And if your head y is at 0, you're not gonna be able to go down anymore. Cool?
Do we wanna should we comment this? We're not gonna comment.
Speaker 0: Get rid
Speaker 1: of those comments. Who needs comments? You've got a whole video to go along with this.
Speaker 0: Exactly.
Speaker 1: Alright. So let's, it should automatically update. I'm gonna just refresh here, and we'll see if it works. Normally, it does. It's pretty good in real time.
So let's go and see what happens. Let's just create a new game and see if our solution sorted itself out. So all we have to do here is literally just create a rematch. It's gonna go and read in with our new Battlesnake data. We're gonna see what this looks like in dark mode.
We may be changing back to light mode. It's almost too dark now. I feel like I need a like a beige mode.
Speaker 0: Like a like a, what is it? Like a Solaris. Is that what it's called?
Speaker 1: Yeah. There you go. Like a sepia mode.
Speaker 0: Yeah. Alright.
Speaker 1: Oh, this is for so long and my wife laughed
Speaker 0: at me. We also called it Nokia. So in the background right now, all of these moves are happening in the background. If we hit play and we get up to the latest turn, it kinda just starts to slow down, and we only and we see moves in real time. So what we're kinda letting it do now is catch up.
So when we hit play, we can just watch it all in one go, which is Yeah. Pretty nice. The other
Speaker 1: great thing that you can do here is you can actually change the playback speed. So if you wanna watch it slower, you can if you wanna watch it faster. We're just gonna leave it as medium. There's also some other things you can do here. Like, as soon as the first turn is ready, you can auto play in these games.
That's nice. You can also grab, like, a scrub bar so you can see how long the game is gonna last. It's really only good for you. If you're doing that in a competitive game, it's a little bit less fun. And then you can also show board coordinates.
I actually think this one's interesting because I think this will show folks something interesting in the game. So let's go back here. So we got the board coordinates up there. As
Speaker 0: you can see
Speaker 1: here, 0011. So this is the stuff that we're talking about. Right? So when we said the board width, which is technically 11, even though it's 0 to 10, it's an 11 board. So if we'd left it at that and just said board width equals Yeah.
Speaker 0: The the the upper the upper right wouldn't have worked. It would have let it go off the yeah. Let it have died first. Let let's hit play so you can see what this thing does. So now it should avoid its neck, and it should avoid walls, which realistically means it will die by hitting itself or running out of food in theory.
Yep.
Speaker 1: And that's exactly what exactly what happened. Ran into its body. And so this is what we mean here. So, technically, the neck counts as part of the body as does the head, but we've defined the neck in our code. And so he's never gonna run into his neck, but it doesn't avoid him running into anything past his neck or or like Kevin said, running out of food.
So, and you can see here, like, he's actually surviving a shorter period of time even though we have more code. But that's honestly I think you're absolutely right.
Speaker 0: That first
Speaker 1: time was a little bit
Speaker 0: of a fix. Yeah. Absolutely. Oh, interesting. That should not have happened.
Speaker 1: That should not have happened. Oh, I see. So head is technically at 0. It might have been because he's at a he's at there's no other safe moves, but that's not true. So what happened on that last move?
Did he yeah. He went down. Interesting.
Speaker 0: Let's let's just quickly check it again. When x is 0, if you head back to the code, when x is 0, remove left. When y is right at the top, hold height minus 1, you can't go up. When x is at the width minus 1, you can't go right. And then when y is at 0, you can't go down.
Interesting. If or else if that Oh. Oh. No. No.
No. I I I I I got it. This is in a a weird, like, else if else if else if. We we don't want this. We we we want each one to be its own individual statement.
All of them need to be Oh, true. I love that.
Speaker 1: If you
Speaker 0: move the else's and and you change.
Speaker 1: I love it. Alright.
Speaker 0: It I'm not sure that's what the explains what just happened, but that was wrong. Like, it needs to be more like that.
Speaker 1: Alright. Let's see if that fixes things for us.
Speaker 0: Oh, timing out. Well, no. 42. Oh, that was an error. Let's scroll up.
Let's see we'll see what happened. Just go all the way up to the top of the error. Alright. What's happening in here?
Speaker 1: I need to zoom out a bit this a little bit. Just give me one second.
Speaker 0: Board width is not defined. We made a typo. I think board width. Board? On line 70.
There is on line 70. Oh, define the variables. Like, let put a let in in front of each one.
Speaker 1: So what's interesting there is it means it was running our old code before. So that's that's part of the problem is it was actually running our old code. So now if we run this, k. Our battlesnake should be up. Let's do a game again.
Speaker 0: And the moment you hit create rematch, we can go back to repl it, and we can see that things are happening. We saw that it made it 34 moves at least. That means all the moves have played out, so we can just hit play. It's looking promising.
Speaker 1: Yep. Yep. Same thing. And it
Speaker 0: went into its body.
Speaker 1: I wanna I wanna examine that because I think that's interesting. Right? We had that l tiff. Why why was that not working? Why why do we think that wasn't working?
Like, where's the logical error in that?
Speaker 0: Oh, if if you're if you're at the bottom and the right, it'll only run 1. It'll run the first statement it it gets, and then it will.
Speaker 1: There we go.
Speaker 0: So you need to you need to get you need to get each of them. So this is now we think working. We'll we'll keep an eye on this one. Let's assume about that, like, logically, this feels good. If it starts moving out of bounds where there are viable options available, we'll come back and revisit this.
The next step is to get it to collide is to get it to not collide with your entire body. Right now, it's just avoiding the neck, which is the second piece next to the head. We wanna avoid all of the pieces. And once again, Andrew and I have created start to battle snakes dozens, if not hundreds of times over. So what what are we gonna be doing here?
We're gonna basically be writing a loop. We're gonna go through every piece of the body, and we're going to see if it's if it's next to me just like it was a boundary, we're gonna remove it. So we're gonna actually end up using reasonable amount of the logic. The logic is gonna look quite similar to the one above, but inside of a loop. Great.
And we don't we don't actually need to do, we don't even need to we don't need to care about the length so much because we can, we can just use a 4, a for of loop for this, which is a syntax, which I really like. So I'll introduce you to a for of loop. John, sure, you cannot you
Speaker 1: know what we're gonna do. We're gonna do what every good programmer does, and then I'm gonna go to Google and look up how do I do a loop in JavaScript because I have legitimately You
Speaker 0: got me. You got me.
Speaker 1: You got me. I it it
Speaker 0: auto filled. Hang on. Hang on. Head back to Replit. It was helping you out there.
It was doing it was and also w three schools. So so if you wrote the word for first first of all, it did actually kind of something yeah. Look. It's kind of giving you a hint here. So this is a very vanilla JavaScript loop.
What this is, there are 3 parts at the top. First thing it's saying is, wow, okay. That's cool, I suppose. So we're initializing the value I with 1. We're saying keep running this loop for as long as I is less than the the the body length.
And at the end of every iteration before you start the new one up I by 1 and I is a is a number, which you can feed into an array to get an index. There's a nicer way of doing this though, in my opinion, for this use case. So I'm gonna propose comment this out because I wanna just quickly show you a follow-up loop because I just think it's a I think it's a really nifty syntax. So instead of this, we're gonna go 4, and we're gonna do the the brackets again, but not let it autofill, all of that. Let piece where whatever we want.
We're gonna call it piece of my body. Exactly. You've got one too many, close brackets there. And then you do squiggly brackets, and we enter into the code block. Piece is an is a variable inside of this loop, which will change its value for each iteration.
So I just think this is yeah. I mean, it if you if you hit tab now, it seems to have already, that code's wrong. I could ain't gonna do anything. I mean, we'll leave it there as, like, as like, you know, we'll base something on this. This is not right.
This is saying if if my head is in the spot of this piece, which also includes my head, make everything foresight. This just won't work. It will mean no isn't a viable move and it will keep it will keep sending you know, it will send it, I think, an undefined and then we'll die. So this is wrong. But just before we jump into the logic here, so this is another way to write a a loop in JavaScript.
And another way you can do it is called a for in loop where you change the word of for in, and then the value of a piece will be the index value. So what we could have done there, an exact copy of what was above is saying for let eye of my body. And then I will automatically increment each time. It will give you the, in sorry, in my body. And then I or whatever variable name you give it, will will be a will be a number that goes up.
The way I remember the difference between of and in, of object in index.
Speaker 1: I love that.
Speaker 0: Yeah. So, we'll we'll use the the for of loop. I think it's really nice because when you start to nest them, you can be really descriptive about what that value means inside of the loop. I think it looks nicer. It's a little more concise.
But there you go. You learn about JavaScript loops. And there are obviously other loop types as well, but these are the more common 3. So what do we care about when we're looking at our body? Well, for every piece, what we wanna know is, is it one space away from us in any direction?
That's all we wanna know. And if that is the case, we cannot move into that position. Even that strictly might not be enough because oh, no. It will be. That that will be enough.
That is groovy. So what we wanna check is is our head equal to x? So is it on the same is it on the same x plane? Oh, no. No.
Sorry. Inside of this initial if on 95. We're we're gonna alter 95 because 95 doesn't work. So we wanna say if it's on the x plane, but my head dot y is piece dot y minus 1, that means we are one space sorry. That means our body is one space below us.
Down goes off the table. So this would be whatever the line is where we remove down. Game what's it called?
Speaker 1: Yep. Yep. Let's go grab that.
Speaker 0: Yeah. It is move is move safe. So if it's 1 under us down, down goes off. So is move safe dot down equals force. On the same x plane, hang on a moment.
But the y for on the same x we're gonna fiddle with these till they work. This this bit always gets me. I think I might have just done that wrong, but we'll find out. Oh,
Speaker 1: it's part of the adventure.
Speaker 0: So, Hannah, if we're on the same x and it's below us if we're on the same Do you
Speaker 1: need to draw this out?
Speaker 0: Yeah. Maybe. Maybe.
Speaker 1: Let's do it. Let's grab,
Speaker 0: let's grab some It's bothering me. If we're if we're on the same x plane, but it's 1 below but then we're not on the same x plane out. But it's y. I wondered what tool you you were gonna grab there.
Speaker 1: We'll see if this works. I might pull up some random drawing that I've created. I bet you I am gonna we're gonna see what magical drawing that I have up on the screen here as this loads.
Speaker 0: What? Can you back a table in there? Because that's all we need is or a Google Sheet even, to be honest.
Speaker 1: Oh, that's a good idea. Let's do a Sheet sheet. Okay. Let's do, sheets.new.
Speaker 0: Sheets.new.
Speaker 1: Sheets.new? Yes. What's happening right now?
Speaker 0: What is slides.new, docs.new, forms.new.
Speaker 1: I love it. That's fantastic. Okay.
Speaker 0: Right. Zoom in. Zoom in. Zoom in. Zoom in a ton.
Let's go zoom in. Oh, no. Wrong one. Let's go zoom zoom zoom.
Speaker 1: There we go.
Speaker 0: And and let's just do, like, we don't need 11. Right? We could just do, like, a 4 by 4 for the sake of argument. Like or up to 5 by 5 if you go to Ian and you go down to 5. Alright.
Speaker 1: And I do feel like this visualization is really helpful when you're doing this, like, genuinely. I think this is, like, a process that is useful for anybody to do if you're considering doing this.
Speaker 0: So draw, like, a 3 parts draw, I don't know. Yeah. Let's just yeah. Yeah. Perfect.
Right. So what we want is if you go if you go right one oh, what's happening? What what we're doing? Just give me one second. This is just a small one to
Speaker 1: do this.
Speaker 0: Hold on. Hold on.
Speaker 1: There we go.
Speaker 0: Great. Hang on. Hang on. I think I think we needed to do it. Do a little more than that.
And I would I would leave them as x's so we can notionally talk about the head. So do do maybe, like, make it like a like a u shape. So also fill in b 5 and b 4.
Speaker 1: I'm gonna you know what? I gotta stop with this x. The the color x is
Speaker 0: I I I I yeah.
Speaker 1: Oh, no. Actually, hold on. I could just literally copy and paste. Come on, Andrew. What are you doing?
There we go. This
Speaker 0: is how we want it. Let's assume that b 5 is gonna be the head. Right. So the first thing we wanna do is to say, let let's try and do the left position first. Yep.
So the x is the same and the piece is on x minus 1. So that's that's the first one we're we're gonna do. So x is the same as my piece dot x, but but the my piece dot. Oh my god. What's going on?
So this is gonna be Sorry. Sorry. Sorry. Sorry. Sorry.
The y is the same. Yeah. Because we're all because we're on the same level. We're on the same height. That's what was getting me.
So if the y if the y is the same, the x is minus 1, you remove left. So let's do that first.
Speaker 1: Alright. So if the y is the same, x minus y?
Speaker 0: Yeah. Yeah. Yeah. So so let let's do the first if the first half of the statement, let's change those for y's. So if the y is the same, but the x is piece x minus 1 remove left.
Speaker 1: Love that.
Speaker 0: Okay. And and it's exactly the inverse for right. So x and sorry, y and y, perfect. We we replace those, but this time it's gonna be plus 1. That's all it was.
We're we're just struggling struggling with that. So just to be clear, sorry, those first two still wanna be you need to basically inverse all of them. So y Correct.
Speaker 1: There we go. And then we're gonna return off
Speaker 0: that will be right. Yeah. And I I don't think we need I'm really glad we pulled out that tool, but I think we can basically invest them now. So copy and paste both of these. So next thing we're gonna do, not like that, is if the x is the same, therefore, the the column we're in is the same.
That was it. But the y piece is minus 1, then it's under us. So we're gonna remove down. And, yeah. Exactly.
Xxy y. There we go. That took us that took us a hot minute, but we got there. So that should now prevent us colliding with oh, hang on. Hang on.
Why? Oh, no. It's fine. On that line 94 piece isn't, like, white, so I thought it was unused. Oh, no.
It's
Speaker 1: because I added an s in there. There was a there was an error there. Just because I'm doing the Windows key save.
Speaker 0: No. No. No. Peace is declared but never used. I don't think that's right.
Speaker 1: Oh, there it is. It caught it.
Speaker 0: There we are. There we go.
Speaker 1: Cool. Oh, but we got a formatting issue? Hold on. So we can
Speaker 0: No. It was a it was a formatting issue. No? Hold
Speaker 1: on. Nope. We're still getting a bug here.
Speaker 0: Someone watching this right now is screaming. They're like 100%. A 100%. I feel like I'm missing it. Scroll to the top of the arrow.
The top of the arrow is gonna tell you tell you what it is, but we're not at the top of it yet. Keep going all the way up, all the way up, all the way up. More more more more. Oh, okay. Less.
Speaker 1: We went too far.
Speaker 0: We went too far.
Speaker 1: It happens. Hold on. There we go. I just went too far into the first interpreter.
Speaker 0: Alright. Board meeting No. No. We sorted that. That was before now.
We did that.
Speaker 1: Oh, it's this one. Hold on. Hold the phone. Close u.
Speaker 0: Wow. Capsule consoles.
Speaker 1: So many consoles. Formatting failed with message. What?
Speaker 0: And go have I missed something pretty obvious here?
Speaker 1: No. I think I think that was the that was the issue for let piece of my body. Hey, bro. Yes. I think it was just that s in there.
Let's try running it again.
Speaker 0: You can do it. You can do it. I'm getting a hunch it can't do it without some intervention.
Speaker 1: What have we done? Is it because we do need to declare this let on my body?
Speaker 0: Oh, yeah. Maybe that that was the grape last time.
Speaker 1: Kevin lied.
Speaker 0: There you go.
Speaker 1: You lied. You said I didn't have to let it.
Speaker 0: No. I literally did earlier. That's what happened with board width.
Speaker 1: I feel like it's it's a useful thing to blame other people for your coding mistakes. I feel like that is what it is the sign of a true a true professional.
Speaker 0: The professionals we clearly are.
Speaker 1: Yeah. As I as I went to Google to search how to
Speaker 0: do a
Speaker 1: loop in JavaScript.
Speaker 0: What's what's happening right now? It's all taking a little long. Can you can you refresh the web view at the top?
Speaker 1: Yeah. Let's do that. I feel like that's k. We can close this out for now. Yeah.
Speaker 0: Yeah. Yeah.
Speaker 1: Let's see what's going on. I don't know. Yeah. I don't know what's happening. Maybe repllets happen a day.
I mean, this is the thing. Right? It's like we are dealing with a cloud ID, so it does chug sometimes. But
Speaker 0: Absolutely.
Speaker 1: The REPL is booting. It's doing its thing.
Speaker 0: It is. I will say as much as I love cloud IDs or cloud development environments as they're trying to brand themselves now, I use Gitpod for ages, I use Codespaces for a while, I have moved back to using a desktop editor for things like this. Like, why am I waiting for my editor to get its act together?
Speaker 1: You're not wrong.
Speaker 0: So so yeah.
Speaker 1: There we go.
Speaker 0: And the GitHub CLI makes it really, like, quite quite nice to to move between PRs as I'm reviewing stuff. So, alright, great. Let's rerun the game. So now it should not die from its own body. So in theory in theory, for a one snake battlesnake, I think it's gonna have a yeah.
I think it's gonna have a decent life. Look at this. We broke a 100. There we go. This is amazing.
Wow. This, okay, 170 moves. Let's see what ended up doing it in no. It could be health or it could be eventually, it had no viable options. You know?
Let's see.
Speaker 1: Yep. So it's doing all the things. Not running into its tail now, which was entirely possible with our previous code. It's not getting bigger because it's not getting food. So now it's going in that circle because it's avoiding its body, and it's avoiding its tail, and it's avoiding its neck.
And so I think he might starve out just because he's getting stuck in that circle.
Speaker 0: Oh, no. Poor buttersnake. Eat something. Look all that food around you, mate.
Speaker 1: Dang. So, yeah, that's the interesting thing is, technically, he got into that loop where, like, technically, he was right, but we didn't say if you do this more than once, get out of it, which is a thing you can do. And what that, chicken or sorry. What that snake did is a is a a very famous move in the Battle State community called chicken snake. And chicken snake used to, like, go into a corner and would just chase its tail and wait for everybody else to die.
And it would do really well.
Speaker 0: Yeah. And you you basically, you are you either other everyone has to die before you or you have to hope food spawns in in well, it it won't spawn where you are though, will it? It won't spawn in a position where a snake is. So actually
Speaker 1: It can spawn, like, right where oh, you're actually not wrong. That's absolutely
Speaker 0: right. Yeah. Interesting. Okay. Cool.
So step 3 is a pretty, a pretty good evolution of what we just did there, which is up until now, we have a single battle snake on our board. But in reality, battle snakes will not be alone on the board. There will be at least one other snake on the on the board. And our job is not only to avoid ourself, but to avoid every snake and all of their body parts. Thankfully, we are effectively gonna get to get gonna get to, like, work on this work on this.
And in fact, Andrew, I don't think we should copy and paste it. I think we should adapt this because our snake is in the snake's array as well. The might the me, whatever it's called, is again a convenience like the head to just give you the first item. So there's no point doing a loop over all our parts, then a loop over an array which includes us. We should just adapt this immediately.
Speaker 1: Okay. Great. Let's do it. Alright. So let's go yeah.
So we've already defined here. So we've got our opponents defined, and we're gonna do that same let again. Right? Like, we're gonna do our loop with around our opponents, or do we wanna remove ourselves from that first?
Speaker 0: You know or I mean, this is I mean, it's up to you. Right? We can either, yes, remove ourselves from it, run the loop again because who cares? You know, it's just repeating logic effectively. Or we can adapt what is written above in that kind of 90 to a 110 line range to just be the loop.
Speaker 1: Oh, I see. Okay. Okay. So where where should we start?
Speaker 0: Us. So we we know here based on line 116, which we should probably comment out because it doesn't have a let in front of it, but we know that game state dot board dot snakes is an array of all snakes including us. I believe we're always first. So let let's create that variable above this loop, first of all.
Speaker 1: Alright. Let's do that up here. I see. I see what you're saying. Now when you said adapt, I was like, is that not what I'm doing?
Alright. So let's define that.
Speaker 0: Yeah. Yeah. We we don't need to build on top of what we've already done here. In theory in theory, we can also do a way above with, the avoid our neck logic that it came with because we're gonna avoid our neck by virtue of this. Let let's leave it for now.
Let's do a little bit of cleanup at the end, I think. So now we have it's not even opponents. I don't even think that's the right name. It's snakes. These are the snakes, and it includes us.
We have a loop that will go through our body and do the check. And, basically, all we wanna do here is write a full loop above it, like surround it in a further full loop, and we'll do the same thing. So we'll go let, snake singular because each iteration is going to be a single snake of snakes. We'll do the open squiggly bracket here on line 44, remove that exactly input precisely, and we'll put that outside the outside of the other one. And all we wanna do here is instead of my body, it will be snake dot body.
Speaker 1: Oh, Kevin. It's like you've done this many times before. That is just like It is. That is beautiful. So in my hearing and
Speaker 0: the We we don't know it works yet.
Speaker 1: No. But I like aesthetically, it's very pleasing.
Speaker 0: Thank you. You're welcome.
Speaker 1: Thank you.
Speaker 0: So now in theory, we're running the same loop for all of for all the snakes. Right? Should we test it?
Speaker 1: Yeah. Yeah. Let's test. Alright. So let's I'm I was wrong.
We do need to stop and start it. So let's see. This should work fine. Perfect. Okay.
Let's head back over here. Gotta do a new game now, because we What? Are actually gonna add
Speaker 0: another set. Of course. Of course. We may as well use one of these bot snakes.
Speaker 1: I love that scared bot just disappears in this dark mode.
Speaker 0: In dark mode.
Speaker 1: Just not there. That's fine. It doesn't matter. We're gonna add him, and we're gonna add in ready, set, and battle snake.
Speaker 0: Right.
Speaker 1: Alright. Let's add that in there. Alright. And so we've got a game running now. Now this is another thing about playing this is, like, you can see a lot of these things from your logs.
So if you're ever playing BattleSync competitively and, like, there's a competition, like, it's almost like you have to close your logs. Otherwise, it gives too much away.
Speaker 0: It's like
Speaker 1: you know Woah.
Speaker 0: What happened. The other the other nice thing about this is, of course, we get the whole board state every time. So as we start to integrate this with Directus, we can we can consume and store as much of this as we want. Let's, let let's play it. Yeah.
Game over. 101 moves. Let's see what happens.
Speaker 1: Okay. So avoiding body, avoiding other snakes as well. Oh, I think I know
Speaker 0: how this is. Yeah. I think I know how it's gonna end for this snake.
Speaker 1: Yeah. Me too.
Speaker 0: Womp womp.
Speaker 1: Womp womp. Womp womp.
Speaker 0: And look how close the food is. Boom. Game over. So it can can we do a rematch? Can we get something hopefully a little more vibrant?
Speaker 1: Let's do a rematch.
Speaker 0: Let's see
Speaker 1: what happens here. Yeah. And we'll play it just so that we can see it in real time. And and this way, you can actually see this What
Speaker 0: is going on with our snake? Why is it happening? Our snake actually oh, there's an error with our snake because there was a viable direction there. It was to go right, and it did not. No safe moves detected.
So that makes sense. So why was it no safe moves? So we have it set that it's not going to go is
Speaker 1: that it's not gonna go no. Because he's been going up there. So she should just
Speaker 0: the final move? He should have gone right.
Speaker 1: Yeah. He should have gone right or
Speaker 0: he should
Speaker 1: have gone wrong. Loop.
Speaker 0: So our logic is wrong. Let's take a look at that. But but and right was the only move. It couldn't go up based on our heuristics. Even though, in theory, to avoid our body, we can remove the tails.
We can remove the final piece.
Speaker 1: But what's interesting is he was doing that. Like, if you look at this, so he was here and he was going here. So, technically, when he was in this spot, he could have actually done this again. Right? Oh, yes.
So he could have gone up or he could have gone right. Of course. Interesting. Okay. But let's go to our code and see why that didn't so why did
Speaker 0: you decide? It's because
Speaker 1: of the other snake. So it is it does have something to do with the fact that he was right next to a snake, and so he didn't think
Speaker 0: what about oh, no. No. It's right. My head is still correct. And we wanna be checking the piece of every snake.
Speaker 1: P sex minus 1, p sex plus 1. Yes. That's right. I feel like it's because we do actually need to bring this logic inside because we're running these this and then we're running through this loop.
Speaker 0: It shouldn't make a difference, though. So? If it's set force once, it's we never set anything's true. We're never undoing the work we did. We're just kind of repeating it.
You know? Yep. Okay. So I guess my
Speaker 1: head is in there. We don't need the my body anymore. We're not referencing my body anymore.
Speaker 0: Sninks does include us. Right?
Speaker 1: Yeah. Well, let's let's figure that out.
Speaker 0: I think Let's I think it does. I think you is the name of the the object as a convenience.
Speaker 1: Snakes snake squad. No. That's not important to us.
Speaker 0: No. That's the snake squad.
Speaker 1: That and then board. So, yeah, you are getting snake 1, snake 2, snake 3.
Speaker 0: Can we see the description? Snakes. All snakes on the game board, including yourself if you have not been eliminated.
Speaker 1: Yep. So it should be working. You're right.
Speaker 0: So what is going on here?
Speaker 1: So for snake of snakes, that's good.
Speaker 0: Again, people watch it people watching this on director's TV are gonna be like, god. It's so obvious. This is the thing.
Speaker 1: Well, let's hold on. Let's remove some some let's comment out some
Speaker 0: I mean, sure. Sure. But, I mean, that's literally gonna
Speaker 1: matter for anything. But okay. So if my head and let's go back to our let's go back to our sheet, drive.
Speaker 0: 94% of storage used?
Speaker 1: Yeah. I should probably, go in here and, you
Speaker 0: know Oh, not pay not pay more for it. Just act stuff. Yeah. That that's the other solution.
Speaker 1: Okay. So let's say we have let's let's actually reimagine the board state that we were in
Speaker 0: I love that. Fine. What one step back? I if it's playing, what's going on here? Oh.
And we just need to go one step back. We're at the end of the game.
Speaker 1: Okay. There we go. Alright. So let's bring this to we will actually bring this to a 10 by 10 board. And let's pull this over.
Speaker 0: No. No. No. No. No.
We we don't need the whole board. We only need, like, however wide. We only need, like, the cluster around around what we're doing. We we don't need to recreate the whole board.
Speaker 1: Alright. So let's go
Speaker 0: Hang on. I'll, on my side, I'll take a little a little cheeky screenshot, and I can I can call that out for you
Speaker 1: if you want? K.
Speaker 0: If you if you head if you head back.
Speaker 1: Go back to the game. There we go.
Speaker 0: Okay. So here's what we're doing. Let's go to our sheet. So we only need 1 like, we we can do it all within here, basically. So put our snake on, a 1b 1, a 2, and b 2.
The head is b 2. And then, that that snake's gonna go, a 3. There. Yes. One more to the left.
We can stop there. The rest is irrelevant. So that's that's what the snake is doing. And so first thing we're doing is we're avoiding ourselves. So we're saying can't go left.
We can't go. The thing that's got me is why is it going right? That is I'm sorry. Why isn't it going right when that is a legal option? Yep.
That's the question. The right logic is bust.
Speaker 1: Okay. So let's look let's pull this side by side. Let's grab this over here and let's go get this over here in our logic and see if we can make sure that our logic addresses this situation. Alright. So let's go here.
Okay. So yeah, our first code here, my head, y.
Speaker 0: Yeah.
Speaker 1: So my head, y, is currently at
Speaker 0: On on b. Sure. Yeah. Right. On on 1.
If it's 0 indexed in the bottom left. Yep. So we're both on 1. Sure. And the x, there is a piece one step down.
Correct. Oh, hang on a moment. I think we've got our things muddled here. If my head y, but x is my so now that's correct. So that that accounts for a 2.
Left is no longer viable. Yep. Going down 1, it's the same. We're on the same column, but right, this one is what's got me, but the piece dot x plus 1, but that is not the case. It's an it's an and statement.
So, you know, both those things have to be true for it to be met. So if y is the same, but the my head dot x equals piece dot x plus 1, then it's on the right, but it isn't. I don't know what's going on here. My head okay.
Speaker 1: Well, hold on. So this technically, these are x aligned, but they're y they're not equal for y.
Speaker 0: They're they're they're y's match. They're wise match. They're on the same column. That means they're the same do you think I've just got the accent? No.
Speaker 1: No. No. I think that my I'm trying to work this out in my head. So this is
Speaker 0: Call that x1 or x. No. No. That's yes. Yes.
No. You're right. You're right. You're right. You're right.
Sorry. Yes. Oh, sorry. X1, x2, x3, x4, x5. Yeah.
Y1y2y3y4.
Speaker 1: Yeah. So right now these are the same x, but they're different y's.
Speaker 0: Well, the yeah. So if we hang on. Let's let's start at the top. So let's do the left first. So the x matches.
We've got them flipped, Andrew. We flipped them.
Speaker 1: Did we? Yeah. Okay.
Speaker 0: Look, the y is the if the y is the same no, we haven't. We got it right. So if the y is the same, let's say let's take, b 2 and c 2. Right? Yep.
The y is the same. Yep. So that they they exist in the same yeah. But the x is minus 1. That means underneath.
No. That means To the to the left. Something on the left. Fine. Then y is the same once again.
They're in the same row.
Speaker 1: Are you
Speaker 0: sure we haven't flipped them?
Speaker 1: I I think we might have hold on. So okay. My head y, my piece and piece y are equal. So yeah. You're right.
These 2 are technically there, and then my head x, so this is my head x, piece x minus 1. So, yeah, this removes left. That that totally makes sense. So we're good there. So next up, my head y equals piece y.
Okay. Well, what would apply here, I guess? What would apply to this one right here?
Speaker 0: It would have to be on the right. I think we got it right. I don't know what's going wrong.
Speaker 1: My head x. Okay. So right now, this is they are the same for these are the same for x. So my head equals piece x. My head y equals piece y minus 1.
Down is false. Yes. That that's right. That's good. My
Speaker 0: head pieces We flipped them. We flipped them. And what's getting me is the 1 on 1 on line 107. So my head dot x means they are in the same it means they're in the same row.
Speaker 1: Yes. It means
Speaker 0: so it means they're in the same column. It means they're in the same column. Yeah. Right? They're in the same column, but the y piece is minus 1.
They're in the same column, but the but the y is is 1 to the left. They're in the same column, but the y I I'm struggling to visualize that based on our head. They're on the same Okay. Hold on. So my head ached I think we've, I think we've muddled these.
I think I think, yeah, these are wrong. And I know we we know this and the audience like, yeah, it's wrong. And here's exactly how, But, I don't think it's as simple as comparing the y's and then comparing the x's. I think only one piece wants to be I think the Right. So can you just put, like, an a in d two for us?
So we're we're gonna test no. No. No. A d 2. So so so so we're gonna test h versus a.
Right? So the y is the same. The the y the y is the same. The x is plus 1. The the y is the same and the x is plus 1.
Yeah. Right gets removed.
Speaker 1: So right yeah. Right should definitely
Speaker 0: So but at least one of these is wrong because we're removing too many options. Yep. If if x is the same, so they're in the same column
Speaker 1: So let's say y here. So these guys are in the same column.
Speaker 0: But the y is minus 1.
Speaker 1: Then we're gonna get that here.
Speaker 0: Fine. Then the y's are the same, the x is plus 1, then we're going right. Dude, this looks correct to me.
Speaker 1: It does
Speaker 0: I don't know what's going on.
Speaker 1: I okay. So I feel like this we've worked through this. I do think it must have something to do with this logic then. Have we screwed something up here? No.
Speaker 0: I don't think so.
Speaker 1: If my head equals 0, head x equals 0.
Speaker 0: It's anywhere in that line. You can't go left. If it's at the board if y is at the height, you can't go up.
Speaker 1: So here, this was at the height minus 1. So wait. What is height returning? Am I wrong? Have we changed the rules, and is height actually returning the height of the board and not 11?
Oh, no. No. Returns 11. Oh. Oh.
Wait. No. That
Speaker 0: No. That's correct.
Speaker 1: That's correct.
Speaker 0: Board width minus 1.
Speaker 1: Yeah. So that's that's fine. That would be the one that would have mattered that it would have removed the right, and that logic makes sense.
Speaker 0: Yeah.
Speaker 1: It's not there. Yeah. This logic is all correct. Let's run another game and see.
Speaker 0: We are. I am full on at the point where I'm just gonna find a snake because I know I know it's less fun. I know it's less fun, but I just, but I also I also don't don't fancy doing this forever. Let's take a look.
Speaker 1: K. I wanna see how this game plays out if something similar happens. K. Why did you run into his head? Why was that a safe move?
Okay. What was the logic there? Did you have no safe moves again? No. So here, he thought he could go right.
So oh, no. Because there. Okay. That makes sense. That tracks because he wasn't directly next.
So there's no look ahead right now. So this takes
Speaker 0: So that's so so that'll happen sometimes.
Speaker 1: Yeah. So that tracks. That that game worked the way it should have. There's no buggy things there. It worked the way it should.
Let's see if we can get another game because I feel like maybe that is it. Like, our code is right and there was just some sort of a glitch, but I don't know. K. So he's going in the circle. He's going in the circle.
So he's gonna starve out anyways. We're not gonna get to see much there. Anyone? That's so weird. Can we can we
Speaker 0: run it again and again and again?
Speaker 1: So he's not making the same mistake again? I don't
Speaker 0: I don't like that it's just doing that. That feel it feels weird to me that it keeps chicken whatever you call it. Chicken Chicken snaking? Chicken snaking. That feels very odd to me that it does that consistently.
Speaker 1: Okay. So he's not doing this
Speaker 0: as well. It isn't. Okay. Fine.
Speaker 1: Okay. And, again, so this ish situation, was that a safe move? So he's gotta finish the game.
Speaker 0: Come on. Come on. Go back.
Speaker 1: Okay. So this does that make sense? Yeah. Again, this one makes sense because he didn't see right? So every one of these games, it's just the one game that was the one that was very strange.
I think that there was some sort of a there was some sort of a an issue there with the actual way that it was reading our logic. I I hate seeing bugs that don't get resolved, but it seems like it's not happening again.
Speaker 0: It seems to have been okay since.
Speaker 1: Yeah. Well, let's try again. Maybe Okay. So why did he do that? So he shouldn't have done that either.
Okay. So here's the thing. So why did he do that? So right. Right.
Right. Game over. So he should not have gone right there. Why did he go right? Why did he think right
Speaker 0: Something's wrong. Was a safe move.
Speaker 1: Okay. So let's look at this again. And we're gonna have these guys here. So let's go, I'm actually gonna do color with these this time because I feel like that will actually help us. And then we'll do here and then we'll do him gray green
Speaker 0: and gray, green, green, green. That's all. I'm literally this is driving me potty.
Speaker 1: It's alright. This is the joy. I and, we'll fix it in post. Right?
Speaker 0: Yeah. We'll fix it. We'll fix it in post. Okay. Okay.
Do do do do you want them to know what lovely editor, Nat? Let's jump cut here to the point where we fix it, and then we'll explain what went wrong.
Speaker 1: Yeah.
Speaker 0: Welcome. Welcome back. We worked it out. Andrew did a lot more like debugging, adding print statements. Andrew, do you want to show the code?
And for those of you who are, let's zoom in like many, many, many times over, what was the issue? I'm yeah. But but what was the issue?
Speaker 1: So the issue was we had things flipped with the Yes.
Speaker 0: We did.
Speaker 1: Actual thing that we were removing. And the way that we discovered that, and this is kind of an interesting way to do it. I actually, like, find this as a really good way to do any debugging
Speaker 0: because I
Speaker 1: threw a console log into each one of these pieces with whatever we had been removing. So, initially, we so let's, like, put this back to what it was before. Originally, this was is moved left, right, down Down
Speaker 0: down and up.
Speaker 1: Yep. And so, originally, we had this. And so I wanted to look here and see where, where we sort of messed up here. And so if you look sort of in this log so, and I think this is the latest game. Is it the latest game?
Speaker 0: No. We ran it once more since. We ran it
Speaker 1: once more since. Did he did he go out for the same reason? That's my question.
Speaker 0: Let's find out.
Speaker 1: Oh, no. Because this was what he was buying correctly. So Yeah. Did I see
Speaker 0: But but but but but we we we don't necessarily need to find it or or replicate it. But, yeah, you you basically post it in a in the state just before you died, just before it died. Yeah. And then where and then did kind of what we did with the spreadsheet again. And, basically, we had it flipped.
So up and down needed to flip, left and right needed to flip. And then our snake has also been a lot more interesting as a result.
Speaker 1: Yeah. So technically, like, even with bad code, it worked.
Speaker 0: Change it back. Change change it back now before
Speaker 1: Yeah. Before we forget. So let's go and I'll actually go in here, and I'll remove these console logs because they're false now. Let's go right. Mhmm.
And remove this one and left. And and I feel like this is kind of the fun of this game is it's like you orienting yourself is also, like, I think it's part of the challenge here. But now, you'll see here so, like, well, in that last game, he didn't follow the rules like we thought he was going to. Now he, she, they, if we go back in here and create a rematch, we're going to see that, like Kevin said, this game is far, far more interesting now. And so here so now he's not constantly going in that loop.
He's not running into these other snakes. And there we go. Now we're starting to get
Speaker 0: some wins. Yes. Now I think that might be where we call this snake because the reality is this snake's doing pretty well. For the extent of our series, we don't need to do much. However, there are some other end statements here.
Did our snake die or did no. No.
Speaker 1: No. No. No. That was good. Nope.
We did the right thing. He he just did head to head.
Speaker 0: So head to head is the other thing to consider. If you collide with a snake head to head in any configuration, right, if you both enter the same square, the snake with the lowest to health, I think. Right? Yeah. Or the shortest snake?
Speaker 1: Yeah.
Speaker 0: No. Which one? I just gave you 2 options. Oh, sorry. Shortest so it's it's
Speaker 1: the snake snake with the it's the snake with the lowest health, I believe. No. Wait. Hold on. Let's talk a little bit.
The shortest snake. Always consult the docs whenever you're not sure.
Speaker 0: And so and so what you will need to do then is also look around the heads of each snake and have an exclusion zone of one one valid direction in any way they can go. You can also remove the tail as well because next move, the tail is gonna have moved out of place. So these are the little bits of logic you can do. The longer Longer about the snake
Speaker 1: will survive. Shorter will be eliminated. If they're both the same length, they both die.
Speaker 0: Fine. Fine. So there is more logic we can add to this, Nate. But the reality is it's gonna perform pretty well. Apart from head to heads, it should perform or running out of food legitimately because it currently is just hitting food randomly.
It should perform pretty well. Good enough for ready set battlesnake. But, yes, in reality, you'd also have an exclusion zone around heads, and you would be able to take the last item of each snake body and remove that from your from your checks because it's going to move out of the tail space. Or rather, the tail will not be in that space anymore. So you can stop.
Ahead might be, but the tail won't be. Sick. Okay. Ready, set, battle snake episode 1. I think the last thing I'd love to do before we just say bye and and stop recording, shall we just do a little bit of cleanup on this on this, file from the top to the bottom, make it feel good, and then we can wrap up.
And next episode, we will take this snake and see if we can run it inside of a director's project.
Speaker 1: Amazing. Alright. So, yeah, let's clean this up. Let's leave those comments in there because I think they're great. Let's leave that step 4 in there as well.
So let's go up here. Now we do need to add a couple of things. So let's do, let's call this Directus TV as our author. And we're going to leave our stuff until next week, I think
Speaker 0: -I think so. -
Speaker 1: for our default. But, we've got that in there. This is all good. This is all good. Do we wanna leave this or do we wanna move this inside?
What do we wanna do, Kevin? What do you think?
Speaker 0: What do you mean inside?
Speaker 1: Like, do we wanna deal with moving this logic for the head and neck inside of our inside of our other logic?
Speaker 0: You can straight up remove it. Leave the variables at the top because my head and my neck might are used. My head is used. My neck is not used. We can remove those.
They're they're captured in the other logic.
Speaker 1: Yep. You're absolutely right. Yeah. Okay. So we can remove and we can remove my neck because we don't need that anymore.
And This is all good. I actually think we should put all of these together. Is there a reason that we should have our board width and height as let and our my head is const, or should we just have them all the same? I feel like they should all
Speaker 0: the same. It literally makes no difference. Like, in reality, I would make them all cons because we don't reassign them. And I think inside of the 4 loops, you can also use const instead of let, if memory serves me right.
Speaker 1: I feel like there's probably a way to select all of the lets in here.
Speaker 0: Command d. Command d. Or control control d. Control
Speaker 1: d. There we go. Let's call these all const. There we go.
Speaker 0: Lovely. And the reality is we're still being overly verbose here. Like, line 79 could just be put inside of line 81. Like, we don't we don't need to be declaring all these variables, but I think this is fine. We're gonna move it over next time.
I think we said we're gonna we're gonna try using direct automate to make this work, which I'm really excited about. There are some interesting quirks. I'm not sure I've quite figured out yet. We have a a pressure based rate limiter that I think we might hit, so we'll we'll have to explore that. But we'll we'll see.
Speaker 1: Yeah. But I think that's I think that's everything. I think we've pulled out any unnecessary variables in here. I think this is looking pretty pretty good right now.
Speaker 0: Sounds good. Great. Hit Save, and let's let's wrap up. I think this was a really nice first episode. Very happy we cut that that bit in the middle of working out what we were doing wrong.
So thank you so much for joining us for the first episode of Ready, Set, Battlesnake. We won't see you next week. This is every 2 weeks. So if you are watching at the time it's coming out and not binge watching at the end, you will find the next episode right here on DIRECTV in 2 weeks' time. I've been Kevin.
I've been Andrew. There we go. And until next time, you ready for the catchphrase?
Speaker 1: Ready. Set Battle Snake. We'll get there. We've got 4 episodes.
Speaker 0: We've got 4 episodes. Bye. Bye.