1 package cz.cuni.amis.pogamut.udk.agent.module.sensor;
2
3 import java.util.Collection;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import cz.cuni.amis.pogamut.udk.bot.IUDKBotController;
8 import cz.cuni.amis.pogamut.udk.bot.impl.UDKBot;
9 import cz.cuni.amis.pogamut.udk.communication.messages.ItemType;
10 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.Item;
11 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
12 import cz.cuni.amis.utils.NullCheck;
13
14 /**
15 * Module specialized on items on the map. This module extends the {@link Items}
16 * module by adding filters for usability and/or "takeability". These filters may
17 * help the agent to decide, whether it is useful for him, to forage specific
18 * items from the map.
19 * <p><p>
20 * You have to provide the implementation of {@link IItemUsefulness} interface
21 * where you have to specify <i>what usefulness is</i>.
22 * <p><p>
23 * Note that it might be useful to instantiate this class multiple times with different item filters to achieve
24 * various specialized filters (e.g., different useful filter for weapons and health).
25 * <p><p>
26 * It is designed to be initialized inside {@link IUDKBotController#initializeController(UDKBot)} method call
27 * and may be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
28 * is called.
29 *
30 * @author Juraj 'Loque' Simlovic
31 * @author Jimmy
32 */
33 public class AdvancedItems
34 {
35
36 /**
37 * Returns a filtered list of items that are guessed to be currently spawned in the map.
38 *
39 * <p><p>WARNING: O(n) complexity!
40 *
41 * <p><p>This implementation is guessing (optimistically) whether the item is spawned based on
42 * the last time we have seen it missing (saw its navpoint but the item was not laying there).
43 *
44 * <p><p>Note that the guessing is not perfect, experiment with it or check the source code
45 * and possibly reimplement to suit your needs.
46 *
47 * <p><p>Note that this method is working only if items are respawning.
48 *
49 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
50 * @return True, if the item is spawned; false if the pickup is empty.
51 */
52 public Map<UnrealId, Item> getSpawnedItems(double usefulness) {
53 return filterUsefulItems(items.getSpawnedItems().values(), usefulness);
54 }
55
56 /**
57 * Returns a filtered list of items of a <b>specific type</b> that are guessed to be currently spawned in the map.
58 *
59 * <p><p>WARNING: O(n) complexity!
60 *
61 * <p><p>This implementation is guessing (optimistically) whether the item is spawned based on
62 * the last time we have seen it missing (saw its navpoint but the item was not laying there).
63 *
64 * <p><p>Note that the guessing is not perfect, experiment with it or check the source code
65 * and possibly reimplement to suit your needs.
66 *
67 * <p><p>Note that this method is working only if items are respawning.
68 *
69 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
70 * @return Map of spawned items.
71 */
72 public Map<UnrealId, Item> getSpawnedItems(ItemType type, double usefulness) {
73 return filterUsefulItems(items.getSpawnedItems(type).values(), usefulness);
74 }
75
76 /**
77 * Returns a filtered list of items of a <b>specific category</b> that are guessed to be currently spawned in the map.
78 *
79 * <p><p>WARNING: O(n) complexity!
80 *
81 * <p><p>This implementation is guessing (optimistically) whether the item is spawned based on
82 * the last time we have seen it missing (saw its navpoint but the item was not laying there).
83 *
84 * <p><p>Note that the guessing is not perfect, experiment with it or check the source code
85 * and possibly reimplement to suit your needs.
86 *
87 * <p><p>Note that this method is working only if items are respawning.
88 *
89 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
90 * @return Map of spawned items.
91 */
92 public Map<UnrealId, Item> getSpawnedItems(ItemType.Category category, double usefulness) {
93 return filterUsefulItems(items.getSpawnedItems(category).values(), usefulness);
94 }
95
96 /**
97 * Returns a filtered list of items of a <b>specific group</b> that are guessed to be currently spawned in the map.
98 *
99 * <p><p>WARNING: O(n) complexity!
100 *
101 * <p><p>This implementation is guessing (optimistically) whether the item is spawned based on
102 * the last time we have seen it missing (saw its navpoint but the item was not laying there).
103 *
104 * <p><p>Note that the guessing is not perfect, experiment with it or check the source code
105 * and possibly reimplement to suit your needs.
106 *
107 * <p><p>Note that this method is working only if items are respawning.
108 *
109 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
110 * @return Map of spawned items.
111 */
112 public Map<UnrealId, Item> getSpawnedItems(ItemType.Group group, double usefulness) {
113 return filterUsefulItems(items.getSpawnedItems(group).values(), usefulness);
114 }
115
116 /*========================================================================*/
117
118 /**
119 * Retrieves map of all items (both known and thrown).
120 *
121 * <p><p>WARNING: O(n) complexity!
122 *
123 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
124 * @return Map of all items. Note: non-spawned items are included too.
125 */
126 public Map<UnrealId, Item> getAllItems(double usefulness)
127 {
128 return filterUsefulItems (
129 items.getAllItems().values(), usefulness
130 );
131 }
132
133 /**
134 * Retrieves map of all items of <b>specific type</b> (both known and thrown).
135 *
136 * <p><p>WARNING: O(n) complexity!
137 *
138 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
139 * @return Map of all items. Note: non-spawned items are included too.
140 */
141 public Map<UnrealId, Item> getAllItems(ItemType type, double usefulness)
142 {
143 return filterUsefulItems (items.getAllItems(type).values(), usefulness);
144 }
145
146 /**
147 * Retrieves map of all items of <b>specific category</b> (both known and thrown).
148 *
149 * <p><p>WARNING: O(n) complexity!
150 *
151 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
152 * @return Map of all items. Note: non-spawned items are included too.
153 */
154 public Map<UnrealId, Item> getAllItems(ItemType.Category category, double usefulness)
155 {
156 return filterUsefulItems (items.getAllItems(category).values(), usefulness);
157 }
158
159 /**
160 * Retrieves map of all items of <b>specific group</b> (both known and thrown).
161 *
162 * <p><p>WARNING: O(n) complexity!
163 *
164 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
165 * @return Map of all items. Note: non-spawned items are included too.
166 */
167 public Map<UnrealId, Item> getAllItems(ItemType.Group group, double usefulness)
168 {
169 return filterUsefulItems (items.getAllItems(group).values(), usefulness);
170 }
171
172 /*========================================================================*/
173
174 /**
175 * Retrieves map of all visible items.
176 *
177 * <p><p>WARNING: O(n) complexity!
178 *
179 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
180 * @return Map of all visible items. Note: Spawned items are included only.
181 */
182 public Map<UnrealId, Item> getVisibleItems(double usefulness)
183 {
184 return filterUsefulItems(items.getVisibleItems().values(), usefulness);
185 }
186
187 /**
188 * Retrieves map of all visible items of <b>specific type</b>.
189 *
190 * <p><p>WARNING: O(n) complexity!
191 *
192 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
193 * @return Map of all visible items. Note: Spawned items are included only.
194 */
195 public Map<UnrealId, Item> getVisibleItems(ItemType type, double usefulness)
196 {
197 return filterUsefulItems(items.getVisibleItems(type).values(), usefulness);
198 }
199
200 /**
201 * Retrieves map of all visible items of <b>specific category</b>.
202 *
203 * <p><p>WARNING: O(n) complexity!
204 *
205 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
206 * @return Map of all visible items. Note: Spawned items are included only.
207 */
208 public Map<UnrealId, Item> getVisibleItems(ItemType.Category category, double usefulness)
209 {
210 return filterUsefulItems(items.getVisibleItems(category).values(), usefulness);
211 }
212
213 /**
214 * Retrieves map of all visible items of <b>specific group</b>.
215 *
216 * <p><p>WARNING: O(n) complexity!
217 *
218 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
219 * @return Map of all visible items. Note: Spawned items are included only.
220 */
221 public Map<UnrealId, Item> getVisibleItems(ItemType.Group group, double usefulness)
222 {
223 return filterUsefulItems(items.getVisibleItems(group).values(), usefulness);
224 }
225
226
227 /*========================================================================*/
228
229 /**
230 * Retrieves map of all reachable items.
231 *
232 * <p><p>WARNING: O(n) complexity!
233 *
234 * <p><p><b>WARNING:</b>It is totally unclear what UT2004 means by reachable!!!
235 *
236 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
237 * @return Map of all reachable items. Note: Spawned items are included only.
238 */
239 public Map<UnrealId, Item> getReachableItems(double usefulness)
240 {
241 return filterUsefulItems(items.getReachableItems().values(), usefulness);
242 }
243
244 /**
245 * Retrieves map of all reachable items of a <b>specific type</b>.
246 *
247 * <p><p>WARNING: O(n) complexity!
248 *
249 * <p><p><b>WARNING:</b>It is totally unclear what UT2004 means by reachable!!!
250 *
251 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
252 * @return Map of all reachable items. Note: Spawned items are included only.
253 */
254 public Map<UnrealId, Item> getReachableItems(ItemType type, double usefulness)
255 {
256 return filterUsefulItems(items.getReachableItems(type).values(), usefulness);
257 }
258
259 /**
260 * Retrieves map of all reachable items of a <b>specific category</b>.
261 *
262 * <p><p>WARNING: O(n) complexity!
263 *
264 * <p><p><b>WARNING:</b>It is totally unclear what UT2004 means by reachable!!!
265 *
266 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
267 * @return Map of all reachable items. Note: Spawned items are included only.
268 */
269 public Map<UnrealId, Item> getReachableItems(ItemType.Category category, double usefulness)
270 {
271 return filterUsefulItems(items.getReachableItems(category).values(), usefulness);
272 }
273
274 /**
275 * Retrieves map of all reachable items of a <b>specific group</b>.
276 *
277 * <p><p>WARNING: O(n) complexity!
278 *
279 * <p><p><b>WARNING:</b>It is totally unclear what UT2004 means by reachable!!!
280 *
281 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
282 * @return Map of all reachable items. Note: Spawned items are included only.
283 */
284 public Map<UnrealId, Item> getReachableItems(ItemType.Group group, double usefulness)
285 {
286 return filterUsefulItems(items.getReachableItems(group).values(), usefulness);
287 }
288
289 /*========================================================================*/
290
291 /**
292 * Retrieves map of all item pickup points.
293 *
294 * <p><p>WARNING: O(n) complexity!
295 *
296 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
297 * @return Map of all items. Note: Empty pickups are included as well.
298 *
299 * @see isPickupSpawned(Item)
300 */
301 public Map<UnrealId, Item> getKnownPickups(double usefulness)
302 {
303 return filterUsefulItems(items.getKnownPickups().values(), usefulness);
304 }
305
306 /**
307 * Retrieves map of all item pickup points of items of a <b>specific type</b>.
308 *
309 * <p><p>WARNING: O(n) complexity!
310 *
311 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
312 * @return Map of all items. Note: Empty pickups are included as well.
313 *
314 * @see isPickupSpawned(Item)
315 */
316 public Map<UnrealId, Item> getKnownPickups(ItemType type, double usefulness)
317 {
318 return filterUsefulItems(items.getKnownPickups(type).values(), usefulness);
319 }
320
321 /**
322 * Retrieves map of all item pickup points of items of a <b>specific category</b>.
323 *
324 * <p><p>WARNING: O(n) complexity!
325 *
326 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
327 * @return Map of all items. Note: Empty pickups are included as well.
328 *
329 * @see isPickupSpawned(Item)
330 */
331 public Map<UnrealId, Item> getKnownPickups(ItemType.Category category, double usefulness)
332 {
333 return filterUsefulItems(items.getKnownPickups(category).values(), usefulness);
334 }
335
336 /**
337 * Retrieves map of all item pickup points of items of a <b>specific group</b>.
338 *
339 * <p><p>WARNING: O(n) complexity!
340 *
341 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
342 * @return Map of all items. Note: Empty pickups are included as well.
343 *
344 * @see isPickupSpawned(Item)
345 */
346 public Map<UnrealId, Item> getKnownPickups(ItemType.Group group, double usefulness)
347 {
348 return filterUsefulItems(items.getKnownPickups(group).values(), usefulness);
349 }
350
351
352 /*========================================================================*/
353
354 /**
355 * Determines, whether an item can be useful for the agent.
356 *
357 * @param item Given item to be checked.
358 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
359 * @return True, if the item can be useful.
360 */
361 public boolean isItemUseful(Item item, double usefulness) {
362 if (usefulness < 0) usefulness = 0;
363 else if (usefulness > 1) usefulness = 1;
364 return filter.getItemUsefulness(this, items, item, usefulness) >= usefulness;
365 }
366
367 /**
368 * Determines, whether an item can be useful for the agent.
369 *
370 * <p><p>WARNING: O(n) complexity!
371 *
372 * @param items Items to be filtered on.
373 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
374 * @return Map of all useful items.
375 */
376 public Map<UnrealId, Item> filterUsefulItems(Collection<Item> items, double usefulness)
377 {
378 // new empty list
379 Map<UnrealId, Item> map = new HashMap<UnrealId, Item> ();
380
381 // run through items and filter them out
382 for (Item i: items) {
383 if (isItemUseful(i, usefulness)) {
384 // add only useful to the results
385 map.put(i.getId(), i);
386 }
387 }
388
389 return map;
390 }
391
392 /*========================================================================*/
393
394 /**
395 * Returns underlying {@link Items} module.
396 */
397 public Items getItems() {
398 return items;
399 }
400
401 /**
402 * Filter of useful items.
403 */
404 private IItemUsefulness filter;
405
406
407 /**
408 * Items memory module.
409 */
410 private Items items;
411
412 /**
413 * Constructor. Setups the memory module based on bot's world view.
414 * @param bot owner of the module
415 * @param filter the filter of the usefulness
416 */
417 public AdvancedItems(UDKBot bot, IItemUsefulness filter) {
418 this(new Items(bot), filter);
419 }
420
421 /**
422 * Constructor. Setups the memory module based on bot's world view.
423 * @param items items memory module
424 * @param filter the filter of the usefulness
425 */
426 public AdvancedItems(Items items, IItemUsefulness filter)
427 {
428 this.items = items;
429 NullCheck.check(this.items, "items");
430 this.filter = filter;
431 }
432
433 }