View Javadoc

1   package cz.cuni.amis.pogamut.defcon.agent.impl;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.lang.reflect.Method;
5   import java.util.LinkedList;
6   import java.util.Random;
7   
8   import cz.cuni.amis.pogamut.base.agent.module.LogicModule;
9   import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
10  import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.AnnotationListenerRegistrator;
11  import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
12  import cz.cuni.amis.pogamut.defcon.agent.DefConAgent;
13  import cz.cuni.amis.pogamut.defcon.agent.IDefConAgentLogicController;
14  import cz.cuni.amis.pogamut.defcon.agent.module.logic.DefConAgentLogic;
15  import cz.cuni.amis.pogamut.defcon.agent.module.sensor.GameInfo;
16  import cz.cuni.amis.pogamut.defcon.communication.mailbox.IMailBox;
17  import cz.cuni.amis.pogamut.defcon.communication.mailbox.MailBox;
18  import cz.cuni.amis.pogamut.defcon.communication.messages.infos.GameRunningChanged;
19  import cz.cuni.amis.pogamut.defcon.communication.worldview.DefConWorldView;
20  import cz.cuni.amis.pogamut.defcon.communication.worldview.modules.grid.flags.IFlagChecker;
21  import cz.cuni.amis.pogamut.defcon.communication.worldview.modules.managers.buildings.BuildingsManager;
22  import cz.cuni.amis.pogamut.defcon.communication.worldview.modules.managers.fleets.FleetsManager;
23  
24  /**
25   * Implements infrastructure for a logic of the bot and simplifies distinction between different stages
26   * of the game.
27   * @author Radek 'Black_Hand' Pibil
28   *
29   * @param <AGENT> Controlled agent's type.
30   */
31  @AgentScoped
32  public class DefConAgentLogicController<AGENT extends DefConAgent>
33  		extends DefConAgentController<AGENT> implements
34  		IDefConAgentLogicController<AGENT, LogicModule<AGENT>> {
35  
36  	protected DefConAgentLogic<AGENT> logicModule;
37  	
38  	private AnnotationListenerRegistrator listenerRegistrator;
39  	
40  	private Method logicMethod;
41  	private Method gameLogic;
42  	private Method preGameLogic;
43  	private Method firstGameLogic;
44  
45  	protected DefConWorldView worldview;
46  	protected GameInfo gameInfo;
47  	
48  	private final Random random = new Random();
49  	
50  	private final IMailBox mailBox = new MailBox();
51  
52  	private final LinkedList<ILogicUpdateListener> logicUpdateListeners = new LinkedList<ILogicUpdateListener>();
53  
54  	protected FleetsManager fleetsManager;
55  
56  	protected BuildingsManager buildingsManager;
57  
58  	protected IFlagChecker flagChecker;
59  
60  	/**
61  	 * Assigns logicMethod, which gets executed in logic().
62  	 * This could be either gameLogic() or preGameLogic(). 
63  	 */
64  	public DefConAgentLogicController() {
65  		try {
66  			preGameLogic = this.getClass().getMethod(
67  					"preGameLogic",
68  					new Class[] {});
69  			logicMethod = preGameLogic;
70  			gameLogic = this.getClass().getMethod(
71  					"gameLogicWorker",
72  					new Class[] {});
73  			firstGameLogic = DefConAgentLogicController.class
74  				.getDeclaredMethod("firstGameLogicWorker", new Class[]{});
75  		} catch (SecurityException e) {
76  			e.printStackTrace();
77  			agent.stop();
78  		} catch (NoSuchMethodException e) {
79  			e.printStackTrace();
80  			agent.stop();
81  		}
82  	}
83  
84  	/**
85  	 * Annotation-based event listener registrator cannot handle inheritance, so we have to use
86  	 * this old styled method.
87  	 */
88  	public IWorldEventListener<GameRunningChanged> gameStartedListener =
89  		new IWorldEventListener<GameRunningChanged>() {
90  			
91  			@Override
92  			public void notify(GameRunningChanged event) {
93  				if (event.getRunning()) {
94  					try {						
95  						logicMethod = firstGameLogic;
96  					} catch (SecurityException e) {
97  						e.printStackTrace();
98  						agent.stop();
99  					}
100 				}
101 			}
102 		};
103 
104 	/**
105 	 * Registers anonymous listeners and creates logic module.
106 	 */
107 	@Override
108 	public void initializeController(AGENT agent) {
109 		super.initializeController(agent);
110 		logicModule = new DefConAgentLogic<AGENT>(agent, this);
111 		this.worldview = agent.getWorldView();
112 		this.gameInfo = this.worldview.getGameInfo();
113 		listenerRegistrator = new AnnotationListenerRegistrator(this,
114 				worldview, getLog());
115 		worldview.addEventListener(
116 				GameRunningChanged.class,
117 				gameStartedListener);		
118 		listenerRegistrator.addListeners();
119 	}
120 
121 	@Override
122 	public long getLogicInitializeTime() {
123 		return 120000;
124 	}
125 
126 	@Override
127 	public long getLogicShutdownTime() {
128 		return 120000;
129 	}	
130 
131 	@Override
132 	public void beforeFirstLogic() {
133 	}
134 	
135 	/**
136 	 * Gets executed periodically. Here we call a method that is currently
137 	 * stored in {@link #logicMethod} field.
138 	 */
139 	@Override
140 	public void logic() {
141 		try {
142 			worldview.updateProducer();
143 			logicMethod.invoke(this, new Object[] {});
144 		} catch (IllegalArgumentException e) {
145 			e.printStackTrace();
146 			agent.stop();
147 		} catch (IllegalAccessException e) {
148 			e.printStackTrace();
149 			agent.stop();
150 		} catch (InvocationTargetException e) {
151 			e.printStackTrace();
152 			agent.stop();
153 		}
154 	}	
155 	
156 	/**
157 	 * Executed instead of {@link #gameLogic} while still in lobby.
158 	 * This is what you could use to talk while the game is not running yet.
159 	 * Defcon API is not entirely clear if this is OK, so if you run into any problems with it,
160 	 * we would be glad to hear about them.
161 	 */
162 	public void preGameLogic() {}
163 	
164 	/**
165 	 * Executed the first tick instead of {@link #gameLogic}.
166 	 */		
167 	public void firstGameLogic() {
168 		gameLogic();
169 	}
170 	
171 	private final void firstGameLogicWorker() {
172 		logicMethod = gameLogic;
173 		firstGameLogic();
174 	}
175 
176 	/**
177 	 * Executed periodically while still in game.
178 	 * This is THE method for your AI. Override it to make your bot do something else than (possibly)
179 	 * a reaction to incoming events.
180 	 */	
181 	public void gameLogic() {}
182 
183 	/**
184 	 * Updates listeners, then calls gameLogic();
185 	 */
186 	public final void gameLogicWorker() {
187 		for (ILogicUpdateListener listener : logicUpdateListeners) {
188 			listener.update();
189 		}
190 		gameLogic();
191 	}
192 
193 	@Override
194 	public void logicInitialize(LogicModule<AGENT> logicModule) {
195 		this.logicModule = (DefConAgentLogic<AGENT>) logicModule;
196 	}
197 
198 	@Override
199 	public void logicShutdown() {
200 	}
201 
202 	/**
203 	 * Registers a listener from updates.
204 	 * 
205 	 * @param updateListener
206 	 */
207 	public void addGameLogicListener(ILogicUpdateListener updateListener) {
208 		if (updateListener != null)
209 			logicUpdateListeners.add(updateListener);
210 	}
211 
212 	/**
213 	 * Unregisters a listener from updates.
214 	 * 
215 	 * @param updateListener
216 	 */
217 	public void unregisterUpdates(ILogicUpdateListener updateListener) {
218 		if (logicUpdateListeners.contains(updateListener))
219 			logicUpdateListeners.remove(updateListener);
220 	}
221 
222 	/**
223 	 * Returns a random number generator.
224 	 * 
225 	 * @return
226 	 */
227 	public final Random getRandom() {
228 		return random;
229 	}
230 
231 	/**
232 	 * Returns the mailbox.
233 	 * 
234 	 * @return
235 	 */
236 	public final IMailBox getMailBox() {
237 		return mailBox;
238 	}
239 
240 	/**
241 	 * Returns flag checker used for map analysis.
242 	 * 
243 	 * @return
244 	 */
245 	public IFlagChecker getFlagChecker() {
246 		return flagChecker;
247 	}
248 
249 	public final FleetsManager getFleetsManager() {
250 		return fleetsManager;
251 	}
252 
253 	public final BuildingsManager getBuildingsManager() {
254 		return buildingsManager;
255 	}
256 
257 }