private List<InternalPosition> generateAllPossiblePositionsAfter(InternalMove move) { List<InternalPosition> positions = new ArrayList<InternalPosition>(); if (move.inTheSameBoundary()) { List<InternalPosition> positionsAfterMove = getPositionsAfterMove(move); positions.addAll(positionsAfterMove); } else { positions.add(getPositionAfterMove(move)); } return positions; }
/** A move in 2 different boundaries. */ private InternalPosition getPositionAfterMove(InternalMove move) { InternalPosition newPosition = position.clone(); InternalRegion region = newPosition.get(move.getRegionIndex()); InternalBoundary fromBoundary = region.get(move.getFrom().getBoundaryIndex()); InternalBoundary toBoundary = region.get(move.getTo().getBoundaryIndex()); // Rename vertices: fromBoundary .get(move.getFrom().getVertexIndex()) .setC( renameVertex( move.getFrom().getVertex().getC(), InternalConstants.TEMP_1, fromBoundary.size())); toBoundary .get(move.getTo().getVertexIndex()) .setC( renameVertex( move.getTo().getVertex().getC(), InternalConstants.TEMP_2, toBoundary.size())); InternalBoundary newBoundary = InternalBoundary.joinTwoBoundaries(fromBoundary, toBoundary, move); region.remove(fromBoundary); region.remove(toBoundary); region.add(newBoundary); return newPosition.recreate(); }
/** A move in the same boundary. */ private List<InternalPosition> getPositionsAfterMove(InternalMove move) { List<InternalPosition> positions = new ArrayList<InternalPosition>(); InternalPosition partialPosition = position.clone(); InternalRegion moveRegion = partialPosition.get(move.getRegionIndex()); InternalBoundary moveBoundary = moveRegion.get(move.getFrom().getBoundaryIndex()); // Rename vertices: if (move.getFrom().getVertexIndex() == move.getTo().getVertexIndex()) { // Same vertex: moveBoundary .get(move.getFrom().getVertexIndex()) .setC(renameVertexTwice(moveBoundary.get(move.getFrom().getVertexIndex()).getC())); } else { moveBoundary .get(move.getFrom().getVertexIndex()) .setC( renameVertex( moveBoundary.get(move.getFrom().getVertexIndex()).getC(), InternalConstants.TEMP_1, moveBoundary.size())); moveBoundary .get(move.getTo().getVertexIndex()) .setC( renameVertex( moveBoundary.get(move.getTo().getVertexIndex()).getC(), InternalConstants.TEMP_2, moveBoundary.size())); } // moveBoundary.compile(); // Remove current region/boundary moveRegion.remove(move.getFrom().getBoundaryIndex()); partialPosition.remove(move.getRegionIndex()); // TODO: detect equivalent boundaries and reduce the number of splits? Set<List<InternalBoundary>> splits = allPossibleSplits(moveRegion); // Output.debug("Number of splits: " + splits.size()); // Output.debug("Splits: " + splits); for (List<InternalBoundary> split : splits) { InternalRegion firstRegion = new InternalRegion(split); InternalRegion secondRegion = new InternalRegion(); secondRegion.addAll(moveRegion); for (InternalBoundary boundary : firstRegion) { secondRegion.remove(boundary); } int fromId = move.getFrom().getVertexIndex(); int toId = move.getTo().getVertexIndex(); InternalBoundary firstBoundary = new InternalBoundary(); firstBoundary.addAll(moveBoundary.subList(0, fromId + 1)); firstBoundary.add(new Vertex(InternalConstants.TEMP_NEW, firstBoundary)); if (moveBoundary.size() > 1) { firstBoundary.addAll(moveBoundary.subList(toId, moveBoundary.size())); } // firstBoundary.compile(); InternalBoundary secondBoundary = new InternalBoundary(); secondBoundary.addAll(moveBoundary.subList(fromId, toId + 1)); secondBoundary.add(new Vertex(InternalConstants.TEMP_NEW, firstBoundary)); // secondBoundary.compile(); // Output.debug("First boundary: " + firstBoundary); // Output.debug("Second boundary: " + secondBoundary); firstRegion.add(firstBoundary); secondRegion.add(secondBoundary); InternalPosition newPosition = new InternalPosition(partialPosition); newPosition.add(firstRegion); newPosition.add(secondRegion); positions.add(newPosition.recreate()); } return positions; }