The test cases are divided into 3 classes.
The first one is just a pinpoint test class that contains some corner cases:
The util class is like this:
The second one is to vary the broken level to see whether it's good enough:
The third one is a brutal force testing to test all cases in a certain range:
Now we should have enough confidence.
The first one is just a pinpoint test class that contains some corner cases:
java 代码
- package glassball;
- import junit.framework.TestCase;
- import java.util.List;
- /**
- * Testcases for path.
- */
- public class PathFinderTest extends TestCase
- {
- public void test1BallSingleCase()
- {
- int broken = 10;
- Building building = new Building(10, broken);
- PathFinder finder = new PathFinder(building, 1);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test2BallSingleCase1()
- {
- // 70 is the beginning of the 2nd level search
- int broken = 70;
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 2);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test2BallSingleCase2()
- {
- // 77 is the end of the 2nd level search.
- // 77 jumps out of the loop without going to return line.
- int broken = 77;
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 2);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test3BallSingleCase()
- {
- int broken = 53;
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 3);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test4BallSingleCase()
- {
- // 89 is a special number to test whether
- // totalFloors == baseFloor + totalFloors, it caused
- // 91 has been hit 3 times. Without this check, it kills 3 balls.
- int broken = 89;
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 4);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test4BallForLowerBound1()
- {
- int broken = 1;
- Building building = new Building(10, broken);
- PathFinder finder = new PathFinder(building, 4);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test4BallForLowerBound2()
- {
- int broken = 2;
- Building building = new Building(10, broken);
- PathFinder finder = new PathFinder(building, 4);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test4BallForLowerBound3()
- {
- int broken = 6;
- Building building = new Building(10, broken);
- PathFinder finder = new PathFinder(building, 4);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test2Ball4Floors()
- {
- int broken = 1;
- Building building = new Building(4, broken);
- PathFinder finder = new PathFinder(building, 2);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test3Ball17Floors()
- {
- int broken = 13;
- Building building = new Building(17, broken);
- PathFinder finder = new PathFinder(building, 3);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test4Ball100Floors()
- {
- int broken = 70;
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 4);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test5Ball100Floors()
- {
- int broken = 70;
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 5);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test6Ball100Floors()
- {
- int broken = 70;
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 6);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- public void test3Ball9Floors()
- {
- int broken = 9;
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 3);
- List path = finder.findPuzzlePath();
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- }
The util class is like this:
java 代码
- package glassball;
- import java.util.List;
- /**
- *
- */
- public class TestUtil
- {
- public static void printPath(List path)
- {
- System.out.print("path=");
- for (int i=0; i<path.size(); i++)
- {
- System.out.print(path.get(i).toString() + "-->");
- }
- System.out.println("END");
- System.out.println("number of trials=" + path.size());
- }
- public static int getPathSize(List path)
- {
- int size = 0;
- for (int i=0; i<path.size(); i++)
- {
- Trial trial = (Trial)path.get(i);
- if (!trial.isDeducted()) size++;
- }
- return size;
- }
- public static int getBrokenFloor(List path)
- {
- // several cases:
- // 1. the last one is broken,
- // 2. the last broken is before several wholes.
- // 3. all are broken, the one we are looking for is not in the list because:
- // it's the last one.
- for (int i=path.size()-1; i>=0; i--)
- {
- Trial trial = (Trial)path.get(i);
- // The last broken piece is the one we are looking for.
- if (trial.isBroken()) return trial.getFloor();
- }
- return -1;
- }
- public static boolean compareTwoIntegerArrays(List path1, List path2)
- {
- if (path1.size() != path2.size()) return false;
- for (int i=0; i<path1.size(); i++)
- {
- if (path1.get(i).equals(path2.get(i))) return false;
- }
- return true;
- }
- }
The second one is to vary the broken level to see whether it's good enough:
java 代码
- package glassball;
- import junit.framework.TestCase;
- import java.util.List;
- /**
- * This is to test the minimal trial numbers.
- */
- public class PathFinderMinimalFullTest extends TestCase
- {
- public void test3Ball100Floors()
- {
- int numOfTrials = 0;
- for (int broken=1; broken < 100; broken++)
- {
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 3);
- List path = finder.findPuzzlePath();
- if (TestUtil.getPathSize(path) > numOfTrials)
- numOfTrials = TestUtil.getPathSize(path);
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- System.out.println("numOfTrials=" + numOfTrials);
- }
- public void test4Ball100Floors()
- {
- int numOfTrials = 0;
- for (int broken=1; broken < 100; broken++)
- {
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 4);
- List path = finder.findPuzzlePath();
- if (TestUtil.getPathSize(path) > numOfTrials)
- numOfTrials = TestUtil.getPathSize(path);
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- System.out.println("numOfTrials=" + numOfTrials);
- }
- public void test5Ball100Floors()
- {
- int numOfTrials = 0;
- for (int broken=1; broken < 100; broken++)
- {
- Building building = new Building(100, broken);
- PathFinder finder = new PathFinder(building, 5);
- List path = finder.findPuzzlePath();
- if (TestUtil.getPathSize(path) > numOfTrials)
- numOfTrials = TestUtil.getPathSize(path);
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- System.out.println("numOfTrials=" + numOfTrials);
- }
- public void test5Ball1000Floors()
- {
- int numOfTrials = 0;
- for (int broken=1; broken < 200; broken++)
- {
- Building building = new Building(200, broken);
- PathFinder finder = new PathFinder(building, 5);
- List path = finder.findPuzzlePath();
- if (TestUtil.getPathSize(path) > numOfTrials)
- numOfTrials = TestUtil.getPathSize(path);
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- System.out.println("numOfTrials=" + numOfTrials);
- }
- public void test6Ball1000Floors()
- {
- int numOfTrials = 0;
- for (int broken=1; broken < 200; broken++)
- {
- Building building = new Building(200, broken);
- PathFinder finder = new PathFinder(building, 6);
- List path = finder.findPuzzlePath();
- if (TestUtil.getPathSize(path) > numOfTrials)
- numOfTrials = TestUtil.getPathSize(path);
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- System.out.println("numOfTrials=" + numOfTrials);
- }
- public void test10Ball1000Floors()
- {
- int numOfTrials = 0;
- for (int broken=1; broken < 200; broken++)
- {
- Building building = new Building(200, broken);
- PathFinder finder = new PathFinder(building, 50);
- List path = finder.findPuzzlePath();
- if (TestUtil.getPathSize(path) > numOfTrials)
- numOfTrials = TestUtil.getPathSize(path);
- TestUtil.printPath(path);
- assertTrue(broken == TestUtil.getBrokenFloor(path));
- assertTrue(TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- }
- System.out.println("numOfTrials=" + numOfTrials);
- }
- }
The third one is a brutal force testing to test all cases in a certain range:
java 代码
- package glassball;
- import junit.framework.TestCase;
- import java.util.List;
- /**
- * The brutal force loops.
- */
- public class PathFinderFullTest extends TestCase
- {
- public void test1BallSingleCase()
- {
- for (int floors=3; floors<=300; floors++)
- {
- for (int broken=1; broken<floors; broken++)
- {
- for (int balls=1; balls<6; balls++)
- {
- Building building = new Building(floors, broken);
- PathFinder finder = new PathFinder(building, balls);
- List path = finder.findPuzzlePath();
- //TestUtil.printPath(path);
- String errorMsg = "floors=" + floors + " broken=" + broken + " balls=" + balls;
- errorMsg += " path size=" + TestUtil.getPathSize(path) + " minimal trials=" +
- finder.getPuzzle().getMinimalTrials();
- errorMsg += " result floor=" + TestUtil.getBrokenFloor(path);
- assertTrue(errorMsg, TestUtil.getPathSize(path) <= finder.getPuzzle().getMinimalTrials());
- assertTrue(errorMsg, broken == TestUtil.getBrokenFloor(path));
- }
- }
- }
- }
- }
Now we should have enough confidence.