Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions java/src/s2/GenericFunc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package s2;

import battlecode.common.*;

@FunctionalInterface
public interface GenericFunc {
void p() throws GameActionException;
}
7 changes: 7 additions & 0 deletions java/src/s2/GenericRobotContoller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package s2;

import battlecode.common.*;

public interface GenericRobotContoller {
void run() throws GameActionException;
}
90 changes: 90 additions & 0 deletions java/src/s2/Mopper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package s2;

import battlecode.common.*;

public class Mopper implements GenericRobotContoller {

RobotController rc;
Pathing pathing_engine;

public Mopper(RobotController handler) throws GameActionException{
rc = handler;
pathing_engine = new Pathing(handler);
}

public void run() throws GameActionException{
System.out.println("Starting mopper logic...");

// Define all possible directions
Direction[] directions = Direction.values();

// Initialize variables to track the best direction
Direction bestDirection = null;
int maxEnemiesInDirection = 0;

// Get the mopper's current location
MapLocation curLoc = rc.getLocation();

// Scan for all enemies within the circle of radius 2 * sqrt(2)
RobotInfo[] nearbyEnemies = rc.senseNearbyRobots(curLoc, 8, rc.getTeam().opponent());

// Count enemies in each direction based on their relative position
for (Direction dir : directions) {
int enemyCount = 0;

for (RobotInfo enemy : nearbyEnemies) {
MapLocation enemyLoc = enemy.getLocation();

// Check if the enemy lies in the swing range for the current direction
if (isInSwingRange(curLoc, enemyLoc, dir)) {
enemyCount++;
}
}

System.out.println("Direction: " + dir + ", Enemies: " + enemyCount);

// Update the best direction if this one has more enemies
if (enemyCount > maxEnemiesInDirection) {
maxEnemiesInDirection = enemyCount;
bestDirection = dir;
}
}

// Perform the mop swing in the best direction if enemies are found
if (bestDirection != null && maxEnemiesInDirection > 0) {

rc.mopSwing(bestDirection);
} else {

}

// If no enemies to mop swing, move randomly
pathing_engine.Move();

// Try to paint beneath us as we walk to avoid paint penalties
MapInfo currentTile = rc.senseMapInfo(rc.getLocation());
if (!currentTile.getPaint().isAlly() && rc.canAttack(rc.getLocation())) {
rc.attack(rc.getLocation());
}
}

private boolean isInSwingRange(MapLocation mopperLoc, MapLocation targetLoc, Direction swingDir) {
// Get the relative position of the target
int dx = targetLoc.x - mopperLoc.x;
int dy = targetLoc.y - mopperLoc.y;

// Check based on direction and relative positions
switch (swingDir) {
case NORTH:
return dx >= -1 && dx <= 1 && dy < 0 && dy >= -2;
case SOUTH:
return dx >= -1 && dx <= 1 && dy > 0 && dy <= 2;
case EAST:
return dy >= -1 && dy <= 1 && dx > 0 && dx <= 2;
case WEST:
return dy >= -1 && dy <= 1 && dx < 0 && dx >= -2;
default:
return false;
}
}
}
130 changes: 130 additions & 0 deletions java/src/s2/Pathing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package s2;

import battlecode.common.*;
import java.util.Random;

public class Pathing {
static final Direction[] directions = {
Direction.NORTH,
Direction.NORTHEAST,
Direction.EAST,
Direction.SOUTHEAST,
Direction.SOUTH,
Direction.SOUTHWEST,
Direction.WEST,
Direction.NORTHWEST,
};

GenericFunc diffuse = Pathing::diffuse1;

static final Random rng = new Random(6147);

static int robot_dir_idx = -1; //also technically velocity

static RobotController rc;

static private int modulo(int x, int y) {
int temp = Math.floorDiv(x,y);
return x-temp*y;
}

public Pathing(RobotController handler) throws GameActionException{
rc = handler;
}

public void Move() throws GameActionException{
diffuse = Pathing::diffuse1;
int bias = rng.nextInt(5);
if (bias == 3) {
diffuse = Pathing::diffuse2;
}
check_dir();
diffuse.p();
}

private void check_dir() {
if (robot_dir_idx == -1) {
robot_dir_idx = rng.nextInt(8);
}
}

private static void diffuse2() throws GameActionException{
MapLocation current_location = rc.getLocation();
boolean CurrIsAlly = rc.senseMapInfo(current_location).getPaint().isAlly();
for (int i = 0; i < 6; i++) {
Direction goal_dir = directions[robot_dir_idx];
if (rc.canMove(goal_dir) ){
boolean NextIsAlly = rc.senseMapInfo(current_location.add(goal_dir)).getPaint().isAlly();
if (!(!CurrIsAlly && NextIsAlly)) {
rc.move(goal_dir);
return;
}
}
int adj1 = modulo(robot_dir_idx + 1, 8);
int adj2 = modulo(robot_dir_idx - 1, 8);
boolean adj1_canMove = rc.canMove(directions[adj1]);
boolean adj2_canMove = rc.canMove(directions[adj2]);
if (robot_dir_idx % 2 == 0 || (!adj1_canMove && !adj2_canMove)) {
robot_dir_idx = modulo(robot_dir_idx + 3 + rng.nextInt(3), 8);
} else {
if (adj1_canMove) {
robot_dir_idx = adj1;
} else { // no need for 2nd check because if both fail then it would have gone into the
// previous if statement
robot_dir_idx = adj2;
}
}
}
// if stuck in hole
for (int i = 0; i < 10; i++) {
robot_dir_idx = rng.nextInt(8);
Direction goal_dir = directions[robot_dir_idx];
if (rc.canMove(goal_dir)) {
rc.move(goal_dir);
}
}
}

private static void diffuse1() throws GameActionException{
MapInfo[] surrounding = rc.senseNearbyMapInfos(2);
int surround_count = 0;
for (MapInfo mapInfo : surrounding) {
if (mapInfo.getPaint().isAlly()) {
surround_count++;
}
}
for (int i = 0; i < 8; i++) {
Direction goal_dir = directions[robot_dir_idx];
if (rc.canMove(goal_dir)) {
rc.move(goal_dir);
break;
}
int adj1 = modulo(robot_dir_idx + 1, 8);
int adj2 = modulo(robot_dir_idx - 1, 8);
boolean adj1_canMove = rc.canMove(directions[adj1]);
boolean adj2_canMove = rc.canMove(directions[adj2]);
if (robot_dir_idx % 2 == 0 || (!adj1_canMove && !adj2_canMove)) {
robot_dir_idx = modulo(robot_dir_idx + 3 + rng.nextInt(3), 8);
} else {
if (adj1_canMove) {
robot_dir_idx = adj1;
} else { // no need for 2nd check because if both fail then it would have gone into the
// previous if statement
robot_dir_idx = adj2;
}
}
boolean next_is_ally = rc.canMove(directions[robot_dir_idx]) && rc.senseMapInfo(rc.getLocation().add(directions[robot_dir_idx])).getPaint().isAlly();
boolean is_surrounded = surround_count > 3;
if (next_is_ally && !is_surrounded) {
int shift = rng.nextInt(7)+1;
int next = modulo( robot_dir_idx + shift ,8);
if (next == robot_dir_idx) {
next++;
}
robot_dir_idx = next;
}
}
}


}
41 changes: 41 additions & 0 deletions java/src/s2/RobotPlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package s2;

import battlecode.common.*;
public class RobotPlayer {
public static void run(RobotController rc) throws GameActionException {
GenericRobotContoller processor;
switch (rc.getType()) {
case SOLDIER:
processor = new Solider(rc);
break;
case MOPPER:
processor = new Mopper(rc);
break;
case SPLASHER:
processor = new Splasher(rc) ;
break; // Consider upgrading examplefuncsplayer to use splashers!
default:
processor = new Tower(rc);
break;
}

while (true) {
try {
processor.run();
} catch (GameActionException e) {
System.out.println("GameActionException");
e.printStackTrace();
} catch (Exception e) {
System.out.println("Exception");
e.printStackTrace();


} finally {
// Signify we've done everything we want to do, thereby ending our turn.
// This will make our code wait until the next turn, and then perform this loop
// again.
Clock.yield();
}
}
}
}
Loading
Loading