From 22c770b37b3635c6beacadda6ef71e07c9a55a8e Mon Sep 17 00:00:00 2001 From: Tommy Ettinger Date: Sun, 19 Jun 2016 21:59:15 -0700 Subject: [PATCH] BREAKING: LinkedHash(Map/Set) -> Ordered(Map/Set) This can be fixed in your code, probably, by doing a search/replace for "LinkedHash" and replacing with "Ordered", then importing `squidpony.squidmath.OrderedMap`, `squidpony.squidmath.OrderedSet`, or `squidpony.squidmath.*`, and removing any appearances of `java.util.OrderedMap` or `java.util.OrderedSet` that mistakenly appeared as a result of the replace. You may also need to change calls to `Maker.makeLHM()` to `Maker.makeOM()`, but both methods are available. There aren't many places where a LinkedHashMap was returned as a specific return type of a SquidLib method, but Placement, RegionMap, ModularMapGenerator, MonsterGen, some of CoordPacker, and virtually all of the AOE-related classes (including AreaUtils, Technique, and the related parts of DijkstraMap) now return `OrderedMap`s instead of `LinkedHashMap`s. SoundMap mistakenly returned `HashMap`s when the ordering did matter, so it now returns `OrderedMap`s. This isn't a strictly necessary change to make in the library, but the memory consumption of OrderedSet is better than LinkedHashSet (because it doesn't store wasteful references to unused values in an internal LinkedHashMap), and both Ordered collections allow better random-access-in-some-order traversal of their data. We also gain the ability to change the ordering, possibly in constant time, and the shuffle() method on both collections does this already (though shuffling takes more time on larger collections, and so is not constant-time). An early case where a "better way" is made possible by these data structures is the removal of `convertThreats()` in the display module's CoveredPathDemo, where it was creating a LinkedHashMap with sequential Integer keys to correspond to the already-unique Threat values in a List. This is represented better with an OrderedSet since the sequential ints associated with Threat values are already present in an OrderedSet for indexing; this is also not possible with a LinkedHashSet. OrderedMap and OrderedSet are likely to get continued improvements over time. If this commit breaks more than it should, please post an issue on GitHub. --- .../performance/DijkstraBenchmark.java | 2 +- .../performance/alternate/DijkstraMap.java | 837 +++++++++--------- .../main/java/squidpony/FakeLanguageGen.java | 8 +- .../main/java/squidpony/LanguageCipher.java | 2 +- .../src/main/java/squidpony/MonsterGen.java | 42 +- .../src/main/java/squidpony/squidai/AOE.java | 18 +- .../java/squidpony/squidai/AreaUtils.java | 18 +- .../main/java/squidpony/squidai/BeamAOE.java | 23 +- .../main/java/squidpony/squidai/BlastAOE.java | 19 +- .../main/java/squidpony/squidai/BurstAOE.java | 22 +- .../main/java/squidpony/squidai/CloudAOE.java | 21 +- .../main/java/squidpony/squidai/ConeAOE.java | 21 +- .../java/squidpony/squidai/DijkstraMap.java | 158 ++-- .../main/java/squidpony/squidai/LineAOE.java | 19 +- .../main/java/squidpony/squidai/PointAOE.java | 21 +- .../java/squidpony/squidai/Technique.java | 12 +- .../squidpony/squidai/WaypointPathfinder.java | 43 +- .../src/main/java/squidpony/squidai/ZOI.java | 7 +- .../squidpony/squidgrid/DetailedMimic.java | 21 +- .../java/squidpony/squidgrid/FOVCache.java | 9 +- .../main/java/squidpony/squidgrid/LOS.java | 7 +- .../java/squidpony/squidgrid/MultiSpill.java | 22 +- .../main/java/squidpony/squidgrid/Radius.java | 8 +- .../java/squidpony/squidgrid/SoundMap.java | 56 +- .../java/squidpony/squidgrid/SpatialMap.java | 42 +- .../main/java/squidpony/squidgrid/Spill.java | 22 +- .../squidgrid/mapping/DungeonGenerator.java | 15 +- .../squidgrid/mapping/LanesMapGenerator.java | 8 +- .../mapping/LegacyDungeonGenerator.java | 31 +- .../mapping/ModularMapGenerator.java | 10 +- .../squidgrid/mapping/Placement.java | 40 +- .../squidgrid/mapping/RoomFinder.java | 10 +- .../mapping/SectionDungeonGenerator.java | 18 +- .../mapping/SerpentDeepMapGenerator.java | 28 +- .../mapping/SerpentMapGenerator.java | 8 +- .../mapping/SymmetryDungeonGenerator.java | 29 +- .../java/squidpony/squidmath/CoordPacker.java | 7 +- .../java/squidpony/squidmath/MathExtras.java | 5 +- .../java/squidpony/squidmath/PoissonDisk.java | 5 +- .../squidpony/squidmath/ProbabilityTable.java | 13 +- .../java/squidpony/squidmath/RandomBias.java | 11 +- .../java/squidpony/squidmath/RegionMap.java | 8 +- .../examples/DungeonGeneratorTest.java | 6 +- .../test/java/squidpony/examples/FOVTest.java | 4 +- .../java/squidpony/examples/SpillTest.java | 8 +- .../squidgrid/gui/gdx/SquidLayers.java | 4 +- .../squidgrid/gui/gdx/SquidPanel.java | 12 +- .../squidgrid/gui/gdx/TextCellFactory.java | 11 +- .../gdx/examples/CoveredPathDemo.java | 50 +- .../gdx/examples/EverythingDemo.java | 4 +- .../squidpony/gdx/examples/SquidAIDemo.java | 27 +- 51 files changed, 913 insertions(+), 939 deletions(-) diff --git a/squidlib-performance/src/main/java/squidpony/performance/DijkstraBenchmark.java b/squidlib-performance/src/main/java/squidpony/performance/DijkstraBenchmark.java index a3fb56ec5d..0053751e93 100644 --- a/squidlib-performance/src/main/java/squidpony/performance/DijkstraBenchmark.java +++ b/squidlib-performance/src/main/java/squidpony/performance/DijkstraBenchmark.java @@ -51,7 +51,7 @@ public class DijkstraBenchmark { - public static final int DIMENSION = 60, PATH_LENGTH = (DIMENSION - 2) * (DIMENSION - 2); + public static final int DIMENSION = 100, PATH_LENGTH = (DIMENSION - 2) * (DIMENSION - 2); public static DungeonGenerator dungeonGen = new DungeonGenerator(DIMENSION, DIMENSION, new StatefulRNG(0x1337BEEFDEAL)); public static SerpentMapGenerator serpent = new SerpentMapGenerator(DIMENSION, DIMENSION, diff --git a/squidlib-performance/src/main/java/squidpony/performance/alternate/DijkstraMap.java b/squidlib-performance/src/main/java/squidpony/performance/alternate/DijkstraMap.java index 491c6fc388..6273b094a1 100644 --- a/squidlib-performance/src/main/java/squidpony/performance/alternate/DijkstraMap.java +++ b/squidlib-performance/src/main/java/squidpony/performance/alternate/DijkstraMap.java @@ -2,7 +2,6 @@ import squidpony.GwtCompatibility; import squidpony.annotation.GwtIncompatible; -import squidpony.squidai.Technique; import squidpony.squidai.Threat; import squidpony.squidgrid.*; import squidpony.squidmath.*; @@ -1476,215 +1475,215 @@ public ArrayList findAttackPath(int moveLength, int minPreferredRange, in return new ArrayList<>(path); } - /** - * Scans the dungeon using DijkstraMap.scan with the listed goals and start point, and returns a list - * of Coord positions (using the current measurement) needed to get closer to a goal, where goals are - * considered valid if they are at a valid range for the given Technique to hit at least one target - * and ideal if that Technique can affect as many targets as possible from a cell that can be moved - * to with at most movelength steps. - *
- * The return value of this method is the path to get to a location to attack, but on its own it - * does not tell the user how to perform the attack. It does set the targetMap 2D Coord array field - * so that if your position at the end of the returned path is non-null in targetMap, it will be - * a Coord that can be used as a target position for Technique.apply() . If your position at the end - * of the returned path is null, then an ideal attack position was not reachable by the path. - *
- * This needs a char[][] dungeon as an argument because DijkstraMap does not always have a char[][] - * version of the map available to it, and certain AOE implementations that a Technique uses may - * need a char[][] specifically to determine what they affect. - *
- * The maximum length of the returned list is given by moveLength; if moving the full length of - * the list would place the mover in a position shared by one of the positions in allies - * (which is typically filled with friendly units that can be passed through in multi-tile- - * movement scenarios, and is also used considered an undesirable thing to affect for the Technique), - * it will recalculate a move so that it does not pass into that cell. - *
- * The keys in impassable should be the positions of enemies and obstacles that cannot be moved - * through, and will be ignored if there is a target overlapping one. - *
- * This caches its result in a member field, path, which can be fetched after finding a path and will change with - * each call to a pathfinding method. - * - * @param moveLength the maximum distance to try to pathfind out to; if a spot to use a Technique can be found - * while moving no more than this distance, then the targetMap field in this object will have a - * target Coord that is ideal for the given Technique at the x, y indices corresponding to the - * last Coord in the returned path. - * @param tech a Technique that we will try to find an ideal place to use, and/or a path toward that place. - * @param dungeon a char 2D array with '#' for walls. - * @param los a squidgrid.LOS object if the preferred range should try to stay in line of sight, or null if LoS - * should be disregarded. - * @param impassable locations of enemies or mobile hazards/obstacles that aren't in the map as walls - * @param allies called onlyPassable in other methods, here it also represents allies for Technique things - * @param start the Coord the pathfinder starts at. - * @param targets a Set of Coord, not an array of Coord or variable argument list as in other methods. - * @return an ArrayList of Coord that represents a path to travel to get to an ideal place to use tech. Copy of path. - */ - public ArrayList findTechniquePath(int moveLength, Technique tech, char[][] dungeon, LOS los, - Set impassable, Set allies, Coord start, Set targets) { - if (!initialized) return null; - tech.setMap(dungeon); - double[][] resMap = new double[width][height]; - double[][] worthMap = new double[width][height]; - double[][] userDistanceMap; - double paidLength = 0.0; - - LinkedHashSet friends; - - - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - resMap[x][y] = (physicalMap[x][y] == WALL) ? 1.0 : 0.0; - targetMap[x][y] = null; - } - } - - path.clear(); - if (targets == null || targets.size() == 0) - return new ArrayList<>(path); - LinkedHashSet impassable2; - if (impassable == null) - impassable2 = new LinkedHashSet<>(); - else - impassable2 = new LinkedHashSet<>(impassable); - - if (allies == null) - friends = new LinkedHashSet<>(); - else { - friends = new LinkedHashSet<>(allies); - friends.remove(start); - } - - resetMap(); - setGoal(start); - userDistanceMap = scan(impassable2); - clearGoals(); - resetMap(); - for (Coord goal : targets) { - setGoal(goal.x, goal.y); - } - if (goals.isEmpty()) - return new ArrayList<>(path); - - Measurement mess = measurement; - /* - if(measurement == Measurement.EUCLIDEAN) - { - measurement = Measurement.CHEBYSHEV; - } - */ - scan(impassable2); - clearGoals(); - - Coord tempPt = Coord.get(0, 0); - LinkedHashMap> ideal; - // generate an array of the single best location to attack when you are in a given cell. - for (int x = 0; x < width; x++) { - CELL: - for (int y = 0; y < height; y++) { - tempPt = Coord.get(x, y); - if (gradientMap[x][y] == WALL || gradientMap[x][y] == DARK || userDistanceMap[x][y] > moveLength * 2.0) - continue; - if (gradientMap[x][y] >= tech.aoe.getMinRange() && gradientMap[x][y] <= tech.aoe.getMaxRange()) { - for (Coord tgt : targets) { - if (los == null || los.isReachable(resMap, x, y, tgt.x, tgt.y)) { - ideal = tech.idealLocations(tempPt, targets, friends); - // this is weird but it saves the trouble of getting the iterator and checking hasNext() . - for (Map.Entry> ip : ideal.entrySet()) { - targetMap[x][y] = ip.getKey(); - worthMap[x][y] = ip.getValue().size(); - setGoal(x, y); - gradientMap[x][y] = 0; - break; - } - continue CELL; - } - } - gradientMap[x][y] = FLOOR; - } else - gradientMap[x][y] = FLOOR; - } - } - scan(impassable2); - - double currentDistance = gradientMap[start.x][start.y]; - if (currentDistance <= moveLength) { - Coord[] g_arr = new Coord[goals.size()]; - g_arr = goals.keySet().toArray(g_arr); - - goals.clear(); - setGoal(start); - scan(impassable2); - goals.clear(); - gradientMap[start.x][start.y] = moveLength; - - for (Coord g : g_arr) { - if (gradientMap[g.x][g.y] <= moveLength && worthMap[g.x][g.y] > 0) { - goals.put(g, 0.0 - worthMap[g.x][g.y]); - } - } - resetMap(); - /* for(Coord g : goals.keySet()) - { - gradientMap[g.x][g.y] = 0.0 - worthMap[g.x][g.y]; - }*/ - scan(impassable2); - - } - - measurement = mess; - - Coord currentPos = Coord.get(start.x, start.y); - while (true) { - if (frustration > 500) { - path.clear(); - break; - } - double best = gradientMap[currentPos.x][currentPos.y]; - final Direction[] dirs = appendDir(shuffleDirs(rng), Direction.NONE); - int choice = rng.nextInt(dirs.length); - - for (int d = 0; d < dirs.length; d++) { - Coord pt = Coord.get(currentPos.x + dirs[d].deltaX, currentPos.y + dirs[d].deltaY); - if (gradientMap[pt.x][pt.y] < best) { - if (dirs[choice] == Direction.NONE || !path.contains(pt)) { - best = gradientMap[pt.x][pt.y]; - choice = d; - } - } - } - if (best >= gradientMap[currentPos.x][currentPos.y]) { - if (friends.contains(currentPos)) { - closed.put(currentPos, WALL); - impassable2.add(currentPos); - return findTechniquePath(moveLength, tech, dungeon, los, impassable2, - friends, start, targets); - } - break; - } - if (best > gradientMap[start.x][start.y] || physicalMap[currentPos.x + dirs[choice].deltaX][currentPos.y + dirs[choice].deltaY] > FLOOR) { - path.clear(); - break; - } - currentPos = currentPos.translate(dirs[choice].deltaX, dirs[choice].deltaY); - path.add(currentPos); - paidLength += costMap[currentPos.x][currentPos.y]; - frustration++; - if (paidLength > moveLength - 1.0) { - if (friends.contains(currentPos)) { - closed.put(currentPos, WALL); - impassable2.add(currentPos); - return findTechniquePath(moveLength, tech, dungeon, los, impassable2, - friends, start, targets); - } - break; - } -// if(gradientMap[currentPos.x][currentPos.y] == 0) +// /** +// * Scans the dungeon using DijkstraMap.scan with the listed goals and start point, and returns a list +// * of Coord positions (using the current measurement) needed to get closer to a goal, where goals are +// * considered valid if they are at a valid range for the given Technique to hit at least one target +// * and ideal if that Technique can affect as many targets as possible from a cell that can be moved +// * to with at most movelength steps. +// *
+// * The return value of this method is the path to get to a location to attack, but on its own it +// * does not tell the user how to perform the attack. It does set the targetMap 2D Coord array field +// * so that if your position at the end of the returned path is non-null in targetMap, it will be +// * a Coord that can be used as a target position for Technique.apply() . If your position at the end +// * of the returned path is null, then an ideal attack position was not reachable by the path. +// *
+// * This needs a char[][] dungeon as an argument because DijkstraMap does not always have a char[][] +// * version of the map available to it, and certain AOE implementations that a Technique uses may +// * need a char[][] specifically to determine what they affect. +// *
+// * The maximum length of the returned list is given by moveLength; if moving the full length of +// * the list would place the mover in a position shared by one of the positions in allies +// * (which is typically filled with friendly units that can be passed through in multi-tile- +// * movement scenarios, and is also used considered an undesirable thing to affect for the Technique), +// * it will recalculate a move so that it does not pass into that cell. +// *
+// * The keys in impassable should be the positions of enemies and obstacles that cannot be moved +// * through, and will be ignored if there is a target overlapping one. +// *
+// * This caches its result in a member field, path, which can be fetched after finding a path and will change with +// * each call to a pathfinding method. +// * +// * @param moveLength the maximum distance to try to pathfind out to; if a spot to use a Technique can be found +// * while moving no more than this distance, then the targetMap field in this object will have a +// * target Coord that is ideal for the given Technique at the x, y indices corresponding to the +// * last Coord in the returned path. +// * @param tech a Technique that we will try to find an ideal place to use, and/or a path toward that place. +// * @param dungeon a char 2D array with '#' for walls. +// * @param los a squidgrid.LOS object if the preferred range should try to stay in line of sight, or null if LoS +// * should be disregarded. +// * @param impassable locations of enemies or mobile hazards/obstacles that aren't in the map as walls +// * @param allies called onlyPassable in other methods, here it also represents allies for Technique things +// * @param start the Coord the pathfinder starts at. +// * @param targets a Set of Coord, not an array of Coord or variable argument list as in other methods. +// * @return an ArrayList of Coord that represents a path to travel to get to an ideal place to use tech. Copy of path. +// */ +// public ArrayList findTechniquePath(int moveLength, Technique tech, char[][] dungeon, LOS los, +// Set impassable, Set allies, Coord start, Set targets) { +// if (!initialized) return null; +// tech.setMap(dungeon); +// double[][] resMap = new double[width][height]; +// double[][] worthMap = new double[width][height]; +// double[][] userDistanceMap; +// double paidLength = 0.0; +// +// LinkedHashSet friends; +// +// +// for (int x = 0; x < width; x++) { +// for (int y = 0; y < height; y++) { +// resMap[x][y] = (physicalMap[x][y] == WALL) ? 1.0 : 0.0; +// targetMap[x][y] = null; +// } +// } +// +// path.clear(); +// if (targets == null || targets.size() == 0) +// return new ArrayList<>(path); +// LinkedHashSet impassable2; +// if (impassable == null) +// impassable2 = new LinkedHashSet<>(); +// else +// impassable2 = new LinkedHashSet<>(impassable); +// +// if (allies == null) +// friends = new LinkedHashSet<>(); +// else { +// friends = new LinkedHashSet<>(allies); +// friends.remove(start); +// } +// +// resetMap(); +// setGoal(start); +// userDistanceMap = scan(impassable2); +// clearGoals(); +// resetMap(); +// for (Coord goal : targets) { +// setGoal(goal.x, goal.y); +// } +// if (goals.isEmpty()) +// return new ArrayList<>(path); +// +// Measurement mess = measurement; +// /* +// if(measurement == Measurement.EUCLIDEAN) +// { +// measurement = Measurement.CHEBYSHEV; +// } +// */ +// scan(impassable2); +// clearGoals(); +// +// Coord tempPt = Coord.get(0, 0); +// LinkedHashMap> ideal; +// // generate an array of the single best location to attack when you are in a given cell. +// for (int x = 0; x < width; x++) { +// CELL: +// for (int y = 0; y < height; y++) { +// tempPt = Coord.get(x, y); +// if (gradientMap[x][y] == WALL || gradientMap[x][y] == DARK || userDistanceMap[x][y] > moveLength * 2.0) +// continue; +// if (gradientMap[x][y] >= tech.aoe.getMinRange() && gradientMap[x][y] <= tech.aoe.getMaxRange()) { +// for (Coord tgt : targets) { +// if (los == null || los.isReachable(resMap, x, y, tgt.x, tgt.y)) { +// ideal = tech.idealLocations(tempPt, targets, friends); +// // this is weird but it saves the trouble of getting the iterator and checking hasNext() . +// for (Map.Entry> ip : ideal.entrySet()) { +// targetMap[x][y] = ip.getKey(); +// worthMap[x][y] = ip.getValue().size(); +// setGoal(x, y); +// gradientMap[x][y] = 0; +// break; +// } +// continue CELL; +// } +// } +// gradientMap[x][y] = FLOOR; +// } else +// gradientMap[x][y] = FLOOR; +// } +// } +// scan(impassable2); +// +// double currentDistance = gradientMap[start.x][start.y]; +// if (currentDistance <= moveLength) { +// Coord[] g_arr = new Coord[goals.size()]; +// g_arr = goals.keySet().toArray(g_arr); +// +// goals.clear(); +// setGoal(start); +// scan(impassable2); +// goals.clear(); +// gradientMap[start.x][start.y] = moveLength; +// +// for (Coord g : g_arr) { +// if (gradientMap[g.x][g.y] <= moveLength && worthMap[g.x][g.y] > 0) { +// goals.put(g, 0.0 - worthMap[g.x][g.y]); +// } +// } +// resetMap(); +// /* for(Coord g : goals.keySet()) +// { +// gradientMap[g.x][g.y] = 0.0 - worthMap[g.x][g.y]; +// }*/ +// scan(impassable2); +// +// } +// +// measurement = mess; +// +// Coord currentPos = Coord.get(start.x, start.y); +// while (true) { +// if (frustration > 500) { +// path.clear(); // break; - } - frustration = 0; - goals.clear(); - return new ArrayList<>(path); - } +// } +// double best = gradientMap[currentPos.x][currentPos.y]; +// final Direction[] dirs = appendDir(shuffleDirs(rng), Direction.NONE); +// int choice = rng.nextInt(dirs.length); +// +// for (int d = 0; d < dirs.length; d++) { +// Coord pt = Coord.get(currentPos.x + dirs[d].deltaX, currentPos.y + dirs[d].deltaY); +// if (gradientMap[pt.x][pt.y] < best) { +// if (dirs[choice] == Direction.NONE || !path.contains(pt)) { +// best = gradientMap[pt.x][pt.y]; +// choice = d; +// } +// } +// } +// if (best >= gradientMap[currentPos.x][currentPos.y]) { +// if (friends.contains(currentPos)) { +// closed.put(currentPos, WALL); +// impassable2.add(currentPos); +// return findTechniquePath(moveLength, tech, dungeon, los, impassable2, +// friends, start, targets); +// } +// break; +// } +// if (best > gradientMap[start.x][start.y] || physicalMap[currentPos.x + dirs[choice].deltaX][currentPos.y + dirs[choice].deltaY] > FLOOR) { +// path.clear(); +// break; +// } +// currentPos = currentPos.translate(dirs[choice].deltaX, dirs[choice].deltaY); +// path.add(currentPos); +// paidLength += costMap[currentPos.x][currentPos.y]; +// frustration++; +// if (paidLength > moveLength - 1.0) { +// if (friends.contains(currentPos)) { +// closed.put(currentPos, WALL); +// impassable2.add(currentPos); +// return findTechniquePath(moveLength, tech, dungeon, los, impassable2, +// friends, start, targets); +// } +// break; +// } +//// if(gradientMap[currentPos.x][currentPos.y] == 0) +//// break; +// } +// frustration = 0; +// goals.clear(); +// return new ArrayList<>(path); +// } /** @@ -2460,217 +2459,217 @@ public ArrayList findCoveredAttackPath(int moveLength, int minPreferredRa return new ArrayList<>(path); } - /** - * Scans the dungeon using DijkstraMap.scan with the listed goals and start point, and returns a list - * of Coord positions (using the current measurement) needed to get closer to a goal, where goals are - * considered valid if they are at a valid range for the given Technique to hit at least one target - * and ideal if that Technique can affect as many targets as possible from a cell that can be moved - * to with at most movelength steps. - *

- * The return value of this method is the path to get to a location to attack, but on its own it - * does not tell the user how to perform the attack. It does set the targetMap 2D Coord array field - * so that if your position at the end of the returned path is non-null in targetMap, it will be - * a Coord that can be used as a target position for Technique.apply() . If your position at the end - * of the returned path is null, then an ideal attack position was not reachable by the path. - *

- * This needs a char[][] dungeon as an argument because DijkstraMap does not always have a char[][] - * version of the map available to it, and certain AOE implementations that a Technique uses may - * need a char[][] specifically to determine what they affect. - *

- * The maximum length of the returned list is given by moveLength; if moving the full length of - * the list would place the mover in a position shared by one of the positions in allies - * (which is typically filled with friendly units that can be passed through in multi-tile- - * movement scenarios, and is also used considered an undesirable thing to affect for the Technique), - * it will recalculate a move so that it does not pass into that cell. - *

- * The keys in impassable should be the positions of enemies and obstacles that cannot be moved - * through, and will be ignored if there is a target overlapping one. - *
- * This caches its result in a member field, path, which can be fetched after finding a path and will change with - * each call to a pathfinding method. - * - * @param moveLength the maximum distance to try to pathfind out to; if a spot to use a Technique can be found - * while moving no more than this distance, then the targetMap field in this object will have a - * target Coord that is ideal for the given Technique at the x, y indices corresponding to the - * last Coord in the returned path. - * @param tech a Technique that we will try to find an ideal place to use, and/or a path toward that place. - * @param dungeon a char 2D array with '#' for walls. - * @param cache a FOVCache that has completed its calculations, and will be used for LOS and Technique work, may be null - * @param impassable locations of enemies or mobile hazards/obstacles that aren't in the map as walls - * @param allies called onlyPassable in other methods, here it also represents allies for Technique things - * @param start the Coord the pathfinder starts at. - * @param targets a Set of Coord, not an array of Coord or variable argument list as in other methods. - * @return an ArrayList of Coord that represents a path to travel to get to an ideal place to use tech. Copy of path. - */ - @GwtIncompatible - public ArrayList findTechniquePath(int moveLength, Technique tech, char[][] dungeon, FOVCache cache, - Set impassable, Set allies, Coord start, Set targets) { - if (!initialized) return null; - tech.setMap(dungeon); - if (cache != null) - tech.aoe.setCache(cache); - double[][] resMap = new double[width][height]; - double[][] worthMap = new double[width][height]; - double[][] userDistanceMap; - double paidLength = 0.0; - - LinkedHashSet friends; - - - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - resMap[x][y] = (physicalMap[x][y] == WALL) ? 1.0 : 0.0; - targetMap[x][y] = null; - } - } - - path.clear(); - if (targets == null || targets.size() == 0) - return new ArrayList<>(path); - LinkedHashSet impassable2; - if (impassable == null) - impassable2 = new LinkedHashSet<>(); - else - impassable2 = new LinkedHashSet<>(impassable); - - if (allies == null) - friends = new LinkedHashSet<>(); - else { - friends = new LinkedHashSet<>(allies); - friends.remove(start); - } - - resetMap(); - setGoal(start); - userDistanceMap = scan(impassable2); - clearGoals(); - resetMap(); - for (Coord goal : targets) { - setGoal(goal.x, goal.y); - } - if (goals.isEmpty()) - return new ArrayList<>(path); - - Measurement mess = measurement; - /* - if(measurement == Measurement.EUCLIDEAN) - { - measurement = Measurement.CHEBYSHEV; - } - */ - scan(impassable2); - clearGoals(); - - Coord tempPt = Coord.get(0, 0); - LinkedHashMap> ideal; - // generate an array of the single best location to attack when you are in a given cell. - for (int x = 0; x < width; x++) { - CELL: - for (int y = 0; y < height; y++) { - tempPt = Coord.get(x, y); - if (gradientMap[x][y] == WALL || gradientMap[x][y] == DARK || userDistanceMap[x][y] > moveLength * 2.0) - continue; - if (gradientMap[x][y] >= tech.aoe.getMinRange() && gradientMap[x][y] <= tech.aoe.getMaxRange()) { - for (Coord tgt : targets) { - if (cache == null || cache.queryLOS(x, y, tgt.x, tgt.y)) { - ideal = tech.idealLocations(tempPt, targets, friends); - // this is weird but it saves the trouble of getting the iterator and checking hasNext() . - for (Map.Entry> ip : ideal.entrySet()) { - targetMap[x][y] = ip.getKey(); - worthMap[x][y] = ip.getValue().size(); - setGoal(x, y); - gradientMap[x][y] = 0; - break; - } - continue CELL; - } - } - gradientMap[x][y] = FLOOR; - } else - gradientMap[x][y] = FLOOR; - } - } - scan(impassable2); - - double currentDistance = gradientMap[start.x][start.y]; - if (currentDistance <= moveLength) { - Coord[] g_arr = new Coord[goals.size()]; - g_arr = goals.keySet().toArray(g_arr); - - goals.clear(); - setGoal(start); - scan(impassable2); - goals.clear(); - gradientMap[start.x][start.y] = moveLength; - - for (Coord g : g_arr) { - if (gradientMap[g.x][g.y] <= moveLength && worthMap[g.x][g.y] > 0) { - goals.put(g, 0.0 - worthMap[g.x][g.y]); - } - } - resetMap(); - /* for(Coord g : goals.keySet()) - { - gradientMap[g.x][g.y] = 0.0 - worthMap[g.x][g.y]; - }*/ - scan(impassable2); - - } - - measurement = mess; - - Coord currentPos = Coord.get(start.x, start.y); - while (true) { - if (frustration > 500) { - path.clear(); - break; - } - double best = gradientMap[currentPos.x][currentPos.y]; - final Direction[] dirs = appendDir(shuffleDirs(rng), Direction.NONE); - int choice = rng.nextInt(dirs.length); - - for (int d = 0; d < dirs.length; d++) { - Coord pt = Coord.get(currentPos.x + dirs[d].deltaX, currentPos.y + dirs[d].deltaY); - if (gradientMap[pt.x][pt.y] < best) { - if (dirs[choice] == Direction.NONE || !path.contains(pt)) { - best = gradientMap[pt.x][pt.y]; - choice = d; - } - } - } - if (best >= gradientMap[currentPos.x][currentPos.y]) { - if (friends.contains(currentPos)) { - closed.put(currentPos, WALL); - impassable2.add(currentPos); - return findTechniquePath(moveLength, tech, dungeon, cache, impassable2, - friends, start, targets); - } - break; - } - if (best > gradientMap[start.x][start.y] || physicalMap[currentPos.x + dirs[choice].deltaX][currentPos.y + dirs[choice].deltaY] > FLOOR) { - path.clear(); - break; - } - currentPos = currentPos.translate(dirs[choice].deltaX, dirs[choice].deltaY); - path.add(currentPos); - paidLength += costMap[currentPos.x][currentPos.y]; - frustration++; - if (paidLength > moveLength - 1.0) { - if (friends.contains(currentPos)) { - closed.put(currentPos, WALL); - impassable2.add(currentPos); - return findTechniquePath(moveLength, tech, dungeon, cache, impassable2, - friends, start, targets); - } - break; - } -// if(gradientMap[currentPos.x][currentPos.y] == 0) +// /** +// * Scans the dungeon using DijkstraMap.scan with the listed goals and start point, and returns a list +// * of Coord positions (using the current measurement) needed to get closer to a goal, where goals are +// * considered valid if they are at a valid range for the given Technique to hit at least one target +// * and ideal if that Technique can affect as many targets as possible from a cell that can be moved +// * to with at most movelength steps. +// *

+// * The return value of this method is the path to get to a location to attack, but on its own it +// * does not tell the user how to perform the attack. It does set the targetMap 2D Coord array field +// * so that if your position at the end of the returned path is non-null in targetMap, it will be +// * a Coord that can be used as a target position for Technique.apply() . If your position at the end +// * of the returned path is null, then an ideal attack position was not reachable by the path. +// *

+// * This needs a char[][] dungeon as an argument because DijkstraMap does not always have a char[][] +// * version of the map available to it, and certain AOE implementations that a Technique uses may +// * need a char[][] specifically to determine what they affect. +// *

+// * The maximum length of the returned list is given by moveLength; if moving the full length of +// * the list would place the mover in a position shared by one of the positions in allies +// * (which is typically filled with friendly units that can be passed through in multi-tile- +// * movement scenarios, and is also used considered an undesirable thing to affect for the Technique), +// * it will recalculate a move so that it does not pass into that cell. +// *

+// * The keys in impassable should be the positions of enemies and obstacles that cannot be moved +// * through, and will be ignored if there is a target overlapping one. +// *
+// * This caches its result in a member field, path, which can be fetched after finding a path and will change with +// * each call to a pathfinding method. +// * +// * @param moveLength the maximum distance to try to pathfind out to; if a spot to use a Technique can be found +// * while moving no more than this distance, then the targetMap field in this object will have a +// * target Coord that is ideal for the given Technique at the x, y indices corresponding to the +// * last Coord in the returned path. +// * @param tech a Technique that we will try to find an ideal place to use, and/or a path toward that place. +// * @param dungeon a char 2D array with '#' for walls. +// * @param cache a FOVCache that has completed its calculations, and will be used for LOS and Technique work, may be null +// * @param impassable locations of enemies or mobile hazards/obstacles that aren't in the map as walls +// * @param allies called onlyPassable in other methods, here it also represents allies for Technique things +// * @param start the Coord the pathfinder starts at. +// * @param targets a Set of Coord, not an array of Coord or variable argument list as in other methods. +// * @return an ArrayList of Coord that represents a path to travel to get to an ideal place to use tech. Copy of path. +// */ +// @GwtIncompatible +// public ArrayList findTechniquePath(int moveLength, Technique tech, char[][] dungeon, FOVCache cache, +// Set impassable, Set allies, Coord start, Set targets) { +// if (!initialized) return null; +// tech.setMap(dungeon); +// if (cache != null) +// tech.aoe.setCache(cache); +// double[][] resMap = new double[width][height]; +// double[][] worthMap = new double[width][height]; +// double[][] userDistanceMap; +// double paidLength = 0.0; +// +// LinkedHashSet friends; +// +// +// for (int x = 0; x < width; x++) { +// for (int y = 0; y < height; y++) { +// resMap[x][y] = (physicalMap[x][y] == WALL) ? 1.0 : 0.0; +// targetMap[x][y] = null; +// } +// } +// +// path.clear(); +// if (targets == null || targets.size() == 0) +// return new ArrayList<>(path); +// LinkedHashSet impassable2; +// if (impassable == null) +// impassable2 = new LinkedHashSet<>(); +// else +// impassable2 = new LinkedHashSet<>(impassable); +// +// if (allies == null) +// friends = new LinkedHashSet<>(); +// else { +// friends = new LinkedHashSet<>(allies); +// friends.remove(start); +// } +// +// resetMap(); +// setGoal(start); +// userDistanceMap = scan(impassable2); +// clearGoals(); +// resetMap(); +// for (Coord goal : targets) { +// setGoal(goal.x, goal.y); +// } +// if (goals.isEmpty()) +// return new ArrayList<>(path); +// +// Measurement mess = measurement; +// /* +// if(measurement == Measurement.EUCLIDEAN) +// { +// measurement = Measurement.CHEBYSHEV; +// } +// */ +// scan(impassable2); +// clearGoals(); +// +// Coord tempPt = Coord.get(0, 0); +// LinkedHashMap> ideal; +// // generate an array of the single best location to attack when you are in a given cell. +// for (int x = 0; x < width; x++) { +// CELL: +// for (int y = 0; y < height; y++) { +// tempPt = Coord.get(x, y); +// if (gradientMap[x][y] == WALL || gradientMap[x][y] == DARK || userDistanceMap[x][y] > moveLength * 2.0) +// continue; +// if (gradientMap[x][y] >= tech.aoe.getMinRange() && gradientMap[x][y] <= tech.aoe.getMaxRange()) { +// for (Coord tgt : targets) { +// if (cache == null || cache.queryLOS(x, y, tgt.x, tgt.y)) { +// ideal = tech.idealLocations(tempPt, targets, friends); +// // this is weird but it saves the trouble of getting the iterator and checking hasNext() . +// for (Map.Entry> ip : ideal.entrySet()) { +// targetMap[x][y] = ip.getKey(); +// worthMap[x][y] = ip.getValue().size(); +// setGoal(x, y); +// gradientMap[x][y] = 0; +// break; +// } +// continue CELL; +// } +// } +// gradientMap[x][y] = FLOOR; +// } else +// gradientMap[x][y] = FLOOR; +// } +// } +// scan(impassable2); +// +// double currentDistance = gradientMap[start.x][start.y]; +// if (currentDistance <= moveLength) { +// Coord[] g_arr = new Coord[goals.size()]; +// g_arr = goals.keySet().toArray(g_arr); +// +// goals.clear(); +// setGoal(start); +// scan(impassable2); +// goals.clear(); +// gradientMap[start.x][start.y] = moveLength; +// +// for (Coord g : g_arr) { +// if (gradientMap[g.x][g.y] <= moveLength && worthMap[g.x][g.y] > 0) { +// goals.put(g, 0.0 - worthMap[g.x][g.y]); +// } +// } +// resetMap(); +// /* for(Coord g : goals.keySet()) +// { +// gradientMap[g.x][g.y] = 0.0 - worthMap[g.x][g.y]; +// }*/ +// scan(impassable2); +// +// } +// +// measurement = mess; +// +// Coord currentPos = Coord.get(start.x, start.y); +// while (true) { +// if (frustration > 500) { +// path.clear(); // break; - } - frustration = 0; - goals.clear(); - return new ArrayList<>(path); - } +// } +// double best = gradientMap[currentPos.x][currentPos.y]; +// final Direction[] dirs = appendDir(shuffleDirs(rng), Direction.NONE); +// int choice = rng.nextInt(dirs.length); +// +// for (int d = 0; d < dirs.length; d++) { +// Coord pt = Coord.get(currentPos.x + dirs[d].deltaX, currentPos.y + dirs[d].deltaY); +// if (gradientMap[pt.x][pt.y] < best) { +// if (dirs[choice] == Direction.NONE || !path.contains(pt)) { +// best = gradientMap[pt.x][pt.y]; +// choice = d; +// } +// } +// } +// if (best >= gradientMap[currentPos.x][currentPos.y]) { +// if (friends.contains(currentPos)) { +// closed.put(currentPos, WALL); +// impassable2.add(currentPos); +// return findTechniquePath(moveLength, tech, dungeon, cache, impassable2, +// friends, start, targets); +// } +// break; +// } +// if (best > gradientMap[start.x][start.y] || physicalMap[currentPos.x + dirs[choice].deltaX][currentPos.y + dirs[choice].deltaY] > FLOOR) { +// path.clear(); +// break; +// } +// currentPos = currentPos.translate(dirs[choice].deltaX, dirs[choice].deltaY); +// path.add(currentPos); +// paidLength += costMap[currentPos.x][currentPos.y]; +// frustration++; +// if (paidLength > moveLength - 1.0) { +// if (friends.contains(currentPos)) { +// closed.put(currentPos, WALL); +// impassable2.add(currentPos); +// return findTechniquePath(moveLength, tech, dungeon, cache, impassable2, +// friends, start, targets); +// } +// break; +// } +//// if(gradientMap[currentPos.x][currentPos.y] == 0) +//// break; +// } +// frustration = 0; +// goals.clear(); +// return new ArrayList<>(path); +// } private double cachedLongerPaths = 1.2; diff --git a/squidlib-util/src/main/java/squidpony/FakeLanguageGen.java b/squidlib-util/src/main/java/squidpony/FakeLanguageGen.java index 9b3ca4eba8..ba0fdcfaab 100644 --- a/squidlib-util/src/main/java/squidpony/FakeLanguageGen.java +++ b/squidlib-util/src/main/java/squidpony/FakeLanguageGen.java @@ -1670,12 +1670,12 @@ public String word(RNG rng, boolean capitalize) { StringBuilder sb = new StringBuilder(20); double syllableChance = rng.nextDouble(totalSyllableFrequency); int syllables = 1, i = 0; - for (Map.Entry kv : syllableFrequencies.entrySet()) { - if (syllableChance < kv.getValue()) { - syllables = kv.getKey(); + for (IntDoubleOrderedMap.MapEntry kv : syllableFrequencies.mapEntrySet()) { + if (syllableChance < kv.getDoubleValue()) { + syllables = kv.getIntKey(); break; } else - syllableChance -= kv.getValue(); + syllableChance -= kv.getDoubleValue(); } if (rng.nextDouble() < vowelStartFrequency) { sb.append(rng.getRandomElement(openingVowels)); diff --git a/squidlib-util/src/main/java/squidpony/LanguageCipher.java b/squidlib-util/src/main/java/squidpony/LanguageCipher.java index 0138cc4857..012b8e87aa 100644 --- a/squidlib-util/src/main/java/squidpony/LanguageCipher.java +++ b/squidlib-util/src/main/java/squidpony/LanguageCipher.java @@ -46,7 +46,7 @@ public class LanguageCipher implements Serializable{ */ public FakeLanguageGen language; private StatefulRNG rng; - // not a LinkedHashMap because this should never be need a random element to be requested + // not an OrderedMap because this should never be need a random element to be requested /** * The mapping of lower-case word keys to lower-case word values, where keys are in the source language and values * are generated by language. diff --git a/squidlib-util/src/main/java/squidpony/MonsterGen.java b/squidlib-util/src/main/java/squidpony/MonsterGen.java index 2c410b8cf7..64e9db8050 100644 --- a/squidlib-util/src/main/java/squidpony/MonsterGen.java +++ b/squidlib-util/src/main/java/squidpony/MonsterGen.java @@ -1,8 +1,6 @@ package squidpony; -import squidpony.squidmath.CrossHash; -import squidpony.squidmath.RNG; -import squidpony.squidmath.StatefulRNG; +import squidpony.squidmath.*; import java.util.*; @@ -40,8 +38,8 @@ public class MonsterGen { */ public static class Chimera { - public LinkedHashMap> parts; - public LinkedHashSet unsaidAdjectives, wholeAdjectives, powerAdjectives, powerPhrases; + public OrderedMap> parts; + public OrderedSet unsaidAdjectives, wholeAdjectives, powerAdjectives, powerPhrases; public String name, mainForm, unknown; /** @@ -57,13 +55,13 @@ public Chimera(String name, Chimera other) mainForm = unknown; else mainForm = other.name; - parts = new LinkedHashMap<>(other.parts); + parts = new OrderedMap<>(other.parts); List oldParts = new ArrayList<>(parts.remove(mainForm)); parts.put(name, oldParts); - unsaidAdjectives = new LinkedHashSet<>(other.unsaidAdjectives); - wholeAdjectives = new LinkedHashSet<>(other.wholeAdjectives); - powerAdjectives = new LinkedHashSet<>(other.powerAdjectives); - powerPhrases = new LinkedHashSet<>(other.powerPhrases); + unsaidAdjectives = new OrderedSet<>(other.unsaidAdjectives); + wholeAdjectives = new OrderedSet<>(other.wholeAdjectives); + powerAdjectives = new OrderedSet<>(other.powerAdjectives); + powerPhrases = new OrderedSet<>(other.powerPhrases); } /** @@ -100,11 +98,11 @@ public Chimera(String name, String unknown, String... terms) mainForm = unknown; else mainForm = name; - parts = new LinkedHashMap<>(); - unsaidAdjectives = new LinkedHashSet<>(); - wholeAdjectives = new LinkedHashSet<>(); - powerAdjectives = new LinkedHashSet<>(); - powerPhrases = new LinkedHashSet<>(); + parts = new OrderedMap<>(); + unsaidAdjectives = new OrderedSet<>(); + wholeAdjectives = new OrderedSet<>(); + powerAdjectives = new OrderedSet<>(); + powerPhrases = new OrderedSet<>(); ArrayList selfParts = new ArrayList<>(); int t = 0; for (; t < terms.length; t++) { @@ -183,11 +181,11 @@ public Chimera(String name, String unknown, Collection parts, Collection mainForm = unknown; else mainForm = name; - this.parts = new LinkedHashMap>(); - unsaidAdjectives = new LinkedHashSet(unsaid); - wholeAdjectives = new LinkedHashSet(whole); - powerAdjectives = new LinkedHashSet(powerAdj); - powerPhrases = new LinkedHashSet(powerPhr); + this.parts = new OrderedMap>(); + unsaidAdjectives = new OrderedSet(unsaid); + wholeAdjectives = new OrderedSet(whole); + powerAdjectives = new OrderedSet(powerAdj); + powerPhrases = new OrderedSet(powerPhr); ArrayList selfParts = new ArrayList(parts); this.parts.put(name, selfParts); } @@ -205,7 +203,7 @@ public String present(boolean capitalize) else sb.append('a'); int i = 0; - LinkedHashSet allAdjectives = new LinkedHashSet<>(wholeAdjectives); + OrderedSet allAdjectives = new OrderedSet<>(wholeAdjectives); if(unknown != null) allAdjectives.addAll(unsaidAdjectives); allAdjectives.addAll(powerAdjectives); @@ -288,7 +286,7 @@ public String presentVisible(boolean capitalize) sb.append('a'); int i = 0; - LinkedHashSet allAdjectives = new LinkedHashSet<>(wholeAdjectives); + OrderedSet allAdjectives = new OrderedSet<>(wholeAdjectives); if(unknown != null) allAdjectives.addAll(unsaidAdjectives); for(String adj : allAdjectives) diff --git a/squidlib-util/src/main/java/squidpony/squidai/AOE.java b/squidlib-util/src/main/java/squidpony/squidai/AOE.java index 4130a348cf..1aedeaf7f5 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/AOE.java +++ b/squidlib-util/src/main/java/squidpony/squidai/AOE.java @@ -4,9 +4,9 @@ import squidpony.squidgrid.FOVCache; import squidpony.squidgrid.Radius; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.Set; /** @@ -37,7 +37,7 @@ public interface AOE { boolean mayContainTarget(Set targets); /** - * Returns a LinkedHashMap of Coord keys and ArrayList of Coord values, where each Coord key is an ideal location to + * Returns a OrderedMap of Coord keys and ArrayList of Coord values, where each Coord key is an ideal location to * hit as many of the Points in targets as possible without hitting any Points in requiredExclusions, and each value * is the collection of targets that will be hit if the associated key is used. The length of any ArrayList in the * returned collection's values will be the number of targets likely to be affected by the AOE when shift() is @@ -54,9 +54,9 @@ public interface AOE { * shift(Coord) with the location of some enemy (probably the closest) as its argument. * @param targets a Set of Points that are desirable targets to include in this AOE * @param requiredExclusions a Set of Points that this tries strongly to avoid including in this AOE - * @return a LinkedHashMap of Coord keys and ArrayList of Coord values where keys are ideal locations and values are the target points that will be hit when that key is used. + * @return a OrderedMap of Coord keys and ArrayList of Coord values where keys are ideal locations and values are the target points that will be hit when that key is used. */ - LinkedHashMap> idealLocations(Set targets, Set requiredExclusions); + OrderedMap> idealLocations(Set targets, Set requiredExclusions); /** * A variant of idealLocations that takes two groups of desirable targets, and will rate locations by how many @@ -69,9 +69,9 @@ public interface AOE { * @param priorityTargets A Set of Points that are the most-wanted targets to include in this AOE * @param lesserTargets A Set of Points that are the less-wanted targets to include in this AOE, should not overlap with priorityTargets * @param requiredExclusions a Set of Points that this tries strongly to avoid including in this AOE - * @return a LinkedHashMap of Coord keys and ArrayList of Coord values where keys are ideal locations and values are the target points that will be hit when that key is used. + * @return a OrderedMap of Coord keys and ArrayList of Coord values where keys are ideal locations and values are the target points that will be hit when that key is used. */ - LinkedHashMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions); + OrderedMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions); /** * This must be called before any other methods, and takes a char[][] with '#' for walls, anything else for floors. @@ -86,12 +86,12 @@ public interface AOE { * the map. The map must be bounded by walls, which DungeonGenerator does automatically and other generators can * easily add with two loops. * - * This returns a HashMap of Coord keys to Double values; if a cell is 100% affected by the AOE then the value + * This returns an OrderedMap of Coord keys to Double values; if a cell is 100% affected by the AOE then the value * should be 1.0; if it is 50% affected it should be 0.5, if unaffected should be 0.0, etc. The Coord keys should * have the same x and y as the x,y map positions they correspond to. - * @return a HashMap of Coord keys to Double values from 1.0 (fully affected) to 0.0 (unaffected). + * @return an OrderedMap of Coord keys to Double values from 1.0 (fully affected) to 0.0 (unaffected). */ - LinkedHashMap findArea(); + OrderedMap findArea(); /** * Get the position from which the AOE originates, which may be related to the location of the AOE's effect, as for diff --git a/squidlib-util/src/main/java/squidpony/squidai/AreaUtils.java b/squidlib-util/src/main/java/squidpony/squidai/AreaUtils.java index 1352183d69..46e7672149 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/AreaUtils.java +++ b/squidlib-util/src/main/java/squidpony/squidai/AreaUtils.java @@ -1,8 +1,8 @@ package squidpony.squidai; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; -import java.util.LinkedHashMap; /** * Static utilities for use in AOE and anything else that might need HashMaps of Coord keys to Double values. @@ -15,9 +15,9 @@ public class AreaUtils { * @param map width by height, commonly generated by FOV methods * @return a HashMap of Coord keys to Double values, but the only value used is 1.0 */ - public static LinkedHashMap arrayToHashMap(boolean[][] map) + public static OrderedMap arrayToHashMap(boolean[][] map) { - LinkedHashMap ret = new LinkedHashMap<>(); + OrderedMap ret = new OrderedMap<>(); for(int i = 0; i < map.length; i++) { for(int j = 0; j < map[i].length; j++) @@ -35,9 +35,9 @@ public static LinkedHashMap arrayToHashMap(boolean[][] map) * @param map width by height, commonly generated by FOV methods * @return a HashMap of Coord keys to Double values, with values all greater than 0.0 */ - public static LinkedHashMap arrayToHashMap(double[][] map) + public static OrderedMap arrayToHashMap(double[][] map) { - LinkedHashMap ret = new LinkedHashMap<>(); + OrderedMap ret = new OrderedMap<>(); for(int i = 0; i < map.length; i++) { for(int j = 0; j < map[i].length; j++) @@ -58,9 +58,9 @@ public static LinkedHashMap arrayToHashMap(double[][] map) * @param cutoff any elements greater than this will be 1.0 in the return, anything else will be ignored * @return a HashMap of Coord keys to Double values, but the only value used is 1.0 */ - public static LinkedHashMap arrayToHashMap(double[][] map, double cutoff) + public static OrderedMap arrayToHashMap(double[][] map, double cutoff) { - LinkedHashMap ret = new LinkedHashMap<>(); + OrderedMap ret = new OrderedMap<>(); for(int i = 0; i < map.length; i++) { for(int j = 0; j < map[i].length; j++) @@ -78,9 +78,9 @@ public static LinkedHashMap arrayToHashMap(double[][] map, double * @param map a double[][] returned by a DijkstraMap running its scan() * @return a HashMap of Coord keys to Double values, with values of 1.0 only */ - public static LinkedHashMap dijkstraToHashMap(double[][] map) + public static OrderedMap dijkstraToHashMap(double[][] map) { - LinkedHashMap ret = new LinkedHashMap<>(); + OrderedMap ret = new OrderedMap<>(); for(int i = 0; i < map.length; i++) { for(int j = 0; j < map[i].length; j++) diff --git a/squidlib-util/src/main/java/squidpony/squidai/BeamAOE.java b/squidlib-util/src/main/java/squidpony/squidai/BeamAOE.java index b456dd8e10..08013d4d0f 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/BeamAOE.java +++ b/squidlib-util/src/main/java/squidpony/squidai/BeamAOE.java @@ -6,8 +6,13 @@ import squidpony.squidgrid.Radius; import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Queue; +import java.util.Set; import static java.lang.Math.*; @@ -302,15 +307,15 @@ public boolean mayContainTarget(Set targets) { } @Override - public LinkedHashMap> idealLocations(Set targets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set targets, Set requiredExclusions) { if(targets == null) - return new LinkedHashMap<>(); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + return new OrderedMap<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = targets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -447,14 +452,14 @@ else if(qualityMap[x][y] == bestQuality) } @Override - public LinkedHashMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { if(priorityTargets == null) return idealLocations(lesserTargets, requiredExclusions); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = priorityTargets.size() + lesserTargets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -742,7 +747,7 @@ public void setMap(char[][] map) { } @Override - public LinkedHashMap findArea() { + public OrderedMap findArea() { double[][] dmap = initDijkstra(); dmap[origin.x][origin.y] = DijkstraMap.DARK; dijkstra.resetMap(); diff --git a/squidlib-util/src/main/java/squidpony/squidai/BlastAOE.java b/squidlib-util/src/main/java/squidpony/squidai/BlastAOE.java index 4a5f367cb6..f56b7b8e77 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/BlastAOE.java +++ b/squidlib-util/src/main/java/squidpony/squidai/BlastAOE.java @@ -7,6 +7,9 @@ import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; + import java.util.*; /** @@ -91,14 +94,14 @@ public boolean mayContainTarget(Set targets) { } @Override - public LinkedHashMap> idealLocations(Set targets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set targets, Set requiredExclusions) { if(targets == null) - return new LinkedHashMap<>(); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + return new OrderedMap<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = targets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -233,14 +236,14 @@ else if(qualityMap[x][y] == bestQuality) { } @Override - public LinkedHashMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { if(priorityTargets == null) return idealLocations(lesserTargets, requiredExclusions); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = priorityTargets.size() + lesserTargets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -510,7 +513,7 @@ public void setMap(char[][] map) { } @Override - public LinkedHashMap findArea() { + public OrderedMap findArea() { return AreaUtils.arrayToHashMap(fov.calculateFOV(map, center.x, center.y, radius, radiusType)); } diff --git a/squidlib-util/src/main/java/squidpony/squidai/BurstAOE.java b/squidlib-util/src/main/java/squidpony/squidai/BurstAOE.java index a8fc85ee77..1b63a16aa5 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/BurstAOE.java +++ b/squidlib-util/src/main/java/squidpony/squidai/BurstAOE.java @@ -6,8 +6,12 @@ import squidpony.squidgrid.Radius; import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Set; /** * An AOE type that has a center and a radius, and uses shadowcasting to create a burst of rays from the center, out to @@ -90,14 +94,14 @@ public boolean mayContainTarget(Set targets) { } @Override - public LinkedHashMap> idealLocations(Set targets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set targets, Set requiredExclusions) { if(targets == null) - return new LinkedHashMap<>(); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + return new OrderedMap<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = targets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -225,14 +229,14 @@ else if(qualityMap[x][y] == bestQuality) @Override - public LinkedHashMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { if(priorityTargets == null) return idealLocations(lesserTargets, requiredExclusions); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = priorityTargets.size() + lesserTargets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -509,7 +513,7 @@ public void setMap(char[][] map) { } @Override - public LinkedHashMap findArea() { + public OrderedMap findArea() { return AreaUtils.arrayToHashMap(fov.calculateFOV(null, center.x, center.y, radius, radiusType)); } diff --git a/squidlib-util/src/main/java/squidpony/squidai/CloudAOE.java b/squidlib-util/src/main/java/squidpony/squidai/CloudAOE.java index e00c41cdab..04c06e9b5f 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/CloudAOE.java +++ b/squidlib-util/src/main/java/squidpony/squidai/CloudAOE.java @@ -8,6 +8,9 @@ import squidpony.squidmath.LightRNG; import squidpony.squidmath.RNG; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; + import java.util.*; /** @@ -191,14 +194,14 @@ public boolean mayContainTarget(Set targets) { } @Override - public LinkedHashMap> idealLocations(Set targets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set targets, Set requiredExclusions) { if(targets == null) - return new LinkedHashMap<>(); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + return new OrderedMap<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = targets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0 || volume <= 0) return bestPoints; @@ -334,15 +337,15 @@ else if(qualityMap[x][y] == bestQuality) } @Override - public LinkedHashMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { if(priorityTargets == null) return idealLocations(lesserTargets, requiredExclusions); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = priorityTargets.size() + lesserTargets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0 || volume <= 0) return bestPoints; @@ -636,9 +639,9 @@ public void setMap(char[][] map) { } @Override - public LinkedHashMap findArea() { + public OrderedMap findArea() { spill.start(center, volume, null); - LinkedHashMap r = AreaUtils.arrayToHashMap(spill.spillMap); + OrderedMap r = AreaUtils.arrayToHashMap(spill.spillMap); if(!expanding) { spill.reset(); diff --git a/squidlib-util/src/main/java/squidpony/squidai/ConeAOE.java b/squidlib-util/src/main/java/squidpony/squidai/ConeAOE.java index 4e0a701402..317999322e 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/ConeAOE.java +++ b/squidlib-util/src/main/java/squidpony/squidai/ConeAOE.java @@ -7,6 +7,9 @@ import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; + import java.util.*; /** @@ -197,14 +200,14 @@ public boolean mayContainTarget(Set targets) { } @Override - public LinkedHashMap> idealLocations(Set targets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set targets, Set requiredExclusions) { if(targets == null) - return new LinkedHashMap<>(); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + return new OrderedMap<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = targets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -327,14 +330,14 @@ else if(qualityMap[x][y] == bestQuality) { } @Override - public LinkedHashMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { if(priorityTargets == null) return idealLocations(lesserTargets, requiredExclusions); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = priorityTargets.size() + lesserTargets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -613,8 +616,8 @@ public void setMap(char[][] map) { } @Override - public LinkedHashMap findArea() { - LinkedHashMap r = AreaUtils.arrayToHashMap(fov.calculateFOV(map, origin.x, origin.y, radius, + public OrderedMap findArea() { + OrderedMap r = AreaUtils.arrayToHashMap(fov.calculateFOV(map, origin.x, origin.y, radius, radiusType, angle, span)); r.remove(origin); return r; diff --git a/squidlib-util/src/main/java/squidpony/squidai/DijkstraMap.java b/squidlib-util/src/main/java/squidpony/squidai/DijkstraMap.java index 214737f6b5..07bc7ed167 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/DijkstraMap.java +++ b/squidlib-util/src/main/java/squidpony/squidai/DijkstraMap.java @@ -737,7 +737,7 @@ public double[][] relax(Coord... saferPoints) { public double[][] scan(Set impassable) { if (!initialized) return null; if (impassable == null) - impassable = new LinkedHashSet<>(); + impassable = new OrderedSet<>(); IntDoubleOrderedMap blocking = new IntDoubleOrderedMap(impassable.size()); for (Coord pt : impassable) { blocking.put(pt.encode(), WALL); @@ -829,7 +829,7 @@ else if (gradientMap[x][y] < currentLowest) { public double[][] partialScan(int limit, Set impassable) { if (!initialized) return null; if (impassable == null) - impassable = new LinkedHashSet<>(); + impassable = new OrderedSet<>(); IntDoubleOrderedMap blocking = new IntDoubleOrderedMap(impassable.size()); for (Coord pt : impassable) { blocking.put(pt.encode(), WALL); @@ -992,7 +992,7 @@ public Coord findNearest(Coord start, Set targets) { * @return the Coord that it found first. */ public Coord findNearest(Coord start, Coord... targets) { - LinkedHashSet tgts = new LinkedHashSet<>(targets.length); + OrderedSet tgts = new OrderedSet<>(targets.length); Collections.addAll(tgts, targets); return findNearest(start, tgts); } @@ -1148,7 +1148,7 @@ public ArrayList findNearestMultiple(Coord start, int limit, Set t public double[][] scan(Set impassable, int size) { if (!initialized) return null; if (impassable == null) - impassable = new LinkedHashSet<>(); + impassable = new OrderedSet<>(); IntDoubleOrderedMap blocking = new IntDoubleOrderedMap(impassable.size()); for (Coord pt : impassable) { blocking.put(pt.encode(), WALL); @@ -1288,13 +1288,13 @@ public ArrayList findPath(int length, Set impassable, Set onlyPassable, Coord start, Coord... targets) { if (!initialized) return null; path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); resetMap(); for (Coord goal : targets) { @@ -1418,13 +1418,13 @@ public ArrayList findAttackPath(int moveLength, int minPreferredRange, in } } path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); resetMap(); for (Coord goal : targets) { @@ -1562,7 +1562,7 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] double[][] userDistanceMap; double paidLength = 0.0; - LinkedHashSet friends; + OrderedSet friends; for (int x = 0; x < width; x++) { @@ -1575,16 +1575,16 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] path.clear(); if (targets == null || targets.size() == 0) return new ArrayList<>(path); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (allies == null) - friends = new LinkedHashSet<>(); + friends = new OrderedSet<>(); else { - friends = new LinkedHashSet<>(allies); + friends = new OrderedSet<>(allies); friends.remove(start); } @@ -1610,7 +1610,7 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] clearGoals(); Coord tempPt = Coord.get(0, 0); - LinkedHashMap> ideal; + OrderedMap> ideal; // generate an array of the single best location to attack when you are in a given cell. for (int x = 0; x < width; x++) { CELL: @@ -1622,13 +1622,11 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] for (Coord tgt : targets) { if (los == null || los.isReachable(resMap, x, y, tgt.x, tgt.y)) { ideal = tech.idealLocations(tempPt, targets, friends); - // this is weird but it saves the trouble of getting the iterator and checking hasNext() . - for (Map.Entry> ip : ideal.entrySet()) { - targetMap[x][y] = ip.getKey(); - worthMap[x][y] = ip.getValue().size(); + if (!ideal.isEmpty()) { + targetMap[x][y] = ideal.keyAt(0); + worthMap[x][y] = ideal.getAt(0).size(); setGoal(x, y); gradientMap[x][y] = 0; - break; } continue CELL; } @@ -1783,13 +1781,13 @@ public ArrayList findAttackPath(int moveLength, int minPreferredRange, in if (maxPreferredRange < minPreferredRange) maxPreferredRange = minPreferredRange; path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); resetMap(); for (Coord goal : targets) { @@ -1910,7 +1908,7 @@ public ArrayList findAttackPath(int moveLength, int minPreferredRange, in */ public ArrayList findCoveredAttackPath(int moveLength, int minPreferredRange, int maxPreferredRange, double coverPreference, Set impassable, - Set onlyPassable, List threats, Coord start, + Set onlyPassable, Iterable threats, Coord start, Coord... targets) { if (!initialized) return null; @@ -1926,13 +1924,13 @@ public ArrayList findCoveredAttackPath(int moveLength, int minPreferredRa path = new ArrayList(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet(); + impassable2 = new OrderedSet(); else - impassable2 = new LinkedHashSet(impassable); + impassable2 = new OrderedSet(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet(); + onlyPassable = new OrderedSet(); resetMap(); for (Coord goal : targets) { @@ -2116,7 +2114,7 @@ public ArrayList findCoveredAttackPath(int moveLength, int preferredRange */ public ArrayList findCoveredAttackPath(int moveLength, int minPreferredRange, int maxPreferredRange, double coverPreference, FOV fov, boolean seekDistantGoals, Set impassable, - Set onlyPassable, List threats, Coord start, + Set onlyPassable, Iterable threats, Coord start, Coord... targets) { if (!initialized) return null; if(fov == null) { @@ -2135,13 +2133,13 @@ public ArrayList findCoveredAttackPath(int moveLength, int minPreferredRa path = new ArrayList(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet(); + impassable2 = new OrderedSet(); else - impassable2 = new LinkedHashSet(impassable); + impassable2 = new OrderedSet(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet(); + onlyPassable = new OrderedSet(); resetMap(); for (Coord goal : targets) { @@ -2364,13 +2362,13 @@ public ArrayList findCoveredAttackPath(int moveLength, int minPreferredRa } path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); resetMap(); for (Coord goal : targets) { @@ -2548,7 +2546,7 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] double[][] userDistanceMap; double paidLength = 0.0; - LinkedHashSet friends; + OrderedSet friends; for (int x = 0; x < width; x++) { @@ -2561,16 +2559,16 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] path.clear(); if (targets == null || targets.size() == 0) return new ArrayList<>(path); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (allies == null) - friends = new LinkedHashSet<>(); + friends = new OrderedSet<>(); else { - friends = new LinkedHashSet<>(allies); + friends = new OrderedSet<>(allies); friends.remove(start); } @@ -2596,7 +2594,7 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] clearGoals(); Coord tempPt = Coord.get(0, 0); - LinkedHashMap> ideal; + OrderedMap> ideal; // generate an array of the single best location to attack when you are in a given cell. for (int x = 0; x < width; x++) { CELL: @@ -2608,13 +2606,11 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] for (Coord tgt : targets) { if (cache == null || cache.queryLOS(x, y, tgt.x, tgt.y)) { ideal = tech.idealLocations(tempPt, targets, friends); - // this is weird but it saves the trouble of getting the iterator and checking hasNext() . - for (Map.Entry> ip : ideal.entrySet()) { - targetMap[x][y] = ip.getKey(); - worthMap[x][y] = ip.getValue().size(); + if (!ideal.isEmpty()) { + targetMap[x][y] = ideal.keyAt(0); + worthMap[x][y] = ideal.getAt(0).size(); setGoal(x, y); gradientMap[x][y] = 0; - break; } continue CELL; } @@ -2709,7 +2705,7 @@ public ArrayList findTechniquePath(int moveLength, Technique tech, char[] private double cachedLongerPaths = 1.2; - private Set cachedImpassable = new LinkedHashSet<>(); + private Set cachedImpassable = new OrderedSet<>(); private Coord[] cachedFearSources; private double[][] cachedFleeMap; private int cachedSize = 1; @@ -2744,14 +2740,14 @@ public ArrayList findFleePath(int length, double preferLongerPaths, Set onlyPassable, Coord start, Coord... fearSources) { if (!initialized) return null; path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); if (fearSources == null || fearSources.length < 1) { path.clear(); return new ArrayList<>(path); @@ -2761,7 +2757,7 @@ public ArrayList findFleePath(int length, double preferLongerPaths, Set(impassable2); + cachedImpassable = new OrderedSet<>(impassable2); cachedFearSources = GwtCompatibility.cloneCoords(fearSources); cachedSize = 1; resetMap(); @@ -2857,14 +2853,14 @@ public ArrayList findPathLarge(int size, int length, Set impassabl Set onlyPassable, Coord start, Coord... targets) { if (!initialized) return null; path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); resetMap(); for (Coord goal : targets) { @@ -2962,14 +2958,14 @@ public ArrayList findAttackPathLarge(int size, int moveLength, int prefer } } path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); resetMap(); for (Coord goal : targets) { @@ -3100,14 +3096,14 @@ public ArrayList findAttackPathLarge(int size, int moveLength, int minPre } } path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); resetMap(); for (Coord goal : targets) { @@ -3230,14 +3226,14 @@ public ArrayList findFleePathLarge(int size, int length, double preferLon Set onlyPassable, Coord start, Coord... fearSources) { if (!initialized) return null; path.clear(); - LinkedHashSet impassable2; + OrderedSet impassable2; if (impassable == null) - impassable2 = new LinkedHashSet<>(); + impassable2 = new OrderedSet<>(); else - impassable2 = new LinkedHashSet<>(impassable); + impassable2 = new OrderedSet<>(impassable); if (onlyPassable == null) - onlyPassable = new LinkedHashSet<>(); + onlyPassable = new OrderedSet<>(); if (fearSources == null || fearSources.length < 1) { path.clear(); return new ArrayList<>(path); @@ -3247,7 +3243,7 @@ public ArrayList findFleePathLarge(int size, int length, double preferLon gradientMap = cachedFleeMap; } else { cachedLongerPaths = preferLongerPaths; - cachedImpassable = new LinkedHashSet<>(impassable2); + cachedImpassable = new OrderedSet<>(impassable2); cachedFearSources = GwtCompatibility.cloneCoords(fearSources); cachedSize = size; resetMap(); @@ -3367,17 +3363,17 @@ public ArrayList findPathPreScanned(Coord target) { } /** - * A simple limited flood-fill that returns a LinkedHashMap of Coord keys to the Double values in the DijkstraMap, only + * A simple limited flood-fill that returns a OrderedMap of Coord keys to the Double values in the DijkstraMap, only * calculating out to a number of steps determined by limit. This can be useful if you need many flood-fills and * don't need a large area for each, or if you want to have an effect spread to a certain number of cells away. * * @param radius the number of steps to take outward from each starting position. * @param starts a vararg group of Points to step outward from; this often will only need to be one Coord. - * @return A LinkedHashMap of Coord keys to Double values; the starts are included in this with the value 0.0. + * @return A OrderedMap of Coord keys to Double values; the starts are included in this with the value 0.0. */ - public LinkedHashMap floodFill(int radius, Coord... starts) { + public Map floodFill(int radius, Coord... starts) { if (!initialized) return null; - LinkedHashMap fill = new LinkedHashMap<>(); + OrderedMap fill = new OrderedMap<>(); resetMap(); for (Coord goal : starts) { diff --git a/squidlib-util/src/main/java/squidpony/squidai/LineAOE.java b/squidlib-util/src/main/java/squidpony/squidai/LineAOE.java index 842437e987..8aba513df7 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/LineAOE.java +++ b/squidlib-util/src/main/java/squidpony/squidai/LineAOE.java @@ -7,6 +7,9 @@ import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; + import java.util.*; /** @@ -259,14 +262,14 @@ public boolean mayContainTarget(Set targets) { } @Override - public LinkedHashMap> idealLocations(Set targets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set targets, Set requiredExclusions) { if(targets == null) - return new LinkedHashMap<>(); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + return new OrderedMap<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = targets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -404,14 +407,14 @@ else if(qualityMap[x][y] == bestQuality) } @Override - public LinkedHashMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { if(priorityTargets == null) return idealLocations(lesserTargets, requiredExclusions); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); //requiredExclusions.remove(origin); int totalTargets = priorityTargets.size() + lesserTargets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 8); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 8); if(totalTargets == 0) return bestPoints; @@ -694,7 +697,7 @@ public void setMap(char[][] map) { } @Override - public LinkedHashMap findArea() { + public OrderedMap findArea() { double[][] dmap = initDijkstra(); dmap[origin.x][origin.y] = DijkstraMap.DARK; dijkstra.resetMap(); diff --git a/squidlib-util/src/main/java/squidpony/squidai/PointAOE.java b/squidlib-util/src/main/java/squidpony/squidai/PointAOE.java index d6ea9b8471..07b5cf6094 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/PointAOE.java +++ b/squidlib-util/src/main/java/squidpony/squidai/PointAOE.java @@ -5,9 +5,10 @@ import squidpony.squidgrid.Radius; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; + import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.Set; /** @@ -64,12 +65,12 @@ public boolean mayContainTarget(Set targets) { } @Override - public LinkedHashMap> idealLocations(Set targets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set targets, Set requiredExclusions) { if(targets == null) - return new LinkedHashMap<>(); + return new OrderedMap<>(); int totalTargets = targets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets); if(totalTargets == 0) return bestPoints; @@ -92,13 +93,13 @@ public LinkedHashMap> idealLocations(Set targets, @Override - public LinkedHashMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { + public OrderedMap> idealLocations(Set priorityTargets, Set lesserTargets, Set requiredExclusions) { if(priorityTargets == null) return idealLocations(lesserTargets, requiredExclusions); - if(requiredExclusions == null) requiredExclusions = new LinkedHashSet<>(); + if(requiredExclusions == null) requiredExclusions = new OrderedSet<>(); int totalTargets = priorityTargets.size() + lesserTargets.size(); - LinkedHashMap> bestPoints = new LinkedHashMap<>(totalTargets * 4); + OrderedMap> bestPoints = new OrderedMap<>(totalTargets * 4); if(totalTargets == 0) return bestPoints; @@ -222,8 +223,8 @@ public void setMap(char[][] map) { } @Override - public LinkedHashMap findArea() { - LinkedHashMap ret = new LinkedHashMap<>(1); + public OrderedMap findArea() { + OrderedMap ret = new OrderedMap<>(1); ret.put(Coord.get(center.x, center.y), 1.0); return ret; } diff --git a/squidlib-util/src/main/java/squidpony/squidai/Technique.java b/squidlib-util/src/main/java/squidpony/squidai/Technique.java index b7e84e4229..4da1cd9c88 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/Technique.java +++ b/squidlib-util/src/main/java/squidpony/squidai/Technique.java @@ -1,9 +1,9 @@ package squidpony.squidai; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.Set; /** @@ -127,9 +127,9 @@ public void setMap(char[][] map) * @param user The location of the user of this Technique * @param targets Set of Coord of desirable targets to include in the area of this Technique, as many as possible. * @param requiredExclusions Set of Coord where each value is something this Technique will really try to avoid. - * @return LinkedHashMap of Coord keys representing target points to pass to apply, to ArrayList of Coord values representing what targets' locations will be affected. + * @return OrderedMap of Coord keys representing target points to pass to apply, to ArrayList of Coord values representing what targets' locations will be affected. */ - public LinkedHashMap> idealLocations(Coord user, Set targets, Set requiredExclusions) { + public OrderedMap> idealLocations(Coord user, Set targets, Set requiredExclusions) { aoe.setOrigin(user); return aoe.idealLocations(targets, requiredExclusions); @@ -151,9 +151,9 @@ public LinkedHashMap> idealLocations(Coord user, Set> idealLocations(Coord user, Set priorityTargets, Set lesserTargets, Set requiredExclusions) { + public OrderedMap> idealLocations(Coord user, Set priorityTargets, Set lesserTargets, Set requiredExclusions) { aoe.setOrigin(user); return aoe.idealLocations(priorityTargets, lesserTargets, requiredExclusions); } @@ -173,7 +173,7 @@ public LinkedHashMap> idealLocations(Coord user, Set apply(Coord user, Coord aimAt) + public OrderedMap apply(Coord user, Coord aimAt) { aoe.setOrigin(user); aoe.shift(aimAt); diff --git a/squidlib-util/src/main/java/squidpony/squidai/WaypointPathfinder.java b/squidlib-util/src/main/java/squidpony/squidai/WaypointPathfinder.java index e366a742ad..7d7e4e8a41 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/WaypointPathfinder.java +++ b/squidlib-util/src/main/java/squidpony/squidai/WaypointPathfinder.java @@ -8,6 +8,9 @@ import squidpony.squidmath.RNG; import squidpony.squidmath.StatefulRNG; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; + import java.util.*; import static squidpony.squidmath.CoordPacker.*; @@ -24,7 +27,7 @@ public class WaypointPathfinder { private char[][] map; private int[][] expansionMap; public RNG rng; - private LinkedHashMap> waypoints; + private OrderedMap> waypoints; /** * Calculates and stores the doors and doors-like connections ("chokepoints") on the given map as waypoints. @@ -48,7 +51,7 @@ public WaypointPathfinder(char[][] map, Radius measurement, RNG rng) Math.min(width, height) * 0.4f, this.rng, '#'); int centerCount = centers.size(); expansionMap = new int[width][height]; - waypoints = new LinkedHashMap<>(64); + waypoints = new OrderedMap<>(64); dm = new DijkstraMap(simplified, DijkstraMap.Measurement.MANHATTAN); for (Coord center : centers) { @@ -79,7 +82,7 @@ public WaypointPathfinder(char[][] map, Radius measurement, RNG rng) } } - LinkedHashSet chokes = new LinkedHashSet<>(128); + OrderedSet chokes = new OrderedSet<>(128); for (int i = 0; i < width; i++) { ELEMENT_WISE: for (int j = 0; j < height; j++) { @@ -101,7 +104,7 @@ public WaypointPathfinder(char[][] map, Radius measurement, RNG rng) if(good) { Coord chk = Coord.get(i, j); chokes.add(chk); - waypoints.put(chk, new LinkedHashMap()); + waypoints.put(chk, new OrderedMap()); } } } @@ -135,7 +138,7 @@ else if(centers.contains(Coord.get(x, y))) dm = new DijkstraMap(map, DijkstraMap.findMeasurement(measurement)); int e = 0; - for(Map.Entry> n : waypoints.entrySet()) + for(Map.Entry> n : waypoints.entrySet()) { chokes.remove(n.getKey()); if(chokes.isEmpty()) @@ -171,8 +174,8 @@ public WaypointPathfinder(char[][] map, Radius measurement, RNG rng, boolean thi height = map[0].length; char[][] simplified = DungeonUtility.simplifyDungeon(map); expansionMap = new int[width][height]; - waypoints = new LinkedHashMap<>(64); - LinkedHashSet chokes = new LinkedHashSet<>(128); + waypoints = new OrderedMap<>(64); + OrderedSet chokes = new OrderedSet<>(128); if(thickCorridors) { @@ -183,7 +186,7 @@ public WaypointPathfinder(char[][] map, Radius measurement, RNG rng, boolean thi Coord[] apart = apartPacked(doors, 1); Collections.addAll(chokes, apart); for (int i = 0; i < apart.length; i++) { - waypoints.put(apart[i], new LinkedHashMap()); + waypoints.put(apart[i], new OrderedMap()); } } else { @@ -241,7 +244,7 @@ public WaypointPathfinder(char[][] map, Radius measurement, RNG rng, boolean thi if (good) { Coord chk = Coord.get(i, j); chokes.add(chk); - waypoints.put(chk, new LinkedHashMap()); + waypoints.put(chk, new OrderedMap()); } } } @@ -250,7 +253,7 @@ public WaypointPathfinder(char[][] map, Radius measurement, RNG rng, boolean thi dm = new DijkstraMap(map, DijkstraMap.findMeasurement(measurement)); int e = 0; - for(Map.Entry> n : waypoints.entrySet()) + for(Map.Entry> n : waypoints.entrySet()) { chokes.remove(n.getKey()); if(chokes.isEmpty()) @@ -292,20 +295,20 @@ public WaypointPathfinder(char[][] map, Radius measurement, RNG rng, int fractio height = map[0].length; char[][] simplified = DungeonUtility.simplifyDungeon(map); expansionMap = new int[width][height]; - waypoints = new LinkedHashMap<>(64); - LinkedHashSet chokes = new LinkedHashSet<>(128); + waypoints = new OrderedMap<>(64); + OrderedSet chokes = new OrderedSet<>(128); short[] floors = pack(simplified, '.'); Coord[] apart = fractionPacked(floors, fraction); Collections.addAll(chokes, apart); for (int i = 0; i < apart.length; i++) { - waypoints.put(apart[i], new LinkedHashMap()); + waypoints.put(apart[i], new OrderedMap()); } dm = new DijkstraMap(map, DijkstraMap.findMeasurement(measurement)); int e = 0; - for(Map.Entry> n : waypoints.entrySet()) + for(Map.Entry> n : waypoints.entrySet()) { chokes.remove(n.getKey()); if(chokes.isEmpty()) @@ -345,7 +348,7 @@ public WaypointPathfinder(char[][] map, DijkstraMap dijkstra, RNG rng) Math.min(width, height) * 0.4f, this.rng, '#'); int centerCount = centers.size(); expansionMap = new int[width][height]; - waypoints = new LinkedHashMap<>(64); + waypoints = new OrderedMap<>(64); dm = new DijkstraMap(simplified, DijkstraMap.Measurement.MANHATTAN); for (Coord center : centers) { @@ -376,7 +379,7 @@ public WaypointPathfinder(char[][] map, DijkstraMap dijkstra, RNG rng) } } - LinkedHashSet chokes = new LinkedHashSet<>(128); + OrderedSet chokes = new OrderedSet<>(128); for (int i = 0; i < width; i++) { ELEMENT_WISE: for (int j = 0; j < height; j++) { @@ -397,13 +400,13 @@ public WaypointPathfinder(char[][] map, DijkstraMap dijkstra, RNG rng) if(good) { Coord chk = Coord.get(i, j); chokes.add(chk); - waypoints.put(chk, new LinkedHashMap()); + waypoints.put(chk, new OrderedMap()); } } } dm = dijkstra; int e = 0; - for(Map.Entry> n : waypoints.entrySet()) + for(Map.Entry> n : waypoints.entrySet()) { chokes.remove(n.getKey()); if(chokes.isEmpty()) @@ -484,9 +487,9 @@ public ArrayList goBackToPath(Coord currentPosition, ArrayList pat return dm.findShortcutPath(currentPosition, path.toArray(new Coord[path.size()])); } - public LinkedHashSet getWaypoints() + public OrderedSet getWaypoints() { - return new LinkedHashSet<>(waypoints.keySet()); + return new OrderedSet<>(waypoints.keySet()); } private static class Edge implements Comparable diff --git a/squidlib-util/src/main/java/squidpony/squidai/ZOI.java b/squidlib-util/src/main/java/squidpony/squidai/ZOI.java index d3fa1b3aa1..db0aa8072a 100644 --- a/squidlib-util/src/main/java/squidpony/squidai/ZOI.java +++ b/squidlib-util/src/main/java/squidpony/squidai/ZOI.java @@ -4,9 +4,10 @@ import squidpony.squidgrid.Radius; import squidpony.squidmath.Coord; import squidpony.squidmath.CoordPacker; +import squidpony.squidmath.OrderedSet; import squidpony.squidmath.ShortVLA; -import java.util.*; +import java.util.Collections; /** * Calculates the Zone of Influence, also known as Zone of Control, for different points on a map. @@ -116,7 +117,7 @@ public short[][] calculate() return packedGroups; } protected boolean[][] increasing(double[][] dm, Coord[] inf) { - LinkedHashSet open = new LinkedHashSet<>(64), fresh = new LinkedHashSet<>(64); + OrderedSet open = new OrderedSet<>(64), fresh = new OrderedSet<>(64); Collections.addAll(open, inf); Direction[] dirs = (radius.equals2D(Radius.DIAMOND)) ? Direction.CARDINALS : Direction.OUTWARDS; boolean[][] influenced = new boolean[map.length][map[0].length]; @@ -147,7 +148,7 @@ protected boolean[][] increasing(double[][] dm, Coord[] inf) { } } - open = new LinkedHashSet<>(fresh); + open = new OrderedSet<>(fresh); fresh.clear(); } diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/DetailedMimic.java b/squidlib-util/src/main/java/squidpony/squidgrid/DetailedMimic.java index b24269cadc..d5a2ac58dc 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/DetailedMimic.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/DetailedMimic.java @@ -12,11 +12,10 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of import squidpony.GwtCompatibility; import squidpony.squidgrid.mapping.AestheticDifference; +import squidpony.squidmath.IntDoubleOrderedMap; +import squidpony.squidmath.OrderedSet; import squidpony.squidmath.RNG; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; - /** * Similar to MimicFill, this class can be used to imitate the style of an existing piece of data, but this works on * more than just booleans; it can produce similar styles of texture (its original use in SynTex), of map, of item @@ -71,7 +70,7 @@ private void analysis(int[] bitmap, int width, int height, int K, int N, boolean { int area = width * height; analyzed = new int[area][]; - LinkedHashSet points = new LinkedHashSet<>(area); + OrderedSet points = new OrderedSet<>(area); for (int i = 0; i < area; i++) points.add(i); double[] similarities = new double[area * area]; @@ -82,7 +81,7 @@ private void analysis(int[] bitmap, int width, int height, int K, int N, boolean for (int i = 0; i < area; i++) { analyzed[i] = new int[K]; - LinkedHashSet copy = new LinkedHashSet<>(points); + OrderedSet copy = new OrderedSet<>(points); analyzed[i][0] = i; copy.remove(i); @@ -117,7 +116,7 @@ private int[] coherentSynthesis(int[] sample, int SW, int SH, int[][] sets, int for (int i = 0; i < OW * OH; i++) { int x = i % OW, y = i / OW; - LinkedHashMap candidates = new LinkedHashMap(); + IntDoubleOrderedMap candidates = new IntDoubleOrderedMap(); GwtCompatibility.insert2D(cleanMask, mask, 0, 0); for (int dy = -1; dy <= 1; dy++){ @@ -240,15 +239,11 @@ private static int weightedRandom(double[] array, double r) return 0; } - private static int weightedRandom(LinkedHashMap dic, double r) { - Integer[] ints = new Integer[dic.size()]; + private static int weightedRandom(IntDoubleOrderedMap dic, double r) { + int[] ints = new int[dic.size()]; double[] doubles = new double[dic.size()]; dic.keySet().toArray(ints); - int i = 0; - for(Double d : dic.values()) - { - doubles[i++] = d; - } + dic.values().toArray(doubles); return ints[weightedRandom(doubles, r)]; } } \ No newline at end of file diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/FOVCache.java b/squidlib-util/src/main/java/squidpony/squidgrid/FOVCache.java index 64f648d8f2..cb1f53c133 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/FOVCache.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/FOVCache.java @@ -3,6 +3,7 @@ import squidpony.annotation.GwtIncompatible; import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; import squidpony.squidmath.ShortVLA; import java.util.*; @@ -101,7 +102,7 @@ public class FOVCache extends FOV{ protected final int NUM_THREADS; private ExecutorService executor; protected double fovPermissiveness; - protected LinkedHashMap lights; + protected OrderedMap lights; protected Coord[] lightSources; protected int[] lightBrightnesses; private double[][] levels; @@ -143,7 +144,7 @@ public FOVCache(char[][] map, int maxRadius, Radius radiusKind) decay = 1.0 / maxRadius; this.radiusKind = radiusKind; fovPermissiveness = 0.9; - lights = new LinkedHashMap<>(); + lights = new OrderedMap<>(); cache = new short[mapLimit][][]; tmpCache = new short[mapLimit][][]; losCache = new short[mapLimit][]; @@ -212,7 +213,7 @@ public FOVCache(char[][] map, int maxRadius, int maxLOSRadius, Radius radiusKind decay = 1.0 / maxRadius; this.radiusKind = radiusKind; fovPermissiveness = 0.9; - lights = new LinkedHashMap<>(); + lights = new OrderedMap<>(); cache = new short[mapLimit][][]; tmpCache = new short[mapLimit][][]; losCache = new short[mapLimit][]; @@ -284,7 +285,7 @@ public FOVCache(char[][] map, int maxRadius, int maxLOSRadius, Radius radiusKind decay = 1.0 / maxRadius; this.radiusKind = radiusKind; fovPermissiveness = 0.9; - this.lights = new LinkedHashMap<>(lights); + this.lights = new OrderedMap<>(lights); cache = new short[mapLimit][][]; tmpCache = new short[mapLimit][][]; losCache = new short[mapLimit][]; diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/LOS.java b/squidlib-util/src/main/java/squidpony/squidgrid/LOS.java index 4b0f8c560f..9ec71a35f8 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/LOS.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/LOS.java @@ -166,8 +166,7 @@ public boolean isReachable(double[][] resistanceMap, int startx, int starty, int return bresenhamReachable(radiusStrategy); case ELIAS: throw new IllegalStateException("Elias LOS is Gwt Incompatible"); - /* FIXME Find a way around that */ - // Required to compile with GWT: + // Comment required to compile with GWT: // return eliasReachable(radiusStrategy); case RAY: return rayReachable(radiusStrategy); @@ -339,7 +338,7 @@ private boolean ddaReachable(Radius radiusStrategy) { private boolean thickReachable(Radius radiusStrategy) { lastPath = new LinkedList<>(); double dist = radiusStrategy.radius(startx, starty, targetx, targety), decay = 1 / dist; - LinkedHashSet visited = new LinkedHashSet<>((int) dist + 3); + OrderedSet visited = new OrderedSet<>((int) dist + 3); List> paths = new ArrayList<>(4); /* // actual corners paths.add(DDALine.line(startx, starty, targetx, targety, 0, 0)); @@ -387,7 +386,7 @@ private boolean thickReachable(Radius radiusStrategy) { private boolean brushReachable(Radius radiusStrategy, int spread) { lastPath = new LinkedList<>(); double dist = radiusStrategy.radius(startx, starty, targetx, targety) + spread * 2, decay = 1 / dist; - LinkedHashSet visited = new LinkedHashSet<>((int) (dist + 3) * spread); + OrderedSet visited = new OrderedSet<>((int) (dist + 3) * spread); List> paths = new ArrayList<>((int) (radiusStrategy.volume2D(spread) * 1.25)); int length = 0; List currentPath; diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/MultiSpill.java b/squidlib-util/src/main/java/squidpony/squidgrid/MultiSpill.java index 360608067a..70eeabb077 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/MultiSpill.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/MultiSpill.java @@ -2,13 +2,13 @@ import squidpony.squidgrid.Spill.Measurement; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedSet; import squidpony.squidmath.RNG; import squidpony.squidmath.StatefulRNG; import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -66,7 +66,7 @@ public class MultiSpill { * are reached on all sides and the Spill has no more room to fill. */ public int filled = 0; - private ArrayList> fresh; + private ArrayList> fresh; /** * The StatefulRNG used to decide how to randomly fill a space; can have its state set and read. */ @@ -308,7 +308,7 @@ protected void setFresh(int idx, int x, int y) { protected void setFresh(int idx, final Coord pt) { if(!initialized) return; - for(LinkedHashSet f : fresh) + for(OrderedSet f : fresh) { if(f.contains(pt)) return; @@ -337,7 +337,7 @@ protected void setFresh(int idx, final Coord pt) { public ArrayList> start(List entries, int volume, Set impassable) { if(!initialized) return null; if(impassable == null) - impassable = new LinkedHashSet<>(); + impassable = new OrderedSet<>(); if(volume < 0) volume = Integer.MAX_VALUE; ArrayList spillers = new ArrayList<>(entries); @@ -345,7 +345,7 @@ public ArrayList> start(List entries, int volume, Set(128)); - fresh.add(new LinkedHashSet(128)); + fresh.add(new OrderedSet(128)); Coord c = spillers.get(i); spillMap[c.x][c.y] = i; @@ -366,7 +366,7 @@ public ArrayList> start(List entries, int volume, Set currentFresh = fresh.get(i); + OrderedSet currentFresh = fresh.get(i); if(currentFresh.isEmpty()) continue; else @@ -416,10 +416,10 @@ public ArrayList> start(List entries, int volume, Set> start(LinkedHashMap entries, int volume, Set impassable) { + public ArrayList> start(Map entries, int volume, Set impassable) { if(!initialized) return null; if(impassable == null) - impassable = new LinkedHashSet<>(); + impassable = new OrderedSet<>(); if(volume < 0) volume = Integer.MAX_VALUE; ArrayList spillers0 = new ArrayList<>(entries.keySet()), @@ -430,7 +430,7 @@ public ArrayList> start(LinkedHashMap entries, i fresh.clear(); for (short i = 0, ctr = 0; i < spillers0.size(); i++, ctr++) { spreadPattern.add(new ArrayList(128)); - fresh.add(new LinkedHashSet(128)); + fresh.add(new OrderedSet(128)); Coord c = spillers0.get(i); spillers.add(c); biases.add(biases0.get(i)); @@ -456,7 +456,7 @@ public ArrayList> start(LinkedHashMap entries, i while (hasFresh && filled < volume) { hasFresh = false; for (short i = 0; i < spillers.size() && filled < volume; i++) { - LinkedHashSet currentFresh = fresh.get(i); + OrderedSet currentFresh = fresh.get(i); if(currentFresh.isEmpty()) continue; else diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/Radius.java b/squidlib-util/src/main/java/squidpony/squidgrid/Radius.java index f705dd05ab..b18a69f6c7 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/Radius.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/Radius.java @@ -2,9 +2,9 @@ import squidpony.squidmath.Coord; import squidpony.squidmath.Coord3D; +import squidpony.squidmath.OrderedSet; import squidpony.squidmath.RNG; -import java.util.LinkedHashSet; import java.util.Set; /** @@ -229,7 +229,7 @@ private int clamp(int n, int min, int max) public Set perimeter(Coord center, int radiusLength, boolean surpassEdges, int width, int height) { - LinkedHashSet rim = new LinkedHashSet<>(4 * radiusLength); + OrderedSet rim = new OrderedSet<>(4 * radiusLength); if(!surpassEdges && (center.x < 0 || center.x >= width || center.y < 0 || center.y > height)) return rim; if(radiusLength < 1) { @@ -445,7 +445,7 @@ else if(x < y) public Set pointsInside(Coord center, int radiusLength, boolean surpassEdges, int width, int height) { - LinkedHashSet contents = new LinkedHashSet((int)Math.ceil(volume2D(radiusLength))); + OrderedSet contents = new OrderedSet((int)Math.ceil(volume2D(radiusLength))); if(!surpassEdges && (center.x < 0 || center.x >= width || center.y < 0 || center.y >= height)) return contents; if(radiusLength < 1) { @@ -510,7 +510,7 @@ public Set pointsInside(Coord center, int radiusLength, boolean surpassEd public Set expand(int distance, int width, int height, Iterable points) { Set around = pointsInside(Coord.get(distance, distance), distance, false, width, height), - expanded = new LinkedHashSet<>(around.size() * 16); + expanded = new OrderedSet<>(around.size() * 16); int tx, ty; for(Coord pt : points) { diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/SoundMap.java b/squidlib-util/src/main/java/squidpony/squidgrid/SoundMap.java index a3474475d7..e8a0aa5660 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/SoundMap.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/SoundMap.java @@ -2,9 +2,9 @@ import squidpony.squidmath.Coord; import squidpony.squidmath.LightRNG; +import squidpony.squidmath.OrderedMap; import squidpony.squidmath.RNG; -import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -62,7 +62,7 @@ public enum Measurement { * The latest results of findAlerted(), with Coord keys representing the positions of creatures that were alerted * and Double values representing how loud the sound was when it reached them. */ - public HashMap alerted = new HashMap<>(); + public OrderedMap alerted = new OrderedMap<>(); /** * Cells with no sound are always marked with 0. */ @@ -75,8 +75,8 @@ public enum Measurement { * Sources of sound on the map; keys are positions, values are how loud the noise is (10.0 should spread 10 cells * away, with diminishing values assigned to further positions). */ - public HashMap sounds; - private HashMap fresh; + public OrderedMap sounds; + private OrderedMap fresh; /** * The RNG used to decide which one of multiple equally-short paths to take. */ @@ -89,9 +89,9 @@ public enum Measurement { */ public SoundMap() { rng = new RNG(new LightRNG()); - alerted = new HashMap<>(); - fresh = new HashMap<>(); - sounds = new HashMap<>(); + alerted = new OrderedMap<>(); + fresh = new OrderedMap<>(); + sounds = new OrderedMap<>(); } /** @@ -100,9 +100,9 @@ public SoundMap() { */ public SoundMap(RNG random) { rng = random; - alerted = new HashMap<>(); - fresh = new HashMap<>(); - sounds = new HashMap<>(); + alerted = new OrderedMap<>(); + fresh = new OrderedMap<>(); + sounds = new OrderedMap<>(); } /** @@ -111,9 +111,9 @@ public SoundMap(RNG random) { */ public SoundMap(final double[][] level) { rng = new RNG(new LightRNG()); - alerted = new HashMap<>(); - fresh = new HashMap<>(); - sounds = new HashMap<>(); + alerted = new OrderedMap<>(); + fresh = new OrderedMap<>(); + sounds = new OrderedMap<>(); initialize(level); } /** @@ -124,9 +124,9 @@ public SoundMap(final double[][] level) { public SoundMap(final double[][] level, Measurement measurement) { rng = new RNG(new LightRNG()); this.measurement = measurement; - alerted = new HashMap<>(); - fresh = new HashMap<>(); - sounds = new HashMap<>(); + alerted = new OrderedMap<>(); + fresh = new OrderedMap<>(); + sounds = new OrderedMap<>(); initialize(level); } @@ -140,9 +140,9 @@ public SoundMap(final double[][] level, Measurement measurement) { */ public SoundMap(final char[][] level) { rng = new RNG(new LightRNG()); - alerted = new HashMap<>(); - fresh = new HashMap<>(); - sounds = new HashMap<>(); + alerted = new OrderedMap<>(); + fresh = new OrderedMap<>(); + sounds = new OrderedMap<>(); initialize(level); } /** @@ -155,9 +155,9 @@ public SoundMap(final char[][] level) { */ public SoundMap(final char[][] level, char alternateWall) { rng = new RNG(new LightRNG()); - alerted = new HashMap<>(); - fresh = new HashMap<>(); - sounds = new HashMap<>(); + alerted = new OrderedMap<>(); + fresh = new OrderedMap<>(); + sounds = new OrderedMap<>(); initialize(level, alternateWall); } @@ -173,9 +173,9 @@ public SoundMap(final char[][] level, char alternateWall) { public SoundMap(final char[][] level, Measurement measurement) { rng = new RNG(new LightRNG()); this.measurement = measurement; - alerted = new HashMap<>(); - fresh = new HashMap<>(); - sounds = new HashMap<>(); + alerted = new OrderedMap<>(); + fresh = new OrderedMap<>(); + sounds = new OrderedMap<>(); initialize(level); } @@ -404,7 +404,7 @@ public double[][] scan() { while (numAssigned > 0) { numAssigned = 0; - HashMap fresh2 = new HashMap<>(fresh.size()); + OrderedMap fresh2 = new OrderedMap<>(fresh.size()); fresh2.putAll(fresh); fresh.clear(); @@ -449,9 +449,9 @@ public double[][] scan() { * @param extraSounds * @return */ - public HashMap findAlerted(Set creatures, Map extraSounds) { + public OrderedMap findAlerted(Set creatures, Map extraSounds) { if(!initialized) return null; - alerted = new HashMap<>(creatures.size()); + alerted = new OrderedMap<>(creatures.size()); resetMap(); for (Map.Entry sound : extraSounds.entrySet()) { diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/SpatialMap.java b/squidlib-util/src/main/java/squidpony/squidgrid/SpatialMap.java index 7c7165a2f7..56a0920217 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/SpatialMap.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/SpatialMap.java @@ -1,6 +1,8 @@ package squidpony.squidgrid; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedMap; +import squidpony.squidmath.OrderedSet; import java.util.*; @@ -11,7 +13,7 @@ * a new value, and perform analogues to most of the features of the Map interface, though this does not implement Map * because it essentially has two key types and one value type. You can also iterate through the values in insertion * order, where insertion order should be stable even when elements are moved or modified (the relevant key is the - * identity, which is never changed in this class). Uses two LinkedHashMap fields internally. + * identity, which is never changed in this class). Uses two OrderedMap fields internally. * Created by Tommy Ettinger on 1/2/2016. */ public class SpatialMap implements Iterable { @@ -56,26 +58,26 @@ public int hashCode() { } } - protected LinkedHashMap> itemMapping; - protected LinkedHashMap> positionMapping; + protected OrderedMap> itemMapping; + protected OrderedMap> positionMapping; /** * Constructs a SpatialMap with capacity 32. */ public SpatialMap() { - itemMapping = new LinkedHashMap<>(32); - positionMapping = new LinkedHashMap<>(32); + itemMapping = new OrderedMap<>(32); + positionMapping = new OrderedMap<>(32); } /** * Constructs a SpatialMap with the given capacity - * @param capacity the capacity for each of the internal LinkedHashMaps + * @param capacity the capacity for each of the internal OrderedMaps */ public SpatialMap(int capacity) { - itemMapping = new LinkedHashMap<>(capacity); - positionMapping = new LinkedHashMap<>(capacity); + itemMapping = new OrderedMap<>(capacity); + positionMapping = new OrderedMap<>(capacity); } /** @@ -88,9 +90,9 @@ public SpatialMap(int capacity) */ public SpatialMap(Coord[] coords, I[] ids, E[] elements) { - itemMapping = new LinkedHashMap<>( + itemMapping = new OrderedMap<>( Math.min(coords.length, Math.min(ids.length, elements.length))); - positionMapping = new LinkedHashMap<>( + positionMapping = new OrderedMap<>( Math.min(coords.length, Math.min(ids.length, elements.length))); for (int i = 0; i < coords.length && i < ids.length && i < elements.length; i++) { @@ -109,9 +111,9 @@ public SpatialMap(Coord[] coords, I[] ids, E[] elements) */ public SpatialMap(Collection coords, Collection ids, Collection elements) { - itemMapping = new LinkedHashMap<>( + itemMapping = new OrderedMap<>( Math.min(coords.size(), Math.min(ids.size(), elements.size()))); - positionMapping = new LinkedHashMap<>( + positionMapping = new OrderedMap<>( Math.min(coords.size(), Math.min(ids.size(), elements.size()))); if(itemMapping.size() <= 0) return; @@ -383,22 +385,22 @@ public I getIdentity(Coord c) } /** - * Get a Set of all positions used for values in this data structure, returning a LinkedHashSet (defensively copying + * Get a Set of all positions used for values in this data structure, returning a OrderedSet (defensively copying * the key set used internally) for its stable iteration order. - * @return a LinkedHashSet of Coord corresponding to the positions present in this data structure. + * @return a OrderedSet of Coord corresponding to the positions present in this data structure. */ - public LinkedHashSet positions() + public OrderedSet positions() { - return new LinkedHashSet<>(positionMapping.keySet()); + return new OrderedSet<>(positionMapping.keySet()); } /** - * Get a Set of all identities used for values in this data structure, returning a LinkedHashSet (defensively + * Get a Set of all identities used for values in this data structure, returning a OrderedSet (defensively * copying the key set used internally) for its stable iteration order. - * @return a LinkedHashSet of I corresponding to the identities present in this data structure. + * @return a OrderedSet of I corresponding to the identities present in this data structure. */ - public LinkedHashSet identities() + public OrderedSet identities() { - return new LinkedHashSet<>(itemMapping.keySet()); + return new OrderedSet<>(itemMapping.keySet()); } /** diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/Spill.java b/squidlib-util/src/main/java/squidpony/squidgrid/Spill.java index a5f2ff8db4..482cbd9046 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/Spill.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/Spill.java @@ -1,12 +1,8 @@ package squidpony.squidgrid; -import squidpony.squidmath.Coord; -import squidpony.squidmath.LightRNG; -import squidpony.squidmath.RNG; -import squidpony.squidmath.StatefulRNG; +import squidpony.squidmath.*; import java.util.ArrayList; -import java.util.LinkedHashSet; import java.util.Set; /** * A randomized flood-fill implementation that can be used for level generation (e.g. filling ponds and lakes), for @@ -79,7 +75,7 @@ public enum Measurement { * are reached on all sides and the Spill has no more room to fill. */ public int filled = 0; - private LinkedHashSet fresh; + private OrderedSet fresh; /** * The RNG used to decide which one of multiple equally-short paths to take. */ @@ -98,7 +94,7 @@ public Spill() { lrng = new LightRNG(); rng = new StatefulRNG(lrng); - fresh = new LinkedHashSet<>(); + fresh = new OrderedSet<>(); } /** * Construct a Spill without a level to actually scan. This constructor allows you to specify an RNG, but the actual @@ -111,7 +107,7 @@ public Spill(RNG random) { lrng = new LightRNG(random.nextLong()); rng = new StatefulRNG(lrng); - fresh = new LinkedHashSet<>(); + fresh = new OrderedSet<>(); } /** @@ -125,7 +121,7 @@ public Spill(LightRNG random) { lrng = random; rng = new StatefulRNG(lrng); - fresh = new LinkedHashSet<>(); + fresh = new OrderedSet<>(); } /** @@ -245,7 +241,7 @@ public Spill(final char[][] level, Measurement measurement, LightRNG random) { * @return */ public Spill initialize(final boolean[][] level) { - fresh = new LinkedHashSet<>(); + fresh = new OrderedSet<>(); width = level.length; height = level[0].length; spillMap = new boolean[width][height]; @@ -268,7 +264,7 @@ public Spill initialize(final boolean[][] level) { * @return */ public Spill initialize(final char[][] level) { - fresh = new LinkedHashSet<>(); + fresh = new OrderedSet<>(); width = level.length; height = level[0].length; spillMap = new boolean[width][height]; @@ -293,7 +289,7 @@ public Spill initialize(final char[][] level) { * @return */ public Spill initialize(final char[][] level, char alternateWall) { - fresh = new LinkedHashSet<>(); + fresh = new OrderedSet<>(); width = level.length; height = level[0].length; spillMap = new boolean[width][height]; @@ -378,7 +374,7 @@ protected void setFresh(final Coord pt) { public ArrayList start(Coord entry, int volume, Set impassable) { if(!initialized) return null; if(impassable == null) - impassable = new LinkedHashSet<>(); + impassable = new OrderedSet<>(); if(!physicalMap[entry.x][entry.y] || impassable.contains(entry)) return null; spreadPattern = new ArrayList<>(volume); diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/DungeonGenerator.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/DungeonGenerator.java index 70189cdc0d..f2631ff4df 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/DungeonGenerator.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/DungeonGenerator.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.EnumMap; -import java.util.LinkedHashSet; import static squidpony.squidmath.CoordPacker.*; @@ -326,7 +325,7 @@ public DungeonGenerator clearEffects() return this; } - protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord pt) + protected OrderedSet removeAdjacent(OrderedSet coll, Coord pt) { for(Coord temp : new Coord[]{Coord.get(pt.x + 1, pt.y), Coord.get(pt.x - 1, pt.y), Coord.get(pt.x, pt.y + 1), Coord.get(pt.x, pt.y - 1)}) @@ -337,7 +336,7 @@ protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord p return coll; } - protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord pt1, Coord pt2) + protected OrderedSet removeAdjacent(OrderedSet coll, Coord pt1, Coord pt2) { for(Coord temp : new Coord[]{Coord.get(pt1.x + 1, pt1.y), Coord.get(pt1.x - 1, pt1.y), @@ -352,9 +351,9 @@ protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord p return coll; } - protected LinkedHashSet viableDoorways(boolean doubleDoors, char[][] map) + protected OrderedSet viableDoorways(boolean doubleDoors, char[][] map) { - LinkedHashSet doors = new LinkedHashSet<>(); + OrderedSet doors = new OrderedSet<>(); for(int x = 1; x < map.length - 1; x++) { for (int y = 1; y < map[x].length - 1; y++) { if(map[x][y] == '#') @@ -544,8 +543,8 @@ public char[][] generateRespectingStairs(char[][] baseDungeon) { private char[][] innerGenerate(char[][] map) { - LinkedHashSet doorways; - LinkedHashSet hazards = new LinkedHashSet<>(); + OrderedSet doorways; + OrderedSet hazards = new OrderedSet<>(); Coord temp; boolean doubleDoors = false; int floorCount = DungeonUtility.countCells(map, '.'), @@ -582,7 +581,7 @@ private char[][] innerGenerate(char[][] map) doorways = viableDoorways(doubleDoors, map); - LinkedHashSet obstacles = new LinkedHashSet<>(doorways.size() * doorFill / 100); + OrderedSet obstacles = new OrderedSet<>(doorways.size() * doorFill / 100); if(doorFill > 0) { int total = doorways.size() * doorFill / 100; diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/LanesMapGenerator.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/LanesMapGenerator.java index b8acc6fe9e..a0cb93c7af 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/LanesMapGenerator.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/LanesMapGenerator.java @@ -1,12 +1,8 @@ package squidpony.squidgrid.mapping; -import squidpony.squidmath.Coord; -import squidpony.squidmath.CoordPacker; -import squidpony.squidmath.DDALine; -import squidpony.squidmath.RNG; +import squidpony.squidmath.*; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; /** @@ -116,7 +112,7 @@ public LanesMapGenerator(int width, int height, RNG rng, int lanes) } - LinkedHashMap> connections = new LinkedHashMap<>(80); + OrderedMap> connections = new OrderedMap<>(80); Coord temp, t; int m = random.nextInt(32), r = random.between(8, 24); temp = CoordPacker.hilbertToCoord(m); diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/LegacyDungeonGenerator.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/LegacyDungeonGenerator.java index 3316b3b9ee..0ee6abcab4 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/LegacyDungeonGenerator.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/LegacyDungeonGenerator.java @@ -5,14 +5,9 @@ import squidpony.squidgrid.Spill; import squidpony.squidgrid.mapping.styled.DungeonBoneGen; import squidpony.squidgrid.mapping.styled.TilesetType; -import squidpony.squidmath.Coord; -import squidpony.squidmath.CoordPacker; -import squidpony.squidmath.PoissonDisk; -import squidpony.squidmath.RNG; +import squidpony.squidmath.*; import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import static squidpony.squidmath.CoordPacker.*; @@ -269,17 +264,17 @@ public DungeonGenerator clearEffects() { } @Override - protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord pt) { + protected OrderedSet removeAdjacent(OrderedSet coll, Coord pt) { return super.removeAdjacent(coll, pt); } @Override - protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord pt1, Coord pt2) { + protected OrderedSet removeAdjacent(OrderedSet coll, Coord pt1, Coord pt2) { return super.removeAdjacent(coll, pt1, pt2); } @Override - protected LinkedHashSet viableDoorways(boolean doubleDoors, char[][] map) { + protected OrderedSet viableDoorways(boolean doubleDoors, char[][] map) { return super.viableDoorways(doubleDoors, map); } @@ -415,9 +410,9 @@ public char[][] generateRespectingStairs(char[][] baseDungeon) { private char[][] innerGenerate(char[][] map) { - LinkedHashSet floors = new LinkedHashSet<>(); - LinkedHashSet doorways; - LinkedHashSet hazards = new LinkedHashSet<>(); + OrderedSet floors = new OrderedSet<>(); + OrderedSet doorways; + OrderedSet hazards = new OrderedSet<>(); Coord temp; boolean doubleDoors = false; int doorFill = 0; @@ -460,7 +455,7 @@ private char[][] innerGenerate(char[][] map) floorRate -= waterRate + grassRate; doorways = viableDoorways(doubleDoors, map); - LinkedHashSet obstacles = new LinkedHashSet<>(doorways.size() * doorFill / 100); + OrderedSet obstacles = new OrderedSet<>(doorways.size() * doorFill / 100); if(doorFill > 0) { int total = doorways.size() * doorFill / 100; @@ -528,7 +523,7 @@ private char[][] innerGenerate(char[][] map) } MultiSpill ms = new MultiSpill(map, Spill.Measurement.MANHATTAN, rng); - LinkedHashMap fillers = new LinkedHashMap<>(128); + OrderedMap fillers = new OrderedMap<>(128); ArrayList dots = PoissonDisk.sampleMap(map, Math.min(width, height) / 8f, rng, '#', '+', '/','<', '>'); for (int i = 0; i < dots.size(); i++) { switch (i % 3) { @@ -629,9 +624,9 @@ private char[][] innerGenerate(char[][] map) private char[][] innerGenerateOld(char[][] map) { - LinkedHashSet floors = new LinkedHashSet<>(); - LinkedHashSet doorways; - LinkedHashSet hazards = new LinkedHashSet<>(); + OrderedSet floors = new OrderedSet<>(); + OrderedSet doorways; + OrderedSet hazards = new OrderedSet<>(); Coord temp; boolean doubleDoors = false; int doorFill = 0; @@ -663,7 +658,7 @@ private char[][] innerGenerateOld(char[][] map) doorways = viableDoorways(doubleDoors, map); - LinkedHashSet obstacles = new LinkedHashSet<>(doorways.size() * doorFill / 100); + OrderedSet obstacles = new OrderedSet<>(doorways.size() * doorFill / 100); if(doorFill > 0) { int total = doorways.size() * doorFill / 100; diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/ModularMapGenerator.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/ModularMapGenerator.java index f9289d2cb3..6a4d814413 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/ModularMapGenerator.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/ModularMapGenerator.java @@ -27,8 +27,8 @@ public class ModularMapGenerator { protected int[][] environment = null; //public RegionMap layout, modules, inverseModules; public RegionMap layout; - public LinkedHashMap> modules; - public LinkedHashMap displacement; + public OrderedMap> modules; + public OrderedMap displacement; private void putModule(short[] module) { char[][] unp = CoordPacker.unpackChar(module, '.', '#'); @@ -60,12 +60,12 @@ private void initModules() { layout = new RegionMap<>(64); //modules = new RegionMap<>(64); //inverseModules = new RegionMap<>(64); - modules = new LinkedHashMap<>(64); + modules = new OrderedMap<>(64); for (int i = 1; i <= 64; i <<= 1) { ArrayList mms = new ArrayList<>(16); modules.put(i, mms); } - displacement = new LinkedHashMap<>(64); + displacement = new OrderedMap<>(64); float multiplier = 1;//(float) Math.sqrt(Math.max(1f, Math.min(width, height) / 24f)); putRectangle(2, 2, multiplier); putRectangle(3, 3, multiplier); @@ -144,7 +144,7 @@ public ModularMapGenerator(ModularMapGenerator copying) { map = GwtCompatibility.copy2D(copying.map); environment = GwtCompatibility.copy2D(copying.environment); layout = new RegionMap<>(copying.layout); - modules = new LinkedHashMap<>(copying.modules); + modules = new OrderedMap<>(copying.modules); } /** diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/Placement.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/Placement.java index 14c96524fd..e6c621061b 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/Placement.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/Placement.java @@ -3,9 +3,7 @@ import squidpony.squidgrid.FOV; import squidpony.squidgrid.Radius; import squidpony.squidmath.Coord; - -import java.util.Collections; -import java.util.LinkedHashSet; +import squidpony.squidmath.OrderedSet; import static squidpony.squidmath.CoordPacker.*; @@ -24,9 +22,9 @@ public class Placement { private short[] allRooms = ALL_WALL, allCaves = ALL_WALL, allCorridors = ALL_WALL, allFloors = ALL_WALL, nonRoom; - private LinkedHashSet> alongStraightWalls = null, + private OrderedSet> alongStraightWalls = null, corners = null, centers = null; - private LinkedHashSet hidingPlaces = null; + private OrderedSet hidingPlaces = null; private Placement() { @@ -63,16 +61,16 @@ public Placement(RoomFinder finder) } /** - * Gets a LinkedHashSet of LinkedHashSet of Coord, where each inner LinkedHashSet of Coord refers to a placement + * 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 LinkedHashSet> getAlongStraightWalls() { + public OrderedSet> getAlongStraightWalls() { if(alongStraightWalls == null) { - alongStraightWalls = new LinkedHashSet<>(32); + alongStraightWalls = new OrderedSet<>(32); short[] working; for(short[] region : finder.rooms.keys()) { working = @@ -92,16 +90,16 @@ public LinkedHashSet> getAlongStraightWalls() { } /** - * Gets a LinkedHashSet of LinkedHashSet of Coord, where each inner LinkedHashSet of Coord refers to a room's + * Gets an OrderedSet of OrderedSet of Coord, where each inner OrderedSet of Coord refers to a room's * corners, and each Coord is one of those corners. There are more uses for corner placement than I can list. This * doesn't always identify all corners, since it only finds ones in rooms, and a cave too close to a corner can * cause that corner to be ignored. * @return a set of sets of Coord where each set of Coord is a room's corners */ - public LinkedHashSet> getCorners() { + public OrderedSet> getCorners() { if(corners == null) { - corners = new LinkedHashSet<>(32); + corners = new OrderedSet<>(32); short[] working; for(short[] region : finder.rooms.keys()) { working = @@ -114,7 +112,7 @@ public LinkedHashSet> getCorners() { nonRoom); for(Coord c : allPacked(working)) { - LinkedHashSet lhs = new LinkedHashSet(); + OrderedSet lhs = new OrderedSet(); lhs.add(c); corners.add(lhs); } @@ -124,7 +122,7 @@ public LinkedHashSet> getCorners() { return corners; } /** - * Gets a LinkedHashSet of LinkedHashSet of Coord, where each inner LinkedHashSet of Coord refers to a room's cells + * Gets an OrderedSet of OrderedSet of Coord, where each inner OrderedSet of Coord refers to a room's cells * that are furthest from the walls, and each Coord is one of those central positions. There are many uses for this, * like finding a position to place a throne or shrine in a large room where it should be visible from all around. * This doesn't always identify all centers, since it only finds ones in rooms, and it can also find multiple @@ -132,10 +130,10 @@ public LinkedHashSet> getCorners() { * find a 1x5 column as the centers of that room). * @return a set of sets of Coord where each set of Coord contains a room's cells that are furthest from the walls. */ - public LinkedHashSet> getCenters() { + public OrderedSet> getCenters() { if(centers == null) { - centers = new LinkedHashSet<>(32); + centers = new OrderedSet<>(32); short[] working, working2; for(short[] region : finder.rooms.keys()) { @@ -162,16 +160,16 @@ public LinkedHashSet> getCenters() { } /** - * Gets a LinkedHashSet of Coord, where each Coord is hidden (using the given radiusStrategy and range for FOV + * Gets an OrderedSet of Coord, where each Coord is hidden (using the given radiusStrategy and range for FOV * calculations) from any doorways or similar narrow choke-points where a character might be easily ambushed. If * multiple choke-points can see a cell (using shadow-casting FOV, which is asymmetrical), then the cell is very * unlikely to be included in the returned Coords, but if a cell is visible from one or no choke-points and is far * enough away, then it is more likely to be included. * @param radiusStrategy a Radius object that will be used to determine visibility. * @param range the minimum distance things are expected to hide at; often related to player FOV range - * @return a set of Coord where each Coord is either far away from or is concealed from a door-like area + * @return a Set of Coord where each Coord is either far away from or is concealed from a door-like area */ - public LinkedHashSet getHidingPlaces(Radius radiusStrategy, int range) { + public OrderedSet getHidingPlaces(Radius radiusStrategy, int range) { if(hidingPlaces == null) { double[][] composite = new double[finder.width][finder.height], @@ -193,10 +191,8 @@ public LinkedHashSet getHidingPlaces(Radius radiusStrategy, int range) { return hidingPlaces; } - private static LinkedHashSet arrayToSet(Coord[] arr) + private static OrderedSet arrayToSet(Coord[] arr) { - LinkedHashSet lhs = new LinkedHashSet<>(arr.length); - Collections.addAll(lhs, arr); - return lhs; + return new OrderedSet (arr); } } diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/RoomFinder.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/RoomFinder.java index 36a79283c9..0cfe7b9c97 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/RoomFinder.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/RoomFinder.java @@ -2,11 +2,11 @@ import squidpony.GwtCompatibility; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedSet; import squidpony.squidmath.RegionMap; import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedHashSet; import java.util.List; import static squidpony.squidmath.CoordPacker.*; @@ -370,7 +370,7 @@ public static char[][] merge(ArrayList regions, int width, int height) */ public char[][] regionAt(int x, int y) { - LinkedHashSet regions = rooms.regionsContaining(x, y); + OrderedSet regions = rooms.regionsContaining(x, y); regions.addAll(corridors.regionsContaining(x, y)); regions.addAll(caves.regionsContaining(x, y)); short[] found; @@ -390,7 +390,7 @@ public char[][] regionAt(int x, int y) */ public char[][] regionsNear(int x, int y) { - LinkedHashSet regions = rooms.regionsContaining(x, y); + OrderedSet regions = rooms.regionsContaining(x, y); regions.addAll(corridors.regionsContaining(x, y)); regions.addAll(caves.regionsContaining(x, y)); short[] found; @@ -399,7 +399,7 @@ public char[][] regionsNear(int x, int y) else { found = GwtCompatibility.first(regions); - LinkedHashSet> near = rooms.allAt(x, y); + OrderedSet> near = rooms.allAt(x, y); for (List links : near) { for(short[] n : links) { @@ -434,7 +434,7 @@ public char[][] regionsNear(int x, int y) public ArrayList regionsConnected(int x, int y) { ArrayList regions = new ArrayList<>(10); - LinkedHashSet> near = rooms.allAt(x, y); + OrderedSet> near = rooms.allAt(x, y); for (List links : near) { for(short[] n : links) { diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SectionDungeonGenerator.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SectionDungeonGenerator.java index ed0fc0e50b..81a39ee761 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SectionDungeonGenerator.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SectionDungeonGenerator.java @@ -564,7 +564,7 @@ public SectionDungeonGenerator clearEffects() return this; } - protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord pt) + protected OrderedSet removeAdjacent(OrderedSet coll, Coord pt) { for(Coord temp : new Coord[]{Coord.get(pt.x + 1, pt.y), Coord.get(pt.x - 1, pt.y), Coord.get(pt.x, pt.y + 1), Coord.get(pt.x, pt.y - 1)}) @@ -575,7 +575,7 @@ protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord p return coll; } - protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord pt1, Coord pt2) + protected OrderedSet removeAdjacent(OrderedSet coll, Coord pt1, Coord pt2) { for(Coord temp : new Coord[]{Coord.get(pt1.x + 1, pt1.y), Coord.get(pt1.x - 1, pt1.y), @@ -589,11 +589,11 @@ protected LinkedHashSet removeAdjacent(LinkedHashSet coll, Coord p return coll; } - protected LinkedHashSet removeNearby(LinkedHashSet coll, char[][] disallowed) + protected OrderedSet removeNearby(OrderedSet coll, char[][] disallowed) { if(coll == null || disallowed == null || disallowed.length == 0 || disallowed[0].length == 0) - return new LinkedHashSet<>(); - LinkedHashSet next = new LinkedHashSet<>(coll.size()); + return new OrderedSet<>(); + OrderedSet next = new OrderedSet<>(coll.size()); int width = disallowed.length, height = disallowed[0].length; COORD_WISE: for(Coord c : coll) @@ -612,10 +612,10 @@ protected LinkedHashSet removeNearby(LinkedHashSet coll, char[][] } - protected LinkedHashSet viableDoorways(boolean doubleDoors, char[][] map, char[][] allCaves, + protected OrderedSet viableDoorways(boolean doubleDoors, char[][] map, char[][] allCaves, char[][] allCorridors) { - LinkedHashSet doors = new LinkedHashSet<>(); + OrderedSet doors = new OrderedSet<>(); for(int x = 1; x < map.length - 1; x++) { for (int y = 1; y < map[x].length - 1; y++) { if(map[x][y] == '#' || allCorridors[x][y] != '#') @@ -917,7 +917,7 @@ private char[][] makeDoors(ArrayList rooms, ArrayList corrid map = RoomFinder.merge(fused, width, height); - LinkedHashSet doorways = viableDoorways(doubleDoors, map, allCaves, allCorridors); + OrderedSet doorways = viableDoorways(doubleDoors, map, allCaves, allCorridors); int total = doorways.size() * doorFill / 100; @@ -1063,7 +1063,7 @@ else if (shallow[x][y]) private char[][] innerGenerate(char[][] map, EnumMap fx) { - LinkedHashSet hazards = new LinkedHashSet<>(); + OrderedSet hazards = new OrderedSet<>(); int floorCount = DungeonUtility.countCells(map, '.'), doorFill = 0, waterFill = 0, diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SerpentDeepMapGenerator.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SerpentDeepMapGenerator.java index bfa96cea3e..4b3cfef2b6 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SerpentDeepMapGenerator.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SerpentDeepMapGenerator.java @@ -1,12 +1,8 @@ package squidpony.squidgrid.mapping; -import squidpony.squidmath.Coord; -import squidpony.squidmath.CoordPacker; -import squidpony.squidmath.RNG; +import squidpony.squidmath.*; import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; /** @@ -24,7 +20,7 @@ public class SerpentDeepMapGenerator { private MixedGenerator[] mix; private int[] columns, rows; private int width, height, depth; - private ArrayList> linksUp,linksDown; + private ArrayList> linksUp,linksDown; private RNG random; /** @@ -79,8 +75,8 @@ public SerpentDeepMapGenerator(int width, int height, int depth, RNG rng, double linksUp = new ArrayList<>(depth); linksDown = new ArrayList<>(depth); for (int i = 0; i < depth; i++) { - linksUp.add(new LinkedHashSet(80)); - linksDown.add(new LinkedHashSet(80)); + linksUp.add(new OrderedSet(80)); + linksDown.add(new OrderedSet(80)); } int csum = 0, rsum = 0; long b = 3; @@ -106,9 +102,9 @@ public SerpentDeepMapGenerator(int width, int height, int depth, RNG rng, double rows[i] += rs3; } - List>> connections = new ArrayList<>(depth); + List>> connections = new ArrayList<>(depth); for (int i = 0; i < depth; i++) { - connections.add(new LinkedHashMap>(80)); + connections.add(new OrderedMap>(80)); } int m = random.nextInt(0x800 * numLayers); int x = CoordPacker.getXMoore3D(m, numLayers), y = CoordPacker.getYMoore3D(m, numLayers), @@ -340,14 +336,14 @@ public char[][][] generate() floors[i] = CoordPacker.pack(dungeon[i], '.'); } //using actual dungeon space per layer, not row/column 3D grid space - ArrayList> ups = new ArrayList<>(depth), + ArrayList> ups = new ArrayList<>(depth), downs = new ArrayList<>(depth); for (int i = 0; i < depth; i++) { - ups.add(new LinkedHashSet(40)); - downs.add(new LinkedHashSet(40)); - LinkedHashSet above = null; + ups.add(new OrderedSet(40)); + downs.add(new OrderedSet(40)); + OrderedSet above = null; if (i > 0) { - above = new LinkedHashSet<>(linksDown.get(i - 1)); + above = new OrderedSet<>(linksDown.get(i - 1)); if(above.size() == 0) continue; Coord higher = random.getRandomElement(above.toArray(new Coord[above.size()])); @@ -375,7 +371,7 @@ public char[][][] generate() } for (int i = 0; i < depth; i++) { - LinkedHashMap used = new LinkedHashMap<>(128); + OrderedMap used = new OrderedMap<>(128); for(Coord up : ups.get(i)) { Integer count = used.get(up); diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SerpentMapGenerator.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SerpentMapGenerator.java index e680b5208a..3aa831e388 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SerpentMapGenerator.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SerpentMapGenerator.java @@ -1,12 +1,8 @@ package squidpony.squidgrid.mapping; -import squidpony.squidmath.Coord; -import squidpony.squidmath.CoordPacker; -import squidpony.squidmath.OrthoLine; -import squidpony.squidmath.RNG; +import squidpony.squidmath.*; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; /** @@ -173,7 +169,7 @@ public SerpentMapGenerator(int width, int height, RNG rng, double branchingChanc rows[i] += rs3; } - LinkedHashMap> connections = new LinkedHashMap<>(80); + OrderedMap> connections = new OrderedMap<>(80); Coord temp, t; int m = random.nextInt(64), r = random.between(4, 12); temp = CoordPacker.mooreToCoord(m); diff --git a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SymmetryDungeonGenerator.java b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SymmetryDungeonGenerator.java index fd65a1f5ce..66cf4c776d 100644 --- a/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SymmetryDungeonGenerator.java +++ b/squidlib-util/src/main/java/squidpony/squidgrid/mapping/SymmetryDungeonGenerator.java @@ -1,10 +1,11 @@ package squidpony.squidgrid.mapping; -import squidpony.squidmath.Coord; -import squidpony.squidmath.PoissonDisk; -import squidpony.squidmath.RNG; +import squidpony.squidmath.*; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * A variant on {@link MixedGenerator} that creates bi-radially symmetric maps (basically a yin-yang shape). Useful for @@ -15,7 +16,7 @@ */ public class SymmetryDungeonGenerator extends MixedGenerator { - public static LinkedHashMap> removeSomeOverlap(int width, int height, List sequence) + public static OrderedMap> removeSomeOverlap(int width, int height, List sequence) { List s2 = new ArrayList<>(sequence.size()); for(Coord c : sequence) @@ -25,9 +26,9 @@ public static LinkedHashMap> removeSomeOverlap(int width, int } return listToMap(s2); } - public static LinkedHashMap> removeSomeOverlap(int width, int height, Map> connections) { - LinkedHashMap> lhm2 = new LinkedHashMap<>(connections.size()); - Set keyset = connections.keySet(), newkeys = new LinkedHashSet<>(connections.size()); + public static OrderedMap> removeSomeOverlap(int width, int height, Map> connections) { + OrderedMap> lhm2 = new OrderedMap<>(connections.size()); + Set keyset = connections.keySet(), newkeys = new OrderedSet<>(connections.size()); for (Coord c : keyset) { if (c.x * 1.0 / width + c.y * 1.0 / height <= 1.0) { newkeys.add(c); @@ -100,7 +101,7 @@ public SymmetryDungeonGenerator(int width, int height, RNG rng, List sequ * @param connections a Map of Coord keys to arrays of Coord to connect to next; shouldn't connect both ways * @see SerpentMapGenerator a class that uses this technique */ - public SymmetryDungeonGenerator(int width, int height, RNG rng, LinkedHashMap> connections) { + public SymmetryDungeonGenerator(int width, int height, RNG rng, OrderedMap> connections) { this(width, height, rng, connections, 0.8f); } @@ -119,13 +120,13 @@ public SymmetryDungeonGenerator(int width, int height, RNG rng, LinkedHashMap> connections, float roomSizeMultiplier) { + public SymmetryDungeonGenerator(int width, int height, RNG rng, OrderedMap> connections, float roomSizeMultiplier) { super(width, height, rng, crossConnect(width, height, connections), roomSizeMultiplier); } - protected static LinkedHashMap> listToMap(List sequence) + protected static OrderedMap> listToMap(List sequence) { - LinkedHashMap> conns = new LinkedHashMap<>(sequence.size() - 1); + OrderedMap> conns = new OrderedMap<>(sequence.size() - 1); for (int i = 0; i < sequence.size() - 1; i++) { Coord c1 = sequence.get(i), c2 = sequence.get(i+1); List cs = new ArrayList<>(1); @@ -135,9 +136,9 @@ protected static LinkedHashMap> listToMap(List sequenc return conns; } - protected static LinkedHashMap> crossConnect(int width, int height, Map> connections) + protected static OrderedMap> crossConnect(int width, int height, Map> connections) { - LinkedHashMap> conns = new LinkedHashMap<>(connections.size()); + OrderedMap> conns = new OrderedMap<>(connections.size()); for(Map.Entry> entry : connections.entrySet()) { conns.put(entry.getKey(), new ArrayList<>(entry.getValue())); diff --git a/squidlib-util/src/main/java/squidpony/squidmath/CoordPacker.java b/squidlib-util/src/main/java/squidpony/squidmath/CoordPacker.java index c4e8a2c181..05ceb04b41 100644 --- a/squidlib-util/src/main/java/squidpony/squidmath/CoordPacker.java +++ b/squidlib-util/src/main/java/squidpony/squidmath/CoordPacker.java @@ -9,7 +9,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.LinkedHashSet; /** @@ -1627,9 +1626,9 @@ public static boolean queryPackedHilbert(short[] packed, short hilbert) * returned by packMulti(); null elements in packed will be skipped. * @return an ArrayList of all packed arrays that store true at the given x,y location. */ - public static LinkedHashSet findManyPacked(int x, int y, short[] ... packed) + public static OrderedSet findManyPacked(int x, int y, short[] ... packed) { - LinkedHashSet packs = new LinkedHashSet<>(packed.length); + OrderedSet packs = new OrderedSet<>(packed.length); int hilbertDistance = posToHilbert(x, y); for (int a = 0; a < packed.length; a++) { if(packed[a] == null) continue; @@ -1658,7 +1657,7 @@ public static LinkedHashSet findManyPacked(int x, int y, short[] ... pa */ public static boolean regionsContain(short[] checking, short[] ... packed) { - LinkedHashSet packs = new LinkedHashSet<>(packed.length); + OrderedSet packs = new OrderedSet<>(packed.length); for (int a = 0; a < packed.length; a++) { if(packed[a] == null) continue; int total = 0; diff --git a/squidlib-util/src/main/java/squidpony/squidmath/MathExtras.java b/squidlib-util/src/main/java/squidpony/squidmath/MathExtras.java index d80ff413f3..af7aca8aa0 100644 --- a/squidlib-util/src/main/java/squidpony/squidmath/MathExtras.java +++ b/squidlib-util/src/main/java/squidpony/squidmath/MathExtras.java @@ -16,7 +16,6 @@ package squidpony.squidmath; import java.math.BigInteger; -import java.util.LinkedHashMap; /** * Mathematical operations not provided by {@link Math java.lang.Math}. @@ -36,8 +35,8 @@ public final class MathExtras 6227020800L, 87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L, 121645100408832000L, 2432902008176640000L }; - private static final LinkedHashMap BIG_FACTORIALS - = new LinkedHashMap(); + private static final OrderedMap BIG_FACTORIALS + = new OrderedMap(); private MathExtras() diff --git a/squidlib-util/src/main/java/squidpony/squidmath/PoissonDisk.java b/squidlib-util/src/main/java/squidpony/squidmath/PoissonDisk.java index fc5a5da55b..bac20b42cd 100644 --- a/squidlib-util/src/main/java/squidpony/squidmath/PoissonDisk.java +++ b/squidlib-util/src/main/java/squidpony/squidmath/PoissonDisk.java @@ -5,7 +5,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.LinkedHashSet; /** * This provides a Uniform Poisson Disk Sampling technique that can be used to generate random points that have a @@ -121,7 +120,7 @@ private static ArrayList sample(Coord minPosition, Coord maxPosition, flo int gridHeight = (int)(dimensions.y / cellSize) + 1; Coord[][] grid = new Coord[gridWidth][gridHeight]; ArrayList activePoints = new ArrayList<>(); - LinkedHashSet points = new LinkedHashSet<>(128); + OrderedSet points = new OrderedSet<>(128); //add first point boolean added = false; @@ -223,7 +222,7 @@ public static ArrayList sampleMap(Coord minPosition, Coord maxPosition, c int gridHeight = (int) (dimensions.y / cellSize) + 1; Coord[][] grid = new Coord[gridWidth][gridHeight]; ArrayList activePoints = new ArrayList<>(); - LinkedHashSet points = new LinkedHashSet<>(128); + OrderedSet points = new OrderedSet<>(128); //add first point diff --git a/squidlib-util/src/main/java/squidpony/squidmath/ProbabilityTable.java b/squidlib-util/src/main/java/squidpony/squidmath/ProbabilityTable.java index a74445c1d3..4a1c7e2861 100644 --- a/squidlib-util/src/main/java/squidpony/squidmath/ProbabilityTable.java +++ b/squidlib-util/src/main/java/squidpony/squidmath/ProbabilityTable.java @@ -3,8 +3,7 @@ import squidpony.annotation.Beta; import java.io.Serializable; -import java.util.HashMap; -import java.util.Set; +import java.util.SortedSet; /** * A generic method of holding a probability table to determine weighted random @@ -20,9 +19,9 @@ @Beta public class ProbabilityTable implements Serializable { private static final long serialVersionUID = -1307656083434154736L; - private final HashMap table = new HashMap<>(); + private final OrderedMap table; private RNG rng; - private int total = 0; + private int total; /** * Creates a new probability table. @@ -39,6 +38,8 @@ public ProbabilityTable() { */ public ProbabilityTable(RNG rng) { this.rng = rng; + table = new OrderedMap<>(); + total = 0; } /** @@ -97,9 +98,9 @@ public int weight(T item) { * Provides a set of the items in this table, without reference to their * weight. * - * @return a set of all items stored + * @return a "sorted" set of all items stored, really sorted in insertion order */ - public Set items() { + public SortedSet items() { return table.keySet(); } } diff --git a/squidlib-util/src/main/java/squidpony/squidmath/RandomBias.java b/squidlib-util/src/main/java/squidpony/squidmath/RandomBias.java index ac46599afc..8213304e16 100644 --- a/squidlib-util/src/main/java/squidpony/squidmath/RandomBias.java +++ b/squidlib-util/src/main/java/squidpony/squidmath/RandomBias.java @@ -1,7 +1,6 @@ package squidpony.squidmath; import java.io.Serializable; -import java.util.LinkedHashMap; import java.util.Map; /** @@ -35,7 +34,7 @@ * Created by Tommy Ettinger on 3/20/2016. */ public class RandomBias implements Serializable { - private LinkedHashMap biases; + private OrderedMap biases; public RNG rng; public int distribution = EXP_TRI; @@ -97,13 +96,13 @@ public class RandomBias implements Serializable { public RandomBias() { - biases = new LinkedHashMap<>(32); + biases = new OrderedMap<>(32); rng = new RNG(); } public RandomBias(RNG rng) { this.rng = rng; - biases = new LinkedHashMap<>(32); + biases = new OrderedMap<>(32); } public RandomBias(RNG rng, Map mapping) { @@ -113,9 +112,9 @@ public RandomBias(RNG rng, Map mapping, int distribution) { this.rng = rng; this.distribution = distribution; if (mapping == null) { - biases = new LinkedHashMap<>(32); + biases = new OrderedMap<>(32); } else { - biases = new LinkedHashMap<>(mapping.size()); + biases = new OrderedMap<>(mapping.size()); double exp; for (Map.Entry kv : mapping.entrySet()) { exp = kv.getValue(); diff --git a/squidlib-util/src/main/java/squidpony/squidmath/RegionMap.java b/squidlib-util/src/main/java/squidpony/squidmath/RegionMap.java index 8faa6b3b0b..cae086e83e 100644 --- a/squidlib-util/src/main/java/squidpony/squidmath/RegionMap.java +++ b/squidlib-util/src/main/java/squidpony/squidmath/RegionMap.java @@ -341,10 +341,10 @@ private V getStash (short[] key, V defaultValue) { * @param y the y coordinate of the point in question * @return an ArrayList of all V values corresponding to regions containing the given x,y point. */ - public LinkedHashSet allAt(int x, int y) + public OrderedSet allAt(int x, int y) { - LinkedHashSet found = new LinkedHashSet<>(capacity); - LinkedHashSet regions = CoordPacker.findManyPacked(x, y, keyTable); + OrderedSet found = new OrderedSet<>(capacity); + OrderedSet regions = CoordPacker.findManyPacked(x, y, keyTable); for(short[] region : regions) { found.add(get(region)); @@ -368,7 +368,7 @@ public boolean containsRegion(short[] region) * @param y the y coordinate of the point in question * @return an ArrayList of all regions in this data structure containing the given x,y point. */ - public LinkedHashSet regionsContaining(int x, int y) + public OrderedSet regionsContaining(int x, int y) { return CoordPacker.findManyPacked(x, y, keyTable); } diff --git a/squidlib-util/src/test/java/squidpony/examples/DungeonGeneratorTest.java b/squidlib-util/src/test/java/squidpony/examples/DungeonGeneratorTest.java index be636b3698..8ba0d9cd0b 100644 --- a/squidlib-util/src/test/java/squidpony/examples/DungeonGeneratorTest.java +++ b/squidlib-util/src/test/java/squidpony/examples/DungeonGeneratorTest.java @@ -169,7 +169,7 @@ public static void main( String[] args ) } */ /* - for(LinkedHashSet lhs : sdg.placement.getAlongStraightWalls()) + for(OrderedSet lhs : sdg.placement.getAlongStraightWalls()) { for(Coord c : lhs) { @@ -177,7 +177,7 @@ public static void main( String[] args ) } } - for(LinkedHashSet lhs : sdg.placement.getCorners()) + for(OrderedSet lhs : sdg.placement.getCorners()) { for(Coord c : lhs) { @@ -185,7 +185,7 @@ public static void main( String[] args ) } } - for(LinkedHashSet lhs : sdg.placement.getCenters()) + for(OrderedSet lhs : sdg.placement.getCenters()) { for(Coord c : lhs) { diff --git a/squidlib-util/src/test/java/squidpony/examples/FOVTest.java b/squidlib-util/src/test/java/squidpony/examples/FOVTest.java index 115d164c76..bd34620bc6 100644 --- a/squidlib-util/src/test/java/squidpony/examples/FOVTest.java +++ b/squidlib-util/src/test/java/squidpony/examples/FOVTest.java @@ -6,10 +6,10 @@ import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidgrid.mapping.OrganicMapGenerator; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedSet; import squidpony.squidmath.StatefulRNG; import java.util.ArrayList; -import java.util.LinkedHashSet; /** * Created by Tommy Ettinger on 5/13/2016. @@ -39,7 +39,7 @@ public static void main(String[] args) { short[] floors = DungeonUtility.packedFloors(dungeon); Coord pt = dungeonGenerator.utility.randomCell(floors); Coord start = pt; - LinkedHashSet points = new LinkedHashSet<>(20); + OrderedSet points = new OrderedSet<>(20); double[][] losMap = fov.calculateLOSMap(resMap, pt.x, pt.y); for (int i = 0; i < 20; i++) { points.add(pt); diff --git a/squidlib-util/src/test/java/squidpony/examples/SpillTest.java b/squidlib-util/src/test/java/squidpony/examples/SpillTest.java index d5fc66cf3f..648b957f00 100644 --- a/squidlib-util/src/test/java/squidpony/examples/SpillTest.java +++ b/squidlib-util/src/test/java/squidpony/examples/SpillTest.java @@ -4,15 +4,11 @@ import squidpony.squidgrid.Spill; import squidpony.squidgrid.mapping.DungeonGenerator; import squidpony.squidgrid.mapping.DungeonUtility; -import squidpony.squidmath.Coord; -import squidpony.squidmath.CoordPacker; -import squidpony.squidmath.LightRNG; -import squidpony.squidmath.RNG; +import squidpony.squidmath.*; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; -import java.util.LinkedHashMap; /** * A test for the randomized flood-fill in the Spill class. This runs the Spill twice from the same starting position, @@ -69,7 +65,7 @@ public static void main(String[] args) { System.out.println(dg); short[] valid = CoordPacker.pack(dun, '.'); - LinkedHashMap entries = new LinkedHashMap<>(16); + OrderedMap entries = new OrderedMap<>(16); ArrayList section = CoordPacker.randomPortion(valid, 16, rng); for (int i = 0; i < 4; i++) { entries.put(section.get(i * 4 ), 1.0); diff --git a/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidLayers.java b/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidLayers.java index 5cc0106920..97b5b182ef 100644 --- a/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidLayers.java +++ b/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidLayers.java @@ -1632,7 +1632,7 @@ public AnimatedEntity animateActor(int x, int y, TextureRegion tr, boolean doubl return animateActor(x, y, tr, Color.WHITE, doubleWidth, stretch); } - public LinkedHashSet getAnimatedEntities(int layer) { + public Set getAnimatedEntities(int layer) { SquidPanel p = foregroundPanel; switch (layer) { case 0: @@ -1648,7 +1648,7 @@ public LinkedHashSet getAnimatedEntities(int layer) { return p.getAnimatedEntities(); } - public LinkedHashSet getAnimatedEntities() { + public Set getAnimatedEntities() { return foregroundPanel.getAnimatedEntities(); } diff --git a/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidPanel.java b/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidPanel.java index fd0963fc05..5dab468733 100644 --- a/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidPanel.java +++ b/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidPanel.java @@ -14,9 +14,13 @@ import squidpony.panel.ISquidPanel; import squidpony.squidgrid.Direction; import squidpony.squidmath.Coord; +import squidpony.squidmath.OrderedSet; import squidpony.squidmath.StatefulRNG; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Set; /** * Displays text and images in a grid pattern. Supports basic animations. @@ -42,7 +46,7 @@ public class SquidPanel extends Group implements ISquidPanel { protected Color lightingColor = SColor.WHITE; protected final TextCellFactory textFactory; protected float xOffset, yOffset; - protected LinkedHashSet animatedEntities; + protected OrderedSet animatedEntities; protected boolean distanceField = false; /** @@ -147,7 +151,7 @@ public SquidPanel(int gridWidth, int gridHeight, TextCellFactory factory, IColor this.xOffset = xOffset; this.yOffset = yOffset; setSize(w, h); - animatedEntities = new LinkedHashSet<>(); + animatedEntities = new OrderedSet<>(); } /** @@ -1312,7 +1316,7 @@ public boolean hasActiveAnimations() { return animationCount != 0; } - public LinkedHashSet getAnimatedEntities() { + public Set getAnimatedEntities() { return animatedEntities; } diff --git a/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/TextCellFactory.java b/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/TextCellFactory.java index 873f770695..08484dbd65 100644 --- a/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/TextCellFactory.java +++ b/squidlib/src/main/java/squidpony/squidgrid/gui/gdx/TextCellFactory.java @@ -17,6 +17,7 @@ import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Disposable; import squidpony.IColorCenter; +import squidpony.squidmath.OrderedMap; import java.util.*; @@ -67,7 +68,7 @@ public class TextCellFactory implements Disposable { protected float smoothingMultiplier = 1f; protected float descent, lineHeight; private Label.LabelStyle style; - protected java.util.LinkedHashMap swap = new LinkedHashMap<>(32); + protected OrderedMap swap = new OrderedMap<>(32); /** @@ -101,7 +102,7 @@ public TextCellFactory copy() next.bmpFont = new BitmapFont(new BitmapFont.BitmapFontData(bmpFont.getData().getFontFile(), false), bmpFont.getRegions(), bmpFont.usesIntegerPositions()); next.block = block; - next.swap = new LinkedHashMap<>(swap); + next.swap = new OrderedMap<>(swap); next.distanceField = distanceField; next.distanceFieldScaleX = distanceFieldScaleX; next.distanceFieldScaleY = distanceFieldScaleY; @@ -1363,7 +1364,7 @@ public TextCellFactory removeSwap(char find) /** * Gets the current mapping of "swaps", or replacement pairs, to replace keys requested for drawing with their - * values in the LinkedHashMap. + * values in the OrderedMap. *
* This can be useful when you want to use certain defaults in squidlib-util's dungeon generation, like '~' for deep * water, but not others, like ',' for shallow water, and would rather have a glyph of your choice replace something @@ -1373,7 +1374,7 @@ public TextCellFactory removeSwap(char find) * swapping, like a top-down char-based map, and elements that should not, like those that display normal text. * @return the mapping of replacement pairs */ - public LinkedHashMap getAllSwaps() { + public OrderedMap getAllSwaps() { return swap; } @@ -1390,7 +1391,7 @@ public LinkedHashMap getAllSwaps() { * @return this for chaining */ public TextCellFactory setAllSwaps(Map swaps) { - this.swap = new LinkedHashMap<>(swaps.size()); + this.swap = new OrderedMap<>(swaps.size()); for(Map.Entry kv : swaps.entrySet()) { if(!kv.getKey().startsWith("\0")) diff --git a/squidlib/src/test/java/squidpony/gdx/examples/CoveredPathDemo.java b/squidlib/src/test/java/squidpony/gdx/examples/CoveredPathDemo.java index 625fea3e3a..2e99361d2c 100644 --- a/squidlib/src/test/java/squidpony/gdx/examples/CoveredPathDemo.java +++ b/squidlib/src/test/java/squidpony/gdx/examples/CoveredPathDemo.java @@ -16,10 +16,7 @@ import squidpony.squidgrid.mapping.DungeonGenerator; import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidgrid.mapping.SerpentMapGenerator; -import squidpony.squidmath.Coord; -import squidpony.squidmath.CoordPacker; -import squidpony.squidmath.LightRNG; -import squidpony.squidmath.RNG; +import squidpony.squidmath.*; import java.util.*; @@ -58,8 +55,8 @@ public Creature(AnimatedEntity ae, int hp, DijkstraMap dijkstraMap) private SquidInput input; private static final Color bgColor = SColor.DARK_SLATE_GRAY; private ArrayList teamRed, teamBlue; - private LinkedHashSet redPlaces, bluePlaces; - private List redThreats, blueThreats; + private OrderedSet redPlaces, bluePlaces; + private OrderedSet redThreats, blueThreats; private DijkstraMap getToRed, getToBlue; private Stage stage; private int framesWithoutAnimation = 0, moveLength = 6; @@ -103,11 +100,11 @@ public void create () { teamRed = new ArrayList<>(numMonsters); teamBlue = new ArrayList<>(numMonsters); - redPlaces = new LinkedHashSet<>(numMonsters); - bluePlaces = new LinkedHashSet<>(numMonsters); + redPlaces = new OrderedSet<>(numMonsters); + bluePlaces = new OrderedSet<>(numMonsters); - redThreats = new ArrayList<>(numMonsters); - blueThreats = new ArrayList<>(numMonsters); + redThreats = new OrderedSet<>(numMonsters); + blueThreats = new OrderedSet<>(numMonsters); for(int i = 0; i < numMonsters; i++) { Coord monPos = dungeonGen.utility.randomCell(placement); @@ -176,7 +173,7 @@ private void startMove(int idx) { DijkstraMap whichDijkstra = null; Technique whichTech; Set whichFoes, whichAllies; - List whichThreats; + OrderedSet whichThreats; AnimatedEntity ae = null; int health = 0; Coord user = null; @@ -263,22 +260,11 @@ private boolean checkOverlap(AnimatedEntity ae, int x, int y) } return false; } - - private LinkedHashMap convertThreats(List ts) - { - LinkedHashMap numbered = new LinkedHashMap<>(); - int i = 0; - for (Threat t : ts) - { - numbered.put(i, t); - i++; - } - return numbered; - } + private void postMove(int idx) { int i = 0, myMax, myMin; - LinkedHashSet whichFoes, whichAllies, visibleTargets = new LinkedHashSet<>(8); + OrderedSet whichFoes, whichAllies, visibleTargets = new OrderedSet<>(8); AnimatedEntity ae = null; int health = 0; Coord user = null; @@ -286,14 +272,14 @@ private void postMove(int idx) { ArrayList previous = null; Color whichTint = Color.WHITE; ArrayList whichEnemyTeam; - LinkedHashMap myThreats, enemyThreats; + OrderedSet myThreats, enemyThreats; if (blueTurn) { whichFoes = redPlaces; whichAllies = bluePlaces; whichTint = Color.CYAN; whichEnemyTeam = teamRed; - myThreats = convertThreats(blueThreats); - enemyThreats = convertThreats(redThreats); + myThreats = blueThreats; + enemyThreats = redThreats; myMin = 3; myMax = 5; Creature entry = teamBlue.get(idx); @@ -307,8 +293,8 @@ private void postMove(int idx) { whichAllies = redPlaces; whichTint = Color.RED; whichEnemyTeam = teamBlue; - myThreats = convertThreats(redThreats); - enemyThreats = convertThreats(blueThreats); + myThreats = redThreats; + enemyThreats = blueThreats; myMin = 0; myMax = 1; @@ -360,8 +346,10 @@ private void postMove(int idx) { } ix++; } - if (successfulKill >= 0) { - Coord deadPos = enemyThreats.remove(successfulKill).position; + if (successfulKill >= 0 && successfulKill < enemyThreats.size()) { + Threat succ = enemyThreats.getAt(successfulKill); + enemyThreats.remove(succ); + Coord deadPos = succ.position; AnimatedEntity deadAE = whichEnemyTeam.get(successfulKill).entity; display.removeAnimatedEntity(deadAE); whichFoes.remove(deadPos); diff --git a/squidlib/src/test/java/squidpony/gdx/examples/EverythingDemo.java b/squidlib/src/test/java/squidpony/gdx/examples/EverythingDemo.java index 9649f7689b..a308a12825 100644 --- a/squidlib/src/test/java/squidpony/gdx/examples/EverythingDemo.java +++ b/squidlib/src/test/java/squidpony/gdx/examples/EverythingDemo.java @@ -25,10 +25,10 @@ import squidpony.squidgrid.mapping.MixedGenerator; import squidpony.squidmath.Coord; import squidpony.squidmath.CoordPacker; +import squidpony.squidmath.OrderedSet; import squidpony.squidmath.StatefulRNG; import java.util.ArrayList; -import java.util.LinkedHashSet; import java.util.List; public class EverythingDemo extends ApplicationAdapter { @@ -506,7 +506,7 @@ private void postMove() // this is an important piece of DijkstraMap usage; the argument is a Set of Points for squares that // temporarily cannot be moved through (not walls, which are automatically known because the map char[][] // was passed to the DijkstraMap constructor, but things like moving creatures and objects). - LinkedHashSet monplaces = monsters.positions(); + OrderedSet monplaces = monsters.positions(); pathMap = getToPlayer.scan(monplaces); diff --git a/squidlib/src/test/java/squidpony/gdx/examples/SquidAIDemo.java b/squidlib/src/test/java/squidpony/gdx/examples/SquidAIDemo.java index fae55eb42a..d7f5ece620 100644 --- a/squidlib/src/test/java/squidpony/gdx/examples/SquidAIDemo.java +++ b/squidlib/src/test/java/squidpony/gdx/examples/SquidAIDemo.java @@ -16,10 +16,7 @@ import squidpony.squidgrid.mapping.DungeonGenerator; import squidpony.squidgrid.mapping.DungeonUtility; import squidpony.squidgrid.mapping.styled.TilesetType; -import squidpony.squidmath.Coord; -import squidpony.squidmath.CoordPacker; -import squidpony.squidmath.LightRNG; -import squidpony.squidmath.RNG; +import squidpony.squidmath.*; import java.util.*; @@ -42,8 +39,8 @@ private enum Phase {MOVE_ANIM, ATTACK_ANIM} private SquidInput input; private static final Color bgColor = SColor.DARK_SLATE_GRAY; - private LinkedHashMap teamRed, teamBlue; - private LinkedHashSet redPlaces, bluePlaces; + private OrderedMap teamRed, teamBlue; + private OrderedSet redPlaces, bluePlaces; private Technique redCone, redCloud, blueBlast, blueBeam; private DijkstraMap getToRed, getToBlue; private Stage stage; @@ -80,11 +77,11 @@ public void create () { short[] placement = CoordPacker.pack(bareDungeon, '.'); - teamRed = new LinkedHashMap<>(numMonsters); - teamBlue = new LinkedHashMap<>(numMonsters); + teamRed = new OrderedMap<>(numMonsters); + teamBlue = new OrderedMap<>(numMonsters); - redPlaces = new LinkedHashSet<>(numMonsters); - bluePlaces = new LinkedHashSet<>(numMonsters); + redPlaces = new OrderedSet<>(numMonsters); + bluePlaces = new OrderedSet<>(numMonsters); for(int i = 0; i < numMonsters; i++) { Coord monPos = dungeonGen.utility.randomCell(placement); @@ -213,7 +210,7 @@ private void startMove(int idx) { int i = 0; DijkstraMap whichDijkstra; Technique whichTech; - Set whichFoes, whichAllies = new LinkedHashSet<>(8); + Set whichFoes, whichAllies = new OrderedSet<>(8); AnimatedEntity ae = null; int health = 0; Coord user = null; @@ -309,13 +306,13 @@ private void postMove(int idx) { int i = 0; Technique whichTech; - Set whichFoes, whichAllies, visibleTargets = new LinkedHashSet<>(8); + Set whichFoes, whichAllies, visibleTargets = new OrderedSet<>(8); AnimatedEntity ae = null; int health = 0; Coord user = null; Color whichTint = Color.WHITE; - LinkedHashMap whichEnemyTeam = null; - LinkedHashMap effects = null; + OrderedMap whichEnemyTeam = null; + OrderedMap effects = null; if (blueTurn) { whichTech = (idx % 2 == 0) ? blueBeam : blueBlast; whichFoes = redPlaces; @@ -358,7 +355,7 @@ private void postMove(int idx) { } } - LinkedHashMap> ideal = whichTech.idealLocations(user, visibleTargets, whichAllies); + OrderedMap> ideal = whichTech.idealLocations(user, visibleTargets, whichAllies); Coord targetCell = null; targetCell = GwtCompatibility.first(ideal.keySet());