Skip to content

Commit

Permalink
Bot like a python kit. Fixed Random. !!! Mixed up axes in board 2d ar…
Browse files Browse the repository at this point in the history
…ray (bug or feature?).
  • Loading branch information
Alexey Pogasiy committed Nov 27, 2022
1 parent 00a425d commit 5057d0e
Show file tree
Hide file tree
Showing 9 changed files with 305 additions and 80 deletions.
117 changes: 78 additions & 39 deletions kits/java/src/main/java/com/luxai/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

public class Agent {

//private State state;
private Random random = new Random(2022);

public Obs obs;
public int step;
Expand All @@ -27,9 +27,8 @@ public String early_setup() throws JsonProcessingException {
if (this.step == 0)
return Mapper.getJson(new BidAction("AlphaStrike", 0));
if (this.obs.teams.get(this.me()).factories_to_place > 0) {
Random random = new Random();
ArrayList<ArrayList<Integer>> mySpawn = this.obs.board.spawns.get(me());
int randomSpawnIndex = random.nextInt(mySpawn.size());
int randomSpawnIndex = this.random.nextInt(mySpawn.size());

SpawnAction spawnAction = new SpawnAction(new int[]{mySpawn.get(randomSpawnIndex).get(0), mySpawn.get(randomSpawnIndex).get(1)},
100,//this.getObs().teams.get(this.me()).metal / 2,
Expand All @@ -44,16 +43,88 @@ public String early_setup() throws JsonProcessingException {
public String act() throws JsonProcessingException {
UnitAction unitAction = new UnitAction();

Map<String, Factory> factories = obs.factories.get(this.me());
for (String unitId : factories.keySet()) {
Factory factory = factories.get(unitId);
Map<String, Factory> myFactories = obs.factories.get(this.me());
for (String unitId : myFactories.keySet()) {
Factory factory = myFactories.get(unitId);
if (factory.canBuildHeavy(this.env_cfg))
unitAction.add(factory.unit_id, Factory.BUILD_HEAVY);
}

Map<String, Robot> units = obs.units.get(this.me());
for (Robot robot : units.values()) {

int xRobot = robot.pos[MoveUtils.X];
int yRobot = robot.pos[MoveUtils.Y];
int factoryDistance = 100000;
Factory nearestFactory = null;
// Find nearest factory
for (Factory factory : obs.factories.get(this.me()).values()) {
int manhattan = MoveUtils.getManhattanDistance(xRobot, yRobot, factory.pos[MoveUtils.X], factory.pos[MoveUtils.Y]);
if (manhattan < factoryDistance) {
factoryDistance = manhattan;
nearestFactory = factory;
}
}
if (nearestFactory != null) {
int factoryDirection = MoveUtils.getDirection(xRobot, yRobot, nearestFactory.pos[MoveUtils.X], nearestFactory.pos[MoveUtils.Y]);
// Cargo full
if (robot.cargo.ice > 40) {
// Factory orthogonally adjacent
if (factoryDistance <= 3) {
if (robot.power > robot.getActionQueueCost(obs, env_cfg))
unitAction.actions.put(robot.unit_id, robot.transfer(factoryDirection, 0, robot.cargo.ice, false));
}
// Factory long away
else {
int moveCost = robot.getMoveCost(obs, env_cfg, this.me(), factoryDirection);
if (moveCost != MoveUtils.MOVE_UNAVAILABLE
&& robot.power >= (moveCost + robot.getActionQueueCost(obs, env_cfg)))
unitAction.actions.put(robot.unit_id, robot.move(factoryDirection, false));
}
}
// Need to mine recourses
else {
// Find closest ice tile
int iceDistance = 100000;
int xIce = -1;
int yIce = -1;
for (int x = 0; x < env_cfg.map_size; x++) {
for (int y = 0; y < env_cfg.map_size; y++) {
// Tile has ice
if (obs.board.ice[y][x] > 0) {
boolean isMyFactoryArea = false;
for (String unitId : myFactories.keySet()) {
Factory factory = myFactories.get(unitId);
if (factory.isFactoryArea(x, y))
isMyFactoryArea = true;
}
if (!isMyFactoryArea) {
int manhattan = MoveUtils.getManhattanDistance(xRobot, yRobot, x, y);
if (manhattan < iceDistance) {
iceDistance = manhattan;
xIce = x;
yIce = y;
}
}
}
}
}
// Robot on ice position
if (xIce != -1 && yIce != -1) {
if (xIce == xRobot && yIce == yRobot) {
if (robot.power >= (robot.getDigCost(obs, env_cfg) + robot.getActionQueueCost(obs, env_cfg)))
unitAction.actions.put(robot.unit_id, robot.dig(false));
}
// Ice long away
else {
int iceDirection = MoveUtils.getDirection(xRobot, yRobot, xIce, yIce);
int moveCost = robot.getMoveCost(obs, env_cfg, this.me(), iceDirection);
if (moveCost != MoveUtils.MOVE_UNAVAILABLE
&& robot.power >= (moveCost + robot.getActionQueueCost(obs, env_cfg)))
unitAction.actions.put(robot.unit_id, robot.move(iceDirection, false));
}
}
}
}
}

if (unitAction.actions.size() > 0)
Expand Down Expand Up @@ -118,36 +189,4 @@ public String me() {
return this.player;
}

// public Obs getObs() {
// return obs;
// }

// public int getStep() {
// return step;
// }
//
// public void setObs(Obs obs) {
// this.obs = obs;
// }
//
// public void setStep(int step) {
// this.step = step;
// }
//
// public void setRemainingOverageTime(int remainingOverageTime) {
// this.remainingOverageTime = remainingOverageTime;
// }
//
// public void setPlayer(String player) {
// this.player = player;
// }
//
// public void setEnv_cfg(Environment env_cfg) {
// this.env_cfg = env_cfg;
// }
//
// public void setReward(double reward) {
// this.reward = reward;
// }

}
86 changes: 54 additions & 32 deletions kits/java/src/main/java/com/luxai/Bot.java

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions kits/java/src/main/java/com/luxai/lux/Board.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
public class Board {
// step = 0
@JsonProperty("rubble_init")
public int[][] rubble;
public int[][] ore;
public int[][] ice;
public int[][] rubble; // Mixed up X and Y. I don`t know it is my bad or json-feature
public int[][] ore; // Mixed up X and Y. I don`t know it is my bad or json-feature
public int[][] ice; // Mixed up X and Y. I don`t know it is my bad or json-feature
@JsonProperty("lichen_init")
public int[][] lichen;
public int[][] lichen; // Mixed up X and Y. I don`t know it is my bad or json-feature
@JsonProperty("strains_init")
public int[][] lichen_strains;
public int[][] lichen_strains; // Mixed up X and Y. I don`t know it is my bad or json-feature
public Map<String, ArrayList<ArrayList<Integer>>> spawns;

// step > 0
Expand Down
24 changes: 24 additions & 0 deletions kits/java/src/main/java/com/luxai/lux/Factory.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ public class Factory {
public static final int BUILD_HEAVY = 1;
public static final int WATER = 2;

public static final int X = 0;
public static final int Y = 1;

public int[] pos;
public int power;
public int strain_id;
Expand All @@ -22,4 +25,25 @@ public boolean canBuildLight(Environment environment) {
RobotInfo robot = environment.ROBOTS.get("LIGHT");
return this.power >= robot.POWER_COST && this.cargo.metal >= robot.METAL_COST;
}

public int waterCost(Obs obs, Environment environment) {
int lichenCounter = 0;
for (int[] row : obs.board.lichen_strains) {
for (int lichenStrain : row) {
if (lichenStrain == this.strain_id)
lichenCounter++;
}
}
// Conflict logic: python kit vs specs
return (int) (Math.ceil(lichenCounter / 10.0) * environment.LICHEN_WATERING_COST_FACTOR); //specs
// return (int) (Math.ceil(lichenCounter / environment.LICHEN_WATERING_COST_FACTOR) + 1); //python
}

public boolean canWater(Obs obs, Environment environment) {
return this.cargo.water >= waterCost(obs, environment);
}

public boolean isFactoryArea(int x, int y) {
return Math.max(Math.abs(this.pos[X] - x), Math.abs(this.pos[Y] - y)) <= 1;
}
}
41 changes: 41 additions & 0 deletions kits/java/src/main/java/com/luxai/lux/MoveUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.luxai.lux;

public class MoveUtils {

public static final int X = 0;
public static final int Y = 1;

public static final int MOVE_CENTER = 0;
public static final int MOVE_DOWN = 1;
public static final int MOVE_RIGHT = 2;
public static final int MOVE_UP = 3;
public static final int MOVE_LEFT = 4;

public static final int MOVE_UNAVAILABLE = -1;

public static int getManhattanDistance(int x1, int y1, int x2, int y2) {
return (Math.abs(x1 - x2) + Math.abs(y1 - y2));
}

public static int getDirection(int xSource, int ySource, int xTarget, int yTarget) {
int dx = xTarget - xSource;
int dy = yTarget - ySource;

if (dx == 0 && dy == 0)
return MOVE_CENTER;

if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 0)
return MOVE_RIGHT;
else
return MOVE_LEFT;
}
else {
if (dy > 0)
return MOVE_UP;
else
return MOVE_DOWN;
}
}

}
70 changes: 68 additions & 2 deletions kits/java/src/main/java/com/luxai/lux/Robot.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.luxai.lux;

import com.luxai.lux.Cargo;

public class Robot {

public static final int[][] modeDeltaArray = new int[][]{{0, 0}, {0, -1}, {1, 0}, {0, 1}, {-1, 0}};

public int[] pos;
public int team_id;
public int power;
Expand All @@ -12,4 +12,70 @@ public class Robot {
public String[] action_queue;
public Cargo cargo;

public double getActionQueueCost (Obs obs, Environment environment) {
int cost = environment.UNIT_ACTION_QUEUE_POWER_COST.get(this.unit_type);
int currentWeather = obs.weather_schedule[obs.real_env_steps];
double weatherLossFactor = Weather.powerLossFactor(currentWeather, environment);
return cost * weatherLossFactor;
}

// Сравнить по team_id
public int getMoveCost(Obs obs, Environment environment, String me, int moveDirection) {
int[] targetPos = new int[]{this.pos[MoveUtils.X] + modeDeltaArray[moveDirection][MoveUtils.X], this.pos[MoveUtils.Y] + modeDeltaArray[moveDirection][MoveUtils.Y]};
// Off the map
if (targetPos[MoveUtils.X] < 0
|| targetPos[MoveUtils.Y] < 0
|| targetPos[MoveUtils.X] >= environment.map_size
|| targetPos[MoveUtils.Y] >= environment.map_size)
return MoveUtils.MOVE_UNAVAILABLE;
// On the enemy factory
for (String player : obs.factories.keySet()) {
if (!player.equals(me)) {
for (Factory factory : obs.factories.get(player).values()) {
if (factory.isFactoryArea(targetPos[MoveUtils.X], targetPos[MoveUtils.Y]))
return MoveUtils.MOVE_UNAVAILABLE;
}
}
}

int targetRubble = obs.board.rubble[targetPos[MoveUtils.Y]][targetPos[MoveUtils.X]];
double powerLossFactor = Weather.powerLossFactor(obs.weather_schedule[obs.real_env_steps], environment);
RobotInfo robotInfo = environment.ROBOTS.get(this.unit_type);
return (int) Math.ceil((robotInfo.MOVE_COST + robotInfo.RUBBLE_MOVEMENT_COST * targetRubble) * powerLossFactor);
}

public int getDigCost(Obs obs, Environment environment) {
double powerLossFactor = Weather.powerLossFactor(obs.weather_schedule[obs.real_env_steps], environment);
return (int) Math.ceil(environment.ROBOTS.get(this.unit_type).DIG_COST * powerLossFactor);
}

public int getSelfDestructCost(Obs obs, Environment environment) {
double powerLossFactor = Weather.powerLossFactor(obs.weather_schedule[obs.real_env_steps], environment);
return (int) Math.ceil(environment.ROBOTS.get(this.unit_type).SELF_DESTRUCT_COST * powerLossFactor);
}

public Object move(int dir, boolean repeat) {
return new Object[]{new Integer[]{0, dir, 0, 0, repeat ? 1 : 0}};
}

public Object transfer(int dir, int type, int amount, boolean repeat) {
return new Object[]{new Integer[]{1, dir, type, amount, repeat ? 1 : 0}};
}

public Object pickup(int resourceType, int amount, boolean repeat) {
return new Object[]{new Integer[]{2, 0, resourceType, amount, repeat ? 1 : 0}};
}

public Object dig(boolean repeat) {
return new Object[]{new Integer[]{3, 0, 0, 0, repeat ? 1 : 0}};
}

public Object selfDestruct(boolean repeat) {
return new Object[]{new Integer[]{4, 0, 0, 0, repeat ? 1 : 0}};
}

public Object recharge(int awaitPower, boolean repeat) {
return new Object[]{new Integer[]{5, 0, 0, awaitPower, repeat ? 1 : 0}};
}

}
3 changes: 3 additions & 0 deletions kits/java/src/main/java/com/luxai/lux/State.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.luxai.lux;

import java.util.ArrayList;
import java.util.List;

public class State {

public Obs obs;
Expand Down
30 changes: 30 additions & 0 deletions kits/java/src/main/java/com/luxai/lux/Weather.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,34 @@ public class Weather {
public DustStorm DUST_STORM;
public SolarFlare SOLAR_FLARE;

public static double getGainFactor(int weatherCode, Environment environment) {
switch (getWeatherName(weatherCode, environment)) {
case "DUST_STORM":
return environment.WEATHER.DUST_STORM.POWER_GAIN;
case "SOLAR_FLARE":
return environment.WEATHER.SOLAR_FLARE.POWER_GAIN;
case "NONE":
case "MARS_QUAKE":
case "COLD_SNAP":
default:
return 1;
}
}

public static double powerLossFactor(int weatherCode, Environment environment) {
switch (getWeatherName(weatherCode, environment)) {
case "COLD_SNAP":
return environment.WEATHER.COLD_SNAP.POWER_CONSUMPTION;
case "DUST_STORM":
case "SOLAR_FLARE":
case "NONE":
case "MARS_QUAKE":
default:
return 1;
}
}

public static String getWeatherName(int weatherCode, Environment environment) {
return environment.WEATHER_ID_TO_NAME.get(weatherCode);
}
}
4 changes: 2 additions & 2 deletions kits/java/src/main/java/com/luxai/lux/action/UnitAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

public class UnitAction {

public Map<String, Integer> actions;
public Map<String, Object> actions;

public UnitAction() {
this.actions = new HashMap<>();
}

public void add(String unit_id, Integer action) {
public void add(String unit_id, Object action) {
actions.put(unit_id, action);
}

Expand Down

0 comments on commit 5057d0e

Please sign in to comment.