Skip to content
Open
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 @@ -86,6 +86,12 @@ NUMBATTLES=3
ROUNDS=35
MELEEBOTS=10

# HIDENAMES
# If set to YES, robots only see their enemies by anonymous names like
# #1 instead of by their real names. Use YES or NOT.

HIDENAMES=NOT

# INPUT Input battles file that is generated by the rumble automatically.
# The rumble uses this file for selecting which robots that must
# battle against each other.
Expand Down
6 changes: 6 additions & 0 deletions robocode.content/src/main/resources/roborumble/roborumble.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ FIELDH=600
NUMBATTLES=50
ROUNDS=35

# HIDENAMES
# If set to YES, robots only see their enemies by anonymous names like
# #1 instead of by their real names. Use YES or NOT.

HIDENAMES=NOT

# INPUT Input battles file that is generated by the rumble automatically.
# The rumble uses this file for selecting which robots that must
# battle against each other.
Expand Down
6 changes: 6 additions & 0 deletions robocode.content/src/main/resources/roborumble/teamrumble.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ FIELDH=1200
NUMBATTLES=10
ROUNDS=10

# HIDENAMES
# If set to YES, robots only see their enemies by anonymous names like
# #1 instead of by their real names. Use YES or NOT.

HIDENAMES=NOT

# INPUT Input battles file that is generated by the rumble automatically.
# The rumble uses this file for selecting which robots that must
# battle against each other.
Expand Down
6 changes: 6 additions & 0 deletions robocode.content/src/main/resources/roborumble/twinduel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ FIELDH=800
NUMBATTLES=10
ROUNDS=75

# HIDENAMES
# If set to YES, robots only see their enemies by anonymous names like
# #1 instead of by their real names. Use YES or NOT.

HIDENAMES=NOT

# INPUT Input battles file that is generated by the rumble automatically.
# The rumble uses this file for selecting which robots that must
# battle against each other.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,16 @@ public final class RobotStatics implements IRobotStatics, Serializable {
private final int robotIndex;
private final int teamIndex;

// One object, like the real name, because many robots compare enemy names with == or !=
private final String annonymousName;

public RobotStatics(RobotSpecification robotSpecification, String name, String suffix, boolean isLeader, BattleRules rules, String teamName,
List<String> teamMembers, int robotIndex, int teamIndex) {
IRobotItem robotItem = (IRobotItem) HiddenAccess.getFileSpecification(robotSpecification);

this.robotIndex = robotIndex;
this.teamIndex = teamIndex;
this.annonymousName = "#" + robotIndex;

this.shortClassName = robotItem.getShortClassName();
this.fullClassName = robotItem.getFullClassName();
Expand Down Expand Up @@ -120,14 +124,15 @@ private RobotStatics(String robocodeVersion, boolean isJuniorRobot, boolean isIn
this.teamName = teamName;
this.robotIndex = robotIndex;
this.teamIndex = teamIndex;
this.annonymousName = "#" + robotIndex;
}

public String getRobocodeVersion() {
return robocodeVersion;
}

public String getAnnonymousName() {
return "#" + robotIndex;
return annonymousName;
}

public boolean isJuniorRobot() {
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 @@ -33,7 +33,10 @@ public class BattlesRunner {
private final int numrounds;
private final int fieldlen;
private final int fieldhei;
private final boolean hidenames;
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 static RobotResults[] lastResults;
Expand All @@ -45,6 +48,10 @@ public BattlesRunner(String game, Properties parameters) {
numrounds = Integer.parseInt(parameters.getProperty("ROUNDS", "10"));
fieldlen = Integer.parseInt(parameters.getProperty("FIELDL", "800"));
fieldhei = Integer.parseInt(parameters.getProperty("FIELDH", "600"));
hidenames = parameters.getProperty("HIDENAMES", "NOT").equals("YES");
if (hidenames) {
resultSettings.append(",HIDENAMES=YES");
}
outfile = parameters.getProperty("OUTPUT", "");
user = parameters.getProperty("USER", "");
this.game = game;
Expand Down Expand Up @@ -97,8 +104,9 @@ public void runBattlesImpl(boolean melee) {
final String teamLast = robotsList[robotsList.length - 1].getTeamId();

if (team0 == null || !team0.equals(teamLast)) {
final BattleSpecification specification = new BattleSpecification(battle.getNumRounds(),
battle.getBattlefield(), robotsList);
final BattleSpecification specification = new BattleSpecification(battle.getBattlefield(),
battle.getNumRounds(), battle.getInactivityTime(), battle.getGunCoolingRate(),
battle.getSentryBorderSize(), hidenames, robotsList);

lastResults = null;
engine.runBattle(specification, true);
Expand Down Expand Up @@ -171,7 +179,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 @@ -171,7 +171,8 @@ public void uploadResults() {
final String commonData = "&version=1" + "&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];
+ second[0] + "&sscore=" + second[1] + "&sbulletd=" + second[2] + "&ssurvival=" + second[3]
+ (hasSetting(header, "HIDENAMES=YES") ? "&hidenames=YES" : "");

String data = "game=" + game + commonData;

Expand Down Expand Up @@ -233,6 +234,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,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"));
}
}
40 changes: 40 additions & 0 deletions robocode.tests.robots/src/main/java/tested/robots/HiddenNames.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 tested.robots;


import robocode.AdvancedRobot;
import robocode.ScannedRobotEvent;


/**
* Reports the enemy names it sees, and whether each name is the same object as the last one.
*
* @author Robert Maupin (original)
*/
public class HiddenNames extends AdvancedRobot {
private String lastName;

@Override
public void run() {
while (true) {
turnRadarRight(360);
}
}

@Override
public void onScannedRobot(ScannedRobotEvent e) {
String name = e.getName();

out.println("Enemy name: " + name);
if (lastName != null && name != lastName) {
out.println("The name is a new object");
}
lastName = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.test.robots;


import net.sf.robocode.test.helpers.Assert;
import net.sf.robocode.test.helpers.RobocodeTestBed;
import org.junit.Test;
import robocode.control.BattleSpecification;
import robocode.control.RobotSpecification;
import robocode.control.events.TurnEndedEvent;


/**
* Many robots compare enemy names with == or !=, which works for real names because a robot's name is one
* object. Hidden names must behave the same, or those robots lose track of their enemies.
*
* @author Robert Maupin (original)
*/
public class TestHiddenNames extends RobocodeTestBed {
private boolean sawHiddenName;

@Test
public void run() {
super.run();
Assert.assertTrue("The robot never saw a hidden name", sawHiddenName);
}

@Override
public String getRobotName() {
return "tested.robots.HiddenNames";
}

@Override
public String getEnemyName() {
return "sample.Target";
}

@Override
protected void runBattle(String robotList, int numRounds, String initialPositions) {
RobotSpecification[] robots = engine.getLocalRepository(robotList);
BattleSpecification battle = new BattleSpecification(battleFieldSpec, numRounds, 450, 0.1, 100, true, robots);

engine.runBattle(battle, initialPositions, true, false);
}

@Override
public void onTurnEnded(TurnEndedEvent event) {
super.onTurnEnded(event);
String out = event.getTurnSnapshot().getRobots()[0].getOutputStreamSnapshot();

if (out.contains("Enemy name: #")) {
sawHiddenName = true;
}
if (out.contains("sample.Target")) {
Assert.fail("The robot saw the enemy's real name");
}
if (out.contains("The name is a new object")) {
Assert.fail("The hidden name was not the same object each time");
}
}
}