with Joe Nash
Remember the old Nokia phone snake game? In this episode, Joe Nash will introduce us to an evolution of the game, Battlesnake, where we code our own snake and see how far we can go!
Resources & Links
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everyone, and welcome to another episode of Learn With Jason. Today on the show, we've got Joe Nash. Joe, so good to have you. How are you doing?
JOE: I'm wonderful. Thank you so much for having me. I've been excited about this all week. Oh, God. Can't wait.
JASON: For folx who aren't familiar with you, do you want to give us a little bit of a background on yourself.
JOE: Yeah, sure thing. I'm a develop educator at Twilio. Prior to that helping others at GitHub and a consultant on my own. I developed a weird little program called Battlesnake, which I'm excited to talk to you about. Nonprogramming wise, I carve spoons. That's my current thing.
JASON: That was, like, you can't just casually drop that in and not volunteer more information. So, like, you just get a block of wood and you make a spoon out of it?
JOE: Yeah, you get a log and guide it with a knife. If you've been spending this current period being I want a hobby that's not a computer but fall into the trap of buying loads of hobby equipment. Carving, really easy. You just need a knife and a block of wood. Very cheap to get into it.
JASON: I love it. I love it. Well, great. I saw right before we started, Prince, you have subbed now for 10 months. Thank you so much. I appreciate it so much.
JOE: Very exciting.
JASON: Okay. So, let's talk a little bit about Battlesnake. So, I mentioned, you know, we're going to be doing some code. It's a game.
JASON: But that's, honestly, as much as I understand about it.
JOE: That's perfect.
JASON: Could you give us a bit of a background. What is Battlesnake? How does it work?
JOE: Well, first of all, I'm really assured you mentioned the Nokia Snake game. That's how I used to intro it. I realized last time I was streaming for Battlesnake, that's probably a really old person way to look at it. So, I'm glad you said it.
JASON: I've crossed the generational gap now where, like, I forget that there are people who actively work in tech who have never existed without cell phones.
JOE: Yeah, yeah.
JASON: And, you know, I remember being very, like, I got my Nokia brick, and I remember that I'm gonna say so many things to date me right now. Carson Daly was on Total Request Live every day talking about how cool text messaging was. I was like this is the worst idea in the world. No one will ever do this.
JOE: And now here we are.
JASON: Turns out I'm not much of a futurist.
JOE: Well, we're operating on the same level. So, that's great. Battlesnake, if you are not aware of this Nokia thing we're talking about, it is a game you have a little snake, moves around a 2D grid. Eats a food. That is the base game, the one people are familiar with. Battlesnake mixes that up by making it multiplayer. So, there are multiple snakes on the grid. A bigger snake can eat a smaller snake. If you are the smallest snake on the board, you are in danger. You want to eat food to get big. There are various other ways to get eliminated. The extra catch is it's controlled by programming. You're writing the AI for this snake. That's what we're going to be starting off with today. So, the basic idea of this game it sits at the intersection of a couple of really fun things, you know, which is a way to learn code in a really friendly way because, like, you mentioned a little bit not the game dev part of it. As we get into it, you'll see it starts with real programming fundamentals. It's a real fun way to learn. In particular, one of the things I really like about it doesn't so much use the game dev stuff. It uses a lot of, like, classic algorithmic thinking that, you know, the only place you ever really see it in our industry is terrifying white board interviews.
JASON: Great. This is making me feel so much better.
JOE: I'm bringing it up in in that context. That the only place we see it. We have all these horrible association with these really fun bits of programming. This is a really fun and friendly way to encounter these things without necessarily realizing you're doing it at first. That's kind of why I fell in love with it. I actually encountered it kind of backwards. I encountered it as an event that I sponsored. I had been doing hackathon for a really long time. And I showed up at this event and I was just like, oh, wow, this is, like, totally different vibe to anything that I've participated in. It gets into some really interesting, like, parts of programming. It's really sorry, I mentioned it has some intersections. I'm all over the place. The other intersection is ESports because it's very viewable and watchable. You go to a hackathon and do group programming, you get the demos at the end. Unless you're participating, it's hard to get much from the experience. Battlesnake is entertaining. Watching people, like, come together and play games with their snakes is really enjoyable and really especially when one of the things I do for Battlesnake is, like, comment on the game. So, if you ever watched any, like, any ESport basically, if you've watched any live game play of any game, you get the casters talking over the game. That's basically how we broadcast Battlesnake. We'll talk over the game. Our theory why the snake is doing X, Y and Z. It's a great way to run the program. And it's also, you know, a really shareable thing where it's like, hey, I learned to program. Look at this really fun game where my snake kicks someone's tail, I guess. It's really contagious in that way. That's why I think it's going to be fun today. It's really easy to get started with. Yeah, go ahead.
JASON: So, quick question. So, when we're building these, we have so, I'm programming my own snake.
JASON: Which I would then put into a game against somebody else's snake?
JASON: And does that mean that if I if I have my snake and they have their snake and neither of us makes changes, we'll play the same game every time, if we go headtohead or is it, like
JOE: Oh, God, so many great questions here. Okay. Let me start by talking briefly about how it works, like
JASON: Okay, yes.
JASON: Nice nice.
JOE: You can enroll it in that. When you said same snakes, same game. There is a little bit of randomness to it. When you start a game, your start position is random. Where the snakes start is random. Some randomness to where the food is placed. When the food spawns in is another element. Two games of the same snake aren't necessarily going to be the same. Your snake will make a decision every time it plays as well. I think I hit everything. You hit on a lot of stuff.
JASON: Yeah, no, I like that. I wasn't really accounting for the fact that food could be randomly generated on the board. So, that does make it interesting.
JOE: Oh, Penelope's in chat.
JASON: Penelope like, after Penelope made the snake in Bash, does that earn you a nickname in the Battlesnake community?
JOE: Well, so Penelope made that for one of the Battlesnake shows, Coding Badly, and we haven't shown that yet, but Penelope has been kicking butt with a snake built in Rust called "does this work LOL," which Penelope built on the streams for the summer league. Penelope is actually unironically doing well with a good snake. On the side, they've built this absolute clownfest, which we will eventually get you on to the show to do, Penelope.
JASON: Absolute clownfest. I love it.
JOE: The annoying thing is I'm sure the bad snake is probably actually gonna be good as well. Just the way Penelope rolls. Yeah, we'll get to that.
JASON: I'm just imagining I'm picturing this you remember the movie "Big Hero 6" where people are sitting around doing robot fights. I'm picturing Penelope coming up and the announcer says, "and now we have Snake Basher," a really hardcore name.
JOE: That is a fantastic name. Penelope, we're stealing that name. Yeah, like, if you ever, like, I don't know, I grew up in, like, rural England. So, you know, these robotic competitions, like First Robotics or whatever were not really accessible to me. If you looked at that in big hero 6 and wished you could get in on it. This is your chance.
JASON: Live your dreams. At this point, I feel like I have more questions, but it might be easier to show than tell here.
JOE: Show some games.
JASON: Let me switch over to pair programming view.
JOE: One disclaimer I have to quickly make before we do this. I mentioned we cast these games. When we cast them, they are slower than what we are going to be seeing. These are games at full speed. No, we'll watch them and then talk about them.
JASON: Okay. Okay. So, before we start doing that, let me do a couple little bits of housekeeping here. First and foremost, this show, like all shows is being live captioned.
. We've got Jordan from White Coat Captioning here today helping make this show more accessible to more people. You can go watch that right on the homepage of the site. That is true of every episode. You can always head over to learnwithjason.dev to watch the show with captions. The captions are made possible by our sponsors. We've got Netlify, Fauna, Auth0 and Hasura making this possible. While you are clicking things on the internet, you can go and follow Joe on Twitter.�@ you pronounce that with a pause. JOE: J_Nash.
JASON: We are today playing Battlesnake. So, this well done. Well done. But that's at Battlesnake.com you can find that. So, this is as much as I know. Like we can see this I see what appears to be a fourplayer Battlesnake going right now.
JOE: Yeah. Yeah. So, there's I don't know what gamer that is. There is always a game playing on the front page. Let's go to one of the arenas. I mentioned it's perpetually playing arenas. In the top bar, you'll see global arenas. Click on that. So, this is the global arena. This is always running. Once you enter a snake in this, it just goes forever, and you can see they've got a score. If you've played any kind of online game, you'll see the advancement between bronze, silver, gold, platinum and elite I guess is the purple one. So, they earn points. Snakes have a variety of things going on here. So, we've got some tags. Tags are things that users can add to their snakes that tells us a little bit about what their snakes are. So, there's tags for the technologies. There's tags for the strategies. There's tags for the cloud host. One of the really fun things about Battlesnake, some programming games have a ceiling where they start to become solved. Battlesnake has lots of dimensions where you can push things. Once you're comfortable in one area, you can move on to something more advanced. Battlesnake has a latency limit. You have to send a response within a given amount of milliseconds. That means on the high end of competition, you go from how smart is my snake to I need to get, like, a little bit of extra time to do, like, an extra layer of my graph search, kind of thing. So, where you host it becomes really important and you see some really wild setups. We have our tags like hungry. So, you know, that kind of indicates the snake's going for food a lot. Aggressive. It's going for eliminations. All kinds of stuff like this. You'll see the snakes are kind of customized. You can dress up your snake. That's, again, done by the API with lots of weird funny heads. So, yeah, this is kind of where we're at. Let's grab let's grab Hungry Caterpillar. That's a nice snake. The green text, if you click on "view that replay," that takes us over to the games. This is the game screen. Scroll down a little bit. Maybe zoom out a touch. Yeah, there we go. Perfect. So, before we click play on this, just to explain some of what we're seeing. Obviously, snakes are on the board. This is the first area of the randomness I mentioned. Those starting positions are random. They are always, you know, in the second from last row or column, so they're always around the outside. And every snake has a piece of food near them, but then there is also a piece of food in the middle. That's very important. Because as I mentioned, size is important in Battlesnake. So, the way that size works is if you if your snake head collides with any snake body part, including your own. So, if you hit a snake tail or neck, as we call it, any part of a snake, you your snake will be eliminated. So, you can't hit a body part. You have to avoid your own body and bodies of others. If you hit a head, if you are the bigger snake, you eliminate that snake and you survive. If you are both the same size, you both get eliminated. The smaller snake loses. The other way you can be eliminated is by hitting a wall. Go through a wall and come out the other side. We don't have that. If you hit a wall, you're out. And the final way is by starving. So, you'll see there's these colored bars under each of the snake names. That's the health bar. It starts at 100. Every turn, it ticks down by 1. When a snake eats a food, it fills back up to 100. So, the minute you eat even if you are on 1 health, if you eat 1 food, you're back to full health and your length increases by 1. The number on the side says 3. That's the current length. The snakes start coiled up. You only see one body part. Every time you eat food, that grows by 1. So, that was a lot of info. Does that make sense? Viewers, does that make sense? Jason, does that make sense?
JASON: I'm following as much as I can without actually watching, I think.
JOE: Hit play and they'll go at it. A little play button. And it will be fast. So, you can see
JASON: Wow, look at it go.
JOE: These are very passive snakes. No one's gone for any eliminations. That's getting really hairy for ShaiHulud. Got stuck in A corner. Which is not uncommon. A pain we'll come to be very familiar with by the end of the stream. This is a long game. That was really cool. If you just hit the left arrow on your keyboard, that should back us up a step.
JASON: Oh, this is cool. Okay.
JOE: So, keep backing up. Okay, there we go. Hit space from about here. So, watch Hungry Caterpillar here. So, Hungry Caterpillar gets the size advantage and then just goes on a killing spree. They've got the size advantage over the others. They got to 16. The other two are at 15. Yo if you see on the size, you see the way they lost. Lost to a headtohead. This is a really common way these things go. The games will play out and they'll kind of be like trying to stay equal size parity playing defensively and then one snake will switch to kill mode. Straight away, Hungry Caterpillar mopped up.
JASON: You know what I love about this? As we were watching this, you did sound like an analyst. Like the expert on all this that would happen as a voiceover in ESports or sports match.
JOE: My role on the analyst team is, like, the one who reads far too much in every snake. I'm always like, I think the snake is doing this. Turns out it's a completely random move.
JASON: I would be if I were to do this, I would be the one that was more, like, you know, John Madden. Look at that snake. He looks hungry. Football is a sport.
JOE: This is getting too in the weeds. I'm the newest addition to the casting team. They had been doing it for years. My original role on the team is I'm here to ask the dumb questions, make them explain stuff. So, I was pretty much doing that. So, that's a very highlevel game. Let's go watch one that is probably going to be operating a little bit closer to where we are. Right down to the bottom. Let's go hang out in Bronze League.
JOE: You can hit that. I didn't know that was a thing. Let's watch one that is customized to make sure it's actually working. Let's go to that Python one. That's got a lot of tags. Let's go with that. So, when you are matched in games, you are matched in kind of, like, you know, against snakes of a similar level. Yeah, click "view replay" on that one.
JASON: Which one?
JOE: Any one. Cool. There we go. Hit "play" and see what happens. There we go. Okay. Very different game.
JASON: Went very fast.
JOE: Yeah. There's a couple of reasons for that. Interesting thing here. So, you see under the length number I don't know why I'm pointing at my screen, like that means anything to anyone. Under the length number, there is a smaller number on these things. That's the latency. That's how fast it returned a response. The reason this game went so fast, and this is common in the lower brackets, is timeouts. The reason this is common so, that red 0 basically means the snake didn't return a move in the time. And so when your snake doesn't return a move, it just moves in the direction it's currently going, basically.
JOE: The reason this is common in the lower brackets is because a lot of, you know, when you're playing Battlesnake, you can play with any host you want. An ngrok to it. Any free cloud plan anywhere. A lot of the free cloud plans take some type to spin up when you hit them. These snakes often end up in this situation, when you start a game, they're actually not awake. This is probably what happened with this one or it was a test snake and someone shut it down.
JASON: All right. I get it.
JOE: One last thing to look at before we jump in. I mentioned different game modes. Royale is fun. If you played a Battle Royale game like Fortnite or Apex Legends, something like that. This is it. There is hazard sauce, which is the cloud and it closes in. Whenever you're in the source, you take extra damage. If you scroll down a little bit, Penelope, where is Does It Work LOL. There it is. Let's take that top one.
JASON: 184 turns. Oh, my goodness.
JOE: We got Smart Caterpillar as well. The one we just watched. They'll be playing. Here comes the hazard sauce. Whenever they're in the hazard sauce, they lose additional food. So, now they're not only, you know, competing as each other and trying to stay alive, trying not to get eaten, they're also looking to stay out of the hazard sauce. Penelope, this is the first time I've seen Does This Work LOL since summer league. Interesting thing here, we're not going to be doing anything this clever today. You'll see the Does It Work name it's got mcts. When I said, you know, this is a fun place where you get to see some cool algorithms that you only otherwise see in white board tests, this is an example of them. Towards the upper end of play, algorithms like Min maps, that kind of thing. I've never encountered Monte Carlo as, like, except in a CS, you know, except in my degree, ever. And then it's like, oh, cool, there's a bunch of people who know an intense amount of this silly snake game.
JASON: That's a word I just learned today.
JOE: We're not going to be going there. It's all good.
JASON: I expect to be more of one of the just setting expectations for the chat, I'm gonna be the one that runs immediately into the wall. Just everyone get ready.
JOE: We're gonna being doing what brad, the founder of Battlesnake, calls eliminationdriven development. Where we see how our snake dies and then we fix that problem. We're going to go at it with "if" statements. That is how all my snakes work, and that is what we're going to be doing today.
JASON: Nice, nice.
JOE: Penelope's bragging into chat. Happily moved into the hazard sauce because it knew it was winning.
JASON: Something really delightful just happened for me, which is when you said hazard sauce with your accent, I thought you were saying hazard source. This is much funnier it's called hazard sauce.
JOE: No, sorry.
JASON: No, don't apologize. I enjoyed that muchly. Okay. Now, okay, so, now I just want to go run the snake into a wall here. So, how do I start?
JOE: Okay. So, to start, we're gonna have to grab a snake. We'll grab one of the starter snakes. The ready to go things. And we'll get an ngrok URL set up for it and create a snake in your profile. So, go to docs in the top.
JOE: Yep. And then this is the documentation. Everything is described here. On the left, you will see a actually, right in front of you. Starter projects. So, this is all the starter projects. Some of them are official. Some are maintained by the community. This is it. This is set up as a GitHub template repo.
JOE: You can just use the template. I don't does it have command lines to support the templates?
JASON: I guess I can use a template. I've never actually done it that way. Let's try it. I'm gonna use this template.
JOE: I haven't used it
JASON: Move it over to Learn With Jason. Cool. Should I name it something different? Is there a convention for this?
JOE: There isn't. We have kind of encoding we have settled on calling our snake whatever the random thing is. This is Silver Succotash, which I actually think is quite good.
JASON: Like that?
JOE: Yeah, that's what GitHub said under that, how about Silver Succotash? Your snake is now set on Silver Succotash. Our last one was Agitated Hoover.
JASON: Okay. I'm going to create a repository, and then I will just clone that repository instead.
JOE: Correct. Yes.
JASON: So, let's repo clone this one.
JOE: Cool. And then, yeah, let's open this up and have a poke around.
JASON: I should probably run the NPM install here. Okay. So, we have what looks to be a pretty yeah, okay, fine. We'll do that later. Okay. So, I have what looks to be pretty straightforward. So, I have just express. Oh, what's up, Samantha? Good to see you. Thank you for coming over. Thank you for the raid. We're playing Battlesnake. Well, we're about to play Battlesnake. You came at just the right time. So, I've just downloaded the starter project, which is an express server with just for testing. And that's it. So, let's look at here. So, I have I'm gonna make this bigger so we can see it.
JASON: I have our logic, which we'll look at in a second. Set up a basic express app boilerplate. Put it at port 8080.
JOE: And then just four end points.
JASON: Four end points. So, a route, which kind of looks more like a health check, like I'm alive.
JOE: Correct. That's also where you set your snake's metadata. That's where you put the snake's name, snake customizations.
JASON: Got it.
JOE: Then that gets set up when you add your snake.
JASON: Okay. So, we can start the snake.
JOE: Kind of.
JASON: Move the snake. End the snake? No, we wouldn't
JOE: End my snake. So, start is sent at the start of the game. End is sent at the end of the game. We are probably not gonna use these. Mostly, we only need move.
JOE: So, start is, like, it will contain some game info. Start and end are only useful if you're doing stateful snake. So, snakes that are kind of keeping track of, you know, things internally between games. Most of the time, you don't need to do that because you get sent the whole game request. We're probably only going to need move info today. So, this is the snake. Now that we've got this code here, we're gonna want to get the server running and then get a ngrok URL and add it to a Battlesnake profile. Before we do that, let's customize your snake. So, if you scroll back to the top, before we dive into logic too much. In this response block is where you're gonna wanna stick you as the author, and probably a color.
JASON: Okay. And do you is there a format?
JOE: I usually put my GitHub handle, but you can put whatever works for you. Yeah. And just little hex for color.
JASON: Uh, yeah, let's see. Let's grab one from the Learn With Jason site because that's always a good time.
JOE: Be on brand.
JASON: Yeah. Why not, right?
JOE: Oh, hey, Brad.
JASON: And let's see what I can find in colors. Here we go. Here are all my colors on the site. Let's use what's a good snake. Do you want to go light or dark with the snake, do you think?
JOE: Pink dark is nice. I like that.
JASON: Pink dark? All right. We're gonna do a pink dark snake.
JOE: Perfect. And then head and tail, we'll leave for now. We'll have to see that in the doc. So, just kind of quick pokearound logic here. I said we've got start and end. We can ignore those mostly. That's just logging. The way this default snake is set up so, you've got this object of possible moves. And you'll see it's got up, down, left, right set to true. So, basically what this snake does, it's got only very basic behavior. It ensures you're not gonna hit your own body. That's what this block here is doing. So, it's getting the game state. That's coming in the request. It's then finding the head. So, we'll look at the game object in the game set object in the docs. For now, this might be a little abstract. In the game state object, there is one called you. An entry for head and array for all of the body segments. And a body segment is represented by an X and Y coordinate, basically. So, where on grid it is. So, we're grabbing the head, we're grabbing the neck, and this if block here is just making sure that, like, I'm a snake on the board, I'm about to pick my next move. I can go up, down, left or right. Quickly check up, down, left or right and make sure that one of my bodies is not occupying that space. If my body is occupying that space, remove it from the possible moves. Set that move to false. And so that's the basic approach we're gonna take here today. We're going to be in a position. We're going to inspect that position for failure cases. And then we're gonna disable that move, if it's a failure case.
JASON: Got it.
JOE: Get that idea? And then you see the we've got some lovely comments in the starter snake that guide us where we're gonna go.
JASON: Not hit walls. Don't hit yourself. You really should change that to stop hitting yourself. Don't collide with others. Find food.
JOE: Yeah. And then this is when it finally runs the move. So, at the end so, it eliminates moves that are dangerous from that JSON object, and then it just picks random ones. So, you know, if you you know, most of the time, you'll only have one of those moves eliminated because the body segment, your head's attached to. So, there are three moves remaining. It doesn't do anything smart. Just picks one at random. So, yeah, let's run this code. Get it ngrok'd and add a snake to your profile so we can watch how a completely random snake goes.
JASON: Okay. So, I'm going to I guess we can npm start. Okay. So, I have my I have my server.
JOE: Yes. So, then
JASON: If I go and hit this at the route, I should just get the object back. There it is. Okay. So, now I need to ngrok. You're gonna have to remind me how to do this because I just reinstalled it.
JOE: It will just be ngrok http 8080. There you go. And then grab that URL.
JASON: Do I need the https one?
JOE: No, that should do.
JASON: Great. Just got something caught in my throat. This is gonna be fun for everybody.
JOE: Oh, God. So sorry. I'll cover for you. So, yeah cool. Perfect.
JASON: There we go. Okay.
JOE: We go over to Battlesnake.com.
JASON: Fun. Fun times.
JOE: Oh, no. Don't pay attention. Battlesnake.com and then to your profile. So, topright. Click on that. And then click "battlesnakes." Here works. My fault. You're in the right place. The big purple button.
JASON: Oh, it's here.
JOE: So, create new. Call it a name. What was it, Silver Succotash? And you can name it however you want. Put a link to the show.
JASON: Yeah. Okay.
JOE: What are these why are people doing up, right, left and down in the chat?
JASON: Do you see the the little dumpster and submarine that is floating around the screen? They can control those.
JOE: Oh, I do. That's really cool!
JASON: So, they, yeah, move it around.
JOE: Neat. Okay. So, tags. I mean
JASON: This is cool.
JOE: Now your community's just showing off. Are these boops falling?
JASON: Yes. For anyone who is a subscriber, you can use that boop command and drop a bunch of them. Oh, Cassidy's here. We're about to get buried.
JOE: Yeah, we are definitely getting buried. And then hit "save." This is amazing. I'm enjoying this a lot. I'm viewing it via the livestream. Okay. So, that's your snake. So, you will see the latency
JASON: This is the default snake.
JOE: This is the default snake. So, if you want to change that actually, let's play a game first and then we'll come back and, and change that. Thanks, Cassidy. Click "play game." I can still see that oh, this is wonderful. They jiggle as well. So, click the little plus next to your snake, the little purple plus.
JASON: Okay. Over here.
JASON: Then I can start the game.
JASON: Chat, you win, but we're not gonna be able to see if you keep doing it.
JOE: It's okay. Jason can drive. I'll just vaguely mouth. (Laughter) How fast, like, this is really, like
JASON: They clear about it's about 30 seconds for the boops to clear.
JOE: Is this Canvas? Or what.
JASON: It is. I'm using Matter JS. My stream is so overengineered.
JOE: The best kind of stream.
JASON: The whole stream overlay is a website. I run a server in the background that gets the Twitch, like, IRC stuff.
JASON: And turns that into a GraphQL subscription so that I can pull out, like, the CDN link for the emotes and use some filtering and make sure people have privileges to do the more disruptive stuff. And then we can from there, I can, like, respond to it. So, all the overlays are basically responding to realtime GraphQL.
JOE: Browser source and overviews for that part of it?
JASON: Cassidy, I do appreciate you being nice. You're the best.
(Laughter) Okay, so JOE: So, this is your snake. In a game. If you click "play," you'll see how a random snake does.
JASON: Insta dead.
JOE: Six turns. It went for the wall. That's our first objective. Important to note here. This is going to be useful for us later. When you rewind and press play, you're watching the same game. The game happens, all the requests hit the server and we're watching a recording of the events that happened. If you want to queue up a new game, which we will be doing a lot, there is rematch. I think it's on the bottom.
JASON: Rematch. Got it. So, then we can play again.
JOE: So, that's a new game. Oh, that was a good one. Hits his tail. Yeah. So, the code we have right now only stop it is hitting, like
JASON: Immediate segment. Yeah.
JOE: The first neck. While we're looking at those buttons, actually, scroll down drop a little bit. Just a fun little note. There is also you can share a game. You can generate a GIF of the game. You can add to favorites. We have graphs. You can watch your length over time. In this case, you see it plummet off a cliff as you hit your own body. Lots of fun things. Okay. So
JASON: This is fun. All right. Okay. I can see the appeal here. This is this looks like a good time.
JOE: Okay. Let's customize your snake a little bit.
JOE: If you go to profile and click on your little head, floating head.
JASON: Sorry, my profile. I don't know why I'm
JOE: You should see oh, yeah, so, go profile. This is where I try and remember this is. I believe it's profile. And then customizations. And then you see where it says "to see the customizations available to everyone, go here?" So, there is ones that are available for everyone and there are ones that you unlock through play. So, here you go. You just grab a name of one you like and throw it into that JSON object at the top. So, what are we thinking? So, these are the standard heads and tails.
JASON: What do you think, chat? Do some votes. What do you want to see?
JOE: There's a docker whale snake.
JASON: This one is the docker whale.
JOE: Silly. We've got a vote for silly. Silly is good. Team default skin forever. Cassidy's on silly. Most votes for silly so far.
JASON: Okay. So, we make the head is silly. What about the tail?
JOE: Some of these I really don't like some of these tales. Some of them like fat rattle will never not look like a lemon to me.
JASON: That does look like a lemon, doesn't it?
JASON: Curled. Round bum.
JOE: It's actually round bum. That's amazing.
JASON: Two votes. Somebody be the tiebreaker. Two for round bum. We've made a decision.
JOE: When life gives you fat rattlesnake amazing. So, now, I think to make that change happen, if you click Battlesnakes again on your profile, we'll need to quickly refresh that snake. You'll probably need to restart the server. Sorry.
JASON: Because we didn't set any we didn't set any
JASON: Okay. So, now
JOE: And then click refresh on the snake.
JOE: Oh, because you restarted ngrok. The URL was changed. If you click "edit" on the snake, you'll be able to change the URL. The joy of using ngrok. It does get us started really quick. We don't end up messing around with cloud deployment.
JASON: Okay. So, I'm gonna edit. Swap this out.
JOE: This is useful viewing, chat, because I guarantee you'll make the same mistake.
JASON: Look at it go.
JOE: Perfect. Okay. So, are you ready to make sure the snake doesn't hit a wall?
JOE: Okay. So, let's put it in a game and get a game set up so we can just hit that rematch button when we're ready. So, play a game.
JASON: So, play a game.
JASON: Pick the snake. Here we go.
JOE: Start that game.
JASON: All right. And so now just chaos mode. Right into a wall.
JOE: Perfect. Okay. So, let's start with have you still got the docs open in the tab? Let's look at the game object and give you a tour of the game object.
JASON: Do I have the docs open? I sure don't. Let's head over here.
JASON: Why do I have my profile open twice? One profile. One docs.
JOE: If you click API reference on the left, and then scroll down oh, hang on a minute. I might be misleading you. Because I don't know where anything is. Apparently. I need to work out where it is because your browser's a little bit narrower than what I'm used to. Used to having the sidebar.
JASON: Sample move request?
JOE: Yeah, that works. Cool. That's perfect. Okay. So, this is what comes with move. So, a lot of this we can ignore. So, you've got the game object at the top. That's got the game ID, the rule set. We don't care about any of that for now. We're just gonna be building for the standard rule set. Board is the one we care about this. That describes the height and width. Because that is dynamic, that can change. Currently, the default is 11. It gives us an array of all the food objects. Again, we don't care about that. Main thing we want is height and widths. Hazards is an array of positions. When we play Royale is have the snakes is then all of the snakes that are in the game. So, for right now, that's only gonna contain us. We are in this object twice. So, the move object has an array of all the snakes, and then it has the U object. We are in the array of snakes and also in the U object. So, the default starter snake already fetches the U object for us, which is nice. When we look at a snake, we don't care about the ID, we don't care about the name. As you get more into the game, you can do clever things, like looking at which other snakes you're playing against. Oh, I know that snake. I know what kind of thing that snake does. And optimizing for given snakes.
JASON: Oh, okay.
JOE: We're not gonna be doing that nonsense. We just want to know where our body parts are. We've got that array with body.
JASON: Penelope is saying, if name is "Pretzel," run away with fear.
JOE: Yeah, Pretzel is the current frontrunner. Scary snake. Every now and then there is a snake that inspires terror in the leaderboard and Pretzel is certainly that one. So, let's dive into your code and have a look at what comments we currently have.
JASON: Okay. So, we know we're not gonna double back on ourselves. That's good.
JOE: Correct. Yes. So, next, we've got this lovely hit walls. So, it gives us some starter variables to get. So, we get the board width and the board height from the game state. So, it's dynamic. So, the Battlesnake board is just a 2D board, X and Y. And bottomleft is 0. It is 0 indexed. This will trip us up more than once. The bottomleft corner is 00. So
JASON: So, that means that, like, okay, so, looking at the board
JASON: just to step through this a little bit. So, this square is 00.
JASON: Which means that right now at this particular moment, the game object would say my snake is at X3, Y4?
JOE: Correct. Yes. No, hang on. X2.
JASON: Oh, right. 0. 1, 2, 3. X2, Y3.
JOE: So, your head in the in the snake objects, there will be the entry for head. That will be X2, Y3. Important to note. As I said, there are lots of places the data is duplicated in the move object, which at first is unintuitive. So, head is its own field in the object, but then the head is also always the first item in the array. So, the body array is ordered as well.
JASON: Oh, okay.
JOE: So, the 0 element is the head and then it goes backwards down from the tail.
JASON: Gotcha. Okay. Okay. So, effectively, then, what I can do just kind of following along with this sophisticated AI we're creating here. I can say if myHead.y is less than 1
JASON: Then possibleMoves.down is false.
JOE: Yeah, exactly.
JOE: That is how we're gonna do this.
JASON: And if myHead.x less than 1, then possibleMoves.left is false.
JASON: And then we need to do the same thing for the furthest extent. So, if the y is greater than boardHeight greater than or equal to, I guess.
JASON: Then we would do possibleMoves.up?
JOE: Wait, have we got these backwards?
JASON: Y, right?
JOE: If y is less than one 0.
JASON: Am I doing that right? We'll find out very quickly if I'm wrong.
JOE: So, it would be board height we want to be we want to be less wait. We want to be greater than board height minus 2 if we're going for greater than.
JASON: Okay. I did the greater than or equal to, but I can do the triple equals.
JOE: Yes. Yep. Correct.
JASON: Also, I can probably clean these up as well to say, like, make it more explicit.
JOE: If it's equal to 0. Yeah. Yep.
JASON: Okay. So, then that would be right. So this, then
JOE: And then we've got possible moves on yep. That's correct. So, that
JASON: If I run this one, theoretically, it should random around in the middle forever until it hits its own body?
JOE: Yes, theoretically. This is where I'm always
JASON: Npm start.
JOE: Okay. I was saying before we got started I really hoped somebody who knew what they were doing came back seat drove my terrible Battlesnake recommendation. Keep doing that. It's very helpful.
JASON: Do I need to refresh the snake?
JOE: Uh, no. No need to refresh if you are doing changes to info.
JASON: Gotcha. Okay. So, this one shouldn't hit a wall?
JOE: Hopefully. There we go. Doing the thing.
JASON: Look at it go. And then it hit itself.
JOE: Doing well. So, brief tangent. Head on over to in a new tab, head on over to challenges. That challenges in the global arenas. Yeah. So, here it is. A little if you want to learn how to play Battlesnake, hey, should I progress along?
JASON: Oh, nice.
JOE: It's because some of these goals are kind of intertwined. So, there is, like, you know, we've already seen Penelope at the high end with Monte Carlo. There is a long path up to that. The usual route is you avoid walls, you avoid yourself, you avoid other snakes, you find food. Avoiding yourself, you know, there are two ways to start about going that route. There is, you know, you can detect where all your body segments are. Make sure you never go into it. But this problem can also only occur if your snake actually gets long enough for you to hit. If it stays at 3 length, you can't hit your own body. This is, like, a point we get to make a decision now, Jason, which is do we want to go about avoiding ourselves by looking at the whole body array and therefore trying to get really big but avoiding our body? Or should we start looking at food and potentially avoiding food. Do you have a preference the way you'd like to go with this.
JASON: Avoiding food?
JOE: So, this is a very common thing in, like, I guess, like, the first realization Battlesnake players have as they play is it's actually not good to always eat food because then you start running out of space. It gets really complicated. So, you can avoid your own body, but where it gets really tricky is if your body creates a loop you create, like, a space that you can't go into sorry, a space that's big enough for you to go into, it's really hard to navigate out of that loop. So, one of the easy ways to avoid the stage where we're at is to actually avoid eating unless we have to. So, we could start doing these challenges right now by going that kind of route.
JASON: Okay. So, yeah, let's I guess let's try that.
JOE: Okay. So, jump back into your code then. So, to do to avoid the food, let's do it where we are now, because we're kind of not we're doing things a bit weird. So, the this is gonna be the array is gonna be in gamestate.board.food.
JOE: Perfect. And then your comment there is great. Avoid food until we need it. So, we've got this 100 health, right? And we don't really, you know, we want to make sure that we start looking for food when we've still got enough time to find it. It's an 11 by 11 board. We can probably avoid food, I'd say maybe a quarter. So, we can put this whole thing in an "if" statement. Which is based on our health.
JASON: Okay. So, if gamestate.you.health
JOE: Yeah. Health.
JASON: And it's 100.
JOE: Yeah. So, I guess, like, 25, 50, whatever you feel like. Yeah. And then, yeah, kind of same logic as the one we've got here. So, comparing the position of our head to, like, basically looking at the squares well, a little bit different. It's gonna be very similar to the body search. So, gonna be looking at the squares around our head and seeing if they contain food. So, actually, we're probably gonna wanna do this with, like, a filter or something on the food array or some I don't know. It's gonna be an array method on the food, probably.
JASON: Okay. So, food.filter. Let's go with what? Okay. So, let me think about this a little bit. So, if we're looking at if we're looking at the board
JASON: And this is the snake's head
JASON: then what I would want to do is get for each food on the board
JASON: I wanna check if it is within one of these things. So, if the food is here
JASON: I would disable right?
JASON: Okay. So, that doesn't feel like a that doesn't feel like a filter. That feels like a forEach, right?
JOE: Yes. For each food, check if it's in myHead, blah, blah, blah.
JASON: If myHead.x
JOE: Is equal to f.x, I guess.
JASON: F.x minus 1, right?
JOE: Wait. No, other way around. It's going to be myHead.x minus one equal to f.x. Does that make sense?
JASON: I'm gonna have to check right, both? I have to check if it's to the left or to the right.
JASON: We can go, if it's f.x minus one, that means it's to the left. So, that would disable right.
JOE: Oh, I see what you mean. Yes. Yes, absolutely. Yeah.
JASON: And then I can do if f.x plus 1
JOE: Then it's on your left.
JASON: We can go left.
JOE: This is where I got told off by the chat last time. You'll need to check both Y and X in the same conditional, because if you do because on, like, this first one, for example, the X being to your left might mean it's at a diagonal from you if you also don't check the Y at the same point. Equals f.x minus 1 and the Y is the same.
JASON: Oh, I gotcha. MyHead.y equals f.y. All right. Good, good. Do that. And then we can change this one to X.
JOE: American2050 asked a really fascinating question. Wouldn't you need to know the facing of the head? I love this question, because it's something that I do every time I'm watching a game. The directions are fixed. So, it's when the up, left, right, and down is always based on the board's up, left, right, and down. It's not from the position it's not from the direction your head is face.
JASON: Thank goodness for that.
JOE: The direction your snake is facing is only cosmetic. I actually think this would be a fascinating game mode. I want that added as a game mode. The rule set is set to be set relative to your snake's perspective rather than the board perspective. I have not so far succeeded in getting that done.
JASON: Okay. So, why don't you like this? Oh, wait, because it's not a const anymore. It's just a loop. This, theoretically, I'm probably going to starve here because I'm not doing anything to change my positions.
JOE: This whole block is only run until you get 25 health, right?
JASON: Right. But there's no
JOE: After that, hopefully accidentally hit food. Yeah, we might have to intentionally go after food in a bit. So
JASON: Not working.
JOE: Oh, hang on.
JASON: I didn't restart the server is why.
JOE: Okay. That will do it. That's ngrok.
JASON: No, it's not.
JOE: No, it's not. My bad.
JASON: I'm ready. Let's see. Here we go. Don't starve to death, little snake. Oh, I just did oh, I just broke everything.
JOE: Oh, that's fun.
JASON: How did you hit a wall?
JOE: How did it go out? Well, we've got our first problem. Why would we have broken that? Are we
JASON: Seems unlikely that I would have been unable to do that, right? Like I don't ever reset anything to "true."
JASON: Hmm. Hmm.
JOE: Let's check which turn you died on and then check the move log again. I mean, that what we should do is add a console log that shows the to console log the object of possible moves.
JASON: Okay. Yeah, we can do that.
JOE: And this is where here is a common annoyance for Battlesnake developers. Obviously, we're not gonna get that same game state again, when we rematch. We can't replicate this situation. If you are ever playing and run into the situation, there is a tool made in the community where you can download the current game state and send it as requests back to your snake. So, that time it didn't happen. So, maybe it was a fluke. I don't know why it would be a fluke.
JOE: Just keep hitting "rematch" until it happens again. I actually it's a shame we already got rid of the game. Okay. This looks fine. I have a theory why it might have happened, but I think it was too soon into the game. It would possibly have been it was set up. Never mind. Anyway, this looks like this is working.
JASON: Okay. Let's try it again.
JOE: Yeah. You're certainly avoiding food.
JOE: Oh, you were avoiding food. Hmm. So, next time you hit food, let's rewind and have a look what the moves are saying. Okay. You're about to hit 25.
JASON: And now chaos mode. And it's it died.
JASON: Come on. Gimme okay. So, that actually has me wondering I think I did my math wrong.
JOE: Oh, really?
JASON: I think I may have. So, this one said where did it okay. So, we
JOE: So, which term is it? Like 33?
JASON: Go back.
JOE: You can do it with the left arrow as well.
JASON: This is turn 31. And 32, it eats. So, on move
JASON: It goes down. Down is true. So, what the X, Y should have been is we were at, let's see, 0, 1, 2, 3, 4, 5, and this would have been 11. Or I guess 10.
JOE: And the food object would have been
JASON: We're down to this. The food y plus 1 should have been 10.
JASON: Head y would have been 10.
JASON: And the x
JOE: Is the same.
JASON: Would have equalled the same, which means that this should have been marked as false.
JASON: Okay. So, maybe what I need to do is just log a headX let's log the y. And there's only gonna be, like, 10 pieces of the food on the board, right? So, if I log these, it's not gonna spam us?
JOE: No, it should be fine. It depends how successful we are. If we are successful in avoiding food, there shouldn't be any there should be a lot, rather. Oh, I love this. There's Battlesnake people explaining how debugging works to folx in your chat.
JASON: Okay. So, this is this is restarted. Is, we should get the right log.
JOE: It's weird it keeps happening every other game, though. Okay. This is looking good. I wonder if it is only happening when we're in that oh, okay. That was were we less than 25 when that happened?
JASON: I think so. Let's rewind.
JOE: No, it shouldn't have been. It was only turn 50 odd. Yeah, that shouldn't have been a food. Move forward one. Might have had no other moves. Down.
JASON: Could have gone to
JOE: Okay. This is an interesting one to start with.
JASON: Okay. So, this was move 53.
JASON: So, 53 wait, it didn't
JOE: All true. How can it
JASON: Wait, wait, wait, wait, wait. Yeah, so, first and foremost, that is all confusing.
JOE: Hang on. Right shouldn't be false. Down should be false in that position.
JASON: I did something wrong. Right, false. Head equals f.x minus 1.
JOE: But even that's the food logic, it should be here, down should be false because of your head position. Something is broken somewhere else.
JASON: Something is broken somewhere else, and also my logging isn't happening. So, I I thought I stopped and started it. Let's okay. Let's try that again. And then rematch.
JOE: I think health is less than 25. I don't think so. Health less than 25 isn't the wrong way around, right? Our health is less than 25.
JASON: We want the health to be less than 25.
JOE: Penelope said did you save the file?
JASON: Did I save the file? That is a great question. I did! I did save it.
JOE: We're eating food again.
JASON: But we're still not getting it, which means if health
JOE: Can you console.log
JASON: No, we were wrong.
JOE: It is greater than that?
JASON: Yeah, because we only want to avoid it until
JOE: Oh, you're right.
JASON: Oh, okay. Well, that's you know what? That makes me feel better, because just being just being wrong, I'm comfortable with just being wrong.
JOE: Degridle, well done. Very well done. Yeah, this is the amount of silly algebraic logic mistakes.
JASON: Avoiding food.
JOE: Less than 25, should eat food.
JASON: It's eating. Okay. So, it's probably gonna
JOE: Yeah, so this is eventually so, what will happen is it will eventually end up with no possible moves. So, it will just keep going the direction it's going or
JASON: Caught itself in a yeah, okay. Okay. All right.
JOE: Nice. Okay.
JASON: So, that's much better. So, I'm gonna get rid of that console log now that it's working.
JOE: That's probably good enough to pass the avoiding walls challenge.
JASON: Okay. Let's try it. Avoiding walls. Attempt.
(Laughter) JOE: What happened?
JASON: What was that all about? It didn't even wait, did it not even try and reload there? That was interesting. Okay. So, let's stop. Start. Let's try that one more time. That was amazing. It was, like, it was so it wasn't even, like
JASON: Come on, Succotash.
JOE: Off the board. It's doing it again.
JASON: What up, Succotash? What are you doing?
JOE: There is not something coded on 11 somewhere, is there?
JASON: It's not getting requests. Is there any way that it could have
JOE: Is your ngrok still running?
JASON: To the best of my knowledge.
JOE: Yeah, it looks fine. This seems like a Brad problem. Brad, does challenges send requests in a weird way? I can't think it would do.
JASON: Maybe I'll just for just for the sake of making sure that it's actually connecting, let me go and edit the snake. And we'll change this. Save. Okay. Let's try that again.
JOE: There we go.
JASON: That's better. I feel like something happened where it was not actually connecting, like, maybe there's a it said I had 12 connections to that ngrok. So, I'm wondering if I just yeah. Okay. But it did starve to death.
JOE: Yeah, but it made it to turn 100, which I think is fine. So, if you go to challenges now.
JOE: So, just click the challenges bar again.
JASON: Challenges. Completed. Okay.
JOE: Okay. And I think if you hover over "avoid yourself," is that also 100 turns?
JOE: All right. We can give it a go. It might we have died to hitting a couple of times, but
JASON: That does seem to be the thing. Should be add a little logic in there? T we can absolutely check for our bodies. Same for reaching over the body array same as the food array, basically.
JASON: Okay. This feels like something we could probably abstract into a little helper function, but that's not how we roll here, so we're going to copy/paste our ways to success.
JOE: Hundred lines. Have you ever heard the story about super meat boy and, like, the movement logic file? I think a bat just flew into my window. There's, like, some story about the platform of super meat boy and how finetuned the feeling of the movement is. If you run and jump off a platform at this speed and land in this way, like, how they made, like, that work and feel really nice. Apparently there is just, like, a 4,000line file of "if" statements just capturing all the different variables and permutations.
JASON: I love it. I love it. What's up, Alex? Thank you for the raid. Welcome, everybody. We are buildings out a battlesnake. Thank you for the sub. I saw that earlier but didn't want to interrupt. Thank you very much. Always very much appreciated. Okay. So, I believe we have restarted our Battlesnake. So, now let's just YOLO, let's just try it and see what happens.
JOE: Close my window before a large flying object comes in my room.
JASON: Not hitting the body.
JOE: How are you doing?
JASON: Got stuck. Hit the wall.
JOE: Made it to 100.
JASON: I think we got stuck here because our health had gone up.
JOE: Oh, I see. Oh, so, that will be a fun check to add.
JASON: Right. We're gonna have to do the logic there. I can see, you know, why selfdriving cars have been such a hard challenge.
JOE: Selfdriving snakes. I want to quickly highlight a comment by Penelope, which I like just because, again, it shows, like, again but Penelope beat the avoid walls challenge by moving in a circle. Get to 100 turns. Grow your snake in whichever way you like.
JASON: Nice, nice.
JOE: So, avoiding other snakes. We haven't done anything with other snakes. How are we doing on time? Got a little bit.
JASON: We have, like, 22 minutes.
JOE: We could fix that bug you just hit. That would be an interesting one, that would be a case where there would have been no moves available, right? Have you still got the game state for that one?
JASON: Uh, yeah.
JOE: Because what we could do sorry, it would be in the console, right? Do we have the possible moves array? Yeah.
JASON: No available moves. So, it just repeated its move?
JOE: Yes, exactly. What we could do is look at have a case right at the end where if there are no possible moves, quickly do a check and see like, okay, is one of those moves food? Because that's nonlethal. And then add that back in. Does that make sense?
JASON: Sure. Yeah. We could do that. So, just knowing that we have about 20 minutes here
JASON: is it more beneficial to figure out that edge case or should we look at the other snakes?
JOE: Other snakes?
JASON: I think just for I would personally prefer to do
JOE: Do other snakes.
JASON: So that we can play with that.
JOE: Yeah, for sure. Let's do that. Get your snake surviving against itself would be fun.
JASON: Wait, what? Ooh, that's fun.
JOE: You can add your snake twice, yeah.
JASON: Okay. All right. Don't collide with others. That seems like the right thing.
JOE: So, this is gonna be gamestate.board.snakes, I think, is the object. No, sorry. Gamestate.board.snakes. Or is it gamestate.snakes? I can't remember how the object works. Sorry, I've gone mad.
JASON: Let's go look. Gamestate.board.snakes.
JASON: Okay. So, this one, we're gonna do a snakes.forEach, and we'll get a snake.
JASON: And then inside of here, we have the snakeBody.
JASON: And that's gonna be snake. so, each snake has a body.
JASON: Okay. And then we want to do snakeBody.forEach. And for that one, I think we can just do this whole thing again.
JOE: That looks good.
JASON: Oh, my goodness. We really need to abstract that out. Okay. It's fine. This is fine.
JOE: It's fine.
JASON: So, this, then, will make it so that all so, effectively, this will very quickly kill us as soon as there's more food on the board. And that's okay.
JOE: How so?
JASON: Well, because if we get locked in, we're just gonna repeat the thing, and it sounds like this will
JOE: Oh, I see
JASON: Lead to a no move. I'm also wondering I have an idea for a hack on this.
JOE: Okay. That's good.
JASON: Where we could change the we could change the value if it's for food to food.
JOE: I see. And just have a different check, yeah.
JASON: That might be that might be a way to do it where we don't have to run the logic
JOE: All over again. Yeah, yeah.
JASON: But let's see how we do this. We'll let's just run this and see what happens. Let me restart.
JOE: Create a new game.
JASON: And then
JOE: Do the food check last and skip if there's only one option left. That's also a good hack.
JASON: Also a good hack.
JOE: Do that. Yeah, we can do it that way. Let's see what happens in here. I wonder what snake it's going to put you up against.
JOE: Okay. Cool.
JASON: Yeah, run away. Run away, snake.
JOE: It's hard to tell get close together so you can see if it's working. It looks like it's working. One's getting food.
JASON: Oh, don't touch.
JOE: What a beautiful dance.
JASON: Is it gonna make it? I made it! First try.
JOE: Nice. Plowing through the challenges.
JASON: Okay. So, the last one is find food. 199 turns. Make sure to eat.
JOE: I think they cranked down the food spawn on this app so there's not as much food.
JASON: What we would need to do for that one is effectively an L statement.
JOE: If we're messing around with this, do you want to take the opportunity to apply another one of the hacks? Still have 15 minutes.
JASON: Yeah, okay. Let's try it. So, here's what I'm gonna try. I think what we can do is we can do the food check. And hmm Jacob's idea might be better than mine.
JOE: Just make it last. That would probably be easier.
JASON: So, let's do that. So, I'm going to take all of this and we'll move this down to "finding food."
And then if we are healthy, we don't look for food. JOE: Correct.
JASON: If we okay. So, here, we would need something that was, like let's see. If
JOE: What are you adding to?
JASON: I'm thinking about the so, we basically if all of the other options are false, then we don't want to mark this as false.
JOE: Oh, I think Jacob's idea is actually even higher level than this, which is because this is now last, right? So, if you get to this if you get to the food block and there's only one possible move, just skip to the food block.
JASON: Oh, yeah, that's even easier. Okay. So, if possibleMoves. what's the right
JASON: Move is move I guess it would just be, like, move. I can simplify that, can't I? I can just drop this right in. �.length equals 1.
JOE: Huh. Okay.
JASON: Let's actually, it would be greater than 1. So, if we have more than one option, then we'll do this block.
JASON: We're gonna find out if that actually works.
JOE: Okay. All right. That should work. And then here, what we should get is if so, then jeez, we really do need to make this JOE: Yeah, folx are pointing out it's an object. So, we can't just do boolean. It would have to be object.key. Possible moves filter.
JASON: Values, right? Because we would want the
JOE: Yeah. Yeah, yeah, yeah.
JASON: So, object.values. And then we'll filter over those. Okay. And if there's more than one true, then we'll do this block of logic. Otherwise, we are going to take this whole block.
JASON: Run it again.
JOE: But backwards.
JASON: But just do the whole thing backwards.
JASON: Oh, wait, for this one, would we want to should I set the other ones to false as well? Like, force it to eat the food?
JOE: Yes. Yeah, that's yes. Genius. Yeah.
JASON: Okay. So, then to do that, I can just take all of these
JOE: Oh, my God, someone's actually using multicurser.
JASON: Okay. So, we'll do this way. And then here, we want left to be true. Here, we want up to be true.
JOE: This is very satisfying to me.
JASON: And here, and we want down to be true.
JOE: The great thing about this I cannot tell you the amount of the beginning snake journeys I've done over the years and every time it ends up different. Even the basic steps end up different. It's so cool.
JASON: Okay. So, this one, theoretically speaking, should start out food avoidant.
JASON: Get to 25 health and get real hungry.
JOE: Yeah, and along the way, it should no longer get stuck in corners because it's avoiding. Theoretically. Straight into the challenge.
JASON: Why test? Test in production, that's what I always say.
JOE: We've got that Jess test and haven't touched it. Don't need to.
JASON: Okay. So, it's not eating, not eating, not eating. It's going to oh, why'd you run out of what?
JOE: the array.
JASON: Why was up possible? Why would you have done that? I suppose it's possible that I did something silly here. So, if game health is over 25
JOE: That's not where oh, I see. Okay. This is the issue we had before. We were having issues in the top row. Can we check the wall avoidance code just to make sure there is not an issue with the wall avoidance code in this case. Don't hit yourself. So, this one? Yeah. MyHead y. Board height minus 1 is correct, right?
JASON: Should be.
JOE: Starting at 0. Board height is 11. So, this is 10. Okay.
JASON: So, this, I wish there was a way to get it to replay.
JOE: Y starts 00 is the bottomleft of the board.
JOE: Unfortunately, there is no way to get a replay unless we add the JSON state.
JASON: Okay. So, we're gonna try this again.
JOE: Gonna do it right out of the gate now. Okay. Once we hit turn 75, we should be good. Okay. This is a problem. It doesn't if it's never adjacent to the food, when there is so little food
JASON: Oh, interesting. Okay. So, we'll have to get it we'll have to make it more
JOE: Have to look ahead, yeah.
JASON: Okay. That's fine. We can I kind of wanted to reproduce this wall smash.
JOE: Oh, there we go.
JASON: Just do wall smash right out of the gate.
JOE: It doesn't like that top row. Oh, but up is false this time.
JASON: Up was not false. Wait a minute. Did it time out? I think it might have timed out, because this
JOE: Because we didn't get a move back?
JASON: This doesn't look like it ran another game.
JOE: Maybe that's is this running out of ngrok stuff again?
JASON: Maybe. Let's check. So, on ngrok, I have 6 wait, no.
JOE: Oh, no, that's
JASON: Did you time out on me? 160 milliseconds. Let's retry and see it might have just been a timeout. Moved out of bounds. So, is that a timeout?
JOE: Timeout would be 0 milliseconds. So, something's getting returned. But, like, that might not be from you. It's getting a response, but it might be getting a response from something on the ngrok tunnel. Try going to the ngrok URL in the browser and see what it's getting us.
JASON: That's a good point. So, I'm going to go to this one. Nope, not that. Here.
JOE: So, it's working.
JASON: Cannot get move.
JOE: Oh, okay, it's a post.
JASON: It's a post. Okay. I can I can make that work. We can
JOE: You'll need to give it a game state.
JASON: Oh, that's right. I can't get it to
JASON: Okay. I don't care. We don't have time for that. We've got, like, 4ish minutes. So, what we can do instead is what we did last time, which is just restart the tunnel.
JASON: And reset the game. So, here's our snake. And I can edit it somewhere.
JOE: Yeah, yeah.
JASON: Here's the edit. There's the ngrok tunnel. We're gonna save that. We're gonna go back out here. We're gonna retry. And let's see if we can get it to do the thing.
JOE: There we go. I was scared for a minute there. It went up for so many turns.
JASON: Don't starve, little friend. Don't starve. Get the food. Come on.
JASON: It moved out of bounds. It did the thing again. So, this time
JOE: Left is true. So, what's interesting about that
JASON: And that would have been
JOE: Y is false is correct. So, it's not that code.
JASON: Board with snake. Why is the snakeX and Y wrong?
JASON: Interesting. Interesting.
JOE: Wait. Hang on. Is it wrong? No, the board
JASON: Yeah, because the snake head should have been 0, 3, and it's showing 4, 3, which should have been, by any estimation, that's incorrect.
JOE: Yeah. That's really weird.
JASON: Wait. Is it offcenter? Like 0, 1, 2, 3, 4?
JOE: No, no, no. It's definitely bottomleft.
JASON: Snakey. Do I have a Y where can X can be? That's definitely possible. Okay. So, myHead.x. MyHead.x left. That's the one that we were looking for. MyHead.x board width.
JASON: Right? So, these are all correct.
JOE: So, the only other thing I can think of is our health there is no way that the part of the code where we start setting things to true sudden have been active in that game state. And even then, that wouldn't have interfaced that wouldn't affect why the snake.x was wrong. I wonder, actually, can you quickly look at turn for that move?
JASON: Uh, here?
JOE: Yeah. So sorry, in the console. That was turn 80. What turn we were just looking at in the console?
JASON: 79. 75. We stopped logging. Oh, it just timed out or something. Okay. So, maybe it's because my snake is flakey because I'm running it through ngrok.
JOE: Maybe. This would be a new ngrok problem. I haven't seen this before.
JASON: I am running a livestream off one computer and ngrok off another computer. Come on, little friend. Come on, little friend. Do it! Do the thing. I bet it timed out. That was turn 121. How far did we get this time? 120 undefined. It failed or timed out or something.
JOE: No, this was a case of you had no moves left. So, this is because was it it was in the corner, right?
JASON: It was in the corner.
JOE: Yeah. Was it completely it should have had down. Why didn't it? There we go. Okay. So, this is actually a really quick one we can do. Your tail
JASON: I think we might be out of time, unfortunately. We got five minutes. So, I think we're gonna call this one, like, I'm actually, I'm pretty happy about this. We got so much further with this than I thought we were going to. The fact that we have a snake that can keep itself alive for around 100
JOE: Over 100 turns.
JASON: When the server works.
JOE: What a problem.
JASON: Okay. I'm gonna go ahead and just call this one, like, we saw we saw it work. I think my yeah, my ngrok has gone down again. So, whatever that is
JOE: At least we worked out it was that I didn't end the stream thinking there was some unsolvable problem.
JASON: So, I mean, for reasonably low general effort, we were able to get the basics of this game up and running. And I can definitely see how deep this rabbit hole goes. Where, you know, the next thing I wanna do is I wanna look at, like, where is the nearest snake and how close is it to food? Can I beat it there? Is it big enough if I do beat it there, I can turn and bite its head? You know, that kind of thing is very
JOE: You know, right now, we're only looking at things adjacent to us and already at the point where we need to find food farther away. Path finding algorithms, that kind of stuff comes in.
JASON: Yeah, what a fun this is a fun project. It's a fun game. I can definitely see this is a wonderful way to learn different programming concepts, too, because it's collaborative. It's interactive. It looks like, I mean, seeing all the just on this stream, how many Battlesnake players showed up to help and play around. So, thank you so much to I saw Penelope. I think there was another two usernames, 21 or something.
JOE: 210. That's Brad. That's the founder.
JASON: Thank you, Brad, for being here. Yeah, this looks great. So, for somebody who wants to get further into this, where should they look? What would you recommend outside of what we did today?
JOE: So, the challenges go quite indepth. There are lots of things to take you along. The Discord is a great place to be. There is a channel called Snake Dev. That's where lots of the folx hang out and chat about what they're building. Lots of snakes are open source. If you're familiar with the concept of awesome lists on GitHub
JASON: I didn't realize there were so many.
JOE: Yeah, there's a lot.
JASON: Oh, that's the end of the challenges. Definitely didn't.
JOE: No, it goes quite far.
JASON: Super fun. There is a bunch of stuff down here. There is a Discord. Looks like there is Twitch and all sorts of good things down here.
JOE: A lot of the good snakes are open source as well. Like a repo list. There is also Battlesnake. So, if you want to look at, you know, like, I think it's this. Some quite advanced snakes, there is source there for past tournament winners. Coming up, we do have the fall league. So, that is gonna be registration for that is open. So, you can join that. It's ranked like the current one. Starts September 24th. Thank you for bringing that up. There will be a ladder, you enter a snake, you gain points. Towards the end, we take the top "X" snakes from a bunch of brackets and run a live tournament with them and there's prizes and stuff. Looking for a chance to get into it, jump in.
JASON: That sounds like so much fun. Joe, thank you so much for being here today. Let's do a quick shoutout to our sponsors. So, as always, we've had live captions here today. We've had Jordan here with us. Thank you so much, Jordan, for being here. Jordan is from White Coat Captioning. That's made possible through the support of our sponsors, Netlify, Fauna, Auth0, Hasura. All kicking in to make this accessible for more people. Thanks to them. While you're looking at the site, make sure you check out the schedule. So many amazing things coming up. It's going to be so fun. I'm bubbling over with excitement for how many fun things are coming up on the stream. With that, I think we're gonna call this one a wrap. I'm gonna go find somebody to raid. Joe, any parting words before we call this one a done deal?
JOE: Thank you so much for having me and thank you for your lovely community chatting along. It's been a lot of fun.
JASON: It's been an absolute blast. Thank you all so much. We will see you all next time.