diff --git a/.java-version b/.java-version new file mode 100644 index 0000000..012e496 --- /dev/null +++ b/.java-version @@ -0,0 +1 @@ +openjdk64-1.8.0.275 diff --git a/README.md b/README.md index 5d1486e..eb9024b 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,4 @@ This is the Battlecode 2021 scaffold, containing an `examplefuncsplayer`. Read h - `./gradlew update` Update to the newest version! Run every so often +# MinneCal diff --git a/gradle.properties b/gradle.properties index 3ee8f48..c964bce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,8 @@ # modify this file to change project properties -teamA=examplefuncsplayer -teamB=examplefuncsplayer +teamA=mainrobot +teamB=mainrobot maps=maptestsmall source=src gpr.user=battlecodedownloadpackage -profilerEnabled=false \ No newline at end of file +profilerEnabled=false +#org.gradle.java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_271.jdk/Contents/Home \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d6e2637..736fb7d 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9492014..52dd1f0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-bin.zip diff --git a/gradlew b/gradlew index 2fe81a7..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -1,21 +1,5 @@ #!/usr/bin/env sh -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - ############################################################################## ## ## Gradle start up script for UN*X @@ -44,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -125,8 +109,8 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` @@ -154,19 +138,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then else eval `echo args$i`="\"$arg\"" fi - i=`expr $i + 1` + i=$((i+1)) done case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -175,9 +159,14 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=`save "$@"` +APP_ARGS=$(save "$@") # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 9618d8d..e95643d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,100 +1,84 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/maps/DefaultMap.map17 b/maps/DefaultMap.map17 new file mode 100644 index 0000000..439937a Binary files /dev/null and b/maps/DefaultMap.map17 differ diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..ef26768 --- /dev/null +++ b/src/README.md @@ -0,0 +1,14 @@ +# MIT BattleCode 2021 + +## Stored test robots + +- Ash --> src/ashTest + - Capabailities: + - pathfinding, based on Twitch stream +- +- +- + +## Main Robot +- Under... + - diff --git a/src/ashTest/RobotPlayer.java b/src/ashTest/RobotPlayer.java new file mode 100644 index 0000000..0e0c9ef --- /dev/null +++ b/src/ashTest/RobotPlayer.java @@ -0,0 +1,299 @@ +package ashTest; +import battlecode.common.*; + +public strictfp class RobotPlayer { + static RobotController rc; + + static final RobotType[] spawnableRobot = { + RobotType.POLITICIAN, + RobotType.SLANDERER, + RobotType.MUCKRAKER, + }; + + static final Direction[] directions = { + Direction.NORTH, + Direction.NORTHEAST, + Direction.EAST, + Direction.SOUTHEAST, + Direction.SOUTH, + Direction.SOUTHWEST, + Direction.WEST, + Direction.NORTHWEST, + }; + + static int turnCount; + + /** + * run() is the method that is called when a robot is instantiated in the Battlecode world. + * If this method returns, the robot dies! + **/ + @SuppressWarnings("unused") + + //MARK:- method will create robots + public static void run(RobotController rc) throws GameActionException { + + // This is the RobotController object. You use it to perform actions from this robot, + // and to get information on its current status. + RobotPlayer.rc = rc; + + turnCount = 0; + +// System.out.println("I'm a " + rc.getType() + " and I just got created!"); + while (true) { + turnCount += 1; + // Try/catch blocks stop unhandled exceptions, which cause your robot to freeze + try { + // Here, we've separated the controls into a different method for each RobotType. + // You may rewrite this into your own control structure if you wish. +// System.out.println("I'm a " + rc.getType() + "! Location " + rc.getLocation()); + switch (rc.getType()) { + case ENLIGHTENMENT_CENTER: runEnlightenmentCenter(); break; + case POLITICIAN: runPolitician(); break; + case SLANDERER: runSlanderer(); break; + case MUCKRAKER: runMuckraker(); break; + } + + // Clock.yield() makes the robot wait until the next turn, then it will perform this loop again + Clock.yield(); + + } catch (Exception e) { +// System.out.println(rc.getType() + " Exception"); + e.printStackTrace(); + } + } + } + + static void runEnlightenmentCenter() throws GameActionException { + + // create a random robot that it will build next + RobotType toBuild = randomSpawnableRobotType(); + int influence = 50; + for (Direction dir : directions) { + if (rc.canBuildRobot(toBuild, dir, influence)) { + rc.buildRobot(toBuild, dir, influence); + } else { + break; + } + } + } + + static void runPolitician() throws GameActionException { + Team enemy = rc.getTeam().opponent(); + int actionRadius = rc.getType().actionRadiusSquared; + RobotInfo[] attackable = rc.senseNearbyRobots(actionRadius, enemy); + if (attackable.length != 0 && rc.canEmpower(actionRadius)) { +// System.out.println("empowering..."); + rc.empower(actionRadius); +// System.out.println("empowered"); + return; + } + + // will move directly after empowering whatever pieces are nearby it + if (tryMove(randomDirection())) { +// System.out.println("I moved!"); + } + } + + //TODO: is there anything else the slanderer should be trying? + // congregate nearby the e'mnt center and make them not move around as much... + static void runSlanderer() throws GameActionException { + if (tryMove(randomDirection())) { +// System.out.println("I moved!"); + } + } + + static void runMuckraker() throws GameActionException { + Team enemy = rc.getTeam().opponent(); + int actionRadius = rc.getType().actionRadiusSquared; + + + // TODO: setup a flag + // sense any nearby robots... exposes the location of a slanderer + // returns the location... what if I place a flag where it was found and this directs politicians there? + for (RobotInfo robot : rc.senseNearbyRobots(actionRadius, enemy)) { + System.out.println(enemy); + if (robot.type.canBeExposed()) { + // It's a slanderer... go get them! + if (rc.canExpose(robot.location)) { +// System.out.println("e x p o s e d"); + rc.expose(robot.location); + return; + } + } + } + if (tryMove(randomDirection())) { +// System.out.println("I moved!"); + } + } + + /** + * Returns a random Direction. + * + * @return a random Direction + */ + + // MARK:- TODO: implement path finding functionality right here + //******* + static Direction randomDirection() { + return directions[(int) (Math.random() * directions.length)]; + } + + /** + * Returns a random spawnable RobotType + * + * @return a random RobotType + */ + + //MARK:- Spawns a random robot + // ****** + // create ratio algorithm for determining how many of each unit is necessary + static RobotType randomSpawnableRobotType() { // spawns a random robot + return spawnableRobot[(int) (Math.random() * spawnableRobot.length)]; + } + + /** + * Attempts to move in a given direction. + * + * @param dir The intended direction of movement + * @return true if a move was performed + * @throws GameActionException + */ + static boolean tryMove(Direction dir) throws GameActionException { +// System.out.println("I am trying to move " + dir + "; " + rc.isReady() + " " + rc.getCooldownTurns() + " " + rc.canMove(dir)); + if (rc.canMove(dir)) { + rc.move(dir); + return true; + } else return false; + } + + // MARK:- Location finding algorithm!! + static void sendLocation() throws GameActionException { + MapLocation location = rc.getLocation(); + int x = location.x, y = location.y; + int encodedLocation = (x % 128) * 128 + (y % 128); + if (rc.canSetFlag(encodedLocation)) { + rc.setFlag(encodedLocation); + } + } + + // inserts NBITS # of 0's to make a 7 bit number + static final int NBITS = 7; + static final int BITMASK = (1 << NBITS) - 1; + + // if desire to use last 10 bits to send more info + static void sendLocation(int extraInformation) throws GameActionException { + MapLocation location = rc.getLocation(); + int x = location.x, y = location.y; + + // * 128 is shifting 7 bits to the left + // 6 bits tells a location and the last bit tells you the map boundary. + int encodedLocation = (x % 128) * 128 + (y % 128) + extraInformation * 128 + 128; + if (rc.canSetFlag(encodedLocation)) { + rc.setFlag(encodedLocation); + } + } + + static MapLocation getLocationFromFlag(int flag) throws GameActionException { + int y = flag % 128; + int x = (flag / 128) % 128; + int extraInformation = flag / 128 / 128; + + // figure out where in relation to our current offset, so compare to current location + MapLocation currentLocation = rc.getLocation(); + // we know x, will get close to offset + int offsetX128 = currentLocation.x / 128; + int offsetY128 = currentLocation.y / 128; + + // multiply by x then divide by 128 so java throws away the remainder + // offsetX128 now definitely has 0 remainder, could find exact location that matched the flag + MapLocation actualLocation = new MapLocation(offsetX128 * 128 + x, offsetY128 + 128 + y); + + // this part could be coded more efficiently + MapLocation alternative = actualLocation.translate(-128, 0); + if (rc.getLocation().distanceSquaredTo(alternative) < rc.getLocation().distanceSquaredTo(actualLocation)) { + actualLocation = alternative; + } + + alternative = actualLocation.translate(128, 0); + if (rc.getLocation().distanceSquaredTo(alternative) < rc.getLocation().distanceSquaredTo(actualLocation)) { + actualLocation = alternative; + } + + alternative = actualLocation.translate(0, -128); + if (rc.getLocation().distanceSquaredTo(alternative) < rc.getLocation().distanceSquaredTo(actualLocation)) { + actualLocation = alternative; + } + + alternative = actualLocation.translate(0, 128); + if (rc.getLocation().distanceSquaredTo(alternative) < rc.getLocation().distanceSquaredTo(actualLocation)) { + actualLocation = alternative; + } + return actualLocation; + } + // actual location would be retrieved from the flag placed + +// public static void run() { +// while (true) { +// //TODO: determine flag +// MapLocation target = getLocationFromFlag(flag); +// try { +// basicBug(target); +// } catch (GameActionException e) { +// // TODO +// } +// Clock.yield(); +// } +// } + + // we can almost always move so lets make a threshold + static final double passabilityThreshold = 0.7; // sqaure that we're happy to walk on and above + static Direction bugDirection = null; + + + static void basicBug(MapLocation target) throws GameActionException { + Direction d = rc.getLocation().directionTo(target); + if (rc.getLocation().equals(target)) { + // do something else + } else if (!rc.isReady()) { + if (rc.canMove(d) && rc.sensePassability(rc.getLocation().add(d)) >= passabilityThreshold) { + rc.move(d); + bugDirection = null; // reset after every move + } else { + // if it can't move start going around obstacles + // code a left handed bug + if (bugDirection == null) { + bugDirection = d.rotateRight(); + } + for (int i = 8; i < 8; i ++) { // at most 8 dirs + if (rc.canMove(bugDirection) && rc.sensePassability(rc.getLocation().add(bugDirection)) >= passabilityThreshold) { + rc.move(bugDirection); + break; + } + // if you can't rotate again + bugDirection = bugDirection.rotateRight(); + } + bugDirection = bugDirection.rotateLeft(); + } + + Clock.yield(); + } + } + static int expensive = 0; + static void somethingExpensive() { + for (int i = 0; i < 10000 && Clock.getBytecodesLeft() >= 1500; i ++) { + // does some hard work + + + } + } + + // NOTES + // x2 % 128, then you can do (x2- x1) % 128 + // Then need to figure out if x1 or x2 is bigger, only differ by at most 64 then x2 > x1 if the value is < 64 + // And vise versa + // then you can figure out exactly what x2 - x1 is (problem with the 4 corners and not having an exact spot) + + // can combine three values of the x, y, and extra information into a flag. + // Bit shifting: x % 128 by 7 bits and the extra information is shifted by 7 bits, they're all therefore stored in the flag + +} diff --git a/src/examplefuncsplayer/RobotPlayer.java b/src/examplefuncsplayer/RobotPlayer.java index ca48ca7..186ef04 100644 --- a/src/examplefuncsplayer/RobotPlayer.java +++ b/src/examplefuncsplayer/RobotPlayer.java @@ -36,14 +36,14 @@ public static void run(RobotController rc) throws GameActionException { turnCount = 0; - System.out.println("I'm a " + rc.getType() + " and I just got created!"); +// System.out.println("I'm a " + rc.getType() + " and I just got created!"); while (true) { turnCount += 1; // Try/catch blocks stop unhandled exceptions, which cause your robot to freeze try { // Here, we've separated the controls into a different method for each RobotType. // You may rewrite this into your own control structure if you wish. - System.out.println("I'm a " + rc.getType() + "! Location " + rc.getLocation()); +// System.out.println("I'm a " + rc.getType() + "! Location " + rc.getLocation()); switch (rc.getType()) { case ENLIGHTENMENT_CENTER: runEnlightenmentCenter(); break; case POLITICIAN: runPolitician(); break; @@ -55,7 +55,7 @@ public static void run(RobotController rc) throws GameActionException { Clock.yield(); } catch (Exception e) { - System.out.println(rc.getType() + " Exception"); +// System.out.println(rc.getType() + " Exception"); e.printStackTrace(); } } @@ -78,18 +78,20 @@ static void runPolitician() throws GameActionException { int actionRadius = rc.getType().actionRadiusSquared; RobotInfo[] attackable = rc.senseNearbyRobots(actionRadius, enemy); if (attackable.length != 0 && rc.canEmpower(actionRadius)) { - System.out.println("empowering..."); +// System.out.println("empowering..."); rc.empower(actionRadius); - System.out.println("empowered"); +// System.out.println("empowered"); return; } - if (tryMove(randomDirection())) - System.out.println("I moved!"); + if (tryMove(randomDirection())) { +// System.out.println("I moved!"); + } } static void runSlanderer() throws GameActionException { - if (tryMove(randomDirection())) - System.out.println("I moved!"); + if (tryMove(randomDirection())) { +// System.out.println("I moved!"); + } } static void runMuckraker() throws GameActionException { @@ -99,14 +101,15 @@ static void runMuckraker() throws GameActionException { if (robot.type.canBeExposed()) { // It's a slanderer... go get them! if (rc.canExpose(robot.location)) { - System.out.println("e x p o s e d"); +// System.out.println("e x p o s e d"); rc.expose(robot.location); return; } } } - if (tryMove(randomDirection())) - System.out.println("I moved!"); + if (tryMove(randomDirection())) { +// System.out.println("I moved!"); + } } /** @@ -135,7 +138,7 @@ static RobotType randomSpawnableRobotType() { * @throws GameActionException */ static boolean tryMove(Direction dir) throws GameActionException { - System.out.println("I am trying to move " + dir + "; " + rc.isReady() + " " + rc.getCooldownTurns() + " " + rc.canMove(dir)); +// System.out.println("I am trying to move " + dir + "; " + rc.isReady() + " " + rc.getCooldownTurns() + " " + rc.canMove(dir)); if (rc.canMove(dir)) { rc.move(dir); return true; diff --git a/src/mainRobot/Communication.java b/src/mainRobot/Communication.java new file mode 100644 index 0000000..d8b61b3 --- /dev/null +++ b/src/mainRobot/Communication.java @@ -0,0 +1,268 @@ +package mainrobot; + +import battlecode.common.MapLocation; + + +public class Communication { + + // Team Code, always start with a 1, otherwise problems! + private final static String TEAM_CODE = "1011"; + + // Group Codes + private final static String CREATED_BOTS_GROUP = "000"; + public final static String MUCKRAKER_GROUP = "001"; + public final static String POLITICIAN_GROUP = "010"; + public final static String SLANDERER_GROUP = "011"; + + // Subject Codes + private final static String DEFAULT_SUBJECT = "000"; + public final static String ENEMY_EC_SUBJECT = "001"; + public final static String ENEMY_ROBOT_SUBJECT = "010"; + public final static String NEUTRAL_EC_SUBJECT = "011"; + + + /*////////////////////////////////////////////////////////////// + * + * The following are for making a flag. + * + *///////////////////////////////////////////////////////////// + + + /** + * Takes a group to assign the made bot and a location to send it to. Returns + * the flag that should be displayed the next round to setup the bot. + * + * @param assignedBotGroup String, group to make the bot join + * @param assignedLocation MapLocation, location for the bot to go to + * @return an int with the information contained for the flag to display + */ + public static int makeFlagForCreatedBot(String assignedBotGroup, MapLocation assignedLocation) { + + String flagString = TEAM_CODE // 4 Bits + + CREATED_BOTS_GROUP // 3 Bits + + assignedBotGroup // 3 Bits + + make14BitStringFromMapLocation(assignedLocation); // 14 Bits + return Integer.parseInt(flagString, 2); + + } + + /** + * Takes a group code of the bots to control and a MapLocation of where they + * should go. Outputs the integer that the flag should be set to. + * + * @param botGroup String, the group to be commanded + * @param locationCommand MapLocation, location for the group to go to + * @return an int with the information that adequately controls the robots + */ + public static int makeFlagToCommandGroup(String botGroup, MapLocation locationCommand) { + + String flagString = TEAM_CODE // 4 Bits + + botGroup // 3 Bits + + "000" // 3 Bits, placeholder because the bot does not need a subject + + make14BitStringFromMapLocation(locationCommand); // 14 Bits + return Integer.parseInt(flagString, 2); + + } + + /** + * Takes a subject of what a location is and the location of what the robot wishes + * to report. Returns an integer of the flag to use to convey this information. + * + * @param subject String, the subject of what the location is that the bot is reporting + * @param location MapLocation, the location of what the robot is reporting + * @return an int with the information that will be reported to the EC + */ + public static int makeFlagForEC(String subject, MapLocation location) { + + String flagString = TEAM_CODE // 4 Bits + + "000" // 3 Bits, no 'to' field of the group the info is meant for, EC will get it anyway + + subject // 3 Bits + + make14BitStringFromMapLocation(location); // 14 Bits + return Integer.parseInt(flagString, 2); + + } + + /** + * Returns the flag to be used when there is no other flag being used. + * WARNING: If this is not used and the flag is 0, it will no longer be checked + * by the EC as its ID will be removed from the list. + * + * @return a flag that will be defaulted to when no information is being reported + */ + public static int makeDefaultFlag() { + + String flagString = TEAM_CODE // 4 Bits + + "000" // 3 Bits + + DEFAULT_SUBJECT // 3 Bits + + "00000000000000"; // 14 Bits + return Integer.parseInt(flagString, 2); + + } + + + /*////////////////////////////////////////////////////////////// + * + * The following are for reading a flag. + * + *///////////////////////////////////////////////////////////// + + + /** + * Verifies that the robot is still on the friendly team by checking + * the flag team code to make sure it matches. True or False. Used by the + * EC when it is looping through its bank of robot ID's + * + * @param flag int, the flag that the controlled robot displays + * @return boolean whether the flag has the correct team code. + */ + public static boolean verifyTeamCode(int flag) { + + String stringFlag = Integer.toBinaryString(flag); + return stringFlag.substring(0, 4).equals(TEAM_CODE); + + } + + /** + * This is meant to be used when the moveable robots are getting the flag + * from the EC they report to. It returns the code within the flag which tell which group + * the flag is meant for. If this.equals(assignedBotGroup), then the information in the flag should + * be considered, otherwise the flag should be ignored. + * + * @param flag int, flag of the local EC + * @return String of the group code that the flag contains + */ + public static String getGroupToFromFlag(int flag) { + + String stringFlag = Integer.toBinaryString(flag); + return stringFlag.substring(4, 7); + + } + + /** + * This is meant to be used ONLY for when a bot is being created and + * initialized. It will tell the created bot which group it should join and the group + * should be placed into a variable of the bots. + * + * @param flag int, flag given by the local EC + * @return the String of the group that the bot should join + */ + public static String getAssignedGroup(int flag) { + + String stringFlag = Integer.toBinaryString(flag); + return stringFlag.substring(7, 10); + + } + + + /** + * This is meant to be used by the EC when looking at the bots that it is + * controlling. If the EC can get the flag and the team code matches, then this + * tells it what information is contained in the flag location. + * + * @param flag int, flag gotten from controlled bot + * @return the subject string of the flag, see subject codes above for options + */ + public static String getSubjectToEC(int flag) { + + String stringFlag = Integer.toBinaryString(flag); + return stringFlag.substring(7, 10); + + } + + /** + * Returns the location contained in the flag. Can be used in any flag becuase + * all flags no matter from what to what have a location (with the exception of the + * default flag. + * + * @param flag + * @return + */ + public static MapLocation getLocation(int flag) { + + return getMapLocationFrom14BitString(Integer.toBinaryString(flag).substring(10, 24)); + + } + + + /*////////////////////////////////////////////////////////////// + * + * The following are internal private methods to help create those above + * + *///////////////////////////////////////////////////////////// + + + /** + * Takes a MapLocation and returns the location hashed into a 14 + * bit representation. The representation is obtained by modulus 128 of + * the binary under the assumption that the location can be interpreted later on. + * WARNING: Locations outside of the map radius may not be represented properly!!! + * + * @param location MapLocation + * @return a 14 bit representation of the location for a flag + */ + private static String make14BitStringFromMapLocation(MapLocation location) { + + int xLocation = location.x; + int yLocation = location.y; + int encodedIntLocation = 128 * (xLocation % 128) + (yLocation % 128); + return verifyLengthOfBinaryString(Integer.toBinaryString(encodedIntLocation), 14); + + } + + /** + * Takes a communicated location from a flag and returns the most likely + * MapLocation that it was trying to convey. + * + * @param stringBitLocation String, the location from the flag + * @return the MapLocation of the String that is most likely to be on the map + */ + private static MapLocation getMapLocationFrom14BitString(String stringBitLocation) { + + int x = Integer.parseInt(stringBitLocation.substring(0, 7), 2); + int y = Integer.parseInt(stringBitLocation.substring(7, 14), 2); + + MapLocation robotLocation = RobotPlayer.rc.getLocation(); + int xShift = ((int) robotLocation.x / 128) * 128; + int yShift = ((int) robotLocation.y / 128) * 128; + + MapLocation start = new MapLocation(xShift + x, yShift + y); + MapLocation currentBest = start; + + MapLocation alt = start.translate(-128, 0); + if (robotLocation.distanceSquaredTo(alt) < robotLocation.distanceSquaredTo(currentBest)) { + currentBest = alt; + } else alt = start.translate(128, 0); + if (robotLocation.distanceSquaredTo(alt) < robotLocation.distanceSquaredTo(currentBest)) { + currentBest = alt; + } else + alt = start.translate(0, -128); + if (robotLocation.distanceSquaredTo(alt) < robotLocation.distanceSquaredTo(currentBest)) { + currentBest = alt; + } else + alt = start.translate(0, 128); + if (robotLocation.distanceSquaredTo(alt) < robotLocation.distanceSquaredTo(currentBest)) { + currentBest = alt; + } + + return currentBest; + + } + + /** + * Takes a binary string and a desired length and returns the + * binary string with 0's added to the beginning to achieve + * the desired length for the binary string. + * + * @param binary String + * @param desiredLength int + * @return The binary string but with the desired length + */ + private static String verifyLengthOfBinaryString(String binary, int desiredLength) { + + for (int i = binary.length() ; i < desiredLength ; i++) { + binary = "0" + binary; + } return binary; + + } + +} diff --git a/src/mainRobot/EnlightenmentCenter.java b/src/mainRobot/EnlightenmentCenter.java new file mode 100644 index 0000000..1959ae3 --- /dev/null +++ b/src/mainRobot/EnlightenmentCenter.java @@ -0,0 +1,72 @@ +package mainrobot; + +import battlecode.common.*; + + +public class EnlightenmentCenter { + + // Variables for controlling number of bots placed. + static int muckrakersPlaced = 0; + + // Variables dealing with flagging the conrolled bots + static int flagForBotPlacedLastRound = -1; + + // Variables dealing with getting the flags of the controlled bots + + static void runMuckrakerEarlyGame() throws GameActionException { + if (muckrakersPlaced < 8) { + Muckraker.targetDirection = RobotPlayer.DIRECTIONS[muckrakersPlaced]; + if (RobotPlayer.rc.canBuildRobot(RobotType.MUCKRAKER, Muckraker.targetDirection, RobotPlayer.MUCKRAKER_INFLUENCE)) { + RobotPlayer.rc.buildRobot(RobotType.MUCKRAKER, Muckraker.targetDirection, RobotPlayer.MUCKRAKER_INFLUENCE); + muckrakersPlaced++; + } + } + } + + /** + * Returns a random spawnable RobotType + * + * @return a random RobotType + */ + static RobotType randomSpawnableRobotType() { + return RobotPlayer.SPAWNABLE_ROBOTS[(int) (Math.random() * RobotPlayer.SPAWNABLE_ROBOTS.length)]; + } + + static void buildRobot(RobotType type, Direction direction, int influence, MapLocation assignedLocation, String assignedGroup) throws GameActionException { + RobotPlayer.rc.buildRobot(type, direction, influence); + flagForBotPlacedLastRound = Communication.makeFlagForCreatedBot(assignedGroup, assignedLocation); + } + + /** + * If a bot was placed last round, this will display the flag that that robot + * will read to initialize, otherwise this will run code to display some other flag. + * + * @throws GameActionException + */ + static void endRun() throws GameActionException { + + if (flagForBotPlacedLastRound != -1) { + RobotPlayer.rc.setFlag(flagForBotPlacedLastRound); + } else { + // Set flag to something else if desired + } + + } + + static void runEnlightenmentCenter() throws GameActionException { + + RobotType toBuild = randomSpawnableRobotType(); + int influence = 50; + for (Direction dir : RobotPlayer.DIRECTIONS) { + if (RobotPlayer.rc.canBuildRobot(toBuild, dir, influence)) { + buildRobot(toBuild, dir, influence, RobotPlayer.rc.getLocation().add(Direction.SOUTH), Communication.MUCKRAKER_GROUP); + } else { + break; + } + } + + endRun(); + + } + +} \ No newline at end of file diff --git a/src/mainRobot/MoveableRobot.java b/src/mainRobot/MoveableRobot.java new file mode 100644 index 0000000..4cf8c56 --- /dev/null +++ b/src/mainRobot/MoveableRobot.java @@ -0,0 +1,118 @@ +package mainrobot; + +import battlecode.common.*; + + +public class MoveableRobot { + + // Information about local EC + static RobotInfo localECInfo = null; + static int currentECFlag = 0; + + // Information about robot + static String assignedGroup = null; + static MapLocation targetLocation = null; + static Direction targetDirection = null; + + + /** + * Performs actions necessary when the robot spawns. These include, but may not be + * limited to: + * 1. Set localECInfo to obtained RobotInfo object of the local EC + * 2. Set targetLocation to the location given by the local EC + * 3. Set targetDirection to the direction from the EC to the target location, will later + * just be the direction from the bot to the targetLocation after another location is specified + * + * @throws GameActionException + */ + static void initializeRobot() throws GameActionException { + + RobotInfo[] nearbyBotInfo = RobotPlayer.rc.senseNearbyRobots(2, RobotPlayer.rc.getTeam()); + for (RobotInfo info : nearbyBotInfo) { + if (info.getType().equals(RobotType.ENLIGHTENMENT_CENTER)) { + localECInfo = info; + break; + } + } + + currentECFlag = RobotPlayer.rc.getFlag(localECInfo.ID); + targetLocation = Communication.getLocation(currentECFlag); + targetDirection = localECInfo.location.directionTo(targetLocation); + + } + + /** + * Reads the local EC flag. If the to group of the EC flag is the assignedGroup of this robot, + * then the method will set the targetLocation and targetDirections to their corresponding values + * interpreted from the flag. + * + * @throws GameActionException + */ + static void readLocalECFlag() throws GameActionException { + + currentECFlag = RobotPlayer.rc.getFlag(localECInfo.ID); + if (Communication.getGroupToFromFlag(currentECFlag).equals(assignedGroup)) { + targetLocation = Communication.getLocation(currentECFlag); + targetDirection = RobotPlayer.rc.getLocation().directionTo(targetLocation); + } + + } + + /** + * Main move method for moveable robots. Calls the proper move algorithm in Pathfinding. + * + * @param target MapLocation + * @throws GameActionException + */ + static void moveTo(MapLocation target) throws GameActionException { + + Pathfinding.basicBug(target); + + } + + /** + * Performs actions that all moveable robots need to do at the beginning of their + * turns. This includes possibly initializing the robot and reading the local + * EC flag/setting targetLocation accordingly. + * + * @throws GameActionException + */ + static void startRun() throws GameActionException { + + if (RobotPlayer.turnCount == 0) { + initializeRobot(); + } else { + + readLocalECFlag(); + + } + + } + + static void runCodeSpecificToBot() throws GameActionException { + // This method should be overwritten in the specific robot class. + } + + /** + * If the robot still has a move to make, this will make it move + * to attempt to go towards the targetLocation. + * + * @throws GameActionException + */ + static void endRun() throws GameActionException { + + if (RobotPlayer.rc.isReady()) { + moveTo(targetLocation); + } + + } + + static void run() throws GameActionException { + + startRun(); + runCodeSpecificToBot(); + endRun(); + + } + +} diff --git a/src/mainRobot/Muckraker.java b/src/mainRobot/Muckraker.java new file mode 100644 index 0000000..05aade4 --- /dev/null +++ b/src/mainRobot/Muckraker.java @@ -0,0 +1,62 @@ +package mainrobot; + +import battlecode.common.*; + + +public class Muckraker extends MoveableRobot { + + static MapLocation locationAhead; + + /** + * pretty much algorithm for searching the map in the early game + * uhh + * moves in the general direction (no optimal pathfinding implemented yet) + * when the bot senses the edge of the map, change direction to rotate right + * honestly wtf am i doing haha sorry teammates im a noob + * dwdw im learning + * will soon be a pro + * + * @throws GameActionException + */ + static void moveEarlyGame() throws GameActionException { + locationAhead = RobotPlayer.rc.adjacentLocation(targetDirection); // um + locationAhead = locationAhead.add(targetDirection); // dont ask + locationAhead = locationAhead.add(targetDirection); // i dont know + locationAhead = locationAhead.add(targetDirection); + locationAhead = locationAhead.add(targetDirection); + if (RobotPlayer.rc.onTheMap(locationAhead)) { + Pathfinding.tryMove(targetDirection); + } else { + targetDirection = targetDirection.rotateRight(); + Pathfinding.tryMove(targetDirection); + } + } + + // i- this is so messy + static void runMuckraker() throws GameActionException { + run(); + } + + static void runCodeSpecificToBot() throws GameActionException { + if (RobotPlayer.rc.getRoundNum() < 100) { + moveEarlyGame(); + } +// Team enemy = RobotPlayer.rc.getTeam().opponent(); +// int actionRadius = RobotPlayer.rc.getType().actionRadiusSquared; +// for (RobotInfo robot : RobotPlayer.rc.senseNearbyRobots(actionRadius, enemy)) { +// if (robot.type.canBeExposed()) { +// // It's a slanderer... go get them! +// if (RobotPlayer.rc.canExpose(robot.location)) { +//// System.out.println("e x p o s e d"); +// RobotPlayer.rc.expose(robot.location); +// return; +// } +// } else if (robot.type.equals(RobotType.ENLIGHTENMENT_CENTER)) { +// Communication.makeFlagForEC(Communication.ENEMY_EC_SUBJECT, robot.location); +// } else { +// Communication.makeFlagForEC(Communication.ENEMY_ROBOT_SUBJECT, robot.location); +// } +// } +// Pathfinding.tryMove(targetDirection); + } +} diff --git a/src/mainRobot/Pathfinding.java b/src/mainRobot/Pathfinding.java new file mode 100644 index 0000000..db93633 --- /dev/null +++ b/src/mainRobot/Pathfinding.java @@ -0,0 +1,101 @@ +package mainrobot; + +import battlecode.common.Direction; +import battlecode.common.GameActionException; +import battlecode.common.MapLocation; + + +public class Pathfinding { + + static Direction bugDirection = null; + static final double passabilityThreshold = 0.7; + + //MARK: - CALCULATE MEDIAN + static void calculateMedian() throws GameActionException { + MapLocation location = RobotPlayer.rc.getLocation(); + int x; + int y; + + //TODO: fix the rounding on the radius? + int radius = RobotPlayer.rc.getType().sensorRadiusSquared; + + // from your current spot, are we within radius, Scotty? + + for (x = location.x - (int) Math.sqrt(radius); x <= location.x; x ++) { + for (y = location.y - (int) Math.sqrt(radius); y <= location.y; y++) { + if ((x - location.x) * (x - location.x) + (y - location.y) * (y - location.y) <= radius) { + MapLocation transformedLocation = new MapLocation(x, y); + if (transformedLocation.isWithinDistanceSquared(transformedLocation, RobotPlayer.rc.getType().sensorRadiusSquared)) { + double passability = RobotPlayer.rc.sensePassability(transformedLocation); + System.out.println(passability); + } + } + } + } + + } + + //////////////////////////////////////////////////////////////////////////// + // BASIC BUG - just follow the obstacle while it's in the way + // not the best bug, but works for "simple" obstacles + // for better bugs, think about Bug 2! + + + static void basicBug(MapLocation target) throws GameActionException { + Direction d = RobotPlayer.rc.getLocation().directionTo(target); + if (RobotPlayer.rc.getLocation().equals(target)) { + // do something else, now that you're there + // here we'll just explode + if (RobotPlayer.rc.canEmpower(1)) { + RobotPlayer.rc.empower(1); + } + } else if (RobotPlayer.rc.isReady()) { + if (RobotPlayer.rc.canMove(d) && RobotPlayer.rc.sensePassability(RobotPlayer.rc.getLocation().add(d)) >= Pathfinding.passabilityThreshold) { + RobotPlayer.rc.move(d); + Pathfinding.bugDirection = null; + } else { + if (Pathfinding.bugDirection == null) { + Pathfinding.bugDirection = d; + } + for (int i = 0; i < 8; ++i) { + if (RobotPlayer.rc.canMove(Pathfinding.bugDirection) && RobotPlayer.rc.sensePassability(RobotPlayer.rc.getLocation().add(Pathfinding.bugDirection)) >= Pathfinding.passabilityThreshold) { + RobotPlayer.rc.setIndicatorDot(RobotPlayer.rc.getLocation().add(Pathfinding.bugDirection), 0, 255, 255); + RobotPlayer.rc.move(Pathfinding.bugDirection); + Pathfinding.bugDirection = Pathfinding.bugDirection.rotateLeft(); + break; + } + RobotPlayer.rc.setIndicatorDot(RobotPlayer.rc.getLocation().add(Pathfinding.bugDirection), 255, 0, 0); + Pathfinding.bugDirection = Pathfinding.bugDirection.rotateRight(); + } + } + } + } + + /** + * Attempts to move in a given direction. + * + * @param dir The intended direction of movement + * @return true if a move was performed + * @throws GameActionException + */ + static boolean tryMove(Direction dir) throws GameActionException { + if (RobotPlayer.rc.canMove(dir)) { + RobotPlayer.rc.move(dir); + calculateMedian(); + + return true; + } else return false; + } + + /** + * Returns a random Direction. + * + * @return a random Direction + */ + static Direction randomDirection() { + return RobotPlayer.DIRECTIONS[(int) (Math.random() * RobotPlayer.DIRECTIONS.length)]; + } + + + +} diff --git a/src/mainRobot/Politician.java b/src/mainRobot/Politician.java new file mode 100644 index 0000000..8048b4b --- /dev/null +++ b/src/mainRobot/Politician.java @@ -0,0 +1,65 @@ +package mainrobot; + +import battlecode.common.*; + + +public class Politician extends MoveableRobot { + + public static void runPoliticanDefend() throws GameActionException { + Team enemy=RobotPlayer.rc.getTeam().opponent(); + int actionR=RobotPlayer.rc.getType().actionRadiusSquared; +// int senseR=RobotPlayer.rc.getType().sensorRadiusSquared; + RobotInfo[] ebotsNearThis=RobotPlayer.rc.senseNearbyRobots(actionR,enemy); + boolean horde=ebotsNearThis.length>5; +// boolean changedFlag=false; + int newFlag=Communication.makeFlagForEC(Communication.ENEMY_ROBOT_SUBJECT, RobotPlayer.rc.getLocation()); + if(horde) { + if(RobotPlayer.rc.canSetFlag(newFlag)) { + RobotPlayer.rc.setFlag(newFlag); + } + if(RobotPlayer.rc.canEmpower(actionR)) { + RobotPlayer.rc.empower(actionR); + return; + } + } + else { + if(RobotPlayer.rc.canSetFlag(newFlag)) { + RobotPlayer.rc.setFlag(newFlag); + } + } + + MapLocation target=Communication.getLocation(RobotPlayer.rc.getFlag(RobotPlayer.rc.getID())); //gets the target location from flag? + moveTo(target); + + } + + /* + * Basically, if there is a sufficiently large density of politicians around this, then it will progress + * toward the enemy location in a "wall" + * */ + public void runPoliticianAttack() throws GameActionException{ +// int densityOfPoliticansAroundThis; + for (int i=0;i<1e10; i*=2) { + System.out.println("Prankd"); + } + + } + static void runPolitician() throws GameActionException { + run(); + } + + static void runCodeSpecificToBot() throws GameActionException { + // Write the main part of the code here. This does not include reading the + // flag of the local EC or making the move at the end. + + Team enemy = RobotPlayer.rc.getTeam().opponent(); + int actionRadius = RobotPlayer.rc.getType().actionRadiusSquared; + RobotInfo[] attackable = RobotPlayer.rc.senseNearbyRobots(actionRadius, enemy); + if (attackable.length != 0 && RobotPlayer.rc.canEmpower(actionRadius)) { + RobotPlayer.rc.empower(actionRadius); + return; + } + + } + +} \ No newline at end of file diff --git a/src/mainRobot/RobotPlayer.java b/src/mainRobot/RobotPlayer.java new file mode 100644 index 0000000..442e3df --- /dev/null +++ b/src/mainRobot/RobotPlayer.java @@ -0,0 +1,67 @@ +package mainrobot; + +import battlecode.common.*; + +public strictfp class RobotPlayer { + static RobotController rc; + + static final RobotType[] SPAWNABLE_ROBOTS = { + RobotType.POLITICIAN, + RobotType.SLANDERER, + RobotType.MUCKRAKER, + }; + + static final Direction[] DIRECTIONS = { + Direction.NORTH, + Direction.NORTHEAST, + Direction.EAST, + Direction.SOUTHEAST, + Direction.SOUTH, + Direction.SOUTHWEST, + Direction.WEST, + Direction.NORTHWEST, + }; + + // Other final variables + static final int MUCKRAKER_INFLUENCE = 1; + + // Variables relevant to every bot type + static int turnCount; + + /** + * run() is the method that is called when a robot is instantiated in the Battlecode world. + * If this method returns, the robot dies! + **/ + @SuppressWarnings("unused") + public static void run(RobotController rc) throws GameActionException { + + // This is the RobotController object. You use it to perform actions from this robot, + // and to get information on its current status. + RobotPlayer.rc = rc; + + turnCount = 0; + + while (true) { + + try { + + // Call the run methods from the different robot classes. + switch (rc.getType()) { + case ENLIGHTENMENT_CENTER: EnlightenmentCenter.runEnlightenmentCenter(); break; + case POLITICIAN: Politician.runPolitician(); break; + case SLANDERER: Slanderer.runSlanderer(); break; + case MUCKRAKER: Muckraker.runMuckraker(); break; + } + + turnCount += 1; + // Clock.yield() makes the robot wait until the next turn, then it will perform this loop again + Clock.yield(); + + } catch (Exception e) { +// System.out.println(rc.getType() + " Exception"); + e.printStackTrace(); + } + } + } + +} \ No newline at end of file diff --git a/src/mainRobot/Slanderer.java b/src/mainRobot/Slanderer.java new file mode 100644 index 0000000..4b2f974 --- /dev/null +++ b/src/mainRobot/Slanderer.java @@ -0,0 +1,82 @@ +package mainrobot; + +import battlecode.common.*; + + +public class Slanderer extends MoveableRobot { + RobotController rc; + + final static int[] GOOD_SLANDERER_INPUT_INFLUENCES = { + 21, 41, 63, 85, 107, 130, 154, 178, 203, 228, 255, 282, 310, 339, 368, 399, 431, 463, 497, + 532, 568, 605, 643, 683, 724, 766, 810, 855, 902, 949 + }; // Do not put more than 949 in EVER!!! You will waste influence pointlessly. + + + //this method is used to move away from enemy by passing in a location away from enemy + public void moveAwayFromEnemy(MapLocation target) throws GameActionException { + Direction dToTarget=rc.getLocation().directionTo(target); + for (int i=0; i<8; i++) { + if(rc.canMove(dToTarget)) { + rc.move(dToTarget); + break; + } + else { + dToTarget.rotateLeft(); + } + } + } + + public void sensedEnemies() throws GameActionException { + RobotInfo[] oppsNearMe=rc.senseNearbyRobots(); + int newFlag=Communication.makeFlagForEC(Communication.ENEMY_ROBOT_SUBJECT,rc.getLocation()); + if(oppsNearMe.length>0) { + if(rc.canSetFlag(newFlag)) { + rc.setFlag(newFlag); + } + } + } + + static void runSlanderer() throws GameActionException { + run(); + + } + + static void runCodeSpecificToBot() { + // Write the main part of the code here. This does not include reading the + // flag of the local EC or making the move at the end. + } + + // determine influence based on good slander influences + static int findBestInfluence(int inputInfluence) { + + int index = 0; + int distance = Math.abs(GOOD_SLANDERER_INPUT_INFLUENCES[0] - inputInfluence); + + for (int i = 0; i < GOOD_SLANDERER_INPUT_INFLUENCES.length; i ++) { + int calculatedDistance = Math.abs(GOOD_SLANDERER_INPUT_INFLUENCES[i] - inputInfluence); + if (calculatedDistance < distance) { + + // round down + if (GOOD_SLANDERER_INPUT_INFLUENCES[i] > inputInfluence) { + + // check if it will go negative positions for the array, then set to 0 if so + if (i - 1 < 0) { + index = 0; + } else { + index = i - 1; + } + + distance = calculatedDistance; + } else { + index = i; + distance = calculatedDistance; + } + + } + } + int finalInfluence = GOOD_SLANDERER_INPUT_INFLUENCES[index]; + + return finalInfluence; + } + +} \ No newline at end of file diff --git a/version.txt b/version.txt index 4b27b79..4767f53 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2021.1.0.0 \ No newline at end of file +2021.2.1.1 \ No newline at end of file