/** * Takes the "on" cells in this GreasedRegion and retracts them by one cell in the 4 orthogonal directions, doing * this iteeratively amount times, making each "on" cell that was within amount orthogonal distance to an "off" cell * into an "off" cell. * <br> * This method is very efficient due to how the class is implemented, and the various spatial increase/decrease * methods (including {@link #expand()}, {@link #retract()}, {@link #fringe()}, and {@link #surface()}) all perform * very well by operating in bulk on up to 64 cells at a time. * @return this for chaining */ public GreasedRegion retract(int amount) { for (int i = 0; i < amount; i++) { retract(); } return this; }
allCorridors = new GreasedRegion(width, height); caves.put(allCaves, new ArrayList<GreasedRegion>()); connections = mouths = allCaves.copy().andNot(allCaves.copy().retract8way()).retract().asCoords(); doorways = new Coord[0]; environment = allCaves.writeInts(environment, DungeonUtility.CAVE_FLOOR);
public ArrayList<GreasedRegion> retractSeriesToLimit() { ArrayList<GreasedRegion> regions = new ArrayList<>(); GreasedRegion temp = new GreasedRegion(this); while (!temp.retract().isEmpty()) { regions.add(new GreasedRegion(temp)); } return regions; }
public GreasedRegion surface() { GreasedRegion cpy = new GreasedRegion(this).retract(); return xor(cpy); } public GreasedRegion surface(int amount)
public GreasedRegion surface(int amount) { GreasedRegion cpy = new GreasedRegion(this).retract(amount); return xor(cpy); }
public GreasedRegion[] retractSeries(int amount) { if(amount <= 0) return new GreasedRegion[0]; GreasedRegion[] regions = new GreasedRegion[amount]; GreasedRegion temp = new GreasedRegion(this); for (int i = 0; i < amount; i++) { regions[i] = new GreasedRegion(temp.retract()); } return regions; }
public double rateDensity() { double sz = height * width; if(sz == 0) return 0; double onAmount = sz - size(), retractedOn = sz - copy().retract().size(); return (onAmount + retractedOn) / (sz * 2.0); } public double rateRegularity()
int w = (width << 1) + 2, h = (height << 1) + 2; GreasedRegion[] regions = new GreasedRegion[]{ new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3) }; int[][] data = GreasedRegion.bitSum(regions); new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3) }; int[][] data2 = GreasedRegion.bitSum(regions), data3 = new int[width][height];
/** * Like {@link #retract()}, this removes the "on" cells that are 4-way-adjacent to any "off" cell, but unlike that * method it keeps a fraction of those surface cells, quasi-randomly selecting them. This can be thought of as * running {@link #surface()} on a copy of this GreasedRegion, running {@link #quasiRandomRegion(double)} on that * surface with the given fractionKept, taking the original GreasedRegion and removing its whole surface with * {@link #retract()}, then inserting the quasi-randomly-removed surface into this GreasedRegion to replace its * surface with a randomly "damaged" one. * @param fractionKept the fraction between 0.0 and 1.0 of how many cells on the outer surface of this to keep "on" * @return this for chaining */ public GreasedRegion fray(double fractionKept) { GreasedRegion cpy = new GreasedRegion(this).retract(); return xor(cpy).quasiRandomRegion(1.0 - fractionKept).or(cpy); }
public GreasedRegion[] surfaceSeries(int amount) { if(amount <= 0) return new GreasedRegion[0]; GreasedRegion[] regions = new GreasedRegion[amount]; GreasedRegion temp = new GreasedRegion(this); regions[0] = new GreasedRegion(temp); for (int i = 1; i < amount; i++) { regions[i] = new GreasedRegion(temp.retract()); } for (int i = 0; i < amount - 1; i++) { regions[i].xor(regions[i + 1]); } regions[amount - 1].surface(); return regions; }
/** * Like {@link #retract()}, this reduces the width of thick areas of this GreasedRegion, but thin() will not remove * areas that would be identical in a subsequent call to retract(), such as if the area would be eliminated. This * is useful primarily for adjusting areas so they do not exceed a width of 2 cells, though their length (the longer * of the two dimensions) will be unaffected by this. Especially wide, irregularly-shaped areas may have unintended * appearances if you call this repeatedly or use {@link #thinFully()}; consider using this sparingly, or primarily * when an area has just gotten thicker than desired. * <br> * This currently uses 4-way adjacency, but had previously used 8-way; if you want the behavior this previously had, * you can use {@link #thin8way()}, but it may be a good idea to try this method as well (some of the old behavior * had problems where it yielded significantly larger minimum widths in some areas). * @return this for chaining */ public GreasedRegion thin() { if(width <= 2 || ySections <= 0) return this; GreasedRegion c1 = new GreasedRegion(this).retract(), c2 = new GreasedRegion(c1).expand().xor(this).expand().and(this); remake(c1).or(c2); /* System.out.println("\n\nc1:\n" + c1.toString() + "\n"); System.out.println("\n\nc2:\n" + c2.toString() + "\n"); System.out.println("\n\nthis:\n" + toString() + "\n"); */ return this; }
/** * Gets an OrderedSet of OrderedSet of Coord, where each inner OrderedSet of Coord refers to a placement * region along a straight wall with length 3 or more, not including corners. Each Coord refers to a single cell * along the straight wall. This could be useful for placing weapon racks in armories, chalkboards in schoolrooms * (tutorial missions, perhaps?), or even large paintings/murals in palaces. * @return a set of sets of Coord where each set of Coord is a wall's viable placement for long things along it */ public OrderedSet<OrderedSet<Coord>> getAlongStraightWalls() { if(alongStraightWalls == null) { alongStraightWalls = new OrderedSet<>(32); GreasedRegion working = new GreasedRegion(finder.width, finder.height); for(GreasedRegion region : finder.rooms.keySet()) { working.remake(region).retract().fringe().andNot(nonRoom); for (GreasedRegion sp : working.split()) { if (sp.size() >= 3) alongStraightWalls.add(arrayToSet(sp.asCoords())); } } } return alongStraightWalls; }
GreasedRegion bounds = new GreasedRegion(width, height).not().retract(5), smallerBounds = bounds.copy().retract(5), area = new GreasedRegion(width, height), tmpEdge = new GreasedRegion(width, height), tmpInner = new GreasedRegion(width, height), tmpOOB = new GreasedRegion(width, height); int volume = 10 + (height * width) / (aLen * 2); area.empty().insert(pts[i]).spill(bounds, volume, rng).expand(3); tmpInner.remake(area).retract(4).expand8way().and(area); tmpEdge.remake(area).surface8way(); Coord[] edges = tmpEdge.mixedRandomSeparated(0.35); map.retract(1); OrderedSet<Coord> peaks = new OrderedSet<>(mountains = map.quasiRandomSeparated(0.4, rng.between(100, 150))); int peakCount = peaks.size();