Discussion:
Recording RoboCode battles from Java API
a***@gmail.com
2016-03-04 10:05:31 UTC
Permalink
Hello everyone

I'm trying to record battles from the java API. I would like to trigger
battles inside Java and then, at the end of the run, be able to see the
replay only of the battles i'm interested in.

This is my code:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

import robocode.control.*;
import net.sf.robocode.battle.events.BattleEventDispatcher;
import net.sf.robocode.io.Logger;
import net.sf.robocode.recording.BattleRecordFormat;
import net.sf.robocode.recording.RecordManager;
import net.sf.robocode.serialization.SerializableOptions;
import net.sf.robocode.settings.SettingsManager;

public class BattleRunner {

// Path configuration
public static String roboCodePath =
"/home/andrea/git/AttProgIA_2016/RoboCode";

private static String recordFile = "/tmp/testingLOL.xml";

// Recording
private static SettingsManager settingsManager = new SettingsManager();
private static BattleEventDispatcher battleEventDispatcher = new
BattleEventDispatcher();
private static RecordManager recordManager = new
RecordManager(settingsManager);

public static void main(String[] args) {


// Disable log messages from Robocode
RobocodeEngine.setLogMessagesEnabled(false);

// Create the RobocodeEngine
RobocodeEngine engine = new RobocodeEngine(new
java.io.File(roboCodePath));


// Setup the battle specification

int numberOfRounds = 5;
BattlefieldSpecification battlefield = new
BattlefieldSpecification(800, 600); // 800x600
RobotSpecification[] selectedRobots =
engine.getLocalRepository("sample.RamFire,sample.Corners");

BattleSpecification battleSpec = new
BattleSpecification(numberOfRounds, battlefield, selectedRobots);

// *********************
Logger.setLogListener(battleEventDispatcher);
recordManager.attachRecorder(battleEventDispatcher);


// Show the Robocode battle view
engine.setVisible(false);

// *********************

// Run our specified battle and let it run till it is over
engine.runBattle(battleSpec, true); // waits till the battle
finishes

// Save the recording

recordManager.saveRecord(recordFile, BattleRecordFormat.XML, new
SerializableOptions(false));
// Cleanup our RobocodeEngine
engine.close();

// Make sure that the Java VM is shut down properly
System.exit(0);
}
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Unfortunately all i get it's:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

No robocode.properties. Using defaults.
Exception in thread "Application Thread" java.lang.NullPointerException
at
net.sf.robocode.recording.RecordManager.saveRecord(RecordManager.java:344)
at BattleRunner.main(BattleRunner.java:57)

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Which i really don't understand... battles run properly (i tried to print
the results and it works correctly), but as soon as i try to save the
record i receive this null pointer exception. It looks like the recordInfo
variable inside RecordManager it's not initialized properly...

Can you give me a hint? It's really annoying, and unfortunately i can't
find any documentation or examples online...

Thank you

Andrea
--
You received this message because you are subscribed to the Google Groups "robocode" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robocode+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
fnl
2016-03-06 22:53:55 UTC
Permalink
Hi Andrea,

First of all, the robocode.control.RobocodeEngine does not support saving
the games. It should be added to the RobocodeEngine.

Note that you should only use classes that are a part of the public API.
That is robocode.* classes like e.g. robocode.control.
You are not supposed to "hack" into the internals of Robocode by accessing
net.sf.robocode classes. Those are internal and could change at any time.
Code based on internal classes might work now, but not in the future. Only
the public API is guaranteed to be backward compatible.

What you could do instead is enabling "auto recording" in Robocode from the
UI by selecting Options -> Preferences -> Common Options -> "Enable auto
recording ..."

This feature will automatically record the battles and store these into the
/battles directory under the /robocode directory.
A record will get a name like
"20160306-233521-sample.RamFire-sample.Corners.zip.br" (br stands for
Battle Record)

You can replay this in Robocode (Battle -> Open Record).

Alternatively, you could use the Robocode command-line option
<http://robowiki.net/wiki/Robocode/Console_Usage>s, where you can set
'-battle <battle file>' to run a specific battle specification and also set
'-recordXML' in order to record the battle in XML format.
You can replay the records using '-replay <record file>' .

Note that you could run Robocode in a Java Process
<https://docs.oracle.com/javase/7/docs/api/java/lang/Process.html>. If you
do this, you should use robocode.sh as the first command-line argument and
the add the command-line options, you need. :-)

I hope this helps?

Kind regards
- Flemming
Post by a***@gmail.com
Hello everyone
I'm trying to record battles from the java API. I would like to trigger
battles inside Java and then, at the end of the run, be able to see the
replay only of the battles i'm interested in.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
import robocode.control.*;
import net.sf.robocode.battle.events.BattleEventDispatcher;
import net.sf.robocode.io.Logger;
import net.sf.robocode.recording.BattleRecordFormat;
import net.sf.robocode.recording.RecordManager;
import net.sf.robocode.serialization.SerializableOptions;
import net.sf.robocode.settings.SettingsManager;
public class BattleRunner {
// Path configuration
public static String roboCodePath =
"/home/andrea/git/AttProgIA_2016/RoboCode";
private static String recordFile = "/tmp/testingLOL.xml";
// Recording
private static SettingsManager settingsManager = new SettingsManager();
private static BattleEventDispatcher battleEventDispatcher = new
BattleEventDispatcher();
private static RecordManager recordManager = new
RecordManager(settingsManager);
public static void main(String[] args) {
// Disable log messages from Robocode
RobocodeEngine.setLogMessagesEnabled(false);
// Create the RobocodeEngine
RobocodeEngine engine = new RobocodeEngine(new
java.io.File(roboCodePath));
// Setup the battle specification
int numberOfRounds = 5;
BattlefieldSpecification battlefield = new
BattlefieldSpecification(800, 600); // 800x600
RobotSpecification[] selectedRobots =
engine.getLocalRepository("sample.RamFire,sample.Corners");
BattleSpecification battleSpec = new
BattleSpecification(numberOfRounds, battlefield, selectedRobots);
// *********************
Logger.setLogListener(battleEventDispatcher);
recordManager.attachRecorder(battleEventDispatcher);
// Show the Robocode battle view
engine.setVisible(false);
// *********************
// Run our specified battle and let it run till it is over
engine.runBattle(battleSpec, true); // waits till the battle
finishes
// Save the recording
recordManager.saveRecord(recordFile, BattleRecordFormat.XML, new
SerializableOptions(false));
// Cleanup our RobocodeEngine
engine.close();
// Make sure that the Java VM is shut down properly
System.exit(0);
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
No robocode.properties. Using defaults.
Exception in thread "Application Thread" java.lang.NullPointerException
at
net.sf.robocode.recording.RecordManager.saveRecord(RecordManager.java:344)
at BattleRunner.main(BattleRunner.java:57)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Which i really don't understand... battles run properly (i tried to print
the results and it works correctly), but as soon as i try to save the
record i receive this null pointer exception. It looks like the recordInfo
variable inside RecordManager it's not initialized properly...
Can you give me a hint? It's really annoying, and unfortunately i can't
find any documentation or examples online...
Thank you
Andrea
--
You received this message because you are subscribed to the Google Groups "robocode" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robocode+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Andrea Giardini
2016-03-07 09:38:08 UTC
Permalink
Hi Flemming

Thank you for your answer, it was helpful :)

However, it didn't really solve my problem... maybe it's better if i
explain you my use case a little:

I would like to trigger a set of battles on my server every time i push
to a git repository. The battles are run using a CI system that,
ideally, will give me the artifacts of the recorded battles once the
process is complete. Using the graphic interface is not an option here.

As you suggested i could just create several Java processes triggering
the Robocode CLI with different battle files. This solution would work
for sure, but I would like to know it we could do something better (it
reloads a JVM after every battle, definitely not optimal). All i need is
something like this example
http://robocode.sourceforge.net/docs/robocode/robocode/control/package-summary.html
but able to record the battles to a br file.

Is it possible?

Cheers
Andrea
Post by fnl
Hi Andrea,
First of all, the robocode.control.RobocodeEngine does not support
saving the games. It should be added to the RobocodeEngine.
Note that you should only use classes that are a part of the public
API. That is robocode.* classes like e.g. robocode.control.
You are not supposed to "hack" into the internals of Robocode by
accessing net.sf.robocode classes. Those are internal and could change
at any time.
Code based on internal classes might work now, but not in the future.
Only the public API is guaranteed to be backward compatible.
What you could do instead is enabling "auto recording" in Robocode
from the UI by selecting Options -> Preferences -> Common Options ->
"Enable auto recording ..."
This feature will automatically record the battles and store these
into the /battles directory under the /robocode directory.
A record will get a name like
"20160306-233521-sample.RamFire-sample.Corners.zip.br" (br stands for
Battle Record)
You can replay this in Robocode (Battle -> Open Record).
Alternatively, you could use the Robocode command-line option
<http://robowiki.net/wiki/Robocode/Console_Usage>s, where you can set
'-battle <battle file>' to run a specific battle specification and
also set '-recordXML' in order to record the battle in XML format.
You can replay the records using '-replay <record file>' .
Note that you could run Robocode in a Java Process
<https://docs.oracle.com/javase/7/docs/api/java/lang/Process.html>. If
you do this, you should use robocode.sh as the first command-line
argument and the add the command-line options, you need. :-)
I hope this helps?
Kind regards
- Flemming
Hello everyone
I'm trying to record battles from the java API. I would like to
trigger battles inside Java and then, at the end of the run, be
able to see the replay only of the battles i'm interested in.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
import robocode.control.*;
import net.sf.robocode.battle.events.BattleEventDispatcher;
import net.sf.robocode.io.Logger;
import net.sf.robocode.recording.BattleRecordFormat;
import net.sf.robocode.recording.RecordManager;
import net.sf.robocode.serialization.SerializableOptions;
import net.sf.robocode.settings.SettingsManager;
public class BattleRunner {
// Path configuration
public static String roboCodePath =
"/home/andrea/git/AttProgIA_2016/RoboCode";
private static String recordFile = "/tmp/testingLOL.xml";
// Recording
private static SettingsManager settingsManager = new
SettingsManager();
private static BattleEventDispatcher battleEventDispatcher =
new BattleEventDispatcher();
private static RecordManager recordManager = new
RecordManager(settingsManager);
public static void main(String[] args) {
// Disable log messages from Robocode
RobocodeEngine.setLogMessagesEnabled(false);
// Create the RobocodeEngine
RobocodeEngine engine = new RobocodeEngine(new
java.io.File(roboCodePath));
// Setup the battle specification
int numberOfRounds = 5;
BattlefieldSpecification battlefield = new
BattlefieldSpecification(800, 600); // 800x600
RobotSpecification[] selectedRobots =
engine.getLocalRepository("sample.RamFire,sample.Corners");
BattleSpecification battleSpec = new
BattleSpecification(numberOfRounds, battlefield, selectedRobots);
// *********************
Logger.setLogListener(battleEventDispatcher);
recordManager.attachRecorder(battleEventDispatcher);
// Show the Robocode battle view
engine.setVisible(false);
// *********************
// Run our specified battle and let it run till it is over
engine.runBattle(battleSpec, true); // waits till the
battle finishes
// Save the recording
recordManager.saveRecord(recordFile,
BattleRecordFormat.XML, new SerializableOptions(false));
// Cleanup our RobocodeEngine
engine.close();
// Make sure that the Java VM is shut down properly
System.exit(0);
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
No robocode.properties. Using defaults.
Exception in thread "Application Thread"
java.lang.NullPointerException
at
net.sf.robocode.recording.RecordManager.saveRecord(RecordManager.java:344)
at BattleRunner.main(BattleRunner.java:57)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Which i really don't understand... battles run properly (i tried
to print the results and it works correctly), but as soon as i try
to save the record i receive this null pointer exception. It looks
like the recordInfo variable inside RecordManager it's not
initialized properly...
Can you give me a hint? It's really annoying, and unfortunately i
can't find any documentation or examples online...
Thank you
Andrea
--
You received this message because you are subscribed to the Google Groups "robocode" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robocode+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
fnl
2016-03-09 21:36:07 UTC
Permalink
Hi Andrea,

It is possible, if the RobocodeEngine is extended to provide the recording
feature (both Java and .NET version).
But it is time consuming to implement, and you might be the only one asking
for such a feature.
You are welcome to add this feature to the RobocodeEngine as Robocode is
Open Source. :-)

Otherwise, I think you'll have to live with the JVM reloading or take
advantage of the auto-recording feature, which also works with the
RobocodeEngine.

Cheers,
- Flemming
Post by Andrea Giardini
Hi Flemming
Thank you for your answer, it was helpful :)
However, it didn't really solve my problem... maybe it's better if i
I would like to trigger a set of battles on my server every time i push to
a git repository. The battles are run using a CI system that, ideally, will
give me the artifacts of the recorded battles once the process is complete.
Using the graphic interface is not an option here.
As you suggested i could just create several Java processes triggering the
Robocode CLI with different battle files. This solution would work for
sure, but I would like to know it we could do something better (it reloads
a JVM after every battle, definitely not optimal). All i need is something
like this example
http://robocode.sourceforge.net/docs/robocode/robocode/control/package-summary.html
but able to record the battles to a br file.
Is it possible?
Cheers
Andrea
Hi Andrea,
First of all, the robocode.control.RobocodeEngine does not support saving
the games. It should be added to the RobocodeEngine.
Note that you should only use classes that are a part of the public API.
That is robocode.* classes like e.g. robocode.control.
You are not supposed to "hack" into the internals of Robocode by accessing
net.sf.robocode classes. Those are internal and could change at any time.
Code based on internal classes might work now, but not in the future. Only
the public API is guaranteed to be backward compatible.
What you could do instead is enabling "auto recording" in Robocode from
the UI by selecting Options -> Preferences -> Common Options -> "Enable
auto recording ..."
This feature will automatically record the battles and store these into
the /battles directory under the /robocode directory.
A record will get a name like "
20160306-233521-sample.RamFire-sample.Corners.zip.br" (br stands for
Battle Record)
You can replay this in Robocode (Battle -> Open Record).
Alternatively, you could use the Robocode command-line option
<http://robowiki.net/wiki/Robocode/Console_Usage>s, where you can set
'-battle <battle file>' to run a specific battle specification and also set
'-recordXML' in order to record the battle in XML format.
You can replay the records using '-replay <record file>' .
Note that you could run Robocode in a Java Process
<https://docs.oracle.com/javase/7/docs/api/java/lang/Process.html>. If
you do this, you should use robocode.sh as the first command-line argument
and the add the command-line options, you need. :-)
I hope this helps?
Kind regards
- Flemming
Post by a***@gmail.com
Hello everyone
I'm trying to record battles from the java API. I would like to trigger
battles inside Java and then, at the end of the run, be able to see the
replay only of the battles i'm interested in.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
import robocode.control.*;
import net.sf.robocode.battle.events.BattleEventDispatcher;
import net.sf.robocode.io.Logger;
import net.sf.robocode.recording.BattleRecordFormat;
import net.sf.robocode.recording.RecordManager;
import net.sf.robocode.serialization.SerializableOptions;
import net.sf.robocode.settings.SettingsManager;
public class BattleRunner {
// Path configuration
public static String roboCodePath =
"/home/andrea/git/AttProgIA_2016/RoboCode";
private static String recordFile = "/tmp/testingLOL.xml";
// Recording
private static SettingsManager settingsManager = new
SettingsManager();
private static BattleEventDispatcher battleEventDispatcher = new
BattleEventDispatcher();
private static RecordManager recordManager = new
RecordManager(settingsManager);
public static void main(String[] args) {
// Disable log messages from Robocode
RobocodeEngine.setLogMessagesEnabled(false);
// Create the RobocodeEngine
RobocodeEngine engine = new RobocodeEngine(new
java.io.File(roboCodePath));
// Setup the battle specification
int numberOfRounds = 5;
BattlefieldSpecification battlefield = new
BattlefieldSpecification(800, 600); // 800x600
RobotSpecification[] selectedRobots =
engine.getLocalRepository("sample.RamFire,sample.Corners");
BattleSpecification battleSpec = new
BattleSpecification(numberOfRounds, battlefield, selectedRobots);
// *********************
Logger.setLogListener(battleEventDispatcher);
recordManager.attachRecorder(battleEventDispatcher);
// Show the Robocode battle view
engine.setVisible(false);
// *********************
// Run our specified battle and let it run till it is over
engine.runBattle(battleSpec, true); // waits till the battle
finishes
// Save the recording
recordManager.saveRecord(recordFile, BattleRecordFormat.XML, new
SerializableOptions(false));
// Cleanup our RobocodeEngine
engine.close();
// Make sure that the Java VM is shut down properly
System.exit(0);
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
No robocode.properties. Using defaults.
Exception in thread "Application Thread" java.lang.NullPointerException
at
net.sf.robocode.recording.RecordManager.saveRecord(RecordManager.java:344)
at BattleRunner.main(BattleRunner.java:57)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Which i really don't understand... battles run properly (i tried to print
the results and it works correctly), but as soon as i try to save the
record i receive this null pointer exception. It looks like the recordInfo
variable inside RecordManager it's not initialized properly...
Can you give me a hint? It's really annoying, and unfortunately i can't
find any documentation or examples online...
Thank you
Andrea
--
You received this message because you are subscribed to the Google Groups "robocode" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robocode+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Andrea Giardini
2016-03-15 16:25:07 UTC
Permalink
Hi Flemming

Can you give me a couple of more hints about this?

Cheers
Andrea
Post by fnl
Hi Andrea,
It is possible, if the RobocodeEngine is extended to provide the
recording feature (both Java and .NET version).
But it is time consuming to implement, and you might be the only one
asking for such a feature.
You are welcome to add this feature to the RobocodeEngine as Robocode
is Open Source. :-)
Otherwise, I think you'll have to live with the JVM reloading or take
advantage of the auto-recording feature, which also works with the
RobocodeEngine.
Cheers,
- Flemming
Hi Flemming
Thank you for your answer, it was helpful :)
However, it didn't really solve my problem... maybe it's better if
I would like to trigger a set of battles on my server every time i
push to a git repository. The battles are run using a CI system
that, ideally, will give me the artifacts of the recorded battles
once the process is complete. Using the graphic interface is not
an option here.
As you suggested i could just create several Java processes
triggering the Robocode CLI with different battle files. This
solution would work for sure, but I would like to know it we could
do something better (it reloads a JVM after every battle,
definitely not optimal). All i need is something like this example
http://robocode.sourceforge.net/docs/robocode/robocode/control/package-summary.html
<http://robocode.sourceforge.net/docs/robocode/robocode/control/package-summary.html>
but able to record the battles to a br file.
Is it possible?
Cheers
Andrea
Post by fnl
Hi Andrea,
First of all, the robocode.control.RobocodeEngine does not
support saving the games. It should be added to the RobocodeEngine.
Note that you should only use classes that are a part of the
public API. That is robocode.* classes like e.g. robocode.control.
You are not supposed to "hack" into the internals of Robocode by
accessing net.sf.robocode classes. Those are internal and could
change at any time.
Code based on internal classes might work now, but not in the
future. Only the public API is guaranteed to be backward compatible.
What you could do instead is enabling "auto recording" in
Robocode from the UI by selecting Options -> Preferences ->
Common Options -> "Enable auto recording ..."
This feature will automatically record the battles and store
these into the /battles directory under the /robocode directory.
A record will get a name like
"20160306-233521-sample.RamFire-sample.Corners.zip.br
<http://20160306-233521-sample.RamFire-sample.Corners.zip.br>"
(br stands for Battle Record)
You can replay this in Robocode (Battle -> Open Record).
Alternatively, you could use the Robocode command-line option
<http://robowiki.net/wiki/Robocode/Console_Usage>s, where you can
set '-battle <battle file>' to run a specific battle
specification and also set '-recordXML' in order to record the
battle in XML format.
You can replay the records using '-replay <record file>' .
Note that you could run Robocode in a Java Process
<https://docs.oracle.com/javase/7/docs/api/java/lang/Process.html>.
If you do this, you should use robocode.sh as the first
command-line argument and the add the command-line options, you
need. :-)
I hope this helps?
Kind regards
- Flemming
Hello everyone
I'm trying to record battles from the java API. I would like
to trigger battles inside Java and then, at the end of the
run, be able to see the replay only of the battles i'm
interested in.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
import robocode.control.*;
import net.sf.robocode.battle.events.BattleEventDispatcher;
import net.sf.robocode.io.Logger;
import net.sf.robocode.recording.BattleRecordFormat;
import net.sf.robocode.recording.RecordManager;
import net.sf.robocode.serialization.SerializableOptions;
import net.sf.robocode.settings.SettingsManager;
public class BattleRunner {
// Path configuration
public static String roboCodePath =
"/home/andrea/git/AttProgIA_2016/RoboCode";
private static String recordFile = "/tmp/testingLOL.xml";
// Recording
private static SettingsManager settingsManager = new
SettingsManager();
private static BattleEventDispatcher
battleEventDispatcher = new BattleEventDispatcher();
private static RecordManager recordManager = new
RecordManager(settingsManager);
public static void main(String[] args) {
// Disable log messages from Robocode
RobocodeEngine.setLogMessagesEnabled(false);
// Create the RobocodeEngine
RobocodeEngine engine = new RobocodeEngine(new
java.io.File(roboCodePath));
// Setup the battle specification
int numberOfRounds = 5;
BattlefieldSpecification battlefield = new
BattlefieldSpecification(800, 600); // 800x600
RobotSpecification[] selectedRobots =
engine.getLocalRepository("sample.RamFire,sample.Corners");
BattleSpecification battleSpec = new
BattleSpecification(numberOfRounds, battlefield, selectedRobots);
// *********************
Logger.setLogListener(battleEventDispatcher);
recordManager.attachRecorder(battleEventDispatcher);
// Show the Robocode battle view
engine.setVisible(false);
// *********************
// Run our specified battle and let it run till it is over
engine.runBattle(battleSpec, true); // waits till the
battle finishes
// Save the recording
recordManager.saveRecord(recordFile,
BattleRecordFormat.XML, new SerializableOptions(false));
// Cleanup our RobocodeEngine
engine.close();
// Make sure that the Java VM is shut down properly
System.exit(0);
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
No robocode.properties. Using defaults.
Exception in thread "Application Thread"
java.lang.NullPointerException
at
net.sf.robocode.recording.RecordManager.saveRecord(RecordManager.java:344)
at BattleRunner.main(BattleRunner.java:57)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Which i really don't understand... battles run properly (i
tried to print the results and it works correctly), but as
soon as i try to save the record i receive this null pointer
exception. It looks like the recordInfo variable inside
RecordManager it's not initialized properly...
Can you give me a hint? It's really annoying, and
unfortunately i can't find any documentation or examples
online...
Thank you
Andrea
--
You received this message because you are subscribed to the Google Groups "robocode" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robocode+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
fnl
2016-03-15 20:31:03 UTC
Permalink
Well,

The robocode.control.RobocodeEngine is initialized with this method:

net.sf.robocode.core.RobocodeMainBase.initContainerForRobocodeEngine
(robocode.core => /src/main/java):


public static void initContainerForRobocodeEngine(File robocodeHome,
IBattleListener listener) {
try {
if (robocodeHome == null) {
robocodeHome = FileUtil.getCwd();
}
FileUtil.setCwd(robocodeHome);

File robotsDir = FileUtil.getRobotsDir();

if (robotsDir == null) {
throw new RuntimeException("No valid robot directory is
specified");
} else if (!(robotsDir.exists() && robotsDir.isDirectory())) {
throw new RuntimeException('\'' +
robotsDir.getAbsolutePath() + "' is not a valid robot directory");
}

} catch (IOException e) {
System.err.println(e);
return;
}

// here we cross transition to EngineClassLoader classes using
interface which is defined in system classLoader
RobocodeMainBase main =
Container.getComponent(RobocodeMainBase.class);

main.initForRobocodeEngine(listener);
}

Robocode(Engine) is started by this method:

robocode.control.RobocodeEngine.runBattle (robocode.api => /src/main/java)

public void runBattle(BattleSpecification battleSpecification, String
initialPositions, boolean waitTillOver) {
this.battleSpecification = battleSpecification;
ContainerBase.getComponent(IBattleManagerBase.class).startNewBattle(
battleSpecification, initialPositions,
waitTillOver, false);
}

Robocode is using the PicoContainer (more lightweight than e.g. Spring) for
code injection, where interfaces like IBattleManagerBase are replaced by
concrete object instaces within Module.java files (found in each Robocode
module/project).

If the RobocodeEngine must be extended to support saving records to XML
files, I propose a new method is provided on the IRobocodeEngine interface
(and RobocodeEngine implementation class) that sets up this stuff - very
similar to the code you used in your first mail in this thread. :-)

Cheers,
- Flemming
Post by Andrea Giardini
Hi Flemming
Can you give me a couple of more hints about this?
Cheers
Andrea
Hi Andrea,
It is possible, if the RobocodeEngine is extended to provide the recording
feature (both Java and .NET version).
But it is time consuming to implement, and you might be the only one
asking for such a feature.
You are welcome to add this feature to the RobocodeEngine as Robocode is
Open Source. :-)
Otherwise, I think you'll have to live with the JVM reloading or take
advantage of the auto-recording feature, which also works with the
RobocodeEngine.
Cheers,
- Flemming
Post by Andrea Giardini
Hi Flemming
Thank you for your answer, it was helpful :)
However, it didn't really solve my problem... maybe it's better if i
I would like to trigger a set of battles on my server every time i push
to a git repository. The battles are run using a CI system that, ideally,
will give me the artifacts of the recorded battles once the process is
complete. Using the graphic interface is not an option here.
As you suggested i could just create several Java processes triggering
the Robocode CLI with different battle files. This solution would work for
sure, but I would like to know it we could do something better (it reloads
a JVM after every battle, definitely not optimal). All i need is something
like this example
http://robocode.sourceforge.net/docs/robocode/robocode/control/package-summary.html
but able to record the battles to a br file.
Is it possible?
Cheers
Andrea
Hi Andrea,
First of all, the robocode.control.RobocodeEngine does not support saving
the games. It should be added to the RobocodeEngine.
Note that you should only use classes that are a part of the public API.
That is robocode.* classes like e.g. robocode.control.
You are not supposed to "hack" into the internals of Robocode by
accessing net.sf.robocode classes. Those are internal and could change at
any time.
Code based on internal classes might work now, but not in the future.
Only the public API is guaranteed to be backward compatible.
What you could do instead is enabling "auto recording" in Robocode from
the UI by selecting Options -> Preferences -> Common Options -> "Enable
auto recording ..."
This feature will automatically record the battles and store these into
the /battles directory under the /robocode directory.
A record will get a name like "
20160306-233521-sample.RamFire-sample.Corners.zip.br" (br stands for
Battle Record)
You can replay this in Robocode (Battle -> Open Record).
Alternatively, you could use the Robocode command-line option
<http://robowiki.net/wiki/Robocode/Console_Usage>s, where you can set
'-battle <battle file>' to run a specific battle specification and also set
'-recordXML' in order to record the battle in XML format.
You can replay the records using '-replay <record file>' .
Note that you could run Robocode in a Java Process
<https://docs.oracle.com/javase/7/docs/api/java/lang/Process.html>. If
you do this, you should use robocode.sh as the first command-line argument
and the add the command-line options, you need. :-)
I hope this helps?
Kind regards
- Flemming
Post by a***@gmail.com
Hello everyone
I'm trying to record battles from the java API. I would like to trigger
battles inside Java and then, at the end of the run, be able to see the
replay only of the battles i'm interested in.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
import robocode.control.*;
import net.sf.robocode.battle.events.BattleEventDispatcher;
import net.sf.robocode.io.Logger;
import net.sf.robocode.recording.BattleRecordFormat;
import net.sf.robocode.recording.RecordManager;
import net.sf.robocode.serialization.SerializableOptions;
import net.sf.robocode.settings.SettingsManager;
public class BattleRunner {
// Path configuration
public static String roboCodePath =
"/home/andrea/git/AttProgIA_2016/RoboCode";
private static String recordFile = "/tmp/testingLOL.xml";
// Recording
private static SettingsManager settingsManager = new
SettingsManager();
private static BattleEventDispatcher battleEventDispatcher = new
BattleEventDispatcher();
private static RecordManager recordManager = new
RecordManager(settingsManager);
public static void main(String[] args) {
// Disable log messages from Robocode
RobocodeEngine.setLogMessagesEnabled(false);
// Create the RobocodeEngine
RobocodeEngine engine = new RobocodeEngine(new
java.io.File(roboCodePath));
// Setup the battle specification
int numberOfRounds = 5;
BattlefieldSpecification battlefield = new
BattlefieldSpecification(800, 600); // 800x600
RobotSpecification[] selectedRobots =
engine.getLocalRepository("sample.RamFire,sample.Corners");
BattleSpecification battleSpec = new
BattleSpecification(numberOfRounds, battlefield, selectedRobots);
// *********************
Logger.setLogListener(battleEventDispatcher);
recordManager.attachRecorder(battleEventDispatcher);
// Show the Robocode battle view
engine.setVisible(false);
// *********************
// Run our specified battle and let it run till it is over
engine.runBattle(battleSpec, true); // waits till the battle
finishes
// Save the recording
recordManager.saveRecord(recordFile, BattleRecordFormat.XML, new
SerializableOptions(false));
// Cleanup our RobocodeEngine
engine.close();
// Make sure that the Java VM is shut down properly
System.exit(0);
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
No robocode.properties. Using defaults.
Exception in thread "Application Thread" java.lang.NullPointerException
at
net.sf.robocode.recording.RecordManager.saveRecord(RecordManager.java:344)
at BattleRunner.main(BattleRunner.java:57)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Which i really don't understand... battles run properly (i tried to
print the results and it works correctly), but as soon as i try to save the
record i receive this null pointer exception. It looks like the recordInfo
variable inside RecordManager it's not initialized properly...
Can you give me a hint? It's really annoying, and unfortunately i can't
find any documentation or examples online...
Thank you
Andrea
--
You received this message because you are subscribed to the Google Groups "robocode" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robocode+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...