diff --git a/.gitignore b/.gitignore index 6e48a5e..3f62c9c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ out .metadata .idea Metropolis.iml -bin metropolis.properties diff --git a/src/ch/k42/metropolis/grid/urbanGrid/districts/District.java b/src/ch/k42/metropolis/grid/urbanGrid/districts/District.java index 41338d3..961b043 100644 --- a/src/ch/k42/metropolis/grid/urbanGrid/districts/District.java +++ b/src/ch/k42/metropolis/grid/urbanGrid/districts/District.java @@ -44,44 +44,40 @@ private Parcel placeRandom(Cartesian2D base,Cartesian2D size){ Direction direction = findRoad(base, size); List clips = grid.getClipboardProvider().getFit(size, context, direction); if(clips.size()!=0){ // can we place anything? - Collections.shuffle(clips); + List sums = new LinkedList<>(); for(Clipboard c : clips){ - if(grid.getRandom().getChance(c.getConfig().getOddsOfAppearance())){ - return new ClipboardParcel(grid, base.X, base.Y, size.X, size.Y, c, context, direction); - } + sums.add(c.getConfig().getOddsOfAppearance()); } + return new ClipboardParcel(grid, base.X, base.Y, size.X, size.Y, clips.get(Minions.getRandomWeighted(sums,grid.getRandom())), context, direction); } return null; } - private Parcel placeRandomForSure(Cartesian2D base,Cartesian2D size){ + private Parcel placeRandom(Cartesian2D base,Cartesian2D size,int buildChance){ + if(!(grid.getRandom().getChance(buildChance))) return null; Direction direction = findRoad(base, size); List clips = grid.getClipboardProvider().getFit(size, context, direction); if(clips.size()!=0){ // can we place anything? - Collections.shuffle(clips); - for(int i=0;i<20;i++){ - for(Clipboard c : clips){ - if(grid.getRandom().getChance(c.getConfig().getOddsOfAppearance())){ - return new ClipboardParcel(grid, base.X, base.Y, size.X, size.Y, c, context, direction); - } - } + List sums = new LinkedList<>(); + for(Clipboard c : clips){ + sums.add(c.getConfig().getOddsOfAppearance()); } - Bukkit.getLogger().info("Couldn't place schem for sure! Tried 20 times, but all odds failed me."); - // you failed! just take the first one - return new ClipboardParcel(grid, base.X, base.Y, size.X, size.Y, clips.get(0), context, direction); + return new ClipboardParcel(grid, base.X, base.Y, size.X, size.Y, clips.get(Minions.getRandomWeighted(sums,grid.getRandom())), context, direction); } return null; } + private static final int BUILD_CHANCE = 80; + private int recPartitionX(Set parcels,Cartesian2D base, Cartesian2D size){ Parcel parcel; if(size.X<2){ // can't make smaller - if((parcel=placeRandom(base,size))!=null){ + if((parcel=placeRandom(base,size,BUILD_CHANCE))!=null){ parcels.add(parcel); return Minions.square(size.X * size.Y); } if(size.Y<2){ - if((parcel=placeRandomForSure(base,size))==null){ + if((parcel=placeRandom(base, size))==null){ parcels.add(new EmptyParcel(grid,base.X,base.Y,size.X,size.Y)); return 0; }else { @@ -91,7 +87,7 @@ private int recPartitionX(Set parcels,Cartesian2D base, Cartesian2D size } return recPartitionZ(parcels,base, size); }else { - if((parcel=placeRandom(base,size))!=null){ + if((parcel=placeRandom(base,size,BUILD_CHANCE))!=null){ parcels.add(parcel); return Minions.square(size.X * size.Y); }else { @@ -107,12 +103,12 @@ private int recPartitionX(Set parcels,Cartesian2D base, Cartesian2D size private int recPartitionZ(Set parcels,Cartesian2D base, Cartesian2D size){ Parcel parcel; if(size.Y<2){ // can't make smaller - if((parcel=placeRandom(base,size))!=null){ + if((parcel=placeRandom(base,size,BUILD_CHANCE))!=null){ parcels.add(parcel); return Minions.square(size.X * size.Y); } if(size.X<2){ - if((parcel=placeRandomForSure(base,size))==null){ + if((parcel=placeRandom(base, size))==null){ parcels.add(new EmptyParcel(grid,base.X,base.Y,size.X,size.Y)); return 0; }else { @@ -122,7 +118,7 @@ private int recPartitionZ(Set parcels,Cartesian2D base, Cartesian2D size } return recPartitionX(parcels,base, size); }else { - if((parcel=placeRandom(base,size))!=null){ + if((parcel=placeRandom(base,size,BUILD_CHANCE))!=null){ parcels.add(parcel); return Minions.square(size.X * size.Y); }else { diff --git a/src/ch/k42/metropolis/minions/Minions.java b/src/ch/k42/metropolis/minions/Minions.java index 9cb01a7..b196497 100644 --- a/src/ch/k42/metropolis/minions/Minions.java +++ b/src/ch/k42/metropolis/minions/Minions.java @@ -3,8 +3,10 @@ import ch.k42.metropolis.generator.MetropolisGenerator; import org.bukkit.Bukkit; import org.bukkit.World; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.generator.ChunkGenerator; +import sun.util.logging.resources.logging_de; import java.io.*; import java.security.MessageDigest; @@ -119,4 +121,24 @@ public static final int getNormalCut(GridRandom random,double mean, double sigma public static final int square(int x){ return x*x; } + + /** + * Selects a random entry from a List + * + * @param rand a number between [0,SUM] + * @return + */ + public static int getRandomWeighted(List odds,GridRandom rand) { + int[] thresholds = new int[odds.size()]; + thresholds[0] = odds.get(0); + for (int i = 1; i < odds.size(); i++) { + thresholds[i] = thresholds[i-1] + odds.get(i); + } + int random = rand.getRandomInt(thresholds[thresholds.length-1]); + for (int i = 0; i < thresholds.length; i++) { + if (random < thresholds[i]) + return i; + } + return 0; // something went wrong + } }