Added research, removed old code

This commit is contained in:
Samy Avrillon 2024-07-07 03:47:04 +02:00
parent a08c6e1c64
commit f9bc9e4fa5
Signed by: Mysaa
GPG Key ID: 0220AC4A3D6A328B
20 changed files with 304 additions and 1219 deletions

View File

@ -4,87 +4,21 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.json.JSONObject; import org.json.JSONObject;
import com.bernard.greposimu.engine.Registerar;
import com.bernard.greposimu.engine.json.MapJsonDeserializer;
import com.bernard.greposimu.model.Dieu;
import com.bernard.greposimu.model.Heros;
import com.bernard.greposimu.model.OffDefStats;
import com.bernard.greposimu.model.game.GameConfig; import com.bernard.greposimu.model.game.GameConfig;
import com.bernard.greposimu.model.game.God;
import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.units.FightType;
import com.bernard.greposimu.model.game.units.NavalUnit;
import com.bernard.greposimu.model.game.units.TerrestrialUnit;
import com.bernard.greposimu.model.game.units.TransportUnit;
import com.bernard.greposimu.model.game.units.Unit;
import com.bernard.greposimu.model.jsongame.GameData;
import com.bernard.greposimu.model.jsongame.Power;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.StreamReadFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class GrepoSimu { public class GrepoSimu {
public static GameData readGameData() throws IOException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try (InputStream is = classLoader.getResourceAsStream("gamedata.json")) {
if (is == null) return null;
try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr)) {
// Reading the file
String json = reader.lines().collect(Collectors.joining(System.lineSeparator()));
// De-serialize to an object
JsonFactory jsonFactory = JsonFactory.builder()
.enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION)
.build();
SimpleModule module = new SimpleModule();
module.addDeserializer(Map.class, new MapJsonDeserializer());
ObjectMapper mapper = new ObjectMapper(jsonFactory);
mapper.registerModule(module);
GameData data = mapper.readValue(json, GameData.class);
// Adapting power map
Map<String,Power> pmap = new HashMap<>();
for(String id : data.powers.keySet()) {
Set<String> types = data.powers.get(id).getTypes();
if(types.isEmpty()) {
pmap.put(id, new Power(data.powers.get(id)));
} else {
for(String type : types) {
pmap.put(id+"."+type, new Power(data.powers.get(id), type));
}
}
}
data.powers = pmap;
System.out.println(data.powers.get("effort_of_the_huntress"));
return data;
}
}
}
public static GameConfig makeGameData() throws IOException { public static GameConfig makeGameData() throws IOException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader(); ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try (InputStream is = classLoader.getResourceAsStream("gamedata.json")) { try (InputStream is = classLoader.getResourceAsStream("gamedata.json")) {
if (is == null) return null; if (is == null) return null;
try (InputStreamReader isr = new InputStreamReader(is); try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr)) { BufferedReader reader = new BufferedReader(isr)) {
// Reading the file // Reading the file
String json = reader.lines().collect(Collectors.joining(System.lineSeparator())); String json = reader.lines().collect(Collectors.joining(System.lineSeparator()));
@ -94,57 +28,4 @@ public class GrepoSimu {
} }
} }
} }
public static void main(String[] args) throws IOException {
System.out.println(makeGameData());
//for(int i=0;i<26;i++)
// System.out.println(i+"->"+Buildings.wallBonus(i));
}
public static void mainZ(String[] args) {
Registerar.regiter();
System.out.println(Registerar.unites.size());
OffDefStats scoring = new OffDefStats(0, 0, 0, 1.0, 0,0,0,0);
for(Heros h : withNull(Registerar.heros)) {
if(h!= null && h.getNom()!="Agamemnon")continue;
for(int l = 1;l<=20&&h!=null;l+=10-(l%10)) {
for(Dieu d : withNull(Arrays.asList(Dieu.values()))) {
//System.out.println("Héros: "+((c.h==null)?"aucun":("%s (lvl %d)".formatted(h.getNom(),l)))+" - Dieu: "+((d==null)?"aucun":d.getNom()));
//up.print(h, l, 1000);
}
}
}
}
public static final <T> Iterable<T> withNull(Iterable<T> itrble) {
return (Iterable<T>) new Iterable<T>() {
@Override
public Iterator<T> iterator() {
Iterator<T> it = itrble.iterator();
return new Iterator<T>() {
boolean pastNull = false;
@Override
public boolean hasNext() {
return !pastNull || it.hasNext();
}
@Override
public T next() {
if(pastNull)
return it.next();
else {
pastNull = true;
return null;
}
}
};
};
};
}
} }

View File

@ -1,15 +1,19 @@
package com.bernard.greposimu; package com.bernard.greposimu;
import java.io.IOException;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.bernard.greposimu.engine.Registerar; import com.bernard.greposimu.model.game.GameConfig;
@SpringBootApplication @SpringBootApplication
public class GrepoSimuApplication { public class GrepoSimuApplication {
public static void main(String[] args) { public static GameConfig GREPOLIS_GC;
Registerar.regiter();
public static void main(String[] args) throws IOException {
GREPOLIS_GC = GrepoSimu.makeGameData();
SpringApplication.run(GrepoSimuApplication.class, args); SpringApplication.run(GrepoSimuApplication.class, args);
} }

View File

@ -1,14 +0,0 @@
/*package com.bernard.greposimu;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(GrepoSimuApplication.class);
}
}
*/

View File

@ -0,0 +1,19 @@
package com.bernard.greposimu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.bernard.greposimu.GrepoSimuApplication;
@Controller
public class GameDataController {
@GetMapping("/gamedata")
public String gamedata(Model model) {
System.out.println("Reading game data");
model.addAttribute("content",GrepoSimuApplication.GREPOLIS_GC);
return "debug";
}
}

View File

@ -1,396 +0,0 @@
package com.bernard.greposimu.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.bernard.greposimu.GrepoSimu;
import com.bernard.greposimu.Utils;
import com.bernard.greposimu.engine.Optimizer;
import com.bernard.greposimu.engine.Optimizer.UnitesProportions;
import com.bernard.greposimu.engine.Registerar;
import com.bernard.greposimu.engine.game.Fight;
import com.bernard.greposimu.model.DefContext;
import com.bernard.greposimu.model.Dieu;
import com.bernard.greposimu.model.FightStats;
import com.bernard.greposimu.model.Heros;
import com.bernard.greposimu.model.OffDefStats;
import com.bernard.greposimu.model.Unite;
import com.bernard.greposimu.model.game.GameConfig;
import com.bernard.greposimu.model.game.units.Unit;
import com.bernard.greposimu.model.jsongame.GameData;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@Controller
public class GrepoSimuController {
@GetMapping("/gamedata")
public String gamedata(Model model) {
System.out.println("Reading game data");
GameData data;
try {
data = GrepoSimu.readGameData();
model.addAttribute("content",data.toString());
} catch (IOException e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
model.addAttribute("content",writer.toString());
}
return "debug";
}
@GetMapping("/simulator")
public String simulator(Model model) throws IOException {
GameData data = GrepoSimu.readGameData();
model.addAttribute("heroes", data.heroes.values());
model.addAttribute("defUnits", Fight.relevantDefUnits(GrepoSimu.makeGameData()));
model.addAttribute("defCounsellors",Fight.relevantDefCounsellors(data));
model.addAttribute("defResearches",Fight.relevantDefResearch(data));
model.addAttribute("defPowers",Fight.relevantDefPowers(data));
model.addAttribute("ctx",new DefSimulatorParams());
return "simulator";
}
@PostMapping("/simulate")
@GetMapping("/simulate")
public String simulate(@ModelAttribute DefSimulatorParams defParams, Model model) throws IOException {
if(defParams == null)
defParams = new DefSimulatorParams();
GameConfig gc = GrepoSimu.makeGameData();
DefContext defCtx = defParams.asDefContext(gc);
FightStats cityStats = Fight.computeDefStats(gc,defCtx);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
model.addAttribute("content",cityStats.toString()+"\n"+mapper.writerWithDefaultPrettyPrinter().writeValueAsString(defCtx));
return "debug";
}
@GetMapping("/optimizer")
public String greeting(Model model) {
model.addAttribute("heros", Registerar.heros);
// Liste des unités
Map<String,List<Unite>> godUnites = Registerar.unites.stream()
.filter(u -> u.getDieu() != null)
.collect(Collectors.groupingBy(u -> u.getDieu().getPname()));
List<Unite> otherUnites = Registerar.unites.stream()
.filter(u -> u.getDieu() == null)
.collect(Collectors.toList());
System.out.println(godUnites);
model.addAttribute("otherunites", otherUnites);
model.addAttribute("godunites", godUnites);
model.addAttribute("dieux", Arrays.stream(Dieu.values()).map(Dieu::getPname).collect(Collectors.toList()));
model.addAttribute("optinput", new OptimizerInput());
return "optimizer";
}
@PostMapping("/optimizer")
public String greetingSubmit(@ModelAttribute OptimizerInput optinput, Model model) {
Optimizer.Contexte ctx = new Optimizer.Contexte();
ctx.h = Registerar.getHeros(optinput.heros);
ctx.level = optinput.herosLvl;
ctx.scoring = optinput.getOffDefStats();
ctx.d = null;
Set<Unite> unites = Registerar.unites.stream().filter(u -> optinput.unites.get(u.getPname())).collect(Collectors.toSet());
Map<String,OptimizerOutput> outputs = new HashMap<>();
outputs.put("none", new OptimizerOutput(Optimizer.optimize(ctx,unites), ctx.h, ctx.level, optinput.population));
for(Dieu d : Dieu.values()) {
ctx.d = d;
outputs.put(d.getPname(), new OptimizerOutput(Optimizer.optimize(ctx,unites), ctx.h, ctx.level, optinput.population));
}
model.addAttribute("dieux", Arrays.stream(Dieu.values()).map(Dieu::getPname).collect(Collectors.toList()));
model.addAttribute("outputs", outputs);
model.addAttribute("requestedPop",optinput.population);
return "optimizerResult";
}
public static class DefSimulatorParams {
// unitID -> number of units
public Map<String, Integer> units = new HashMap<>();
public String hero = "";
public int heroLevel = 0;
public int wallLevel = 0;
public boolean hasTower = false;
public Set<String> powers = new HashSet<>();
public Set<String> researches = new HashSet<>();
public Set<String> counsellors = new HashSet<>();
public boolean nightBonus = false;
public DefContext asDefContext(GameConfig gc) {
Map<Unit,Integer> unitsU = new HashMap<>(units.size());
for(String u : units.keySet())
unitsU.put(gc.getUnit(u), units.get(u));
return new DefContext(
unitsU,
gc.getHero(hero),
heroLevel,
wallLevel,
hasTower,
powers,
researches,
counsellors,
nightBonus
);
}
public Map<String, Integer> getUnits() {
return units;
}
public void setUnits(Map<String, Integer> units) {
this.units = units;
}
public String getHero() {
return hero;
}
public void setHero(String hero) {
this.hero = hero;
}
public int getHeroLevel() {
return heroLevel;
}
public void setHeroLevel(int heroLevel) {
this.heroLevel = heroLevel;
}
public int getWallLevel() {
return wallLevel;
}
public void setWallLevel(int wallLevel) {
this.wallLevel = wallLevel;
}
public boolean isHasTower() {
return hasTower;
}
public void setHasTower(boolean hasTower) {
this.hasTower = hasTower;
}
public Set<String> getPowers() {
return powers;
}
public Map<String,Boolean> getPowersAsMap() {
return Utils.setToMap(powers);
}
public Map<String,Boolean> getResearchesAsMap() {
return Utils.setToMap(researches);
}
public Map<String,Boolean> getCounsellorsAsMap() {
return Utils.setToMap(counsellors);
}
public boolean isNightBonus() {
return nightBonus;
}
public void setNightBonus(boolean nightBonus) {
this.nightBonus = nightBonus;
}
}
public static class OptimizerInput {
public String heros = Registerar.heros.stream().map(Heros::getPname).min(Comparator.comparing(Function.identity())).get();
public int herosLvl = 1;
public double att_hack_proportion = 0.0;
public double att_pierce_proportion = 0.0;
public double att_distance_proportion = 0.0;
public double ship_attack_proportion = 0.0;
public double def_hack_proportion = 1.0;
public double def_pierce_proportion = 1.0;
public double def_distance_proportion = 1.0;
public double ship_defense_proportion = 1.0;
public int population = 1000;
public Map<String,Boolean> unites = Registerar.unites.stream().collect(Collectors.toMap(Unite::getPname, u -> true));
public String getHeros() {
return heros;
}
public void setHeros(String heros) {
this.heros = heros;
}
public int getHerosLvl() {
return herosLvl;
}
public void setHerosLvl(int herosLvl) {
this.herosLvl = herosLvl;
}
public double getAtt_hack_proportion() {
return att_hack_proportion;
}
public void setAtt_hack_proportion(double att_hack_proportion) {
this.att_hack_proportion = att_hack_proportion;
}
public double getAtt_pierce_proportion() {
return att_pierce_proportion;
}
public void setAtt_pierce_proportion(double att_pierce_proportion) {
this.att_pierce_proportion = att_pierce_proportion;
}
public double getAtt_distance_proportion() {
return att_distance_proportion;
}
public void setAtt_distance_proportion(double att_distance_proportion) {
this.att_distance_proportion = att_distance_proportion;
}
public double getShip_attack_proportion() {
return ship_attack_proportion;
}
public void setShip_attack_proportion(double ship_attack_proportion) {
this.ship_attack_proportion = ship_attack_proportion;
}
public double getDef_hack_proportion() {
return def_hack_proportion;
}
public void setDef_hack_proportion(double def_hack_proportion) {
this.def_hack_proportion = def_hack_proportion;
}
public double getDef_pierce_proportion() {
return def_pierce_proportion;
}
public void setDef_pierce_proportion(double def_pierce_proportion) {
this.def_pierce_proportion = def_pierce_proportion;
}
public double getDef_distance_proportion() {
return def_distance_proportion;
}
public void setDef_distance_proportion(double def_distance_proportion) {
this.def_distance_proportion = def_distance_proportion;
}
public double getShip_defense_proportion() {
return ship_defense_proportion;
}
public void setShip_defense_proportion(double ship_defense_proportion) {
this.ship_defense_proportion = ship_defense_proportion;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
public Map<String, Boolean> getUnites() {
return unites;
}
public void setUnites(Map<String, Boolean> unites) {
this.unites = unites;
}
public OffDefStats getOffDefStats() {
return new OffDefStats(att_hack_proportion, att_pierce_proportion, att_distance_proportion, ship_attack_proportion, def_hack_proportion, def_pierce_proportion, def_distance_proportion, ship_defense_proportion);
}
@Override
public String toString() {
return "OptimizerInput [heros=" + heros + ", herosLvl=" + herosLvl + ", att_hack_proportion="
+ att_hack_proportion + ", att_pierce_proportion=" + att_pierce_proportion
+ ", att_distance_proportion=" + att_distance_proportion + ", ship_attack_proportion="
+ ship_attack_proportion + ", def_hack_proportion=" + def_hack_proportion
+ ", def_pierce_proportion=" + def_pierce_proportion + ", def_distance_proportion="
+ def_distance_proportion + ", ship_defense_proportion=" + ship_defense_proportion + ", population="
+ population + ", unites=" + unites + "]";
}
}
public static class OptimizerOutput {
OffDefStats total;
int totalpop;
List<Unite> unites;
Map<Unite,Integer> ucounts;
public OptimizerOutput(UnitesProportions data, Heros h, int level, int pop) {
this.ucounts = new HashMap<>(data.getData().size());
for(Unite u : data.getData().keySet())
this.ucounts.put(u, (int) Math.floor((data.getData().get(u) * pop) / u.getPopulation()));
this.unites = Registerar.unites.stream().filter(u -> ucounts.containsKey(u)).toList();
this.totalpop = this.ucounts.entrySet().stream().mapToInt(e -> e.getKey().getPopulation() * e.getValue()).sum();
this.total = this.ucounts.entrySet().stream()
.map(e -> ((h==null)?e.getKey().getStats():h.applyToUnit(e.getKey(), level)).times(e.getValue()))
.reduce(OffDefStats.zero,(a,b) -> a.plus(b));
}
public OffDefStats getTotal() {
return total;
}
public int getTotalpop() {
return totalpop;
}
public Map<Unite, Integer> getUcounts() {
return ucounts;
}
public List<Unite> getUnites() {
return unites;
}
}
}

View File

@ -0,0 +1,157 @@
package com.bernard.greposimu.controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.bernard.greposimu.GrepoSimuApplication;
import com.bernard.greposimu.Utils;
import com.bernard.greposimu.engine.game.Fight;
import com.bernard.greposimu.model.DefContext;
import com.bernard.greposimu.model.FightStats;
import com.bernard.greposimu.model.game.GameConfig;
import com.bernard.greposimu.model.game.units.Unit;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@Controller
public class SimulatorController {
@GetMapping("/simulator")
public String simulator(Model model) throws IOException {
GameConfig gc = GrepoSimuApplication.GREPOLIS_GC;
model.addAttribute("heroes", gc.getHeroes());
model.addAttribute("defUnits", Fight.relevantDefUnits(gc));
model.addAttribute("defCounsellors",Fight.relevantDefCounsellors(gc));
model.addAttribute("defResearches",Fight.relevantDefResearch(gc));
model.addAttribute("defPowers",Fight.relevantDefPowers(gc));
model.addAttribute("ctx",new DefSimulatorParams());
return "simulator";
}
@PostMapping("/simulate")
@GetMapping("/simulate")
public String simulate(@ModelAttribute DefSimulatorParams defParams, Model model) throws IOException {
if(defParams == null)
defParams = new DefSimulatorParams();
GameConfig gc = GrepoSimuApplication.GREPOLIS_GC;
DefContext defCtx = defParams.asDefContext(gc);
FightStats cityStats = Fight.computeDefStats(gc,defCtx);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
model.addAttribute("content",cityStats.toString()+"\n"+mapper.writerWithDefaultPrettyPrinter().writeValueAsString(defCtx));
return "debug";
}
public static class DefSimulatorParams {
// unitID -> number of units
public Map<String, Integer> units = new HashMap<>();
public String hero = "";
public int heroLevel = 0;
public int wallLevel = 0;
public boolean hasTower = false;
public Set<String> powers = new HashSet<>();
public Set<String> researches = new HashSet<>();
public Set<String> counsellors = new HashSet<>();
public boolean nightBonus = false;
public DefContext asDefContext(GameConfig gc) {
Map<Unit,Integer> unitsU = new HashMap<>(units.size());
for(String u : units.keySet())
unitsU.put(gc.getUnit(u), units.get(u));
return new DefContext(
unitsU,
gc.getHero(hero),
heroLevel,
wallLevel,
hasTower,
powers,
researches,
counsellors,
nightBonus
);
}
public Map<String, Integer> getUnits() {
return units;
}
public void setUnits(Map<String, Integer> units) {
this.units = units;
}
public String getHero() {
return hero;
}
public void setHero(String hero) {
this.hero = hero;
}
public int getHeroLevel() {
return heroLevel;
}
public void setHeroLevel(int heroLevel) {
this.heroLevel = heroLevel;
}
public int getWallLevel() {
return wallLevel;
}
public void setWallLevel(int wallLevel) {
this.wallLevel = wallLevel;
}
public boolean isHasTower() {
return hasTower;
}
public void setHasTower(boolean hasTower) {
this.hasTower = hasTower;
}
public Set<String> getPowers() {
return powers;
}
public Map<String,Boolean> getPowersAsMap() {
return Utils.setToMap(powers);
}
public Map<String,Boolean> getResearchesAsMap() {
return Utils.setToMap(researches);
}
public Map<String,Boolean> getCounsellorsAsMap() {
return Utils.setToMap(counsellors);
}
public boolean isNightBonus() {
return nightBonus;
}
public void setNightBonus(boolean nightBonus) {
this.nightBonus = nightBonus;
}
}
}

View File

@ -1,116 +0,0 @@
package com.bernard.greposimu.engine;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.ojalgo.optimisation.Expression;
import org.ojalgo.optimisation.ExpressionsBasedModel;
import org.ojalgo.optimisation.Optimisation;
import org.ojalgo.optimisation.Optimisation.Result;
import org.ojalgo.optimisation.Variable;
import com.bernard.greposimu.model.Dieu;
import com.bernard.greposimu.model.Heros;
import com.bernard.greposimu.model.OffDefStats;
import com.bernard.greposimu.model.Unite;
public class Optimizer {
public static UnitesProportions optimize(Contexte c,Set<Unite> uniteList) {
// Computing the stats of the unités in this context
Map<Unite,OffDefStats> stats = uniteList.stream()
.filter(u -> u.getDieu() == null || u.getDieu().equals(c.d))
.collect(Collectors.toMap(
Function.identity(),
u -> (OffDefStats)((c.h==null)?u.getStats():c.h.applyToUnit(u, c.level)).div(u.getPopulation())
));
// Clean list of unités
List<Unite> unites = stats.keySet().stream().sorted((u,v) -> u.getNom().compareTo(v.getNom())).toList();
// Création du modèle
ExpressionsBasedModel model = new ExpressionsBasedModel();
// Variable à optimiser
Variable y = model.addVariable("y").weight(1.0);
// Création des variables correspondant aux proportions, elles ne sont pas «optimisées» (weight 0.0) et sont positives
List<Variable> varz = new ArrayList<>(unites.size());
for(Unite u : unites) {
Variable xi = model.addVariable(u.getNom()).weight(0.0);
model.addExpression().lower(0.0).set(xi, 1.0); // 0 <= x_i
varz.add(xi);
}
// Les proportions doivent être maximalement 1 (en pratique, 1, parce que croissante)
Expression esum = model.addExpression().upper(1.0);
// y doit se comparer à chaque somme suivant ce que le scoring précise
Expression eAttqCont = model.addExpression().lower(0.0).set(y, -c.scoring.getAttqCont()); // y <= sum(a_1_i * x_i)
Expression eAttqBlan = model.addExpression().lower(0.0).set(y, -c.scoring.getAttqBlan()); // y <= sum(a_1_i * x_i)
Expression eAttqJet = model.addExpression().lower(0.0).set(y, -c.scoring.getAttqJet() ); // y <= sum(a_1_i * x_i)
Expression eAttqNav = model.addExpression().lower(0.0).set(y, -c.scoring.getAttqNav() ); // y <= sum(a_1_i * x_i)
Expression eDefCont = model.addExpression().lower(0.0).set(y, -c.scoring.getDefCont() ); // y <= sum(a_1_i * x_i)
Expression eDefBlan = model.addExpression().lower(0.0).set(y, -c.scoring.getDefBlan() ); // y <= sum(a_1_i * x_i)
Expression eDefJet = model.addExpression().lower(0.0).set(y, -c.scoring.getDefJet() ); // y <= sum(a_1_i * x_i)
Expression eDefNav = model.addExpression().lower(0.0).set(y, -c.scoring.getDefNav() ); // y <= sum(a_1_i * x_i)
for(int i=0;i<varz.size();i++) {
esum.set(varz.get(i), 1.0);
eAttqCont.set(varz.get(i), stats.get(unites.get(i)).getAttqCont());
eAttqBlan.set(varz.get(i), stats.get(unites.get(i)).getAttqBlan());
eAttqJet .set(varz.get(i), stats.get(unites.get(i)).getAttqJet());
eAttqNav .set(varz.get(i), stats.get(unites.get(i)).getAttqNav());
eDefCont .set(varz.get(i), stats.get(unites.get(i)).getDefCont());
eDefBlan .set(varz.get(i), stats.get(unites.get(i)).getDefBlan());
eDefJet .set(varz.get(i), stats.get(unites.get(i)).getDefJet());
eDefNav .set(varz.get(i), stats.get(unites.get(i)).getDefNav());
}
Result r = model.maximise(); // maximize y
return new UnitesProportions(unites, r);
}
public static class UnitesProportions {
Map<Unite,Double> data;
public UnitesProportions(List<Unite> unites, Optimisation.Result result) {
this.data = new HashMap<>();
for(int i=0;i<unites.size();i++) {
double val = result.doubleValue(1+i);
if(val>=0.0001) {
this.data.put(unites.get(i), val);
}
}
}
public void print(Heros h, int level, int pop) {
Map<Unite,Integer> ucounts = new HashMap<>(data.size());
for(Unite u : data.keySet())
ucounts.put(u, (int) Math.floor((data.get(u) * pop) / u.getPopulation()));
int totalpop = ucounts.entrySet().stream().mapToInt(e -> e.getKey().getPopulation() * e.getValue()).sum();
OffDefStats t = ucounts.entrySet().stream()
.map(e -> h.applyToUnit(e.getKey(), level).times(e.getValue()))
.reduce(OffDefStats.zero,(a,b) -> a.plus(b));
System.out.println("Population totale de %d".formatted(totalpop));
for(Unite u : data.keySet())
System.out.println("|-- %d %s (%.1f%% de la population)".formatted(ucounts.get(u),u.getNom(),data.get(u)*100));
System.out.println("--- Attaque (%d,%d,%d,%d) Défense (%d,%d,%d,%d)".formatted(
(int)t.getAttqCont(),(int)t.getAttqBlan(),(int)t.getAttqJet(),(int)t.getAttqNav(),(int)t.getDefCont(),(int)t.getDefBlan(),(int)t.getDefJet(),(int)t.getDefNav()
));
}
public Map<Unite, Double> getData() {
return data;
}
}
public static class Contexte {
public Dieu d;
public Heros h;
public int level;
public OffDefStats scoring;
}
}

View File

@ -1,114 +0,0 @@
package com.bernard.greposimu.engine;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.bernard.greposimu.model.Dieu;
import com.bernard.greposimu.model.Heros;
import com.bernard.greposimu.model.OffDefStats;
import com.bernard.greposimu.model.Unite;
public class Registerar {
public static List<Unite> unites;
public static List<Heros> heros;
public static Heros getHeros(String pname) {
return heros.stream().filter(h -> h.getPname().equals(pname)).findAny().orElse(null);
}
public static List<Unite> getUnites(Dieu dieu) {
return unites.stream().filter(u -> u.getDieu() == null || u.getDieu().equals(dieu)).collect(Collectors.toList());
}
public static void addHeros(
String nom,
String pname,
Set<String> appliedToNames,
boolean appTerrestre,
boolean appNavale,
boolean appMythique,
double attqContZero,
double attqContPlus,
double attqBlanZero,
double attqBlanPlus,
double attqJetZero,
double attqJetPlus,
double attqNavZero,
double attqNavPlus,
double defContZero,
double defContPlus,
double defBlanZero,
double defBlanPlus,
double defJetZero,
double defJetPlus,
double defNavZero,
double defNavPlus) {
heros.add(new Heros(
nom, pname, appliedToNames, appTerrestre, appNavale, appMythique,
new OffDefStats(attqContZero, attqBlanZero, attqJetZero, attqNavZero, defContZero, defBlanZero, defJetZero, defNavZero),
new OffDefStats(attqContPlus, attqBlanPlus, attqJetPlus, attqNavPlus, defContPlus, defBlanPlus, defJetPlus, defNavPlus)
));
}
public static void addUnite(String nom, String pname, int population, int speed, int butin, double attqCont, double attqBlan, double attqJet, double attqNav, double defCont, double defBlan,
double defJet, double defNav, boolean terrestre, boolean navale,
boolean mythique, Dieu dieu) {
unites.add(new Unite(
nom, pname, population, speed, butin,
new OffDefStats(attqCont, attqBlan, attqJet, attqNav, defCont, defBlan, defJet, defNav),
terrestre, navale, mythique, dieu
));
}
public static void regiter() {
unites = new ArrayList<Unite>();
addUnite("Combattant à l'épée","sword",1,8,16,5.0,0.0,0.0,0.0,14.0,8.0,30.0,0.0,true,false,false,null);
addUnite("Frondeur","slinger",1,14,8,0.0,0.0,23.0,0.0,7.0,8.0,2.0,0.0,true,false,false,null);
addUnite("Archer","archer",1,12,24,0.0,0.0,8.0,0.0,7.0,25.0,13.0,0.0,true,false,false,null);
addUnite("Hoplite","hoplite",1,6,8,0.0,16.0,0.0,0.0,18.0,12.0,7.0,0.0,true,false,false,null);
addUnite("Cavalier","rider",3,22,72,60.0,0.0,0.0,0.0,18.0,1.0,24.0,0.0,true,false,false,null);
addUnite("Char","chariot",4,18,64,0.0,56.0,0.0,0.0,76.0,16.0,56.0,0.0,true,false,false,null);
addUnite("Catapulte","catapult",15,2,400,0.0,0.0,100.0,0.0,30.0,30.0,30.0,0.0,true,false,false,null);
addUnite("Envoyé divin","godsent",3,16,5,45.0,0.0,0.0,0.0,40.0,40.0,40.0,0.0,true,false,true,null);
addUnite("Centaure","centaur",12,18,200,0.0,0.0,134.0,0.0,195.0,585.0,80.0,0.0,true,false,true,Dieu.ATHENA);
addUnite("Cerbère","cerberus",30,4,240,210.0,0.0,0.0,0.0,825.0,300.0,1575.0,0.0,true,false,true,Dieu.HADES);
addUnite("Cyclope","zyklop",40,8,320,0.0,0.0,1035.0,0.0,1050.0,10.0,1450.0,0.0,true,false,true,Dieu.POSEIDON);
addUnite("Érinye","fury",55,10,440,0.0,0.0,1700.0,0.0,460.0,460.0,595.0,0.0,true,false,true,Dieu.HADES);
addUnite("Méduse","medusa",18,6,400,0.0,425.0,0.0,0.0,480.0,345.0,290.0,0.0,true,false,true,Dieu.HERA);
addUnite("Minotaure","minotaur",30,10,480,650.0,0.0,0.0,0.0,750.0,330.0,640.0,0.0,true,false,true,Dieu.ZEUS);
addUnite("Sanglier","calydonian_boar",20,16,240,0.0,180.0,0.0,0.0,700.0,700.0,100.0,0.0,true,false,true,Dieu.ARTEMIS);
addUnite("Satyre","satyr",16,136,335,0.0,385.0,0.0,0.0,55.0,105.0,170.0,0.0,true,false,true,Dieu.APHRODITE);
addUnite("Sparte","spartoi",10,16,275,205.0,0.0,0.0,0.0,100.0,100.0,150.0,0.0,true,false,true,Dieu.ARES);
addUnite("Harpie","harpy",14,28,340,295.0,0.0,0.0,0.0,105.0,70.0,1.0,0.0,true,false,true,Dieu.HERA);
addUnite("Manticore","manticore",45,22,360,0.0,1010.0,0.0,0.0,170.0,225.0,505.0,0.0,true,false,true,Dieu.ZEUS);
addUnite("Pégase","pegasus",20,35,160,0.0,100.0,0.0,0.0,750.0,275.0,275.0,0.0,true,false,true,Dieu.ATHENA);
addUnite("Griffon","griffin",35,18,350,900.0,0.0,0.0,0.0,320.0,330.0,100.0,0.0,true,false,true,Dieu.ARTEMIS);
addUnite("Ladon","ladon",85,40,1000,0.0,0.0,1195.0,0.0,478.0,390.0,420.0,0.0,true,false,true,Dieu.ARES);
addUnite("Birème","bireme",8,15,0,0.0,0.0,0.0,24.0,0.0,0.0,0.0,160.0,false,true,false,null);
addUnite("Bateau-feu","attack_ship",10,13,0,0.0,0.0,0.0,200.0,0.0,0.0,0.0,60.0,false,true,false,null);
addUnite("Trière","trireme",16,15,0,0.0,0.0,0.0,250.0,0.0,0.0,0.0,250.0,false,true,false,null);
addUnite("Hydre","sea_monster",50,8,0,0.0,0.0,0.0,1310.0,0.0,0.0,0.0,1400.0,false,false,true,Dieu.POSEIDON);
addUnite("Sirène","siren",16,22,0,0.0,0.0,0.0,180.0,0.0,0.0,0.0,170.0,false,false,true,Dieu.APHRODITE);
//addUnite("Ladon (max)","ladon",85000,40,1000,0.0,0.0,2988.0,0.0,478.0,390.0,420.0,0.0,true,false,true,Dieu.ARES);
heros = new ArrayList<Heros>();
addHeros("Agamemnon","agamemnon",Set.of("hoplite","archer"),false,false,false,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000);
addHeros("Ajax","ajax",Set.of("hoplites"),false,false,false,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000);
addHeros("Alexandrios","alexandrios",Set.of("archers"),false,false,false,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000);
addHeros("Déimos","deimos",Set.of(),true,true,true,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000);
addHeros("Hector","hector",Set.of("sword","slinger"),false,false,false,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000);
addHeros("Lysippe","lysippe",Set.of("rider"),false,false,false,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000);
addHeros("Léonidas","leonidas",Set.of(),true,true,true,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005);
addHeros("Mihalis","mihalis",Set.of(),true,false,false,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.100,0.010,0.100,0.010,0.000,0.000,0.000,0.000);
addHeros("Médée","medea",Set.of("slinger"),false,false,false,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000);
addHeros("Mélousa","melousa",Set.of("chariot"),false,false,false,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000,0.150,0.010,0.150,0.010,0.150,0.010,0.000,0.000);
addHeros("Pélops","pelops",Set.of("hoplite","chariot"),false,false,false,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000);
addHeros("Thémistocle","themistokles",Set.of("godsent","rider"),false,false,false,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000,0.100,0.010,0.100,0.010,0.100,0.010,0.000,0.000);
addHeros("Télémaque","telemachos",Set.of("sword"),false,false,false,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000,0.150,0.015,0.150,0.015,0.150,0.015,0.000,0.000);
addHeros("Urephon","urephon",Set.of(),false,false,true,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005,0.050,0.005);
addHeros("Zuretha","zuretha",Set.of(),false,true,false,0.000,0.000,0.000,0.000,0.000,0.000,0.050,0.005,0.000,0.000,0.000,0.000,0.000,0.000,0.050,0.005);
}
}

View File

@ -7,12 +7,11 @@ import com.bernard.greposimu.model.DefContext;
import com.bernard.greposimu.model.FightStats; import com.bernard.greposimu.model.FightStats;
import com.bernard.greposimu.model.OffContext; import com.bernard.greposimu.model.OffContext;
import com.bernard.greposimu.model.game.GameConfig; import com.bernard.greposimu.model.game.GameConfig;
import com.bernard.greposimu.model.game.researches.Research;
import com.bernard.greposimu.model.game.units.NavalUnit; import com.bernard.greposimu.model.game.units.NavalUnit;
import com.bernard.greposimu.model.game.units.TerrestrialUnit; import com.bernard.greposimu.model.game.units.TerrestrialUnit;
import com.bernard.greposimu.model.game.units.Unit; import com.bernard.greposimu.model.game.units.Unit;
import com.bernard.greposimu.model.jsongame.GameData;
import com.bernard.greposimu.model.jsongame.Power;
import com.bernard.greposimu.model.jsongame.Research;
public class Fight { public class Fight {
public static FightStats computeDefStats(GameConfig gc, DefContext def) { public static FightStats computeDefStats(GameConfig gc, DefContext def) {
@ -95,23 +94,23 @@ public class Fight {
throw new UnsupportedOperationException("I don't know how to manage units of type "+u.getClass().getName()); throw new UnsupportedOperationException("I don't know how to manage units of type "+u.getClass().getName());
} }
public static List<Power> relevantDefPowers(GameData gd) { public static List<Object> relevantDefPowers(GameConfig gd) {
System.out.println(gd.powers); return List.of();
return List.of("acumen", "divine_senses", "myrmidion_attack", "trojan_defense", "defense_boost", /*List.of("acumen", "divine_senses", "myrmidion_attack", "trojan_defense", "defense_boost",
"defense_penalty", "longterm_defense_boost", "assassins_acumen", "rare_defense_boost", "defense_penalty", "longterm_defense_boost", "assassins_acumen", "rare_defense_boost",
"epic_defense_boost", "olympic_torch.grepolympia_summer", "olympic_senses.grepolympia_summer", "missions_power_4.missions_dionysia", "epic_defense_boost", "olympic_torch.grepolympia_summer", "olympic_senses.grepolympia_summer", "missions_power_4.missions_dionysia",
"divine_battle_strategy_rare", "divine_battle_strategy_epic", "naval_battle_strategy_rare", "divine_battle_strategy_rare", "divine_battle_strategy_epic", "naval_battle_strategy_rare",
"naval_battle_strategy_epic", "land_battle_strategy_rare", "land_battle_strategy_epic", "naval_battle_strategy_epic", "land_battle_strategy_rare", "land_battle_strategy_epic",
"soterias_shrine.not_cast").stream().map(gd.powers::get).map(p -> (Power)p).toList(); "soterias_shrine.not_cast").stream().map(gd.powers::get).map(p -> (Power)p).toList();*/
} }
public static List<Research> relevantDefResearch(GameData gd) { public static List<Research> relevantDefResearch(GameConfig gd) {
return List.of("divine_selection","phalanx","ram") return List.of("divine_selection","phalanx","ram")
.stream().map(gd.researches::get).toList(); .stream().map(gd::getResearch).toList();
} }
public static List<Unit> relevantDefUnits(GameConfig gc) { public static List<Unit> relevantDefUnits(GameConfig gc) {
return gc.getUnits().stream().toList(); return gc.getUnits().stream().toList();
} }
public static List<String> relevantDefCounsellors(GameData data) { public static List<String> relevantDefCounsellors(GameConfig data) {
return List.of("priest","commander","captain"); return List.of("priest","commander","captain");
} }
public FightStats computeOffStats(DefContext off) { public FightStats computeOffStats(DefContext off) {

View File

@ -1,57 +0,0 @@
package com.bernard.greposimu.engine.json;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
public class MapJsonDeserializer extends StdDeserializer<Map<String,?>> implements ContextualDeserializer{
private static final long serialVersionUID = -888029778299077908L;
private JavaType type;
public MapJsonDeserializer() {
super(Object.class);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException{
MapJsonDeserializer deserializer = new MapJsonDeserializer();
if(property != null)
deserializer.type = property.getType().containedType(1);
else
deserializer.type = ctxt.getContextualType();
return deserializer;
}
@Override
public Map<String,?> deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
JsonNode node = parser.getCodec().readTree(parser);
if(node.isNull() || (node.isArray() && node.isEmpty()))
return new HashMap<>();
else if(node.isObject()) {
ObjectCodec codec = parser.getCodec();
Map<String,Object> output = new HashMap<>();
java.util.Iterator<Entry<String, JsonNode>> it = node.fields();
while(it.hasNext()) {
Entry<String, JsonNode> entry = it.next();
output.put(entry.getKey(), entry.getValue().traverse(codec).readValueAs(this.type.getRawClass()));
}
return output;
} else
throw MismatchedInputException.from(parser, Map.class, "JSON is neither an empty array nor a map");
}
}

View File

@ -1,28 +0,0 @@
package com.bernard.greposimu.model;
public enum Dieu {
ZEUS("Zeus","zeus"),
POSEIDON("Poséidon","poseidon"),
HERA("Héra","hera"),
ATHENA("Athéna","athena"),
HADES("Hadès","hades"),
ARTEMIS("Artémis","artemis"),
APHRODITE("Aphrodite","aphrodite"),
ARES("Arès","ares");
String nom;
String pname;
Dieu(String nom,String pname){
this.nom = nom;
this.pname = pname;
}
public String getNom() {
return nom;
}
public String getPname() {
return pname;
}
}

View File

@ -1,87 +0,0 @@
package com.bernard.greposimu.model;
import java.util.Set;
public class Heros {
String nom;
String pname;
Set<String> appliedToNames;
boolean appTerrestre,appNavale,appMythique;
OffDefStats statsZero;
OffDefStats statsPlus;
public Heros(String nom, String pname, Set<String> appliedToNames, boolean appTerrestre, boolean appNavale, boolean appMythique,
OffDefStats statsZero, OffDefStats statsPlus) {
this.nom = nom;
this.pname = pname;
this.appliedToNames = appliedToNames;
this.appTerrestre = appTerrestre;
this.appNavale = appNavale;
this.appMythique = appMythique;
this.statsZero = statsZero;
this.statsPlus = statsPlus;
}
public OffDefStats applyToUnit(Unite unite,int level) {
if((appTerrestre && unite.terrestre) ||
(appNavale && unite.navale) ||
(appMythique && unite.mythique) ||
appliedToNames.contains(unite.pname)) {
return unite.stats.plus(unite.stats.prod(statsZero.plus(statsPlus.times(level))));
}
return unite.stats;
}
public String getNom() {
return nom;
}
public String getPname() {
return pname;
}
public Set<String> getAppliedToNames() {
return appliedToNames;
}
public boolean isAppTerrestre() {
return appTerrestre;
}
public boolean isAppNavale() {
return appNavale;
}
public boolean isAppMythique() {
return appMythique;
}
public OffDefStats getStatsZero() {
return statsZero;
}
public OffDefStats getStatsPlus() {
return statsPlus;
}
}

View File

@ -1,182 +0,0 @@
package com.bernard.greposimu.model;
public class OffDefStats {
double att_hack;
double att_pierce;
double att_distance;
double ship_attack;
double def_hack;
double def_pierce;
double def_distance;
double ship_defense;
public OffDefStats(double attqCont, double attqBlan, double attqJet, double attqNav, double defCont, double defBlan,
double defJet, double defNav) {
this.att_hack = attqCont;
this.att_pierce = attqBlan;
this.att_distance = attqJet;
this.ship_attack = attqNav;
this.def_hack = defCont;
this.def_pierce = defBlan;
this.def_distance = defJet;
this.ship_defense = defNav;
}
public static final OffDefStats zero = new OffDefStats(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
public OffDefStats plus(OffDefStats other) {
return new OffDefStats(
this.att_hack + other.att_hack,
this.att_pierce + other.att_pierce,
this.att_distance + other.att_distance ,
this.ship_attack + other.ship_attack ,
this.def_hack + other.def_hack ,
this.def_pierce + other.def_pierce ,
this.def_distance + other.def_distance ,
this.ship_defense + other.ship_defense
);
}
public OffDefStats prod(OffDefStats other) {
return new OffDefStats(
this.att_hack * other.att_hack,
this.att_pierce * other.att_pierce,
this.att_distance * other.att_distance ,
this.ship_attack * other.ship_attack ,
this.def_hack * other.def_hack ,
this.def_pierce * other.def_pierce ,
this.def_distance * other.def_distance ,
this.ship_defense * other.ship_defense
);
}
public OffDefStats times(int factor) {
return new OffDefStats(
this.att_hack * factor,
this.att_pierce * factor,
this.att_distance * factor,
this.ship_attack * factor,
this.def_hack * factor,
this.def_pierce * factor,
this.def_distance * factor,
this.ship_defense * factor
);
}
public OffDefStats div(int factor) {
return new OffDefStats(
this.att_hack / factor,
this.att_pierce / factor,
this.att_distance / factor,
this.ship_attack / factor,
this.def_hack / factor,
this.def_pierce / factor,
this.def_distance / factor,
this.ship_defense / factor
);
}
public double getAttqCont() {
return att_hack;
}
public void setAttqCont(double attqCont) {
this.att_hack = attqCont;
}
public double getAttqBlan() {
return att_pierce;
}
public void setAttqBlan(double attqBlan) {
this.att_pierce = attqBlan;
}
public double getAttqJet() {
return att_distance;
}
public void setAttqJet(double attqJet) {
this.att_distance = attqJet;
}
public double getAttqNav() {
return ship_attack;
}
public void setAttqNav(double attqNav) {
this.ship_attack = attqNav;
}
public double getDefCont() {
return def_hack;
}
public void setDefCont(double defCont) {
this.def_hack = defCont;
}
public double getDefBlan() {
return def_pierce;
}
public void setDefBlan(double defBlan) {
this.def_pierce = defBlan;
}
public double getDefJet() {
return def_distance;
}
public void setDefJet(double defJet) {
this.def_distance = defJet;
}
public double getDefNav() {
return ship_defense;
}
public void setDefNav(double defNav) {
this.ship_defense = defNav;
}
public double getAtt_hack() {
return att_hack;
}
public double getAtt_pierce() {
return att_pierce;
}
public double getAtt_distance() {
return att_distance;
}
public double getShip_attack() {
return ship_attack;
}
public double getDef_hack() {
return def_hack;
}
public double getDef_pierce() {
return def_pierce;
}
public double getDef_distance() {
return def_distance;
}
public double getShip_defense() {
return ship_defense;
}
public static OffDefStats getZero() {
return zero;
}
}

View File

@ -1,74 +0,0 @@
package com.bernard.greposimu.model;
public class Unite {
String nom;
String pname;
int population;
int speed;
int butin;
OffDefStats stats;
boolean terrestre,navale,mythique;
Dieu dieu;
public Unite(String nom, String pname, int population, int speed, int butin, OffDefStats stats, boolean terrestre, boolean navale,
boolean mythique, Dieu dieu) {
this.nom = nom;
this.pname = pname;
this.population = population;
this.speed = speed;
this.butin = butin;
this.stats = stats;
this.terrestre = terrestre;
this.navale = navale;
this.mythique = mythique;
this.dieu = dieu;
}
public String getNom() {
return nom;
}
public String getPname() {
return pname;
}
public int getPopulation() {
return population;
}
public int getSpeed() {
return speed;
}
public int getButin() {
return butin;
}
public OffDefStats getStats() {
return stats;
}
public boolean isTerrestre() {
return terrestre;
}
public boolean isNavale() {
return navale;
}
public boolean isMythique() {
return mythique;
}
public Dieu getDieu() {
return dieu;
}
}

View File

@ -6,11 +6,11 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.json.JSONObject; import org.json.JSONObject;
import com.bernard.greposimu.Utils; import com.bernard.greposimu.Utils;
import com.bernard.greposimu.model.game.researches.Research;
import com.bernard.greposimu.model.game.units.FightType; import com.bernard.greposimu.model.game.units.FightType;
import com.bernard.greposimu.model.game.units.Hero; import com.bernard.greposimu.model.game.units.Hero;
import com.bernard.greposimu.model.game.units.Hero.HeroCategory; import com.bernard.greposimu.model.game.units.Hero.HeroCategory;
@ -28,6 +28,8 @@ public class GameConfig {
Set<Hero> heroes; Set<Hero> heroes;
Set<Research> researches;
public Set<Unit> getUnits() { public Set<Unit> getUnits() {
return Collections.unmodifiableSet(this.units); return Collections.unmodifiableSet(this.units);
} }
@ -43,6 +45,13 @@ public class GameConfig {
return Utils.getIdentified(this.heroes, id); return Utils.getIdentified(this.heroes, id);
} }
public Set<Research> getResearches() {
return Collections.unmodifiableSet(this.researches);
}
public Research getResearch(String id) {
return Utils.getIdentified(this.researches, id);
}
public GameConfig(JSONObject json) { public GameConfig(JSONObject json) {
JSONObject godsJ = json.getJSONObject("gods"); JSONObject godsJ = json.getJSONObject("gods");
@ -52,6 +61,26 @@ public class GameConfig {
gods.add(new God(godJ.getString("id"), godJ.getString("name"))); gods.add(new God(godJ.getString("id"), godJ.getString("name")));
} }
JSONObject researchesJ = json.getJSONObject("researches");
this.researches = new HashSet<>();
for(String r : researchesJ.keySet()) {
JSONObject research = researchesJ.getJSONObject(r);
this.researches.add(new Research(
research.getString("id"),
research.getString("name"),
research.getString("description"),
research.isNull("research_dependencies")?Set.of():research.getJSONArray("research_dependencies").toList().stream().map(k -> this.getResearch((String)k)).collect(Collectors.toSet()),
research.isNull("building_dependencies")?Map.of():research.getJSONObject("building_dependencies").keySet().stream()
.collect(Collectors.toMap(Function.identity(), b -> research.getJSONObject("building_dependencies").getInt(b))),
research.isNull("resources")?null:new Resources(
research.getJSONObject("resources").getInt("wood"),
research.getJSONObject("resources").getInt("stone"),
research.getJSONObject("resources").getInt("iron")),
research.getInt("required_time"),
research.getInt("research_points")
));
}
JSONObject unitsJ = json.getJSONObject("units"); JSONObject unitsJ = json.getJSONObject("units");
this.units = new HashSet<>(); this.units = new HashSet<>();
for(String u : unitsJ.keySet()) { for(String u : unitsJ.keySet()) {
@ -72,10 +101,8 @@ public class GameConfig {
unit.getJSONObject("resources").getInt("iron")), unit.getJSONObject("resources").getInt("iron")),
unit.getInt("favor"), unit.getInt("favor"),
unit.getInt("build_time"), unit.getInt("build_time"),
IntStream.range(0, unit.getJSONArray("research_dependencies").length()) unit.isNull("research_dependencies")?Set.of():unit.getJSONArray("research_dependencies").toList().stream().map(k -> this.getResearch((String)k)).collect(Collectors.toSet()),
.mapToObj(i -> unit.getJSONArray("research_dependencies").getString(i)) unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
.collect(Collectors.toSet()),
unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
.collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))), .collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))),
unit.getInt("attack"), unit.getInt("attack"),
unit.getInt("defense"), unit.getInt("defense"),
@ -96,10 +123,8 @@ public class GameConfig {
unit.getJSONObject("resources").getInt("iron")), unit.getJSONObject("resources").getInt("iron")),
unit.getInt("favor"), unit.getInt("favor"),
unit.getInt("build_time"), unit.getInt("build_time"),
IntStream.range(0, unit.getJSONArray("research_dependencies").length()) unit.isNull("research_dependencies")?Set.of():unit.getJSONArray("research_dependencies").toList().stream().map(k -> this.getResearch((String)k)).collect(Collectors.toSet()),
.mapToObj(i -> unit.getJSONArray("research_dependencies").getString(i)) unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
.collect(Collectors.toSet()),
unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
.collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))), .collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))),
unit.getInt("attack"), unit.getInt("attack"),
unit.getInt("defense") unit.getInt("defense")
@ -126,10 +151,8 @@ public class GameConfig {
unit.getJSONObject("resources").getInt("iron")), unit.getJSONObject("resources").getInt("iron")),
unit.getInt("favor"), unit.getInt("favor"),
unit.getInt("build_time"), unit.getInt("build_time"),
unit.isNull("research_dependencies")?Set.of():IntStream.range(0, unit.getJSONArray("research_dependencies").length()) unit.isNull("research_dependencies")?Set.of():unit.getJSONArray("research_dependencies").toList().stream().map(k -> this.getResearch((String)k)).collect(Collectors.toSet()),
.mapToObj(i -> unit.getJSONArray("research_dependencies").getString(i)) unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
.collect(Collectors.toSet()),
unit.isNull("building_dependencies")?Map.of():unit.getJSONObject("building_dependencies").keySet().stream()
.collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))), .collect(Collectors.toMap(Function.identity(), b -> unit.getJSONObject("building_dependencies").getInt(b))),
unit.getInt("attack"), unit.getInt("attack"),
ft, ft,

View File

@ -0,0 +1,66 @@
package com.bernard.greposimu.model.game.researches;
import java.util.Map;
import java.util.Set;
import com.bernard.greposimu.model.game.Identified;
import com.bernard.greposimu.model.game.Resources;
public class Research implements Identified{
String id;
String name;
String description;
Set<Research> researchDependencies;
Map<String,Integer> building_dependencies;
Resources resources;
int required_time;
int research_points;
public Research(String id, String name, String description, Set<Research> researchDependencies,
Map<String, Integer> building_dependencies, Resources resources, int required_time, int research_points) {
this.id = id;
this.name = name;
this.description = description;
this.researchDependencies = researchDependencies;
this.building_dependencies = building_dependencies;
this.resources = resources;
this.required_time = required_time;
this.research_points = research_points;
}
@Override
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public Set<Research> getResearchDependencies() {
return researchDependencies;
}
public Map<String, Integer> getBuilding_dependencies() {
return building_dependencies;
}
public Resources getResources() {
return resources;
}
public int getRequired_time() {
return required_time;
}
public int getResearch_points() {
return research_points;
}
}

View File

@ -5,6 +5,7 @@ import java.util.Set;
import com.bernard.greposimu.model.game.God; import com.bernard.greposimu.model.game.God;
import com.bernard.greposimu.model.game.Resources; import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.researches.Research;
public class NavalUnit extends Unit { public class NavalUnit extends Unit {
@ -12,7 +13,7 @@ public class NavalUnit extends Unit {
int defense; int defense;
public NavalUnit(String id, String name, String description, int population, int speed, boolean mythological, God god, public NavalUnit(String id, String name, String description, int population, int speed, boolean mythological, God god,
Resources buildCost, int favorCost, int buildTime, Set<String> research_dependencies, Resources buildCost, int favorCost, int buildTime, Set<Research> research_dependencies,
Map<String, Integer> building_dependencies,int attack, int defense) { Map<String, Integer> building_dependencies,int attack, int defense) {
this.id = id; this.id = id;
this.name = name; this.name = name;

View File

@ -5,6 +5,7 @@ import java.util.Set;
import com.bernard.greposimu.model.game.God; import com.bernard.greposimu.model.game.God;
import com.bernard.greposimu.model.game.Resources; import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.researches.Research;
public class TerrestrialUnit extends Unit{ public class TerrestrialUnit extends Unit{
@ -19,7 +20,7 @@ public class TerrestrialUnit extends Unit{
boolean flight; boolean flight;
public TerrestrialUnit(String id, String name, String description, int population, int speed, boolean mythological, God god, public TerrestrialUnit(String id, String name, String description, int population, int speed, boolean mythological, God god,
Resources buildCost, int favorCost, int buildTime, Set<String> research_dependencies, Resources buildCost, int favorCost, int buildTime, Set<Research> research_dependencies,
Map<String, Integer> building_dependencies,int attack, FightType attackType, int pierceDef, int hackDef, int distanceDef, int booty, Map<String, Integer> building_dependencies,int attack, FightType attackType, int pierceDef, int hackDef, int distanceDef, int booty,
boolean flight) { boolean flight) {
this.id = id; this.id = id;

View File

@ -5,12 +5,13 @@ import java.util.Set;
import com.bernard.greposimu.model.game.God; import com.bernard.greposimu.model.game.God;
import com.bernard.greposimu.model.game.Resources; import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.researches.Research;
public class TransportUnit extends NavalUnit { public class TransportUnit extends NavalUnit {
int capacity; int capacity;
public TransportUnit(String id, String name, String description, int population, int speed, boolean mythological, public TransportUnit(String id, String name, String description, int population, int speed, boolean mythological,
God god, Resources buildCost, int favorCost, int buildTime, Set<String> research_dependencies, God god, Resources buildCost, int favorCost, int buildTime, Set<Research> research_dependencies,
Map<String, Integer> building_dependencies, int attack, int defense, int capacity) { Map<String, Integer> building_dependencies, int attack, int defense, int capacity) {
super(id, name, description, population, speed, mythological, god, buildCost, favorCost, buildTime, super(id, name, description, population, speed, mythological, god, buildCost, favorCost, buildTime,
research_dependencies, building_dependencies, attack, defense); research_dependencies, building_dependencies, attack, defense);

View File

@ -6,6 +6,7 @@ import java.util.Set;
import com.bernard.greposimu.model.game.God; import com.bernard.greposimu.model.game.God;
import com.bernard.greposimu.model.game.Identified; import com.bernard.greposimu.model.game.Identified;
import com.bernard.greposimu.model.game.Resources; import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.researches.Research;
public abstract class Unit implements Identified{ public abstract class Unit implements Identified{
@ -23,7 +24,7 @@ public abstract class Unit implements Identified{
int favorCost; int favorCost;
int buildTime; int buildTime;
Set<String> research_dependencies; Set<Research> research_dependencies;
Map<String, Integer> building_dependencies; Map<String, Integer> building_dependencies;
@Override @Override
@ -76,7 +77,7 @@ public abstract class Unit implements Identified{
} }
public Set<String> getResearch_dependencies() { public Set<Research> getResearch_dependencies() {
return research_dependencies; return research_dependencies;
} }