/*******************************************************************************
* Copyright (c) 2003, 2010 Albert P�rez and RoboRumble 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
*
* Contributors:
* Albert P�rez
* - Initial API and implementation
* Flemming N. Larsen
* - Ported to Java 5
* - Removed dead code
* - Minor cleanup and optimizations
* - Properties are now read using PropertiesUtil.getProperties()
* - Renamed CheckCompetitorsForSize() into checkCompetitorsForSize()
* - Catch of entire Exception has been reduced to catch of IOException when
* only this exception is ever thrown
* - Added missing close() to buffered readers
* Jerome Lavigne
* - Added "smart battles" (priority robot pairs) for melee
*******************************************************************************/
package net.sf.robocode.roborumble.battlesengine;
import net.sf.robocode.io.Logger;
import static net.sf.robocode.roborumble.util.ExcludesUtil.*;
import static net.sf.robocode.roborumble.util.PropertiesUtil.getProperties;
import java.io.*;
import java.util.Properties;
import java.util.Random;
import java.util.Vector;
/**
* 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;
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() {
Vector<String> names = new Vector<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.checkCompetitorsForSize(name, name, 1500))
|| (runonly.equals("MICRO") && size.checkCompetitorsForSize(name, name, 750))
|| (runonly.equals("NANO") && size.checkCompetitorsForSize(name, 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() {
Vector<String> namesall = new Vector<String>();
Vector<String> namesmini = new Vector<String>();
Vector<String> namesmicro = new Vector<String>();
Vector<String> namesnano = new Vector<String>();
Vector<String> priorityall = new Vector<String>();
Vector<String> prioritymini = new Vector<String>();
Vector<String> prioritymicro = new Vector<String>();
Vector<String> prioritynano = new Vector<String>();
Vector<String> prioritarybattles = new Vector<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.checkCompetitorsForSize(name, name, 1500)) {
namesmini.add(name);
}
if (size.checkCompetitorsForSize(name, name, 750)) {
namesmicro.add(name);
}
if (size.checkCompetitorsForSize(name, name, 250)) {
namesnano.add(name);
}
if (robothaspriority(name, generalratings)) {
priorityall.add(name);
}
if (size.checkCompetitorsForSize(name, name, 1500) && robothaspriority(name, miniratings)) {
prioritymini.add(name);
}
if (size.checkCompetitorsForSize(name, name, 750) && robothaspriority(name, microratings)) {
prioritymicro.add(name);
}
if (size.checkCompetitorsForSize(name, name, 250) && robothaspriority(name, nanoratings)) {
prioritynano.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();
String jar2 = items[1].replace(' ', '_') + ".jar";
boolean exists2 = (new File(botsrepository + jar2)).exists();
// Add battles to prioritary battles vector
if (exists1 && exists2) {
prioritarybattles.add(record);
}
}
}
} catch (IOException e) {
System.out.println("Prioritary battles file not found ... ");
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {}
}
}
// Delete priority battles (avoid duplication)
File r = new File(priority);
if (r.exists() && !r.delete()) {
Logger.logError("Cannot delete: " + r);
}
// 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;
// Add prioritary battles
while (count < numbattles && count < prioritarybattles.size()) {
String battle = prioritarybattles.get(count);
outtxt.println(battle);
count++;
}
// Add bots with less than 500 battles, or a random battle if all bots have enough battles
while (count < numbattles && namesall.size() > 1) {
String[] bots;
if (priorityall.size() > 0) {
bots = getbots(priorityall, namesall, random);
} else if (prioritymini.size() > 0 && namesmini.size() > 1) {
bots = getbots(prioritymini, namesmini, random);
} else if (prioritymicro.size() > 0 && namesmicro.size() > 1) {
bots = getbots(prioritymicro, namesmicro, random);
} else if (prioritynano.size() > 0 && namesnano.size() > 1) {
bots = getbots(prioritynano, namesnano, random);
} else {
bots = getbots(namesall, namesall, random);
}
if (bots != null) {
outtxt.println(bots[0] + "," + bots[1] + "," + runonly);
count++;
}
}
outtxt.close();
return true;
}
private String[] getbots(Vector<String> list1, Vector<String> list2, Random rand) {
int bot1 = rand.nextInt(list1.size());
int bot2 = rand.nextInt(list2.size());
while ((list1.get(bot1)).equals(list2.get(bot2))) {
bot1 = rand.nextInt(list1.size());
bot2 = rand.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 (ratings == null) {
return false;
}
String bot = name.replaceAll(" ", "_");
String values = ratings.getProperty(bot);
if (values == null) {
return true;
}
String[] value = values.split(",");
double battles = Double.parseDouble(value[1]);
return (battles < prioritynum);
}
public boolean createMeleeBattlesList() {
Vector<String> namesall = new Vector<String>();
Vector<String> namesmini = new Vector<String>();
Vector<String> namesmicro = new Vector<String>();
Vector<String> namesnano = new Vector<String>();
Vector<String> priorityall = new Vector<String>();
Vector<String> prioritymini = new Vector<String>();
Vector<String> prioritymicro = new Vector<String>();
Vector<String> prioritynano = new Vector<String>();
Vector<String[]> prioritypairs = new Vector<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.checkCompetitorsForSize(name, name, 1500)) {
namesmini.add(name);
}
if (size.checkCompetitorsForSize(name, name, 750)) {
namesmicro.add(name);
}
if (size.checkCompetitorsForSize(name, name, 250)) {
namesnano.add(name);
}
if (robothaspriority(name, generalratings)) {
priorityall.add(name);
}
if (size.checkCompetitorsForSize(name, name, 1500) && robothaspriority(name, miniratings)) {
prioritymini.add(name);
}
if (size.checkCompetitorsForSize(name, name, 750) && robothaspriority(name, microratings)) {
prioritymicro.add(name);
}
if (size.checkCompetitorsForSize(name, name, 250) && robothaspriority(name, nanoratings)) {
prioritynano.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();
String jar2 = items[1].replace(' ', '_') + ".jar";
boolean exists2 = (new File(botsrepository + jar2)).exists();
// Add battles to prioritary battles vector
if (exists1 && exists2) {
prioritypairs.add(items);
}
}
}
} catch (IOException e) {
System.out.println("Priority battles file not found ... ");
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {}
}
}
// Delete priority battles (avoid duplication)
File r = new File(priority);
if (!r.delete()) {
System.out.println("Cannot delete the priority battles file " + 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
Random random = new Random();
int count = 0;
// Add bots with less than 500 battles, or a random battle if all bots have enough battles
while (count < numbattles && namesall.size() > meleebots) {
String[] bots = null;
if (count < prioritypairs.size()) {
String[] prioritybots = prioritypairs.get(count);
bots = getMeleeBots(prioritybots[0], prioritybots[1], namesall, random);
} else if (priorityall.size() > 0 && namesall.size() >= meleebots) {
bots = getmeleebots(priorityall, namesall, random);
} else if (prioritymini.size() > 0 && namesmini.size() >= meleebots) {
bots = getmeleebots(prioritymini, namesmini, random);
} else if (prioritymicro.size() > 0 && namesmicro.size() >= meleebots) {
bots = getmeleebots(prioritymicro, namesmicro, random);
} else if (prioritynano.size() > 0 && namesnano.size() >= meleebots) {
bots = getmeleebots(prioritynano, namesnano, random);
} else if (namesall.size() >= meleebots) {
bots = getmeleebots(namesall, namesall, random);
}
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[] getmeleebots(Vector<String> list1, Vector<String> list2, Random rand) {
String[] bots = new String[meleebots];
bots[0] = list1.get(rand.nextInt(list1.size()));
int count = 1;
while (count < meleebots) {
bots[count] = list2.get(rand.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[] getMeleeBots(String bot1, String bot2, Vector<String> list2, Random rand) {
String[] bots = new String[meleebots];
bots[0] = bot1;
bots[1] = bot2;
int count = 2;
while (count < meleebots) {
bots[count] = list2.get(rand.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;
}
}