// Exercise20_26.java: The Maze problem
// Comment the block() and unblock() methods to show Figure 10.30 for jbBook
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Exercise20_26 extends JApplet {
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);
// Add cells to jpBoard
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]);
}
}
// Add jpBoard, jpButtons and jlblStatus to the applet
setLayout(new BorderLayout());
add(jlblStatus, BorderLayout.NORTH);
add(jpBoard, BorderLayout.CENTER);
add(jpButton, BorderLayout.SOUTH);
// Register listeners
jbtFindPath.addActionListener(new Listener());
jbtClearPath.addActionListener(new Listener());
}
// Main method
public static void main(String[] args) {
// Create a frame
JFrame frame = new JFrame("Exercise20_26");
// Create an instance of MortgageApplet
Exercise20_26 applet = new Exercise20_26();
// Add the applet instance to the frame
frame.add(applet, BorderLayout.CENTER);
// Invoke init() and start()
applet.init();
applet.start();
// Display the frame
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null); // Center the frame
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;
}
// Temporary block the neighbor to prevent neighboring path
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();
}
}
// Remove the temporary 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();
}
}
}
// Inner class
class Cell extends JPanel implements MouseListener {
private boolean marked = false;
private boolean visited = false;
private boolean blocked = false;
private boolean cellSelected = 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();
}
}
}