不管怎么去解决迷宫问题,回溯法都是一个经典解法。
这里加了一个简单的图形界面。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Maze extends JApplet {
/**
*
*/
private static final long serialVersionUID = 1L;
private Cell[][] board = new Cell[8][8];
private JButton jbtFindPath = new JButton("Find Path");
private JButton jbtClearPath = new JButton("Clear Path");
private JPanel jpBoard, jpButton;
private JLabel jlblStatus = new JLabel();
public void init() {
jpBoard = new JPanel();
jpBoard.setLayout(new GridLayout(8, 8, 2, 2));
jpButton = new JPanel();
jpButton.setLayout(new FlowLayout());
jpButton.add(jbtFindPath);
jpButton.add(jbtClearPath);
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
board[row][col] = new Cell();
jpBoard.add(board[row][col]);
}
}
setLayout(new BorderLayout());
add(jlblStatus, BorderLayout.NORTH);
add(jpBoard, BorderLayout.CENTER);
add(jpButton, BorderLayout.SOUTH);
jbtFindPath.addActionListener(new Listener());
jbtClearPath.addActionListener(new Listener());
}
public static void main(String[] args) {
JFrame frame = new JFrame("Maze");
Maze applet = new Maze();
frame.add(applet, BorderLayout.CENTER);
applet.init();
applet.start();
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class Listener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String arg = e.getActionCommand();
if (e.getSource() instanceof JButton) {
if ("Find Path".equals(arg)) {
findPath();
} else if ("Clear Path".equals(arg)) {
clearPath();
}
}
}
}
public void findPath() {
if (findPath(0, 0)) {
jlblStatus.setText("path found");
} else {
jlblStatus.setText("No path exists");
}
}
public boolean findPath(int row, int col) {
board[row][col].visit();
if ((col == 7) && (row == 7)) {
board[row][col].selectCell();
return true;
}
if ((row > 0) && !board[row - 1][col].marked()
&& !board[row - 1][col].blocked() && !board[row - 1][col].visited()) {
block(row, col);
if (findPath(row - 1, col)) {
board[row][col].selectCell();
return true;
}
unblock(row, col);//没有路径,解除标记
}
if ((row < 7) && !board[row + 1][col].marked()
&& !board[row + 1][col].blocked() && !board[row + 1][col].visited()) {
block(row, col);
if (findPath(row + 1, col)) {
board[row][col].selectCell();
return true;
}
unblock(row, col);
}
if ((col > 0) && !board[row][col - 1].marked()
&& !board[row][col - 1].blocked() && !board[row][col - 1].visited()) {
block(row, col);
if (findPath(row, col - 1)) {
board[row][col].selectCell();
return true;
}
unblock(row, col);
}
if ((col < 7) && !board[row][col + 1].marked()
&& !board[row][col + 1].blocked() && !board[row][col + 1].visited()) {
block(row, col);
if (findPath(row, col + 1)) {
board[row][col].selectCell();
return true;
}
unblock(row, col);
}
return false;
}
//标记走过的路径
public void block(int row, int col) {
if (row > 0) {
board[row - 1][col].block();
}
if (row < 7) {
board[row + 1][col].block();
}
if (col > 0) {
board[row][col - 1].block();
}
if (col < 7) {
board[row][col + 1].block();
}
}
public void unblock(int row, int col) {
if (row > 0) {
board[row - 1][col].unblock();
}
if (row < 7) {
board[row + 1][col].unblock();
}
if (col > 0) {
board[row][col - 1].unblock();
}
if (col < 7) {
board[row][col + 1].unblock();
}
}
public void clearPath() {
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
board[row][col].deselectCell();
}
}
}
class Cell extends JPanel implements MouseListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private boolean marked = false;
private boolean visited = false;
private boolean blocked = false;
public Cell() {
setBackground(Color.white);
addMouseListener(this);
}
public boolean marked() {
return marked;
}
public void visit() {
visited = true;
}
public boolean visited() {
return visited;
}
public boolean blocked() {
return blocked;
}
public void block() {
blocked = true;
}
public void unblock() {
blocked = false;
}
public void selectCell() {
setBackground(Color.red);
repaint();
}
public void deselectCell() {
setBackground(Color.white);
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
//画叉
if (marked) {
g.drawLine(0, 0, getSize().width, getSize().height);
g.drawLine(getSize().width, 0, 0, getSize().height);
}
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
marked = !marked;
repaint();
}
}
}