求解迷宫游戏

问题描述

迷宫问题求解2
•	使用深度优先的方法解决迷宫问题
•	规定迷宫的最外围为一圈墙,给出起点和终点要求输出一条正确的路径,但不要求为最短路径
•	使用opencv实现可视化,演示一个动态求解迷宫的过程

在这里插入图片描述

代码部分

Position.java 文件

package MazeGame;

//位置类,用语记录当前所走的位置
public class Position {
    int x;
    int y;

    public Position(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public Position(Position p) {
        this.x = p.x;
        this.y = p.y;
    }
}

MyNode.java 文件

package MazeGame;

//自己所设置的点的位置
public class MyNode {
    Position element;
    MyNode next;

    public MyNode(Position p) {
        this.element = new Position(p);
        this.next = null;
    }
}

MyMaze.java 文件

package MazeGame;

import java.util.EmptyStackException;

//自己所设计的迷宫
public class MyMaze {
    protected MyNode top = null;

    public MyMaze() {

    }

    public void push(Position element) {
        if (this.top == null) {
            this.top = new MyNode(element);
        } else {
            MyNode current = new MyNode(element);
            current.next = this.top;
            this.top = current;
        }

    }

    public Position pop() {
        if (this.isEmpty()) {
            throw new EmptyStackException();
        } else {
            Position p = this.top.element;
            this.top = this.top.next;
            return p;
        }
    }

    public boolean isEmpty() {
        return this.top == null;
    }
}

Gird.java 文件

package MazeGame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

//网格背景类
class Grid extends JButton implements ActionListener {
    //墙
    boolean isWall;

    public Grid() {
        this.isWall = false;
        this.setBackground(Color.white);
        this.addActionListener(this);
    }

    public Grid(int i) {
        Font font = new Font("Serif", 1, 12);
        this.isWall = true;
        this.setText(String.valueOf(i));
        this.setFont(font);
        //this.setBackground(new Color(1.0F, 1.0F, 1.0F, 0.0F));
    }

    public void setWall() {
        this.isWall = true;
        this.setBackground(Color.BLACK);
    }

    public void actionPerformed(ActionEvent arg) {
        if (this.isWall) {
            this.isWall = false;
            this.setBackground(Color.WHITE);
        } else {
            this.isWall = true;
            this.setBackground(Color.BLACK);
        }

    }

 /*   public void click() {
       if (this.isWall) {
            this.isWall = false;
            this.setBackground(Color.WHITE);
        } else {
           this.isWall = true;
           this.setBackground(Color.BLACK);
        }
    }*/

}

Maze.java 文件

package MazeGame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class Maze implements MouseListener {
    static Grid[][] grid;
    static MyMaze path;
    static Position start;
    static Position end;
    static int WIDTH;
    static int HEIGHT;
    JTextField start1;
    JTextField end1;
    JTextField out;
    boolean isMousePressed;

    public Maze(int width, int height) {
        WIDTH = width + 2;
        HEIGHT = height + 2;
        grid = new Grid[WIDTH][HEIGHT];
        this.layout(width + 2, height + 2);
    }

    private void layout(int width, int height) {
        int sideLength = 40;
        int frameWidth = sideLength * width + 20;
        int frameHeight = sideLength * (height + 2) + 32;
        JFrame frame = new JFrame();
        frame.setTitle("Maze Solution");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(frameWidth, frameHeight);
        frame.addMouseListener(this);
        frame.setLayout(null);

        int i;
        for(i = 1; i < width - 1; ++i) {
            for(int j = 1; j < height - 1; ++j) {
                grid[i][j] = new Grid();
                grid[i][j].addMouseListener(this);
                frame.add(grid[i][j]);
                grid[i][j].setBounds(sideLength * i, sideLength * j, sideLength, sideLength);
            }
        }

        for(i = 1; i < width - 1; ++i) {
            grid[0][i] = new Grid(i);
            frame.add(grid[0][i]);
            grid[0][i].setBounds(sideLength * i, 0, sideLength, sideLength);
            grid[height - 1][i] = new Grid(i);
            frame.add(grid[height - 1][i]);
            grid[height - 1][i].setBounds(sideLength * i, sideLength * (height - 1), sideLength, sideLength);
        }

        for(i = 1; i < height - 1; ++i) {
            grid[i][0] = new Grid(i);
            frame.add(grid[i][0]);
            grid[i][0].setBounds(0, sideLength * i, sideLength, sideLength);
            grid[i][width - 1] = new Grid(i);
            frame.add(grid[i][width - 1]);
            grid[i][width - 1].setBounds(sideLength * (width - 1), sideLength * i, sideLength, sideLength);
        }

        JLabel start0 = new JLabel("enter:");
        frame.add(start0);
        start0.setBounds(0, sideLength * height, 40, 40);
        this.start1 = new JTextField();
        frame.add(this.start1);
        this.start1.setBounds(40, sideLength * height, 60, 40);
        JLabel end0 = new JLabel("exit:");
        frame.add(end0);
        end0.setBounds(100, sideLength * height, 40, 40);
        this.end1 = new JTextField();
        frame.add(this.end1);
        this.end1.setBounds(140, sideLength * height, 60, 40);
        JButton mark = new JButton("mark");
        frame.add(mark);
        mark.setBounds(sideLength * width - 210, sideLength * height, 70, 40);
        mark.addActionListener(new Maze.MarkListener());
        JButton find = new JButton("find");
        frame.add(find);
        find.setBounds(sideLength * width - 140, sideLength * height, 70, 40);
        find.addActionListener(new Maze.FindListener());
        JButton retry = new JButton("retry");
        frame.add(retry);
        retry.setBounds(sideLength * width - 70, sideLength * height, 70, 40);
        retry.addActionListener(new Maze.RetryListener());
        JLabel label = new JLabel("");
        frame.add(label);
        label.setBounds(0, sideLength * (height + 1), sideLength, sideLength);
        this.out = new JTextField();
        frame.add(this.out);
        this.out.setBounds(0, sideLength * (height + 1), frameWidth - 20, 40);
    }

    private int[] intOfStr(String str) {
        int[] result = new int[2];
        int index = str.indexOf(44);
        result[0] = Integer.parseInt(str.substring(1, index));
        result[1] = Integer.parseInt(str.substring(index + 1, str.length() - 1));
        return result;
    }

    private boolean isfit(int i, int standard) {
        return i > 0 && i < standard;
    }

    private static boolean findPath() {
        path = new MyMaze();
        Position[] offset = new Position[]{new Position(1, 0), new Position(0, 1), new Position(-1, 0), new Position(0, -1)};
        Position current = start;
        grid[current.x][current.y].isWall = true;
        int option = 0;
        int lastOption = 3;
        float red = 0.0F;
        float green = 1.0F - red;

        while(current.x != end.x || current.y != end.y) {
            int gridX = 0;

            int gridY;
            for(gridY = 0; option <= lastOption; ++option) {
                gridX = current.x + offset[option].x;
                gridY = current.y + offset[option].y;
                if (!grid[gridX][gridY].isWall) {
                    break;
                }
            }

            if (option <= lastOption) {
                path.push(current);
                grid[current.x][current.y].setBackground(new Color(red, green, 0.0F, 1.0F));
                red += 0.035F;
                if (red >= 1.0F) {
                    red = 1.0F;
                    green = 1.0F - red;
                }

                current = new Position(gridX, gridY);
                grid[current.x][current.y].isWall = true;
                option = 0;
            } else {
                if (path.isEmpty()) {
                    return false;
                }

                Position next = path.pop();
                grid[next.x][next.y].setBackground(Color.WHITE);
                if (next.y == current.y) {
                    option = 2 + next.x - current.x;
                } else {
                    option = (3 + next.y - current.y) % 3;
                }

                current = next;
            }
        }

        return true;
    }

    public static void main(String[] args) {
        new Maze(9, 9);
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
        if (this.isMousePressed) {
            if (e.getComponent().getBackground() == Color.BLACK) {
                e.getComponent().setBackground(Color.WHITE);
            } else if (e.getComponent().getBackground() == Color.WHITE) {
                e.getComponent().setBackground(Color.BLACK);
            }
        }

    }

    public void mouseExited(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
        this.isMousePressed = true;
        if (e.getComponent().getBackground() == Color.BLACK) {
            e.getComponent().setBackground(Color.WHITE);
        } else if (e.getComponent().getBackground() == Color.WHITE) {
            e.getComponent().setBackground(Color.BLACK);
        }

    }

    public void mouseReleased(MouseEvent e) {
        this.isMousePressed = false;
    }

    class FindListener implements ActionListener {
        FindListener() {
        }

        public void actionPerformed(ActionEvent arg0) {
            for(int i = 1; i < Maze.WIDTH - 1; ++i) {
                for(int j = 1; j < Maze.HEIGHT - 1; ++j) {
                    if (Maze.grid[i][j].getBackground() == Color.BLACK) {
                        Maze.grid[i][j].setWall();
                    }
                }
            }

            if (!Maze.findPath()) {
                Maze.this.out.setText("i cannot find the way");
            } else {
                Maze.this.out.setText("success");
            }

        }
    }

    class MarkListener implements ActionListener {
        MarkListener() {
        }

        public void actionPerformed(ActionEvent arg0) {
            String str1 = Maze.this.start1.getText();
            String str2 = Maze.this.end1.getText();
            int startX = Maze.this.intOfStr(str1)[0];
            int startY = Maze.this.intOfStr(str1)[1];
            if (!Maze.this.isfit(startX, Maze.WIDTH - 1)) {
                Maze.this.out.setText("未找到该点");
            } else if (!Maze.this.isfit(startY, Maze.HEIGHT - 1)) {
                Maze.this.out.setText("未找到该点");
            } else {
                Maze.start = new Position(startX, startY);
                Maze.grid[startX][startY].isWall = false;
                Maze.grid[startX][startY].setBackground(new Color(0.0F, 1.0F, 0.0F, 1.0F));
                int endX = Maze.this.intOfStr(str2)[0];
                int endY = Maze.this.intOfStr(str2)[1];
                if (!Maze.this.isfit(endX, Maze.WIDTH - 1)) {
                    Maze.this.out.setText("未找到该点");
                } else if (!Maze.this.isfit(endY, Maze.HEIGHT- 1)) {
                    Maze.this.out.setText("未找到该点");
                } else {
                    Maze.end = new Position(endX, endY);
                    Maze.grid[endX][endY].isWall = false;
                    Maze.grid[endX][endY].setBackground(Color.RED);
                }
            }
        }
    }

    class RetryListener implements ActionListener {
        RetryListener() {

        }

        public void actionPerformed(ActionEvent arg0) {
            for(int i = 1; i < Maze.WIDTH - 1; i++) {
                for(int j = 1; j < Maze.HEIGHT - 1; j++ ) {
                    Maze.grid[i][j].isWall = false;
                    Maze.grid[i][j].setBackground(Color.WHITE);
                    Maze.this.start1.setText("");
                    Maze.this.end1.setText("");
                    Maze.this.out.setText("");
                }
            }

        }
    }
}

特别提醒:
源代码来源于网络,进行了学习与简单的修改,仅此记录本次学习内容,方便以后再次学习,若发现有侵权行为,请私信博主,进行删除,谢谢。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值