1
00:00:00,000 --> 00:00:02,667
(upbeat music)

2
00:00:05,535 --> 00:00:07,605
A few videos back I mentioned that the way

3
00:00:07,605 --> 00:00:10,635
we were adding loot to the inventory wasn't a good idea.

4
00:00:10,635 --> 00:00:12,393
And in this video we're going to look at why

5
00:00:12,393 --> 00:00:14,815
that isn't a good idea and what we can do about it.

6
00:00:14,815 --> 00:00:16,271
We're going to start though by deleting

7
00:00:16,271 --> 00:00:18,755
the code we used for for loops

8
00:00:18,755 --> 00:00:21,099
and un-commenting our player code.

9
00:00:21,099 --> 00:00:24,585
So I'm just going to delete the for loop code

10
00:00:24,585 --> 00:00:27,845
and I'm going to select or delete the rest of it first.

11
00:00:27,845 --> 00:00:31,626
And select the rest of the code that was commented out.

12
00:00:31,626 --> 00:00:32,879
You can come up to the code menu

13
00:00:32,879 --> 00:00:36,426
and I can click on comment with live comment

14
00:00:36,426 --> 00:00:41,119
which un-does the changes if it was already commented at.

15
00:00:41,119 --> 00:00:43,294
And obviously these other things that were commented at,

16
00:00:43,294 --> 00:00:45,275
were things that were commented at previously,

17
00:00:45,275 --> 00:00:47,152
in case you're wondering why that's still

18
00:00:47,152 --> 00:00:48,459
sitting there and commented at.

19
00:00:48,459 --> 00:00:50,412
Okay, let's just run the programme

20
00:00:50,412 --> 00:00:52,745
and make sure that it works.

21
00:00:59,228 --> 00:01:01,770
Okay, we can see that we've got our code working again,

22
00:01:01,770 --> 00:01:03,325
everything's working nicely.

23
00:01:03,325 --> 00:01:05,415
So getting back to the problem at hand,

24
00:01:05,415 --> 00:01:08,049
why isn't it a good idea for our main function

25
00:01:08,049 --> 00:01:09,664
to add loot to Tim's inventory

26
00:01:09,664 --> 00:01:13,264
in this fashion that it's doing here.

27
00:01:13,264 --> 00:01:15,784
Well there's a couple reasons why it's not a good idea.

28
00:01:15,784 --> 00:01:18,622
One reason is that main shouldn't have to know

29
00:01:18,622 --> 00:01:21,987
that the players are using an array list to store the loot.

30
00:01:21,987 --> 00:01:24,297
So looking at our player class

31
00:01:24,297 --> 00:01:27,421
we've declared inventory to be an array list.

32
00:01:27,421 --> 00:01:29,579
Now we may decide to change that in the future

33
00:01:29,579 --> 00:01:31,851
to use some other kind of structure.

34
00:01:31,851 --> 00:01:35,896
Now if we do that, we might break the code in main.

35
00:01:35,896 --> 00:01:38,197
Our main function's expecting an array list

36
00:01:38,197 --> 00:01:40,823
with an add method that it can use.

37
00:01:40,823 --> 00:01:42,733
Now if we use something else, maybe a structure

38
00:01:42,733 --> 00:01:44,982
that has a pin function instead of add

39
00:01:44,982 --> 00:01:47,329
then the code in main would stop working.

40
00:01:47,329 --> 00:01:48,619
Now one of the principles

41
00:01:48,619 --> 00:01:52,256
of object oriented programming is encapsulation.

42
00:01:52,256 --> 00:01:54,347
So encapsulation here, basically means

43
00:01:54,347 --> 00:01:57,826
not exposing the inner workings of a class

44
00:01:57,826 --> 00:02:00,354
to code outside of that class.

45
00:02:00,354 --> 00:02:03,199
Now Kotlin takes a more relaxed attitude or approach

46
00:02:03,199 --> 00:02:05,334
to encapsulating class properties.

47
00:02:05,334 --> 00:02:07,697
Everything's public by default.

48
00:02:07,697 --> 00:02:09,235
Now that's why the main function

49
00:02:09,235 --> 00:02:12,043
can directly access inventory.

50
00:02:12,043 --> 00:02:14,337
Now if we want to encapsulate our inventory,

51
00:02:14,337 --> 00:02:16,699
we can mark it as private.

52
00:02:16,699 --> 00:02:19,507
So come up here to the definition on line seven

53
00:02:19,507 --> 00:02:23,755
and type private ahead of the val inventory

54
00:02:23,755 --> 00:02:26,291
and now nothing outside of the player class

55
00:02:26,291 --> 00:02:28,812
can access the inventory.

56
00:02:28,812 --> 00:02:31,996
Now by default Kotlin makes properties and functions public,

57
00:02:31,996 --> 00:02:35,105
which means that they're available to external code.

58
00:02:35,105 --> 00:02:38,116
Anything that creates an instance of our player class,

59
00:02:38,116 --> 00:02:41,897
for example, could access all it's properties and functions.

60
00:02:41,897 --> 00:02:44,705
Now you can find the documentation and visibility

61
00:02:44,705 --> 00:02:47,821
modifiers in Kotlin and I'm just gonna put the link,

62
00:02:47,821 --> 00:02:49,783
bring the link up into a browser.

63
00:02:49,783 --> 00:02:51,950
Have a quick look at that.

64
00:02:58,326 --> 00:03:00,688
Now I'm not actually going to go through this document.

65
00:03:00,688 --> 00:03:02,982
It can be quite confusing at the moment,

66
00:03:02,982 --> 00:03:06,091
but it's worth bookmarking this page for reference later.

67
00:03:06,091 --> 00:03:07,480
When you find some code that uses

68
00:03:07,480 --> 00:03:09,804
the internal modifier, for example, you can

69
00:03:09,804 --> 00:03:12,989
check back here to find out what that means.

70
00:03:12,989 --> 00:03:14,257
So scrolling down quickly, we'll get

71
00:03:14,257 --> 00:03:18,211
to the classes and interfaces section.

72
00:03:18,211 --> 00:03:19,139
You see that it's a description

73
00:03:19,139 --> 00:03:21,972
on the private modifier, up here.

74
00:03:22,807 --> 00:03:26,112
Means visible inside the class only,

75
00:03:26,112 --> 00:03:28,279
including all its members.

76
00:03:29,259 --> 00:03:32,163
So by marking the inventory properly as private,

77
00:03:32,163 --> 00:03:34,759
it's now no longer available to any code

78
00:03:34,759 --> 00:03:37,069
outside of the player class.

79
00:03:37,069 --> 00:03:38,208
Now of course that should mean

80
00:03:38,208 --> 00:03:39,929
that we've now broken main.

81
00:03:39,929 --> 00:03:42,596
So if I switch back to that now,

82
00:03:44,668 --> 00:03:47,241
you can see we've got some errors showing.

83
00:03:47,241 --> 00:03:51,158
So every time main tries to access a player's inventory

84
00:03:51,158 --> 00:03:53,362
Android Studio is showing an error.

85
00:03:53,362 --> 00:03:56,229
Now that's not good, but it's okay to get errors

86
00:03:56,229 --> 00:03:58,259
while you're still developing your classes.

87
00:03:58,259 --> 00:04:01,504
That's normal as you try things out and modify your design.

88
00:04:01,504 --> 00:04:03,670
What's not good though, is modifying a class

89
00:04:03,670 --> 00:04:07,043
once it's been used and breaking all the code that uses it.

90
00:04:07,043 --> 00:04:09,911
So that's one of the things we're trying to avoid here.

91
00:04:09,911 --> 00:04:13,216
Now if we don't want main or any other client code

92
00:04:13,216 --> 00:04:16,152
of our player class to access the inventory directly,

93
00:04:16,152 --> 00:04:18,182
then we need to provide a method for clients

94
00:04:18,182 --> 00:04:21,797
to call when they need to add things to the inventory.

95
00:04:21,797 --> 00:04:24,317
So I'm going to call that method or function

96
00:04:24,317 --> 00:04:27,532
get loot and that reflects what's happening

97
00:04:27,532 --> 00:04:30,355
when loot's added to a player's inventory.

98
00:04:30,355 --> 00:04:32,405
So let's go ahead and do that.

99
00:04:32,405 --> 00:04:33,915
Go back to the player class,

100
00:04:33,915 --> 00:04:38,027
we're going to add that below, the toString function.

101
00:04:38,027 --> 00:04:39,491
And again what we're doing is, we're creating

102
00:04:39,491 --> 00:04:41,778
a function for clients to call when they need

103
00:04:41,778 --> 00:04:44,332
to add things to the inventory.

104
00:04:44,332 --> 00:04:47,415
We'll start with fun, space, getloot

105
00:04:49,408 --> 00:04:51,241
(item

106
00:04:52,154 --> 00:04:52,987
:loot

107
00:04:56,582 --> 00:05:00,332
After {, it's going to be inventory.add item.

108
00:05:03,147 --> 00:05:06,038
So now that we've done that, we can go back to our main

109
00:05:06,038 --> 00:05:09,358
and we can change main to use the getloot function

110
00:05:09,358 --> 00:05:11,999
instead of accessing the inventory directly.

111
00:05:11,999 --> 00:05:15,199
So to do that we type, we select,

112
00:05:15,199 --> 00:05:16,866
we type tim.getloot.

113
00:05:28,284 --> 00:05:30,269
Those two changes there and then for the second one

114
00:05:30,269 --> 00:05:32,269
we do something similar.

115
00:05:33,982 --> 00:05:34,815
Getloot

116
00:05:43,631 --> 00:05:44,464
Getloot

117
00:05:47,685 --> 00:05:49,104
The right number of parentheses

118
00:05:49,104 --> 00:05:52,319
there to keep everything consistent and working okay.

119
00:05:52,319 --> 00:05:55,805
We've now changed it so that the main function

120
00:05:55,805 --> 00:05:58,303
is no longer accessing inventory directly.

121
00:05:58,303 --> 00:06:01,918
Rather it's doing it via the getloot function.

122
00:06:01,918 --> 00:06:02,846
Let's just run the programme

123
00:06:02,846 --> 00:06:06,763
to make sure everything works as it did before.

124
00:06:12,241 --> 00:06:15,388
And you can see we still got the same results when we run it

125
00:06:15,388 --> 00:06:17,184
but now though main doesn't know

126
00:06:17,184 --> 00:06:19,569
how the player class is storing the loot.

127
00:06:19,569 --> 00:06:22,339
So it can call the getloot function,

128
00:06:22,339 --> 00:06:24,301
passing on a piece of loot and leave details

129
00:06:24,301 --> 00:06:27,417
of how to store it to the player class.

130
00:06:27,417 --> 00:06:30,421
So our inventory is now encapsulated and isn't

131
00:06:30,421 --> 00:06:34,398
available to any code outside of the player class.

132
00:06:34,398 --> 00:06:37,598
Now another reason for encapsulating data like this,

133
00:06:37,598 --> 00:06:39,680
is let's say we want to store the inventory

134
00:06:39,680 --> 00:06:41,778
to disc whenever it changes.

135
00:06:41,778 --> 00:06:44,035
That way we when I come to play the game again,

136
00:06:44,035 --> 00:06:46,336
my inventory can be loaded back up,

137
00:06:46,336 --> 00:06:48,050
and I'll still have all my loot.

138
00:06:48,050 --> 00:06:50,721
Now before we encapsulated the inventory,

139
00:06:50,721 --> 00:06:52,238
we'll have to add code to store it

140
00:06:52,238 --> 00:06:54,630
each time we added new loot.

141
00:06:54,630 --> 00:06:56,758
Now that's something we could forget to do,

142
00:06:56,758 --> 00:06:58,901
which wouldn't make our players very happy.

143
00:06:58,901 --> 00:07:01,920
So we could introduce a bug into our code quite easily.

144
00:07:01,920 --> 00:07:04,199
But now though, we just need to add the code

145
00:07:04,199 --> 00:07:07,452
to save the inventory in the getloot function.

146
00:07:07,452 --> 00:07:12,452
In other words, to go back now to the player class and here,

147
00:07:14,687 --> 00:07:16,854
code to save the inventory

148
00:07:18,587 --> 00:07:19,976
goes here.

149
00:07:19,976 --> 00:07:22,308
I'm not going to add the code to store the inventory

150
00:07:22,308 --> 00:07:23,901
but you can see how we only have to put

151
00:07:23,901 --> 00:07:26,466
this code in a single place now.

152
00:07:26,466 --> 00:07:28,693
Whenever a new piece of loot gets added,

153
00:07:28,693 --> 00:07:31,296
the inventory could be saved to disc,

154
00:07:31,296 --> 00:07:32,639
and it will always be up to date,

155
00:07:32,639 --> 00:07:36,692
and there's no chance of us forgetting to save it in main.

156
00:07:36,692 --> 00:07:37,696
So that's another reason why

157
00:07:37,696 --> 00:07:40,835
our previous approach wasn't a good idea.

158
00:07:40,835 --> 00:07:42,918
Okay so if we're going to prevent external code

159
00:07:42,918 --> 00:07:44,585
from accessing the inventory, we should

160
00:07:44,585 --> 00:07:47,929
also provide a way to remove items from our loot.

161
00:07:47,929 --> 00:07:50,298
So let's go ahead and write another function here.

162
00:07:50,298 --> 00:07:52,909
We're going to call this one droploot.

163
00:07:52,909 --> 00:07:55,166
It's slightly more complex than getloot,

164
00:07:55,166 --> 00:07:57,775
because we need to make sure that we've got the item,

165
00:07:57,775 --> 00:07:58,998
before trying to drop it.

166
00:07:58,998 --> 00:08:01,217
So let's start with the definition,

167
00:08:01,217 --> 00:08:02,217
fun droploot

168
00:08:04,743 --> 00:08:07,076
(item: Loot

169
00:08:09,086 --> 00:08:09,919
: Boolean.

170
00:08:11,269 --> 00:08:13,704
Then we have that code block.

171
00:08:13,704 --> 00:08:16,371
Then we're going to do return if

172
00:08:17,401 --> 00:08:19,125
inventory dot

173
00:08:19,125 --> 00:08:19,958
contains

174
00:08:20,981 --> 00:08:21,814
item.

175
00:08:23,705 --> 00:08:26,901
Close our parentheses and add another code block.

176
00:08:26,901 --> 00:08:27,984
Inventory dot

177
00:08:29,152 --> 00:08:29,985
remove

178
00:08:31,356 --> 00:08:32,188
item.

179
00:08:34,849 --> 00:08:36,313
True.

180
00:08:36,313 --> 00:08:37,980
The next line, else,

181
00:08:39,331 --> 00:08:40,164
false.

182
00:08:43,578 --> 00:08:45,798
So I've used if as an expression there,

183
00:08:45,798 --> 00:08:48,696
which we covered earlier in this tutorial section.

184
00:08:48,696 --> 00:08:51,798
Now if the item of loot exists in the inventory,

185
00:08:51,798 --> 00:08:54,386
we remove it and return true.

186
00:08:54,386 --> 00:08:57,284
Now if it didn't exist it will return false.

187
00:08:57,284 --> 00:08:58,831
So that's letting the calling code know

188
00:08:58,831 --> 00:09:02,144
that if the item was successfully removed or not.

189
00:09:02,144 --> 00:09:04,438
So let's see how that works in main,

190
00:09:04,438 --> 00:09:06,022
we'll go back to main now.

191
00:09:06,022 --> 00:09:07,395
And right down to the end here

192
00:09:07,395 --> 00:09:10,564
after the last showInventory,

193
00:09:10,564 --> 00:09:12,458
let's try and drop the red potion.

194
00:09:12,458 --> 00:09:14,549
So we're going to put if

195
00:09:14,549 --> 00:09:16,812
(tim

196
00:09:16,812 --> 00:09:17,645
.droploot

197
00:09:18,713 --> 00:09:21,213
that's going to be red potion,

198
00:09:22,373 --> 00:09:23,498
Code block.

199
00:09:23,498 --> 00:09:25,158
Tim

200
00:09:25,158 --> 00:09:26,408
.showInventory.

201
00:09:27,512 --> 00:09:29,587
So let's run the programme and we should find

202
00:09:29,587 --> 00:09:33,754
that the red potion is removed from the inventory.

203
00:09:40,295 --> 00:09:42,330
So you can see we've got our first printout

204
00:09:42,330 --> 00:09:44,225
of Tim's inventory, the red potion was there.

205
00:09:44,225 --> 00:09:47,395
Then after the call to the droploot,

206
00:09:47,395 --> 00:09:50,255
the second time, the second block of code here,

207
00:09:50,255 --> 00:09:51,553
the second block of output,

208
00:09:51,553 --> 00:09:54,489
the red potion is no longer there.

209
00:09:54,489 --> 00:09:56,790
Now we should also test what happens

210
00:09:56,790 --> 00:09:58,617
if an item can't be removed.

211
00:09:58,617 --> 00:10:00,035
So I'm going to create a new piece of loot

212
00:10:00,035 --> 00:10:02,518
and try to remove it from Tim's inventory.

213
00:10:02,518 --> 00:10:04,020
Let's go ahead and do that.

214
00:10:04,020 --> 00:10:08,187
And let's also change this to put an else in here.

215
00:10:09,574 --> 00:10:11,197
Else, code block.

216
00:10:11,197 --> 00:10:12,773
And it'll be

217
00:10:12,773 --> 00:10:13,606
println,

218
00:10:17,209 --> 00:10:18,542
you don't have a

219
00:10:20,432 --> 00:10:23,695
$, that's a right curving braces

220
00:10:23,695 --> 00:10:24,862
redpotion.name

221
00:10:26,218 --> 00:10:28,180
So we're printing something out that's not there,

222
00:10:28,180 --> 00:10:31,017
but let's go ahead and create this other item as I mentioned

223
00:10:31,017 --> 00:10:32,267
val blue potion

224
00:10:35,794 --> 00:10:37,551
is equal to loot

225
00:10:37,551 --> 00:10:40,134
("blue potion"

226
00:10:42,601 --> 00:10:43,934
loot type.potion

227
00:10:46,489 --> 00:10:49,832
and let's we'll set the value six

228
00:10:49,832 --> 00:10:51,107
Then we'll try doing a drop,

229
00:10:51,107 --> 00:10:52,942
even though we haven't gotten it in the inventory.

230
00:10:52,942 --> 00:10:54,442
So if tim.droploot

231
00:10:57,527 --> 00:10:58,360
bluepotion

232
00:11:00,047 --> 00:11:01,464
tim.showInventory

233
00:11:02,440 --> 00:11:03,273
Else

234
00:11:05,141 --> 00:11:05,974
Code block again

235
00:11:05,974 --> 00:11:08,141
That's going to be println

236
00:11:09,197 --> 00:11:10,364
You don't have

237
00:11:13,670 --> 00:11:14,682
Pound sign

238
00:11:14,682 --> 00:11:18,432
That's right curving braces, bluepotion.name.

239
00:11:23,403 --> 00:11:26,236
Alright so let's try running that.

240
00:11:32,768 --> 00:11:34,523
What I should probably do to avoid some confusion

241
00:11:34,523 --> 00:11:36,300
is just delete that last line there.

242
00:11:36,300 --> 00:11:39,217
So let's just try running it again.

243
00:11:44,639 --> 00:11:46,299
And you can see this time we got the message,

244
00:11:46,299 --> 00:11:48,404
you don't have blue potion.

245
00:11:48,404 --> 00:11:49,657
So that's working well.

246
00:11:49,657 --> 00:11:52,510
Our players can now pick up loot and drop it again.

247
00:11:52,510 --> 00:11:53,343
But what about something

248
00:11:53,343 --> 00:11:55,438
like the Invisibility Potion though?

249
00:11:55,438 --> 00:11:57,309
You can see that the way we've defined it,

250
00:11:57,309 --> 00:11:59,664
we haven't actually got a reference to it in main.

251
00:11:59,664 --> 00:12:02,878
So we can't call the droploot function to drop it.

252
00:12:02,878 --> 00:12:04,591
So that's probably something we probably shouldn't

253
00:12:04,591 --> 00:12:06,644
have called getloot the way we did

254
00:12:06,644 --> 00:12:09,097
for the Ring of Protection and Invisibility Potion

255
00:12:09,097 --> 00:12:11,097
on lines 41 and 42 here.

256
00:12:12,372 --> 00:12:14,070
So this is what I meant earlier,

257
00:12:14,070 --> 00:12:17,670
when I said we need to consider who should own the objects.

258
00:12:17,670 --> 00:12:20,733
Now both those objects really belong to the game.

259
00:12:20,733 --> 00:12:23,126
We should really have created variables to hold

260
00:12:23,126 --> 00:12:26,016
a reference to them in main, so that's how

261
00:12:26,016 --> 00:12:27,933
we've got a way to drop them.

262
00:12:27,933 --> 00:12:30,053
The way we've got our code currently,

263
00:12:30,053 --> 00:12:32,253
there's no way to reference,

264
00:12:32,253 --> 00:12:34,407
there's no reference to either of those bits of loot,

265
00:12:34,407 --> 00:12:37,207
so we've got no way to get Tim to drop them.

266
00:12:37,207 --> 00:12:38,754
Now that's the sort of thing you need

267
00:12:38,754 --> 00:12:40,957
to be aware of when designing your programmes.

268
00:12:40,957 --> 00:12:42,678
After coding for a while, you'll make

269
00:12:42,678 --> 00:12:45,712
the correct decision the first time, most of the time.

270
00:12:45,712 --> 00:12:48,187
Now you still make mistakes occasionally, of course.

271
00:12:48,187 --> 00:12:50,602
Just like I did there, with those two items.

272
00:12:50,602 --> 00:12:53,349
That's fine, that's all part of the learning process.

273
00:12:53,349 --> 00:12:55,847
But of course, in a real game, we'd probably

274
00:12:55,847 --> 00:12:59,099
give the players a way to go through their inventory

275
00:12:59,099 --> 00:13:01,748
and choose items to drop, so in that case

276
00:13:01,748 --> 00:13:03,340
we wouldn't have this problem.

277
00:13:03,340 --> 00:13:06,412
So in our code main is in charge of controlling everything.

278
00:13:06,412 --> 00:13:09,747
The way to fix this then is to change main,

279
00:13:09,747 --> 00:13:12,540
so that we've got references to the Ring and the Potion.

280
00:13:12,540 --> 00:13:13,822
But I'm not going to do that

281
00:13:13,822 --> 00:13:15,203
because this gives us a good excuse

282
00:13:15,203 --> 00:13:16,909
to look overloading a function

283
00:13:16,909 --> 00:13:19,278
and we'll do that in the next video.

