Talk:RoboRumble/Development
Background Uploader
This code, if run with a script in background after every iteration of roborumble's client, will upload your result while your client is fighting a new iteration, reducing the iteration time of 25% in the best case.
I'm actually patching roborumble 1.6.0 code to include this script's functionally (simply threading it and modifying the logging system for multi thread) in the hope this will be included in the next official roborumble's client
see after the code for installation instruction
ATTENTION: you MUST set roborumble.txt UPLOAD=NOT, ITERATION=NOT, and this code WORKS ONLY FOR 1VS1!!
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; public class UploaderMain { static String infoThread; String clientVersion = "1"; long maxTry = 10; public static void main(String args[]){ String infoFilePath = "./roborumble/roborumble.txt"; switch (args.length){ case 2: infoFilePath = args[1]; //whitout break; case 1: infoThread = args[0]; break; case 0: infoThread = ""; break; default: System.out.println("Usage: java UploaderMain [id] [path]\nid: name of this thread\npath: Path to roborumble settings file"); return; } File test = new File(infoFilePath); if ( !test.exists() ){ System.err.println("Roborumble setting file not found, try to specify his pah by default"); return; } new UploaderMain(infoFilePath); } public UploaderMain(String infoFilePath){ logOut("Starting Uploader"); // read info from file ArrayList<String> allInfo = readFIle( infoFilePath ); // extact info String[] info = findInfo(allInfo); if ((info == null) || (info.length != 2)){ logErr("Roborumble settings file invalid"); return; } // set info String uploadServerUrl = info[0]; String battleFilePath = info[1]; // read battle from file ArrayList<String> battles = readFIle( battleFilePath ); if (battles == null){ logErr("Battle files format invalid"); return; } // delete old battle file File oldBattle = new File( battleFilePath ); oldBattle.delete(); // prepare data to be uploaded (only 1vs1 supported) battles = prepareToUpload1VS1(battles); ArrayList<String> battlesNotSend; long countTry = 0; while ((battles.size() > 0) && (countTry < maxTry)){ battlesNotSend = new ArrayList<String>(); for (String battle : battles){ if ( !sendBattle(battle, uploadServerUrl) ) battlesNotSend.add(battle); } battles = battlesNotSend; countTry++; } logOut("Stopping Uploader, number of not uploaded battle: "+battles.size()); if (battles.size() > 0) for (String battle:battles) write(battle+"\n", "results.txt"); } private String[] findInfo(ArrayList<String> allInfo) { /* * FIND INFO: * at [0]: uploadServerUrl - RESULTSURL= * at [1]: battleFilePath - OUTPUT= */ String[] info = new String[2]; info[0] = null; info[1] = null; for (String ris : allInfo){ if (ris.indexOf("RESULTSURL=") >= 0){ info[0] = ris.substring(ris.indexOf("=")+1); } if (ris.indexOf("OUTPUT=") >= 0){ info[1] = ris.substring(ris.indexOf("=")+1); } } if ((info[0] != null)&&(info[1] != null)) return info; return null; } private ArrayList<String> prepareToUpload1VS1(ArrayList<String> battles) { ArrayList<String> preparedBattles = new ArrayList<String>(); String[] parametres = new String[6]; String preparingBattle; for(int i = 0; i < battles.size(); i++){ //extrapolate battlefield information parametres = battles.get(i).split(","); if ( parametres.length != 6 ){ logErr( "invalid battlefield: "+battles.get(i) ); continue; } // preparing string to upload preparingBattle = new String(); preparingBattle += "version="+clientVersion; preparingBattle += "&game="+parametres[0]; preparingBattle += "&rounds="+parametres[1]; preparingBattle += "&field="+parametres[2]; preparingBattle += "&user="+parametres[3]; preparingBattle += "&time="+parametres[4]; // extrapolate robot 1 i++; parametres = battles.get(i).split(","); // if invalid information if ( parametres.length != 4 ){ logErr( "invalid robot: "+battles.get(i) ); continue; } // preparing string to upload preparingBattle += "&fname="+parametres[0]; preparingBattle += "&fscore="+parametres[1]; preparingBattle += "&fbulletd="+parametres[2]; preparingBattle += "&fsurvival="+parametres[3]; // extrapolate robot 2 i++; parametres = battles.get(i).split(","); // if invalid information if ( parametres.length != 4 ){ logErr( "invalid robot: "+battles.get(i) ); continue; } // preparing string to upload preparingBattle += "&sname="+parametres[0]; preparingBattle += "&sscore="+parametres[1]; preparingBattle += "&sbulletd="+parametres[2]; preparingBattle += "&ssurvival="+parametres[3]; preparedBattles.add(preparingBattle); } return preparedBattles; } private boolean sendBattle(String battle, String uploadServerURL){ // crea l'URL e la connessione HTTP con la servlet try{ URL url = new URL(uploadServerURL); HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection(); httpURLConnection.setRequestMethod( "POST" ) ; //httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); httpURLConnection.connect() ; OutputStreamWriter dataOutputStream = new OutputStreamWriter(httpURLConnection.getOutputStream()); dataOutputStream.write( battle ); dataOutputStream.flush(); dataOutputStream.close(); BufferedReader dataInputStream = new BufferedReader( new InputStreamReader( httpURLConnection.getInputStream() ) ); String response = new String(); boolean okUpload = false; while(true){ response = dataInputStream.readLine(); if ( response == null ) break; if ( response.indexOf("OK.") == 0 ) okUpload = true; logOut("risposta: "+response); } dataInputStream.close(); return okUpload; }catch(Exception e){ logErr("error: "+e); } return false; } private void logOut(String string) { log(string, "./log/outUploader"); } private void logErr(String string) { log(string, "./log/errUploader"); } private void log(String string, String fileName) { write(infoThread+": "+string+"\n", fileName); } private void write(String string, String fileName) { try { BufferedWriter output = new BufferedWriter(new FileWriter(fileName, true)); output.write(string); output.close(); } catch (Exception e) { e.printStackTrace(); } } private ArrayList<String> readFIle( String filePath ) { try{ ArrayList<String> battles = new ArrayList<String>(); FileReader battleFile = new FileReader( filePath ); BufferedReader battleReader = new BufferedReader(battleFile); String battle = null; while(true){ battle = battleReader.readLine(); if (battle==null) break; battles.add(battle); } battleReader.close(); return battles; }catch(Exception e){ System.out.println("Error: "+e); return null; } } }
thank to Rednaxela for code formatting
INSTALLATION copy and compile the code in the robocode home directory(where there is roborumble.bat and roborumble.sh), then if you are windows user create a new file "nameAsYouWant.bat" and write on it (script is not tested!):
:inizio CALL roborumble.bat START java UploaderMain GOTO inizio
if you are under UNIX create a new directory "log" new file "nameAsYouWant.sh" and write on it the following code. This script is more advanced: in the log directory you will find the log of all client's iteration, with at the end the execution time. you can find also 2 log file of the uploader:
- errUpdaters.txt created and filled with the uploader's error (no error no file)
- outUploader.txt filled with server response and live time of uploaders
- results.txt
this last 2 file have to be deleted sometimes
#!/bin/bash echo count=0 while [ "$var1" != "fine" ] # while test "$var1" != "fine", forever do let "count=count+1" date echo "battle n: " $count time ./roborumble.sh &> ./log/temp$count.txt java UploaderMain $count & echo done exit 0
WARNING: in the robocode's home directory there will be created a file called results.txt with all unloaded battle; delete it sometimes, with errUpdaters.txt and outUpdaters.txt if you're using unix's script. --lestofante 00:09, 6 December 2008 (UTC)
Hmm, when implementing this functionality as a patch, could you make it an option? Or alternatively, at least also make an option for a delay between iterations? I don't like how hot my laptop CPU gets if it doesn't get any breaks ;) --Rednaxela 02:41, 6 December 2008 (UTC)