package mhfc.net.common.world.controller;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import org.hamcrest.core.IsEqual;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import junit.framework.TestCase;
import mhfc.net.common.util.CyclicIterator;
import mhfc.net.common.world.controller.SimpleRectanglePlacer.CornerList;
import mhfc.net.common.world.controller.SimpleRectanglePlacer.IRectanglePlacingFunction;
@RunWith(value = BlockJUnit4ClassRunner.class)
public class SimpleRectanglePlacerTest extends TestCase {
private void basicABATestCase(IRectanglePlacingFunction func, int inSize, int outSize, List<Corner> expected) {
List<Corner> out = new ArrayList<>(5);
CornerPosition placedAt = func
.tryPlace(at20outer, at00inner, at02outer, -1, minCorner, maxCorner, inSize, outSize, out);
Assert.assertThat(placedAt, IsEqual.equalTo(zerozero));
Assert.assertThat(out, IsEqual.equalTo(expected));
}
private void basicAATestCase(
IRectanglePlacingFunction func,
int inSize,
int outSize,
CornerPosition placement,
List<Corner> expected) {
List<Corner> out = new ArrayList<>(5);
CornerPosition placedAt = func
.tryPlace(at_20outer, at00outer, at02outer, -1, minCorner, maxCorner, inSize, outSize, out);
Assert.assertThat(placedAt, IsEqual.equalTo(placement));
Assert.assertThat(out, IsEqual.equalTo(expected));
}
private void basicBABTestCase(IRectanglePlacingFunction func, int inSize, int outSize) {
List<Corner> out = new ArrayList<>(5);
CornerPosition placedAt = func
.tryPlace(at_20inner, at00outer, at02inner, -1, minCorner, maxCorner, inSize, outSize, out);
Assert.assertThat(placedAt, IsEqual.equalTo(null));
}
private Corner at02outer, at02inner, at00outer, at00inner, at20outer, at_20outer, at_20inner;
private CornerPosition minCorner, maxCorner, zerozero;
private CornerPosition beforeAASmallPlacedAt;
private List<Corner> beforeAASmallReplacement;
private CornerPosition beforeAAEqualPlacedAt;
private List<Corner> beforeAAEqualReplacement;
private CornerPosition beforeAABiggerPlacedAt;
private List<Corner> beforeAABiggerReplacement;
private CornerPosition afterAASmallPlacedAt;
private List<Corner> afterAASmallReplacement;
private CornerPosition afterAAEqualPlacedAt;
private List<Corner> afterAAEqualReplacement;
private CornerPosition afterAABiggerPlacedAt;
private List<Corner> afterAABiggerReplacement;
private List<Corner> ABASmallSmallReplacement;
private List<Corner> ABASmallEqualReplacement;
private List<Corner> ABASmallLargeReplacement;
private List<Corner> ABAEqualSmallReplacement;
private List<Corner> ABAEqualEqualReplacement;
private List<Corner> ABAEqualLargeReplacement;
private List<Corner> ABALargeSmallReplacement;
private List<Corner> ABALargeEqualReplacement;
private List<Corner> ABALargeLargeReplacement;
public SimpleRectanglePlacerTest() {
super("SimpleRectanglePlacer");
}
@Before
@Override
public void setUp() throws Exception {
at02outer = new Corner(CornerType.UP_LEFT, 0, 2);
at02inner = new Corner(CornerType.UP_RIGHT, 0, 2);
at00outer = new Corner(CornerType.RIGHT_UP, 0, 0);
at00inner = new Corner(CornerType.LEFT_UP, 0, 0);
at20outer = new Corner(CornerType.UP_LEFT, 2, 0);
at_20outer = new Corner(CornerType.DOWN_RIGHT, -2, 0);
at_20inner = new Corner(CornerType.UP_RIGHT, -2, 0);
zerozero = new CornerPosition(0, 0);
minCorner = zerozero;
maxCorner = zerozero;
// BeforeAASmaller
Corner testAASmall_10inner = new Corner(CornerType.RIGHT_DOWN, -1, 0);
Corner testAASmall_1_1outer = new Corner(CornerType.DOWN_RIGHT, -1, -1);
Corner testAASmall0_1outer = new Corner(CornerType.RIGHT_UP, 0, -1);
beforeAASmallPlacedAt = new CornerPosition(-1, -1);
beforeAASmallReplacement = Arrays
.asList(at_20outer, testAASmall_10inner, testAASmall_1_1outer, testAASmall0_1outer, at02outer);
// BeforeAAEqual
Corner testAAEqual_2_1outer = new Corner(CornerType.DOWN_RIGHT, -2, -1);
Corner testAAEqual0_1outer = new Corner(CornerType.RIGHT_UP, 0, -1);
beforeAAEqualPlacedAt = new CornerPosition(-2, -1);
beforeAAEqualReplacement = Arrays.asList(testAAEqual_2_1outer, testAAEqual0_1outer, at02outer);
// BeforeAABigger
Corner testAABigger_20inner = new Corner(CornerType.DOWN_LEFT, -2, 0);
Corner testAABigger_30outer = new Corner(CornerType.LEFT_DOWN, -3, 0);
Corner testAABigger_31outer = new Corner(CornerType.DOWN_RIGHT, -3, -1);
Corner testAABigger0_1outer = new Corner(CornerType.RIGHT_UP, 0, -1);
beforeAABiggerPlacedAt = new CornerPosition(-3, -1);
beforeAABiggerReplacement = Arrays.asList(
testAABigger_20inner,
testAABigger_30outer,
testAABigger_31outer,
testAABigger0_1outer,
at02outer);
// AfterAASmaller
Corner testAASmall10outer = new Corner(CornerType.RIGHT_UP, 1, 0);
Corner testAASmall11outer = new Corner(CornerType.UP_LEFT, 1, 1);
Corner testAASmall01inner = new Corner(CornerType.LEFT_UP, 0, 1);
afterAASmallPlacedAt = new CornerPosition(0, 0);
afterAASmallReplacement = Arrays
.asList(at_20outer, testAASmall10outer, testAASmall11outer, testAASmall01inner, at02outer);
// AfterAAEqual
Corner testAAEqual10outer = new Corner(CornerType.RIGHT_UP, 1, 0);
Corner testAAEqual12outer = new Corner(CornerType.UP_LEFT, 1, 2);
afterAAEqualPlacedAt = new CornerPosition(0, 0);
afterAAEqualReplacement = Arrays.asList(at_20outer, testAAEqual10outer, testAAEqual12outer);
// AfterAABigger
Corner testAABigger10outer = new Corner(CornerType.RIGHT_UP, 1, 0);
Corner testAABigger13outer = new Corner(CornerType.UP_LEFT, 1, 3);
Corner testAABigger03outer = new Corner(CornerType.LEFT_DOWN, 0, 3);
Corner testAABigger02inner = new Corner(CornerType.DOWN_LEFT, 0, 2);
afterAABiggerPlacedAt = new CornerPosition(0, 0);
afterAABiggerReplacement = Arrays
.asList(at_20outer, testAABigger10outer, testAABigger13outer, testAABigger03outer, testAABigger02inner);
// BBBeforeSmall
Corner testABASmall10inner = new Corner(CornerType.LEFT_UP, 1, 0);
// BBBeforeLarger
Corner testABALarge30outer = new Corner(CornerType.RIGHT_UP, 3, 0);
Corner testABALarge20inner = new Corner(CornerType.UP_RIGHT, 2, 0);
// BBAfterSmall
Corner testABASmall01inner = new Corner(CornerType.LEFT_UP, 0, 1);
// BBAfterLarger
Corner testABALarge03outer = new Corner(CornerType.LEFT_DOWN, 0, 3);
Corner testABALarge02inner = new Corner(CornerType.DOWN_LEFT, 0, 2);
Corner testABA11outer = new Corner(CornerType.UP_LEFT, 1, 1);
Corner testABA12outer = new Corner(CornerType.UP_LEFT, 1, 2);
Corner testABA21outer = new Corner(CornerType.UP_LEFT, 2, 1);
Corner testABA13outer = new Corner(CornerType.UP_LEFT, 1, 3);
Corner testABA22outer = new Corner(CornerType.UP_LEFT, 2, 2);
Corner testABA31outer = new Corner(CornerType.UP_LEFT, 3, 1);
Corner testABA23outer = new Corner(CornerType.UP_LEFT, 2, 3);
Corner testABA32outer = new Corner(CornerType.UP_LEFT, 3, 2);
Corner testABA33outer = new Corner(CornerType.UP_LEFT, 3, 3);
ABASmallSmallReplacement = Arrays
.asList(at20outer, testABASmall10inner, testABA11outer, testABASmall01inner, at02outer);
ABASmallEqualReplacement = Arrays.asList(at20outer, testABASmall10inner, testABA12outer);
ABASmallLargeReplacement = Arrays
.asList(at20outer, testABASmall10inner, testABA13outer, testABALarge03outer, testABALarge02inner);
ABAEqualSmallReplacement = Arrays.asList(testABA21outer, testABASmall01inner, at02outer);
ABAEqualEqualReplacement = Arrays.asList(testABA22outer);
ABAEqualLargeReplacement = Arrays.asList(testABA23outer, testABALarge03outer, testABALarge02inner);
ABALargeSmallReplacement = Arrays
.asList(testABALarge20inner, testABALarge30outer, testABA31outer, testABASmall01inner, at02outer);
ABALargeEqualReplacement = Arrays.asList(testABALarge20inner, testABALarge30outer, testABA32outer);
ABALargeLargeReplacement = Arrays.asList(
testABALarge20inner,
testABALarge30outer,
testABA33outer,
testABALarge03outer,
testABALarge02inner);
}
@After
@Override
public void tearDown() throws Exception {}
/**
* <pre>
* {@code
* --+ --+
* ..| -> ..|
* +-* ++|
* ++
* }
* </pre>
*/
@Test
public void BeforeAASmaller() {
basicAATestCase(SimpleRectanglePlacer.BeforeOuterCorner, 1, 1, beforeAASmallPlacedAt, beforeAASmallReplacement);
}
/**
* <pre>
* {@code
* --+ --+
* ..| -> ..|
* +-* |.|
* +-+
* }
* </pre>
*/
@Test
public void BeforeAAEqual() {
basicAATestCase(SimpleRectanglePlacer.BeforeOuterCorner, 2, 1, beforeAAEqualPlacedAt, beforeAAEqualReplacement);
}
/**
* <pre>
* {@code
* ---+ --+
* ..| -> ..|
* +-* ++.|
* +--+
* }
* </pre>
*/
@Test
public void BeforeAABigger() {
basicAATestCase(
SimpleRectanglePlacer.BeforeOuterCorner,
3,
1,
beforeAABiggerPlacedAt,
beforeAABiggerReplacement);
}
/**
* <pre>
* {@code
* --+ --+
* ..| -> ..++
* +-* +--+
* }
* </pre>
*/
@Test
public void AfterAASmaller() {
basicAATestCase(SimpleRectanglePlacer.AfterOuterCorner, 1, 1, afterAASmallPlacedAt, afterAASmallReplacement);
}
/**
* <pre>
* {@code
* --+ ---+
* ..| -> ...|
* +-* +--+
* }
* </pre>
*/
@Test
public void AfterAAEqual() {
basicAATestCase(SimpleRectanglePlacer.AfterOuterCorner, 1, 2, afterAAEqualPlacedAt, afterAAEqualReplacement);
}
/**
* <pre>
* {@code
* ++
* --+ -+|
* ..| -> ..|
* +-* +-+
* }
* </pre>
*/
@Test
public void AfterAABigger() {
basicAATestCase(SimpleRectanglePlacer.AfterOuterCorner, 1, 3, afterAABiggerPlacedAt, afterAABiggerReplacement);
}
@Test
public void BeforeBASmaller() {
basicBABTestCase(SimpleRectanglePlacer.BeforeOuterCorner, 1, 1);
}
@Test
public void BeforeBAEqual() {
basicBABTestCase(SimpleRectanglePlacer.BeforeOuterCorner, 2, 1);
}
@Test
public void BeforeBALarger() {
basicBABTestCase(SimpleRectanglePlacer.BeforeOuterCorner, 3, 1);
}
@Test
public void AfterABSmaller() {
basicBABTestCase(SimpleRectanglePlacer.AfterOuterCorner, 1, 1);
}
@Test
public void AfterABEqual() {
basicBABTestCase(SimpleRectanglePlacer.AfterOuterCorner, 1, 2);
}
@Test
public void AfterABLarger() {
basicBABTestCase(SimpleRectanglePlacer.AfterOuterCorner, 1, 3);
}
/**
* <pre>
* {@code
* + +
* | -> ++
* +-+ .++
* }
* </pre>
*/
@Test
public void AtABASmallSmall() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 1, 1, ABASmallSmallReplacement);
}
/**
* <pre>
* {@code
* + -+
* | -> .|
* +-+ .++
* }
* </pre>
*/
@Test
public void AtABASmallEqual() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 1, 2, ABASmallEqualReplacement);
}
/**
* <pre>
* {@code
* ++
* + +|
* | -> .|
* +-+ .++
* }
* </pre>
*/
@Test
public void AtABASmallLarge() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 1, 3, ABASmallLargeReplacement);
}
/**
* <pre>
* {@code
* + +
* | -> +-+
* +-+ ..|
* }
* </pre>
*/
@Test
public void AtABAEqualSmall() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 2, 1, ABAEqualSmallReplacement);
}
/**
* <pre>
* {@code
* + --+
* | -> ..|
* +-+ ..|
* }
* </pre>
*/
@Test
public void AtABAEqualEqual() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 2, 2, ABAEqualEqualReplacement);
}
/**
* <pre>
* {@code
* +-+
* + +.|
* | -> ..|
* +-+ ..|
* }
* </pre>
*/
@Test
public void AtABAEqualLarge() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 2, 3, ABAEqualLargeReplacement);
}
/**
* <pre>
* {@code
* + +
* | -> +--+
* +-+ ..++
* }
* </pre>
*/
@Test
public void AtABALargeSmall() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 3, 1, ABALargeSmallReplacement);
}
/**
* <pre>
* {@code
* + ---+
* | -> ...|
* +-+ ..++
* }
* </pre>
*/
@Test
public void AtABALargeEqual() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 3, 2, ABALargeEqualReplacement);
}
/**
* <pre>
* {@code
* +--+
* + +..|
* | -> ...|
* +-+ ..++
* }
* </pre>
*/
@Test
public void AtABALargeLarge() {
basicABATestCase(SimpleRectanglePlacer.AtInnerCorner, 3, 3, ABALargeLargeReplacement);
}
@Test
public void simpleInvariantFix() {
List<Corner> test = new ArrayList<>(
Arrays.asList(
new Corner(CornerType.RIGHT_DOWN, 1, 4),
new Corner(CornerType.DOWN_RIGHT, 1, 2),
new Corner(CornerType.RIGHT_DOWN, 2, 2),
new Corner(CornerType.DOWN_RIGHT, 2, 0),
//
new Corner(CornerType.RIGHT_UP, 4, 0),
new Corner(CornerType.UP_RIGHT, -4, 0),
new Corner(CornerType.RIGHT_UP, 0, 0),
new Corner(CornerType.UP_RIGHT, 0, 4)));
SimpleRectanglePlacer.fixInvariant(new CyclicIterator<>(test, 7), true);
Assert.assertThat(
test,
IsEqual.equalTo(
Arrays.asList(new Corner(CornerType.RIGHT_UP, 4, 0), new Corner(CornerType.UP_RIGHT, -4, 0))));
}
private void checkNotBothInner(Corner one, Corner two) {
TestCase.assertTrue(one.type.isOuter() || two.type.isOuter());
}
private void checkCornerList(CornerList list) {
checkNotBothInner(list.get(0), list.get(list.size() - 1));
Corner previous = list.get(0);
Iterator<Corner> listIt = list.listIterator(1);
while (listIt.hasNext()) {
Corner curr = listIt.next();
checkNotBothInner(previous, curr);
previous = curr;
}
}
@Test
public void fullTest() {
SimpleRectanglePlacer placer = new SimpleRectanglePlacer();
Random rand = new Random();
for (int i = 0; i < 25; i++) {
int sizeX = rand.nextInt(10) + 1, sizeZ = rand.nextInt(10) + 1;
placer.addRectangle(sizeX, sizeZ);
// System.out.print(sizeX + " " + sizeZ + "->");
// System.out.println(placedAt);
// System.out.println(placer);
checkCornerList(placer.getCorners());
int count = 0;
for (Corner c : placer.getCorners()) {
count += c.type.isOuter ? 1 : -1;
}
Assert.assertTrue(count == 4);
}
}
}