1. 程式人生 > >回溯法迷宮求解

回溯法迷宮求解

回溯法解迷宮(利用棧的性質進行迷宮求解)

一、迷宮類:

package migongqiujie;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.FlatteningPathIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.Stack;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.omg.CORBA.PRIVATE_MEMBER;
import org.omg.CORBA.PUBLIC_MEMBER;
/*
* 回溯法解迷宮(窮舉法)
* 實現思路:
* 1、運用java Swing生成一個迷宮面板,使用Cell繼承面板實現迷宮中的每個方塊
* 2、生成迷宮主要是用了隨機數的生成
* 3、解迷宮主要是運用了窮舉法,構造棧來存放走過的路徑,同時對相應的Cell塊進行塗色,
* 如果遇到走不通或者走過的地方都要進行出棧,同時對另一個方向進行探索。
*/

public class Migong2 extends JFrame {
private int M = 30;// 設定面板為30*30
private Cell[][] cells = new Cell[M][M];// 引入Cell類
private JButton jbCreate = new JButton(“生成迷宮”);
private JButton jbFindPath = new JButton(“尋找解法”);
private JPanel jpUp, jpBut;
private Thread th1 = new Thread();
int row, col;

public Migong2(int row, int col) {
    this.row = row;
    this.col = col;
}

public Migong2() {
    super();
    setSize(700, 700);
    setTitle("回溯法解迷宮");
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    jpUp = new JPanel();
    jpBut = new JPanel();
    jpUp.setLayout(new GridLayout(M, M, 2, 2));
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < M; j++) {
            cells[i][j] = new Cell(i, j);
            jpUp.add(cells[i][j]);
        }
    }
    for (int i = 0; i < M; i++)// 為迷宮增加邊框
    {
        cells[0][i].setBackground(Color.red);
        cells[M - 1][i].setBackground(Color.red);
        cells[i][0].setBackground(Color.red);
        cells[i][M - 1].setBackground(Color.red);
    }
    cells[1][0].setBackground(Color.green);// 入口
    cells[28][29].setBackground(Color.green);// 出口
    add(jpUp, BorderLayout.CENTER);
    jpBut.add(jbCreate);
    jpBut.add(jbFindPath);
    add(jpBut, BorderLayout.SOUTH);
    jbCreate.addActionListener(new ActionListener() {// 為生成迷宮新增事件函式
        @Override
        public void actionPerformed(ActionEvent e) {
            th1.suspend();
            CreatePath();
        }
    });
    jbFindPath.addActionListener(new ActionListener() {// 為找解新增事件函式

                @Override
                public void actionPerformed(ActionEvent e) {
                    th1.suspend();
                    FindPath();
                }
            });
    setVisible(true);
}
public void CreatePath()// 生成迷宮的圖樣,JbCreate的函式呼叫
{
    for (int rrow = 1; rrow < M - 1; rrow++) {// 每次生成迷宮重新整理
        for (int rcol = 1; rcol < M - 1; rcol++) {
            cells[rrow][rcol].setBackground(Color.black);
        }
    }
    Random random = new Random();
    int row;
    int col;
    int i = 250;
    int max = M - 2;
    int min = 1;
    while (i > 0) {
        row = random.nextInt(max) % (max - min + 1) + min;
        col = random.nextInt(max) % (max - min + 1) + min;
        cells[row][col].setBackground(Color.red);
        i--;
    }
}

public void FindPath()// 解迷宮,做為jbFindPath的函式呼叫
{
    final Stack<Migong2> stack = new Stack<Migong2>();// 構造空棧Migong2型別的空棧
    Runnable runable = new Runnable() {
        public void run() {
            int i = 1;
            int j = 1;
            Cell cell = new Cell(i, j);
            cells[i][j].setBackground(Color.green);
            stack.push(new Migong2(i, j));
            while (!stack.empty()) {// 棧不空,執行迴圈
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }
                if (cells[i][j + 1].getBackground() == Color.black) {
                    cells[i][j + 1].setBackground(Color.green);
                    stack.push(new Migong2(i, j + 1));
                    j++;
                } else if (cells[i + 1][j].getBackground() == Color.black) {
                    cells[i + 1][j].setBackground(Color.green);
                    stack.push(new Migong2(i + 1, j));
                    i++;
                } else if (cells[i][j - 1].getBackground() == Color.black) {
                    cells[i][j - 1].setBackground(Color.green);
                    stack.push(new Migong2(i, j - 1));
                    j--;
                } else if (cells[i - 1][j].getBackground() == Color.black) {
                    cells[i - 1][j].setBackground(Color.green);
                    stack.push(new Migong2(i - 1, j));
                    i--;
                } else {
                    Migong2 maze = stack.pop();// 出棧
                    int m;
                    int n;
                    m = maze.row;// 取出出棧元素的行標
                    n = maze.col;// 取出出棧元素的列標
                    cells[m][n].setBackground(Color.blue);
                    if (stack.empty()) {
                        break;
                    }
                    i = stack.peek().row;// 取棧頂元素的行標
                    j = stack.peek().col;// 取棧頂元素的列標
                    cells[i][j].setBackground(Color.blue);
                }
                if (i == M - 2 && j == M - 2) {
                    JOptionPane.showMessageDialog(null, "找到出口了!", "",
                            JOptionPane.ERROR_MESSAGE);
                    return;
                }
            }
            JOptionPane.showMessageDialog(null, "沒找到出口!", "",
                    JOptionPane.ERROR_MESSAGE);
        }
    };
    th1 = new Thread(runable);
    th1.start();
}
public static void main(String[] args) {
    new Migong2();
}

}
二、Cell類:
package migongqiujie;

import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JPanel;
public class Cell extends JPanel{
Cell(int row,int col){
setBackground(Color.black);
}
}
生成迷宮:
這裡寫圖片描述
這裡寫圖片描述
解迷宮:
這裡寫圖片描述
無解:
這裡寫圖片描述