diff --git a/Projektgruppe_175/res/highscores.txt b/Projektgruppe_175/res/highscores.txt new file mode 100644 index 0000000..e69de29 diff --git a/Projektgruppe_175/src/game/map/Clustering.java b/Projektgruppe_175/src/game/map/Clustering.java index d27078e..f541479 100644 --- a/Projektgruppe_175/src/game/map/Clustering.java +++ b/Projektgruppe_175/src/game/map/Clustering.java @@ -1,40 +1,112 @@ -package game.map; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Random; - -/** - * Diese Klasse teilt Burgen in Königreiche auf - */ -public class Clustering { - - private Random random; - private final List allCastles; - private final int kingdomCount; - - /** - * Ein neues Clustering-Objekt erzeugen. - * @param castles Die Liste von Burgen, die aufgeteilt werden sollen - * @param kingdomCount Die Anzahl von Königreichen die generiert werden sollen - */ - public Clustering(List castles, int kingdomCount) { - if (kingdomCount < 2) - throw new IllegalArgumentException("Ungültige Anzahl an Königreichen"); - - this.random = new Random(); - this.kingdomCount = kingdomCount; - this.allCastles = Collections.unmodifiableList(castles); - } - - /** - * Gibt eine Liste von Königreichen zurück. - * Jedes Königreich sollte dabei einen Index im Bereich 0-5 bekommen, damit die Burg richtig angezeigt werden kann. - * Siehe auch {@link Kingdom#getType()} - */ - public List getPointsClusters() { - // TODO Clustering#getPointsClusters() - return new ArrayList<>(); - } -} +package game.map; + +import java.awt.Point; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +/** + * Diese Klasse teilt Burgen in Königreiche auf + */ +public class Clustering { + + private Random random; + private final List allCastles; + private final int kingdomCount; + + /** + * Ein neues Clustering-Objekt erzeugen. + * @param castles Die Liste von Burgen, die aufgeteilt werden sollen + * @param kingdomCount Die Anzahl von Königreichen die generiert werden sollen + */ + public Clustering(List castles, int kingdomCount) { + if (kingdomCount < 2) + throw new IllegalArgumentException("Ungültige Anzahl an Königreichen"); + + this.random = new Random(); + this.kingdomCount = kingdomCount; + this.allCastles = Collections.unmodifiableList(castles); + } + + /** + * Gibt eine Liste von Königreichen zurück. + * Jedes Königreich sollte dabei einen Index im Bereich 0-5 bekommen, damit die Burg richtig angezeigt werden kann. + * Siehe auch {@link Kingdom#getType()} + */ + public List getPointsClusters() { + List kingdoms = new ArrayList<>(); + + // Erzeuge Königreiche mit zufälligen Zentren + for(int i = 0; i < kingdomCount; i++) { + kingdoms.add(new Kingdom(i, allCastles.get(random.nextInt(allCastles.size())))); + } + + boolean changed; + Kingdom lastKingdom; + + // Wiederhole, solange sich die Zuordnungen der Burgen zu den Königreichen ändern + do { + changed = false; + + // Ordne jede Burg dem nächstgelegenen Königreich zu + for(Castle c : allCastles) { + lastKingdom = c.getKingdom(); + c.setKingdom(this.getNearestKingdom(c, kingdoms)); + if(c.getKingdom() != lastKingdom) changed = true; // Eine Zuordnung hat sich geändert + } + + // Setze die Zentren der Königreiche neu + for(Kingdom k : kingdoms) { + double meanX=0, meanY=0, sumX=0, sumY=0; + double numCastles = k.getCastles().size(); + for(Castle c : k.getCastles()) { + sumX += c.getLocationOnMap().getX(); + sumY += c.getLocationOnMap().getY(); + } + meanX = sumX/numCastles; + meanY = sumY/numCastles; + Point p = new Point(); + p.setLocation(meanX, meanY); + k.setCenter(getNearestCastle(p, allCastles)); + } + + }while(changed); + + return kingdoms; + } + + /** + * Gibt die dem übergebenen Punkt nächstgelegene Burg zurück + * @param point der Punkt auf der Karte + * @param castles die Liste aller Burgen + * @return die nächstgelegene Burg + */ + protected Castle getNearestCastle(Point point, List castles) { + Castle nearest = castles.get(0); + for(Castle c : castles) { + if(c.distance(point) < nearest.distance(point)) { + nearest = c; + } + } + return nearest; + } + + /** + * Gibt das zur übergebenen Burg nächstgelegene Königreich zurück + * @param castle die Burg + * @param kingdoms die Liste aller Königreiche + * @return das nächstgelegene Königreich + */ + protected Kingdom getNearestKingdom(Castle castle, List kingdoms) { + Kingdom nearest = kingdoms.get(0); + double dist = castle.distance(nearest.getCenter()); + for(Kingdom k : kingdoms) { + if(castle.distance(k.getCenter()) < dist) { + nearest = k; + dist = castle.distance(nearest.getCenter()); + } + } + return nearest; + } +} diff --git a/Projektgruppe_175/src/game/map/Kingdom.java b/Projektgruppe_175/src/game/map/Kingdom.java index 4e43cc3..7286bf2 100644 --- a/Projektgruppe_175/src/game/map/Kingdom.java +++ b/Projektgruppe_175/src/game/map/Kingdom.java @@ -1,75 +1,96 @@ -package game.map; - -import game.Player; - -import java.util.LinkedList; -import java.util.List; - -/** - * Diese Klasse representiert ein Königreich. Jedes Königreich hat eine Liste von Burgen sowie einen Index {@link #type} im Bereich von 0-5 - * - */ -public class Kingdom { - - private List castles; - private int type; - - /** - * Erstellt ein neues Königreich - * @param type der Typ des Königreichs (im Bereich 0-5) - */ - public Kingdom(int type) { - this.castles = new LinkedList<>(); - this.type = type; - } - - /** - * Eine Burg zum Königreich hinzufügen - * @param castle die Burg, die hinzugefügt werden soll - */ - public void addCastle(Castle castle) { - this.castles.add(castle); - } - - /** - * Gibt den Typen des Königreichs zurück. Dies wird zur korrekten Anzeige benötigt - * @return der Typ des Königreichs. - */ - public int getType() { - return this.type; - } - - /** - * Eine Burg aus dem Königreich entfernen - * @param castle die zu entfernende Burg - */ - public void removeCastle(Castle castle) { - this.castles.remove(castle); - } - - /** - * Gibt den Spieler zurück, der alle Burgen in dem Köngreich besitzt. - * Sollte es keinen Spieler geben, der alle Burgen besitzt, wird null zurückgegeben. - * @return der Besitzer oder null - */ - public Player getOwner() { - if(castles.isEmpty()) - return null; - - Player owner = castles.get(0).getOwner(); - for(Castle castle : castles) { - if(castle.getOwner() != owner) - return null; - } - - return owner; - } - - /** - * Gibt alle Burgen zurück, die in diesem Königreich liegen - * @return Liste von Burgen im Königreich - */ - public List getCastles() { - return this.castles; - } -} +package game.map; + +import game.Player; + +import java.util.LinkedList; +import java.util.List; + +/** + * Diese Klasse representiert ein Königreich. Jedes Königreich hat eine Liste von Burgen sowie einen Index {@link #type} im Bereich von 0-5 + * + */ +public class Kingdom { + + private List castles; + private Castle center; + private int type; + + /** + * Erstellt ein neues Königreich + * @param type der Typ des Königreichs (im Bereich 0-5) + * @param center das Zentrum des Königreichs + */ + public Kingdom(int type, Castle center) { + this.castles = new LinkedList<>(); + this.type = type; + this.center = center; + center.setKingdom(this); + this.castles.add(center); + } + + /** + * Eine Burg zum Königreich hinzufügen + * @param castle die Burg, die hinzugefügt werden soll + */ + public void addCastle(Castle castle) { + this.castles.add(castle); + } + + /** + * Eine Burg als Zentrum des Königreichs festlegen + * @param castle die Burg, die als Zentrum festgelegt werden soll + */ + public void setCenter(Castle castle) { + this.center = castle; + } + + /** + * Gibt das Zentrum des Königreichs zurück + * @param castle die Burg, die das Zentrum des Königreichs darstellt + */ + public Castle getCenter() { + return this.center; + } + + /** + * Gibt den Typen des Königreichs zurück. Dies wird zur korrekten Anzeige benötigt + * @return der Typ des Königreichs. + */ + public int getType() { + return this.type; + } + + /** + * Eine Burg aus dem Königreich entfernen + * @param castle die zu entfernende Burg + */ + public void removeCastle(Castle castle) { + this.castles.remove(castle); + } + + /** + * Gibt den Spieler zurück, der alle Burgen in dem Köngreich besitzt. + * Sollte es keinen Spieler geben, der alle Burgen besitzt, wird null zurückgegeben. + * @return der Besitzer oder null + */ + public Player getOwner() { + if(castles.isEmpty()) + return null; + + Player owner = castles.get(0).getOwner(); + for(Castle castle : castles) { + if(castle.getOwner() != owner) + return null; + } + + return owner; + } + + /** + * Gibt alle Burgen zurück, die in diesem Königreich liegen + * @return Liste von Burgen im Königreich + */ + public List getCastles() { + return this.castles; + } +}