diff --git a/src/main/java/analyzer/AnalyzerRoot.java b/src/main/java/analyzer/AnalyzerRoot.java index 2dfa39f3..42937686 100644 --- a/src/main/java/analyzer/AnalyzerRoot.java +++ b/src/main/java/analyzer/AnalyzerRoot.java @@ -6,6 +6,7 @@ import analyzer.exercises.hamming.HammingAnalyzer; import analyzer.exercises.lasagna.LasagnaAnalyzer; import analyzer.exercises.leap.LeapAnalyzer; +import analyzer.exercises.needforspeed.NeedForSpeedAnalyzer; import analyzer.exercises.twofer.TwoferAnalyzer; import java.util.ArrayList; @@ -50,6 +51,7 @@ private static List createAnalyzers(String slug) { case "hamming" -> analyzers.add(new HammingAnalyzer()); case "lasagna" -> analyzers.add(new LasagnaAnalyzer()); case "leap" -> analyzers.add(new LeapAnalyzer()); + case "need-for-speed" -> analyzers.add(new NeedForSpeedAnalyzer()); case "two-fer" -> analyzers.add(new TwoferAnalyzer()); } diff --git a/src/main/java/analyzer/exercises/needforspeed/AvoidConditionalLogic.java b/src/main/java/analyzer/exercises/needforspeed/AvoidConditionalLogic.java new file mode 100644 index 00000000..5455680a --- /dev/null +++ b/src/main/java/analyzer/exercises/needforspeed/AvoidConditionalLogic.java @@ -0,0 +1,19 @@ +package analyzer.exercises.needforspeed; + +import analyzer.Comment; + +/** + * @see Markdown Template + */ +class AvoidConditionalLogic extends Comment { + + @Override + public String getKey() { + return "java.need-for-speed.avoid_conditional_logic"; + } + + @Override + public Type getType() { + return Type.ACTIONABLE; + } +} diff --git a/src/main/java/analyzer/exercises/needforspeed/AvoidLoops.java b/src/main/java/analyzer/exercises/needforspeed/AvoidLoops.java new file mode 100644 index 00000000..8e010d62 --- /dev/null +++ b/src/main/java/analyzer/exercises/needforspeed/AvoidLoops.java @@ -0,0 +1,19 @@ +package analyzer.exercises.needforspeed; + +import analyzer.Comment; + +/** + * @see Markdown Template + */ +class AvoidLoops extends Comment{ + + @Override + public String getKey() { + return "java.need-for-speed.avoid_loops"; + } + + @Override + public Type getType() { + return Type.ACTIONABLE; + } +} diff --git a/src/main/java/analyzer/exercises/needforspeed/NeedForSpeedAnalyzer.java b/src/main/java/analyzer/exercises/needforspeed/NeedForSpeedAnalyzer.java new file mode 100644 index 00000000..32f6a0d8 --- /dev/null +++ b/src/main/java/analyzer/exercises/needforspeed/NeedForSpeedAnalyzer.java @@ -0,0 +1,82 @@ +package analyzer.exercises.needforspeed; + +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.ConditionalExpr; +import com.github.javaparser.ast.visitor.VoidVisitorAdapter; +import com.github.javaparser.ast.stmt.IfStmt; +import com.github.javaparser.ast.stmt.Statement; + +import analyzer.Analyzer; +import analyzer.OutputCollector; +import analyzer.Solution; +import analyzer.comments.ExemplarSolution; + +/** + * The {@link NeedForSpeedAnalyzer} is the analyzer implementation for the {@code need-for-speed} practice exercise. + * It has two subclasses NeedForSpeedClassAnalyzer and RaceTrackClassAnalyzer that extend the {@link VoidVisitorAdapter} and use the visitor pattern to traverse each compilation unit. + * + * @see The need-for-speed exercise on the Java track + */ +public class NeedForSpeedAnalyzer implements Analyzer { + private static final String EXERCISE_NAME = "Need for Speed"; + + @Override + public void analyze(Solution solution, OutputCollector output) { + var needForSpeedClassAnalyzer = new NeedForSpeedClassAnalyzer(); + var raceTrackClassAnalyzer = new RaceTrackClassAnalyzer(); + + for (var compilationUnit : solution.getCompilationUnits()) { + compilationUnit.getClassByName("NeedForSpeed").ifPresent(c -> c.accept(needForSpeedClassAnalyzer, output)); + compilationUnit.getClassByName("RaceTrack").ifPresent(c -> c.accept(raceTrackClassAnalyzer, output)); + } + + if (output.getComments().isEmpty()) { + output.addComment(new ExemplarSolution(EXERCISE_NAME)); + } + } + + class NeedForSpeedClassAnalyzer extends VoidVisitorAdapter { + + @Override + public void visit(MethodDeclaration node, OutputCollector output) { + if (node.getNameAsString().equals("batteryDrained") && hasConditional(node)) { + output.addComment(new AvoidConditionalLogic()); + } + + super.visit(node, output); + } + + private static boolean hasConditional(MethodDeclaration node) { + return node.getBody() + .map(body -> body.getStatements().stream() + .anyMatch(NeedForSpeedClassAnalyzer::isConditionalExpresion)) + .orElse(false); + } + + private static boolean isConditionalExpresion(Statement statement) { + return !statement.findAll(IfStmt.class).isEmpty() || !statement.findAll(ConditionalExpr.class).isEmpty(); + } + } + + class RaceTrackClassAnalyzer extends VoidVisitorAdapter { + + @Override + public void visit(MethodDeclaration node, OutputCollector output) { + if (node.getNameAsString().equals("tryFinishTrack") && hasLoop(node)) { + output.addComment(new AvoidLoops()); + } + + super.visit(node, output); + } + + private static boolean hasLoop(MethodDeclaration node) { + return node.getBody() + .map(body -> body.getStatements().stream().anyMatch(RaceTrackClassAnalyzer::isLoopStatement)) + .orElse(false); + } + + private static boolean isLoopStatement(Statement statement) { + return statement.isForStmt() || statement.isForEachStmt() || statement.isWhileStmt() || statement.isDoStmt(); + } + } +} diff --git a/src/test/java/analyzer/AnalyzerIntegrationTest.java b/src/test/java/analyzer/AnalyzerIntegrationTest.java index b040708d..17af176d 100644 --- a/src/test/java/analyzer/AnalyzerIntegrationTest.java +++ b/src/test/java/analyzer/AnalyzerIntegrationTest.java @@ -113,4 +113,20 @@ public void annalynsinfiltration(String scenario) throws IOException { Approvals.verify(serialize(output.analysis()), Approvals.NAMES.withParameters(scenario)); } + + @ParameterizedTest + @ValueSource(strings = { + "ExemplarSolution", + "UsingForLoop", + "UsingIfStatement", + "UsingTernary", + "UsingWhileLoop", + }) + void needforspeed(String scenario) throws IOException { + var path = Path.of("need-for-speed", scenario + ".java"); + var solution = new SolutionFromFiles("need-for-speed", SCENARIOS.resolve(path)); + var output = AnalyzerRoot.analyze(solution); + + Approvals.verify(serialize(output.analysis()), Approvals.NAMES.withParameters(scenario)); + } } diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.ExemplarSolution.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.ExemplarSolution.approved.txt new file mode 100644 index 00000000..1ab9139f --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.ExemplarSolution.approved.txt @@ -0,0 +1,11 @@ +{ + "comments": [ + { + "comment": "java.general.exemplar", + "params": { + "exerciseName": "Need for Speed" + }, + "type": "celebratory" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingForLoop.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingForLoop.approved.txt new file mode 100644 index 00000000..905f1de0 --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingForLoop.approved.txt @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.need-for-speed.avoid_loops", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingIfStatement.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingIfStatement.approved.txt new file mode 100644 index 00000000..529d4671 --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingIfStatement.approved.txt @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.need-for-speed.avoid_conditional_logic", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingTernary.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingTernary.approved.txt new file mode 100644 index 00000000..529d4671 --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingTernary.approved.txt @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.need-for-speed.avoid_conditional_logic", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingWhileLoop.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingWhileLoop.approved.txt new file mode 100644 index 00000000..905f1de0 --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.needforspeed.UsingWhileLoop.approved.txt @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.need-for-speed.avoid_loops", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/scenarios/need-for-speed/ExemplarSolution.java b/src/test/resources/scenarios/need-for-speed/ExemplarSolution.java new file mode 100644 index 00000000..418db97e --- /dev/null +++ b/src/test/resources/scenarios/need-for-speed/ExemplarSolution.java @@ -0,0 +1,56 @@ +package scenarios.neeedforspeed; + +public class NeedForSpeed { + private int speed; + private int batteryDrain; + private int distance = 0; + private int battery = 100; + + public NeedForSpeed(int speed, int batteryDrain) { + this.speed = speed; + this.batteryDrain = batteryDrain; + } + + public static NeedForSpeed nitro() { + return new NeedForSpeed(50, 4); + } + + public boolean batteryDrained() { + return battery < batteryDrain; + } + + public int distanceDriven() { + return distance; + } + + public int getSpeed() { + return speed; + } + + public int getBatteryDrain() { + return batteryDrain; + } + + public int getCurrentBattery() { + return battery; + } + + public void drive() { + if (!batteryDrained()) { + battery -= batteryDrain; + distance += speed; + } + } +} + +class RaceTrack { + private int distance; + + RaceTrack(int distance) { + this.distance = distance; + } + + public boolean tryFinishTrack(NeedForSpeed car) { + return ((double) distance / car.getSpeed()) <= (car.getCurrentBattery() / car.getBatteryDrain()); + } +} diff --git a/src/test/resources/scenarios/need-for-speed/UsingForLoop.java b/src/test/resources/scenarios/need-for-speed/UsingForLoop.java new file mode 100644 index 00000000..5a91ea7f --- /dev/null +++ b/src/test/resources/scenarios/need-for-speed/UsingForLoop.java @@ -0,0 +1,55 @@ +package scenarios.neeedforspeed; + +public class NeedForSpeed { + private int speed; + private int batteryDrain; + private int distance = 0; + private int battery = 100; + + public NeedForSpeed(int speed, int batteryDrain) { + this.speed = speed; + this.batteryDrain = batteryDrain; + } + + public static NeedForSpeed nitro() { + return new NeedForSpeed(50, 4); + } + + public boolean batteryDrained() { + return battery < batteryDrain; + } + + public int distanceDriven() { + return distance; + } + + public int getSpeed() { + return speed; + } + + public void drive() { + if (!batteryDrained()) { + battery -= batteryDrain; + distance += speed; + } + } +} + +class RaceTrack { + private int distance; + + RaceTrack(int distance) { + this.distance = distance; + } + + public boolean tryFinishTrack(NeedForSpeed car) { + for (int i = 0; i < this.distance / car.getSpeed(); i++) { + car.drive(); + } + + if (car.distanceDriven() >= distance) { + return true; + } else + return false; + } +} diff --git a/src/test/resources/scenarios/need-for-speed/UsingIfStatement.java b/src/test/resources/scenarios/need-for-speed/UsingIfStatement.java new file mode 100644 index 00000000..84f0f9d5 --- /dev/null +++ b/src/test/resources/scenarios/need-for-speed/UsingIfStatement.java @@ -0,0 +1,59 @@ +package scenarios.neeedforspeed; + +public class NeedForSpeed { + private int speed; + private int batteryDrain; + private int distance = 0; + private int battery = 100; + + public NeedForSpeed(int speed, int batteryDrain) { + this.speed = speed; + this.batteryDrain = batteryDrain; + } + + public static NeedForSpeed nitro() { + return new NeedForSpeed(50, 4); + } + + public boolean batteryDrained() { + if (battery <= 0) { + return true; + } + return false; + } + + public int distanceDriven() { + return distance; + } + + public int getSpeed() { + return speed; + } + + public int getBatteryDrain() { + return batteryDrain; + } + + public int getCurrentBattery() { + return battery; + } + + public void drive() { + if (!batteryDrained()) { + battery -= batteryDrain; + distance += speed; + } + } +} + +class RaceTrack { + private int distance; + + RaceTrack(int distance) { + this.distance = distance; + } + + public boolean tryFinishTrack(NeedForSpeed car) { + return ((double) distance / car.getSpeed()) <= (car.getCurrentBattery() / car.getBatteryDrain()); + } +} diff --git a/src/test/resources/scenarios/need-for-speed/UsingTernary.java b/src/test/resources/scenarios/need-for-speed/UsingTernary.java new file mode 100644 index 00000000..441803df --- /dev/null +++ b/src/test/resources/scenarios/need-for-speed/UsingTernary.java @@ -0,0 +1,56 @@ +package scenarios.neeedforspeed; + +public class NeedForSpeed { + private int speed; + private int batteryDrain; + private int distance = 0; + private int battery = 100; + + public NeedForSpeed(int speed, int batteryDrain) { + this.speed = speed; + this.batteryDrain = batteryDrain; + } + + public static NeedForSpeed nitro() { + return new NeedForSpeed(50, 4); + } + + public boolean batteryDrained() { + return battery <= 0 ? true : false; + } + + public int distanceDriven() { + return distance; + } + + public int getSpeed() { + return speed; + } + + public int getBatteryDrain() { + return batteryDrain; + } + + public int getCurrentBattery() { + return battery; + } + + public void drive() { + if (!batteryDrained()) { + battery -= batteryDrain; + distance += speed; + } + } +} + +class RaceTrack { + private int distance; + + RaceTrack(int distance) { + this.distance = distance; + } + + public boolean tryFinishTrack(NeedForSpeed car) { + return ((double) distance / car.getSpeed()) <= (car.getCurrentBattery() / car.getBatteryDrain()); + } +} diff --git a/src/test/resources/scenarios/need-for-speed/UsingWhileLoop.java b/src/test/resources/scenarios/need-for-speed/UsingWhileLoop.java new file mode 100644 index 00000000..32c075bb --- /dev/null +++ b/src/test/resources/scenarios/need-for-speed/UsingWhileLoop.java @@ -0,0 +1,52 @@ +package scenarios.neeedforspeed; + +public class NeedForSpeed { + private int speed; + private int batteryDrain; + private int distance = 0; + private int battery = 100; + + public NeedForSpeed(int speed, int batteryDrain) { + this.speed = speed; + this.batteryDrain = batteryDrain; + } + + public static NeedForSpeed nitro() { + return new NeedForSpeed(50, 4); + } + + public boolean batteryDrained() { + return battery < batteryDrain; + } + + public int distanceDriven() { + return distance; + } + + public void drive() { + if (!batteryDrained()) { + battery -= batteryDrain; + distance += speed; + } + } +} + +class RaceTrack { + private int distance; + + RaceTrack(int distance) { + this.distance = distance; + } + + public boolean tryFinishTrack(NeedForSpeed car) { + + while (!car.batteryDrained()) { + car.drive(); + } + + if (car.distanceDriven() >= distance) { + return true; + } else + return false; + } +} diff --git a/tests/need-for-speed/exemplar-solution/.meta/config.json b/tests/need-for-speed/exemplar-solution/.meta/config.json new file mode 100644 index 00000000..44ceb72d --- /dev/null +++ b/tests/need-for-speed/exemplar-solution/.meta/config.json @@ -0,0 +1,23 @@ +{ + "authors": [ + "ystromm" + ], + "contributors": [ + "mirkoperillo" + ], + "files": { + "solution": [ + "src/main/java/NeedForSpeed.java" + ], + "test": [ + "src/test/java/NeedForSpeedTest.java" + ], + "exemplar": [ + ".meta/src/reference/java/NeedForSpeed.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Learn about classes by creating cars." +} \ No newline at end of file diff --git a/tests/need-for-speed/exemplar-solution/expected_analysis.json b/tests/need-for-speed/exemplar-solution/expected_analysis.json new file mode 100644 index 00000000..934e6969 --- /dev/null +++ b/tests/need-for-speed/exemplar-solution/expected_analysis.json @@ -0,0 +1,11 @@ +{ + "comments": [ + { + "comment": "java.general.exemplar", + "params": { + "exerciseName": "Need for Speed" + }, + "type": "celebratory" + } + ] +} \ No newline at end of file diff --git a/tests/need-for-speed/exemplar-solution/expected_tags.json b/tests/need-for-speed/exemplar-solution/expected_tags.json new file mode 100644 index 00000000..eb25b190 --- /dev/null +++ b/tests/need-for-speed/exemplar-solution/expected_tags.json @@ -0,0 +1,3 @@ +{ + "tags": [] +} \ No newline at end of file diff --git a/tests/need-for-speed/exemplar-solution/src/main/java/NeedForSpeed.java b/tests/need-for-speed/exemplar-solution/src/main/java/NeedForSpeed.java new file mode 100644 index 00000000..481e932a --- /dev/null +++ b/tests/need-for-speed/exemplar-solution/src/main/java/NeedForSpeed.java @@ -0,0 +1,54 @@ +class NeedForSpeed { + private int speed; + private int batteryDrain; + private int distance = 0; + private int battery = 100; + + public NeedForSpeed(int speed, int batteryDrain) { + this.speed = speed; + this.batteryDrain = batteryDrain; + } + + public static NeedForSpeed nitro() { + return new NeedForSpeed(50, 4); + } + + public boolean batteryDrained() { + return battery < batteryDrain; + } + + public int distanceDriven() { + return distance; + } + + public int getSpeed() { + return speed; + } + + public int getBatteryDrain() { + return batteryDrain; + } + + public int getCurrentBattery() { + return battery; + } + + public void drive() { + if (!batteryDrained()) { + battery -= batteryDrain; + distance += speed; + } + } +} + +class RaceTrack { + private int distance; + + RaceTrack(int distance) { + this.distance = distance; + } + + public boolean tryFinishTrack(NeedForSpeed car) { + return ((double) distance / car.getSpeed()) <= (car.getCurrentBattery() / car.getBatteryDrain()); + } +} diff --git a/tests/need-for-speed/using-if-statement/.meta/config.json b/tests/need-for-speed/using-if-statement/.meta/config.json new file mode 100644 index 00000000..44ceb72d --- /dev/null +++ b/tests/need-for-speed/using-if-statement/.meta/config.json @@ -0,0 +1,23 @@ +{ + "authors": [ + "ystromm" + ], + "contributors": [ + "mirkoperillo" + ], + "files": { + "solution": [ + "src/main/java/NeedForSpeed.java" + ], + "test": [ + "src/test/java/NeedForSpeedTest.java" + ], + "exemplar": [ + ".meta/src/reference/java/NeedForSpeed.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Learn about classes by creating cars." +} \ No newline at end of file diff --git a/tests/need-for-speed/using-if-statement/expected_analysis.json b/tests/need-for-speed/using-if-statement/expected_analysis.json new file mode 100644 index 00000000..d4b880b4 --- /dev/null +++ b/tests/need-for-speed/using-if-statement/expected_analysis.json @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.need-for-speed.avoid_conditional_logic", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/tests/need-for-speed/using-if-statement/expected_tags.json b/tests/need-for-speed/using-if-statement/expected_tags.json new file mode 100644 index 00000000..eb25b190 --- /dev/null +++ b/tests/need-for-speed/using-if-statement/expected_tags.json @@ -0,0 +1,3 @@ +{ + "tags": [] +} \ No newline at end of file diff --git a/tests/need-for-speed/using-if-statement/src/main/java/NeedForSpeed.java b/tests/need-for-speed/using-if-statement/src/main/java/NeedForSpeed.java new file mode 100644 index 00000000..772050df --- /dev/null +++ b/tests/need-for-speed/using-if-statement/src/main/java/NeedForSpeed.java @@ -0,0 +1,57 @@ +class NeedForSpeed { + private int speed; + private int batteryDrain; + private int distance = 0; + private int battery = 100; + + public NeedForSpeed(int speed, int batteryDrain) { + this.speed = speed; + this.batteryDrain = batteryDrain; + } + + public static NeedForSpeed nitro() { + return new NeedForSpeed(50, 4); + } + + public boolean batteryDrained() { + if (battery <= 0) { + return true; + } + return false; + } + + public int distanceDriven() { + return distance; + } + + public int getSpeed() { + return speed; + } + + public int getBatteryDrain() { + return batteryDrain; + } + + public int getCurrentBattery() { + return battery; + } + + public void drive() { + if (!batteryDrained()) { + battery -= batteryDrain; + distance += speed; + } + } +} + +class RaceTrack { + private int distance; + + RaceTrack(int distance) { + this.distance = distance; + } + + public boolean tryFinishTrack(NeedForSpeed car) { + return ((double) distance / car.getSpeed()) <= (car.getCurrentBattery() / car.getBatteryDrain()); + } +} diff --git a/tests/need-for-speed/using-while-loop/.meta/config.json b/tests/need-for-speed/using-while-loop/.meta/config.json new file mode 100644 index 00000000..44ceb72d --- /dev/null +++ b/tests/need-for-speed/using-while-loop/.meta/config.json @@ -0,0 +1,23 @@ +{ + "authors": [ + "ystromm" + ], + "contributors": [ + "mirkoperillo" + ], + "files": { + "solution": [ + "src/main/java/NeedForSpeed.java" + ], + "test": [ + "src/test/java/NeedForSpeedTest.java" + ], + "exemplar": [ + ".meta/src/reference/java/NeedForSpeed.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Learn about classes by creating cars." +} \ No newline at end of file diff --git a/tests/need-for-speed/using-while-loop/expected_analysis.json b/tests/need-for-speed/using-while-loop/expected_analysis.json new file mode 100644 index 00000000..02b94ded --- /dev/null +++ b/tests/need-for-speed/using-while-loop/expected_analysis.json @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.need-for-speed.avoid_loops", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/tests/need-for-speed/using-while-loop/expected_tags.json b/tests/need-for-speed/using-while-loop/expected_tags.json new file mode 100644 index 00000000..eb25b190 --- /dev/null +++ b/tests/need-for-speed/using-while-loop/expected_tags.json @@ -0,0 +1,3 @@ +{ + "tags": [] +} \ No newline at end of file diff --git a/tests/need-for-speed/using-while-loop/src/main/java/NeedForSpeed.java b/tests/need-for-speed/using-while-loop/src/main/java/NeedForSpeed.java new file mode 100644 index 00000000..226ee3f1 --- /dev/null +++ b/tests/need-for-speed/using-while-loop/src/main/java/NeedForSpeed.java @@ -0,0 +1,50 @@ +class NeedForSpeed { + private int speed; + private int batteryDrain; + private int distance = 0; + private int battery = 100; + + public NeedForSpeed(int speed, int batteryDrain) { + this.speed = speed; + this.batteryDrain = batteryDrain; + } + + public static NeedForSpeed nitro() { + return new NeedForSpeed(50, 4); + } + + public boolean batteryDrained() { + return battery < batteryDrain; + } + + public int distanceDriven() { + return distance; + } + + public void drive() { + if (!batteryDrained()) { + battery -= batteryDrain; + distance += speed; + } + } +} + +class RaceTrack { + private int distance; + + RaceTrack(int distance) { + this.distance = distance; + } + + public boolean tryFinishTrack(NeedForSpeed car) { + + while (!car.batteryDrained()) { + car.drive(); + } + + if (car.distanceDriven() >= distance) { + return true; + } else + return false; + } +}