use of ultimate.karoapi4j.model.official.Map in project KaroToolsCollection by ultimate.
the class Planner method planSeriesKLC.
/**
* Plan the games for a {@link EnumGameSeriesType#KLC} {@link GameSeries}.<br>
* Note: the original league lists in <code>playersByKey</code> will be shuffled.<br>
*
* @param title - the title (including placeholders)
* @param playersByKey - the map of {@link User}s (by leagues)
* @param homeMaps - the home {@link Map}s for the {@link User}s
* @param leagues - the number of leagues
* @param groups - the number of groups
* @param rules - the {@link Rules} to use
* @param round - the round to plan
* @return the list of {@link PlannedGame}s
*/
public static List<PlannedGame> planSeriesKLC(String title, User creator, java.util.Map<String, List<User>> playersByKey, java.util.Map<String, List<Map>> homeMaps, int leagues, int groups, Rules rules, int round) {
int totalPlayers = groups * leagues;
BiFunction<Team, Team, Team> whoIsHome = (team1, team2) -> {
int league1 = -1;
int league2 = -1;
for (int l = 1; l <= leagues; l++) {
if (playersByKey.get(GameSeries.KEY_LEAGUE + l).contains(team1.getMembers().get(0)))
league1 = l;
if (playersByKey.get(GameSeries.KEY_LEAGUE + l).contains(team2.getMembers().get(0)))
league2 = l;
}
if (league1 == -1 || league2 == -1)
logger.error("should not happen!");
if (// Spieler 0 ist in der niedrigeren Liga (= h�here Liga Nummer)
league1 > league2)
return team1;
else if (// Spieler 1 ist in der niedrigeren Liga (= h�here Liga Nummer)
league1 < league2)
return team2;
// beide sind in der gleichen Liga -> zufall
return (random.nextBoolean() ? team1 : team2);
};
if (round == totalPlayers)
return planGroupphase(title, creator, playersByKey, homeMaps, leagues, groups, whoIsHome, rules, round);
else if (round == 2) {
// create tmp list of teams so we can use planTeamGame
List<Team> winners = new ArrayList<>(playersByKey.get(GameSeries.KEY_ROUND + round).size());
for (User user : playersByKey.get(GameSeries.KEY_ROUND + round)) winners.add(new Team(user.getLogin(), Arrays.asList(user), homeMaps.get("" + user.getId()).get(0)));
List<Team> losers = new ArrayList<>(playersByKey.get(GameSeries.KEY_ROUND + round).size());
List<User> playersWhoLost = new ArrayList<>(playersByKey.get(GameSeries.KEY_ROUND + (round * 2)));
playersWhoLost.removeAll(playersByKey.get(GameSeries.KEY_ROUND + round));
for (User user : playersWhoLost) losers.add(new Team(user.getLogin(), Arrays.asList(user), homeMaps.get("" + user.getId()).get(0)));
return planSeriesKO(title, creator, winners, losers, null, null, rules, true, true, 2);
} else {
// create tmp list of teams so we can use planTeamGame
List<Team> teams = new ArrayList<>(playersByKey.get(GameSeries.KEY_ROUND + round).size());
for (User user : playersByKey.get(GameSeries.KEY_ROUND + round)) teams.add(new Team(user.getLogin(), Arrays.asList(user), homeMaps.get("" + user.getId()).get(0)));
return planSeriesKO(title, creator, teams, null, null, whoIsHome, rules, true, true, 1);
}
}
use of ultimate.karoapi4j.model.official.Map in project KaroToolsCollection by ultimate.
the class Planner method planSeriesAllCombinations.
/**
* Plan the games for an {@link EnumGameSeriesType#AllCombinations} {@link GameSeries}
*
* @param title - the title (including placeholders)
* @param teams - the list of {@link Team}s
* @param maps - the list of {@link Map}s
* @param rules - the {@link Rules}
* @param numberOfGamesPerPair - the number of games per pair/combination
* @param numberOfTeamsPerMatch - the number of {@link Team}s per match
* @return the list of {@link PlannedGame}s
*/
public static List<PlannedGame> planSeriesAllCombinations(String title, User creator, List<Team> teams, List<Map> maps, Rules rules, int numberOfGamesPerPair, int numberOfTeamsPerMatch) {
List<PlannedGame> games = new LinkedList<>();
// create local copy of the input list
List<Team> tmp = new LinkedList<>(teams);
Collections.shuffle(tmp, random);
List<Match> matches = planMatchesAllCombinations(tmp, numberOfTeamsPerMatch);
PlannedGame game;
Map map;
List<User> gamePlayers;
int count = 0;
int dayCount;
HashMap<String, String> placeholderValues;
for (int round = 0; round < numberOfGamesPerPair; round++) {
dayCount = 0;
for (Match match : matches) {
map = maps.get(random.nextInt(maps.size()));
gamePlayers = new LinkedList<User>();
gamePlayers.add(creator);
for (Team team : match.getTeams()) {
for (User member : team.getMembers()) {
if (!gamePlayers.contains(member))
gamePlayers.add(member);
}
}
placeholderValues = new HashMap<>();
placeholderValues.put("i", toString(count + 1, 1));
placeholderValues.put("spieltag", toString(round + 1, 1));
placeholderValues.put("spieltag.i", toString(dayCount + 1, 1));
game = planGame(title, creator, map, gamePlayers, rules, placeholderValues);
games.add(game);
count++;
dayCount++;
}
}
return games;
}
use of ultimate.karoapi4j.model.official.Map in project KaroToolsCollection by ultimate.
the class Demo method main.
/**
* Demo Code
*
* @param args - not used here
* @throws IOException - if loading properties fails
*/
public static void main(String[] args) throws IOException {
// in this example I am reading username and password from a properties file
// (but of course, you can also set them differently)
Properties properties = PropertiesUtil.loadProperties(new File("target/test-classes/login.properties"));
String username = properties.getProperty("karoapi.user");
String password = properties.getProperty("karoapi.password");
// initiate the KaroAPI
KaroAPI api = new KaroAPI(username, password);
// check wether the login is successful?
User currentUser;
try {
currentUser = api.check().get();
if (currentUser != null)
logger.info("login successful");
} catch (InterruptedException | ExecutionException e) {
logger.error("login NOT successful");
return;
}
// all calls to the API work in the same way
// 1) calling an API method will return a CompletableFuture which is wrapping and executing the API call in the background
// for example
CompletableFuture<List<Map>> mapsCF = api.getMaps();
try {
// 2a) to get the result, you can either wait blocking
List<Map> maps = mapsCF.get();
// and then do something with the result
logger.info("2a) maps found = " + maps.size());
} catch (InterruptedException | ExecutionException e) {
// Note that this can throw an Exception, if loading fails (for example server is not reachable)
logger.error("2a) loading maps not successful NOT successful");
}
// 2b) or you can pass a callback
mapsCF.whenComplete((result, throwable) -> {
if (throwable == null)
// do something with the result
logger.info("2b) maps found = " + result.size());
else
logger.error("2b) something went wrong");
});
// 2c) or you can use the CompletableFuture to build up your logic
api.getMaps().thenCompose((result) -> {
logger.info("2c) maps found = " + result.size());
return CompletableFuture.supplyAsync(() -> {
PlannedGame game = new PlannedGame();
Random r = new Random();
// only select current player
game.getPlayers().add(currentUser);
// choose a random map
game.setMap(result.get(r.nextInt(result.size())));
// set name
game.setName("Test game");
// set options
game.setOptions(new Options(2, true, EnumGameDirection.free, EnumGameTC.free));
return api.createGame(game);
});
}).thenCompose(Function.identity()).whenComplete((game, throwable) -> {
if (game != null && throwable == null)
logger.info("game created: id=" + game.getId());
}).exceptionally((throwable) -> {
logger.error("2c) something went wrong");
return null;
}).join();
// 3) do with the result whatever you want (if you haven't already used in in 2b or 2c)
// ...
}
use of ultimate.karoapi4j.model.official.Map in project KaroToolsCollection by ultimate.
the class KaroAPICache method getMap.
/**
* get the {@link Map} with the given ID from the cache or load it from the API if not yet cached
*
* @see KaroAPI#getMapWithDetails(int)
* @param id - the map id
* @return the {@link Map}
*/
public Map getMap(int id) {
if (!this.mapsById.containsKey(id)) {
if (karoAPI != null) {
try {
Map m = karoAPI.getMapWithDetails(id).get();
updateMap(m);
} catch (InterruptedException | ExecutionException e) {
logger.error("could not get map: " + id);
}
} else {
// debug mode
Map m = createDummyMap(id);
updateMap(m);
}
}
return this.mapsById.get(id);
}
use of ultimate.karoapi4j.model.official.Map in project KaroToolsCollection by ultimate.
the class KaroAPICache method refresh.
/**
* Refresh the internal cache from the {@link KaroAPI} (asynchronously)
*
* @return a {@link CompletableFuture} for async execution
*/
public CompletableFuture<Void> refresh() {
if (karoAPI != null) {
logger.info("refreshing KaroAPICache...");
// load users
logger.info("loading users...");
CompletableFuture<Void> loadUsers = karoAPI.getUsers().thenAccept(userList -> {
logger.info("users loaded: " + userList.size());
for (User u : userList) updateUser(u);
});
// load extra users
if (config != null && config.containsKey(CONFIG_EXTRA_USERS))
loadUsers = loadExtras(User.class, config.getProperty(CONFIG_EXTRA_USERS), loadUsers);
// then check the current user
CompletableFuture<Void> loadCheck = loadUsers.thenComposeAsync(v -> {
logger.info("checking login...");
return karoAPI.check();
}).thenAccept(checkUser -> {
if (checkUser != null) {
logger.info("credentials confirmed: " + checkUser.getLogin() + " (" + checkUser.getId() + ")");
// but don't use the user returned, but instead use the same instance as
// previously loaded by getUsers
updateUser(checkUser);
User preloaded = getUser(checkUser.getId());
this.currentUser = preloaded;
} else {
logger.error("could not confirm credentials");
}
});
// load maps
logger.info("loading maps...");
CompletableFuture<Void> loadMaps = karoAPI.getMaps().thenAccept(mapList -> {
logger.info("maps loaded: " + mapList.size());
for (Map m : mapList) updateMap(m);
});
// load extra maps
if (config != null && config.containsKey(CONFIG_EXTRA_MAPS))
loadMaps = loadExtras(Map.class, config.getProperty(CONFIG_EXTRA_MAPS), loadMaps);
// then load map images
logger.info("loading map images...");
CompletableFuture<Void> loadImages = loadMaps.thenApplyAsync(_void -> {
CompletableFuture<?>[] loadAllImages = new CompletableFuture[this.mapsById.size()];
int cursor = 0;
for (Map m : mapsById.values()) {
if (m.getImage() == null || m.getThumb() == null) {
// @formatter:off
loadAllImages[cursor++] = CompletableFuture.supplyAsync(() -> {
return m;
}).thenComposeAsync(map -> {
return loadMapImage(map.getId(), false);
}).thenApply(image -> {
m.setImage(image);
return m;
}).thenComposeAsync(map -> {
return loadMapImage(map.getId(), true);
}).thenAccept(thumb -> {
m.setThumb(thumb);
});
// @formatter:on
} else {
loadAllImages[cursor++] = CompletableFuture.completedFuture(null);
}
}
return CompletableFuture.allOf(loadAllImages);
}).thenCompose(Function.identity());
// join all operations
return CompletableFuture.allOf(loadUsers, loadCheck, loadMaps, loadImages).thenAccept(v -> {
logger.info("refresh complete");
});
} else {
// debug mode
return CompletableFuture.runAsync(() -> {
logger.info("creating dummy KaroAPICache...");
final int DUMMY_USERS = 100;
final int DUMMY_MAPS = 100;
// create some dummy users
logger.info("creating dummy users...");
User u;
for (int i = 1; i <= DUMMY_USERS; i++) {
u = createDummyUser(i);
updateUser(u);
}
// create some dummy maps
logger.info("creating dummy maps...");
Map m;
for (int i = 1; i <= DUMMY_MAPS; i++) {
m = createDummyMap(i);
updateMap(m);
}
currentUser = usersById.get(1);
}).thenAccept(v -> {
logger.info("refresh complete");
});
}
}
Aggregations