1
2
3
4
5 package spellcast.game;
6
7 import java.beans.PropertyChangeEvent;
8 import java.io.Serializable;
9 import java.util.ArrayList;
10 import java.util.List;
11
12 import org.apache.commons.chain.Catalog;
13 import org.apache.commons.chain.Command;
14 import org.apache.commons.chain.Context;
15 import org.apache.commons.lang.StringUtils;
16 import org.apache.commons.lang.Validate;
17 import org.apache.log4j.Logger;
18
19 import spellcast.beings.IBeing;
20 import spellcast.beings.IMonster;
21 import spellcast.beings.IWizard;
22 import spellcast.model.Id;
23
24 /***
25 * The Game class is the model for the Spellcast game. No control logic is
26 * contained in this class.
27 *
28 * @author Barrie Treloar
29 */
30 public class Game implements Serializable, IGame {
31 /***
32 * Default Listener List Size.
33 */
34 private static final int DEFAULT_LISTENER_LIST_SIZE = 2;
35
36 /***
37 * Default Monster List Size.
38 */
39 private static final int DEFAULT_MONSTER_LIST_SIZE = 5;
40
41 /***
42 * Default Wizard List Size.
43 */
44 private static final int DEFAULT_WIZARD_LIST_SIZE = 10;
45
46 /***
47 * Logger for this class.
48 */
49 private static Logger logger = Logger.getLogger(Game.class);
50
51 /***
52 * serialVersionUID for Serializable.
53 */
54 private static final long serialVersionUID = 1L;
55
56 /***
57 * Contains the commands needed by the <code>Game</code>.
58 */
59 private Catalog commandCatalog;
60
61 /***
62 * Create a game.
63 * @param theGameName
64 * the name of the game.
65 * @param theCommandCatalog contains the commands needed by the <code>Game</code>.
66 */
67 public Game(final String theGameName, Catalog theCommandCatalog) {
68 Validate.isTrue(StringUtils.isNotEmpty(theGameName));
69 Validate.notNull(theCommandCatalog);
70 gameName = theGameName;
71 commandCatalog = theCommandCatalog;
72 turn = Turn.BEFORE_GAME;
73 }
74
75 /***
76 * {@inheritDoc}
77 */
78 public final void addWizard(final IWizard w) {
79 if (hasStarted()) {
80 throw new IllegalStateException("Can not add a Wizard as the Game has started.");
81 }
82 wizards.add(w);
83 }
84
85 /***
86 * Find the specified being by Id. If no match found then return null.
87 * Checks amongst all Wizards and Monsters.
88 *
89 * @param idToMatch
90 * the Id to match
91 * @return the matching <code>IBeing</code> or null if no match found.
92 */
93 private IBeing getBeing(final Id idToMatch) {
94 IBeing result = null;
95
96 result = getWizard(idToMatch);
97 if (result == null) {
98 result = getMonster(idToMatch);
99 }
100
101 return result;
102 }
103
104 /***
105 * {@inheritDoc}
106 */
107 public final GameLog getGameLog() {
108 return gameLog;
109 }
110
111 /***
112 * Find the specified monster by Id. If no match found then return null.
113 *
114 * @param idToMatch
115 * the Id to match
116 * @return the matchin <code>IMonster</code> or null if no match found.
117 */
118 private IMonster getMonster(final Id idToMatch) {
119 for (IMonster potentialMatchingMonster : monsters) {
120 if (potentialMatchingMonster.getId().equals(idToMatch)) {
121 return potentialMatchingMonster;
122 }
123 }
124 return null;
125 }
126
127 /***
128 * {@inheritDoc}
129 */
130 public final List<IMonster> getMonsters() {
131 return new ArrayList<IMonster>(monsters);
132 }
133
134 /***
135 * {@inheritDoc}
136 */
137 public final String getName() {
138 return gameName;
139 }
140
141 /***
142 * {@inheritDoc}
143 */
144 public final Turn getTurn() {
145 return turn;
146 }
147
148 /***
149 * Find the specified wizard by Id. If no match found then return null.
150 *
151 * @param idToMatch
152 * the <code>Id</code> to match
153 * @return the wizard with the matching <code>Id</code> or null otherwise.
154 */
155 public final IWizard getWizard(final Id idToMatch) {
156 for (IWizard potentialMatchingWizard : wizards) {
157 if (potentialMatchingWizard.getId().equals(idToMatch)) {
158 return potentialMatchingWizard;
159 }
160 }
161 return null;
162 }
163
164 /***
165 * {@inheritDoc}
166 */
167 public final List<IWizard> getWizards() {
168 return new ArrayList<IWizard>(wizards);
169 }
170
171 /***
172 * {@inheritDoc}
173 */
174 public final boolean hasFinished() {
175 return (turn.equals(Turn.AFTER_GAME));
176 }
177
178 /***
179 * {@inheritDoc}
180 */
181 public final boolean hasStarted() {
182 return (!turn.equals(Turn.BEFORE_GAME));
183 }
184
185 /***
186 * {@inheritDoc}
187 */
188 public void processTurn() {
189 Command processTurnCommand = commandCatalog.getCommand("processTurn");
190 try {
191 Context theContext = new GameContext();
192 processTurnCommand.execute(theContext);
193 } catch (Exception e) {
194 logger.warn("Unexpected exception", e);
195 }
196 }
197
198 /***
199 * {@inheritDoc}
200 */
201 public final void removeWizard(final IWizard w) {
202 if (hasStarted()) {
203 throw new IllegalStateException("Can not remove a Wizard as the Game has started.");
204 }
205 wizards.remove(w);
206 }
207
208 /***
209 * Set the value of gameLog.
210 *
211 * @param v
212 * Value to assign to gameLog.
213 */
214 public final void setGameLog(final GameLog v) {
215 gameLog = v;
216 }
217
218 /***
219 * {@inheritDoc}
220 */
221 public final void setTurn(final Turn v) {
222 turn = v;
223 }
224
225 /***
226 * Update the client's local copy of the game with the value contained in
227 * the property change event.
228 *
229 * @param pce
230 * needs more work here.
231 */
232 public final void update(final PropertyChangeEvent pce) {
233 IBeing target = getBeing((Id) pce.getSource());
234 if (target != null) {
235
236
237
238 int todo = 0;
239 } else {
240 logger.error("Received update for unknown object: "
241 + pce.getSource() + "\n" + "Property ("
242 + pce.getPropertyName() + ") = " + pce.getNewValue());
243
244 }
245 }
246
247 /***
248 * The <code>GameLog</code> for this game.
249 */
250 private transient GameLog gameLog;
251
252 /***
253 * The name of the game.
254 */
255 private String gameName;
256
257 /***
258 * The property listeners, probably to be removed.
259 */
260 private transient ArrayList listeners = new ArrayList(
261 DEFAULT_LISTENER_LIST_SIZE);
262
263 /***
264 * List of the <code>IMonster</code>s in the game.
265 */
266 private List<IMonster> monsters = new ArrayList<IMonster>(
267 DEFAULT_MONSTER_LIST_SIZE);
268
269 /***
270 * The current <code>Turn</code>.
271 */
272 private Turn turn;
273
274 /***
275 * List of the <code>IWizard</code>s in the game.
276 */
277 private ArrayList<IWizard> wizards = new ArrayList<IWizard>(
278 DEFAULT_WIZARD_LIST_SIZE);
279
280 }