305 lines
9.9 KiB
Java
305 lines
9.9 KiB
Java
package planetwars;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.JsonArray;
|
|
import com.google.gson.JsonObject;
|
|
import com.google.gson.JsonSyntaxException;
|
|
|
|
|
|
/**********************************************
|
|
* ______ _ _______ _____
|
|
* |___ / | | | | ___ \_ _|
|
|
* / / ___ _ _ ___ | | | | |_/ / | |
|
|
* / / / _ \ | | / __| | |/\| | __/ | |
|
|
* ./ /__| __/ |_| \__ \ \ /\ / | _| |_
|
|
* \_____/\___|\__,_|___/ \/ \/\_| \___/
|
|
*
|
|
*********************************************/
|
|
|
|
|
|
/**
|
|
* Klasse die het staat van het spel bijhoudt.
|
|
*
|
|
* Je doet dit door een instance aan te maken en bij elke keer als je input
|
|
* krijgt van het spel dit door te geven aan de klasse met de functie update().
|
|
*
|
|
* Deze functie zal de input verwerken zodat je alle data in variabelen hebt namelijk
|
|
* - myPlanets
|
|
* - neutralPlanets
|
|
* - ...
|
|
* - enemyExpeditions
|
|
*
|
|
* De data wordt opgeslagen als een bepaalde klasse.
|
|
* Deze zijn allemaal record klassen wat wilt zeggen dat ze alleen maar dienen om
|
|
* data in op te slaan.
|
|
* Je kan de data ervan niet bewerken.
|
|
* Meer informatie over hoe elke klasse zijn data bijhoudt kan je zien in
|
|
* de file van die klasse.
|
|
*
|
|
* Je kan dan door middel van de functie addMove() zetten toevoegen.
|
|
* Wanneer je al je zetten hebt toegevoegd en je ze effectief wilt spelen
|
|
* kan je de functie Move() oproepen.
|
|
* Daarna kan je geen extra moves meer spelen tot de volgende beurt waarbij je
|
|
* de functie update() oproept.
|
|
*
|
|
* Tenslotte heb je nog de variabele currentTurn.
|
|
* Die wordt momenteel voor niets gebruikt maar houd bij aan welke turn we zitten.
|
|
*
|
|
*
|
|
* je kan in de file Example.java een voorbeeld implementatie vinden.
|
|
*/
|
|
public class PlanetWars {
|
|
public List<Planet> myPlanets;
|
|
public List<Planet> neutralPlanets;
|
|
public List<Planet> enemyPlanets;
|
|
|
|
public List<Expedition> myExpeditions;
|
|
public List<Expedition> enemyExpeditions;
|
|
|
|
public int currentTurn;
|
|
|
|
private List<Move> queuedMoves;
|
|
private boolean moved;
|
|
private DateTimeFormatter dateFormatter;
|
|
|
|
|
|
public PlanetWars() {
|
|
this.myPlanets = new ArrayList<>();
|
|
this.neutralPlanets = new ArrayList<>();
|
|
this.enemyPlanets = new ArrayList<>();
|
|
|
|
this.myExpeditions = new ArrayList<>();
|
|
this.enemyExpeditions = new ArrayList<>();
|
|
|
|
this.currentTurn = 0;
|
|
|
|
this.queuedMoves = new ArrayList<>();
|
|
this.dateFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
|
|
}
|
|
|
|
/**
|
|
* Roep dit iedere beurt op met de input die je krijgt van het spel.
|
|
* Gaat over de data en maakt er de juiste objecten van.
|
|
*
|
|
* @param input | De data die je krijgt van het spel. Zie Main.java hoe je dit het best krijgt
|
|
*
|
|
* @return | Geeft aan of opgegeven data klopt en of je iets kan doen.
|
|
*/
|
|
public boolean update(String input) {
|
|
// Maak alle lijsten leeg.
|
|
this.nextTurn();
|
|
|
|
// Vorm de input om tot een JsonObject.
|
|
JsonObject state;
|
|
try {
|
|
state = new Gson().fromJson(input, JsonObject.class);
|
|
} catch (JsonSyntaxException e) {
|
|
this.log("Error: Converting input to json");
|
|
this.log(input);
|
|
return false;
|
|
}
|
|
|
|
// Krijg een lijst van alle planeten.
|
|
List<Planet> planets = new ArrayList<>();
|
|
try {
|
|
JsonArray planetsJson = state.getAsJsonArray("planets");
|
|
for (int i = 0; i < planetsJson.size(); i++) {
|
|
planets.add(new Planet(planetsJson.get(i).getAsJsonObject()));
|
|
}
|
|
} catch (Exception e) {
|
|
this.log("Error: Parsing planet input");
|
|
this.log(input);
|
|
return false;
|
|
}
|
|
|
|
if (planets.isEmpty()) {
|
|
this.log("Error: No planets");
|
|
this.log(input);
|
|
return false;
|
|
}
|
|
|
|
// Voeg de planeten toe tot de juiste lijst.
|
|
for (Planet planet : planets) {
|
|
if (planet.owner() == null) {
|
|
neutralPlanets.add(planet);
|
|
} else if (planet.owner() == 1) {
|
|
myPlanets.add(planet);
|
|
} else {
|
|
enemyPlanets.add(planet);
|
|
}
|
|
}
|
|
|
|
// Doe hetzelfde met de expedities.
|
|
try {
|
|
JsonArray expeditionsJson = state.getAsJsonArray("expeditions");
|
|
|
|
for (int i = 0; i < expeditionsJson.size(); i++) {
|
|
JsonObject expedition = expeditionsJson.get(i).getAsJsonObject();
|
|
|
|
// Zoek naar de planeet object vanwaar ze komen en naar toe gaan.
|
|
String originString = expedition.get("origin").getAsString();
|
|
String destinationString = expedition.get("destination").getAsString();
|
|
Planet originPlanet = null;
|
|
Planet destinationPlanet = null;
|
|
for (Planet planet: planets) {
|
|
if (planet.name().equals(originString)) {
|
|
// Planeet van waar ze komen is gevonden
|
|
originPlanet = planet;
|
|
}
|
|
if (planet.name().equals(destinationString)) {
|
|
// Planeet waar ze naar toe gaan is ook gevonden
|
|
destinationPlanet = planet;
|
|
}
|
|
}
|
|
|
|
// Maak nieuwe expeditie aan en voeg het toe bij de juiste lijst
|
|
Expedition exp = new Expedition(expedition, originPlanet, destinationPlanet);
|
|
if (exp.owner() == 1) {
|
|
myExpeditions.add(exp);
|
|
} else {
|
|
enemyExpeditions.add(exp);
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
this.log("Error: Parsing expedition input");
|
|
this.log(input);
|
|
return false;
|
|
}
|
|
|
|
this.moved = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Voeg een zet toe.
|
|
* Je kan zoveel zetten toevoegen als je wilt en ze worden pas doorgegeven wanneer je move() aanroept.
|
|
*
|
|
* @param origin | De planeet van waar de schepen moeten komen.
|
|
* @param destination | De planeet waar de schepen moeten toekomen.
|
|
* @param ships | De hoeveelheid schepen die je wilt versturen
|
|
*
|
|
* @return | Geeft weer indien het een geldige zet is. Let op er worden maar een paar basis checks gedaan hiervoor
|
|
*/
|
|
public boolean addMove(Planet origin, Planet destination, int ships) {
|
|
// Je kan maar 1 keer al je moves versturen per buurt.
|
|
// Je kan daarin wel meerdere moves zetten.
|
|
// Je kan dit doen door meerdere keren add_move op te roepen voor je move() oproept.
|
|
if (this.moved) {
|
|
return false;
|
|
}
|
|
|
|
// Je kan alleen schepen sturen die komen van je eigen planeet.
|
|
if (origin.owner() != 1) {
|
|
return false;
|
|
}
|
|
|
|
// Je kan geen schepen sturen naar dezelfde planeet als van waar ze komen.
|
|
if (origin.equals(destination)) {
|
|
return false;
|
|
}
|
|
|
|
// Je kan niet meer schepen versturen dan er zijn op de oorsprong planeet.
|
|
int totalShips = ships;
|
|
for (Move move: this.queuedMoves) {
|
|
if (move.origin().equals(origin)) {
|
|
totalShips += move.shipCount();
|
|
}
|
|
}
|
|
if (totalShips > origin.shipCount()) {
|
|
return false;
|
|
}
|
|
|
|
this.queuedMoves.add(new Move(origin, destination, ships));
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Verwijder de moves die je al had toegevoegd.
|
|
*/
|
|
public void clearMoves() {
|
|
this.queuedMoves.clear();
|
|
}
|
|
|
|
/**
|
|
* Voer alle zetten uit en ga naar de volgende beurt.
|
|
*/
|
|
public void move() {
|
|
// Je kan maar 1 keer al je moves versturen per beurt.
|
|
// Je kan daarin wel meerdere moves zetten.
|
|
// Je kan dit doen door meerdere keren add_move op te roepen voor je move() oproept.
|
|
if (this.moved) {
|
|
return;
|
|
}
|
|
|
|
List<JsonObject> movesJson = new ArrayList<>();
|
|
for (Move move : queuedMoves) {
|
|
movesJson.add(move.toJson());
|
|
}
|
|
|
|
JsonObject movesObj = new JsonObject();
|
|
movesObj.add("moves", new Gson().toJsonTree(movesJson));
|
|
|
|
this.moved = true;
|
|
|
|
System.out.println(movesObj);
|
|
}
|
|
|
|
/**
|
|
* Print een bericht met een tijdstip ervoor.
|
|
*
|
|
* @param message | Het bericht dat je wilt printen.
|
|
*/
|
|
public void log(String message) {
|
|
LocalDateTime timestamp = LocalDateTime.now();
|
|
String formattedTimestamp = timestamp.format(this.dateFormatter);
|
|
|
|
System.err.println("[" + formattedTimestamp + "] " + message);
|
|
}
|
|
|
|
/**
|
|
* Maakt variabelen klaar voor de volgende beurt.
|
|
*/
|
|
private void nextTurn() {
|
|
this.myPlanets.clear();
|
|
this.neutralPlanets.clear();
|
|
this.enemyPlanets.clear();
|
|
|
|
this.myExpeditions.clear();
|
|
this.enemyExpeditions.clear();
|
|
|
|
this.currentTurn += 1;
|
|
|
|
this.queuedMoves.clear();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Weet je niet hoe je nu verder moet?
|
|
*
|
|
* Kijk naar example.py hoe de klasse te implementeren.
|
|
*
|
|
* Nog enkele tips hoe je je bot beter kan maken:
|
|
*
|
|
* - Maak een nieuwe functie aan in de klasse PlanetWars `predict`.
|
|
* Deze probeert te voorspellen hoeveel schepen van je tegenstander er op een bepaalde
|
|
* planeet toekomen na x aantal beurten.
|
|
*
|
|
* - Maak een onderscheid tussen de gevallen waarbij jouw tegenstander geen extra schepen meer
|
|
* verstuurd naar een bepaalde planeet en al zijn schepen ernaar heeft verstuurd.
|
|
* Welke planeten kan je met de minste effort makkelijk pakken?
|
|
*
|
|
* - Indien je al meerdere planeten hebt probeer schepen van de achterliggende planeten naar
|
|
* de frontline te sturen.
|
|
*
|
|
* - ...
|
|
*
|
|
* Wees creatief, de mogelijkheden zijn eindeloos :D
|
|
*/
|