diff --git a/src/main/java/org/example/chaosgame/controller/ChaosGameController.java b/src/main/java/org/example/chaosgame/controller/ChaosGameController.java index 61f99576c2abee01c9c0b0c68c428a6e9c6ecc8b..065e5bd776f5720c1a2184a960e5cdaa690a710a 100644 --- a/src/main/java/org/example/chaosgame/controller/ChaosGameController.java +++ b/src/main/java/org/example/chaosgame/controller/ChaosGameController.java @@ -144,46 +144,22 @@ public class ChaosGameController implements Observer, Subject, GameController { Vector2D max = new Vector2D(Double.parseDouble(coords.get(2)), Double.parseDouble(coords.get(3))); - if (validateCoordinates(min) && validateCoordinates(max)) { - updateChaosGame(new ChaosGameDescription( - min, max, - chaosGame.getDescription().getTransforms())); - } else { - AlertUtility.showErrorDialog("Invalid input", - "Please enter a double between -50 and 50."); - } + updateChaosGame(new ChaosGameDescription(min, max, + chaosGame.getDescription().getTransforms())); } catch (NumberFormatException e) { - AlertUtility.showErrorDialog("Invalid input", "Please enter a valid number."); } catch (IndexOutOfBoundsException e) { AlertUtility.showErrorDialog("Invalid input", "Please enter all coordinates."); + } catch (IllegalArgumentException e) { + AlertUtility.showErrorDialog("Invalid input", + e.getMessage()); } } } - /** - * Method for validating the coordinates. - * - * @param vector Vector2D with the coordinates - * @return boolean True if the coordinates are valid, false otherwise - */ - private boolean validateCoordinates(Vector2D vector) { - try { - System.out.println("parsing" + vector.getX() + " " + vector.getY()); - double x = vector.getX(); - double y = vector.getY(); - if (x < -50 || x > 50 || y < -50 || y > 50) { - return false; - } - } catch (NumberFormatException e) { - return false; - } - return true; - } - /** * Method for opening a file with a chaos game description. * diff --git a/src/main/java/org/example/chaosgame/model/chaos/ChaosGame.java b/src/main/java/org/example/chaosgame/model/chaos/ChaosGame.java index 2b461a65f30263788a3ac0722029a25e753d4309..6ee43e34f845e10696777fb0da4fe27442048edc 100644 --- a/src/main/java/org/example/chaosgame/model/chaos/ChaosGame.java +++ b/src/main/java/org/example/chaosgame/model/chaos/ChaosGame.java @@ -103,8 +103,13 @@ public class ChaosGame implements Subject { * Method for setting the chaos game description. * * @param newDescription New description of the chaos game + * @throws IllegalArgumentException If newDescription is null */ - public void setChaosGameDescription(ChaosGameDescription newDescription) { + public void setChaosGameDescription(ChaosGameDescription newDescription) + throws IllegalArgumentException { + if (newDescription == null) { + throw new IllegalArgumentException("Description cannot be null"); + } this.description = newDescription; resetTotalSteps(); setChaosCanvas(description.getMinCoords(), description.getMaxCoords()); diff --git a/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescription.java b/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescription.java index 3e9af32d5eac7627b740fd5db56a0292389c328d..587c0df52d262416405b1399bef22f77e6b16b51 100644 --- a/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescription.java +++ b/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescription.java @@ -30,6 +30,8 @@ public class ChaosGameDescription { */ public ChaosGameDescription(Vector2D minCoords, Vector2D maxCoords, List<Transform2D> transforms) { + validateCoordinates(minCoords, maxCoords); + validateTransforms(transforms); this.minCoords = minCoords; this.maxCoords = maxCoords; this.transforms = transforms; @@ -48,13 +50,51 @@ public class ChaosGameDescription { * @param probabilities List of probabilities for the transformations */ public ChaosGameDescription(Vector2D minCoords, Vector2D maxCoords, - List<Transform2D> transforms, List<Integer> probabilities) { + List<Transform2D> transforms, List<Integer> probabilities) + throws IllegalArgumentException { + validateCoordinates(minCoords, maxCoords); + validateTransforms(transforms); + if (probabilities.size() != transforms.size()) { + throw new IllegalArgumentException("Probabilities must match the number of transformations"); + } this.minCoords = minCoords; this.maxCoords = maxCoords; this.transforms = transforms; this.probabilities = probabilities; } + /** + * Method for validating the coordinates. + * + * @param minCoords Minimum coordinates of the game area + * + * @param maxCoords Maximum coordinates of the game area + */ + private void validateCoordinates(Vector2D minCoords, Vector2D maxCoords) { + if (minCoords.getX() < -50 || minCoords.getY() < -50 + || minCoords.getX() > 50 || minCoords.getY() > 50 + || maxCoords.getX() > 50 || maxCoords.getY() > 50 + || maxCoords.getX() < -50 || maxCoords.getY() < -50) { + throw new IllegalArgumentException("Coordinates must be between -50 and 50"); + } else if (minCoords.getX() > maxCoords.getX() || minCoords.getY() > maxCoords.getY()) { + throw new IllegalArgumentException("Minimum coordinates must be less than maximum coordinates"); + } + if (minCoords.equals(maxCoords)) { + throw new IllegalArgumentException("Minimum and maximum coordinates cannot be the same"); + } + } + + /** + * Method for validating the transformations. + * + * @param transforms List of transformations to apply to the points + */ + private void validateTransforms(List<Transform2D> transforms) { + if (transforms.size() > 4 || transforms.isEmpty()) { + throw new IllegalArgumentException("Number of transformations must be between 1 and 4"); + } + } + public Vector2D getMinCoords() { return minCoords; } diff --git a/src/test/java/org/example/chaosgame/model/chaos/ChaosGameTest.java b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameTest.java index c6ec2d42aa21ab4c15519176e77f097c96097fef..b1d2d65898d91a19974c4398ad74adf5d707acf9 100644 --- a/src/test/java/org/example/chaosgame/model/chaos/ChaosGameTest.java +++ b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameTest.java @@ -14,7 +14,7 @@ import static org.junit.jupiter.api.Assertions.*; class ChaosGameTest { private static ChaosGameDescription juliaDescription; - private static ChaosGameDescription affineDescription; + private static ChaosGameDescription affineDescriptionWithProb; private static ChaosGame instance; @BeforeAll @@ -26,17 +26,19 @@ class ChaosGameTest { new JuliaTransform(new Complex(-0.70176, -0.3842), 1) )); - affineDescription = new ChaosGameDescription( - new Vector2D(0.0, 0.0), - new Vector2D(1.0, 1.0), + affineDescriptionWithProb = new ChaosGameDescription( + new Vector2D(-2.65, 0.0), + new Vector2D(2.65, 10.0), List.of( - new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), + new AffineTransform2D(new Matrix2x2(0.0, 0.0, 0.0, 0.16), new Vector2D(0.0, 0.0)), - new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), - new Vector2D(0.25, 0.50)), - new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), - new Vector2D(0.5, 0.0)) - )); + new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85), + new Vector2D(0.0, 1.60)), + new AffineTransform2D(new Matrix2x2(0.20, -0.26, 0.23, 0.22), + new Vector2D(0.0, 1.60)), + new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24), + new Vector2D(0.0, 0.44)) + ), List.of(2, 84, 7, 7)); } @BeforeEach @@ -138,14 +140,45 @@ class ChaosGameTest { instance.runSteps(); assertEquals(10, instance.getSteps(), "The total steps should be 10"); } + + @Test + void runStepsUniform() { + instance = ChaosGame.getInstance(juliaDescription, 500, 500); + instance.setSteps(10); + assertEquals(10, instance.getSteps()); + } + + @Test + void runStepsWithProbabilities() { + instance.setChaosGameDescription(affineDescriptionWithProb); + instance.setSteps(10); + assertEquals(10, instance.getSteps()); + } } - @Test - void setChaosGameDescription() { + @Nested + class setDescription { + @Test + void setChaosGameDescription() { + instance.setChaosGameDescription(affineDescriptionWithProb); + assertEquals(affineDescriptionWithProb, instance.getDescription(), "The description should be the same"); + assertEquals(0, instance.getTotalSteps(), "The total steps should be 0"); + assertEquals(500, instance.getCanvas().getWidth(), "The width should be 500"); + assertEquals(500, instance.getCanvas().getHeight(), "The height should be 500"); + } + + @Test + void setChaosGameDescriptionNull() { + assertThrows(IllegalArgumentException.class, () -> instance.setChaosGameDescription(null), + "The description should not be null"); + } } @Test void setChaosCanvas() { + instance.setChaosCanvas(new Vector2D(-1.6, -1), new Vector2D(1.6, 1)); + assertEquals(new Vector2D(-1.6, -1), instance.getDescription().getMinCoords(), "The min coords should be the same"); + assertEquals(new Vector2D(1.6, 1), instance.getDescription().getMaxCoords(), "The max coords should be the same"); } } \ No newline at end of file