Klassen Map Erstellung mit Rekursion

Kiriku

Mitglied
Guten Mittag zusammen,
ich habe in der Uni seit wochen eine Aufgabe wo mit ich ein Konsolen-Spiel programmieren msus alles schon und gut aber mittlerweile haben wir die Map erstellung per Rekursion und bin ehrlich das ich das garnicht hinbekomme. Die Map soll so aussehen
unknown.png

wie soll sowas durch Rekursion erstellbar sein?
 

VfL_Freak

Top Contributor
Moin,
ich habe in der Uni seit wochen eine Aufgabe wo mit ich ein Konsolen-Spiel programmieren msus alles schon und gut
bedeutet das, dass Du schon eine nicht-rekursive Lösung hast?? :rolleyes:
Wenn ja, dann poste mal den Code! Sowas läßt sich gemeinhin immer in eine rekursive Variante umbauen!

BTW: ein bisschen mehr Zeichensetzung in Deinem Text würde ihn auch lesbarer machen!

VG Klaus
 

Kiriku

Mitglied
Moin,

bedeutet das, dass Du schon eine nicht-rekursive Lösung hast?? :rolleyes:
Wenn ja, dann poste mal den Code! Sowas läßt sich gemeinhin immer in eine rekursive Variante umbauen!

BTW: ein bisschen mehr Zeichensetzung in Deinem Text würde ihn auch lesbarer machen!

VG Klaus
Ich besitze eine Lösungen wie ich eine normale Arena bauen kann (NxN Dimension mit Wänden und ohne Hindernissen) aber keine die wie die gewollte Arena ist.
 

httpdigest

Top Contributor
Rekursion eignet sich immer gut, wenn es selbstähnliche Strukturen in der Map gibt, und diese dann mittels Skalierung/Rotation/Translation und/oder Spiegelung per Rekursion zu generieren.
Also, so wie bei einem Fraktal. Versuche mal, ob du irgendwelche Symmetrien in dem Level findest.
Z.B. wäre bei diesem sehr einfachen Level:
Code:
XXXXXXXXX
X       X
X XXXXX X
X X   X X
X X X X X
X X   X X
X XXXXX X
X       X
XXXXXXXXX
eine Symmetrie zu erkennen, die man per Rekursion generieren könnte, indem es drei Rekursionsstufen gibt, die jeweils die zu generierenden/füllenden Felder (bzw. die Positionen/Koordinaten der Felder) um den Ursprung skalieren und die Skalierung von der Rekursionstiefe abhängt.
 

Kiriku

Mitglied
Rekursion eignet sich immer gut, wenn es selbstähnliche Strukturen in der Map gibt, und diese dann mittels Skalierung/Rotation/Translation und/oder Spiegelung per Rekursion zu generieren.
Also, so wie bei einem Fraktal. Versuche mal, ob du irgendwelche Symmetrien in dem Level findest.
Z.B. wäre bei diesem sehr einfachen Level:
Code:
XXXXXXXXX
X       X
X XXXXX X
X X   X X
X X X X X
X X   X X
X XXXXX X
X       X
XXXXXXXXX
eine Symmetrie zu erkennen, die man per Rekursion generieren könnte, indem es drei Rekursionsstufen gibt, die jeweils die zu generierenden/füllenden Felder (bzw. die Positionen/Koordinaten der Felder) um den Ursprung skalieren und die Skalierung von der Rekursionstiefe abhängt.
Mein Problem liegt daran das ich mit Rekursion an sich nichts anfangen kann, wir hatten Rekursion nicht mal in den Vorlesung deswegen erkenne ich sowas nicht und kann das gewollte auch nicht umsetzen.
 

Kiriku

Mitglied
Hab hier schon mal Code ohne Rekursion
Code:
import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Random;
public class Try1 {


    public static class MyMaze {
      private int dimensionX, dimensionY; // dimension of maze
      private int gridDimensionX, gridDimensionY; // dimension of output grid
      private char[][] grid; // output grid
      private Cell[][] cells; // 2d array of Cells
      private Random random = new Random(); // The random object

      // initialize with x and y the same
      public MyMaze(int aDimension) {
          // Initialize
          this(aDimension, aDimension);
      }
      // constructor
      public MyMaze(int xDimension, int yDimension) {
          dimensionX = xDimension;
          dimensionY = yDimension;
          gridDimensionX = xDimension * 4 + 1;
          gridDimensionY = yDimension * 2 + 1;
          grid = new char[gridDimensionX][gridDimensionY];
          init();
          generateMaze();
      }

      private void init() {
          // create cells
          cells = new Cell[dimensionX][dimensionY];
          for (int x = 0; x < dimensionX; x++) {
              for (int y = 0; y < dimensionY; y++) {
                  cells[x][y] = new Cell(x, y, false); // create cell (see Cell constructor)
              }
          }
      }

      // inner class to represent a cell
      private class Cell {
        int x, y; // coordinates
        // cells this cell is connected to
        ArrayList<Cell> neighbors = new ArrayList<>();
        // solver: if used in last attempt to solve path
        boolean inPath = false;
        // impassable cell
        boolean wall = true;
        // if true, has yet to be used in generation
        boolean open = true;
        // construct Cell at x, y
        Cell(int x, int y) {
            this(x, y, true);
        }
        // construct Cell at x, y and with whether it isWall
        Cell(int x, int y, boolean isWall) {
            this.x = x;
            this.y = y;
            this.wall = isWall;
        }
        // add a neighbor to this cell, and this cell as a neighbor to the other
        void addNeighbor(Cell other) {
            if (!this.neighbors.contains(other)) { // avoid duplicates
                this.neighbors.add(other);
            }
            if (!other.neighbors.contains(this)) { // avoid duplicates
                other.neighbors.add(this);
            }
        }
        // used in updateGrid()
        boolean isCellBelowNeighbor() {
            return this.neighbors.contains(new Cell(this.x, this.y + 1));
        }
        // used in updateGrid()
        boolean isCellRightNeighbor() {
            return this.neighbors.contains(new Cell(this.x + 1, this.y));
        }
        // useful Cell representation
        @Override
        public String toString() {
            return String.format("Cell(%s, %s)", x, y);
        }
        // useful Cell equivalence
        @Override
        public boolean equals(Object other) {
            if (!(other instanceof Cell)) return false;
            Cell otherCell = (Cell) other;
            return (this.x == otherCell.x && this.y == otherCell.y);
        }
        // should be overridden with equals
        @Override
        public int hashCode() {
            // random hash code method designed to be usually unique
            return this.x + this.y * 256;
        }
      }
      // generate from upper left (In computing the y increases down often)
      private void generateMaze() {
          generateMaze(0, 0);
      }
      // generate the maze from coordinates x, y
      private void generateMaze(int x, int y) {
          generateMaze(getCell(x, y)); // generate from Cell
      }
      private void generateMaze(Cell startAt) {
          // don't generate from cell not there
          if (startAt == null) return;
          startAt.open = false; // indicate cell closed for generation
          ArrayList<Cell> cells = new ArrayList<>();
          cells.add(startAt);

          while (!cells.isEmpty()) {
              Cell cell;
              // this is to reduce but not completely eliminate the number
              //   of long twisting halls with short easy to detect branches
              //   which results in easy mazes
              if (random.nextInt(10)==0)
                  cell = cells.remove(random.nextInt(cells.size()));
              else cell = cells.remove(cells.size() - 1);
              // for collection
              ArrayList<Cell> neighbors = new ArrayList<>();
              // cells that could potentially be neighbors
              Cell[] potentialNeighbors = new Cell[]{
                  getCell(cell.x + 1, cell.y),
                  getCell(cell.x, cell.y + 1),
                  getCell(cell.x - 1, cell.y),
                  getCell(cell.x, cell.y - 1)
              };
              for (Cell other : potentialNeighbors) {
                  // skip if outside, is a wall or is not opened
                  if (other==null || other.wall || !other.open) continue;
                  neighbors.add(other);
              }
              if (neighbors.isEmpty()) continue;
              // get random cell
              Cell selected = neighbors.get(random.nextInt(neighbors.size()));
              // add as neighbor
              selected.open = false; // indicate cell closed for generation
              cell.addNeighbor(selected);
              cells.add(cell);
              cells.add(selected);
          }
      }
      // used to get a Cell at x, y; returns null out of bounds
      public Cell getCell(int x, int y) {
          try {
              return cells[x][y];
          } catch (ArrayIndexOutOfBoundsException e) { // catch out of bounds
              return null;
          }
      }

      public double getProjectedDistance(Cell current, double travelled, Cell end) {
          return travelled + Math.abs(current.x - end.x) +
                  Math.abs(current.y - current.x);
      }

      // draw the maze
      public void updateGrid() {
          char backChar = ' ', wallChar = '#', cellChar = ' ', pathChar = '*';
          // fill background
          for (int x = 0; x < gridDimensionX; x ++) {
              for (int y = 0; y < gridDimensionY; y ++) {
                  grid[x][y] = backChar;
              }
          }
          // build walls
          for (int x = 0; x < gridDimensionX; x ++) {
              for (int y = 0; y < gridDimensionY; y ++) {
                  if (x % 4 == 0 || y % 2 == 0)
                      grid[x][y] = wallChar;
              }
          }
          // make meaningful representation
          for (int x = 0; x < dimensionX; x++) {
              for (int y = 0; y < dimensionY; y++) {
                  Cell current = getCell(x, y);
                  int gridX = x * 4 + 2, gridY = y * 2 + 1;
                  if (current.inPath) {
                      grid[gridX][gridY] = pathChar;
                      if (current.isCellBelowNeighbor())
                          if (getCell(x, y + 1).inPath) {
                              grid[gridX][gridY + 1] = pathChar;
                              grid[gridX + 1][gridY + 1] = backChar;
                              grid[gridX - 1][gridY + 1] = backChar;
                          } else {
                              grid[gridX][gridY + 1] = cellChar;
                              grid[gridX + 1][gridY + 1] = backChar;
                              grid[gridX - 1][gridY + 1] = backChar;
                          }
                      if (current.isCellRightNeighbor())
                          if (getCell(x + 1, y).inPath) {
                              grid[gridX + 2][gridY] = pathChar;
                              grid[gridX + 1][gridY] = pathChar;
                              grid[gridX + 3][gridY] = pathChar;
                          } else {
                              grid[gridX + 2][gridY] = cellChar;
                              grid[gridX + 1][gridY] = cellChar;
                              grid[gridX + 3][gridY] = cellChar;
                          }
                  } else {
                      grid[gridX][gridY] = cellChar;
                      if (current.isCellBelowNeighbor()) {
                          grid[gridX][gridY + 1] = cellChar;
                          grid[gridX + 1][gridY + 1] = backChar;
                          grid[gridX - 1][gridY + 1] = backChar;
                      }
                      if (current.isCellRightNeighbor()) {
                          grid[gridX + 2][gridY] = cellChar;
                          grid[gridX + 1][gridY] = cellChar;
                          grid[gridX + 3][gridY] = cellChar;
                      }
                  }
              }
          }
      }

      // simply prints the map
      public void draw() {
          System.out.print(this);
      }
      // forms a meaningful representation
      @Override
      public String toString() {
          updateGrid();
          String output = "";
          for (int y = 0; y < gridDimensionY; y++) {
              for (int x = 0; x < gridDimensionX; x++) {
                  output += grid[x][y];
              }
              output += "\n";
          }
          return output;
      }

      // run it
      public static void main(String[] args) {
          MyMaze maze = new MyMaze(5);
          maze.draw();
      }
    }

}
 

Neue Themen


Oben