From a9aabc26c4d4088b8ea1c1a4edfc194aa18efdcd Mon Sep 17 00:00:00 2001 From: Mo Date: Sat, 19 Nov 2016 16:31:17 +0300 Subject: [PATCH] add CC compute and stat to PowerPlay --- .../controllers/PowerPlayController.java | 70 +++++++++++++++++-- .../resources/lang/locale_en_US.properties | 3 + .../resources/lang/locale_ru_RU.properties | 3 + client/src/main/resources/view/powerplay.fxml | 20 +++++- .../trader/analysis/PowerPlayAnalyzator.java | 8 +-- core/src/main/java/ru/trader/core/Place.java | 16 +++++ .../src/main/java/ru/trader/core/Profile.java | 30 +++++++- .../java/ru/trader/powerplay/PPParser.java | 7 +- 8 files changed, 142 insertions(+), 15 deletions(-) diff --git a/client/src/main/java/ru/trader/controllers/PowerPlayController.java b/client/src/main/java/ru/trader/controllers/PowerPlayController.java index f7bb83f..8f6913e 100644 --- a/client/src/main/java/ru/trader/controllers/PowerPlayController.java +++ b/client/src/main/java/ru/trader/controllers/PowerPlayController.java @@ -17,6 +17,7 @@ import ru.trader.analysis.PowerPlayAnalyzator; import ru.trader.core.*; import ru.trader.model.*; import ru.trader.model.support.BindingsHelper; +import ru.trader.view.support.Localization; import ru.trader.view.support.PowerStateStringConverter; import ru.trader.view.support.PowerStringConverter; import ru.trader.view.support.ViewUtils; @@ -25,6 +26,7 @@ import ru.trader.view.support.autocomplete.CachedSuggestionProvider; import ru.trader.view.support.autocomplete.SystemsProvider; import java.util.Collection; +import java.util.Collections; import java.util.Optional; import java.util.stream.Collectors; @@ -67,6 +69,10 @@ public class PowerPlayController { private Label resultPopSumm; @FXML private Label detailPopSumm; + @FXML + private Label resultCCSumm; + @FXML + private Label detailCCSumm; private MarketModel world; private ProfileModel profile; @@ -173,11 +179,15 @@ public class PowerPlayController { }); tblDetail.setOnDragDetected(new StarSystemDragDetect(tblDetail)); NumberStringConverter converter = new NumberStringConverter("#,##0.##"); - result.addListener((InvalidationListener) i -> - resultPopSumm.setText(converter.toString(getPopulationSumm(result))) + result.addListener((InvalidationListener) i -> { + resultPopSumm.setText(converter.toString(getPopulationSumm(result))); + resultCCSumm.setText(getCCSummText(result)); + } ); - detail.addListener((InvalidationListener) i -> - detailPopSumm.setText(converter.toString(getPopulationSumm(detail))) + detail.addListener((InvalidationListener) i -> { + detailPopSumm.setText(converter.toString(getPopulationSumm(detail))); + detailCCSumm.setText(getCCSummText(detail)); + } ); } @@ -185,11 +195,46 @@ public class PowerPlayController { return collection.stream().mapToLong(ResultEntry::getPopulation).sum(); } + private String getCCSummText(Collection collection){ + String ccFormat = Localization.getString("powerplay.label.summcc"); + String pwCCFormat = Localization.getString("powerplay.label.cc"); + PowerStringConverter converter = new PowerStringConverter(); + long[] contestedCc = new long[POWER.values().length]; + long[] totalCc = new long[POWER.values().length]; + long contested = 0; + long summCc = 0; + for (ResultEntry entry : collection) { + long cc = entry.getCc(); + summCc += cc; + if (entry.getPower() == null || entry.getPowerState() == null) continue; + if (entry.getPowerState() != POWER_STATE.NONE){ + contested += cc; + if (entry.getPowerState() == POWER_STATE.CONTESTED){ + for (Place place : entry.getControllingSystems()){ + contestedCc[place.getPower().ordinal()] += cc; + } + } else { + totalCc[entry.getPower().ordinal()] += cc; + } + } + } + StringBuilder builder = new StringBuilder(); + builder.append(String.format(ccFormat, summCc, contested, summCc - contested)); + for (int i = 0; i < POWER.values().length; i++) { + if (totalCc[i] > 0 || contestedCc[i] > 0){ + builder.append("\n"); + builder.append(String.format(pwCCFormat, converter.toString(POWER.values()[i]), totalCc[i], contestedCc[i])); + } + } + return builder.toString(); + } + private void fillDetail(SystemModel detailSystem) { final Place starSystem = ModelFabric.get(detailSystem); detail.clear(); if (starSystem != null){ Collection controllings = analyzator.getControlling(starSystem); + controllings.add(new PowerPlayAnalyzator.IntersectData(starSystem)); detail.addAll(BindingsHelper.observableList(controllings, d -> new ResultEntry(d, starSystem))); } } @@ -210,6 +255,7 @@ public class PowerPlayController { result.clear(); if (starSystem != null){ Collection controllings = analyzator.getControlling(starSystem); + controllings.add(new PowerPlayAnalyzator.IntersectData(starSystem)); result.addAll(BindingsHelper.observableList(controllings,d -> new ResultEntry(d, starSystem))); } } @@ -366,6 +412,7 @@ public class PowerPlayController { private final ReadOnlyLongProperty population; private final ReadOnlyLongProperty upkeep; private final ReadOnlyLongProperty income; + private final ReadOnlyLongProperty cc; public ResultEntry(PowerPlayAnalyzator.IntersectData data) { this(data, null); @@ -383,7 +430,7 @@ public class PowerPlayController { population = new SimpleLongProperty(data.getStarSystem().getPopulation()); upkeep = new SimpleLongProperty(data.getStarSystem().getUpkeep()); income = new SimpleLongProperty(data.getStarSystem().getIncome()); - + cc = new SimpleLongProperty(data.getStarSystem().computeCC(ModelFabric.get(profile).getCCgroups())); } private String getControllingString(Collection controllings) { @@ -461,6 +508,11 @@ public class PowerPlayController { return intersectCount; } + private Collection getControllingSystems(){ + Place place = ModelFabric.get(starSystem); + return place != null ? place.getControllingSystems() : Collections.emptyList(); + } + public ReadOnlyStringProperty controllingProperty() { return controlling; } @@ -488,6 +540,14 @@ public class PowerPlayController { public ReadOnlyStringProperty nearStationsProperty() { return nearStations; } + + public long getCc() { + return cc.get(); + } + + public ReadOnlyLongProperty ccProperty() { + return cc; + } } private class StarSystemDragDetect implements EventHandler { diff --git a/client/src/main/resources/lang/locale_en_US.properties b/client/src/main/resources/lang/locale_en_US.properties index 4c94533..b532083 100644 --- a/client/src/main/resources/lang/locale_en_US.properties +++ b/client/src/main/resources/lang/locale_en_US.properties @@ -11,6 +11,7 @@ market.economic=Economy market.power=Power market.powerState=State market.population=Population +market.cc=CC #Item market.item=Commodity @@ -283,6 +284,8 @@ powerplay.label.controlling=Controlled systems: powerplay.label.power.systems=Systems of Power: powerplay.label.power.state=State: powerplay.label.populationSumm=Summ populations: +powerplay.label.cc=%s: %4d CC Contested: %4d CC +powerplay.label.summcc=Summ: %6d CC Contested: %6d CC Total: %6dCC powerplay.result.title=Analyze result powerplay.column.intersecting=Intersect powerplay.column.intersectCount=Intersect count diff --git a/client/src/main/resources/lang/locale_ru_RU.properties b/client/src/main/resources/lang/locale_ru_RU.properties index 92ba757..050e2f4 100644 --- a/client/src/main/resources/lang/locale_ru_RU.properties +++ b/client/src/main/resources/lang/locale_ru_RU.properties @@ -11,6 +11,7 @@ market.economic=\u042D\u043A\u043E\u043D\u043E\u043C\u0438\u043A\u0430 market.power=\u0421\u0438\u043B\u0430 market.powerState=\u0421\u0442\u0430\u0442\u0443\u0441 market.population=\u041D\u0430\u0441\u0435\u043B\u0435\u043D\u0438\u0435 +market.cc=\u041A\u041A #Item market.item=\u0422\u043E\u0432\u0430\u0440 @@ -283,6 +284,8 @@ powerplay.label.controlling=\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u043B\u04 powerplay.label.power.systems=C\u0438\u0441\u0442\u0435\u043C\u044B \u0441\u0438\u043B\u044B: powerplay.label.power.state=\u0421\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435: powerplay.label.populationSumm=\u0421\u0443\u043C\u043C\u0430 \u043D\u0430\u0441\u0435\u043B\u0435\u043D\u0438\u044F: +powerplay.label.cc=%s: %4d \u041A\u041A \u041E\u0441\u043F\u0430\u0440\u0438\u0432\u0430\u0435\u043C\u044B\u0445: %4d \u041A\u041A +powerplay.label.summcc=\u0421\u0443\u043C\u043C\u0430: %6d \u041A\u041A \u041E\u0441\u043F\u0430\u0440\u0438\u0432\u0430\u0435\u043C\u044B\u0445: %6d \u041A\u041A \u0418\u0442\u043E\u0433\u043E: %6d\u041A\u041A powerplay.result.title=\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u0430\u043D\u0430\u043B\u0438\u0437\u0430 powerplay.column.intersecting=\u041F\u0435\u0440\u0435\u0441\u0435\u043A\u0430\u0435\u0442\u0441\u044F \u0441 powerplay.column.intersectCount=\u041F\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043D\u0438\u0439 diff --git a/client/src/main/resources/view/powerplay.fxml b/client/src/main/resources/view/powerplay.fxml index fe38f68..beab677 100644 --- a/client/src/main/resources/view/powerplay.fxml +++ b/client/src/main/resources/view/powerplay.fxml @@ -122,6 +122,9 @@ + + + @@ -154,7 +157,12 @@ - + + + + + + @@ -182,6 +190,9 @@ + + + @@ -207,7 +218,12 @@ - + + + + + + diff --git a/core/src/main/java/ru/trader/analysis/PowerPlayAnalyzator.java b/core/src/main/java/ru/trader/analysis/PowerPlayAnalyzator.java index 3265a70..0b0c656 100644 --- a/core/src/main/java/ru/trader/analysis/PowerPlayAnalyzator.java +++ b/core/src/main/java/ru/trader/analysis/PowerPlayAnalyzator.java @@ -31,7 +31,7 @@ public class PowerPlayAnalyzator { } public Collection getControlling(Place starSystem){ - Stream candidates = market.get().stream().filter(p -> p.getFaction() != FACTION.NONE); + Stream candidates = market.get().stream().filter(Place::isPopulated); return getControlling(starSystem, candidates, Market.CONTROLLING_RADIUS).collect(Collectors.toList()); } @@ -40,17 +40,17 @@ public class PowerPlayAnalyzator { } public Collection getIntersects(Place starSystem, Collection starSystems){ - Stream candidates = market.get().stream().filter(p -> p.getFaction() != FACTION.NONE); + Stream candidates = market.get().stream().filter(Place::isPopulated); return getIntersects(starSystem, candidates, starSystems, Market.CONTROLLING_RADIUS).collect(Collectors.toList()); } public Collection getMaxIntersect(Collection starSystems){ - Stream candidates = market.get().stream().filter(p -> p.getFaction() != FACTION.NONE); + Stream candidates = market.get().stream().filter(Place::isPopulated); return getMaxIntersect(candidates, starSystems, Market.CONTROLLING_RADIUS).collect(Collectors.toList()); } public Collection getNear(Collection starSystems){ - Stream candidates = market.get().stream().filter(p -> p.getFaction() != FACTION.NONE); + Stream candidates = market.get().stream().filter(Place::isPopulated); return getNear(candidates, starSystems, Market.CONTROLLING_RADIUS, Market.CONTROLLING_RADIUS * 2).collect(Collectors.toList()); } diff --git a/core/src/main/java/ru/trader/core/Place.java b/core/src/main/java/ru/trader/core/Place.java index 601fbbd..1e28c6a 100644 --- a/core/src/main/java/ru/trader/core/Place.java +++ b/core/src/main/java/ru/trader/core/Place.java @@ -97,4 +97,20 @@ public interface Place extends Connectable { default Vendor asTransit(){ return new TransitVendor(this); } + + default boolean isPopulated(){ + return getPopulation() > 0; + } + + default long computeCC(long[] CCgroups){ + long population = getPopulation(); + if (population == 0) return 0; + for (int i = 0; i < CCgroups.length; i++) { + long minPop = CCgroups[i]; + if (population < minPop){ + return i+1; + } + } + return CCgroups.length+1; + } } diff --git a/core/src/main/java/ru/trader/core/Profile.java b/core/src/main/java/ru/trader/core/Profile.java index d94d715..ab99b4d 100644 --- a/core/src/main/java/ru/trader/core/Profile.java +++ b/core/src/main/java/ru/trader/core/Profile.java @@ -3,7 +3,7 @@ package ru.trader.core; import java.util.Properties; public class Profile { - public static enum PATH_PRIORITY {FAST, ECO} + public enum PATH_PRIORITY {FAST, ECO} private String name; private double balance; @@ -25,6 +25,7 @@ public class Profile { private double rechargeTime; private double fuelPrice; private PATH_PRIORITY pathPriority; + private long[] CCgroups; public Profile(Ship ship) { this.ship = ship; @@ -41,6 +42,7 @@ public class Profile { jumpTime = 32; rechargeTime = 12; pathPriority = PATH_PRIORITY.FAST; + CCgroups = new long[]{0,0,0,3_000,30_000,300_000,3_000_000,30_000_000,300_000_000,3_000_000_000L}; } protected Profile(Profile profile){ @@ -63,6 +65,7 @@ public class Profile { this.system = profile.system; this.station = profile.station; this.ship = Ship.clone(profile.ship); + this.CCgroups = profile.CCgroups; } public String getName() { @@ -217,6 +220,14 @@ public class Profile { this.pathPriority = pathPriority; } + public long[] getCCgroups() { + return CCgroups; + } + + public void setCCgroups(long[] CCgroups) { + this.CCgroups = CCgroups; + } + public static Profile readFrom(Properties values, Market market){ Ship ship = Ship.readFrom(values); Profile profile = new Profile(ship); @@ -236,7 +247,7 @@ public class Profile { profile.setSystem(null); profile.setStation(null); } - profile.setDocked(Boolean.valueOf(values.getProperty("profile.docked","false"))); + profile.setDocked(Boolean.valueOf(values.getProperty("profile.docked", "false"))); profile.setJumps(Integer.valueOf(values.getProperty("profile.jumps", "3"))); profile.setLands(Integer.valueOf(values.getProperty("profile.lands", "4"))); profile.setPathPriority(PATH_PRIORITY.valueOf(values.getProperty("profile.search.priority", "FAST"))); @@ -249,6 +260,15 @@ public class Profile { profile.setTakeoffTime(Double.valueOf(values.getProperty("profile.search.times.takeoff", "40"))); profile.setJumpTime(Double.valueOf(values.getProperty("profile.search.times.jump", "32"))); profile.setRechargeTime(Double.valueOf(values.getProperty("profile.search.times.recharge", "12"))); + v = values.getProperty("profile.powerplay.cc", null); + if (v != null){ + String[] strings = v.split(","); + long[] cc = new long[strings.length]; + for (int i = 0; i < strings.length; i++) { + cc[i] = Long.valueOf(strings[i]); + } + profile.setCCgroups(cc); + } return profile; } @@ -270,6 +290,12 @@ public class Profile { values.setProperty("profile.search.times.takeoff", String.valueOf(takeoffTime)); values.setProperty("profile.search.times.jump", String.valueOf(jumpTime)); values.setProperty("profile.search.times.recharge", String.valueOf(rechargeTime)); + StringBuilder builder = new StringBuilder(); + for (long cc : CCgroups) { + if (builder.length() > 0) builder.append(","); + builder.append(cc); + } + values.setProperty("profile.powerplay.cc", builder.toString()); ship.writeTo(values); } diff --git a/utils/src/main/java/ru/trader/powerplay/PPParser.java b/utils/src/main/java/ru/trader/powerplay/PPParser.java index d9d7920..988fdcb 100644 --- a/utils/src/main/java/ru/trader/powerplay/PPParser.java +++ b/utils/src/main/java/ru/trader/powerplay/PPParser.java @@ -4,7 +4,10 @@ import au.com.bytecode.opencsv.CSVParser; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import ru.trader.core.*; +import ru.trader.core.Market; +import ru.trader.core.POWER; +import ru.trader.core.POWER_STATE; +import ru.trader.core.Place; import java.io.BufferedReader; import java.io.File; @@ -165,7 +168,7 @@ public class PPParser { private void updatePowerState(){ if (controllingSystems.isEmpty()) return; for (Place starSystem : market.get()) { - if (starSystem.getFaction() == FACTION.NONE) continue; + if (!starSystem.isPopulated()) continue; if (starSystem.getPowerState() != POWER_STATE.HEADQUARTERS){ starSystem.setPower(POWER.NONE, POWER_STATE.NONE); }