1414import java .io .IOException ;
1515import java .util .HashMap ;
1616import java .util .HashSet ;
17+ import java .util .List ;
18+ import java .util .ArrayList ;
1719import java .util .Map ;
1820import java .util .Set ;
1921import 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
0 commit comments