*/
protected void placeBossGoalRooms(KeyLevelRoomMapping levels)
throws RetryException {
List<Room> possibleGoalRooms = new ArrayList<Room>(dungeon.roomCount());
Symbol goalSym = new Symbol(Symbol.GOAL),
bossSym = new Symbol(Symbol.BOSS);
for (Room room: dungeon.getRooms()) {
if (room.getChildren().size() > 0 || room.getItem() != null)
continue;
Room parent = room.getParent();
if (parent == null || parent.getChildren().size() != 1 ||
room.getItem() != null ||
!parent.getPrecond().implies(room.getPrecond()))
continue;
if (isGenerateGoal()) {
if (!constraints.roomCanFitItem(room.id, goalSym) ||
!constraints.roomCanFitItem(parent.id, bossSym))
continue;
} else {
if (!constraints.roomCanFitItem(room.id, bossSym))
continue;
}
possibleGoalRooms.add(room);
}
if (possibleGoalRooms.size() == 0) throw new RetryException();
Room goalRoom = possibleGoalRooms.get(random.nextInt(
possibleGoalRooms.size())),
bossRoom = goalRoom.getParent();
if (!isGenerateGoal()) {
bossRoom = goalRoom;
goalRoom = null;
}
if (goalRoom != null) goalRoom.setItem(goalSym);
bossRoom.setItem(bossSym);
if (isBossRoomLocked()) {
int oldKeyLevel = bossRoom.getPrecond().getKeyLevel(),
newKeyLevel = Math.min(levels.keyCount(), constraints.getMaxKeys());
List<Room> oklRooms = levels.getRooms(oldKeyLevel);
if (goalRoom != null) oklRooms.remove(goalRoom);
oklRooms.remove(bossRoom);
if (goalRoom != null) levels.addRoom(newKeyLevel, goalRoom);
levels.addRoom(newKeyLevel, bossRoom);
Symbol bossKey = new Symbol(newKeyLevel-1);
Condition precond = bossRoom.getPrecond().and(bossKey);
bossRoom.setPrecond(precond);
if (goalRoom != null) goalRoom.setPrecond(precond);
if (newKeyLevel == 0) {