Как я могу сделать рекурсию назад по себе? - PullRequest
0 голосов
/ 24 апреля 2018

У меня проблема, и я не уверен, основано ли это на рекурсии. Я создал лабиринт с графическим интерфейсом, который решает сам, но курсор перескакивает через любой пройденный рекурсией квадрат вместо повторного перемещения по квадрату. Несмотря на то, что в конечном итоге цель найдена, я хочу показать весь ее путь, но не могу удержать курсор от прыжка.

Я использую Runnable для отслеживания лабиринта в режиме реального времени, чтобы я мог видеть его отскок, но без рекурсивного перемещения, удерживающего его в привязке, рекурсивные функции перестают работать (он просто отскакивает назад и вперед, что, опять же, я Я не совсем понимаю.) Я запустил Java около трех месяцев назад в ускоренной программе, поэтому я не уверен, является ли проблема в моем понимании рекурсии, или в простом добавлении к методу, или мне придется переписать большая часть кода.

Я включил весь код на всякий случай, но на самом деле это проблема, связанная с методом travel или с методом посещения. Будет ли ответом написать совершенно новый метод, который перемещает измененный «посещенный» струнный лабиринт? Я боролся с этим немного, и мне просто нужно какое-то направление к ответу.

import java.awt.*;
import javax.swing.*;

class extraCreditMaze extends JPanel implements Runnable {        //uses Runnable to execute jPanel

   private String [][] ratMaze =                         //string maze
   {{"blocked","blocked","blocked","blocked","blocked","blocked","blocked","blocked"},
    {"blocked","open","blocked","blocked","blocked","blocked","blocked","blocked"},
    {"blocked","open","open","open","open","open","open","blocked"},
    {"blocked","blocked","open","blocked","open","blocked","open","blocked"},
    {"blocked","blocked","open","blocked","open","blocked","open","goal"},
    {"blocked","open","open","open","blocked","open","open","blocked"},
    {"blocked","blocked","blocked","open","open","open","blocked","blocked"},
    {"blocked","blocked","blocked","blocked","blocked","blocked","blocked","blocked"}};

   final private int SquareSize = 15;
   final private int BoardSize = 17;
   private boolean free = false;
   int axisX = 1, axisY = 1;

   public void paintComponent(Graphics color)            //paint components for char
   {
      super.paintComponent(color);
        for(int row = 0;  row < ratMaze.length; row++)
      {
         for(int col = 0; col< ratMaze.length; col++)
         {
            if(row==axisX && col==axisY)                 //traveling curser = blue
            {
               color.setColor(Color.blue);
               color.fillOval(col*15,row*15,15,15);
                }
            else if(ratMaze[row][col]=="blocked")              //empty = black
            {
               color.setColor(Color.black);
               color.fillRect(col*SquareSize,row*SquareSize,BoardSize,BoardSize);
            }
           else if(ratMaze[row][col]=="goal")
            {
               color.setColor(Color.red);               //goal = red
               color.fillOval(col*15,row*15,15,15);
            }
            else if(ratMaze[row][col]=="visited")
            {
               color.setColor(Color.green);              //path traveled = green
               color.fillOval(col*15,row*15,15,15);
            }
            else
            {
                color.setColor(Color.white);              //empty space = white
                color.fillRect(col*SquareSize,row*SquareSize,BoardSize,BoardSize);
            }
        }
      }
   }

   public void run ()                                    //starts run at (1,1)
   {
      travel(1,1);
   }

   public boolean goal(int x, int y){                    //method to check goal (true/false)
        if(ratMaze[x][y]=="goal")
            return true;
        else 
            return false;
   }

   public void changedVisited(int x, int y)              //method to change traveled
   {
            ratMaze[x][y] = "visited";
            axisX = x;
            axisY = y;
   }

   public boolean boundaries(int x, int y)               //check boundaries
   {
        if(ratMaze[x][y]=="blocked")
            return true;
        else 
            return false;
   }

   public boolean visited(int x, int y)                  //check if visited
   {
        if(ratMaze[x][y]=="visited")
                return true;
            else 
                return false;
   }

   private void travel(int x, int y)
   {
      if(boundaries(x,y))                                //makes sure it's within bounds
         return;

      if(visited(x,y))                                   //makes sure it hasn't already been visited
         return;

      if(goal(x,y))                                      //checks if it's the goal/changes boolean
      {
         free = true;
        JOptionPane.showMessageDialog(this, "You did it, Dr. Cui!");      //fun message!
      }

      if(!free)                                           //all recursion functions if free=false
      {
        changedVisited(x,y);                             //changes traveled block to "visited"
        repaint();                                       //repaints visited
        try {Thread.sleep(300); } catch (Exception e) { }//slows down the traveling curser
                                                          //I do not understand catch (Exception e)

            travel(x-1,y);                                 //recursive travel functions
            travel(x+1,y);
            travel(x,y-1);
            travel(x,y+1);
        }       
   }
}

public class runExtraCreditMaze {
   public static void main (String [] args) {       //JFrame panel and perimeters
      JFrame output = new JFrame();
      output.setSize(115, 150);
      output.setTitle("The Rat Maze");
      output.setLocationRelativeTo(null);
      extraCreditMaze Maze = new extraCreditMaze();
      output.setContentPane(Maze);
      output.setVisible(true);

      Thread runnable = new Thread(Maze);           //Creates Runnable thread for Maze object
      runnable.start();                             //Starts Runnable thread of Maze object
   }
}

1 Ответ

0 голосов
/ 24 апреля 2018

Проблема в том, как вы писали с «посещенными». Вам не хватает дерева решений о том, что делать, когда нет действительного хода, и вы не в цели. Вам нужно будет разрешить своей крысе проследить за собой. Вам, вероятно, нужно будет «освободить» посещенные ячейки, когда вы вернетесь без действительного хода. Я постараюсь добавить несколько примеров кода, когда попаду в IDE:)

обновление: это очень плохо написано, и это немного отстает. но это должно работать. Это требует небольшой очистки и проверки ... Я повторно использовал вашу логическую переменную, что плохо .. :) и переключил значение true / false. Завтра я сделаю небольшую уборку, чтобы оставить более хороший ответ, но я думаю, что вам удастся понять, что происходит.

update2: я немного почистил. Важные уроки здесь следующие:

1) Возврат должен быть выполнен, если все 4 шага не пройдены. Когда вашей крысе некуда деваться, вам нужно исключить ячейку из вашего кратчайшего пути (ratMaze [x] [y] = "open")
2) Вам нужно изменить положение вашей крысы, когда вы вернетесь из рекурсивного вызова, но перед тем, как перейти к следующему шагу. Вам также нужно сообщить вашей программе, что вы возвращаетесь из рекурсии (таким образом, isBacktracking)

private void repaintMaze(int x, int y) {
  changedVisited(x, y); //changes traveled block to "visited"
  repaint(); //repaints visited
  isBacktracking = false;
  try {
      Thread.sleep(500);
  } catch (Exception e) {
  }
}

private boolean travel(int x, int y) {
  if (goal(x, y)) //checks if it's the goal/changes boolean
  {
      JOptionPane.showMessageDialog(this, "You did it, Dr. Cui!");//fun message!
      return true;
  }

  if (boundaries(x, y) || visited(x, y))  //makes sure it's within bounds
        return false;

  repaintMaze(x, y);
  boolean result; //recursive travel functions
  result = travel(x - 1, y);
  if (result) {
      return true;
  }
  if (isBacktracking) {
      repaintMaze(x, y);
  }
  result = travel(x + 1, y);
  if (result) {
      return true;
  }
  if (isBacktracking) {
      repaintMaze(x, y);
  }
  result = travel(x, y - 1);
  if (result) {
      return true;
  }
  if (isBacktracking) {
      repaintMaze(x, y);
  }
  result = travel(x, y + 1);
  if (result) {
      return true;
  }
  if (isBacktracking) {
      repaintMaze(x, y);
  }

  ratMaze[x][y] = "open";
  isBacktracking = true;
  return false;
}

Вы также должны добавить выход при закрытии JFrame :) Приложение остановится, как только вы нажмете кнопку X в самом окне

output.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
...