/******************************************************************************* * Copyright (c) 2015 - 2017 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *******************************************************************************/ package jsettlers.logic.map.grid.partition; import jsettlers.algorithms.interfaces.IContainingProvider; import jsettlers.algorithms.traversing.borders.BorderTraversingAlgorithm; import jsettlers.algorithms.traversing.borders.IBorderVisitor; import jsettlers.common.position.ShortPoint2D; import jsettlers.common.utils.mutables.MutableInt; import jsettlers.logic.map.grid.partition.PartitionsListingBorderVisitor.BorderPartitionInfo; /** * This class implements an algorithm used by the {@link PartitionsGrid} to check if two positions of a partition are divided. * * @author Andreas Eberle * */ final class PartitionsDividedTester { /** * Private constructor to prevent the creation of objects. */ private PartitionsDividedTester() { } /** * Tests if the given positions (that need to lie on the border of the given partition) are connected by the given partition. * * @param partitionObjects * @param partitions * @param width * @param partition1 * @param partition1Size * @param partition2 * @param partition2Size * @return true if both positions are connected by the given partition.<br> * false if the positions are not connected. */ public static boolean isPartitionDivided(Partition[] partitionObjects, short[] partitions, short width, BorderPartitionInfo partition1, MutableInt partition1Size, BorderPartitionInfo partition2, MutableInt partition2Size) { assert partition1.partitionId == partition2.partitionId; return posNotOnBorder(partitionObjects, partitions, width, partition1.positionOfPartition, partition1.insideNeighborPosition, partition2.positionOfPartition, partition1.partitionId, partition1Size) && posNotOnBorder(partitionObjects, partitions, width, partition2.positionOfPartition, partition2.insideNeighborPosition, partition1.positionOfPartition, partition1.partitionId, partition2Size); } /** * NOTE: The call to this method is different if the given positions are swapped! * * @param partitionObjects * @param partitions * @param width * @param insideStartPosition * @param checkPosition * @param partitionSize * @return */ private static boolean posNotOnBorder(final Partition[] partitionObjects, final short[] partitions, final short width, final ShortPoint2D insideStartPosition, final ShortPoint2D outsideStartPosition, final ShortPoint2D checkPosition, final short partitionId, MutableInt partitionSize) { final short checkPositionX = checkPosition.x; final short checkPositionY = checkPosition.y; boolean pos2NotOnBorder = BorderTraversingAlgorithm.traverseBorder(new IContainingProvider() { @Override public boolean contains(int x, int y) { return partitionObjects[partitions[x + y * width]].partitionId == partitionId; } }, insideStartPosition, outsideStartPosition, new IBorderVisitor() { @Override public boolean visit(int insideX, int insideY, int outsideX, int outsideY) { return checkPositionX != insideX || checkPositionY != insideY; } }, false, partitionSize); return pos2NotOnBorder; } }