diff --git a/src/main/java/com/epita/creeps/Program.java b/src/main/java/com/epita/creeps/Program.java index 18c05f1..a4e3d29 100644 --- a/src/main/java/com/epita/creeps/Program.java +++ b/src/main/java/com/epita/creeps/Program.java @@ -2,21 +2,29 @@ package com.epita.creeps; import com.epita.creeps.commands.Basics; import com.epita.creeps.given.vo.geometry.Direction; +import com.epita.creeps.given.vo.geometry.Point; import com.epita.creeps.given.vo.response.CommandResponse; import com.epita.creeps.given.vo.response.InitResponse; import com.epita.creeps.units.Building; import com.epita.creeps.units.Citizen; +import com.epita.creeps.units.Turret; +import com.epita.creeps.units.Unit; import kong.unirest.core.HttpResponse; import kong.unirest.core.JsonNode; import kong.unirest.core.Unirest; import kong.unirest.core.UnirestException; +import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.List; + public class Program { private static String srvUrl; private static Logger logger; + @Getter private static String login; public static void main(String[] args) { @@ -62,24 +70,28 @@ public class Program { login = initResponse.login; // Just in case AsyncExec.setTicksPerSecond((float) initResponse.setup.ticksPerSeconds); - Citizen citizen1 = new Citizen(login, initResponse.citizen1Id); - Citizen citizen2 = new Citizen(login, initResponse.citizen2Id); + Citizen citizen1 = new Citizen(login, initResponse.citizen1Id, initResponse.householdCoordinates); + Citizen citizen2 = new Citizen(login, initResponse.citizen2Id, initResponse.householdCoordinates); + Unit.getUnits().add(citizen1); + Unit.getUnits().add(citizen2); citizen1.move(Direction.UP).waitFinished(); - while (true) { - citizen1.move(Direction.UP); - citizen2.move(Direction.RIGHT); - citizen1.waitFinished(); - citizen2.waitFinished(); + citizen1.fetchMessages(); + citizen2.move(Direction.UP); + citizen1.waitFinished(); + citizen2.waitFinished(); - citizen1.build(Building.ROAD); - citizen2.gather(); + citizen2.spawn("turret"); + citizen1.move(Direction.RIGHT); + citizen1.waitFinished(); + citizen2.waitFinished(); + + List turrets = Turret.getTurretUnits(); + Turret t = (Turret) turrets.getFirst(); + t.fire(t.getPosition().plus(new Point(4, 0))).waitFinished(); - citizen1.waitFinished(); - citizen2.waitFinished(); - } diff --git a/src/main/java/com/epita/creeps/commands/Basics.java b/src/main/java/com/epita/creeps/commands/Basics.java index 7a21963..a626b2c 100644 --- a/src/main/java/com/epita/creeps/commands/Basics.java +++ b/src/main/java/com/epita/creeps/commands/Basics.java @@ -1,10 +1,14 @@ package com.epita.creeps.commands; import com.epita.creeps.AsyncExec; +import com.epita.creeps.Program; import com.epita.creeps.given.exception.NoReportException; +import com.epita.creeps.given.extra.Cartographer; import com.epita.creeps.given.json.Json; -import com.epita.creeps.given.vo.report.Report; +import com.epita.creeps.given.vo.report.*; import com.epita.creeps.given.vo.response.InitResponse; +import com.epita.creeps.units.Turret; +import com.epita.creeps.units.Unit; import kong.unirest.core.HttpResponse; import kong.unirest.core.JsonNode; import kong.unirest.core.Unirest; @@ -48,18 +52,64 @@ public class Basics { // Asks the server for a certain report public static Report getReport (String reportId) { - HttpResponse response; + HttpResponse response = null; try { response = Unirest.get(srvUrl + "/report/" + reportId).asJson(); - logger.debug("Got report: " + response.getBody().toPrettyString()); - return Json.parseReport(response.getBody().toString()); +// logger.debug("Got report: " + response.getBody().toPrettyString()); + Report report = Json.parseReport(response.getBody().toString()); + handleReport(report); + return report; } catch (UnirestException e) { logger.error("Could not retrieve report"); throw new RuntimeException(e); } catch (NoReportException e) { logger.error("Could not parse report: not a report"); + logger.debug(response.getBody().toPrettyString()); throw new RuntimeException(e); } } + public static void handleReport(Report report) { + Cartographer c = Cartographer.INSTANCE; + if (report.opcode.startsWith("farm")) { + c.register((FarmReport) report); + } + else if (report.opcode.startsWith("gather")) { + c.register((GatherReport) report); + } + else if (report.opcode.startsWith("move")) { + c.register((MoveReport) report); + } + else if (report.opcode.startsWith("build")) { + c.register((BuildReport) report); + } + else if (report.opcode.startsWith("observe")) { + c.register((ObserveReport) report); + } + else if (report.opcode.startsWith("spawn")) + { + SpawnReport spawnReport = (SpawnReport) report; + if (spawnReport.errorCode != null) { + logger.warn("Could not spawn unit: got report with an error: " + report.errorCode); + } + if (spawnReport.spawnedUnit.opcode.endsWith("turret")) { + Turret turret = new Turret(Program.getLogin(), spawnReport.spawnedUnitId, spawnReport.spawnedUnit.position); + Unit.getUnits().add(turret); + } + else if (spawnReport.spawnedUnit.opcode.endsWith("bomber-bot")) { + Turret turret = new Turret(Program.getLogin(), spawnReport.spawnedUnitId, spawnReport.spawnedUnit.position); + Unit.getUnits().add(turret); + } + else { + logger.warn("Spawned unit is an unknown type. Ignored..."); + } + } + else if (report.opcode.startsWith("fire")) { + logger.debug("FIRREEE!!"); + } + else { + logger.warn("Unknown opcode '" + report.opcode + "' in the server report. Ignored..."); + } + } + } diff --git a/src/main/java/com/epita/creeps/commands/ObeserveReport.java b/src/main/java/com/epita/creeps/commands/ObeserveReport.java new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/epita/creeps/units/BomberBot.java b/src/main/java/com/epita/creeps/units/BomberBot.java new file mode 100644 index 0000000..9250b47 --- /dev/null +++ b/src/main/java/com/epita/creeps/units/BomberBot.java @@ -0,0 +1,10 @@ +package com.epita.creeps.units; + +import com.epita.creeps.given.vo.geometry.Point; + +public class BomberBot extends Unit { + + public BomberBot(String login, String id, Point position) { + super(login, id, position); + } +} diff --git a/src/main/java/com/epita/creeps/units/Citizen.java b/src/main/java/com/epita/creeps/units/Citizen.java index a5e1c0d..6d2b4a5 100644 --- a/src/main/java/com/epita/creeps/units/Citizen.java +++ b/src/main/java/com/epita/creeps/units/Citizen.java @@ -6,6 +6,7 @@ import com.epita.creeps.commands.Basics; import com.epita.creeps.given.exception.NoReportException; import com.epita.creeps.given.json.Json; import com.epita.creeps.given.vo.geometry.Direction; +import com.epita.creeps.given.vo.geometry.Point; import com.epita.creeps.given.vo.parameter.MessageParameter; import com.epita.creeps.given.vo.report.MoveReport; import com.epita.creeps.given.vo.report.Report; @@ -19,8 +20,8 @@ import java.util.concurrent.CompletableFuture; public class Citizen extends Unit { - public Citizen(String login, String citizen_id ) { - super(login, citizen_id); + public Citizen(String login, String citizen_id, Point position) { + super(login, citizen_id, position); } public Citizen move(Direction direction) { diff --git a/src/main/java/com/epita/creeps/units/Turret.java b/src/main/java/com/epita/creeps/units/Turret.java new file mode 100644 index 0000000..f2ba638 --- /dev/null +++ b/src/main/java/com/epita/creeps/units/Turret.java @@ -0,0 +1,27 @@ +package com.epita.creeps.units; + +import com.epita.creeps.given.extra.Cartographer; +import com.epita.creeps.given.json.Json; +import com.epita.creeps.given.vo.geometry.Point; +import com.epita.creeps.given.vo.parameter.FireParameter; + +import java.util.List; + +public class Turret extends Unit { + + public Turret(String login, String id, Point position) { + super(login, id, position); + } + + // Retrieves all units that are turrets + public static List getTurretUnits() { + return getUnits().stream().filter(unit -> unit.getClass() == Turret.class).toList(); + } + + public Turret fire(Point target) { + FireParameter fp = new FireParameter(target); + Cartographer cartographer = Cartographer.INSTANCE; + sendActionWithBody("fire:turret", Json.serialize(fp), 2); + return this; + } +} diff --git a/src/main/java/com/epita/creeps/units/Unit.java b/src/main/java/com/epita/creeps/units/Unit.java index 6ba8cd8..fdff9cf 100644 --- a/src/main/java/com/epita/creeps/units/Unit.java +++ b/src/main/java/com/epita/creeps/units/Unit.java @@ -4,33 +4,42 @@ import com.epita.creeps.AsyncExec; import com.epita.creeps.ServerReponseException; import com.epita.creeps.commands.Basics; import com.epita.creeps.given.json.Json; +import com.epita.creeps.given.vo.geometry.Point; import com.epita.creeps.given.vo.report.Report; import com.epita.creeps.given.vo.response.CommandResponse; import kong.unirest.core.HttpResponse; import kong.unirest.core.JsonNode; import kong.unirest.core.Unirest; +import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CompletableFuture; public abstract class Unit { + @Getter + private static final List units = new ArrayList<>(); public static String srvUrl; public static final Logger logger = LoggerFactory.getLogger(Unit.class); protected final String id; + @Getter + protected final Point position; protected final String command_uri; protected CompletableFuture> pendingAction; protected CompletableFuture pendingReport; protected Report lastReport; + protected boolean idle = true; - - public Unit(String login, String id) { + public Unit(String login, String id, Point position) { if (srvUrl == null) { throw new RuntimeException("Tried to create a citizen without properly initializing static fields"); } this.id = id; + this.position = position; command_uri = srvUrl + "/command/" + login + "/" + id + "/"; } @@ -38,7 +47,8 @@ public abstract class Unit { // Sets pending action accordingly and asks for a report after `delay` ticks public void sendActionWithBody(String actionCode, String body, long delay) { // Move - pendingAction = AsyncExec.asyncExec(() -> Unirest.post(command_uri + actionCode).asJson(), delay) + idle = false; + pendingAction = AsyncExec.asyncExec(() -> Unirest.post(command_uri + actionCode).body(body).asJson(), delay) .thenApplyAsync( x -> x ); // Get report pendingReport = getCommandReport(); @@ -60,6 +70,10 @@ public abstract class Unit { * @return true if action succeeded, false otherwise */ public boolean waitFinished() { + if (idle) { + logger.warn("Tried to wait for an idle citizen"); + return false; + } if (pendingAction == null || pendingReport == null) { logger.warn("Tried to wait a citizen with no pending action or report"); return false; @@ -70,6 +84,7 @@ public abstract class Unit { return false; } logger.debug("Got report: " + lastReport); + idle = true; return lastReport.errorCode != null; }