Skip to content

Commit 85017b6

Browse files
authored
Merge pull request #128 from battlecode/release-1.3.0
Release 1.3.0
2 parents 377289e + c679c46 commit 85017b6

File tree

15 files changed

+198
-34
lines changed

15 files changed

+198
-34
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ task headless(type: JavaExec, dependsOn: [':engine:build', ':example-bots:build'
6969
'-Dbc.game.team-b.package=' + (project.findProperty('packageNameB') ?: project.property('teamB')),
7070
'-Dbc.game.maps=' + project.property('maps'),
7171
'-Dbc.server.validate-maps=' + project.property('validateMaps'),
72+
'-Dbc.server.alternate-order=' + project.property('alternateOrder'),
7273
'-Dbc.server.save-file=' + (project.findProperty('replay') ?: defaultReplay),
7374
]
7475
}

client/visualizer/src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export enum Mode {
154154
export function defaults(supplied?: any): Config {
155155
let year = "2023"
156156
let conf: Config = {
157-
gameVersion: "1.2.4", //TODO: Change this on each release!
157+
gameVersion: "1.3.0", //TODO: Change this on each release!
158158
year: year,
159159
map_extension: 'map'+year.substring(2),
160160
game_extension: 'bc'+year.substring(2),

client/visualizer/src/main/scaffold.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ export default class ScaffoldCommunicator {
166166
`-PteamB=${teamB}`,
167167
`-Pmaps=${maps.join(',')}`,
168168
`-PvalidateMaps=false`,
169+
`-PalternateOrder=false`,
169170
`-PenableProfiler=${enableProfiler}`,
170171
];
171172
const proc = child_process.spawn(

engine/src/main/battlecode/common/GameConstants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class GameConstants {
1010
/**
1111
* The current spec version the server compiles with.
1212
*/
13-
public static final String SPEC_VERSION = "1.2.4";
13+
public static final String SPEC_VERSION = "1.3.0";
1414

1515
// *********************************
1616
// ****** MAP CONSTANTS ************

engine/src/main/battlecode/common/RobotController.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,10 @@ public strictfp interface RobotController {
162162
*
163163
* @param loc the location to check
164164
* @return true if the location is on the map; false otherwise
165-
* @throws GameActionException if the location is not within vision range
166165
*
167166
* @battlecode.doc.costlymethod
168167
*/
169-
boolean onTheMap(MapLocation loc) throws GameActionException;
168+
boolean onTheMap(MapLocation loc);
170169

171170
/**
172171
* Checks whether the given location is within the robot's vision range, and if it is on the map.
@@ -459,6 +458,55 @@ public strictfp interface RobotController {
459458
*/
460459
Anchor senseAnchor(int islandIdx) throws GameActionException;
461460

461+
/**
462+
* Sense if location has cloud.
463+
*
464+
* @param loc to sense cloud at
465+
* @return if location has cloud
466+
* @throws GameActionException if location can not be sensed
467+
*
468+
* @battlecode.doc.costlymethod
469+
*/
470+
boolean senseCloud(MapLocation loc) throws GameActionException;
471+
472+
/**
473+
* Return all clouds.
474+
*
475+
* @return all locations within vision radius that contain clouds
476+
*
477+
* @battlecode.doc.costlymethod
478+
*/
479+
MapLocation[] senseNearbyCloudLocations();
480+
481+
/**
482+
* Return all locations with clouds within a specified radius of a center location.
483+
* If radiusSquared is larger than the robot's vision radius, uses the robot's
484+
* vision radius instead. If -1 is passed, all locations within vision radius
485+
* are returned.
486+
*
487+
* @param radiusSquared the squared radius of all locations to be returned
488+
* @return all locations that contain clouds within the radius
489+
* @throws GameActionException if the radius is negative (and not -1)
490+
*
491+
* @battlecode.doc.costlymethod
492+
*/
493+
MapLocation[] senseNearbyCloudLocations(int radiusSquared) throws GameActionException;
494+
495+
/**
496+
* Return all nearby locations with clouds within a specified radius of a center location.
497+
* If radiusSquared is larger than the robot's vision radius, uses the robot's
498+
* vision radius instead. If -1 is passed, all locations within vision radius
499+
* are returned.
500+
*
501+
* @param center the center of the search area
502+
* @param radiusSquared the squared radius of all locations to be returned
503+
* @return all locations that contain clouds within the radius
504+
* @throws GameActionException if the radius is negative (and not -1)
505+
*
506+
* @battlecode.doc.costlymethod
507+
*/
508+
MapLocation[] senseNearbyCloudLocations(MapLocation center, int radiusSquared) throws GameActionException;
509+
462510
/**
463511
* Sense well at location.
464512
*

engine/src/main/battlecode/instrumenter/bytecode/resources/MethodCosts.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ battlecode/common/RobotController/senseNearbyRobots 100 tru
8686
battlecode/common/RobotController/senseRobot 25 true
8787
battlecode/common/RobotController/senseRobotAtLocation 25 true
8888
battlecode/common/RobotController/sensePassability 5 true
89+
battlecode/common/RobotController/senseCloud 5 true
90+
battlecode/common/RobotController/senseNearbyCloudLocations 100 true
8991
battlecode/common/RobotController/senseWell 5 true
9092
battlecode/common/RobotController/senseNearbyWells 100 true
9193
battlecode/common/RobotController/senseMapInfo 10 true

engine/src/main/battlecode/server/Config.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public class Config {
5050
defaults.setProperty("bc.server.throttle-count", "15");
5151
defaults.setProperty("bc.server.output-xml", "true");
5252
defaults.setProperty("bc.server.validate-maps", "true");
53+
defaults.setProperty("bc.server.alternate-order", "false");
54+
5355

5456

5557
// Whether to write robot player output to match files / system out

engine/src/main/battlecode/server/ErrorReporter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ private static void printThingsToTry(String thingsToTry) {
5353
private static void printReportString() {
5454
Server.warn(String.format("java version \"%s\"\n", System.getProperty("java.version")));
5555
Server.warn(String.format("%s (build %s, %s)\n\n", System.getProperty("java.vm.name"), System.getProperty("java.vm.version"), System.getProperty("java.vm.info")));
56-
Server.warn("Please report this to the 6.370 devs, by posting to the forum\n"
56+
Server.warn("Please report this to the 6.9610 devs, by posting to the forum\n"
5757
+ "under the \"bugs\" thread. Include a copy of this printout and\n"
5858
+ "a brief description of the bug, including whether it's consistent\n"
5959
+ "or sporadic. Thanks!");

engine/src/main/battlecode/server/Server.java

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import java.io.IOException;
1515
import java.util.HashMap;
1616
import java.util.HashSet;
17+
import java.util.List;
18+
import java.util.ArrayList;
1719
import java.util.Map;
1820
import java.util.Set;
1921
import java.util.concurrent.BlockingQueue;
@@ -165,16 +167,18 @@ public void run() {
165167
final RobotControlProvider prov = createControlProvider(currentGame, gameMaker, profilingEnabled);
166168

167169
final boolean checkMapGuarantees = options.getBoolean("bc.server.validate-maps");
170+
final boolean alternateOrder = options.getBoolean("bc.server.alternate-order");
168171

169172
// Count wins
170173
int aWins = 0, bWins = 0;
171174

172175
// Loop through the maps in the current game
176+
boolean teamsReversed = false;
173177
for (int matchIndex = 0; matchIndex < currentGame.getMaps().length; matchIndex++) {
174-
175178
Team winner;
176179
try {
177-
winner = runMatch(currentGame, matchIndex, prov, gameMaker, checkMapGuarantees);
180+
winner = runMatch(currentGame, matchIndex, prov, gameMaker, checkMapGuarantees, teamsReversed);
181+
if (alternateOrder) {teamsReversed = !teamsReversed;}
178182
} catch (Exception e) {
179183
ErrorReporter.report(e);
180184
this.state = ServerState.ERROR;
@@ -222,6 +226,20 @@ public MapLocation indexToLocation(LiveMap liveMap, int idx) {
222226
return new MapLocation(idx % liveMap.getWidth(),
223227
idx / liveMap.getWidth());
224228
}
229+
230+
private void extendOut(LiveMap liveMap, MapLocation mapLocation, Set<MapLocation> seenLocations) {
231+
int[] islandArray = liveMap.getIslandArray();
232+
int currValue = islandArray[locationToIndex(liveMap, mapLocation)];
233+
seenLocations.add(mapLocation);
234+
for (Direction dir : Direction.cardinalDirections()) {
235+
MapLocation newLocation = mapLocation.add(dir);
236+
if (seenLocations.contains(newLocation)) {continue;}
237+
if (islandArray[locationToIndex(liveMap, newLocation)] == currValue) {
238+
extendOut(liveMap, newLocation, seenLocations);
239+
}
240+
}
241+
}
242+
225243
private void validateMapOnGuarantees(LiveMap liveMap) {
226244
// Check map dimensions
227245
if (liveMap.getWidth() > GameConstants.MAP_MAX_WIDTH) {
@@ -280,18 +298,25 @@ private void validateMapOnGuarantees(LiveMap liveMap) {
280298
if ((liveMap.getResourceArray()[i] != 0) && (robotArray[i] != null))
281299
throw new RuntimeException("Wells can't be on same square as headquarters");
282300

301+
//assert that wells are not on same square as currents
302+
if ((liveMap.getResourceArray()[i] != 0) && (liveMap.getCurrentArray()[i] != 0))
303+
throw new RuntimeException("Wells can't be on same square as currents");
304+
283305
//assert that currents are not on same square as headquarters
284306
if (liveMap.getCurrentArray()[i] != 0 && robotArray[i] != null)
285307
throw new RuntimeException("Currents can't be on same square as headquarters");
286308
}
287309

288-
//assert that island guarantees are met (atleast 4 islands, none of which are larger than 20 units)
289-
Map<Integer, Integer> islandToAreaMapping = new HashMap<>();
290-
for (int i : liveMap.getIslandArray()) {
291-
if (i == 0) {
310+
//assert that island guarantees are met (at least 4 islands, none of which are larger than 20 units, all connected)
311+
Map<Integer, List<MapLocation>> islandToAreaMapping = new HashMap<>();
312+
for (int i = 0; i < liveMap.getIslandArray().length; i++) {
313+
int islandId = liveMap.getIslandArray()[i];
314+
if (islandId == 0) {
292315
continue; // No island
293316
} else {
294-
islandToAreaMapping.put(i, islandToAreaMapping.getOrDefault(i, 0) + 1);
317+
List<MapLocation> islandAreas = islandToAreaMapping.getOrDefault(islandId, new ArrayList<MapLocation>());
318+
islandAreas.add(indexToLocation(liveMap, i));
319+
islandToAreaMapping.put(islandId, islandAreas);
295320
}
296321
}
297322
if (islandToAreaMapping.size() < GameConstants.MIN_NUMBER_ISLANDS) {
@@ -300,10 +325,18 @@ private void validateMapOnGuarantees(LiveMap liveMap) {
300325
if (islandToAreaMapping.size() > GameConstants.MAX_NUMBER_ISLANDS) {
301326
throw new RuntimeException("Islands num of " + islandToAreaMapping.size() + " ABOVE GameConstants.MAX_NUMBER_ISLANDS");
302327
}
303-
for (int i : islandToAreaMapping.values()) {
304-
if (i > GameConstants.MAX_ISLAND_AREA) {
328+
Set<MapLocation> seenIslands = new HashSet<>();
329+
int sumIslandSquares = 0;
330+
for (int islandId : islandToAreaMapping.keySet()) {
331+
List<MapLocation> islandLocs = islandToAreaMapping.get(islandId);
332+
if (islandLocs.size() > GameConstants.MAX_ISLAND_AREA) {
305333
throw new RuntimeException("Island exceeds max allowable area");
306334
}
335+
sumIslandSquares += islandLocs.size();
336+
extendOut(liveMap, islandLocs.get(0), seenIslands);
337+
}
338+
if (seenIslands.size() != sumIslandSquares) {
339+
throw new RuntimeException("Islands are not continous");
307340
}
308341

309342

@@ -402,6 +435,9 @@ private void validateMapOnGuarantees(LiveMap liveMap) {
402435
}
403436
}
404437
}
438+
private Team runMatch(GameInfo currentGame, int matchIndex, RobotControlProvider prov, GameMaker gameMaker, boolean checkMapGuarantees) throws Exception {
439+
return runMatch(currentGame, matchIndex, prov, gameMaker, checkMapGuarantees, false);
440+
}
405441

406442
/**
407443
* @return the winner of the match
@@ -410,7 +446,7 @@ private void validateMapOnGuarantees(LiveMap liveMap) {
410446
private Team runMatch(GameInfo currentGame,
411447
int matchIndex,
412448
RobotControlProvider prov,
413-
GameMaker gameMaker, boolean checkMapGuarantees) throws Exception {
449+
GameMaker gameMaker, boolean checkMapGuarantees, boolean teamsReversed) throws Exception {
414450

415451
final String mapName = currentGame.getMaps()[matchIndex];
416452
final LiveMap loadedMap;
@@ -423,7 +459,7 @@ private Team runMatch(GameInfo currentGame,
423459
}
424460

425461
// Create the game world!
426-
currentWorld = new GameWorld(loadedMap, prov, gameMaker.getMatchMaker());
462+
currentWorld = new GameWorld(loadedMap, prov, gameMaker.getMatchMaker(), teamsReversed);
427463

428464
if (checkMapGuarantees) {
429465
// Validate the map

engine/src/main/battlecode/world/GameWorld.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,12 @@ public strictfp class GameWorld {
5252
private Random rand;
5353
private final GameMaker.MatchMaker matchMaker;
5454

55+
public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker matchMaker) {
56+
this(gm, cp, matchMaker, false);
57+
}
5558

5659
@SuppressWarnings("unchecked")
57-
public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker matchMaker) {
60+
public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker matchMaker, boolean reverseTeams) {
5861
this.walls = gm.getWallArray();
5962
this.clouds = gm.getCloudArray();
6063
this.islandIds = gm.getIslandArray();
@@ -83,8 +86,26 @@ public GameWorld(LiveMap gm, RobotControlProvider cp, GameMaker.MatchMaker match
8386

8487
// Add the robots contained in the LiveMap to this world.
8588
RobotInfo[] initialBodies = this.gameMap.getInitialBodies();
89+
RobotInfo[] bodiesToUse = initialBodies;
90+
RobotInfo[] reversedBodies = new RobotInfo[initialBodies.length];
8691
for (int i = 0; i < initialBodies.length; i++) {
8792
RobotInfo robot = initialBodies[i];
93+
Inventory inv = new Inventory();
94+
for (ResourceType rType : ResourceType.values()) {
95+
if (rType == ResourceType.NO_RESOURCE) {
96+
continue;
97+
}
98+
inv.addResource(rType, robot.getResourceAmount(rType));
99+
}
100+
reversedBodies[i] = new RobotInfo(robot.ID, robot.team.opponent(), robot.type, inv, robot.health, robot.location);
101+
}
102+
103+
if (reverseTeams) {
104+
bodiesToUse = reversedBodies;
105+
}
106+
107+
for (int i = 0; i < bodiesToUse.length; i++) {
108+
RobotInfo robot = bodiesToUse[i];
88109
MapLocation newLocation = robot.location.translate(gm.getOrigin().x, gm.getOrigin().y);
89110
spawnRobot(robot.ID, robot.type, newLocation, robot.team);
90111
}
@@ -175,9 +196,6 @@ public synchronized GameState runRound() {
175196
}
176197
hq.addResourceAmount(ResourceType.ADAMANTIUM, GameConstants.INITIAL_AD_AMOUNT);
177198
hq.addResourceAmount(ResourceType.MANA, GameConstants.INITIAL_MN_AMOUNT);
178-
// Add initial amounts of resource
179-
this.teamInfo.addAdamantium(hq.getTeam(), GameConstants.INITIAL_AD_AMOUNT);
180-
this.teamInfo.addMana(hq.getTeam(), GameConstants.INITIAL_MN_AMOUNT);
181199
return true;
182200
} else {
183201
throw new RuntimeException("non-robot body registered as dynamic");
@@ -694,7 +712,7 @@ public void processEndOfRound() {
694712
//deal damage
695713
InternalRobot robot = getRobot(loc);
696714
if (robot != null && robot.getTeam().ordinal() == teamIndex) {
697-
robot.addHealth(-1*robot.getType().damage);
715+
robot.addHealth(-1*RobotType.DESTABILIZER.damage);
698716
}
699717
//update multiplier if no longer being destabilized
700718
if (curDestabilize.size() <= GameConstants.MAX_DESTABILIZE_STACKS) {
@@ -843,6 +861,9 @@ public void destroyRobot(int id, boolean checkArchonDeath) {
843861
controlProvider.robotKilled(robot);
844862
objectInfo.destroyRobot(id);
845863

864+
for (ResourceType rType : ResourceType.values()) {
865+
robot.addResourceAmount(rType, -1*robot.getResource(rType));
866+
}
846867
matchMaker.addDied(id);
847868
}
848869

0 commit comments

Comments
 (0)