1
00:00:04,130 --> 00:00:06,800
Hi. Welcome to this new video on

2
00:00:06,800 --> 00:00:09,260
our ecosystem simulation series.

3
00:00:09,260 --> 00:00:11,440
This is Week 3. We're
going to continue working

4
00:00:11,440 --> 00:00:15,155
on the behavior of
our herbivore class.

5
00:00:15,155 --> 00:00:18,340
We're going to be looking at
the seeking food function.

6
00:00:18,340 --> 00:00:20,020
This is very similar to some

7
00:00:20,020 --> 00:00:21,640
of the things that we
have done with particles.

8
00:00:21,640 --> 00:00:23,380
So you might be familiar
with that if you've

9
00:00:23,380 --> 00:00:26,475
done already Week 2.

10
00:00:26,475 --> 00:00:28,660
The seek food behavior,

11
00:00:28,660 --> 00:00:32,360
it's going to detect
food particles

12
00:00:32,360 --> 00:00:35,170
or food entities within range,

13
00:00:35,170 --> 00:00:39,320
and it's going to operate
by finding the closest one.

14
00:00:39,320 --> 00:00:41,440
We're going to redo

15
00:00:41,440 --> 00:00:43,220
an algorithm that
we've written already,

16
00:00:43,220 --> 00:00:46,360
which is finding closest entity.

17
00:00:46,760 --> 00:00:51,910
Basically at that
point, you reorient,

18
00:00:52,550 --> 00:00:57,080
look to the target and start
walking towards the target.

19
00:00:57,080 --> 00:01:00,050
We're not going to write
just yet the eating food,

20
00:01:00,050 --> 00:01:03,820
the transferring of killing
that food and absorbing

21
00:01:03,820 --> 00:01:06,560
a transition as well of

22
00:01:06,560 --> 00:01:07,960
behavior after getting

23
00:01:07,960 --> 00:01:09,700
that energy of
obtaining that food.

24
00:01:09,700 --> 00:01:11,100
But we're just going to write

25
00:01:11,100 --> 00:01:13,550
the boilerplate
behavior for seek

26
00:01:13,550 --> 00:01:20,355
food using the closest food
calculation. Let's do that.

27
00:01:20,355 --> 00:01:26,670
I know this is becoming one
of relatively complex class.

28
00:01:26,670 --> 00:01:28,530
That's why it's important

29
00:01:28,530 --> 00:01:30,450
that your naming
conventions are right.

30
00:01:30,450 --> 00:01:32,565
Remember that when
we were writing

31
00:01:32,565 --> 00:01:34,680
here in the herbivore class.

32
00:01:34,680 --> 00:01:37,955
If I navigate all the
way down to wander,

33
00:01:37,955 --> 00:01:43,160
we had turned off this exit
state after maybe spending

34
00:01:43,160 --> 00:01:49,605
200 frames wandering,
we get hungry.

35
00:01:49,605 --> 00:01:51,940
The herbivore will get hungry.

36
00:01:51,980 --> 00:01:58,190
Right now, I think that's set
to hunger threshold, 300.

37
00:01:58,190 --> 00:01:59,870
Let's do a little bit higher.

38
00:01:59,870 --> 00:02:02,160
Let's do 400 frames.

39
00:02:04,080 --> 00:02:10,855
We want to see that our
herbivore is in wander state,

40
00:02:10,855 --> 00:02:14,175
starts moving, doing its thing,

41
00:02:14,175 --> 00:02:19,310
and eventually, it should
get to seeking food.

42
00:02:19,800 --> 00:02:22,715
Let's just wait for it.

43
00:02:22,715 --> 00:02:25,065
Now it's currently in
seeking food mode.

44
00:02:25,065 --> 00:02:27,045
It shouldn't be moving anymore.

45
00:02:27,045 --> 00:02:28,790
This means that we drop

46
00:02:28,790 --> 00:02:30,410
completely the calling of

47
00:02:30,410 --> 00:02:32,500
the functions that are
associated with wander.

48
00:02:32,500 --> 00:02:34,015
This is why it's
important that we

49
00:02:34,015 --> 00:02:36,325
break down those behaviors,

50
00:02:36,325 --> 00:02:38,630
because we don't want
to be mixing them up.

51
00:02:38,630 --> 00:02:41,795
We want to be able to address
very specifically wander.

52
00:02:41,795 --> 00:02:43,570
Let's resolve that well.

53
00:02:43,570 --> 00:02:45,090
Let's move into seek food.

54
00:02:45,090 --> 00:02:48,075
As much as the code
might be longer,

55
00:02:48,075 --> 00:02:52,215
if each one of these building
blocks are understandable,

56
00:02:52,215 --> 00:02:54,360
we should be able to handle

57
00:02:54,360 --> 00:02:58,130
the complexity of a
rather complex class.

58
00:02:58,130 --> 00:03:00,025
Still the behavior
is very simple.

59
00:03:00,025 --> 00:03:01,980
It's not that the behavior
is really complex.

60
00:03:01,980 --> 00:03:03,660
But if you're new to coding,

61
00:03:03,660 --> 00:03:05,780
maybe starting to
engage with a project

62
00:03:05,780 --> 00:03:08,365
that has more and
more functions,

63
00:03:08,365 --> 00:03:10,495
might be a little
bit more daunting.

64
00:03:10,495 --> 00:03:12,790
I just want to be
mindful of what is

65
00:03:12,790 --> 00:03:15,510
the strategy that we're
taking towards this.

66
00:03:15,510 --> 00:03:17,250
We do have the seek
food function.

67
00:03:17,250 --> 00:03:19,520
This is what we're going to
be working with right now.

68
00:03:19,520 --> 00:03:21,350
Let's write an outline

69
00:03:21,350 --> 00:03:23,450
of what we want this
function to do.

70
00:03:23,450 --> 00:03:29,870
We want to find
the closest food.

71
00:03:33,630 --> 00:03:40,025
Let's just also
look at the food.

72
00:03:40,025 --> 00:03:42,630
Basically, orient
yourself to the food,

73
00:03:42,630 --> 00:03:48,610
and then move towards the food.

74
00:03:48,650 --> 00:03:54,250
Then later, we're
going to eat it.

75
00:03:57,560 --> 00:04:00,790
Probably, we're going to
write some transitions

76
00:04:00,790 --> 00:04:03,430
as well like, at that point,

77
00:04:03,430 --> 00:04:05,730
you might not be hungry
anymore and you transition

78
00:04:05,730 --> 00:04:09,440
to where your hungry
state should be false.

79
00:04:09,440 --> 00:04:12,100
We could also say,
well, after eating,

80
00:04:12,100 --> 00:04:14,105
maybe you get tired,
so we could say,

81
00:04:14,105 --> 00:04:16,490
you're not awakening once
you go to take a nap.

82
00:04:16,490 --> 00:04:18,640
You eat something and
maybe you take a nap,

83
00:04:18,640 --> 00:04:20,665
and there's a resting state.

84
00:04:20,665 --> 00:04:23,345
Then the resting
state comes back.

85
00:04:23,345 --> 00:04:26,400
Once you've recovered
from resting,

86
00:04:26,400 --> 00:04:28,860
you wake up and you
start over again.

87
00:04:28,860 --> 00:04:30,680
That could be the
cycle that we're

88
00:04:30,680 --> 00:04:32,565
going to build at the moment.

89
00:04:32,565 --> 00:04:35,800
Let's start by defining
closest food, which is, again,

90
00:04:35,800 --> 00:04:40,405
an algorithm that we
have written before.

91
00:04:40,405 --> 00:04:46,610
Define find closest food.

92
00:04:48,660 --> 00:04:55,085
We usually do this by starting
with a closest distance,

93
00:04:55,085 --> 00:04:57,240
with a very high number,

94
00:04:57,240 --> 00:04:59,740
maybe that's not too high,

95
00:05:06,520 --> 00:05:13,760
and the closest ID.

96
00:05:13,760 --> 00:05:15,785
Let's start with a -1,

97
00:05:15,785 --> 00:05:21,920
and for i, and food.

98
00:05:21,920 --> 00:05:23,550
We're going to do this technique

99
00:05:23,550 --> 00:05:25,890
now that we're a bit
more advanced in

100
00:05:25,890 --> 00:05:27,850
programming where we're
going to just be able

101
00:05:27,850 --> 00:05:31,470
to use the enumerate.

102
00:05:32,030 --> 00:05:36,570
This way, using this function,

103
00:05:36,570 --> 00:05:42,010
we can actually look through
all the food entities here.

104
00:05:42,590 --> 00:05:45,650
The herbivore is going through

105
00:05:45,650 --> 00:05:48,310
all the food entities available.

106
00:05:48,310 --> 00:05:50,090
Well, first of all,

107
00:05:50,090 --> 00:05:51,790
do we have access
to the old foods?

108
00:05:51,790 --> 00:05:53,270
Let's just double check that,

109
00:05:53,270 --> 00:05:55,810
because I don't remember
if we actually wrote that

110
00:05:55,810 --> 00:05:59,710
into our herbivore class.

111
00:05:59,990 --> 00:06:04,780
We don't have a reference
to that. That's new here.

112
00:06:10,950 --> 00:06:25,400
Let's just make a
variable, all_foods.

113
00:06:34,340 --> 00:06:38,730
We're going to have to
provide that from outside.

114
00:06:38,730 --> 00:06:42,785
This is going to change
the way we construct.

115
00:06:42,785 --> 00:06:44,620
Once we construct the variable,

116
00:06:44,620 --> 00:06:47,515
we need to be passing on the
collection of the foods,

117
00:06:47,515 --> 00:06:49,735
basically, the collection of,

118
00:06:49,735 --> 00:06:51,820
let's just call it all_food.

119
00:06:51,820 --> 00:06:56,455
Sounds weird as a plural.

120
00:06:56,455 --> 00:07:01,600
All_food. When we go

121
00:07:01,600 --> 00:07:06,175
into the construction
of the herbivore.

122
00:07:06,175 --> 00:07:09,820
Herbivore equals new_herbivore.

123
00:07:09,820 --> 00:07:15,790
We need to provide the
all_food list here in

124
00:07:15,790 --> 00:07:17,695
the constructor, we need to
make sure that we do that.

125
00:07:17,695 --> 00:07:20,950
Also, if you would do it
through this function,

126
00:07:20,950 --> 00:07:22,330
which we were doing before,

127
00:07:22,330 --> 00:07:25,030
we would also need
to provide it here,

128
00:07:25,030 --> 00:07:28,195
because now the
constructor would require

129
00:07:28,195 --> 00:07:32,695
the all_food list in
order to execute.

130
00:07:32,695 --> 00:07:35,450
Let's make sure we do that.

131
00:07:35,700 --> 00:07:38,110
Let's go back to our herbivore.

132
00:07:38,110 --> 00:07:39,865
Now that the herbivore has

133
00:07:39,865 --> 00:07:43,645
visibility to the
food collection,

134
00:07:43,645 --> 00:07:46,180
we can continue doing
what we were doing.

135
00:07:46,180 --> 00:07:48,415
I was getting ahead
of myself in terms of

136
00:07:48,415 --> 00:07:52,540
accessing something that
I assumed we had already,

137
00:07:52,540 --> 00:07:54,685
which is the all_food.

138
00:07:54,685 --> 00:07:59,185
Let's just spell that correctly,
the all_food variable.

139
00:07:59,185 --> 00:08:01,690
The way we've done
this in the past is

140
00:08:01,690 --> 00:08:04,330
using a difference vector.

141
00:08:04,330 --> 00:08:07,670
We take self.position.copy.

142
00:08:07,710 --> 00:08:10,375
We copy the position,

143
00:08:10,375 --> 00:08:15,320
and we substract
the food position.

144
00:08:25,650 --> 00:08:27,850
We should have called
this position,

145
00:08:27,850 --> 00:08:30,340
but we call it vector_position.

146
00:08:30,340 --> 00:08:33,355
We need to sometimes remember
that I would rather keep

147
00:08:33,355 --> 00:08:37,285
the convention that all our
classes have a position.

148
00:08:37,285 --> 00:08:38,590
But for some reason,

149
00:08:38,590 --> 00:08:43,700
I wrote vector_position
at the time.

150
00:08:44,010 --> 00:08:46,825
We could refactor this, meaning,

151
00:08:46,825 --> 00:08:49,765
change the naming
conventions of variable.

152
00:08:49,765 --> 00:08:53,920
You can do that with I think
command F in the Mac or

153
00:08:53,920 --> 00:08:56,590
Control F and just
change all the instances

154
00:08:56,590 --> 00:09:00,160
of a particular variable.

155
00:09:00,160 --> 00:09:06,800
But we're not going to do
that here yet in distance.

156
00:09:07,320 --> 00:09:10,015
We're going to say
diff.magnitude.

157
00:09:10,015 --> 00:09:12,850
The magnitude we created
the substract vector

158
00:09:12,850 --> 00:09:14,020
between the position of

159
00:09:14,020 --> 00:09:16,345
the herbivore and the
position of the food.

160
00:09:16,345 --> 00:09:18,280
We create that
vector, we calculate

161
00:09:18,280 --> 00:09:19,390
the magnitude of that vector,

162
00:09:19,390 --> 00:09:21,580
and that gives us the distance.

163
00:09:21,580 --> 00:09:30,440
If the distance is smaller
than the closest distance,

164
00:09:33,660 --> 00:09:41,380
well, then the closest distance
becomes the distance and

165
00:09:41,380 --> 00:09:49,570
the closest ID becomes i.

166
00:09:49,570 --> 00:09:51,970
We use the enumerate
to be able to

167
00:09:51,970 --> 00:09:54,460
have both access to the i,

168
00:09:54,460 --> 00:09:58,780
the index of the
list and then food,

169
00:09:58,780 --> 00:10:00,055
which is the entry,

170
00:10:00,055 --> 00:10:01,765
the item that we're evaluating.

171
00:10:01,765 --> 00:10:03,970
This is a way of having
this loop giving

172
00:10:03,970 --> 00:10:06,250
us both of those pieces
of information which

173
00:10:06,250 --> 00:10:12,110
we needed for the
calculation of the index.

174
00:10:12,840 --> 00:10:15,640
Again, we did spend

175
00:10:15,640 --> 00:10:18,010
a bit more time looking
at this algorithm before,

176
00:10:18,010 --> 00:10:21,040
so I would refer you to that
video where we go a little

177
00:10:21,040 --> 00:10:25,130
bit in a further explanation
of how this works.

178
00:10:25,200 --> 00:10:30,205
Closest_food. The
closest_food now

179
00:10:30,205 --> 00:10:35,120
is going to be the
self.all food,

180
00:10:36,600 --> 00:10:41,060
using the closest ID.

181
00:10:42,750 --> 00:10:46,510
That is the actual food element.

182
00:10:46,510 --> 00:10:48,950
We're using the closest ID.

183
00:10:49,170 --> 00:10:53,050
Here, what I would like
to make sure that we

184
00:10:53,050 --> 00:10:57,490
are going to draw

185
00:10:57,490 --> 00:11:01,880
it just because I would
like to evaluate,

186
00:11:04,740 --> 00:11:09,260
have some visual confirmation.

187
00:11:09,920 --> 00:11:15,060
Self.position.x and
self.position.y.

188
00:11:15,060 --> 00:11:21,340
Here, let's use the
closest_food.vec_position.x,

189
00:11:29,570 --> 00:11:39,370
closest_food.vec_position.y.
Then we also

190
00:11:39,370 --> 00:11:43,900
want to return because
what we want to pass

191
00:11:43,900 --> 00:11:49,880
on to the rest of the
algorithm is the closest_food.

192
00:11:51,240 --> 00:11:54,190
Let's just for good measure,

193
00:11:54,190 --> 00:12:02,080
test that this part of
the algorithm is working.

194
00:12:02,080 --> 00:12:04,075
We're replacing this outline.

195
00:12:04,075 --> 00:12:06,505
Is a pseudo-code
kind of intention

196
00:12:06,505 --> 00:12:10,750
with the actual algorithm.

197
00:12:10,750 --> 00:12:13,480
Hopefully, when we
start seeking for food,

198
00:12:13,480 --> 00:12:15,340
we're going to basically find

199
00:12:15,340 --> 00:12:18,800
the closest_food and draw
a line towards that entry.

200
00:12:18,800 --> 00:12:22,990
We are running into
some issues, let's see.

201
00:12:29,960 --> 00:12:32,760
One of my most common mistakes,

202
00:12:32,760 --> 00:12:40,530
I think it's
forgetting the self.

203
00:12:40,530 --> 00:12:46,770
Let's see if that helps.

204
00:12:46,770 --> 00:12:48,960
We're still wondering,

205
00:12:48,960 --> 00:12:51,585
we can see that in the
console down here,

206
00:12:51,585 --> 00:12:53,610
and now we transition
to seeking food and we

207
00:12:53,610 --> 00:12:56,625
draw a line to the closest food.

208
00:12:56,625 --> 00:12:59,355
It's dynamic. It's being
calculated every frame so,

209
00:12:59,355 --> 00:13:02,850
if for some reason
there's food entry,

210
00:13:02,850 --> 00:13:06,615
you see like this one that
is closer, that's updated.

211
00:13:06,615 --> 00:13:09,195
That's actually working well.

212
00:13:09,195 --> 00:13:11,235
We have that in place.

213
00:13:11,235 --> 00:13:15,940
Let's do one more, which
is look towards target.

214
00:13:16,040 --> 00:13:22,660
Let's define look towards.

215
00:13:28,280 --> 00:13:30,810
This is going to be a
generic function that

216
00:13:30,810 --> 00:13:33,210
takes a target vector,

217
00:13:33,210 --> 00:13:37,960
and it's going to
calculate the difference.

218
00:13:48,080 --> 00:13:50,190
Taking the target vector,

219
00:13:50,190 --> 00:13:52,260
let's create a copy of that,

220
00:13:52,260 --> 00:13:57,790
and do a substruction
to the position.

221
00:13:58,340 --> 00:14:01,815
What we're doing here
is, again, similar idea;

222
00:14:01,815 --> 00:14:04,320
creating a substruction between

223
00:14:04,320 --> 00:14:06,240
our position and
that foot position

224
00:14:06,240 --> 00:14:07,560
or the target position,

225
00:14:07,560 --> 00:14:09,030
we're going to create a vector

226
00:14:09,030 --> 00:14:11,040
between those two
with substruction.

227
00:14:11,040 --> 00:14:14,200
We're going to calculate
the current magnitude.

228
00:14:19,070 --> 00:14:30,975
It's going to be the magnitude

229
00:14:30,975 --> 00:14:33,040
of our velocity.

230
00:14:34,130 --> 00:14:43,860
This vector, we can
normalize it and scale

231
00:14:43,860 --> 00:14:50,910
it by the magnitude

232
00:14:50,910 --> 00:14:57,640
of the velocity and
finally, assign that.

233
00:15:00,680 --> 00:15:05,715
What we're doing here is
because we're associating

234
00:15:05,715 --> 00:15:11,235
the velocity vector as the
orientation of the herbivore,

235
00:15:11,235 --> 00:15:13,950
we're saying, create
a vector that's

236
00:15:13,950 --> 00:15:17,370
the vector between
the two units,

237
00:15:17,370 --> 00:15:20,310
store the magnitude
of your velocity,

238
00:15:20,310 --> 00:15:24,345
and now we're going to
match that vector that

239
00:15:24,345 --> 00:15:29,745
orient the herbivore
towards this target.

240
00:15:29,745 --> 00:15:34,380
We give it that magnitude,

241
00:15:34,380 --> 00:15:38,415
and then that new vector
becomes the velocity.

242
00:15:38,415 --> 00:15:40,950
We're overriding the
velocity completely for

243
00:15:40,950 --> 00:15:42,315
this new vector
that actually looks

244
00:15:42,315 --> 00:15:44,610
into the direction of the food.

245
00:15:44,610 --> 00:15:48,060
I think I spelled
wrong normalize.

246
00:15:48,060 --> 00:15:55,810
There we go. Normalize.
Now we have this function,

247
00:15:59,030 --> 00:16:03,940
self.look_towards, the
target, in this case.

248
00:16:04,460 --> 00:16:07,320
We need to provide
in the function.

249
00:16:07,320 --> 00:16:14,250
We're going to say that
the closest food equals,

250
00:16:14,250 --> 00:16:15,825
because remember
that this function

251
00:16:15,825 --> 00:16:17,700
defined closest returns value,

252
00:16:17,700 --> 00:16:19,350
returns the closest food,

253
00:16:19,350 --> 00:16:21,810
so we're going to say
the closest food is

254
00:16:21,810 --> 00:16:24,825
the execution of define
closest_food function,

255
00:16:24,825 --> 00:16:26,490
and now we can use

256
00:16:26,490 --> 00:16:30,510
the vector of position

257
00:16:30,510 --> 00:16:35,230
of that food, so
closest_food.position.vec_position.

258
00:16:37,310 --> 00:16:40,470
The position of the food,

259
00:16:40,470 --> 00:16:41,700
we basically need
to give a vector,

260
00:16:41,700 --> 00:16:45,750
and the vector we're looking
at is from the food,

261
00:16:45,750 --> 00:16:47,190
which is the closest
food we're looking

262
00:16:47,190 --> 00:16:49,215
at the vector position.

263
00:16:49,215 --> 00:16:52,030
The only thing that we
should see at this point,

264
00:16:53,800 --> 00:17:00,120
is that our agent

265
00:17:00,120 --> 00:17:03,840
actually or herbivore orients
itself towards that food,

266
00:17:03,840 --> 00:17:05,115
which is the closest food,

267
00:17:05,115 --> 00:17:06,510
and the other one,

268
00:17:06,510 --> 00:17:10,270
we already written
it, so self.move.

269
00:17:10,700 --> 00:17:12,915
We have this function already.

270
00:17:12,915 --> 00:17:14,610
The move is just moving

271
00:17:14,610 --> 00:17:17,145
in the direction
of your velocity.

272
00:17:17,145 --> 00:17:20,190
Let's see if we
can get it to move

273
00:17:20,190 --> 00:17:22,800
towards the closest food.

274
00:17:22,800 --> 00:17:24,375
In wondering mode, we are

275
00:17:24,375 --> 00:17:26,655
engaging with a
different behavior.

276
00:17:26,655 --> 00:17:28,920
At some point, we
transition, and you can see,

277
00:17:28,920 --> 00:17:30,870
now the herbivore, it's

278
00:17:30,870 --> 00:17:33,810
actually moving towards
that closest food.

279
00:17:33,810 --> 00:17:36,915
Here, because we're
not eating it yet,

280
00:17:36,915 --> 00:17:39,310
it's just stuck,

281
00:17:42,380 --> 00:17:46,950
keeps on moving
around that target.

282
00:17:46,950 --> 00:17:49,300
We can try it again.

283
00:17:49,400 --> 00:17:51,750
But, yeah, this is
working pretty well.

284
00:17:51,750 --> 00:17:53,670
We have basically
the wonder behavior

285
00:17:53,670 --> 00:17:55,155
and then the seeking
food behavior.

286
00:17:55,155 --> 00:17:56,880
What I would like to do in

287
00:17:56,880 --> 00:17:58,185
the next video is maybe start

288
00:17:58,185 --> 00:17:59,655
giving it a bit of expressivity.

289
00:17:59,655 --> 00:18:01,140
Maybe when you're
seeking food you're

290
00:18:01,140 --> 00:18:03,090
actually moving a
little bit faster.

291
00:18:03,090 --> 00:18:04,680
You're having a sense of

292
00:18:04,680 --> 00:18:08,310
urgency and maybe
there's competition,

293
00:18:08,310 --> 00:18:09,930
and maybe two
different herbivores

294
00:18:09,930 --> 00:18:11,535
are going for the
same food supply,

295
00:18:11,535 --> 00:18:16,080
so moving faster may get

296
00:18:16,080 --> 00:18:18,240
a bit more expressive in
terms of the behaviors that

297
00:18:18,240 --> 00:18:20,520
we're separating it from
the wonder behavior.

298
00:18:20,520 --> 00:18:21,930
Which is more like,
oh, I'm just relaxed

299
00:18:21,930 --> 00:18:23,370
wandering around, and
then at some point,

300
00:18:23,370 --> 00:18:27,195
I get hungry, I really want
to just go and get my food.

301
00:18:27,195 --> 00:18:29,760
We'll leave it here.
We'll continue

302
00:18:29,760 --> 00:18:31,665
building up on these behaviors

303
00:18:31,665 --> 00:18:34,120
in the next video, so
I'll see you then.