Skip to content

Instantly share code, notes, and snippets.

@j-mao
Created January 10, 2021 01:29
Show Gist options
  • Save j-mao/2f09d958958dfbe5064aac0f645eb25f to your computer and use it in GitHub Desktop.
Save j-mao/2f09d958958dfbe5064aac0f645eb25f to your computer and use it in GitHub Desktop.
Battlecode 2021 Pathfinding lecture
/*
* Battlecode 2021
* Pathfinding Lecture - sample code
*
* Bug pathing and communication strategies. Run this on the map "Quadrants" for a sense of how
* this strategy behaves: watch the red robots in the bottom-left corner.
*
* https://www.battlecode.org/
* https://github.com/battlecode/battlecode21
*/
package examplefuncsplayer;
import battlecode.common.*;
public strictfp class RobotPlayer {
static RobotController rc;
/**
* 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;
System.out.println("I'm a " + rc.getType() + " and I just got created!");
while (true) {
// 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.
switch (rc.getType()) {
case ENLIGHTENMENT_CENTER: runEnlightenmentCenter(); break;
case POLITICIAN: runPolitician(); break;
default: return; // we're not creating these here
}
// 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();
}
}
}
/** Enlightenment centers spam politicians */
static void runEnlightenmentCenter() throws GameActionException {
RobotType toBuild = RobotType.POLITICIAN;
int influence = 50;
for (Direction dir : Direction.values()) {
if (rc.canBuildRobot(toBuild, dir, influence)) {
rc.buildRobot(toBuild, dir, influence);
} else {
break;
}
}
// a bit silly, but something for the sake of example:
sendLocation(rc.getLocation().translate(15, 7));
}
static int enlightenmentCenterId = -1;
static MapLocation politicianTarget = null;
static void runPolitician() throws GameActionException {
if (enlightenmentCenterId == -1) {
for (RobotInfo robot : rc.senseNearbyRobots(-1, rc.getTeam())) {
if (robot.type == RobotType.ENLIGHTENMENT_CENTER) {
enlightenmentCenterId = robot.ID;
}
}
}
if (rc.canGetFlag(enlightenmentCenterId)) {
politicianTarget = getLocationFromFlag(rc.getFlag(enlightenmentCenterId));
}
if (politicianTarget != null) {
basicBug(politicianTarget);
}
}
////////////////////////////////////////////////////////////////////////////
// COMMUNICATION
static final int NBITS = 7;
static final int BITMASK = (1 << NBITS) - 1;
static void sendLocation(MapLocation location) throws GameActionException {
int x = location.x, y = location.y;
int encodedLocation = ((x & BITMASK) << NBITS) + (y & BITMASK);
if (rc.canSetFlag(encodedLocation)) {
rc.setFlag(encodedLocation);
}
}
@SuppressWarnings("unused")
static void sendLocation(MapLocation location, int extraInformation) throws GameActionException {
int x = location.x, y = location.y;
int encodedLocation = (extraInformation << (2*NBITS)) + ((x & BITMASK) << NBITS) + (y & BITMASK);
if (rc.canSetFlag(encodedLocation)) {
rc.setFlag(encodedLocation);
}
}
static MapLocation getLocationFromFlag(int flag) {
int y = flag & BITMASK;
int x = (flag >> NBITS) & BITMASK;
// int extraInformation = flag >> (2*NBITS);
MapLocation currentLocation = rc.getLocation();
int offsetX128 = currentLocation.x >> NBITS;
int offsetY128 = currentLocation.y >> NBITS;
MapLocation actualLocation = new MapLocation((offsetX128 << NBITS) + x, (offsetY128 << NBITS) + y);
// You can probably code this in a neater way, but it works
MapLocation alternative = actualLocation.translate(-(1 << NBITS), 0);
if (rc.getLocation().distanceSquaredTo(alternative) < rc.getLocation().distanceSquaredTo(actualLocation)) {
actualLocation = alternative;
}
alternative = actualLocation.translate(1 << NBITS, 0);
if (rc.getLocation().distanceSquaredTo(alternative) < rc.getLocation().distanceSquaredTo(actualLocation)) {
actualLocation = alternative;
}
alternative = actualLocation.translate(0, -(1 << NBITS));
if (rc.getLocation().distanceSquaredTo(alternative) < rc.getLocation().distanceSquaredTo(actualLocation)) {
actualLocation = alternative;
}
alternative = actualLocation.translate(0, 1 << NBITS);
if (rc.getLocation().distanceSquaredTo(alternative) < rc.getLocation().distanceSquaredTo(actualLocation)) {
actualLocation = alternative;
}
return actualLocation;
}
////////////////////////////////////////////////////////////////////////////
// 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 final double passabilityThreshold = 0.7;
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, now that you're there
// here we'll just explode
if (rc.canEmpower(1)) {
rc.empower(1);
}
} else if (rc.isReady()) {
if (rc.canMove(d) && rc.sensePassability(rc.getLocation().add(d)) >= passabilityThreshold) {
rc.move(d);
bugDirection = null;
} else {
if (bugDirection == null) {
bugDirection = d;
}
for (int i = 0; i < 8; ++i) {
if (rc.canMove(bugDirection) && rc.sensePassability(rc.getLocation().add(bugDirection)) >= passabilityThreshold) {
rc.setIndicatorDot(rc.getLocation().add(bugDirection), 0, 255, 255);
rc.move(bugDirection);
bugDirection = bugDirection.rotateLeft();
break;
}
rc.setIndicatorDot(rc.getLocation().add(bugDirection), 255, 0, 0);
bugDirection = bugDirection.rotateRight();
}
}
}
}
}
// vim: set ts=4 sts=4 sw=4 :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment