Welcome to this new lesson on data structures. We're going to be moving towards a continuation of four-video series. This is the second one of four in which we're actually going to build a Langton's algorithm. In this case we're going to be looking at the movement of an entity, a worker in a grid. We've been talking about this already. We've been creating a random walker and we're going to recreate some of that, but we're going to allow it to change the data of the grid. We're going to start creating this symbiosis, this relationship between the walker affecting the grid or the base or the ground in which it's walking and also the later taking decisions based on that. If we have a coordinate, our position of an entity within a grid and we identify, as we have been discussing, a variable direction, that gives us a sense of an arrow. Like the arrow zero would be representing movement towards the right. We can say that movement of that entity within that grid is position x plus equals one. We are moving the Indexing 1 in one direction. If we actually, a rotation would mean that we could actually change the variable of rotation plus one, and that would actually flip the orientation, and in which case if we are in the Direction 1, the movement down in this case would be a movement in y. These are constructs in a way that we are using to identify that the coordinate represented by position and direction would allow us to move freely within the grid. We could make other moves like diagonally or hopping or things like that, and that's just about coming up with our own variables or our own naming conventions for such operations. Let's just use some of those principles. How do we actually create a walker first in the grid and make it move to the right, move forward and so on. Let's just jump into processing. If you remember, this is the script where we left off. Let me just run it once so that you know where we're starting. We basically have the random information zero and one in the grid. Let's just create a worker as a red dot somewhere in this grid. We already have the variables int current x and integer current y, which will represent the position of the worker. Let's just put it somewhere in the middle. I think in the middle will be somewhere like 50 and 25. Let's do a draw function. Let's just do something like an ellipse. Let's just do feel of red. We know that the ellipse will be in a position, that will be the walker position. Let's just make variables for that. Let's call it w position x and w for walker position in y. The position will be, let's see, it's going to be certainly associated with this variable. Let's just multiply that times the cell size. We will see that we will need something else. But maybe for now let's just do this. Is the current position. This is the main index information of the entity of the walker in the grid times the size of the cell. Let's copy that for y, y here. Now we can use the variables for the position of the ellipse. Let's do a 20 and a 20 for now. This is going to be a placeholder size. I think that at this point we will have some issues. I don't think we should have access to these variables here. Let's just make sure that we have access to them by making a global, there we go. Because these are global variables, we may not have access to them down here. We do have up here our ellipse all the way in the top. It's not really drawing itself where we're actually intending to have it. Let's just print the lines to see what information are we getting. We are getting that 50. What about the cell value? This is something that I like doing. Right now we're having a cell value of zero. That's the problem. Let's make sure that we recalculate the cell value. We had it done all the way up here, so let's just include that calculation here. There we go. Now our walker is somewhere in the middle, but it doesn't really seem to be fitting anywhere within the grid and that's because this ellipse is, I believe it's drawn from its center. If we really wanted to place this object into the position in x and y, let's just make it slightly smaller, like maybe a 15. If we really wanted to make it fit within the grid, let's just add half of the cell size. The way we would do that is add to the position the cell size divided by two, that's in x and let's do it in y as well. What we're adding here is because the ellipse is in the center, if we want to displace it half of its amount, let's say its radius to the right, we would add to the coordinate. You can see here, it actually seems to be fitting well within a rectangle. It's a little bit too big maybe we can go back to a 10, some value that allows us to identify. Here we have it. We have the walker position here in the grid and yeah, it's sitting within a rectangle of the cell. Let's just do some operations here to understand movement. I'm going to delete the print. That was a useful line to debug and understand what the data is doing behind the scenes. What we would say in the draw, that my position in x+=1. Let's just draw that. Let's see. You see that our walker moved towards the right, and that's happening because we're not refreshing the background of the screen. We will see that in this example we are going to start having to redraw the cells every frame so we might have to copy-paste some of this information down here in the draw, because what we actually want to do is have an interactive relationship between the grid and the background. But as you can see here, when we add +1 in x, we can draw the walker towards the right. If we actually do the current y+1, we would actually make it walk down. As you can see we could actually do that in all the different. If you do x-1, it would move to the left and you can understand doing negative in y would actually move up. How do we redraw? Let's redraw the cells in the draw. We're going to copy this, but we don't really want to copy everything. We don't want to add more cells to the system, we just want to draw them. Let's just copy that. We are going to include this all the way up here. We certainly don't want to append more information. The cells already exist and they have their data. We are going to calculate their position, we are going to use their information to determine if they should be black or white and do a rectangle and again continue the counting as we go. We also want to make sure that the count x on count y start at zero every frame. Because if you remember, the draw function, it will draw itself every frame, so we want to make sure that the counting variables start at zero. We recreate the grid every frame and then we move into our walker area. You could actually say that this section here, it's the walker section, and if you want it, you could actually say, hey, this is going to be my grid section. I like sometimes just add certain clarity to my script so that I could start remembering, this is the area where I'm working on the walker logic. Of course, we could do functions and we will start looking at functions in the next lesson where we will start doing functions for movement, for rotation, and so on. But for now, I think it's good enough to have some clarity that this part of the script really refers to the grid and this part here refers to the walker. We are running into an error here because this is not running and for some reason, the total number of cells value, if we actually try to print that information, let's just try to print it, it doesn't really exist here. That's because we haven't really bring it in. That is a calculation that we only want to do once. Total number of cells. We can actually take this information out of here and put it all the way up here at the beginning of our script certainly after the definition of resolution so that we can actually use that information now in our script down here. Let's print again the total number of cells, you have 5,000 and now the walker is actually showing in the screen. Sometimes you forget to put some calculations in the right place and you don't have access to some variables, it can happen. It should be working right now. As you can see now, the walker, I commented out this line to move to the left, but if we would run that line, you'll see that the walker moves really quickly. It's been redrawn every time, but the grid is also redrawn every time. It gives an illusion of movement as opposed to before. We would just have draw the background only once and then redraw the walker over and over on top of that grid. Now we actually could have a system that establishes a relationship between the walker and the grid. Let's do a simple operation. Let's say that the walker, it's going to move to the right, but it also wants to change the information of the grid. As it moves to the right, it will flip the zero to a one, or a one to a zero or make sure that all the indexes as it's moving around switch to the value of zero which is black. How do we actually access the information of the index, because we actually have an information of the x and y, so this information, the current x and the current y are actually a way for us to know where do they sit in the grid that it's intuitive, x and y, but it doesn't really map to an index in the grid. Here we're going to use a little bit of logic. The index value is the current index in x plus, we're going to use the current index in the current y times the resolution in y. Let's just write this equation here and then understand it. The current y represents how many rows down are we in? We know that we basically have the resolution in y is 50. If we're, let's say, in the fifth row, we're going to multiply 50 times our current y-coordinate. The current x, it's going to be the missing amount, because we will be moving, let's say, 10 units or whatever number of units we have an x on top of all the x's and y's that we are being covering. I don't know if that makes sense. I will actually do a small drawing once we run the script. Let me just comment out the movement so that we can actually comment on this for a second. If you think about this, so this is 100. We have a 50 in x. The index of the cell we're in is 50 plus all these rows, basically. Twenty-five rows times 100, which is all the cells included in every row. This is the equation in which we can convert the x and y into an index number, which is a singular index number. We could say something like, well, the cells, let's just look at the cells, and access the cell with the index value. We know that a cell can be either a zero or one. Let's just make sure that it's a zero. Let's just force it to be a zero wherever the agent is. Let's also make the agent walk to the right. What we're trying to do here is do a first painting of the agent. As you can see here, it's painting the information of the grid to black. We have some unexpected behavior here, because we don't have a boundary condition. We discussed this last week, or in last session, that whenever we are creating some behavior of movement, we want to determine what happens if I reach the edge of the screen. If we remember, I'm going to rewrite some of that code. If the current index in x is smaller than zero, then the current index in x is zero. We block that x to be any number smaller than zero, and the same thing in y. Then we also want to make sure that if the value of x is bigger or equals that the resolution in x, the number in x becomes the resolution in x. Let's just copy based that for y. Let's see if this actually changes the behavior of our agent. We are, in fact, stopping, but you see that we actually are not affecting the right index. We have to double-check our index operation here. I think that this equation, I just wrote it wrongly. I think that we should do resolution in x, because resolution in y, it's 50. If we actually want to calculate how many rows we have down, we actually should use x here, not y. There we go. I think that there's something wrong with the equation of the index. I couldn't quite see it, but it's here. We are calculating the resolution in x which is 100 times how many times we've covered 100, and then we're adding the current x to it. In this way we're actually setting up the cell value to zero and we're painting it black. If you wanted to move in the negative direction, let's see if that is actually working well. We can move to the left and we stay in zero. That's great. At this point, what we are having, it's a way in which the agent can walk on top of the grid, but it's also able to affect the value of the grid. Let's do one final thing. Let's just bring back this idea of random movement. The movement in x is going to be plus equals a random rand int between -1 and 1. It's bringing back the idea of the random walker. We have both of those, x and y, changing dynamically with a random number. You can see we have the worker that we had back and this time is actually printing black. But instead of printing black. It actually runs into an issue here. We'll come back to that issue in a minute. But let's just, instead of saying change the value to zero all the time, let's just flip the value. If the cell is zero, converted to one. Let's do that as an if statement. We could say the cell value is zero, then the cell value equals one. Then we can do an L if statement. If the cell value equals one, we will assign it to zero. We want an agent that is able to flip the value of the grid, where whites become blood, black becomes white and it's basically repainting that pattern. This is the beginning of the Langton's algorithm. The Langton plays heavily on an entity, a walker, that uses the information of the grid to take a decision on how to move forward. But at the same time it changes that information as it moves. Basically, the result of this condition is that you end up having an emergent pattern and emergent behavior. If you want to see the work of this worker a little bit more in a more interesting way. Instead of starting all our cells with a value of zero, we could start like this. We can make a comment here, and this is a random data for cells. Let's comment that out to just leave. Instead of that, I'm going to append a number zero which is going to force the fact that all the cells are going to start black. But the behavior of the cell, it's always going to flip. It's going to start painting white as it flip around, but that's it move back into white. Cells are going to be repainted black and so forth. It's a very powerful system, is starting to explain how a data structure of the grid becomes the driver of the behavior of this walker. Then again, the behavior of the walker, it's affecting the pattern of the grid. Very interesting ideas here. I'm going to see you in the next video where we're going to continue talking about how to build the lantern sand in its entirety. See you then.