/** * Copyright (c) 2001-2017 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html */ package net.sf.robocode.roborumble.battlesengine; import static net.sf.robocode.roborumble.util.ExcludesUtil.*; import static net.sf.robocode.roborumble.util.PropertiesUtil.getProperties; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.Random; /** * PrepareBattles is used for preparing battles. * Controlled by properties files. * * @author Albert P�rez (original) * @author Flemming N. Larsen (contributor) * @author Jerome Lavigne (contributor) */ public class PrepareBattles { private final String botsrepository; private final String participantsfile; private final String battlesfile; private final int numbattles; private final CompetitionsSelector size; private final String runonly; private final Properties generalratings; private final Properties miniratings; private final Properties microratings; private final Properties nanoratings; private final String priority; private final int prioritynum; private final int meleebots; private final static Random RANDOM = new Random(); public PrepareBattles(String propertiesfile) { // Read parameters Properties parameters = getProperties(propertiesfile); botsrepository = parameters.getProperty("BOTSREP", ""); participantsfile = parameters.getProperty("PARTICIPANTSFILE", ""); battlesfile = parameters.getProperty("INPUT", ""); numbattles = Integer.parseInt(parameters.getProperty("NUMBATTLES", "100")); String sizesfile = parameters.getProperty("CODESIZEFILE", ""); size = new CompetitionsSelector(sizesfile, botsrepository); runonly = parameters.getProperty("RUNONLY", "GENERAL"); prioritynum = Integer.parseInt(parameters.getProperty("BATTLESPERBOT", "500")); meleebots = Integer.parseInt(parameters.getProperty("MELEEBOTS", "10")); generalratings = getProperties(parameters.getProperty("RATINGS.GENERAL", "")); miniratings = getProperties(parameters.getProperty("RATINGS.MINIBOTS", "")); microratings = getProperties(parameters.getProperty("RATINGS.MICROBOTS", "")); nanoratings = getProperties(parameters.getProperty("RATINGS.NANOBOTS", "")); priority = parameters.getProperty("PRIORITYBATTLESFILE", ""); // Read and prepare exclude filters setExcludes(parameters); } public boolean createBattlesList() { List<String> names = new ArrayList<String>(); // Read participants BufferedReader br = null; try { FileReader fr = new FileReader(participantsfile); br = new BufferedReader(fr); String participant; while ((participant = br.readLine()) != null) { if (participant.indexOf(",") != -1) { String name = participant.substring(0, participant.indexOf(",")); if (isExcluded(name)) { continue; // ignore excluded participant } String jar = name.replace(' ', '_') + ".jar"; boolean exists = (new File(botsrepository + jar)).exists(); if (exists) { if ((runonly.equals("MINI") && size.checkCompetitorForSize(name, 1500)) || (runonly.equals("MICRO") && size.checkCompetitorForSize(name, 750)) || (runonly.equals("NANO") && size.checkCompetitorForSize(name, 250)) || (!runonly.equals("MINI") && !runonly.equals("MICRO") && !runonly.equals("NANO"))) { names.add(name); } } } } } catch (IOException e) { System.out.println("Participants file not found ... Aborting"); System.out.println(e); return false; } finally { if (br != null) { try { br.close(); } catch (IOException ignored) {} } } // Open battles file PrintStream outtxt; try { outtxt = new PrintStream(new BufferedOutputStream(new FileOutputStream(battlesfile)), false); } catch (IOException e) { System.out.println("Not able to open battles file " + battlesfile + " ... Aborting"); System.out.println(e); return false; } // Create the participants file Random random = new Random(); int count = 0; while (count < numbattles && names.size() > 1) { int bot1 = random.nextInt(names.size()); int bot2 = random.nextInt(names.size()); if (bot1 != bot2) { outtxt.println(names.get(bot1) + "," + names.get(bot2) + "," + runonly); count++; } } outtxt.close(); return true; } public boolean createSmartBattlesList() { List<String> namesAll = new ArrayList<String>(); List<String> namesMini = new ArrayList<String>(); List<String> namesMicro = new ArrayList<String>(); List<String> namesNano = new ArrayList<String>(); List<String> namesNoRanking = new ArrayList<String>(); List<String> priorityAll = new ArrayList<String>(); List<String> priorityMini = new ArrayList<String>(); List<String> priorityMicro = new ArrayList<String>(); List<String> priorityNano = new ArrayList<String>(); List<String> priorityBattles = new ArrayList<String>(); // Read participants BufferedReader br = null; try { FileReader fr = new FileReader(participantsfile); br = new BufferedReader(fr); String participant; while ((participant = br.readLine()) != null) { if (participant.indexOf(",") != -1) { String name = participant.substring(0, participant.indexOf(",")); if (isExcluded(name)) { continue; // ignore excluded participant } String jar = name.replace(' ', '_') + ".jar"; boolean exists = (new File(botsrepository + jar)).exists(); if (exists) { namesAll.add(name); if (size.checkCompetitorForSize(name, 1500)) { namesMini.add(name); } if (size.checkCompetitorForSize(name, 750)) { namesMicro.add(name); } if (size.checkCompetitorForSize(name, 250)) { namesNano.add(name); } if (robotHasPriority(name, generalratings)) { priorityAll.add(name); } if (size.checkCompetitorForSize(name, 1500) && robotHasPriority(name, miniratings)) { priorityMini.add(name); } if (size.checkCompetitorForSize(name, 750) && robotHasPriority(name, microratings)) { priorityMicro.add(name); } if (size.checkCompetitorForSize(name, 250) && robotHasPriority(name, nanoratings)) { priorityNano.add(name); } if (!isRobotInRatings(name)) { namesNoRanking.add(name); } } } } } catch (IOException e) { System.out.println("Participants file not found ... Aborting"); System.out.println(e); return false; } finally { if (br != null) { try { br.close(); } catch (IOException ignored) {} } } // Read priority battles br = null; try { FileReader fr = new FileReader(priority); br = new BufferedReader(fr); String record; while ((record = br.readLine()) != null) { String[] items = record.split(","); if (items.length == 3) { // Check that competitors exist String jar1 = items[0].replace(' ', '_') + ".jar"; boolean exists1 = (new File(botsrepository + jar1)).exists() && namesAll.contains(items[0]); String jar2 = items[1].replace(' ', '_') + ".jar"; boolean exists2 = (new File(botsrepository + jar2)).exists() && namesAll.contains(items[1]); // Add battles to priority battles list if (exists1 && exists2 && !priorityBattles.contains(record)) { priorityBattles.add(record); } else { System.out.println("Ignoring: " + record); } } } } catch (IOException e) { System.out.println("Priority battles file not found ... "); } finally { if (br != null) { try { br.close(); } catch (IOException ignore) {} } } // Delete priority battles (avoid duplication) File r = new File(priority); if (r.exists() && !r.delete()) { System.out.println("Cannot delete: " + priority); } // Open battles file PrintStream outtxt; try { outtxt = new PrintStream(new BufferedOutputStream(new FileOutputStream(battlesfile)), false); } catch (IOException e) { System.out.println("Not able to open battles file " + battlesfile + " ... Aborting"); System.out.println(e); return false; } // Create the participants file int count = 0; // Add priority battles while (count < numbattles && count < priorityBattles.size()) { String battle = priorityBattles.get(count); outtxt.println(battle); count++; } // Add bots with less than 500 battles, or a random battle if all bots have enough battles if (namesAll.size() > 1) { while (count < numbattles) { String[] bots; if (namesNoRanking.size() > 0) { // Bug [3547611] - New bots not given priority List<String> listWithSingleItem = new ArrayList<String>(); String bot = namesNoRanking.get(0); listWithSingleItem.add(bot); bots = getRandomBots(listWithSingleItem, namesAll); namesNoRanking.remove(0); } else if (priorityAll.size() > 0) { bots = getRandomBots(priorityAll, namesAll); } else if (priorityMini.size() > 0 && namesMini.size() > 1) { bots = getRandomBots(priorityMini, namesMini); } else if (priorityMicro.size() > 0 && namesMicro.size() > 1) { bots = getRandomBots(priorityMicro, namesMicro); } else if (priorityNano.size() > 0 && namesNano.size() > 1) { bots = getRandomBots(priorityNano, namesNano); } else { bots = getRandomBots(namesAll, namesAll); } if (bots != null) { outtxt.println(bots[0] + "," + bots[1] + "," + runonly); count++; } } } outtxt.close(); return true; } private String[] getRandomBots(List<String> list1, List<String> list2) { int bot1 = RANDOM.nextInt(list1.size()); int bot2 = RANDOM.nextInt(list2.size()); while ((list1.get(bot1)).equals(list2.get(bot2))) { bot1 = RANDOM.nextInt(list1.size()); bot2 = RANDOM.nextInt(list2.size()); } String[] bots = new String[2]; bots[0] = list1.get(bot1); bots[1] = list2.get(bot2); return bots; } private boolean robotHasPriority(String name, Properties ratings) { if (name == null || ratings == null) { return false; } String bot = name.replaceAll(" ", "_"); String values = ratings.getProperty(bot); if (values == null) { return false; // must be false (Bug 3474173) } String[] value = values.split(","); double battles = Double.parseDouble(value[1]); return (battles < prioritynum); } private boolean isRobotInRatings(String name) { if (name == null || name.trim().length() == 0) { return false; } String bot = name.replaceAll(" ", "_"); Properties[] ratingLists = new Properties[] { generalratings, miniratings, microratings, nanoratings }; for (Properties ratings : ratingLists) { if (ratings.getProperty(bot) != null) { return true; } } return false; } public boolean createMeleeBattlesList() { List<String> namesAll = new ArrayList<String>(); List<String> namesMini = new ArrayList<String>(); List<String> namesMicro = new ArrayList<String>(); List<String> namesNano = new ArrayList<String>(); List<String> namesNoRanking = new ArrayList<String>(); List<String> priorityAll = new ArrayList<String>(); List<String> priorityMini = new ArrayList<String>(); List<String> priorityMicro = new ArrayList<String>(); List<String> priorityNano = new ArrayList<String>(); List<String[]> priorityPairs = new ArrayList<String[]>(); // Read participants BufferedReader br = null; try { FileReader fr = new FileReader(participantsfile); br = new BufferedReader(fr); String participant; while ((participant = br.readLine()) != null) { if (participant.indexOf(",") != -1) { String name = participant.substring(0, participant.indexOf(",")); if (isExcluded(name)) { continue; // ignore excluded participant } String jar = name.replace(' ', '_') + ".jar"; boolean exists = (new File(botsrepository + jar)).exists(); if (exists) { namesAll.add(name); if (size.checkCompetitorForSize(name, 1500)) { namesMini.add(name); } if (size.checkCompetitorForSize(name, 750)) { namesMicro.add(name); } if (size.checkCompetitorForSize(name, 250)) { namesNano.add(name); } if (robotHasPriority(name, generalratings)) { priorityAll.add(name); } if (size.checkCompetitorForSize(name, 1500) && robotHasPriority(name, miniratings)) { priorityMini.add(name); } if (size.checkCompetitorForSize(name, 750) && robotHasPriority(name, microratings)) { priorityMicro.add(name); } if (size.checkCompetitorForSize(name, 250) && robotHasPriority(name, nanoratings)) { priorityNano.add(name); } if (!isRobotInRatings(name)) { namesNoRanking.add(name); } } } } } catch (IOException e) { System.out.println("Participants file not found ... Aborting"); System.out.println(e); return false; } finally { if (br != null) { try { br.close(); } catch (IOException ignored) {} } } // Read priority battles br = null; try { FileReader fr = new FileReader(priority); br = new BufferedReader(fr); String record; while ((record = br.readLine()) != null) { String[] items = record.split(","); if (items.length == 3) { // Check that competitors exist String jar1 = items[0].replace(' ', '_') + ".jar"; boolean exists1 = (new File(botsrepository + jar1)).exists() && namesAll.contains(items[0]); String jar2 = items[1].replace(' ', '_') + ".jar"; boolean exists2 = (new File(botsrepository + jar2)).exists() && namesAll.contains(items[1]); // Add battles to priority battles vector if (exists1 && exists2 && !priorityPairs.contains(items)) { priorityPairs.add(items); } else { System.out.println("Ignoring: " + record); } } } } catch (IOException e) { System.out.println("Priority battles file not found ... "); } finally { if (br != null) { try { br.close(); } catch (IOException ignore) {} } } // Delete priority battles (avoid duplication) File r = new File(priority); if (r.exists() && !r.delete()) { System.out.println("Cannot delete: " + priority); } // Open battles file PrintStream outtxt; try { outtxt = new PrintStream(new BufferedOutputStream(new FileOutputStream(battlesfile)), false); } catch (IOException e) { System.out.println("Not able to open battles file " + battlesfile + " ... Aborting"); System.out.println(e); return false; } // Create the participants file int count = 0; // Add bots with less than 500 battles, or a random battle if all bots have enough battles if (namesAll.size() > meleebots) { while (count < numbattles) { String[] bots = null; if (namesNoRanking.size() > 0) { // Bug [3547611] - New bots not given priority List<String> listWithSingleItem = new ArrayList<String>(); String bot = namesNoRanking.get(0); listWithSingleItem.add(bot); bots = getRandomMeleeBots(listWithSingleItem, namesAll); namesNoRanking.remove(0); } else if (count < priorityPairs.size()) { String[] prioritybots = priorityPairs.get(count); bots = getRandomMeleeBots(prioritybots[0], prioritybots[1], namesAll); } else if (priorityAll.size() > 0 && namesAll.size() >= meleebots) { bots = getRandomMeleeBots(priorityAll, namesAll); } else if (priorityMini.size() > 0 && namesMini.size() >= meleebots) { bots = getRandomMeleeBots(priorityMini, namesMini); } else if (priorityMicro.size() > 0 && namesMicro.size() >= meleebots) { bots = getRandomMeleeBots(priorityMicro, namesMicro); } else if (priorityNano.size() > 0 && namesNano.size() >= meleebots) { bots = getRandomMeleeBots(priorityNano, namesNano); } else if (namesAll.size() >= meleebots) { bots = getRandomMeleeBots(namesAll, namesAll); } if (bots != null) { StringBuilder battle = new StringBuilder(bots[0]); for (int i = 1; i < bots.length; i++) { battle.append(',').append(bots[i]); } battle.append(',').append(runonly); outtxt.println(battle); count++; } } } outtxt.close(); return true; } private String[] getRandomMeleeBots(List<String> list1, List<String> list2) { String[] bots = new String[meleebots]; bots[0] = list1.get(RANDOM.nextInt(list1.size())); int count = 1; while (count < meleebots) { bots[count] = list2.get(RANDOM.nextInt(list2.size())); boolean exists = false; for (int i = 0; i < count; i++) { if (bots[i].equals(bots[count])) { exists = true; } } if (!exists) { count++; } } return bots; } private String[] getRandomMeleeBots(String bot1, String bot2, List<String> list2) { String[] bots = new String[meleebots]; bots[0] = bot1; bots[1] = bot2; int count = 2; while (count < meleebots) { bots[count] = list2.get(RANDOM.nextInt(list2.size())); boolean exists = false; for (int i = 0; i < count; i++) { if (bots[i].equals(bots[count])) { exists = true; } } if (!exists) { count++; } } return bots; } }