View Javadoc

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 }