Java Labyrinth

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Java Labyrinth

      hey leute
      ich hab in java ein programm geschrieben, welches ein labyrinth - aufgebaut auf zeichen in einem array - erstellt
      und dann einen weg durch dieses finden soll (rekursiver algo).

      es sollte funktionieren, tut es aber nicht.
      ich kann ums verrecken keinen fehler finden.
      könnt ihr mir weiterhelfen?

      hier mein code:

      public class Maze {

      static char[][] maze =new char[10][10];
      final static int[] STEPX = { 0, 1, 0,-1 };
      final static int[] STEPY = { -1, 0, 1, 0 };
      static int step, aktX, aktY;


      static void createMaze(){

      for(int i=0;i<10;i++){
      maze[0]='X';
      maze[i][0]='X';
      maze[9][i]='X';
      maze[i][9]='X'; //erstellen der Ränder

      }

      for(int k=1; k<9;k++){
      for(int j=1;j<9;j++){
      Random rWall = new Random(0, 2);
      int wall=rWall.readInt();
      if(wall==0){
      maze[k][j]='X'; //mit zufälligen Wänden befüllen
      }else{
      maze[k][j]=' ';
      }
      }
      }

      maze[1][1]='A';
      maze[8][8]='Z'; //setzen von Anfang und Ziel

      }

      static boolean findWay(char[][] maze1, int i, int j){

      int step = -1;
      while (step != 3) {
      step ++;
      int newX = i + STEPX[step];
      int newY = j + STEPY[step];

      boolean ok = true;

      if (newX < 1 || newX >= 8) ok = false;
      if (newY < 1 || newY >= 8) ok = false;
      if (ok && maze1[newX][newY] !=' ') ok = false;

      if(ok){
      maze1[newX][newY] = '*';

      if (!ausgangGefunden(newX, newY)) {
      // rekursiver Aufruf von findWay
      if (findWay(maze1, newX, newY)) {
      // Lösung gefunden
      return true;
      } else {
      maze1[newX][newY] = ' ';
      }
      } else return true;
      }
      }//while
      return false;
      }

      private static boolean ausgangGefunden(int newX, int newY) {

      if(newX==8 && newY==8){
      return true;
      }
      return false;
      }

      static void printMaze(){

      for(int i=0;i<10;i++){
      for(int j=0;j<10;j++){
      System.out.print(maze[i][j]);
      }
      System.out.println();
      }
      System.out.println();

      }

      public static void main (String[] args) {

      createMaze();
      printMaze();
      boolean b = findWay(maze, 1, 1);
      if (b) System.out.println("Weg gefunden");
      else System.out.println("Keinen Weg gefunden");
      printMaze();


      }


      }


      MfG
    • Hallo,

      Gut wäre es, wenn du das nicht funktionieren des Programms besser beschreibst, dann kann man sich kritische Stellen anschauen, ohne sich in das ganze Programm einarbeiten zu müssen. Wenn du nicht weißt wo es hapert, kannst du entweder einen Debugger drüber laufen lassen und das Programm zeile für zeile abarbeiten lassen oder deinen Code künstlich durch Benutzereingaben anhalten und Variablen, die gerade wichtig sind ausgeben lassen. Damit solltest du die Stelle, die nicht funktioniert sehr gut einkreisen können und ggf. auch selber eine Lösung finden.

      Tray

      Quellcode

      1. main()
      2. {
      3. for(;;)
      4. printf("DotaInside - ich war dabei!\n");
      5. }

    • es sollte funktionieren, tut es aber nicht.

      Mit so einer Fehlermeldung wird dir weder hier, noch sonst in nem Java-Forum wer antworten.
      Kriegst du ne Fehlermeldung? GGF SYSOUTS printen um zu sehen, wo er hängen bleibt.
      Schonmal was von nem Debugger gehört?
      Wenn ja, Debuggen und gucken wo er hängen bleibt.
      Hast du dir überlegt, daß es einfach keine Möglichkeit geben kann zum Ziel zu finden? Wie schließt du das aus? Brauchen doch bloß zufällig 3 Wände neben dem Startblock erscheinen und schon kann man garkeinen Weg finden.

      edit:
      eben noch aufgefallen:
      if (ok && maze1[newX][newY] !=' ') ok = false;

      hier sagst du auch ganz klar, daß er seinen weg nicht zurückgehen kann, das heißt sobald er in irgendeine sackgasse läuft, gehtsnicht mehr weiter, er is in ner endlosschleife gefangen.
      du musst also * noch als Feld erlauben und solltest ne Priorität machen:
      Wand = Da darfst nicth hin
      * (da war ich schon) = Nur dann zurückgehen, wenn nix freies mehr erreichbar
      ' ' (da war ich noch nicht) = Primär hier hingehen, wenn mein Step das möchte, ansonsten neuen Step wählen.

      Du hast ja von jedem Punkt aus 8 Möglichkeiten zu laufen (weil du diagonal ja erlaubst).

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von henpara ()

      Ich bin nur hier weil Dotacontents!
    • ich habe das hier leider jetzt erst gelesen.

      zum einen musst du ihn auch parallel laufen lassen (ok, musst du nicht, aber läuft er nur waagerecht und senkrecht ist die wahrscheinlichkeit deutlich kleiner, dass ein weg zum ziel existiert)
      und zum anderen musst du, wie der vorposter schon erwähnt hat, prioriäten setzen und erst auf freie felder (' ') gehen und dir dann die schon begangenen felden ('*') merken.

      zudem ist mir noch aufgefallen, dass du das ziel aufgrund dieser zwei abfragen nie erreichen kannst

      Quellcode

      1. if (newX < 1 || newX >= 8) {
      2. ok = false;
      3. }
      4. if (newY < 1 || newY >= 8) {
      5. ok = false;
      6. }


      hier sagst du ja eindeutig, dass er position [8][8], wo das ziel ('Z') ja sitzt nie auf "boolean ausgangGefunden(int newX, int newY)" abfragen kann.
      der vergleich muss also auf newX/newY > 8 sein.

      ich hab den code mal überarbeitet und folgende dinge eingebaut(is auch an den stellen entsprechend kommentiert):

      - kann in 8 richtungen gehen
      - wartet wenn er ein schon begangenes feld findet erstmal ab, ob noch ein freies feld in seiner umgebung liegt und merkt sich solange wo der ausweg ('*') war
      - einige if abfragen ein wenig überarbeitet und hinzugefügt

      hier mal der komplette code jetzt (ich behaupte nicht, dass das eine optimale lösung oder sonstiges ist, aber so funktioniert der alrorithmus. er findet immer seinen weg zum ziel, auch wenn dies meist nicht der optimale weg ist, was wohl auch nicht der anspruch des algos ist wenn ich mir den so anschau ;) )

      Java-Quellcode

      1. import java.util.Random;
      2. public class Maze {
      3. static char[][] maze = new char[10][10];
      4. final static int[] STEPX = { 0, 1, 1, 1, 0, -1, -1, -1 }; // jetzt alle 8 Richtungen möglich
      5. final static int[] STEPY = { -1, -1, 0, 1, 1, 1, 0, -1 };
      6. static int step, aktX, aktY;
      7. static boolean hasResort = false;
      8. static void createMaze() {
      9. for (int i = 0; i < 10; i++) {
      10. maze[0][i] = 'X';
      11. maze[i][0] = 'X';
      12. maze[9][i] = 'X';
      13. maze[i][9] = 'X'; // erstellen der Ränder
      14. }
      15. for (int k = 1; k < 9; k++) {
      16. for (int j = 1; j < 9; j++) {
      17. Random rWall = new Random();
      18. int wall = rWall.nextInt(3);
      19. if (wall == 0) {
      20. maze[k][j] = 'X'; // mit zufälligen Wänden befüllen
      21. } else {
      22. maze[k][j] = ' ';
      23. }
      24. }
      25. }
      26. maze[1][1] = 'A';
      27. maze[8][8] = 'Z'; // setzen von Anfang und Ziel
      28. }
      29. static boolean findWay(char[][] maze1, int i, int j) {
      30. int step = -1;
      31. while (step != 7) { // nun != wegen 8 Richtungen
      32. step++;
      33. int newX = i + STEPX[step];
      34. int newY = j + STEPY[step];
      35. boolean ok = true;
      36. if (newX < 1 || newX > 8) { // Ziel darf nun auf ausgangGefunden() überprüft werden
      37. ok = false;
      38. continue; // springt sofort in die nächste iteration der schleife -> kleine performance-optimierung
      39. }
      40. if (newY < 1 || newY > 8) {
      41. ok = false;
      42. continue;
      43. }
      44. if ((maze1[newX][newY] == 'X') || (maze1[newX][newY] == 'A')) {
      45. ok = false;
      46. continue;
      47. }
      48. if (maze1[newX][newY] == '*') {
      49. if (!hasResort) { // merkt sich Ausweg falls kein freies Feld (' ') mehr kommt
      50. saveResort(newX, newY);
      51. }
      52. hasResort = true;
      53. ok = false;
      54. continue;
      55. }
      56. if (maze1[newX][newY] != ' ' && (STEPX[step] == -1 && STEPY[step] == -1)) { // nutzt Ausweg
      57. newX = aktX;
      58. newY = aktY;
      59. hasResort = false;
      60. ok = true;
      61. }
      62. if (ok) {
      63. if (maze1[newX][newY] == ' '){
      64. maze1[newX][newY] = '*';
      65. }
      66. if (!ausgangGefunden(newX, newY)) {
      67. // rekursiver Aufruf von findWay
      68. if (findWay(maze1, newX, newY)) {
      69. // Lösung gefunden
      70. return true;
      71. } else {
      72. maze1[newX][newY] = ' ';
      73. }
      74. } else {
      75. return true;
      76. }
      77. }
      78. }// while
      79. return false;
      80. }
      81. private static boolean ausgangGefunden(int newX, int newY) {
      82. if (newX == 8 && newY == 8) {
      83. return true;
      84. }
      85. return false;
      86. }
      87. private static void saveResort(int pX, int pY) {
      88. aktX = pX;
      89. aktY = pY;
      90. }
      91. static void printMaze() {
      92. for (int i = 0; i < 10; i++) {
      93. for (int j = 0; j < 10; j++) {
      94. System.out.print(maze[i][j]);
      95. }
      96. System.out.println();
      97. }
      98. System.out.println();
      99. }
      100. public static void main(String[] args) {
      101. createMaze();
      102. printMaze();
      103. boolean b = findWay(maze, 1, 1);
      104. if (b)
      105. System.out.println("Weg gefunden");
      106. else
      107. System.out.println("Keinen Weg gefunden");
      108. printMaze();
      109. }
      110. }
      Alles anzeigen


      mfg
      Dis


      edit:

      was mir eben noch eingefallen ist:

      durch die anornung von start und zielpunkt könnte man die wegfindunung in den meisten fällen wohl optimieren in dem man die zwei arrays STEPX und STEPY umsortiert.
      da er tendenziell nach rechts unten muss könnte man die arrays so sortieren, dass er zuerst die drei felder rechts( +1, 0), rechts-unten(+1,+1) und unten(0,+1) abfragt.

      mfg

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Disaster ()