Hi, welcome to this new video. We're going to continue working on our ecosystem simulation. In this video, we're going to be continuing on the work on the decision tree. How we're using a decision tree in the brain of the herbivore, which is one of the classes that we have our animals that will eat food eventually. We're going to be able to evaluate or execute some functions like wander and seek food by navigating the decision tree. What have we done so far? We created a decision tree that has an awake state. Are you awake, condition? Then it checks, are you hungry or not and then it dictates if it's going to go into, seeking food mode or wondering. We want to associate a function in the code that will be executed if we're in that state, in the final state of wander. But that function should also have a transition, meaning that if let's say if we wander for a long time, maybe we start getting hungry, or the hunger level starts growing and eventually, the wander state reaches a threshold or a point of transition, in which we are going to reevaluate the decision tree. Some decision trees would actually just navigate back to the previous node, and potentially ask that question again. Are we going to seek food? But we want to create a system that might be able to completely evaluate the decision tree and double check. It may be that a condition such as wander or it might make the entity sleepy, and we want to go back all the way down to the question of, are you awake. We're going to be able to return to the root, and we're going to do that with our same function or construct the decision tree. We're going to refresh the decision tree, go back to the root node, and start the cascading down in the flow chart as we go. Let's see how we can put this in action. We're going to jump here into processing. What do we have so far? We just constructed. I'm continuing with the code that we did last video. I'm here in the herbivore class, and we just wrote the update current node and build a decision tree. We basically created the nodes, gave the information for them and we created the flow chart navigation. Let's just try to create because that we end up in some of these action notes. But right now these action notes, we are just printing the line, if you remember here. We're just printing the line. You're currently in this action note. It doesn't do anything. It doesn't execute a function. We're going to comment out this line. We're going to try to execute specific functions that are associated with the behaviors. We're not still going to fully fleshed out those functions, but let's create functions for them. Let's define the wander function. For now, also, we're going to use the placeholder print line. I'm wandering. That's the function wander. Let's define rest function. Basically, let's do the same thing. I hope you understand this. I'm trying to work on the structure before I'm actually working on the behavior. Here, we're going to say I'm resting and then the function seek food. We're going to type here, I'm seeking food. These are the functions that we want to execute, so how would we go about passing these functions to the nodes so that whenever we create a node, the node knows which function to call? Let's just delete or comment out this print out. We want to say the current node should activate its own function, so what we could do here is go to the node and let's do a new thing, a new piece of information that the node might have, which we're going to call action function, abbreviate that a little bit action func. None. We're creating a new variable called action function. Now we can make the internal variable self.action function equals to action function. This is something that we haven't seen yet, which is, this is a variable. But we could assign a function to a variable. That's an interesting technique. Let's just say assign to this action function. In this area here, all the action nodes, we will be able to assign to them a function. Let's just do in this case, self.wander. Because we created that function already. The function is self.wander. It's written here, so we're assigning that to this variable. That means that we can actually execute that function because the node would have a variable that gives us access to that. Let's just do the next one, which is the next one would be self.seek food. We're going to do the same thing for action function for rest, self.rest. Because each one of these functions will be printing these texts, we need to make sure that those functions are being executed. Instead of printing this line here that was a placeholder, let's say that the current node ,.action function. Because that's a function, we're going to just use open and closed parentheses. That's not a variable. It's actually a function that lives within this node. We can actually call that directly. Obviously, each one of those would be different depending on the node we're in, but now we're actually not only associating data to a node, but also potentially a functionality to the node, like a particular form of execution of code will happen at the end of this decision tree. Again, we're not spending time in diving deeper into what these functions are doing, which we're going to do in the next few videos. But we're trying to make sure that our decision tree, it's not only constructed, but is capable to executing code. Let's see if we have this working. You see right now we have, I'm seeking food, so that function is being called. The function seeking food, I'm seeking food. That's because if we look at the data, is hungry is true. Let's just make it false again. To see. I'm wondering, so we are executing those functions. That's great. Let's look at one example of how we transition out of let's say we're in wander state, and that wander execution, we want to go from wander to hungry. Well, we're going to need to create a few extra variables for that. We're going to use a particular naming convention here. We're going to say self.hunger level equal zero. That's going to be something that counts how hungry are we and self.hunger threshold, and we're going to say something like 100. The threshold would represent how high this value of the hunger value needs to get to trigger a transition, and the level is going to be a country. We're going to start 0, 1, 2, 3, 4, 5, 6, 7, until we get to the hungry state and something will happen. Let's just It's a very simple counting statement here, we're going to say if the hunger level. First of all, we're going to say hunger level plus equals one, so every frame we go up in one, and if the hunger level it's bigger than the hunger threshold. Basically, this is the moment in which we transition. What we want to transition is a self.hunger equals true. We're saying that this state of, actually is called is hungry. Which is our bullion. Let's just double check. Here is is hungry. We want to say if that hunger level reaches the threshold, we transition to this state changes, but then we also need to say self.current node, so the decision tree resets and self.build, which in a way, is a way of saying rebuild decision tree. This will take the current node back to the root node, and we're going to go through the chart again. In this case, now we're going to be hungry. What should be happening is that we are in wander state. We're in wander state for 100 frames of hunger until the hunger level reaches this point and we transition out of hungry and we go into seeking food. Let's see if we're getting errors. We are running into an error here. Oh, yeah, I keep forgetting to self. Let's try it now. I'm wandering, and now, because we have multiple entries, this is going to start mixing up, but all of them start wandering, and then after 100 frames, they transition to seeking food. The way I would try this at this point, especially when you're working on the behavior of a decision tree, we probably don't want to be creating herbivores every frame. You probably want to create only one single herbivore which you could do not by running this in the run, but like here. You could say, Hey, let's create one herbivore that is situated in the middle of the screen, so that's 600 by 300. This is just a testing code. It's position is going to be that. That's a new herbivore added to the list. It's going to be there from the very beginning, but we are not creating herbivores dynamically. We can have one herbivore in the middle. It's wandering and eventually transitions into seeking food. If you want that transition to happen slower, you just need to give the herbivore a bit more time. You can say up to 300 frames. It's going to take a bit longer, and eventually will transition back into seeking food. We're going to get to a point where we're going to visualize those states more graphically. But yeah, it's conforming. You can do your own way of looking at printing out how much hunger level you have in relation to the hunger threshold that gives you an amount of the temporal duration of the wandering around until the animal actually starts feeling that it needs food. With that in mind, we're going to leave it here and we're going to see you in the next video.