Added Town Objectives

This commit is contained in:
Samy Avrillon 2024-10-31 16:23:49 +01:00
parent 6bc9d4df9d
commit fa7d0362c7
Signed by: Mysaa
GPG Key ID: 0220AC4A3D6A328B
42 changed files with 1980 additions and 49 deletions

View File

@ -25,11 +25,10 @@ dependencies {
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.yaml:snakeyaml:2.2'
implementation 'org.ojalgo:ojalgo:54.0.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.1'
implementation 'org.json:json:20240303'
}
tasks.named('test') {

View File

@ -1,26 +1,76 @@
package com.bernard.greposimu.model.game;
public enum Building {
AGORA,
SENAT,
SCIERIE,
FERME,
CARRIERE,
ENTREPOT,
MINE,
CASERNE,
TEMPLE,
MARCHE,
PORT,
ACADEMIE,
REMPARTS,
GROTTE,
THEATRE,
THERMES,
BIBLIOTHEQUE,
PHARE,
TOUR,
STATUE,
ORACLE,
COMPTOIR;
import java.util.Map;
public enum Building implements Identified{
/*
* var s = ""
for(var b in GameData.buildings){
var bb = GameData.buildings[b];
s += b.toUpperCase()+'("'+b+'",'+bb.resources.wood+","+bb.wood_factor+","+bb.resources.stone+","+bb.stone_factor+","+bb.resources.iron+","+bb.iron_factor+","+bb.pop+","+bb.pop_factor+","+bb.points+","+bb.points_factor+bb.build_time+","+bb.build_time_factor+","+bb.build_time_reduction+"),\n";
}
*/
MAIN("main",6.0,2.15,2.0,2.53,2.0,2.3,1.0,1.5,100.0,1.1300,1.8,0.3,25),
HIDE("hide",200.0,1.3,400.0,1,700.0,0.9,3.0,0.5,50.0,1.2420,1.456,0,10),
PLACE("place",10.0,2,0.0,2,0.0,2,1.0,0,30.0,1.111,2.17,0,1),
LUMBER("lumber",2.6,1.9,2.0,2.1,1.49,2.1,1.0,1.25,20.0,1.1120,1.9,1,40),
STONER("stoner",1.3,2.1,2.6,1.9,2.4,2.1,1.0,1.25,20.0,1.1300,1.62,1,40),
IRONER("ironer",5.0,1.9,2.0,2,4.0,1.8,1.0,1.25,20.0,1.1600,1.41,0.5,40),
MARKET("market",50.0,1.48,20.0,1.62,5.0,1.98,2.0,1.1,100.0,1.08480,1.6,0.4,30),
DOCKS("docks",400.0,0.9,200.0,0.98,100.0,1.1,4.0,1,60.0,1.11500,1.1,0,30),
BARRACKS("barracks",70.0,1.22,20.0,1.67,40.0,1.54,1.0,1.3,30.0,1.115900,1.25,0.5,30),
WALL("wall",400.0,0,350.0,1,200.0,1.1,2.0,1.16,30.0,1.12900,1.3,0,25),
STORAGE("storage",35.0,1.52,55.0,1.52,15.0,1.66,0.0,1,13.0,1.141800,1.23,0.4,35),
FARM("farm",8.0,1.87,5.0,2.03,1.0,2.4,0.0,0,15.0,1.12300,1.7,1,45),
ACADEMY("academy",100.0,1.21,200.0,1.1,120.0,1.2,3.0,1,60.0,1.121200,1.25,0,36),
TEMPLE("temple",500.0,0.865,900.0,0.7,600.0,0.82,5.0,1,200.0,1.083600,1.145,0,30),
THEATER("theater",8000.0,2,8000.0,2,8000.0,2,60.0,1,500.0,164800,2.17,0,1),
THERMAL("thermal",9000.0,2,6000.0,2,9000.0,2,60.0,1,500.0,164800,2.17,0,1),
LIBRARY("library",9500.0,2,7500.0,2,7000.0,2,60.0,1,500.0,164800,2.17,0,1),
LIGHTHOUSE("lighthouse",6000.0,2,10000.0,2,8000.0,2,60.0,1,500.0,164800.0,2.17,0,1),
TOWER("tower",8000.0,2,10000.0,2,6000.0,2,60.0,1,500.0,164800.0,2.17,0,1),
STATUE("statue",6000.0,2,10500.0,2,7500.0,2,60.0,1,500.0,164800.0,2.17,0,1),
ORACLE("oracle",6500.0,2,7000.0,2,9500.0,2,60.0,1,500.0,164800.0,2.17,0,1),
TRADE_OFFICE("trade_office",10500.0,2,7000.0,2,6500.0,2,60.0,1,500.0,164800.0,1,0,1);
String id;
private double wood0,woodF,stone0,stoneF,iron0,ironF,pop0,popF,pts0,ptsF,build0,buildF,buildR;
int maxLevel;
private Building(String id, double wood0, double woodF, double stone0, double stoneF, double iron0, double ironF,
double pop0, double popF, double pts0, double ptsF, double build0, double buildF, int maxLevel) {
this.id = id;
this.wood0 = wood0;
this.woodF = woodF;
this.stone0 = stone0;
this.stoneF = stoneF;
this.iron0 = iron0;
this.ironF = ironF;
this.pop0 = pop0;
this.popF = popF;
this.pts0 = pts0;
this.ptsF = ptsF;
this.build0 = build0;
this.buildF = buildF;
this.maxLevel = maxLevel;
}
@Override
public String getId() {
return id;
}
public static int getFarmPopulation(int farm) {
return (int) Math.floor(Math.pow(farm, 1.455)*14);
}
public int getRequiredPop(int level) {
return (int) Math.floor(pop0*Math.pow(level, popF));
}
public int popInBuildings(Map<Building,Integer> buildings) {
return buildings.entrySet().stream().mapToInt(e -> e.getKey().getRequiredPop(e.getValue())).sum();
}
}

View File

@ -1,5 +1,6 @@
package com.bernard.greposimu.model.game;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
@ -58,4 +59,40 @@ public class GameConfig {
return Utils.getIdentified(this.researches, id);
}
public Building getBuilding(String bid) {
return Arrays.stream(Building.values()).filter(b -> b.id.equals(bid)).findAny().orElse(null);
}
public God getGod(String god) {
return Utils.getIdentified(this.gods, god);
}
public Set<Building> getBuildings() {
return Set.of(Building.values());
}
@SuppressWarnings("unchecked")
public <T extends Identified> T getIdentified(Class<T> clazz, String id) {
if(Unit.class.isAssignableFrom(clazz))
return (T)this.getUnit(id);
if(Hero.class.isAssignableFrom(clazz))
return (T)this.getHero(id);
if(Research.class.isAssignableFrom(clazz))
return (T)this.getResearch(id);
if(God.class.isAssignableFrom(clazz))
return (T)this.getGod(id);
if(Building.class.isAssignableFrom(clazz))
return (T)this.getBuilding(id);
throw new UnsupportedOperationException("Cannot get identified object of class "+clazz.getName());
}
public static int getTotalPop(int farmLevel, boolean thermal, boolean charrue, boolean pygmallion, int bonus) {
int tot = Building.getFarmPopulation(farmLevel);
if(thermal)tot = (int)Math.floor(tot*1.1);
if(charrue)tot += 200;
if(pygmallion)tot += 5*farmLevel;
tot += bonus;
return tot;
}
}

View File

@ -0,0 +1,78 @@
package com.bernard.greposimu.model.game;
import java.io.IOException;
import com.bernard.greposimu.model.game.researches.Research;
import com.bernard.greposimu.model.game.units.Hero;
import com.bernard.greposimu.model.game.units.Unit;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class GrepoYaml extends SimpleModule {
GameConfig gc;
public GrepoYaml(GameConfig gc) {
this.gc = gc;
registerId(Unit.class);
registerId(Research.class);
registerId(Building.class);
registerId(God.class);
registerId(Hero.class);
}
private <T extends Identified> void registerId(Class<T> clazz){
this.addSerializer(clazz, new IdSerializer<T>());
this.addKeySerializer(clazz, new IdKeySerializer<T>());
this.addDeserializer(clazz, new IdDeserializer<T>(clazz));
this.addKeyDeserializer(clazz, new IdKeyDeserializer<T>(clazz));
}
public class IdSerializer<T extends Identified> extends JsonSerializer<T>{
@Override
public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(value.getId());
}
}
public class IdKeySerializer<T extends Identified> extends JsonSerializer<T>{
@Override
public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeFieldName(value.getId());
}
}
public class IdDeserializer<T extends Identified> extends JsonDeserializer<T> {
Class<T> clazz;
public IdDeserializer(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
String id = p.getText();
return gc.getIdentified(clazz, id);
}
}
public class IdKeyDeserializer<T extends Identified> extends KeyDeserializer {
Class<T> clazz;
public IdKeyDeserializer(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {
return gc.getIdentified(clazz, key);
}
}
}

View File

@ -0,0 +1,28 @@
package com.bernard.greposimu.model.game;
public class UnitResources extends Resources {
God god;
int favor;
public UnitResources(int wood, int stone, int iron) {
super(wood, stone, iron);
this.god = null;
this.favor = 0;
}
public UnitResources(int wood, int stone, int iron, God god, int favor) {
super(wood, stone, iron);
this.god = god;
this.favor = favor;
}
public God getGod() {
return god;
}
public int getFavor() {
return favor;
}
}

View File

@ -0,0 +1,55 @@
package com.bernard.greposimu.model.game.queues;
import com.bernard.greposimu.model.game.Building;
import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.runtime.Timestamp;
public class BuildingQueueItem extends QueueItem {
public BuildingQueueItem(long buildingTime, Building building, boolean tearingDown, Timestamp beginTime,
Timestamp endTime, Resources refund, Resources cost) {
this.buildingTime = buildingTime;
this.building = building;
this.tearingDown = tearingDown;
this.beginTime = beginTime;
this.endTime = endTime;
this.refund = refund;
this.cost = cost;
}
long buildingTime;
// the building being built
Building building;
boolean tearingDown;
Timestamp beginTime;
Timestamp endTime;
Resources refund;
Resources cost;
public long getBuildingTime() {
return buildingTime;
}
public Building getBuilding() {
return building;
}
public boolean isTearingDown() {
return tearingDown;
}
public Timestamp getBeginTime() {
return beginTime;
}
public Timestamp getEndTime() {
return endTime;
}
public Resources getRefund() {
return refund;
}
public Resources getCost() {
return cost;
}
}

View File

@ -0,0 +1,5 @@
package com.bernard.greposimu.model.game.queues;
public class QueueItem {
}

View File

@ -0,0 +1,43 @@
package com.bernard.greposimu.model.game.queues;
import com.bernard.greposimu.model.game.UnitResources;
import com.bernard.greposimu.model.game.units.Unit;
import com.bernard.greposimu.model.runtime.Timestamp;
public class RecruitmentQueueItem extends QueueItem {
RecruitmentKind kind;
Unit unit;
// Number of units requested
int count;
// Number of units that have been done
int done;
Timestamp beginTime;
Timestamp endTime;
UnitResources refund;
UnitResources cost;
public RecruitmentQueueItem(RecruitmentKind kind, Unit unit, int count, int done, Timestamp beginTime,
Timestamp endTime, UnitResources refund, UnitResources cost) {
this.kind = kind;
this.unit = unit;
this.count = count;
this.done = done;
this.beginTime = beginTime;
this.endTime = endTime;
this.refund = refund;
this.cost = cost;
}
public static enum RecruitmentKind {
GROUND,NAVAL;
}
}

View File

@ -0,0 +1,44 @@
package com.bernard.greposimu.model.game.queues;
import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.researches.Research;
import com.bernard.greposimu.model.runtime.Timestamp;
public class ResearchQueueItem extends QueueItem {
// the building being built
Research research;
Timestamp beginTime;
Timestamp endTime;
Resources refund;
public ResearchQueueItem(Research research, Timestamp beginTime, Timestamp endTime, Resources refund) {
this.research = research;
this.beginTime = beginTime;
this.endTime = endTime;
this.refund = refund;
}
public Research getResearch() {
return research;
}
public Timestamp getBeginTime() {
return beginTime;
}
public Timestamp getEndTime() {
return endTime;
}
public Resources getRefund() {
return refund;
}
}

View File

@ -92,4 +92,9 @@ public abstract class Unit implements Identified{
return !this.isGround();
}
@Override
public String toString() {
return name;
}
}

View File

@ -4,4 +4,9 @@ public class Timestamp {
long timestamp;
public Timestamp(long timestamp) {
this.timestamp = timestamp;
}
}

View File

@ -1,5 +1,7 @@
package com.bernard.greposimu.model.runtime;
import java.util.Map;
import com.bernard.greposimu.model.game.Resources;
public class Ville {
@ -13,6 +15,6 @@ public class Ville {
Resources resources;
Map<String,Integer> batiments
Map<String,Integer> batiments;
}

View File

@ -2,6 +2,7 @@ package com.bernard.greposimu.model.simulator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.bernard.greposimu.model.game.God;
import com.bernard.greposimu.model.runtime.Timestamp;
@ -24,9 +25,78 @@ public class Joueureuse {
List<String> inventory;
// Remparts
Troupes slainAsOff,slainAsDef,lostAsOff,lostAsDef;
Set<Movements> movements;
public Joueureuse(Map<God, Integer> favor, int rage, int gold, Map<String, Integer> heroes,
Map<String, Timestamp> heroesArrival, Map<String, Integer> heroesLevel, List<String> inventory,
Troupes slainAsOff, Troupes slainAsDef, Troupes lostAsOff, Troupes lostAsDef, Set<Movements> movements) {
this.favor = favor;
this.rage = rage;
this.gold = gold;
this.heroes = heroes;
this.heroesArrival = heroesArrival;
this.heroesLevel = heroesLevel;
this.inventory = inventory;
this.slainAsOff = slainAsOff;
this.slainAsDef = slainAsDef;
this.lostAsOff = lostAsOff;
this.lostAsDef = lostAsDef;
this.movements = movements;
}
public Map<God, Integer> getFavor() {
return favor;
}
public int getRage() {
return rage;
}
public int getGold() {
return gold;
}
public Map<String, Integer> getHeroes() {
return heroes;
}
public Map<String, Timestamp> getHeroesArrival() {
return heroesArrival;
}
public Map<String, Integer> getHeroesLevel() {
return heroesLevel;
}
public List<String> getInventory() {
return inventory;
}
public Troupes getSlainAsDef() {
return slainAsDef;
}
public Troupes getSlainAsOff() {
return slainAsOff;
}
public Troupes getLostAsDef() {
return lostAsDef;
}
public Troupes getLostAsOff() {
return lostAsOff;
}
public Set<Movements> getMovements() {
return movements;
}
//TODO quêtes
//TODO messages/rapports
//TODO profile
//TODO alliance + allianceMessages
}

View File

@ -0,0 +1,23 @@
package com.bernard.greposimu.model.simulator;
import com.bernard.greposimu.model.runtime.Timestamp;
public class Movements {
Timestamp arrival;
Timestamp started;
Timestamp cancelableUntil;
Timestamp invisibleUntil;
boolean destIsAttack;
boolean origIsAttack;
int home;
int player;
int target;
String type;
Troupes troupes;
}

View File

@ -0,0 +1,25 @@
package com.bernard.greposimu.model.simulator;
import java.util.Map;
public class SimulatorData {
Map<String,Ville> villes;
Joueureuse joueureuse;
public SimulatorData(Map<String, Ville> villes, Joueureuse joueureuse) {
super();
this.villes = villes;
this.joueureuse = joueureuse;
}
public Map<String, Ville> getVilles() {
return villes;
}
public Joueureuse getJoueureuse() {
return joueureuse;
}
}

View File

@ -1,9 +1,40 @@
package com.bernard.greposimu.model.simulator;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.bernard.greposimu.model.game.units.Unit;
public class Troupes {
Map<String,Integer> unites;
Map<Unit,Integer> unites;
public Troupes(Map<Unit, Integer> unites) {
this.unites = unites;
}
public Map<Unit, Integer> getUnites() {
return unites;
}
public static final Troupes add(Troupes a, Troupes b) {
return new Troupes(
Stream.concat(a.unites.keySet().stream(), b.unites.keySet().stream())
.distinct().collect(Collectors.toMap(Function.identity(),
u -> a.unites.getOrDefault(u, 0)+b.unites.getOrDefault(u, 0)))
);
}
public int pop() {
return unites.entrySet().stream().mapToInt(e -> e.getValue()*e.getKey().getPopulation()).sum();
}
@Override
public String toString() {
return "Troupes [unites=" + unites + "]";
}
}

View File

@ -4,15 +4,22 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.bernard.greposimu.model.game.Building;
import com.bernard.greposimu.model.game.God;
import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.powers.Power;
import com.bernard.greposimu.model.game.queues.BuildingQueueItem;
import com.bernard.greposimu.model.game.queues.RecruitmentQueueItem;
import com.bernard.greposimu.model.game.queues.ResearchQueueItem;
import com.bernard.greposimu.model.game.researches.Research;
import com.bernard.greposimu.model.runtime.Timestamp;
public class Ville {
int id;
String nom;
Map<String,Integer> batiments;
Map<Building,Integer> batiments;
Troupes troupes;
@ -23,35 +30,33 @@ public class Ville {
Map<Integer,Troupes> soutenus;
// sortilegeId -> effectEnd
Map<String,Timestamp> sortileges;
Map<Power,Timestamp> sortileges;
// Agora
Timestamp festivalEnd,olympiquesEnd,marchEnd,theaterEnd;
// Academie
Set<String> researches;
List<QueueItem> researchQueue;
Set<Research> researches;
List<ResearchQueueItem> researchQueue;
// Senat
List<QueueItem> buildingQueue;
List<BuildingQueueItem> buildingQueue;
// Farm
Timestamp miliceAppel;
// End time of militia
Timestamp miliceUntil;
// Entrepôt
Resources storage;
// Caserne
List<QueueItem> terrestrialQueue;
List<RecruitmentQueueItem> terrestrialQueue;
// Temple
God god;
// Port
List<QueueItem> navalQueue;
// Remparts
Troupes slainAsOff,slainAsDef,lostAsOff,lostAsDef;
List<RecruitmentQueueItem> navalQueue;
// Grotte
int piecesStoquees;
@ -61,9 +66,47 @@ public class Ville {
Set<TradeOrder> incomingTrade;
Set<TradeOrder> outgoingTrade;
public Ville(int id, String nom, Map<Building, Integer> batiments, Troupes troupes, Map<Integer, Troupes> soutiens,
Map<Integer, Troupes> soutenus, Map<Power, Timestamp> sortileges, Timestamp festivalEnd,
Timestamp olympiquesEnd, Timestamp marchEnd, Timestamp theaterEnd, Set<Research> researches,
List<ResearchQueueItem> researchQueue, List<BuildingQueueItem> buildingQueue, Timestamp miliceUntil,
Resources storage, List<RecruitmentQueueItem> terrestrialQueue, God god,
List<RecruitmentQueueItem> navalQueue, int piecesStoquees, Set<UnitOrder> ordresMilitaires, Set<TradeOrder> incomingTrade,
Set<TradeOrder> outgoingTrade) {
super();
this.id = id;
this.nom = nom;
this.batiments = batiments;
this.troupes = troupes;
this.soutiens = soutiens;
this.soutenus = soutenus;
this.sortileges = sortileges;
this.festivalEnd = festivalEnd;
this.olympiquesEnd = olympiquesEnd;
this.marchEnd = marchEnd;
this.theaterEnd = theaterEnd;
this.researches = researches;
this.researchQueue = researchQueue;
this.buildingQueue = buildingQueue;
this.miliceUntil = miliceUntil;
this.storage = storage;
this.terrestrialQueue = terrestrialQueue;
this.god = god;
this.navalQueue = navalQueue;
this.piecesStoquees = piecesStoquees;
this.ordresMilitaires = ordresMilitaires;
this.incomingTrade = incomingTrade;
this.outgoingTrade = outgoingTrade;
}
public static class TradeOrder {
Resources resources;
Integer other;
public TradeOrder(Resources resources, Integer other) {
this.resources = resources;
this.other = other;
}
}
public static class UnitOrder {
Troupes attq;
@ -85,4 +128,96 @@ public class Ville {
long duration;
}
public int getId() {
return id;
}
public String getNom() {
return nom;
}
public Map<Building, Integer> getBatiments() {
return batiments;
}
public Troupes getTroupes() {
return troupes;
}
public Map<Integer, Troupes> getSoutiens() {
return soutiens;
}
public Map<Integer, Troupes> getSoutenus() {
return soutenus;
}
public Map<Power, Timestamp> getSortileges() {
return sortileges;
}
public Timestamp getFestivalEnd() {
return festivalEnd;
}
public Timestamp getOlympiquesEnd() {
return olympiquesEnd;
}
public Timestamp getMarchEnd() {
return marchEnd;
}
public Timestamp getTheaterEnd() {
return theaterEnd;
}
public Set<Research> getResearches() {
return researches;
}
public List<ResearchQueueItem> getResearchQueue() {
return researchQueue;
}
public List<BuildingQueueItem> getBuildingQueue() {
return buildingQueue;
}
public Timestamp getMiliceUntil() {
return miliceUntil;
}
public Resources getStorage() {
return storage;
}
public List<RecruitmentQueueItem> getTerrestrialQueue() {
return terrestrialQueue;
}
public God getGod() {
return god;
}
public List<RecruitmentQueueItem> getNavalQueue() {
return navalQueue;
}
public int getPiecesStoquees() {
return piecesStoquees;
}
public Set<UnitOrder> getOrdresMilitaires() {
return ordresMilitaires;
}
public Set<TradeOrder> getIncomingTrade() {
return incomingTrade;
}
public Set<TradeOrder> getOutgoingTrade() {
return outgoingTrade;
}
}

View File

@ -0,0 +1,31 @@
package com.bernard.greposimu.model.simulator.command;
import com.bernard.greposimu.model.game.Building;
import com.bernard.greposimu.model.game.Resources;
public class BuildCommand extends TownCommand {
Building building;
// Destination level of the build
int level;
boolean tearingDown;
public BuildCommand(int town, Resources need, Building building, int level, boolean tearingDown) {
this.town = town;
this.need = need;
this.building = building;
this.level = level;
this.tearingDown = tearingDown;
}
@Override
public String toString() {
if(tearingDown)
return "[%d] Destroy %s from %d -> %d".formatted(this.town,this.building.name(),this.level+1,this.level);
else
return "[%d] Build %s from %d -> %d".formatted(this.town,this.building.name(),this.level-1,this.level);
}
}

View File

@ -0,0 +1,5 @@
package com.bernard.greposimu.model.simulator.command;
public abstract class Command {
}

View File

@ -0,0 +1,17 @@
package com.bernard.greposimu.model.simulator.command;
public class HideStoreCommand extends TownCommand {
int amount;
public HideStoreCommand(int town, int amount) {
this.town = town;
this.amount = amount;
}
@Override
public String toString() {
return "[%d] Store %d iron in the hide".formatted(this.town,this.amount);
}
}

View File

@ -0,0 +1,23 @@
package com.bernard.greposimu.model.simulator.command;
import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.units.Unit;
public class RecruitCommand extends TownCommand{
Unit unit;
int count;
public RecruitCommand(int town, Resources need, Unit unit, int count) {
this.town = town;
this.need = need;
this.unit = unit;
this.count = count;
}
@Override
public String toString() {
return "[%d] Recruit %d %s".formatted(this.town,this.count, this.unit.getName());
}
}

View File

@ -0,0 +1,25 @@
package com.bernard.greposimu.model.simulator.command;
import com.bernard.greposimu.model.game.Resources;
import com.bernard.greposimu.model.game.researches.Research;
public class ResearchCommand extends TownCommand {
Research research;
boolean forget;
public ResearchCommand(int town, Resources need, Research research, boolean forget) {
this.town = town;
this.need = need;
this.research = research;
this.forget = forget;
}
@Override
public String toString() {
if(forget)
return "[%d] Forget research %s".formatted(this.town,this.research.getName());
else
return "[%d] Research %s".formatted(this.town,this.research.getName());
}
}

View File

@ -0,0 +1,11 @@
package com.bernard.greposimu.model.simulator.command;
import com.bernard.greposimu.model.game.Resources;
public abstract class TownCommand extends Command {
int town;
Resources need;
}

View File

@ -0,0 +1,132 @@
package com.bernard.greposimu.model.simulator.objective;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.bernard.greposimu.model.game.Building;
import com.bernard.greposimu.model.game.GameConfig;
import com.bernard.greposimu.model.game.God;
import com.bernard.greposimu.model.game.researches.Research;
import com.bernard.greposimu.model.game.units.Unit;
import com.bernard.greposimu.model.simulator.Troupes;
import com.bernard.greposimu.model.simulator.Ville;
import com.bernard.greposimu.model.simulator.command.BuildCommand;
import com.bernard.greposimu.model.simulator.command.Command;
import com.bernard.greposimu.model.simulator.command.HideStoreCommand;
import com.bernard.greposimu.model.simulator.command.RecruitCommand;
import com.bernard.greposimu.model.simulator.command.ResearchCommand;
public class TownObjective {
GameConfig gc;
Map<Building,Integer> buildings;
Map<Unit,Double> unitsProportions;
Set<Research> researches;
int hide;
God god;
TownObjective() {}
public TownObjective(GameConfig gc, Map<Building, Integer> buildings, Map<Unit, Double> unitsProportions,
Set<Research> researches, int hide, God god) {
this.gc = gc;
this.buildings = buildings;
this.unitsProportions = unitsProportions;
this.researches = researches;
this.hide = hide;
this.god = god;
}
public static final int villeMaxPop(GameConfig gc, Ville v) {
return GameConfig.getTotalPop(
v.getBatiments().getOrDefault(Building.FARM,0),
v.getBatiments().getOrDefault(Building.THERMAL, 0)>=1,
v.getResearches().contains(gc.getResearch("plow")),
v.getGod().getId().equals("aphrodite"),
0); //TODO take popultion_boost into account
}
public Troupes targetTroupes() {
int popRest = GameConfig.getTotalPop(
this.buildings.getOrDefault(Building.FARM,0),
this.buildings.getOrDefault(Building.THERMAL, 0)>=1,
this.researches.contains(gc.getResearch("plow")),
this.god.getId().equals("aphrodite"),
0) //TODO take popultion_boost into account
-
this.buildings.entrySet().stream().mapToInt(e -> e.getKey().getRequiredPop(e.getValue())).sum();
double totalProp = this.unitsProportions.values().stream().collect(Collectors.summarizingDouble(d -> d)).getSum();
return new Troupes(this.unitsProportions.entrySet().stream().collect(Collectors.toMap(
e -> e.getKey(),
e -> (int)Math.floor(e.getValue()*popRest/totalProp/e.getKey().getPopulation()))));
}
public Set<Command> getDifferences(Ville v) {
Set<Command> commands = new HashSet<>();
for(Building b :gc.getBuildings()) {
int cur = v.getBatiments().getOrDefault(b, 0);
int obj = this.buildings.getOrDefault(b, 0);
if(cur != obj) {
if(obj>cur)
for(int i=cur+1;i<=obj;i++)
commands.add(new BuildCommand(v.getId(), null, b, i, false));
else
for(int i=cur-1;i>=obj;i--)
commands.add(new BuildCommand(v.getId(), null, b, i, true));
}
//TODO check queue
}
for(Research r : gc.getResearches()) {
boolean cur = v.getResearches().contains(r);
boolean obj = this.researches.contains(r);
if(cur && !obj)
commands.add(new ResearchCommand(v.getId(),null,r,true));
else if (!cur && obj)
commands.add(new ResearchCommand(v.getId(),null,r,false));
//TODO check queue
}
Troupes tot = Troupes.add(v.getTroupes(),v.getSoutiens().values().stream().reduce(Troupes::add).orElse(new Troupes(Map.of())));
Troupes target = this.targetTroupes();
for(Unit u : gc.getUnits()) {
int diff = target.getUnites().getOrDefault(u,0) - tot.getUnites().getOrDefault(u,0);
if(diff > 0)
commands.add(new RecruitCommand(v.getId(), null, u, diff));
//TODO manage unit removal planned
}
if(v.getPiecesStoquees() < hide)
commands.add(new HideStoreCommand(v.getId(), hide - v.getPiecesStoquees()));
return commands;
}
public Map<Building, Integer> getBuildings() {
return buildings;
}
public Map<Unit, Double> getUnitsProportions() {
return unitsProportions;
}
public Set<Research> getResearches() {
return researches;
}
public int getHide() {
return hide;
}
public God getGod() {
return god;
}
@Override
public String toString() {
return "TownObjective [gc=" + gc + ", buildings=" + buildings + ", unitsProportions=" + unitsProportions
+ ", researches=" + researches + ", hide=" + hide + ", god=" + god + "]";
}
}

View File

@ -0,0 +1,183 @@
package com.bernard.greposimu.source;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.bernard.greposimu.GrepoSimu;
import com.bernard.greposimu.model.game.Building;
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.UnitResources;
import com.bernard.greposimu.model.game.powers.Power;
import com.bernard.greposimu.model.game.queues.BuildingQueueItem;
import com.bernard.greposimu.model.game.queues.RecruitmentQueueItem;
import com.bernard.greposimu.model.game.queues.RecruitmentQueueItem.RecruitmentKind;
import com.bernard.greposimu.model.game.queues.ResearchQueueItem;
import com.bernard.greposimu.model.game.researches.Research;
import com.bernard.greposimu.model.game.units.Unit;
import com.bernard.greposimu.model.runtime.Timestamp;
import com.bernard.greposimu.model.simulator.Joueureuse;
import com.bernard.greposimu.model.simulator.SimulatorData;
import com.bernard.greposimu.model.simulator.Troupes;
import com.bernard.greposimu.model.simulator.Ville;
import com.bernard.greposimu.model.simulator.Ville.TradeOrder;
import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSONSourcer {
public static final void readSource(File file) {
ObjectMapper om = new ObjectMapper();
try {
SourcedData sd = om.readValue(file, SourcedData.class);
System.out.println(sd);
} catch (StreamReadException e) {
e.printStackTrace();
} catch (DatabindException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static final Troupes getTroupes(GameConfig gc, Map<String,Integer> count) {
Map<Unit,Integer> troup = new HashMap<>();
for(String u : count.keySet())troup.put(gc.getUnit(u), count.get(u));
return new Troupes(troup);
}
public static final Resources getResources(SourcedRessources res) {
return new Resources(res.wood, res.stone, res.iron);
}
public static final UnitResources getUnitResources(God god, SourcedFavRessources res) {
return new UnitResources(res.wood, res.stone, res.iron,god,res.favor);
}
public static final SimulatorData makeSimulationData(File file, GameConfig gc) {
ObjectMapper om = new ObjectMapper();
try {
SourcedData sd = om.readValue(file, SourcedData.class);
Map<String,Ville> villes = new HashMap<String, Ville>();
for(String idS : sd.towns.keySet()) {
Integer id = Integer.parseInt(idS);
SourcedTown st = sd.getTowns().get(idS);
Map<Building,Integer> buildings = new HashMap<>();
for(String bid : st.buildings.keySet())buildings.put(gc.getBuilding(bid), st.buildings.get(bid));
Set<Research> researches = new HashSet<>();
for(String rid : st.researches.keySet())if(st.researches.get(rid))researches.add(gc.getResearch(rid));
Map<Integer,Troupes> soutiens = new HashMap<Integer, Troupes>();
Map<Integer,Troupes> soutenus = new HashMap<Integer, Troupes>();
for(SourcedUnits uts : sd.units) {
if(uts.orig == id && uts.curr != id)
soutiens.put(uts.curr, getTroupes(gc, uts.getUnits()));
if(uts.curr == id && uts.orig != id)
soutenus.put(uts.orig, getTroupes(gc, uts.getUnits()));
}
List<BuildingQueueItem> buildingQueue = new ArrayList<>();
for(SourcedBuildingOrder sbo : st.buildingOrders)
buildingQueue.add(new BuildingQueueItem(
sbo.getBuildingTime(),
gc.getBuilding(sbo.building),
sbo.isTearingDown(),
new Timestamp(sbo.getBeginTime()),
new Timestamp(sbo.getEndTime()),
getResources(sbo.getRefund()),
getResources(sbo.getCost())
));
List<RecruitmentQueueItem> terrestrialQueue = new ArrayList<>();
List<RecruitmentQueueItem> navalQueue = new ArrayList<>();
for(SourcedRecruitmentOrder sro : st.recruitingOrders) {
Unit u = gc.getUnit(sro.unit);
RecruitmentQueueItem rqi = new RecruitmentQueueItem(
sro.getKind().equals("ground")?RecruitmentKind.GROUND:RecruitmentKind.NAVAL,
u,
sro.getCount(),
sro.getDone(),
new Timestamp(sro.getBeginTime()),
new Timestamp(sro.getEndTime()),
getUnitResources(u.isMythological()?u.getGod():null, sro.getRefund()),
getUnitResources(null, sro.getCost())
);
if(sro.kind.equals("ground"))
terrestrialQueue.add(rqi);
else if(sro.kind.equals("naval"))
navalQueue.add(rqi);
}
List<ResearchQueueItem> researchQueue = new ArrayList<>();
for(SourcedResearchOrder sro : st.researchOrders)
researchQueue.add(new ResearchQueueItem(
gc.getResearch(sro.getResearch()),
new Timestamp(sro.getBeginTime()),
new Timestamp(sro.getEndTime()),
getResources(sro.getRefund())
));
Map<Power,Timestamp> sortileges = new HashMap<>();
for(SourcedCastedPower sp : st.castedPowers) {
//TODO
}
Set<TradeOrder> incomingTrade = new HashSet<>();
Set<TradeOrder> outgoingTrade = new HashSet<>();
for(SourcedTrades str : sd.trades) {
//TODO support farmtowns
if(str.destType.equals("town_trade") && str.origType.equals("town_trade")){
if(Integer.parseInt(str.dest) == id)
incomingTrade.add(new TradeOrder(new Resources(str.getWood(), str.getStone(), str.getIron()), Integer.parseInt(str.orig)));
if(Integer.parseInt(str.orig) == id)
incomingTrade.add(new TradeOrder(new Resources(str.getWood(), str.getStone(), str.getIron()), Integer.parseInt(str.dest)));
}
}
Set<SourcedCelebration> townCele = sd.celebrations.stream().filter(c -> c.getTown() == id).collect(Collectors.toSet());
villes.put(st.name, new Ville(
id,
st.name,
buildings,
getTroupes(gc, st.getUnitsTotal()),
soutiens,
soutenus,
sortileges,
townCele.stream().filter(c -> c.type.equals("party")).map(SourcedCelebration::getEnd).map(Timestamp::new).findAny().orElse(null),
townCele.stream().filter(c -> c.type.equals("games")).map(SourcedCelebration::getEnd).map(Timestamp::new).findAny().orElse(null),
townCele.stream().filter(c -> c.type.equals("triumph")).map(SourcedCelebration::getEnd).map(Timestamp::new).findAny().orElse(null),
townCele.stream().filter(c -> c.type.equals("theater")).map(SourcedCelebration::getEnd).map(Timestamp::new).findAny().orElse(null),
researches,
researchQueue,
buildingQueue,
st.getMilitia()==null?null:new Timestamp(st.getMilitia().getEnd()),
new Resources(st.getResources().wood, st.getResources().stone, st.getResources().iron),
terrestrialQueue,
gc.getGod(st.god),
navalQueue,
st.espstorage,
null,//ordresMilitaires,
incomingTrade,
outgoingTrade));
}
Joueureuse joueureuse = new Joueureuse(null, 0, 0, null, null, null, null, null, null, null, null, null);
return new SimulatorData(villes, joueureuse);
} catch (StreamReadException e) {
e.printStackTrace();
} catch (DatabindException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,46 @@
package com.bernard.greposimu.source;
public class SourcedBuildingOrder {
@Override
public String toString() {
return "SourcedBuildingOrder [buildingTime=" + buildingTime + ", building=" + building + ", beginTime="
+ beginTime + ", tearingDown=" + tearingDown + ", endTime=" + endTime + ", refund=" + refund + ", cost="
+ cost + "]";
}
long buildingTime;
// the id of the building being built
String building;
long beginTime;
boolean tearingDown;
long endTime;
SourcedRessources refund;
SourcedRessources cost;
public long getBuildingTime() {
return buildingTime;
}
public String getBuilding() {
return building;
}
public long getBeginTime() {
return beginTime;
}
public boolean isTearingDown() {
return tearingDown;
}
public long getEndTime() {
return endTime;
}
public SourcedRessources getRefund() {
return refund;
}
public SourcedRessources getCost() {
return cost;
}
}

View File

@ -0,0 +1,37 @@
package com.bernard.greposimu.source;
public class SourcedCastedPower {
Object configuration;
Long endTime;
int extended;
Integer level;
Long originPlayer;
String power;
@Override
public String toString() {
return "SourcedCastedPower [configuration=" + configuration + ", endTime=" + endTime + ", extended=" + extended
+ ", level=" + level + ", originPlayer=" + originPlayer + ", power=" + power + "]";
}
public Object getConfiguration() {
return configuration;
}
public Long getEndTime() {
return endTime;
}
public int getExtended() {
return extended;
}
public Integer getLevel() {
return level;
}
public Long getOriginPlayer() {
return originPlayer;
}
public String getPower() {
return power;
}
}

View File

@ -0,0 +1,18 @@
package com.bernard.greposimu.source;
public class SourcedCelebration {
int town;
String type;
long end;
public int getTown() {
return town;
}
public String getType() {
return type;
}
public long getEnd() {
return end;
}
}

View File

@ -0,0 +1,40 @@
package com.bernard.greposimu.source;
import java.util.List;
import java.util.Map;
public class SourcedData {
Map<String,SourcedTown> towns;
List<SourcedCelebration> celebrations;
List<SourcedMilitaryOrders> movements;
List<SourcedTrades> trades;
Map<String,Integer> favors;
List<SourcedUnits> units;
public Map<String, SourcedTown> getTowns() {
return towns;
}
public List<SourcedCelebration> getCelebrations() {
return celebrations;
}
public List<SourcedMilitaryOrders> getMovements() {
return movements;
}
public List<SourcedTrades> getTrades() {
return trades;
}
public Map<String, Integer> getFavors() {
return favors;
}
public List<SourcedUnits> getUnits() {
return units;
}
@Override
public String toString() {
return "SourcedData [towns=" + towns + ", celebrations=" + celebrations + ", movements=" + movements
+ ", trades=" + trades + ", favors=" + favors + "]";
}
}

View File

@ -0,0 +1,31 @@
package com.bernard.greposimu.source;
public class SourcedFavRessources {
int wood;
int iron;
int stone;
int favor;
int pop;
public int getWood() {
return wood;
}
public int getIron() {
return iron;
}
public int getStone() {
return stone;
}
public int getFavor() {
return favor;
}
public int getPop() {
return pop;
}
@Override
public String toString() {
return "SourcedFavRessources [wood=" + wood + ", iron=" + iron + ", stone=" + stone + ", favor=" + favor
+ ", pop=" + pop + "]";
}
}

View File

@ -0,0 +1,51 @@
package com.bernard.greposimu.source;
public class SourcedMilitaryOrders {
long start;
long arrival;
long cancelableUntil;
long invisibleUntil;
boolean destIsAttackSpot;
boolean origIsAttackSpot;
int player;
int homeId;
int targetId;
String type;
public long getArrival() {
return arrival;
}
public long getCancelableUntil() {
return cancelableUntil;
}
public long getInvisibleUntil() {
return invisibleUntil;
}
public boolean isDestIsAttackSpot() {
return destIsAttackSpot;
}
public boolean isOrigIsAttackSpot() {
return origIsAttackSpot;
}
public int getHomeId() {
return homeId;
}
public int getPlayer() {
return player;
}
public long getStart() {
return start;
}
public int getTargetId() {
return targetId;
}
public String getType() {
return type;
}
}

View File

@ -0,0 +1,13 @@
package com.bernard.greposimu.source;
public class SourcedMilitiaTimes {
long start;
long end;
public long getStart() {
return start;
}
public long getEnd() {
return end;
}
}

View File

@ -0,0 +1,49 @@
package com.bernard.greposimu.source;
public class SourcedRecruitmentOrder {
int count;
int done;
String kind;
// the id of the building being built
String unit;
long beginTime;
long endTime;
SourcedFavRessources refund;
SourcedFavRessources cost;
public int getCount() {
return count;
}
public int getDone() {
return done;
}
public String getKind() {
return kind;
}
public String getUnit() {
return unit;
}
public long getBeginTime() {
return beginTime;
}
public long getEndTime() {
return endTime;
}
public SourcedFavRessources getRefund() {
return refund;
}
public SourcedFavRessources getCost() {
return cost;
}
@Override
public String toString() {
return "SourcedRecruitmentOrder [count=" + count + ", done=" + done + ", kind=" + kind + ", unit=" + unit
+ ", beginTime=" + beginTime + ", endTime=" + endTime + ", refund=" + refund + ", cost=" + cost + "]";
}
}

View File

@ -0,0 +1,31 @@
package com.bernard.greposimu.source;
public class SourcedResearchOrder {
// the id of the building being built
String research;
long beginTime;
long endTime;
SourcedRessources refund;
public String getResearch() {
return research;
}
public long getBeginTime() {
return beginTime;
}
public long getEndTime() {
return endTime;
}
public SourcedRessources getRefund() {
return refund;
}
}

View File

@ -0,0 +1,22 @@
package com.bernard.greposimu.source;
public class SourcedRessources {
int wood;
int iron;
int stone;
@Override
public String toString() {
return "SourcedRessources [wood=" + wood + ", iron=" + iron + ", stone=" + stone + "]";
}
public int getWood() {
return wood;
}
public int getIron() {
return iron;
}
public int getStone() {
return stone;
}
}

View File

@ -0,0 +1,95 @@
package com.bernard.greposimu.source;
import java.util.List;
import java.util.Map;
public class SourcedTown {
String name;
int points;
String god;
SourcedTownResources resources;
int espstorage;
/* GLOBAL UNITS */
// unit_id -> number of units
// TOTAL units defending this city
Map<String,Integer> unitsTotal;
// TOTAL units from this city defending another city
Map<String,Integer> outerTotal;
// TOTAL units from other cities defending this city
Map<String,Integer> supportTotal;
// building_id -> level
Map<String,Integer> buildings;
// research_id -> hasBeenResearched
Map<String,Boolean> researches;
List<SourcedCastedPower> castedPowers;
List<SourcedBuildingOrder> buildingOrders;
List<SourcedRecruitmentOrder> recruitingOrders;
List<SourcedResearchOrder> researchOrders;
SourcedMilitiaTimes militia;
public String getName() {
return name;
}
public int getPoints() {
return points;
}
public Map<String, Integer> getUnitsTotal() {
return unitsTotal;
}
public Map<String, Integer> getOuterTotal() {
return outerTotal;
}
public Map<String, Integer> getSupportTotal() {
return supportTotal;
}
public Map<String, Integer> getBuildings() {
return buildings;
}
public Map<String, Boolean> getResearches() {
return researches;
}
public List<SourcedCastedPower> getCastedPowers() {
return castedPowers;
}
public List<SourcedBuildingOrder> getBuildingOrders() {
return buildingOrders;
}
public List<SourcedRecruitmentOrder> getRecruitingOrders() {
return recruitingOrders;
}
public List<SourcedResearchOrder> getResearchOrders() {
return researchOrders;
}
public SourcedTownResources getResources() {
return resources;
}
public int getEspstorage() {
return espstorage;
}
public SourcedMilitiaTimes getMilitia() {
return militia;
}
public String getGod() {
return god;
}
@Override
public String toString() {
return "SourcedTown [name=" + name + ", points=" + points + ", god=" + god + ", resources=" + resources
+ ", espstorage=" + espstorage + ", unitsTotal=" + unitsTotal + ", outerTotal=" + outerTotal
+ ", supportTotal=" + supportTotal + ", buildings=" + buildings + ", researches=" + researches
+ ", castedPowers=" + castedPowers + ", buildingOrders=" + buildingOrders + ", recruitingOrders="
+ recruitingOrders + ", researchOrders=" + researchOrders + ", militia=" + militia + "]";
}
}

View File

@ -0,0 +1,39 @@
package com.bernard.greposimu.source;
public class SourcedTownResources {
int wood,stone,iron,storage,population,favor;
public int getWood() {
return wood;
}
public int getStone() {
return stone;
}
public int getIron() {
return iron;
}
public int getStorage() {
return storage;
}
public int getPopulation() {
return population;
}
@Override
public String toString() {
return "SourcedTownResources [wood=" + wood + ", stone=" + stone + ", iron=" + iron + ", storage=" + storage
+ ", population=" + population + ", favor=" + favor + "]";
}
public int getFavor() {
return favor;
}
}

View File

@ -0,0 +1,66 @@
package com.bernard.greposimu.source;
public class SourcedTrades {
long start;
long arrival;
String dest;
String destType;
String orig;
String origType;
int gold,stone,wood,iron;
boolean exchange;
public long getStart() {
return start;
}
public long getArrival() {
return arrival;
}
public String getDest() {
return dest;
}
public String getDestType() {
return destType;
}
public String getOrig() {
return orig;
}
public String getOrigType() {
return origType;
}
public int getGold() {
return gold;
}
public int getStone() {
return stone;
}
public int getWood() {
return wood;
}
public int getIron() {
return iron;
}
public boolean isExchange() {
return exchange;
}
@Override
public String toString() {
return "SourcedTrades [start=" + start + ", arrival=" + arrival + ", dest=" + dest + ", destType=" + destType
+ ", orig=" + orig + ", origType=" + origType + ", gold=" + gold + ", stone=" + stone + ", wood=" + wood
+ ", iron=" + iron + ", exchange=" + exchange + "]";
}
}

View File

@ -0,0 +1,23 @@
package com.bernard.greposimu.source;
import java.util.Map;
public class SourcedUnits {
int orig;
int curr;
Map<String,Integer> units;
boolean sameIsland;
public int getOrig() {
return orig;
}
public int getCurr() {
return curr;
}
public Map<String, Integer> getUnits() {
return units;
}
public boolean isSameIsland() {
return sameIsland;
}
}

View File

@ -1,11 +1,183 @@
function downloadObjectAsJson(exportObj, exportName){
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj,null,2));
var downloadAnchorNode = document.createElement('a');
downloadAnchorNode.setAttribute("href", dataStr);
downloadAnchorNode.setAttribute("download", exportName + ".json");
document.body.appendChild(downloadAnchorNode); // required for firefox
downloadAnchorNode.click();
downloadAnchorNode.remove();
}
function getAllFragments() {
out = {}
for(var storename in ITowns){
if(typeof ITowns[storename] === 'object' && "fragments" in ITowns[storename]){
out[storename] = {}
store = ITowns[storename].fragments
for(var townid in store) {
out[storename][townid] = []
for(var i = 0; i < store[townid].models.length;i++){
out[storename][townid].push(store[townid].models[i].attributes)
}
}
}
}
return out
}
function makeObject() {
out = {}
for(var townid in ITowns.towns) {
out[townid] = {}
out[townid].units = ITowns.towns[townid].units()
out[townid].support = ITowns.towns[townid].unitsSupport()
out[townid].outer = ITowns.towns[townid].unitsOuter()
out[townid].name = ITowns.towns[townid].name
out[townid].points = ITowns.towns[townid].points
out[townid].god = ITowns.towns[townid].god()
out[townid].unitsTotal = ITowns.towns[townid].units()
out[townid].supportTotal = ITowns.towns[townid].unitsSupport()
out[townid].outerTotal = ITowns.towns[townid].unitsOuter()
out[townid].resources = ITowns.towns[townid].resources()
out[townid].buildings = ITowns.towns[townid].buildings().getBuildings()
out[townid].buildings = ITowns.towns[townid].getBuildings().getBuildings()
out[townid].researches = ITowns.towns[townid].researches().attributes
out[townid].espstorage = ITowns.towns[townid].getEspionageStorage()
orderz = ITowns.towns[townid].buildingOrders()
out[townid].buildingOrders = []
for(var i = 0; i<orderz.length;i++) {
order = orderz.models[i].attributes
out[townid].buildingOrders.push({
buildingTime: order.building_time,
building: order.building_type,
beginTime: order.created_at,
tearingDown: order.tear_down,
endTime: order.to_be_completed_at,
refund: order.cancel_refund,
cost: {wood: order.wood, stone: order.stone, iron: order.iron}
})
}
var json = JSON.stringify(out)
recruitments = ITowns.all_remaining_unit_orders.fragments[townid]
out[townid].recruitingOrders = []
for(var i = 0; i<recruitments.models.length; i++) {
order = recruitments.models[i].attributes
out[townid].recruitingOrders.push({
count: order.count,
beginTime: order.created_at,
kind: order.kind,
done: order.parts_done,
refund: order.refund_for_single_unit,
endTime: order.to_be_completed_at,
unit: order.unit_type,
cost: {wood: order.wood, stone: order.stone, iron: order.iron, favor: order.favor}
})
}
castedPowers = ITowns.all_casted_powers.fragments[townid]
out[townid].castedPowers = []
for(var i = 0; i<castedPowers.models.length; i++) {
order = castedPowers.models[i].attributes
out[townid].castedPowers.push({
configuration: order.configuration,
endTime: order.to_be_completed_at,
extended: order.extended,
level: order.level,
originPlayer: order.origin_player_id,
power: order.power_id
})
}
researches = MM.getTownAgnosticCollectionsByName("ResearchOrder")[0].fragments[townid]
out[townid].researchOrders = []
for(var i = 0; i<researches.models.length; i++) {
order = researches.models[i].attributes
out[townid].researchOrders.push({
research: order.research_type,
beginTime: order.created_at,
endTime: order.to_be_completed_at,
refund: order.cancel_refund
})
}
/*
militia = MM.getModels().Militia
if(townid in militia){
out[townid].militia = {
start : militia[townid].attributes.started_at,
end: militia[townid].attributes.finished_at
}
} else {
out[townid].militia = null
}*/
out[townid].militia = null
}
celebrations = MM.getModels().Celebration
outCele = []
for (var i in celebrations) {
outCele.push({
town: celebrations[i].attributes.townid,
type: celebrations[i].attributes.celebration_type,
end: celebrations[i].attributes.finished_at,
})
}
mvts = MM.getModels().MovementsUnits
outMvts = []
for (var i in mvts) {
mvt = mvts[i].attributes
outMvts.push({
arrival: mvt.arrival_at,
cancelableUntil: mvt.cancelable_until,
invisibleUntil: mvt.cap_of_invisibility_effective_until,
destIsAttackSpot: mvt.destination_is_attack_spot,
origIsAttackSpot: mvt.origin_is_attack_spot,
homeId: mvt.home_town_id ,
player: mvt.player_id,
start: mvt.started_at,
targetId: mvt.target_town_id,
type: mvt.type,
})
trdz = MM.getModels().Trade
outTrd = []
for (var i in trdz) {
trd = trdz[i].attributes
outTrd.push({
start: trd.started_at,
arrival: trd.arrival_at,
dest: trd.destination_town_id,
destType: trd.destination_town_type,
gold: trd.gold,
stone: trd.stone,
wood: trd.wood,
iron: trd.iron,
orig: trd.origin_town_id,
origType: trd.origin_town_type,
exchange: trd.in_exchange
})
}
}
fav = MM.getModels().PlayerGods[Object.keys(MM.getModels().PlayerGods)[0]].attributes
outFav = {
aphrodite: fav.aphrodite_favor,
ares: fav.ares_favor,
artemis: fav.artemis_favor,
athena: fav.athena_favor,
fury: fav.fury,
hades: fav.hades_favor,
hera: fav.hera_favor,
poseidon: fav.poseidon_favor,
zeus: fav.zeus_favor
}
utz = MM.getModels().Units
outUts = []
for (var i in utz) {
outUts.push({
orig: utz[i].getOriginTownId(),
curr: utz[i].getCurrentTownId(),
units: utz[i].getUnits(),
sameIsland: utz[i].isSameIsland()
})
}
return {towns: out,celebrations: outCele, movements: outMvts, trades: outTrd, favors: outFav, units: outUts}
}
downloadObjectAsJson(makeObject(),"greposimu")

View File

@ -1,16 +1,85 @@
package com.bernard.greposimu;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import com.bernard.greposimu.model.game.GameConfig;
import com.bernard.greposimu.model.game.GrepoYaml;
import com.bernard.greposimu.model.game.units.Unit;
import com.bernard.greposimu.model.simulator.SimulatorData;
import com.bernard.greposimu.model.simulator.objective.TownObjective;
import com.bernard.greposimu.source.JSONSourcer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
@SpringBootTest
class GrepoSimuApplicationTests {
@Test
void loadGameData() throws IOException {
System.out.println(GrepoSimu.makeGameData());
// System.out.println(GrepoSimu.makeGameData());
}
@Test
void testJsonRead() throws IOException {
System.out.println("Test de sérialisation :");
GameConfig gc = GrepoSimu.makeGameData();
SimulatorData sd = JSONSourcer.makeSimulationData(new File("/home/mysaa/Downloads/greposimu.json"),gc);
//System.out.println(sd);
}
TownObjective testObjective(GameConfig gc) {
return new TownObjective(gc, Map.of(
gc.getBuilding("main"), 24,
gc.getBuilding("wall"), 25,
gc.getBuilding("farm"), 45,
gc.getBuilding("academy"), 20,
gc.getBuilding("docks"), 1,
gc.getBuilding("barracks"), 30),
Map.of(
gc.getUnit("sword"), 8.0,
gc.getUnit("archer"), 8.0,
gc.getUnit("hoplite"), 16.0,
gc.getUnit("big_transporter"),7.0),
Set.of(
gc.getResearch("hoplite"),
gc.getResearch("archer"),
gc.getResearch("conscription")),
100_000,
gc.getGod("poseidon"));
}
@Test
void testDifferences() throws IOException {
GameConfig gc = GrepoSimu.makeGameData();
SimulatorData sd = JSONSourcer.makeSimulationData(new File("/home/mysaa/Downloads/greposimu.json"),gc);
System.out.println(gc.getUnits().stream().map(Unit::getId).collect(Collectors.joining(",")));
TownObjective defObjective = testObjective(gc);
/*
for(Ville v : sd.getVilles().values()) {
System.out.println("==== Ville "+v.getNom()+" ====");
System.out.println(defObjective.getDifferences(v).stream().map(Command::toString).sorted().collect(Collectors.joining("\n")));
}*/
}
@Test
void writeTestObjective() throws IOException {
ObjectMapper om = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER));
GameConfig gc = GrepoSimu.makeGameData();
om.registerModule(new GrepoYaml(gc));
om.writeValue(new File("/tmp/out.yml"), testObjective(gc));
TownObjective newObjective = om.readValue(new File("/tmp/out.yml"), TownObjective.class);
System.out.println("READ VALUE");
System.out.println(newObjective);
}
}

View File

@ -0,0 +1,67 @@
defTerTown:
buildings:
main: 24
lumber: 40
farm: 45
stoner: 40
storage: 35
ironer: 40
barracks: 30
temple: 10
market: 15
docks: 1
academy: 25
wall: 25
hide: 10
tower: 1
thermal: 1
unitsProportions:
sword: 8.0
big_transporter: 7.0
hoplite: 16.0
archer: 8.0
researches:
- "archer"
- "town_guard"
- "hoplite"
- "pottery"
- "instructor"
- "crane"
- "conscription"
- "cryptography"
- "plow"
- "berth"
- "phalanx"
hide: 100000
god: "ares"
defNavTown:
buildings:
main: 24
lumber: 40
farm: 45
stoner: 40
storage: 35
ironer: 40
barracks: 1
temple: 10
market: 15
docks: 30
academy: 28
wall: 0
hide: 10
thermal: 1
unitsProportions:
bireme: 1.0
researches:
- "town_guard"
- "pottery"
- "bireme"
- "shipwright"
- "cryptography"
- "plow"
- "mathematics"
- "ram"
- "cartography"
hide: 100000
god: "poseidon"