1 package cz.cuni.amis.pogamut.ut2004.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.ut2004.bot.IUT2004BotController;
8 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
9 import cz.cuni.amis.pogamut.ut2004.communication.messages.ItemType;
10 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
11 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Item;
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 IUT2004BotController#initializeController(UT2004Bot)} method call
27 * and may be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.ut2004.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 * Retrieves map of all item pickup points.
230 *
231 * <p><p>WARNING: O(n) complexity!
232 *
233 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
234 * @return Map of all items. Note: Empty pickups are included as well.
235 *
236 * @see isPickupSpawned(Item)
237 */
238 public Map<UnrealId, Item> getKnownPickups(double usefulness)
239 {
240 return filterUsefulItems(items.getKnownPickups().values(), usefulness);
241 }
242
243 /**
244 * Retrieves map of all item pickup points of items of a <b>specific type</b>.
245 *
246 * <p><p>WARNING: O(n) complexity!
247 *
248 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
249 * @return Map of all items. Note: Empty pickups are included as well.
250 *
251 * @see isPickupSpawned(Item)
252 */
253 public Map<UnrealId, Item> getKnownPickups(ItemType type, double usefulness)
254 {
255 return filterUsefulItems(items.getKnownPickups(type).values(), usefulness);
256 }
257
258 /**
259 * Retrieves map of all item pickup points of items of a <b>specific category</b>.
260 *
261 * <p><p>WARNING: O(n) complexity!
262 *
263 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
264 * @return Map of all items. Note: Empty pickups are included as well.
265 *
266 * @see isPickupSpawned(Item)
267 */
268 public Map<UnrealId, Item> getKnownPickups(ItemType.Category category, double usefulness)
269 {
270 return filterUsefulItems(items.getKnownPickups(category).values(), usefulness);
271 }
272
273 /**
274 * Retrieves map of all item pickup points of items of a <b>specific group</b>.
275 *
276 * <p><p>WARNING: O(n) complexity!
277 *
278 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
279 * @return Map of all items. Note: Empty pickups are included as well.
280 *
281 * @see isPickupSpawned(Item)
282 */
283 public Map<UnrealId, Item> getKnownPickups(ItemType.Group group, double usefulness)
284 {
285 return filterUsefulItems(items.getKnownPickups(group).values(), usefulness);
286 }
287
288
289 /*========================================================================*/
290
291 /**
292 * Determines, whether an item can be useful for the agent.
293 *
294 * @param item Given item to be checked.
295 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
296 * @return True, if the item can be useful.
297 */
298 public boolean isItemUseful(Item item, double usefulness) {
299 if (usefulness < 0) usefulness = 0;
300 else if (usefulness > 1) usefulness = 1;
301 return filter.getItemUsefulness(this, items, item, usefulness) >= usefulness;
302 }
303
304 /**
305 * Determines, whether an item can be useful for the agent.
306 *
307 * <p><p>WARNING: O(n) complexity!
308 *
309 * @param items Items to be filtered on.
310 * @param usefulness degree of usefulness, 0 - return also useless, 1 - return only <b>really truly</b> useful items which are MUST HAVE!
311 * @return Map of all useful items.
312 */
313 public Map<UnrealId, Item> filterUsefulItems(Collection<Item> items, double usefulness)
314 {
315 // new empty list
316 Map<UnrealId, Item> map = new HashMap<UnrealId, Item> ();
317
318 // run through items and filter them out
319 for (Item i: items) {
320 if (isItemUseful(i, usefulness)) {
321 // add only useful to the results
322 map.put(i.getId(), i);
323 }
324 }
325
326 return map;
327 }
328
329 /*========================================================================*/
330
331 /**
332 * Returns underlying {@link Items} module.
333 */
334 public Items getItems() {
335 return items;
336 }
337
338 /**
339 * Filter of useful items.
340 */
341 private IItemUsefulness filter;
342
343
344 /**
345 * Items memory module.
346 */
347 private Items items;
348
349 /**
350 * Constructor. Setups the memory module based on bot's world view.
351 * @param bot owner of the module
352 * @param filter the filter of the usefulness
353 */
354 public AdvancedItems(UT2004Bot bot, IItemUsefulness filter) {
355 this(new Items(bot), filter);
356 }
357
358 /**
359 * Constructor. Setups the memory module based on bot's world view.
360 * @param items items memory module
361 * @param filter the filter of the usefulness
362 */
363 public AdvancedItems(Items items, IItemUsefulness filter)
364 {
365 this.items = items;
366 NullCheck.check(this.items, "items");
367 this.filter = filter;
368 }
369
370 }