Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Soldier healing #4

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
470 changes: 470 additions & 0 deletions src/rebutia_heal/Archon.java

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions src/rebutia_heal/BOT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package rebutia_heal;

public enum BOT {
NONE(0),
MINER(1),
SOLDIER(2),
BUILDER(3),
SAGE(4),
WATCHTOWER(5),
LABORATORY(6),
;

private final int id;
BOT(int id) { this.id = id; }
public int getValue() { return id; }
}
25 changes: 25 additions & 0 deletions src/rebutia_heal/BiCHANNEL.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package rebutia_heal;

/**
* For BiCHANNEL communications using one-round lagging updates.
* Use for data that needs to be recomputed each round (ex. # of soldiers alive
* this round).
* BiCHANNEL alternate between two channels. Use Comms.getCounterChannel() to
* get the update or read (lagging) channel.
*/
public enum BiCHANNEL {
MINERS_ALIVE(CHANNEL.MINERS_ALIVE, CHANNEL.MINERS_ALIVE_ALT),
SOLDIERS_ALIVE(CHANNEL.SOLDIERS_ALIVE, CHANNEL.SOLDIERS_ALIVE_ALT),
BUILDERS_ALIVE(CHANNEL.BUILDERS_ALIVE, CHANNEL.BUILDERS_ALIVE_ALT),
TOWERS_ALIVE(CHANNEL.TOWERS_ALIVE, CHANNEL.TOWERS_ALIVE_ALT),
USEFUL_MINERS(CHANNEL.USEFUL_MINERS, CHANNEL.USEFUL_MINERS_ALT),
;

final CHANNEL ch1;
final CHANNEL ch2;

BiCHANNEL(CHANNEL ch1, CHANNEL ch2) {
this.ch1 = ch1;
this.ch2 = ch2;
}
}
206 changes: 206 additions & 0 deletions src/rebutia_heal/Builder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package rebutia_heal;

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

public class Builder extends Unit {
public enum MODE {
HEALING,
BUILDING,
REPAIRING
}

int travel_counter = 0;
int[] exploratoryDir = getExploratoryDir();
int counter = 0;
Direction[] dirs;
RANK rank;
MODE mode;

private int num_watchtowers = 0;
private int num_labs = 0;
private int[] troopCounter = { 0, 0, 0, 0, 0 }; // miner, soldier, builder, sage, watchtower
MapLocation target = null;

private int built_units = 0;
private int[] build_order;

public Builder(RobotController rc) throws GameActionException {
super(rc);
rank = getBuilderRank();
dirs = sortedDirections();
}

@Override
public void run() throws GameActionException {
super.run();
radio.updateCounter();
troopCounter = new int[] { radio.readCounter(RobotType.MINER), radio.readCounter(RobotType.SOLDIER),
radio.readCounter(RobotType.BUILDER), 0, radio.readCounter(RobotType.WATCHTOWER) };
build_order = getBuildOrder();
switch (rank) {
case MARTYR:
forTheGreaterGood();
break;
case DEFAULT:
mode = getMode();
switch (mode) {
case HEALING:
heal();
break;
case BUILDING:
build(build_order);
break;
case REPAIRING:
if (rc.canRepair(target))
rc.repair(target);
else
moveToLocation(target);
target = null;
break;
}
break;
default:
break;
}
}

private int[] getBuildOrder() {
return new int[] { 0, 1 }; // laboratories, watchtowers
}

public MODE getMode() throws GameActionException {
if (findUnrepaired()) {
return MODE.REPAIRING;
} else if (troopCounter[4] <= (CONSTANTS.SOLDIERS_TO_TOWERS * (double) troopCounter[2])) {
return MODE.BUILDING;
} else
return MODE.HEALING;
}

public boolean findUnrepaired() throws GameActionException {
RobotInfo[] nearbyBots = rc.senseNearbyRobots(-1, rc.getTeam());
for (RobotInfo bot : nearbyBots) {
if (bot.type == RobotType.WATCHTOWER && bot.mode == RobotMode.PROTOTYPE) {
target = bot.location;
return true;
}
}
return false;
}

public int distToWall(Direction d) {
MapLocation my = rc.getLocation();
MapLocation n = my.add(d);
int min = 61;
min = Math.min(min, n.x);
min = Math.min(min, n.y);
min = Math.min(min, rc.getMapWidth() - n.x);
min = Math.min(min, rc.getMapHeight() - n.y);
return min;
}

public Direction[] sortedDirections() {
Direction[] dirs = { Direction.NORTH, Direction.NORTHEAST, Direction.EAST, Direction.SOUTHEAST, Direction.SOUTH,
Direction.SOUTHWEST, Direction.WEST, Direction.NORTHWEST };
Arrays.sort(dirs, (a, b) -> distToWall(b) - distToWall(a));
return dirs;
}

public void build(int[] build_order) throws GameActionException {
for (Direction dir : dirs) {
switch (counter % 2) {
case 0:
rc.setIndicatorString("Trying to build a laboratory" + " built_units: " + built_units + " "
+ build_order[counter % 2]);
buildLaboratory(dir);
break;
case 1:
rc.setIndicatorString("Trying to build a watchtower" + " built_units: " + built_units + " "
+ build_order[counter % 2]);
buildWatchtower(dir);
break;
}
if (built_units >= build_order[counter % 2]) {
counter++;
built_units = 0;
}
}
}

public void buildLaboratory(Direction dir) throws GameActionException {
if (rc.canBuildRobot(RobotType.LABORATORY, dir)) {
rc.buildRobot(RobotType.LABORATORY, dir);
built_units++;
num_labs++;
}
}

public void buildWatchtower(Direction dir) throws GameActionException {
if (rc.canBuildRobot(RobotType.WATCHTOWER, dir)) {
rc.buildRobot(RobotType.WATCHTOWER, dir);
built_units++;
num_watchtowers++;
}
}

public void heal() throws GameActionException {
RobotInfo[] nearbyBots = rc.senseNearbyRobots(-1, rc.getTeam());
for (RobotInfo bot : nearbyBots) {
if (bot.type == RobotType.WATCHTOWER || bot.type == RobotType.LABORATORY) {
if (bot.health < bot.type.health) {
if (rc.canRepair(bot.location))
rc.repair(bot.location);
else
moveToLocation(bot.location);
}
}
}
}

public void forTheGreaterGood() throws GameActionException {
MapLocation cur = rc.getLocation();
MapLocation target = null;
if (rc.senseLead(cur) == 0) {
rc.disintegrate();
}
// robot finds closest spot to archon without lead on it, then destroys itself.
int distSquared;
int minDistSquared = 10000;
for (int dx = -4; dx <= 4; dx++) {
for (int dy = -4; dy <= 4; dy++) {
if (dx == 0 && dy == 0)
continue;
if (validCoords(cur.x + dx, cur.y + dy)) {
MapLocation loc = new MapLocation(cur.x + dx, cur.y + dy);
if (loc.equals(homeArchon))
continue;
if (rc.canSenseLocation(loc)) {
int numLead = rc.senseLead(loc);
if (numLead == 0) {
distSquared = cur.distanceSquaredTo(loc);
if (distSquared < minDistSquared) {
minDistSquared = distSquared;
target = loc;
}
}

}
}
}
}
if (target != null) {
moveToLocation(target);
rc.setIndicatorString("target: " + target.x + " " + target.y);
} else
moveInDirection(exploratoryDir);
}

public RANK getBuilderRank() throws GameActionException {
RANK new_rank = findRank();
if (new_rank == RANK.DEFAULT || new_rank == RANK.MARTYR) {
return new_rank;
}
return RANK.DEFAULT;
}
}
36 changes: 36 additions & 0 deletions src/rebutia_heal/CHANNEL.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package rebutia_heal;

public enum CHANNEL {
ROUND_NUM(0),
MINERS_ALIVE(1),
SOLDIERS_ALIVE(2),
BUILDERS_ALIVE(3),
TOWERS_ALIVE(4),
MINERS_ALIVE_ALT(5),
SOLDIERS_ALIVE_ALT(6),
BUILDERS_ALIVE_ALT(7),
TOWERS_ALIVE_ALT(8),
USEFUL_MINERS(9),
USEFUL_MINERS_ALT(10),

LEAD_ESTIMATE(19),
ARCHON_LOC_1(20),
fARCHON_STATUS1(24),
ARCHON_NUMBER(28),
UNIT_BUILT(29),

MINING1(30),
TARGET(35),
ARCHON_MODE(40),
ARCHON_POSITION(44), //44-47
ORDERS(61),
SEND_RANKS1(62),
SEND_RANKS2(63),
;

public static final int NUM_TARGETS = 5;

private final int id;
CHANNEL(int id) { this.id = id; }
public int getValue() { return id; }
}
10 changes: 10 additions & 0 deletions src/rebutia_heal/CONSTANTS.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package rebutia_heal;

import battlecode.common.Direction;

public class CONSTANTS {
public static final double SOLDIERS_TO_TOWERS = 0.25;
public static Direction[] directions = {
Direction.NORTH, Direction.NORTHEAST, Direction.EAST, Direction.SOUTHEAST,
Direction.SOUTH, Direction.SOUTHWEST, Direction.WEST, Direction.NORTHWEST };
}
Loading