import java.util.*; /** * Tester for programs that find the code word door to pass through. * @author Kyle Burke */ public class CodeDoorTester { //Student's code that finds the hole in the wall CodeDoorFinder finder; //worst ratio that will earn points private static final int WORST_RATIO_FOR_POINTS = 10000; //worst ratio seen during a test private long maxRatio; //worst location seen during a test private long maxRatioLocation; //whether we should print out the results of every test. private boolean verbose; /** * Constructor. */ public CodeDoorTester(CodeDoorFinder finder, boolean isVerbose) { this.maxRatio = 1; this.maxRatioLocation=0; this.finder = finder; this.verbose = isVerbose; } /** * Tests the finder on a single CodeDoorWall */ private void runTest(long distance) { if (this.keepTesting()) { CodeDoorWall wall = new CodeDoorWall(distance); finder.findDoor(wall); long ratio = wall.getRatio(); if (this.verbose) { System.out.println("Ratio at distance " + distance + ": " + ratio); } if (ratio > this.maxRatio) { System.out.println("Got a new worst ratio at distance " + distance + ": " + ratio); this.maxRatio = ratio; this.maxRatioLocation = distance; } } else { if (this.verbose) { System.out.println("Skipping a test because we've gone past the worst ratio worth points."); } } } /** * Runs the tests. */ public void run() { // You may rename this method to better suit the purpose of your test case // Your test case logic here Random random = new Random(); CodeDoorWall wall; long distance; System.out.println("*~~~~~~~~ Time for public distances. ~~~~~~~~*"); //cover all cases in a short range. int coverAllMax = 100; for (int i = 1; i <= coverAllMax; i++) { //positive this.runTest(i); //negative this.runTest(-i); } //the easy and deterministic ones long[] distances = new long[]{1, 2, 5, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 2000000, 2500000, 3000000, 5000000, 6000000, 7000000, 8500000}; for (int i = 0; i < distances.length; i++) { distance = distances[i]; //positive this.runTest(distance); //negative this.runTest(-distance); } System.out.println("\n*~~~~~~~~ Time for random distances. ~~~~~~~~*"); //again, but with random offsets long[] distancesB = new long[2 * distances.length]; for (int i = 0; i < distances.length; i++) { long oldDistance = distances[i]; long offset = (random.nextInt() % oldDistance) - (oldDistance / 2); distance = oldDistance + offset; distancesB[2*i] = distance; //do it again for the negative offset = (random.nextInt() % oldDistance) - (oldDistance / 2); if (distance == 0) { //don't use zero! i --; } else { distance = -oldDistance + offset; distancesB[2*i+1] = distance; } } for (int i = 0; i < distancesB.length; i++) { distance = distancesB[i]; //positive this.runTest(distance); //negative this.runTest(-distance); } List<List<Integer>> pointLevels = new ArrayList<>(); pointLevels.add(Arrays.asList(7, 102)); pointLevels.add(Arrays.asList(9, 100)); pointLevels.add(Arrays.asList(11, 98)); pointLevels.add(Arrays.asList(15, 94)); pointLevels.add(Arrays.asList(20, 90)); pointLevels.add(Arrays.asList(30, 80)); pointLevels.add(Arrays.asList(50, 70)); pointLevels.add(Arrays.asList(100, 60)); pointLevels.add(Arrays.asList(250, 50)); pointLevels.add(Arrays.asList(500, 40)); pointLevels.add(Arrays.asList(1000, 30)); pointLevels.add(Arrays.asList(3000, 20)); pointLevels.add(Arrays.asList(WORST_RATIO_FOR_POINTS, 10)); int pointsEarned = 0; for (List<Integer> level : pointLevels) { int targetRatio = level.get(0); if (this.maxRatio <= targetRatio) { pointsEarned = level.get(1); break; } } String teamMembers = this.finder.getAuthors(); System.out.println(); System.out.println("*~~~~~~~ Summary for " + teamMembers + " ~~~~~~~~~~~*"); System.out.println("Max ratio from distance " + this.maxRatioLocation + ": " + this.maxRatio); System.out.println("Earned " + pointsEarned + " points!"); System.out.println(); System.out.println("Score: " + pointsEarned + "/100"); } //determines whether we should keep testing private boolean keepTesting() { return this.maxRatio <= WORST_RATIO_FOR_POINTS; } public static void main(String[] args) { //default is false; boolean verbose = false; if (args.length > 0) { verbose = args[0].toLowerCase().startsWith("t"); } else { System.out.println("Running in non-verbose mode. If you want to specify the verbosity, add a t (for true) or f (for false) to the end of the command line."); } CodeDoorTester tester = new CodeDoorTester(new CodeDoorFinder(), verbose); tester.run(); } }