package bots; import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import com.biotools.meerkat.Player; import com.biotools.meerkat.util.Preferences; /** * A BotRepository is responsible for loading Meerkat-Bots that are defined in * the /data/bots directory of the program in *.pd-files.<br> * <br> * Currently not supported properties: PLAYER_JAR_FILE <br> * */ public class BotRepository { // key = botname in canonical form AINAME/BOTNAME private Map<String, BotMetaData> botNameToBots = new HashMap<String, BotMetaData>(); private Logger log = Logger.getLogger(this.getClass().getName()); public BotRepository() { findBots(new File("./data/bots")); } /** * searches recursivly through the given directory to find *.pd files */ private void findBots(File botDirectory) { File[] dirEntries = botDirectory.listFiles(); for (File file : dirEntries) { if (file.isDirectory()) { findBots(file); } else if (file.getName().endsWith(".pd")) { readBotFromMeerkatFile(file); } } } private void readBotFromMeerkatFile(File meerkatPDFile) { Preferences prefs = new Preferences(meerkatPDFile); String botClassName = prefs.getPreference("PLAYER_CLASS"); if (botClassName.endsWith("PlugInOpponent")) { // PlugInOpponent is just a Decorator used in PA to allow for // special classLoading. // For now we expect all bots on the classpath botClassName = prefs.getPreference("BOT_PLAYER_CLASS"); } String playerName = prefs.getPreference("PLAYER_NAME"); String aiName = prefs.getPreference("AI_NAME"); String fullName = aiName + "/" + playerName; boolean noLimitBot = prefs.getBoolean("NO_LIMIT", false); try { Class.forName(botClassName); botNameToBots.put(fullName, new BotMetaData(fullName, botClassName, noLimitBot, prefs)); } catch (ClassNotFoundException e) { log.fine("Bot '" + botClassName + "' from '" + meerkatPDFile + "' could not be loaded"); } } /** * @return names of all bots found */ public Set<String> getBotNames() { return Collections.unmodifiableSet(botNameToBots.keySet()); } /** * @param botName * @return BotMetaData of bot with given name (or null if not existent) */ public BotMetaData getBotMetaData(String botName) { return botNameToBots.get(botName); } /** * creates a bot and initializes it. * * @param string * @return * @throws IllegalArgumentException * if bot doesn't exist */ public Player createBot(String botName) { BotMetaData botMetaData = botNameToBots.get(botName); if (botMetaData == null) { throw new IllegalArgumentException("Bot '" + botName + "' does not exist"); } try { Class<?> botClass = Class.forName(botMetaData.getBotClassName()); Player botInstance = (Player) botClass.newInstance(); botInstance.init(botMetaData.getBotPreferences()); return botInstance; } catch (Exception e) { throw new RuntimeException("Error creating bot '" + botName + "'", e); } } /** * add a bot manually without *.pd-file * @param botMetaData */ public void addBot(BotMetaData botMetaData) { botNameToBots.put(botMetaData.getBotName(), botMetaData); } }