Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ TEAMS=NOT
# Properties for the battle engine
#------------------------------------------------------------------------------

# CLEARDATA
# If set to YES, the data robots saved is deleted before each battle,
# so they only keep it between the rounds of one battle. Data in a
# robot's jar is not lost. Use YES or NOT.

CLEARDATA=NOT

# FIELDL Battlefield width measured in pixels.
# FIELDH Battlefield height measured in pixels.
#
Expand Down
7 changes: 7 additions & 0 deletions robocode.content/src/main/resources/roborumble/roborumble.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ TEAMS=NOT
# Properties for the battle engine
#------------------------------------------------------------------------------

# CLEARDATA
# If set to YES, the data robots saved is deleted before each battle,
# so they only keep it between the rounds of one battle. Data in a
# robot's jar is not lost. Use YES or NOT.

CLEARDATA=NOT

# FIELDL Battlefield width measured in pixels.
# FIELDH Battlefield height measured in pixels.
#
Expand Down
7 changes: 7 additions & 0 deletions robocode.content/src/main/resources/roborumble/teamrumble.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ TEAMS=YES
# Properties for the battle engine
#------------------------------------------------------------------------------

# CLEARDATA
# If set to YES, the data robots saved is deleted before each battle,
# so they only keep it between the rounds of one battle. Data in a
# robot's jar is not lost. Use YES or NOT.

CLEARDATA=NOT

# FIELDL Battlefield width measured in pixels.
# FIELDH Battlefield height measured in pixels.
#
Expand Down
7 changes: 7 additions & 0 deletions robocode.content/src/main/resources/roborumble/twinduel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ TEAMS=YES
# Properties for the battle engine
#------------------------------------------------------------------------------

# CLEARDATA
# If set to YES, the data robots saved is deleted before each battle,
# so they only keep it between the rounds of one battle. Data in a
# robot's jar is not lost. Use YES or NOT.

CLEARDATA=NOT

# FIELDL Battlefield width measured in pixels.
# FIELDH Battlefield height measured in pixels.
#
Expand Down
1 change: 1 addition & 0 deletions robocode.roborumble/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies {
runtimeOnly(project(":robocode.core"))
runtimeOnly(project(":robocode.battle"))
runtimeOnly(libs.codesize)
testImplementation(testLibs.junit)
}

description = "Roborumble Client"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
package net.sf.robocode.roborumble.battlesengine;


import net.sf.robocode.io.FileUtil;
import net.sf.robocode.io.Logger;
import robocode.control.*;
import robocode.control.events.BattleAdaptor;
import robocode.control.events.BattleCompletedEvent;
import robocode.control.events.BattleErrorEvent;

import java.io.*;
import java.nio.file.Files;
import java.util.*;


Expand All @@ -34,8 +36,11 @@ public class BattlesRunner {
private final int fieldlen;
private final int fieldhei;
private final String outfile;
// The settings saved with each battle's results, which an upload may only read much later
private final StringBuilder resultSettings = new StringBuilder();
private final String user;
private final String game;
private final boolean cleardata;
private static RobotResults[] lastResults;
private static IRobocodeEngine engine;

Expand All @@ -48,6 +53,10 @@ public BattlesRunner(String game, Properties parameters) {
outfile = parameters.getProperty("OUTPUT", "");
user = parameters.getProperty("USER", "");
this.game = game;
cleardata = parameters.getProperty("CLEARDATA", "NOT").equals("YES");
if (cleardata) {
resultSettings.append(",CLEARDATA=YES");
}

initialize();
}
Expand Down Expand Up @@ -101,6 +110,9 @@ public void runBattlesImpl(boolean melee) {
battle.getBattlefield(), robotsList);

lastResults = null;
if (cleardata) {
deleteContents(FileUtil.getRobotsDataDir());
}
engine.runBattle(specification, true);
if (lastResults != null && lastResults.length > 1) {
dumpResults(outtxt, lastResults, rumbleBattle, melee);
Expand All @@ -116,6 +128,25 @@ public void runBattlesImpl(boolean melee) {
outtxt.close();
}

/**
* Deletes everything in a directory. For the robot data directory this is safe between battles, as
* a robot gets back the data in its jar when a battle starts.
*/
static void deleteContents(File directory) {
final File[] files = directory.listFiles();

if (files != null) {
for (File file : files) {
if (file.isDirectory() && !Files.isSymbolicLink(file.toPath())) {
deleteContents(file);
}
if (!file.delete()) {
Logger.logWarning("Could not delete " + file);
}
}
}
}

private String getEnemies(boolean melee, String[] bots) {
String enemies;

Expand Down Expand Up @@ -171,7 +202,7 @@ private void dumpResults(PrintStream outtxt, RobotResults[] results, RumbleBattl

outtxt.println(
game + "," + numrounds + "," + fieldlen + "x" + fieldhei + "," + user + ","
+ System.currentTimeMillis() + "," + rumbleBattle.getRunonly());
+ System.currentTimeMillis() + "," + rumbleBattle.getRunonly() + resultSettings);
outtxt.println(name1 + "," + points1 + "," + bullets1 + "," + survival1);
outtxt.println(name2 + "," + points2 + "," + bullets2 + "," + survival2);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public void uploadResults() {
// if the match mode was general, then send the results to all competitions (assuming codesize is used).
// if its not, then send results only to smaller size competitions

final String commonData = "&version=1" + "&client=" + client + "&teams=" + teams + "&melee=" + melee
final String commonData = "&version=1" + (hasSetting(header, "CLEARDATA=YES") ? "&cleardata=YES" : "") + "&client=" + client + "&teams=" + teams + "&melee=" + melee
+ "&rounds=" + header[1] + "&field=" + header[2] + "&user=" + user + "&time=" + header[4] + "&fname="
+ first[0] + "&fscore=" + first[1] + "&fbulletd=" + first[2] + "&fsurvival=" + first[3] + "&sname="
+ second[0] + "&sscore=" + second[1] + "&sbulletd=" + second[2] + "&ssurvival=" + second[3];
Expand Down Expand Up @@ -233,6 +233,19 @@ private void saveError(PrintStream outtxt, String match, String bot1, String bot
System.out.println("Unable to upload results " + match + " " + bot1 + " " + bot2);
}

/**
* Returns whether a battle's saved header has a setting. Settings come after the match type, and a header
* saved by an earlier version of the client has none.
*/
static boolean hasSetting(String[] header, String setting) {
for (int i = 6; i < header.length; i++) {
if (header[i].equals(setting)) {
return true;
}
}
return false;
}

private boolean senddata(String game, String data, PrintStream outtxt, boolean saveonerror, Vector<String> results, int i, PrintStream battlesnum, PrintStream prioritybattles) {
boolean errorsfound = false;
OutputStream out = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2001-2026 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
* https://robocode.sourceforge.io/license/epl-v10.html
*/
package net.sf.robocode.roborumble.battlesengine;


import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.IOException;


/**
* @author Robert Maupin (original)
*/
public class BattlesRunnerTest {

@Rule
public TemporaryFolder folder = new TemporaryFolder();

@Test
public void deletesEverythingInTheDirectoryAndKeepsIt() throws IOException {
File data = folder.newFolder("data");
File robot = new File(data, "a/b/One.data");

Assert.assertTrue(robot.mkdirs());
Assert.assertTrue(new File(robot, "#1").createNewFile());
Assert.assertTrue(new File(data, "loose").createNewFile());

BattlesRunner.deleteContents(data);

Assert.assertTrue(data.isDirectory());
Assert.assertEquals(0, data.list().length);
}

@Test
public void aMissingDirectoryIsFine() {
BattlesRunner.deleteContents(new File(folder.getRoot(), "missing"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2001-2026 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
* https://robocode.sourceforge.io/license/epl-v10.html
*/
package net.sf.robocode.roborumble.netengine;


import org.junit.Assert;
import org.junit.Test;


/**
* @author Robert Maupin (original)
*/
public class ResultsUploadTest {

@Test
public void aHeaderCanHoldSeveralSettings() {
String[] header = "game,35,800x600,user,1000,GENERAL,ONE=YES,TWO=YES".split(",");

Assert.assertTrue(ResultsUpload.hasSetting(header, "ONE=YES"));
Assert.assertTrue(ResultsUpload.hasSetting(header, "TWO=YES"));
Assert.assertFalse(ResultsUpload.hasSetting(header, "THREE=YES"));
}

@Test
public void aHeaderFromAnEarlierClientHasNoSettings() {
Assert.assertFalse(ResultsUpload.hasSetting("game,35,800x600,user,1000,GENERAL".split(","), "ONE=YES"));
Assert.assertFalse(ResultsUpload.hasSetting("game,35,800x600,user,1000".split(","), "ONE=YES"));
}

@Test
public void onlyTheSettingsCount() {
Assert.assertFalse(ResultsUpload.hasSetting("game,35,800x600,ONE=YES,1000,ONE=YES".split(","), "ONE=YES"));
}
}
Loading