diff --git a/src/com/lukzar/Chess.java b/src/com/lukzar/Chess.java index 725cf5c..ff4892b 100644 --- a/src/com/lukzar/Chess.java +++ b/src/com/lukzar/Chess.java @@ -87,7 +87,7 @@ public void testScale() throws IOException { double scale = 0.5; - Main.writeToFile(Arrays.asList(p, p.scale(scale)), "out/scale"); + Main.writeToFile(Arrays.asList(p, p.scale(scale, Point.of(0,0), Point.of(200,200))), "out/scale"); } diff --git a/src/com/lukzar/config/Configuration.java b/src/com/lukzar/config/Configuration.java index ea7d22c..57fb94c 100644 --- a/src/com/lukzar/config/Configuration.java +++ b/src/com/lukzar/config/Configuration.java @@ -115,9 +115,11 @@ public static List getDescription() { public static class Mutation { public static double STARTING_POINT_CHANCE = 0.1; - public static double CHANCE_TO_CHANGE_POINT = 0.6; + public static double CHANCE_TO_CHANGE_POINT = 0.5; public static double CHANCE_TO_CHANGE_PART = 0.38; - // CHANCE_TO_CONVERT_TO_ASYM = 1 - CHANCE_TO_CHANGE_POINT - CHANCE_TO_CHANGE_PART + public static double CHANCE_TO_CONVERT_TO_ASYNC = 0.02; + public static double CHANCE_TO_SCALE = 1.0 - CHANCE_TO_CHANGE_POINT - CHANCE_TO_CHANGE_PART - CHANCE_TO_CONVERT_TO_ASYNC; + public static double SCALE_OFFSET = 0.1; public static double CHANCE_TO_SPLIT_LINE = 0.8; // 20% to convert to Arc, 80% to split public static double OFFSET = 40; } diff --git a/src/com/lukzar/model/Piece.java b/src/com/lukzar/model/Piece.java index 9aaf77a..3e6c640 100644 --- a/src/com/lukzar/model/Piece.java +++ b/src/com/lukzar/model/Piece.java @@ -1,5 +1,6 @@ package com.lukzar.model; +import com.lukzar.config.Configuration; import com.lukzar.config.Templates; import com.lukzar.fitness.FitnessUtil; import com.lukzar.model.elements.Arc; @@ -7,6 +8,9 @@ import com.lukzar.model.elements.Line; import com.lukzar.model.elements.Part; import com.lukzar.utils.IntersectionUtil; +import com.lukzar.utils.RandomUtils; + +import sun.security.krb5.Config; import java.util.BitSet; import java.util.Collection; @@ -61,35 +65,37 @@ public String toSvg() { ); } - public Piece scale(double scale) { - Piece result = new Piece(scale(this.getStart(), scale)); + public Piece scale(double scale, Point minBound, Point maxBound) { + Point startPoint = scale(this.getStart(), scale, minBound, maxBound); + Piece result = new Piece(Point.of(startPoint.getX(), Configuration.Piece.HEIGHT)); if (this.isAsymmetric()) { result.convertToAsymmetric(); } for (Part part : this.getParts()) { if (part instanceof Line) { - result.add(new Line(scale(part.getEndPos(), scale))); + result.add(new Line(scale(part.getEndPos(), scale, minBound, maxBound))); } else if (part instanceof Arc) { result.add(new Arc( - scale(part.getEndPos(), scale), - scale(((Arc) part).getQ(), scale))); + scale(part.getEndPos(), scale, minBound, maxBound), + scale(((Arc) part).getQ(), scale, minBound, maxBound))); } else if (part instanceof DoubleArc) { result.add(new DoubleArc( - scale(part.getEndPos(), scale), - scale(((DoubleArc) part).getQ1(), scale), - scale(((DoubleArc) part).getQ2(), scale)) + scale(part.getEndPos(), scale, minBound, maxBound), + scale(((DoubleArc) part).getQ1(), scale, minBound, maxBound), + scale(((DoubleArc) part).getQ2(), scale, minBound, maxBound)) ); } } return result; } - private Point scale(Point p, double scale) { + private Point scale(Point p, double scale, Point min, Point max) { + double scaledX = p.getX() * scale + ((Configuration.Piece.WIDTH / 2) * (1.0 - scale)); + double scaledY = p.getY() * scale + (Configuration.Piece.HEIGHT * (1.0 - scale)); return Point.of( - - p.getX() * scale + (100 * (1.0 - scale)), - p.getY() * scale + (200 * (1.0 - scale)) + RandomUtils.ensureRange(scaledX, min.getX(), max.getX()), + RandomUtils.ensureRange(scaledY, min.getY(), max.getY()) ); } diff --git a/src/com/lukzar/services/evolution/Evolution.java b/src/com/lukzar/services/evolution/Evolution.java index 6d864c4..51fd2d6 100644 --- a/src/com/lukzar/services/evolution/Evolution.java +++ b/src/com/lukzar/services/evolution/Evolution.java @@ -55,7 +55,7 @@ public static Collection initialize(int size) { public static Collection evolvePopulation(Collection input) { final Set newPopulation = new HashSet<>(); - for (int i = 0; i < Math.min(Configuration.Evolution.CROSSOVER_SIZE, input.size() / 2); i++) { + for (int i = 0; i < Math.min(Configuration.Evolution.CROSSOVER_SIZE, input.size()); i++) { final List crossover = crossover(tournamentSelection(input), tournamentSelection(input)); crossover .stream() @@ -125,7 +125,7 @@ private static Piece mutate(Piece piece) { startPoint = piece.getStart(); } - final Piece result = new Piece(startPoint, piece); + Piece result = new Piece(startPoint, piece); final Point minBound = Point.of(result.isAsymmetric() ? 0 : Configuration.Piece.WIDTH / 2.0, 0); final Point maxBound = Point.of(Configuration.Piece.WIDTH, Configuration.Piece.HEIGHT); @@ -137,10 +137,9 @@ private static Piece mutate(Piece piece) { final Part newPart; + if (random <= Configuration.Evolution.Mutation.CHANCE_TO_CHANGE_POINT) { // change points - - newPart = PointMutation.mutate(part, minBound, maxBound); newPart.setStartPos(part.getStartPos()); result.getParts().set(partToChange, newPart); @@ -152,9 +151,16 @@ private static Piece mutate(Piece piece) { for (int i = 0; i < mutate.size(); i++) { result.getParts().add(partToChange + i, mutate.get(i)); } - } else { + } else if (random <= Configuration.Evolution.Mutation.CHANCE_TO_CHANGE_POINT + Configuration.Evolution.Mutation.CHANCE_TO_CHANGE_PART + + Configuration.Evolution.Mutation.CHANCE_TO_CONVERT_TO_ASYNC) { // convert to asymmetric result.convertToAsymmetric(); + } else { + double scaleMin = 1 - Configuration.Evolution.Mutation.SCALE_OFFSET; + double scaleMax = 1 + Configuration.Evolution.Mutation.SCALE_OFFSET; + result = result.scale( + RandomUtils.randomRange(scaleMin, scaleMax), + minBound, maxBound); } result.updateStartPoints(); @@ -200,8 +206,8 @@ private static List crossover(Piece piece1, Piece piece2) { right = piece2.getParts(); } - int l = new Random().nextInt(left.size() - 2) + 1; - int r = new Random().nextInt(right.size() - 2) + 1; + int l = new Random().nextInt(left.size()); + int r = new Random().nextInt(right.size()); final List l1 = left.subList(0, l); final List l2 = left.subList(l, left.size());