Skip to content

Commit

Permalink
Merge branch 'master' into public-release
Browse files Browse the repository at this point in the history
  • Loading branch information
TheApplePieGod committed Jan 22, 2025
2 parents 0d84876 + f040dc9 commit 653c403
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 9 deletions.
21 changes: 21 additions & 0 deletions engine/src/main/battlecode/common/Clock.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ public static int getBytecodeNum() {
return RobotMonitor.getBytecodeNum();
}

/**
* Returns the total amount of execution time left this team has before they timeout
*
* @return the amount of execution time remaining, in nanoseconds
* @battlecode.doc.costlymethod
*/
public static long getTimeLeft() {
return RobotMonitor.getTimeLeft();
}

/**
* Returns the total amount of time that this team's robots have collectively spent executing
* since the beginning of the match.
*
* @return the total execution time, in nanoseconds
* @battlecode.doc.costlymethod
*/
public static long getTimeElapsed() {
return RobotMonitor.getTimeElapsed();
}

/**
* Prevent construction.
*/
Expand Down
10 changes: 8 additions & 2 deletions engine/src/main/battlecode/common/GameConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,14 @@ public class GameConstants {
/** The percent of the map which a team needs to paint to win. */
public static final int PAINT_PERCENT_TO_WIN = 70;

/** The maximum number of towers that a team can have. */
public static final int MAX_NUMBER_OF_TOWERS = 25;
/** The maximum number of towers that a team can have. */
public static final int MAX_NUMBER_OF_TOWERS = 25;

/**
* The maximum execution time that can be spent on a team in one match. If the total time spent executing a team's bots
* exceeds this limit, the team will immediately lose the game. Execution time is measured in ns.
*/
public static final long MAX_TEAM_EXECUTION_TIME = 1200000000000L;

// *********************************
// ****** GAME MECHANICS ***********
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import battlecode.instrumenter.stream.RoboPrintStream;
import battlecode.instrumenter.stream.SilencedPrintStream;
import battlecode.server.ErrorReporter;
import battlecode.world.control.PlayerControlProvider;
import battlecode.server.Config;

import java.io.OutputStream;
Expand Down Expand Up @@ -111,7 +112,8 @@ public SandboxedRobotPlayer(String teamName,
int seed,
TeamClassLoaderFactory.Loader loader,
OutputStream robotOut,
Profiler profiler)
Profiler profiler,
PlayerControlProvider provider)
throws InstrumentationException {
this.robotController = robotController;
this.seed = seed;
Expand All @@ -135,7 +137,7 @@ public SandboxedRobotPlayer(String teamName,
setBytecodeLimitMethod = monitor.getMethod("setBytecodeLimit", int.class);
getBytecodeNumMethod = monitor.getMethod("getBytecodeNum");
pauseMethod = monitor.getMethod("pause");
initMethod = monitor.getMethod("init", Pauser.class, Killer.class, int.class, Profiler.class);
initMethod = monitor.getMethod("init", Pauser.class, Killer.class, int.class, Profiler.class, PlayerControlProvider.class);

// Note: loading this here also keeps any initialization we do in System
// from inflicting its bytecode cost on the player.
Expand Down Expand Up @@ -175,7 +177,7 @@ public SandboxedRobotPlayer(String teamName,
mainThread = new Thread(() -> {
try {
// Init RobotMonitor
initMethod.invoke(null, pauser, killer, this.seed, profiler);
initMethod.invoke(null, pauser, killer, this.seed, profiler, provider);
// Pause immediately
pauseMethod.invoke(null);
// Run the robot!
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
battlecode/common/Clock/yield 0 true
battlecode/common/Clock/getBytecodesLeft 0 false
battlecode/common/Clock/getBytecodeNum 0 false
battlecode/common/Clock/getTimeLeft 0 false
battlecode/common/Clock/getTimeElapsed 0 false
battlecode/common/Direction/equals 1 false
battlecode/common/Direction/getDeltaX 1 false
battlecode/common/Direction/getDeltaY 1 false
Expand Down
24 changes: 23 additions & 1 deletion engine/src/main/battlecode/instrumenter/inject/RobotMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import battlecode.instrumenter.SandboxedRobotPlayer;
import battlecode.instrumenter.profiler.Profiler;
import battlecode.server.ErrorReporter;
import battlecode.world.control.PlayerControlProvider;

import java.io.PrintStream;
import java.lang.Math;
Expand Down Expand Up @@ -33,6 +34,7 @@ public final class RobotMonitor {
private static SandboxedRobotPlayer.Killer killer;

private static Profiler profiler;
private static PlayerControlProvider provider;

// Methods called from SandboxedRobotPlayer

Expand All @@ -46,12 +48,14 @@ public final class RobotMonitor {
* @param theKiller killer to use to kill the thread
* @param seed seed to use for new Random instances
* @param theProfiler profiler to log bytecode usage per method to (profiling is disabled if null)
* @param theProvider player control provider to query computation time remaining
*/
@SuppressWarnings("unused")
public static void init(SandboxedRobotPlayer.Pauser thePauser,
SandboxedRobotPlayer.Killer theKiller,
int seed,
Profiler theProfiler) {
Profiler theProfiler,
PlayerControlProvider theProvider) {
shouldDie = false;
bytecodesLeft = 0;
debugLevel = 0;
Expand All @@ -61,6 +65,7 @@ public static void init(SandboxedRobotPlayer.Pauser thePauser,
killer = theKiller;

profiler = theProfiler;
provider = theProvider;
}

/**
Expand Down Expand Up @@ -111,6 +116,23 @@ public static int getBytecodesLeft() {
return bytecodesLeft;
}

/**
* @return the bytecode number that the active robot is currently on.
* Note that this can be above bytecodeLimit in some cases.
*/
@SuppressWarnings("unused")
public static long getTimeElapsed() {
return provider.getTimeElapsed();
}

/**
* @return the bytecodes this robot has left to use.
*/
@SuppressWarnings("unused")
public static long getTimeLeft() {
return provider.getTimeLeft();
}

// Methods called from RobotPlayer

/**
Expand Down
4 changes: 4 additions & 0 deletions engine/src/main/battlecode/server/ErrorReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// TODO: pass messages along to the client
public class ErrorReporter {

public static void warn(String message) {
Server.warn(message + "\n\n");
}

// reports the error, and tells the contestant to contact the devs
public static void report(Throwable e) {
report(e, true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package battlecode.world.control;

import battlecode.common.GameConstants;
import battlecode.common.Team;
import battlecode.instrumenter.InstrumentationException;
import battlecode.instrumenter.TeamClassLoaderFactory;
Expand Down Expand Up @@ -70,6 +71,11 @@ public class PlayerControlProvider implements RobotControlProvider {
*/
private int matchId = -1;

/**
* The total time the player's bots have spent executing, measured in ns
*/
private long totalPlayerTime = 0;

/**
* Create a new PlayerControlProvider.
*
Expand All @@ -95,6 +101,14 @@ public PlayerControlProvider(Team team,
}
}

public long getTimeElapsed() {
return totalPlayerTime;
}

public long getTimeLeft() {
return Math.max(GameConstants.MAX_TEAM_EXECUTION_TIME - totalPlayerTime, 0L);
}

@Override
public void matchStarted(GameWorld gameWorld) {
this.gameWorld = gameWorld;
Expand All @@ -116,6 +130,7 @@ public void matchEnded() {

this.sandboxes.clear();
this.gameWorld = null;
this.totalPlayerTime = 0;
}

@Override
Expand All @@ -132,7 +147,8 @@ public void robotSpawned(InternalRobot robot) {
robot.getID(),
factory.createLoader(profiler != null),
robotOut,
profiler
profiler,
this
);
this.sandboxes.put(robot.getID(), player);
} catch (InstrumentationException e) {
Expand Down Expand Up @@ -173,7 +189,13 @@ public void runRobot(InternalRobot robot) {

if (player != null) {
player.setBytecodeLimit(robot.getBytecodeLimit());
long timeBefore = System.nanoTime();
player.step();
totalPlayerTime += (System.nanoTime() - timeBefore);
if(totalPlayerTime > GameConstants.MAX_TEAM_EXECUTION_TIME) {
ErrorReporter.warn("Team " + team + " has timed out!");
robot.getController().resign();
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions engine/src/test/battlecode/instrumenter/LoaderTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package battlecode.instrumenter;

import battlecode.instrumenter.profiler.Profiler;
import battlecode.world.control.PlayerControlProvider;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
Expand Down Expand Up @@ -69,8 +71,9 @@ public TeamClassLoaderFactory.Loader setupLoader(TeamClassLoaderFactory cache) t
SandboxedRobotPlayer.Pauser.class,
SandboxedRobotPlayer.Killer.class,
int.class,
Profiler.class)
.invoke(null, pauser, killer, 0, null);
Profiler.class,
PlayerControlProvider.class)
.invoke(null, pauser, killer, 0, null, null);
monitor1.getMethod("setBytecodeLimit", int.class)
.invoke(null, Integer.MAX_VALUE);

Expand Down
Binary file modified specs/specs.pdf
Binary file not shown.

0 comments on commit 653c403

Please sign in to comment.