package myai;
import static myai.MapModule.P;
import static myai.MapModule.manhattan;
import java.awt.Point;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import myai.Tuples.Tuple3;
import rts.GameState;
import rts.units.Unit;
import rts.units.UnitAction;
public class ArmyManager {
private LinkedHashMap<Long, TaskedSoldier> mySoldiers = new LinkedHashMap<Long, TaskedSoldier>();
public static Random random = new Random();
public void preUnitLogic(MapModule map, GameState state) {
// Prune dead units
List<Long> aliveSoldiers = new LinkedList<Long>();
for (Unit unit : state.getMyUnits()) {
if (!unit.isBuilding() && !unit.isWorker() && !unit.isResources()) {
aliveSoldiers.add(unit.getID());
}
}
Iterator<Entry<Long, TaskedSoldier>> ite = mySoldiers.entrySet().iterator();
while (ite.hasNext()) {
Entry<Long, TaskedSoldier> s = ite.next();
if (!aliveSoldiers.contains(s.getValue().unit.getID())) {
ite.remove();
}
}
}
public void commandUnit(Unit unit, GameState state, MapModule map, UnitGeneral men) {
// ASSIGN DEFAULT TASK
if (!mySoldiers.containsKey(unit.getID())) {
mySoldiers.put(unit.getID(), new TaskedSoldier(unit, SoldierTaskType.SCOUT));
}
// FETCH CURRENT TASK
TaskedSoldier UNIT = mySoldiers.get(unit.getID());
switch (UNIT.task) {
case SCOUT: {
if (!map.pointRef_THEM.isEmpty()) {
UNIT.clearScoutGoals();
setTask(unit, SoldierTaskType.ATTACK_NEAREST);
} else {
if (UNIT.goalPos == null) {
UNIT.goalPos = P(random.nextInt(map.mapDim.width), random.nextInt(map.mapDim.height));
}
Tuple3<Boolean, Double, List<Point>> g = map.findPath(P(unit), UNIT.goalPos, true, unit.isFlying());
if (g.a && g.c.size() > 2) {
// MOVE
men.findAndSetAction(unit, g.c.get(1), UnitAction.MOVE, true);
} else {
UNIT.clearScoutGoals();
}
}
break;
}
case ATTACK_NEAREST :{
if (map.pointRef_THEM.isEmpty()) {
setTask(unit, SoldierTaskType.SCOUT);
} else {
Point closest = null; double dist = Double.MAX_VALUE;
Point u = P(unit);
for (Entry<Point, Unit> p : map.pointRef_THEM.entrySet()) {
double mDist = manhattan(p.getKey(), u);
if (mDist < dist) {
dist = mDist;
closest = p.getKey();
}
}
UNIT.goalPos = closest;
// ATTACK!
if (closest != null) {
Tuple3<Boolean, Double, List<Point>> target = map.findPath(P(unit), UNIT.goalPos, false, unit.isFlying());
if (target.c.size() > 1) {
men.findAndSetAction(unit, target.c.get(1), UnitAction.MOVE, true);
}
}
}
break;
}
default:
System.err.println("Unit " + unit + " is in a bad state!");
break;
}
}
enum SoldierTaskType {
SCOUT, ATTACK_NEAREST;
}
private void setTask(Unit unit, SoldierTaskType type) {
mySoldiers.get(unit.getID()).task = type;
}
public class TaskedSoldier {
SoldierTaskType task = SoldierTaskType.SCOUT;
Point goalPos;
final Unit unit;
public TaskedSoldier(Unit unit, SoldierTaskType task) {
this.unit = unit;
this.task = task;
}
public void clearScoutGoals() {
goalPos = null;
}
}
}