1 package cz.cuni.amis.pogamut.ut2004.tournament.deathmatch;
2
3 import java.io.File;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 import org.apache.commons.io.FileUtils;
12
13 import cz.cuni.amis.pogamut.ut2004.tournament.match.IUT2004BotConfig;
14 import cz.cuni.amis.pogamut.ut2004.tournament.match.UT2004BotConfig;
15 import cz.cuni.amis.pogamut.ut2004.tournament.match.UT2004NativeBotConfig;
16 import cz.cuni.amis.pogamut.ut2004.utils.UCCWrapperConf;
17 import cz.cuni.amis.utils.NullCheck;
18 import cz.cuni.amis.utils.exception.PogamutException;
19 import cz.cuni.amis.utils.token.IToken;
20 import cz.cuni.amis.utils.token.Tokens;
21
22
23
24
25
26
27
28
29
30
31
32
33
34 public class UT2004DeathMatchTournamentConfig {
35
36
37
38
39 protected int numBotsInOneMatch = 2;
40
41
42
43
44 protected IToken tournamentId;
45
46
47
48
49 protected int fragLimit;
50
51
52
53
54 protected int timeLimitInMinutes;
55
56 protected UCCWrapperConf uccConf = new UCCWrapperConf();
57
58
59
60
61
62
63 protected String outputDir;
64
65
66
67
68 protected Map<IToken, UT2004BotConfig> bots = new HashMap<IToken, UT2004BotConfig>();
69
70
71
72
73 protected Map<IToken, UT2004NativeBotConfig> nativeBots = new HashMap<IToken, UT2004NativeBotConfig>();
74
75
76
77
78 public UT2004DeathMatchTournamentConfig() {
79 uccConf.setGameType("BotDeathMatch");
80 uccConf.setStartOnUnusedPort(true);
81 }
82
83
84
85
86
87 public int getNumBotsInOneMatch() {
88 return numBotsInOneMatch;
89 }
90
91
92
93
94
95
96 public int getFragLimit() {
97 return fragLimit;
98 }
99
100
101
102
103
104
105 public int getTimeLimitInMinutes() {
106 return timeLimitInMinutes;
107 }
108
109
110
111
112
113
114 public IToken getTournamentId() {
115 return tournamentId;
116 }
117
118
119
120
121
122
123 public String getOutputDir() {
124 return outputDir;
125 }
126
127
128
129
130
131 public UCCWrapperConf getUccConf() {
132 return uccConf;
133 }
134
135
136
137
138
139 public Map<IToken, UT2004BotConfig> getBots() {
140 return bots;
141 }
142
143
144
145
146
147 public Map<IToken, UT2004NativeBotConfig> getNativeBots() {
148 return nativeBots;
149 }
150
151 public void setNumBotsInOneMatch(int numBotsInOneMatch) {
152 this.numBotsInOneMatch = numBotsInOneMatch;
153 }
154
155 public UT2004DeathMatchTournamentConfig setTournamentId(IToken id) {
156 this.tournamentId = id;
157 return this;
158 }
159
160 public UT2004DeathMatchTournamentConfig setTournamentId(String id) {
161 this.tournamentId = Tokens.get(id);
162 return this;
163 }
164
165 public UT2004DeathMatchTournamentConfig setFragLimit(int fragLimit) {
166 this.fragLimit = fragLimit;
167 return this;
168 }
169
170 public UT2004DeathMatchTournamentConfig setTimeLimitInMinutes(int timeLimitInMinutes) {
171 this.timeLimitInMinutes = timeLimitInMinutes;
172 return this;
173 }
174
175 public UT2004DeathMatchTournamentConfig setUnrealHome(String unrealHome) {
176 this.uccConf.setUnrealHome(unrealHome);
177 return this;
178 }
179
180 public UT2004DeathMatchTournamentConfig setMapName(String mapName) {
181 this.uccConf.setMapName(mapName);
182 return this;
183 }
184
185 public UT2004DeathMatchTournamentConfig setOutputDir(String outputDir) {
186 this.outputDir = outputDir;
187 return this;
188 }
189
190 public void setUccConf(UCCWrapperConf uccConf) {
191 this.uccConf = uccConf;
192 }
193
194 public UT2004DeathMatchTournamentConfig setBots(Map<IToken, UT2004BotConfig> bots) {
195 this.bots = bots;
196 return this;
197 }
198
199 public UT2004DeathMatchTournamentConfig setNativeBots(Map<IToken, UT2004NativeBotConfig> nativeBots) {
200 this.nativeBots = nativeBots;
201 return this;
202 }
203
204 public UT2004DeathMatchTournamentConfig clearBots() {
205 this.bots.clear();
206 return this;
207 }
208
209 public UT2004DeathMatchTournamentConfig clearNativeBots() {
210 this.nativeBots.clear();
211 return this;
212 }
213
214
215
216
217
218
219 public UT2004DeathMatchTournamentConfig addBot(UT2004BotConfig... bots) {
220 if (bots == null) return this;
221 for (UT2004BotConfig bot : bots) {
222 NullCheck.check(bot.getBotId(), "bot.getBotId()");
223 if (this.bots.containsKey(bot.getBotId())) {
224 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing custom bot configuration under this ID. If you need to override it, use setBot().", this);
225 }
226 if (this.nativeBots.containsKey(bot.getBotId())) {
227 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing native bot configuration under this ID. If you need to override it, use setBot().", this);
228 }
229 this.bots.put(bot.getBotId(), bot);
230 }
231 return this;
232 }
233
234
235
236
237
238
239
240 public UT2004DeathMatchTournamentConfig setBot(UT2004BotConfig... bots) {
241 if (bots == null) return this;
242 for (UT2004BotConfig bot : bots) {
243 NullCheck.check(bot.getBotId(), "bot.getBotId()");
244 if (this.nativeBots.containsKey(bot.getBotId())) {
245 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing native bot configuration under this ID. If you need to override it, use setBot().", this);
246 }
247 this.bots.put(bot.getBotId(), bot);
248 }
249 return this;
250 }
251
252
253
254
255
256
257 public UT2004DeathMatchTournamentConfig addNativeBot(UT2004NativeBotConfig... bots) {
258 if (bots == null) return this;
259 for (UT2004NativeBotConfig bot : bots) {
260 NullCheck.check(bot.getBotId(), "bot.getBotId()");
261 if (this.bots.containsKey(bot.getBotId())) {
262 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing custom bot configuration under this ID. If you need to override it, use setBot().", this);
263 }
264 if (this.nativeBots.containsKey(bot.getBotId())) {
265 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing native bot configuration under this ID. If you need to override it, use setNativeBot().", this);
266 }
267 this.nativeBots.put(bot.getBotId(), bot);
268 }
269 return this;
270 }
271
272
273
274
275
276
277 public UT2004DeathMatchTournamentConfig setNativeBot(UT2004NativeBotConfig... bots) {
278 if (bots == null) return this;
279 for (UT2004NativeBotConfig bot : bots) {
280 NullCheck.check(bot.getBotId(), "bot.getBotId()");
281 if (this.bots.containsKey(bot.getBotId())) {
282 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing custom bot configuration under this ID. If you need to override it, use setBot().", this);
283 }
284 this.nativeBots.put(bot.getBotId(), bot);
285 }
286 return this;
287 }
288
289 public boolean isNativeBot(IToken botId) {
290 return nativeBots.containsKey(botId);
291 }
292
293
294
295
296
297
298 public IUT2004BotConfig getBotConfig(IToken botId) {
299 UT2004BotConfig config = bots.get(botId);
300 if (config != null) return config;
301 return nativeBots.get(botId);
302 }
303
304
305
306
307 public void cleanUp() {
308 try {
309 FileUtils.deleteQuietly(new File(outputDir));
310 } catch (Exception e) {
311 }
312 }
313
314
315
316
317
318
319
320
321
322 public UT2004DeathMatchConfig createConfiguration(List<IToken> chosenBots) {
323 UT2004DeathMatchConfig matchConfig = new UT2004DeathMatchConfig();
324
325 StringBuffer matchId = new StringBuffer();
326 boolean first = true;
327 for (IToken token : chosenBots) {
328 if (first) first = false;
329 else matchId.append("-vs-");
330 matchId.append(token.getToken());
331 }
332 matchConfig.setMatchId(matchId.toString());
333 matchConfig.setOutputDirectory(new File(outputDir));
334
335 matchConfig.setFragLimit(getFragLimit());
336 matchConfig.setTimeLimit(getTimeLimitInMinutes());
337 matchConfig.setUccConf(new UCCWrapperConf(uccConf));
338
339 for (IToken botId : chosenBots) {
340 if (isNativeBot(botId)) {
341 matchConfig.addNativeBot(new UT2004NativeBotConfig(nativeBots.get(botId)));
342 } else {
343 matchConfig.addBot(new UT2004BotConfig(bots.get(botId)));
344 }
345 }
346
347 return matchConfig;
348 }
349
350 protected void generate(List<UT2004DeathMatchConfig> result, int numBots, List<IToken> botIds, int startFrom, List<IToken> chosenBots) {
351 if (startFrom >= botIds.size()) {
352
353 return;
354 }
355 if (chosenBots.size() + (botIds.size() - startFrom) < numBots) {
356
357 return;
358 }
359
360 chosenBots.add(botIds.get(startFrom));
361
362 if (chosenBots.size() == numBots) {
363
364 result.add(createConfiguration(chosenBots));
365 } else {
366
367 for (int i = startFrom+1; i < botIds.size(); ++i) {
368 generate(result, numBots, botIds, i, chosenBots);
369 }
370 }
371
372 chosenBots.remove(chosenBots.size()-1);
373 }
374
375 protected UT2004DeathMatchConfig[] generateMatches(int numBots) {
376 List<IToken> botIds = new ArrayList<IToken>(bots.size() + nativeBots.size());
377 botIds.addAll(bots.keySet());
378 Collections.sort(botIds, new Comparator<IToken>() {
379 @Override
380 public int compare(IToken o1, IToken o2) {
381 if (o1 == null) {
382 if (o2 == null) return 0;
383 else return -1;
384 }
385 if (o2 == null) return 1;
386 return o1.getToken().compareTo(o2.getToken());
387 }
388 });
389
390 List<IToken> nativeBotIds = new ArrayList<IToken>(nativeBots.keySet());
391 Collections.sort(nativeBotIds, new Comparator<IToken>() {
392 @Override
393 public int compare(IToken o1, IToken o2) {
394 if (o1 == null) {
395 if (o2 == null) return 0;
396 else return -1;
397 }
398 if (o2 == null) return 1;
399 return o1.getToken().compareTo(o2.getToken());
400 }
401 });
402
403 botIds.addAll(nativeBotIds);
404
405 List<IToken> chosenBots = new ArrayList<IToken>();
406
407 List<UT2004DeathMatchConfig> result = new ArrayList<UT2004DeathMatchConfig>();
408 for (int i = 0; i < bots.size(); ++i) {
409 generate(result, numBots, botIds, i, chosenBots);
410 }
411 return result.toArray(new UT2004DeathMatchConfig[result.size()]);
412 }
413
414
415
416
417
418
419
420
421
422
423
424
425 public UT2004DeathMatchConfig[] createMatcheConfigs(int numBotsInOneMatch) {
426 if (numBotsInOneMatch < 2) throw new IllegalArgumentException("numBotsInOneMatch = " + numBotsInOneMatch + " < 2 !!!");
427 if (numBotsInOneMatch > bots.size() + nativeBots.size()) throw new IllegalArgumentException("numBotsInOneMatch = " + numBotsInOneMatch + " > " + (bots.size() + nativeBots.size()) + " = number of all (custom+native) enlisted bots");
428 if (bots.size() == 0) throw new PogamutException("No custom (Pogamut) bots enlisted to the tournament!", this);
429 return generateMatches(numBotsInOneMatch);
430 }
431
432
433
434
435
436
437
438
439
440
441
442
443 public UT2004DeathMatchConfig[] createMatcheConfigs() {
444 return createMatcheConfigs(getNumBotsInOneMatch());
445 }
446
447 }