From c6df65638195e1702b6045339336a2e44503a0bf Mon Sep 17 00:00:00 2001 From: Debucquoy Anthony Date: Mon, 1 May 2023 18:38:52 +0200 Subject: [PATCH] MapGenerator (#34) This generate maps following a simple structure First we choose map size depending on the difficulty we grind the edge with a random pattern so the map is not just a square we pick a random open piece and try to make a piece out of it between a size of 1 to 3 and we do this in a loop until all open spaces are filled this is not the best but it's efficient known problem: - We can have sometime a lot of small pieces - We can have weird shape, for instance pieces that are only connected by corner I think this is technically not a problem in the end. but this could be changed Co-authored-by: Debucquoy Reviewed-on: https://git.herisson.ovh/undefined_name/School_Project/pulls/34 Reviewed-by: Mat_02 --- .../java/school_project/MapGenerator.java | 78 +++++++++++++++++++ .../java/school_project/MapGeneratorTest.java | 26 +++++++ 2 files changed, 104 insertions(+) create mode 100644 app/src/main/java/school_project/MapGenerator.java create mode 100644 app/src/test/java/school_project/MapGeneratorTest.java diff --git a/app/src/main/java/school_project/MapGenerator.java b/app/src/main/java/school_project/MapGenerator.java new file mode 100644 index 0000000..f6a44b8 --- /dev/null +++ b/app/src/main/java/school_project/MapGenerator.java @@ -0,0 +1,78 @@ +package school_project; + +import school_project.Utils.Array; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Random; + +public class MapGenerator { + private static final Random rand = new Random(); + public enum Difficulty { + Easy, + Medium, + Difficult, + } + public static Map generate(Difficulty difficulty){ + Vec2 map_size; + int depth = 1; // how much the map shape generator could grind + + // define map size depending on the difficulty + switch (difficulty){ + case Easy -> map_size = new Vec2(rand.nextInt(3, 5), rand.nextInt(3, 5)); + case Medium -> map_size = new Vec2(rand.nextInt(5, 8), rand.nextInt(5, 8)); + case Difficult -> { + map_size = new Vec2(rand.nextInt(8, 10), rand.nextInt(8, 10)); + depth = 2; + } + default -> map_size = new Vec2(); + } + + // Cut edges + boolean[][] map_shape = new boolean[map_size.x][map_size.y]; + for (boolean[] b : map_shape) { + Arrays.fill(b, true); + } + for (int i = 0; i < map_shape.length; i++) { + for (int j = 0; j < map_shape[0].length; j++) { + if(i > depth - 1 && i < map_shape.length - depth && j > depth - 1 && j < map_shape[0].length - depth){ + j = map_shape[0].length - depth; + } + map_shape[i][j] = rand.nextBoolean(); + } + } + Map ret = new Map(map_shape); + boolean[][] piece_layout = Array.MatrixCopyOf(map_shape); + ArrayList EmptySlots = new ArrayList<>(); + + for (int i = 0; i < piece_layout.length; i++) { + for (int j = 0; j < piece_layout[i].length; j++) { + if(piece_layout[i][j]){ + EmptySlots.add(new Vec2(i, j)); + } + } + } + + while (EmptySlots.size() > 0){ + Collections.shuffle(EmptySlots); + Vec2 selected = EmptySlots.get(0); + int size = rand.nextInt(1, 4); + boolean[][] shape = new boolean[size][size]; + for(int i = 0; i < size; i++){ + for (int j = 0; j < size; j++) { + Vec2 checked = new Vec2(i, j).add(selected); + if(EmptySlots.contains(checked)){ + EmptySlots.remove(checked); + piece_layout[checked.x][checked.y] = false; + shape[i][j] = true; + } + } + } + ret.addPiece(new Piece(shape)); + } + + //generate pieces + return ret; + } +} diff --git a/app/src/test/java/school_project/MapGeneratorTest.java b/app/src/test/java/school_project/MapGeneratorTest.java new file mode 100644 index 0000000..d052592 --- /dev/null +++ b/app/src/test/java/school_project/MapGeneratorTest.java @@ -0,0 +1,26 @@ +package school_project; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class MapGeneratorTest { + + @Test + void generate() { + Map[] maps = new Map[] { + MapGenerator.generate(MapGenerator.Difficulty.Easy), + MapGenerator.generate(MapGenerator.Difficulty.Medium), + MapGenerator.generate(MapGenerator.Difficulty.Difficult), + }; + + for(Map m: maps){ + System.out.println("=========="); + System.out.println(m); + System.out.println("++++++++++++++++++++"); + for (Piece p: m.getPieces()){ + System.out.println(p); + } + } + } +} \ No newline at end of file