Completed Subtree Searches for Dungeon Packs
Completed the implementation of searching through dungeon subtrees to avoid duplicates in "nearby" rooms
This commit is contained in:
parent
5c44ddefe9
commit
8ebaa0f493
2 changed files with 52 additions and 26 deletions
|
@ -138,17 +138,22 @@ public class DungeonPack
|
||||||
int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : MAX_HISTORY_LENGTH;
|
int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : MAX_HISTORY_LENGTH;
|
||||||
ArrayList<DungeonData> history = DungeonHelper.getDungeonChainHistory(parent, this, maxSearchLength);
|
ArrayList<DungeonData> history = DungeonHelper.getDungeonChainHistory(parent, this, maxSearchLength);
|
||||||
|
|
||||||
ArrayList<DungeonData> subtreeHistory;
|
ArrayList<DungeonData> subtreeHistory = null;
|
||||||
/*if (config.getDuplicateSearchLevels() > 0)
|
if (config.getDuplicateSearchLevels() > 0)
|
||||||
{
|
{
|
||||||
subtreeHistory = DungeonHelper.getFlatDungeonTree(
|
// Search over (DuplicateSearchLevels - 1); zero means don't search at all,
|
||||||
DungeonHelper.getAncestor(parent, config.getDuplicateSearchLevels()),
|
// one means search only up to the level of the immediate parent, and so on.
|
||||||
MAX_SUBTREE_LIST_SIZE);
|
// Since we start with the parent, we need to drop the max levels by one.
|
||||||
|
NewDimData ancestor = DungeonHelper.getAncestor(parent, this, config.getDuplicateSearchLevels() - 1);
|
||||||
|
if (ancestor != null)
|
||||||
|
{
|
||||||
|
subtreeHistory = DungeonHelper.listDungeonsInTree(ancestor, this, MAX_SUBTREE_LIST_SIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
if (subtreeHistory == null)
|
||||||
{
|
{
|
||||||
subtreeHistory = new ArrayList<DungeonData>();
|
subtreeHistory = new ArrayList<DungeonData>();
|
||||||
}*/
|
}
|
||||||
subtreeHistory = new ArrayList<DungeonData>();
|
subtreeHistory = new ArrayList<DungeonData>();
|
||||||
|
|
||||||
return getNextDungeon(history, subtreeHistory, random);
|
return getNextDungeon(history, subtreeHistory, random);
|
||||||
|
|
|
@ -641,45 +641,66 @@ public class DungeonHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a breadth-first listing of all dungeons rooted at a specified dimension. Only dungeons from the same pack as the root will be included.
|
* Performs a breadth-first listing of all dungeons rooted at a specified dimension. Only dungeons from the specified pack will be included.
|
||||||
* @param root - the pocket dimension that serves as the root for the dungeon tree
|
* @param root - the pocket dimension that serves as the root for the dungeon tree
|
||||||
|
* @param pack - the pack to which any dungeons must belong in order to be listed
|
||||||
* @param maxSize - the maximum number of dungeons that can be listed
|
* @param maxSize - the maximum number of dungeons that can be listed
|
||||||
* @return a list of the dungeons used in a given dungeon tree
|
* @return a list of the dungeons used in a given dungeon tree
|
||||||
*/
|
*/
|
||||||
public static ArrayList<DungeonData> listDungeonsInTree(NewDimData root, int maxSize)
|
public static ArrayList<DungeonData> listDungeonsInTree(NewDimData root, DungeonPack pack, int maxSize)
|
||||||
{
|
{
|
||||||
|
int count = 0;
|
||||||
|
NewDimData current;
|
||||||
|
DungeonData dungeon;
|
||||||
ArrayList<DungeonData> dungeons = new ArrayList<DungeonData>();
|
ArrayList<DungeonData> dungeons = new ArrayList<DungeonData>();
|
||||||
Queue<NewDimData> pendingDimensions = new LinkedList<NewDimData>();
|
Queue<NewDimData> pendingDimensions = new LinkedList<NewDimData>();
|
||||||
|
|
||||||
if (root.dungeon() == null)
|
|
||||||
{
|
|
||||||
return dungeons;
|
|
||||||
}
|
|
||||||
pendingDimensions.add(root);
|
pendingDimensions.add(root);
|
||||||
|
|
||||||
|
// Perform a breadth-first search through the dungeon graph
|
||||||
while (dungeons.size() < maxSize && !pendingDimensions.isEmpty())
|
while (dungeons.size() < maxSize && !pendingDimensions.isEmpty())
|
||||||
{
|
{
|
||||||
NewDimData current = pendingDimensions.remove();
|
current = pendingDimensions.remove();
|
||||||
for (NewDimData child : current.children())
|
dungeon = current.dungeon();
|
||||||
|
// Check that this is a dungeon, and if so, that it belongs to the pack that we want
|
||||||
|
if (dungeon != null && dungeon.dungeonType().Owner == pack)
|
||||||
{
|
{
|
||||||
if (child.dungeon() != null)
|
dungeons.add(dungeon);
|
||||||
|
// Add all child dungeons for checking later
|
||||||
|
for (NewDimData child : current.children())
|
||||||
{
|
{
|
||||||
dungeons.add(child.dungeon());
|
|
||||||
pendingDimensions.add(child);
|
pendingDimensions.add(child);
|
||||||
}
|
}
|
||||||
if (dungeons.size() == maxSize)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dungeons;
|
return dungeons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NewDimData getAncestor(NewDimData dimension, int levels)
|
/**
|
||||||
|
* Gets the highest ancestor of a dimension with a dungeon that belongs to the specified pack.
|
||||||
|
* @param dimension - the first dimension to include in the search
|
||||||
|
* @param pack - the pack to which the ancestors must belong
|
||||||
|
* @param maxLevels - the maximum number of ancestors to check
|
||||||
|
* @return the highest ancestor that belongs to the specified pack within the specified levels, or <code>null</code> if none exists
|
||||||
|
*/
|
||||||
|
public static NewDimData getAncestor(NewDimData dimension, DungeonPack pack, int maxLevels)
|
||||||
{
|
{
|
||||||
// Find the ancestor of a dimension located a specified number of levels up.
|
// Find the ancestor of a dimension located a specified number of levels up.
|
||||||
// If such an ancestor does not exist, return the root dimension.
|
NewDimData parent = dimension;
|
||||||
return null;
|
NewDimData current = null;
|
||||||
|
|
||||||
|
// We solve this inductively. We begin with null as the first valid ancestor,
|
||||||
|
// like a kind of virtual child dimension. Then "current" references the
|
||||||
|
// highest valid ancestor found so far and "parent" references its parent
|
||||||
|
for (int levels = 0; levels <= maxLevels; levels++)
|
||||||
|
{
|
||||||
|
if (parent == null || parent.dungeon() == null ||
|
||||||
|
parent.dungeon().dungeonType().Owner != pack)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = parent;
|
||||||
|
parent = parent.parent();
|
||||||
|
}
|
||||||
|
return current;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue