1
00:00:05,160 --> 00:00:07,640
Hi, welcome to this new video.

2
00:00:07,640 --> 00:00:08,880
We're going to continue working

3
00:00:08,880 --> 00:00:11,210
on our ecosystem simulation.

4
00:00:11,210 --> 00:00:13,340
In this video, we're going to be

5
00:00:13,340 --> 00:00:16,700
continuing on the work
on the decision tree.

6
00:00:16,700 --> 00:00:18,980
How we're using a decision tree

7
00:00:18,980 --> 00:00:20,760
in the brain of the herbivore,

8
00:00:20,760 --> 00:00:22,500
which is one of the
classes that we have

9
00:00:22,500 --> 00:00:25,445
our animals that will
eat food eventually.

10
00:00:25,445 --> 00:00:27,980
We're going to be able

11
00:00:27,980 --> 00:00:29,920
to evaluate or execute
some functions like

12
00:00:29,920 --> 00:00:35,975
wander and seek food by
navigating the decision tree.

13
00:00:35,975 --> 00:00:37,980
What have we done
so far? We created

14
00:00:37,980 --> 00:00:40,780
a decision tree that
has an awake state.

15
00:00:40,780 --> 00:00:42,640
Are you awake, condition?

16
00:00:42,640 --> 00:00:44,100
Then it checks,
are you hungry or

17
00:00:44,100 --> 00:00:47,650
not and then it dictates
if it's going to go into,

18
00:00:47,650 --> 00:00:50,710
seeking food mode or wondering.

19
00:00:50,710 --> 00:00:52,840
We want to associate

20
00:00:52,840 --> 00:00:55,120
a function in the code

21
00:00:55,120 --> 00:00:56,785
that will be executed
if we're in that state,

22
00:00:56,785 --> 00:00:58,300
in the final state of wander.

23
00:00:58,300 --> 00:01:01,485
But that function should
also have a transition,

24
00:01:01,485 --> 00:01:05,660
meaning that if let's say if
we wander for a long time,

25
00:01:05,660 --> 00:01:07,405
maybe we start getting hungry,

26
00:01:07,405 --> 00:01:10,880
or the hunger level starts
growing and eventually,

27
00:01:10,880 --> 00:01:12,980
the wander state reaches

28
00:01:12,980 --> 00:01:16,995
a threshold or a
point of transition,

29
00:01:16,995 --> 00:01:20,920
in which we are going to
reevaluate the decision tree.

30
00:01:20,920 --> 00:01:22,540
Some decision trees
would actually

31
00:01:22,540 --> 00:01:25,480
just navigate back to
the previous node,

32
00:01:25,480 --> 00:01:27,960
and potentially ask
that question again.

33
00:01:27,960 --> 00:01:30,730
Are we going to seek food?

34
00:01:30,730 --> 00:01:32,880
But we want to create a system

35
00:01:32,880 --> 00:01:34,480
that might be able to completely

36
00:01:34,480 --> 00:01:38,130
evaluate the decision
tree and double check.

37
00:01:38,130 --> 00:01:40,940
It may be that a condition
such as wander or it

38
00:01:40,940 --> 00:01:43,820
might make the entity sleepy,

39
00:01:43,820 --> 00:01:45,580
and we want to go
back all the way

40
00:01:45,580 --> 00:01:48,590
down to the question
of, are you awake.

41
00:01:48,860 --> 00:01:51,680
We're going to be able
to return to the root,

42
00:01:51,680 --> 00:01:53,580
and we're going to do that
with our same function

43
00:01:53,580 --> 00:01:54,960
or construct the decision tree.

44
00:01:54,960 --> 00:01:57,260
We're going to refresh
the decision tree,

45
00:01:57,260 --> 00:01:58,580
go back to the root node,

46
00:01:58,580 --> 00:02:02,850
and start the cascading down
in the flow chart as we go.

47
00:02:02,850 --> 00:02:05,205
Let's see how we can
put this in action.

48
00:02:05,205 --> 00:02:08,520
We're going to jump
here into processing.

49
00:02:08,520 --> 00:02:12,810
What do we have so far?
We just constructed.

50
00:02:12,810 --> 00:02:15,890
I'm continuing with the code
that we did last video.

51
00:02:15,890 --> 00:02:18,010
I'm here in the herbivore class,

52
00:02:18,010 --> 00:02:19,345
and we just wrote

53
00:02:19,345 --> 00:02:24,125
the update current node
and build a decision tree.

54
00:02:24,125 --> 00:02:26,705
We basically created the nodes,

55
00:02:26,705 --> 00:02:30,240
gave the information
for them and

56
00:02:30,240 --> 00:02:34,090
we created the flow
chart navigation.

57
00:02:34,850 --> 00:02:38,235
Let's just try to create

58
00:02:38,235 --> 00:02:41,850
because that we end up in
some of these action notes.

59
00:02:41,850 --> 00:02:43,120
But right now these
action notes,

60
00:02:43,120 --> 00:02:46,280
we are just printing the
line, if you remember here.

61
00:02:46,280 --> 00:02:47,740
We're just printing the line.

62
00:02:47,740 --> 00:02:49,390
You're currently in
this action note.

63
00:02:49,390 --> 00:02:50,920
It doesn't do anything.

64
00:02:50,920 --> 00:02:52,615
It doesn't execute a function.

65
00:02:52,615 --> 00:02:57,340
We're going to comment
out this line.

66
00:02:57,340 --> 00:02:58,900
We're going to try to execute

67
00:02:58,900 --> 00:03:00,360
specific functions that are

68
00:03:00,360 --> 00:03:02,300
associated with the behaviors.

69
00:03:02,300 --> 00:03:03,860
We're not still going to fully

70
00:03:03,860 --> 00:03:05,540
fleshed out those functions,

71
00:03:05,540 --> 00:03:07,545
but let's create
functions for them.

72
00:03:07,545 --> 00:03:10,480
Let's define the
wander function.

73
00:03:12,530 --> 00:03:14,720
For now, also,
we're going to use

74
00:03:14,720 --> 00:03:17,340
the placeholder print line.

75
00:03:20,750 --> 00:03:24,160
I'm wandering.

76
00:03:37,670 --> 00:03:41,700
That's the function wander.

77
00:03:41,700 --> 00:03:53,955
Let's define rest function.

78
00:03:53,955 --> 00:03:56,760
Basically, let's
do the same thing.

79
00:03:56,760 --> 00:03:58,775
I hope you understand this.

80
00:03:58,775 --> 00:04:00,240
I'm trying to work
on the structure

81
00:04:00,240 --> 00:04:03,035
before I'm actually
working on the behavior.

82
00:04:03,035 --> 00:04:08,360
Here, we're going to say
I'm resting and then

83
00:04:08,360 --> 00:04:22,285
the function seek food.

84
00:04:22,285 --> 00:04:25,950
We're going to type
here, I'm seeking food.

85
00:04:26,740 --> 00:04:29,915
These are the functions
that we want to execute,

86
00:04:29,915 --> 00:04:32,840
so how would we go about passing

87
00:04:32,840 --> 00:04:34,505
these functions to the nodes

88
00:04:34,505 --> 00:04:35,825
so that whenever
we create a node,

89
00:04:35,825 --> 00:04:38,700
the node knows which
function to call?

90
00:04:39,010 --> 00:04:44,405
Let's just delete or
comment out this print out.

91
00:04:44,405 --> 00:04:47,750
We want to say the current node

92
00:04:47,750 --> 00:04:49,820
should activate
its own function,

93
00:04:49,820 --> 00:04:53,495
so what we could do
here is go to the node

94
00:04:53,495 --> 00:04:58,130
and let's do a new thing,

95
00:04:58,130 --> 00:05:01,880
a new piece of information
that the node might have,

96
00:05:01,880 --> 00:05:05,270
which we're going to
call action function,

97
00:05:05,270 --> 00:05:08,720
abbreviate that a
little bit action func.

98
00:05:08,720 --> 00:05:11,270
None. We're creating

99
00:05:11,270 --> 00:05:14,240
a new variable called
action function.

100
00:05:14,240 --> 00:05:17,945
Now we can make the
internal variable

101
00:05:17,945 --> 00:05:22,685
self.action function
equals to action function.

102
00:05:22,685 --> 00:05:24,680
This is something that
we haven't seen yet,

103
00:05:24,680 --> 00:05:27,185
which is, this is a variable.

104
00:05:27,185 --> 00:05:31,850
But we could assign a
function to a variable.

105
00:05:31,850 --> 00:05:34,985
That's an interesting technique.

106
00:05:34,985 --> 00:05:40,700
Let's just say assign to
this action function.

107
00:05:40,700 --> 00:05:43,085
In this area here,

108
00:05:43,085 --> 00:05:45,330
all the action nodes,

109
00:05:45,490 --> 00:05:52,235
we will be able to assign
to them a function.

110
00:05:52,235 --> 00:05:56,670
Let's just do in this
case, self.wander.

111
00:05:58,420 --> 00:06:01,145
Because we created
that function already.

112
00:06:01,145 --> 00:06:02,900
The function is self.wander.

113
00:06:02,900 --> 00:06:04,445
It's written here,

114
00:06:04,445 --> 00:06:06,965
so we're assigning
that to this variable.

115
00:06:06,965 --> 00:06:08,435
That means that we can actually

116
00:06:08,435 --> 00:06:11,480
execute that function because

117
00:06:11,480 --> 00:06:13,055
the node would have a variable

118
00:06:13,055 --> 00:06:16,790
that gives us access to that.

119
00:06:16,790 --> 00:06:20,855
Let's just do the next one,

120
00:06:20,855 --> 00:06:26,100
which is the next one
would be self.seek food.

121
00:06:32,110 --> 00:06:35,540
We're going to do
the same thing for

122
00:06:35,540 --> 00:06:43,535
action function for
rest, self.rest.

123
00:06:43,535 --> 00:06:45,620
Because each one of
these functions will

124
00:06:45,620 --> 00:06:47,480
be printing these texts,

125
00:06:47,480 --> 00:06:48,740
we need to make sure that

126
00:06:48,740 --> 00:06:50,780
those functions are
being executed.

127
00:06:50,780 --> 00:06:52,730
Instead of printing this line

128
00:06:52,730 --> 00:06:53,990
here that was a placeholder,

129
00:06:53,990 --> 00:07:05,490
let's say that the current
node ,.action function.

130
00:07:07,210 --> 00:07:09,740
Because that's a function,
we're going to just

131
00:07:09,740 --> 00:07:11,510
use open and closed parentheses.

132
00:07:11,510 --> 00:07:13,145
That's not a variable.

133
00:07:13,145 --> 00:07:18,005
It's actually a function
that lives within this node.

134
00:07:18,005 --> 00:07:20,525
We can actually
call that directly.

135
00:07:20,525 --> 00:07:22,400
Obviously, each one
of those would be

136
00:07:22,400 --> 00:07:24,425
different depending
on the node we're in,

137
00:07:24,425 --> 00:07:26,090
but now we're actually not only

138
00:07:26,090 --> 00:07:27,845
associating data to a node,

139
00:07:27,845 --> 00:07:30,695
but also potentially a
functionality to the node,

140
00:07:30,695 --> 00:07:32,990
like a particular
form of execution of

141
00:07:32,990 --> 00:07:36,125
code will happen at the
end of this decision tree.

142
00:07:36,125 --> 00:07:38,015
Again, we're not spending time

143
00:07:38,015 --> 00:07:42,395
in diving deeper into what
these functions are doing,

144
00:07:42,395 --> 00:07:43,940
which we're going to do
in the next few videos.

145
00:07:43,940 --> 00:07:46,250
But we're trying to make
sure that our decision tree,

146
00:07:46,250 --> 00:07:47,840
it's not only constructed,

147
00:07:47,840 --> 00:07:50,750
but is capable to
executing code.

148
00:07:50,750 --> 00:07:54,710
Let's see if we
have this working.

149
00:07:54,710 --> 00:07:56,780
You see right now we have,

150
00:07:56,780 --> 00:07:57,950
I'm seeking food,

151
00:07:57,950 --> 00:08:00,455
so that function
is being called.

152
00:08:00,455 --> 00:08:03,380
The function seeking
food, I'm seeking food.

153
00:08:03,380 --> 00:08:05,975
That's because if we
look at the data,

154
00:08:05,975 --> 00:08:08,255
is hungry is true.

155
00:08:08,255 --> 00:08:10,610
Let's just make it false again.

156
00:08:10,610 --> 00:08:21,005
To see. I'm wondering,

157
00:08:21,005 --> 00:08:22,490
so we are executing
those functions.

158
00:08:22,490 --> 00:08:25,520
That's great. Let's look
at one example of how we

159
00:08:25,520 --> 00:08:30,050
transition out of let's
say we're in wander state,

160
00:08:30,050 --> 00:08:32,720
and that wander execution,

161
00:08:32,720 --> 00:08:37,140
we want to go from
wander to hungry.

162
00:08:37,270 --> 00:08:39,620
Well, we're going to need to

163
00:08:39,620 --> 00:08:42,020
create a few extra
variables for that.

164
00:08:42,020 --> 00:08:48,700
We're going to use a particular
naming convention here.

165
00:08:48,700 --> 00:08:57,220
We're going to say
self.hunger level equal zero.

166
00:08:57,220 --> 00:08:58,360
That's going to
be something that

167
00:08:58,360 --> 00:09:00,280
counts how hungry are we

168
00:09:00,280 --> 00:09:05,690
and self.hunger threshold,

169
00:09:11,520 --> 00:09:15,390
and we're going to say
something like 100.

170
00:09:16,220 --> 00:09:21,420
The threshold would
represent how high

171
00:09:21,420 --> 00:09:23,670
this value of the
hunger value needs

172
00:09:23,670 --> 00:09:26,625
to get to trigger a transition,

173
00:09:26,625 --> 00:09:29,055
and the level is going
to be a country.

174
00:09:29,055 --> 00:09:30,210
We're going to start 0, 1, 2,

175
00:09:30,210 --> 00:09:31,725
3, 4, 5, 6, 7,

176
00:09:31,725 --> 00:09:35,010
until we get to the hungry state

177
00:09:35,010 --> 00:09:36,630
and something will happen.

178
00:09:36,630 --> 00:09:41,580
Let's just It's a very simple
counting statement here,

179
00:09:41,580 --> 00:09:46,815
we're going to say
if the hunger level.

180
00:09:46,815 --> 00:09:49,050
First of all, we're going
to say hunger level

181
00:09:49,050 --> 00:09:50,280
plus equals one,

182
00:09:50,280 --> 00:09:52,020
so every frame we go up in one,

183
00:09:52,020 --> 00:09:53,730
and if the hunger
level it's bigger

184
00:09:53,730 --> 00:09:58,120
than the hunger threshold.

185
00:10:05,210 --> 00:10:08,700
Basically, this is the moment
in which we transition.

186
00:10:08,700 --> 00:10:17,130
What we want to transition is
a self.hunger equals true.

187
00:10:17,130 --> 00:10:21,765
We're saying that this state of,

188
00:10:21,765 --> 00:10:24,880
actually is called is hungry.

189
00:10:28,820 --> 00:10:32,595
Which is our bullion.
Let's just double check.

190
00:10:32,595 --> 00:10:35,175
Here is is hungry.

191
00:10:35,175 --> 00:10:40,140
We want to say if
that hunger level

192
00:10:40,140 --> 00:10:41,415
reaches the threshold,

193
00:10:41,415 --> 00:10:44,295
we transition to
this state changes,

194
00:10:44,295 --> 00:10:49,150
but then we also need to
say self.current node,

195
00:10:49,610 --> 00:10:56,320
so the decision tree
resets and self.build,

196
00:10:57,890 --> 00:11:05,350
which in a way, is a way of
saying rebuild decision tree.

197
00:11:05,480 --> 00:11:10,065
This will take the current
node back to the root node,

198
00:11:10,065 --> 00:11:12,120
and we're going to go
through the chart again.

199
00:11:12,120 --> 00:11:14,970
In this case, now we're
going to be hungry.

200
00:11:14,970 --> 00:11:19,245
What should be happening is
that we are in wander state.

201
00:11:19,245 --> 00:11:20,490
We're in wander state for

202
00:11:20,490 --> 00:11:25,710
100 frames of hunger until
the hunger level reaches

203
00:11:25,710 --> 00:11:30,180
this point and we transition out

204
00:11:30,180 --> 00:11:35,355
of hungry and we go
into seeking food.

205
00:11:35,355 --> 00:11:38,850
Let's see if we're
getting errors.

206
00:11:38,850 --> 00:11:41,235
We are running into
an error here.

207
00:11:41,235 --> 00:11:47,590
Oh, yeah, I keep
forgetting to self.

208
00:12:01,910 --> 00:12:04,960
Let's try it now.

209
00:12:06,830 --> 00:12:10,065
I'm wandering, and now,

210
00:12:10,065 --> 00:12:11,820
because we have
multiple entries,

211
00:12:11,820 --> 00:12:13,710
this is going to
start mixing up,

212
00:12:13,710 --> 00:12:16,155
but all of them start wandering,

213
00:12:16,155 --> 00:12:17,490
and then after 100 frames,

214
00:12:17,490 --> 00:12:19,395
they transition to seeking food.

215
00:12:19,395 --> 00:12:22,290
The way I would try
this at this point,

216
00:12:22,290 --> 00:12:23,610
especially when you're
working on the behavior

217
00:12:23,610 --> 00:12:25,365
of a decision tree,

218
00:12:25,365 --> 00:12:27,180
we probably don't want to be

219
00:12:27,180 --> 00:12:29,860
creating herbivores every frame.

220
00:12:31,370 --> 00:12:33,390
You probably want to create

221
00:12:33,390 --> 00:12:38,010
only one single
herbivore which you

222
00:12:38,010 --> 00:12:44,220
could do not by running this
in the run, but like here.

223
00:12:44,220 --> 00:12:46,305
You could say, Hey,

224
00:12:46,305 --> 00:12:48,390
let's create one herbivore

225
00:12:48,390 --> 00:12:50,430
that is situated in the
middle of the screen,

226
00:12:50,430 --> 00:12:53,655
so that's 600 by 300.

227
00:12:53,655 --> 00:12:57,315
This is just a testing code.

228
00:12:57,315 --> 00:12:59,535
It's position is
going to be that.

229
00:12:59,535 --> 00:13:02,950
That's a new herbivore
added to the list.

230
00:13:05,210 --> 00:13:08,520
It's going to be there
from the very beginning,

231
00:13:08,520 --> 00:13:11,880
but we are not creating
herbivores dynamically.

232
00:13:11,880 --> 00:13:14,490
We can have one
herbivore in the middle.

233
00:13:14,490 --> 00:13:15,720
It's wandering and eventually

234
00:13:15,720 --> 00:13:17,280
transitions into seeking food.

235
00:13:17,280 --> 00:13:19,875
If you want that transition
to happen slower,

236
00:13:19,875 --> 00:13:24,040
you just need to give the
herbivore a bit more time.

237
00:13:24,800 --> 00:13:29,650
You can say up to 300 frames.

238
00:13:30,650 --> 00:13:32,985
It's going to take a bit longer,

239
00:13:32,985 --> 00:13:36,795
and eventually will transition
back into seeking food.

240
00:13:36,795 --> 00:13:38,220
We're going to get
to a point where

241
00:13:38,220 --> 00:13:39,285
we're going to visualize

242
00:13:39,285 --> 00:13:42,590
those states more graphically.

243
00:13:42,590 --> 00:13:44,945
But yeah, it's conforming.

244
00:13:44,945 --> 00:13:47,300
You can do your
own way of looking

245
00:13:47,300 --> 00:13:50,930
at printing out how much
hunger level you have in

246
00:13:50,930 --> 00:13:53,060
relation to the
hunger threshold that

247
00:13:53,060 --> 00:13:55,560
gives you an amount of

248
00:13:55,560 --> 00:13:59,385
the temporal duration
of the wandering around

249
00:13:59,385 --> 00:14:01,860
until the animal actually

250
00:14:01,860 --> 00:14:04,275
starts feeling that
it needs food.

251
00:14:04,275 --> 00:14:06,270
With that in mind, we're
going to leave it here

252
00:14:06,270 --> 00:14:08,590
and we're going to see
you in the next video.