前言
因为某些原因重启了这个项目,就重新梳理了一边项目,并且增加了一些功能。
原项目可见链接
一、运行效果
黄色(s)是起点
粉色(e)是终点
浅蓝色(s)是寻找过的路径
深蓝色(r)是找到的路径
二、代码
1.项目目录
2.代码
TestGUI.java
package main;
import util.Global;
import window.Window;
/**
* 测试类
*/
public class TestGUI {
public static void main(String[] args) {
Global.window = new Window();
Global.window.init();
}
}
Window.java
package window;
import javax.swing.*;
import java.util.Arrays;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import listener.*;
import util.*;
/**
* ui
*/
public class Window {
private JFrame frame;
private JPanel panel;
private Integer[] names;
private State[][] data;
private JTable table;
private JButton changeMap;
private JButton setStart;
private JButton setEnd;
private JButton setWall;
private JButton run;
private JButton recovery;
private JList<String> algorithms;
private JLabel algLabel;
private JLabel tip;
public boolean init() {
//创建窗口
frame = new JFrame("经典寻路算法演示");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
//frame.setLocation(200, 200);
frame.setLayout(null);
frame.setResizable(false);
//创建panel存放table
panel = new JPanel();
panel.setBounds(0, 0, Global.COL_WIDTH * Global.COL, Global.ROW_HEIGHT * Global.ROW);
frame.add(panel);
//新建table
names = new Integer[Global.COL];
Arrays.fill(names, 0);
data = new State[Global.ROW][Global.COL];
for (int i = 0; i < Global.ROW; i++) {
for (int j = 0; j < Global.COL; j++) {
data[i][j] = State.normal;
}
}
table = new SimpleTable(data, names);
//设置table的行高列宽
table.setRowHeight(Global.ROW_HEIGHT);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
for (int j = 0; j < table.getColumnCount(); j++) {
table.getColumnModel().getColumn(j).setPreferredWidth(Global.COL_WIDTH);
}
table.addMouseListener(new TableListener());
panel.add(table);
//设置按钮
changeMap = new JButton(Global.CHANGE_MAP);
changeMap.setBounds(Global.COL_WIDTH * Global.COL + 30, Global.ROW_HEIGHT * Global.ROW_HEIGHT - 150, 140, 40);
changeMap.addActionListener(new ButtonActionListener());
frame.add(changeMap);
recovery = new JButton(Global.RECOVERY);
recovery.setBounds(Global.COL_WIDTH * Global.COL + 30, Global.ROW_HEIGHT * Global.ROW_HEIGHT - 100, 140, 40);
recovery.addActionListener(new ButtonActionListener());
frame.add(recovery);
setStart = new JButton(Global.SET_STAT);
setStart.setBounds(Global.COL_WIDTH * Global.COL + 30, Global.ROW_HEIGHT * Global.ROW_HEIGHT -50, 140, 40);
setStart.addActionListener(new ButtonActionListener());
frame.add(setStart);
setEnd = new JButton(Global.SET_END);
setEnd.setBounds(Global.COL_WIDTH * Global.COL + 30, Global.ROW_HEIGHT * Global.ROW_HEIGHT, 140, 40);
setEnd.addActionListener(new ButtonActionListener());
frame.add(setEnd);
setWall = new JButton(Global.SET_WALL);
setWall.setBounds(Global.COL_WIDTH*Global.COL+30,Global.ROW_HEIGHT*Global.ROW_HEIGHT+50,140,40);
setWall.addActionListener(new ButtonActionListener());
frame.add(setWall);
run = new JButton(Global.RUN);
run.setBounds(Global.COL_WIDTH * Global.COL + 30, Global.ROW_HEIGHT * Global.ROW_HEIGHT + 100, 140, 40);
run.addActionListener(new RunListener());
frame.add(run);
//设置列表
String[] al = new String[]{"BFS算法","DFS算法","A*算法"};
algorithms = new JList<>(al);
algorithms.setFixedCellHeight(40);
algorithms.setBounds(Global.COL_WIDTH * Global.COL + 30, 20, 140, 150);
algorithms.addListSelectionListener(new ListListener());
frame.add(algorithms);
//设置label
algLabel = new JLabel("已选择BFS算法");
algLabel.setBounds(Global.COL_WIDTH * Global.COL + 40, 170, 140, 50);
frame.add(algLabel);
tip = new JLabel("请设置坐标");
tip.setBounds(Global.COL_WIDTH * Global.COL + 40, 200, 140, 50);
frame.add(tip);
frame.setVisible(true);
return true;
}
public void setAlgoLabelText(String str) {
algLabel.setText(str);
}
public void setTipText(String str) {
tip.setText(str);
}
public JFrame getFrame() {
return frame;
}
public void setFrame(JFrame frame) {
this.frame = frame;
}
public JPanel getPanel() {
return panel;
}
public void setPanel(JPanel panel) {
this.panel = panel;
}
public Integer[] getNames() {
return names;
}
public void setNames(Integer[] names) {
this.names = names;
}
public State[][] getData() {
return data;
}
public void setData(State[][] data) {
this.data = data;
}
public JTable getTable() {
return table;
}
public void setTable(JTable table) {
this.table = table;
}
public JButton getSetStart() {
return setStart;
}
public void setSetStart(JButton setStart) {
this.setStart = setStart;
}
public JButton getRun() {
return run;
}
public void setRun(JButton run) {
this.run = run;
}
public JList<String> getAlgorithms() {
return algorithms;
}
public void setAlgorithms(JList<String> algorithms) {
this.algorithms = algorithms;
}
public JLabel getAlgLabel() {
return algLabel;
}
public void setAlgLabel(JLabel algLabel) {
this.algLabel = algLabel;
}
}
Global.java
package util;
import window.Window;
/**
* 一些全局变量
*/
public class Global {
public static Window window;
public static final int ROW = 30;
public static final int COL = 30;
public static final int ROW_HEIGHT = 20;
public static final int COL_WIDTH = 20;
public static final String SET_STAT = "设置起点";
public static final String SET_END = "设置终点";
public static final String SET_WALL = "设置障碍";
public static final String CHANGE_MAP = "换地图";
public static final String RECOVERY = "复位";
public static final String RUN = "Run";
public static final String DFS = "DFS算法";
public static final String BFS = "BFS算法";
public static final String A = "A*算法";
public static Action action = Action.normal;
public static Algorithm algorithm = Algorithm.BFS;
public static int startNum = 0;
public static int endNum = 0;
public static int startRow = 0;
public static int startCol = 0;
public static int endRow = 0;
public static int endCol = 0;
public static Thread draw = null;
}
State.java
package util;
/**
* 表格单元格中的值(状态)
*/
public enum State {
normal,
start,
end,
wall,
road,
search
}
Action.java
package util;
/**
* 当前操作状态
*
* @author: lsxuan
* @email: 1146887979@qq.com
* @create: 2022-10-09 18:44
*/
public enum Action {
normal,
setSta,
setEnd,
setWall,
Recovery,
}
Algorithm.java
package util;
/**
* 选择的算法
*
* @author: lsxuan
* @email: 1146887979@qq.com
* @create: 2022-10-09 18:44
*/
public enum Algorithm {
DFS,//深度优先
BFS,//广度优先
A
}
SimpleTable.java
package util;
import javax.swing.*;
import java.awt.*;
/**
* 自定义表格样式
* 为了使单元格不能通过点击编辑
* 以及通过单元格的值渲染颜色
*/
public class SimpleTable extends JTable {
Color color = getForeground();
public SimpleTable(Object[][] rowData, Object[] columnNames) {
super(rowData, columnNames);
}
//设置table中值不可编辑
public boolean isCellEditable(int row, int col) {
return false;
}
@Override
public java.awt.Component prepareRenderer(javax.swing.table.TableCellRenderer renderer, int row, int column) {
int modelRow = convertRowIndexToModel(row);
int modelColumn = convertColumnIndexToModel(column);
java.awt.Component comp = super.prepareRenderer(renderer, row, column);
if (!isRowSelected(modelRow)) {
switch ((State) Global.window.getTable().getValueAt(modelRow, modelColumn)) {
case start:
comp.setBackground(Color.orange);
break;
case end:
comp.setBackground(Color.magenta);
break;
case road:
comp.setBackground(Color.BLUE);
break;
case search:
comp.setBackground(Color.cyan);
break;
case wall:
comp.setBackground(Color.BLACK);
break;
default:
comp.setBackground(Color.WHITE);
}
}
return comp;
}
}
Maze.java
package util.maze;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;
/**
* Maze
*
* 这部分借鉴了一个网上的代码,但是当时忘记留下链接了,现在找不到了。。。
*/
public class Maze {
private int len = 11; //迷宫长度
private int wid = 11; //迷宫宽度
private char wall = '■'; //代表墙
private char blank = '○'; //代表空地
private char[][] maze; //迷宫
private boolean[][] visit; //用来标记某一格是否被访问过
private Node start = new Node(0, 0); //开始节点
private Node exit = new Node(len - 1, wid - 1); //出口,其实现在也没什么用,因为没有交互只是生成了一个迷宫而已
private Node cur; //当前格
private Node next; //下
private Stack path = new Stack(); //表示路径的栈
private int[][] adj = {
{0, 2}, {0, -2}, {2, 0}, {-2, 0}
}; //用来计算邻接格
/**
* 迷宫的格子类
*
* @author Yan
*/
class Node {
int x, y;
public Node() {
}
public Node(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "Node [x=" + x + ", y=" + y + "]";
}
}
/**
* 初始化,初始化迷宫参数
*/
public void init() {
maze = new char[len][wid];
visit = new boolean[len][wid];
for (int i = 0; i < len; i++) {
for (int j = 0; j < wid; j++) {
maze[i][j] = wall;
visit[i][j] = false;
}
}
visit[start.x][start.y] = true;
maze[start.x][start.y] = blank;
cur = start; //将当前格标记为开始格
}
/**
* 打印结果
*/
public void printMaze() {
for (int i = 0; i < len; i++) {
for (int j = 0; j < wid; j++) {
System.out.print(maze[i][j] + " ");
}
System.out.println();
}
System.out.println("==========================================");
}
/**
* 开始制作迷宫
*/
public void makeMaze() {
path.push(cur); //将当前格压入栈
while (!path.empty()) {
Node[] adjs = notVisitedAdj(cur);//寻找未被访问的邻接格
if (adjs.length == 0) {
cur = (Node) path.pop();//如果该格子没有可访问的邻接格,则跳回上一个格子
continue;
}
next = adjs[new Random().nextInt(adjs.length)]; //随机选取一个邻接格
int x = next.x;
int y = next.y;
//如果该节点被访问过,则回到上一步继续寻找
if (visit[x][y]) {
cur = (Node) path.pop();
} else//否则将当前格压入栈,标记当前格为已访问,并且在迷宫地图上移除障碍物
{
path.push(next);
visit[x][y] = true;
maze[x][y] = blank;
maze[(cur.x + x) / 2][(cur.y + y) / 2] = blank; //移除当前格与下一个之间的墙
cur = next;//当前格等于下一格
}
}
}
/**
* 判断节点是否都被访问
*
* @param ns
* @return
*/
public boolean allVisited(Node[] ns) {
for (Node n : ns) {
if (!visit[n.x][n.y])
return false;
}
return true;
}
/**
* 寻找可访问的邻接格,这里可以优化,不用list
*
* @param node
* @return
*/
public Node[] notVisitedAdj(Node node) {
List list = new ArrayList();
for (int i = 0; i < adj.length; i++) {
int x = node.x + adj[i][0];
int y = node.y + adj[i][1];
if (x >= 0 && x < len && y >= 0 && y < wid) {
if (!visit[x][y])
list.add(new Node(x, y));
}
}
Node[] a = new Node[list.size()];
for (int i = 0; i < list.size(); i++) {
a[i] = (Node) list.get(i);
}
return a;
}
public int getLen() {
return len;
}
public void setLen(int len) {
this.len = len;
}
public int getWid() {
return wid;
}
public void setWid(int wid) {
this.wid = wid;
}
public char[][] getMaze() {
return maze;
}
/**
* 入口方法
*
* @param args
*/
public static void main(String[] args) {
Maze m = new Maze();
m.init();
m.makeMaze();
m.printMaze();
}
}
MazeUtil.java
package util.maze;
import util.Global;
/**
* TODO
*
* @author: lsxuan
* @email: 1146887979@qq.com
* @create: 2022-10-09 22:21
*/
public class MazeUtil {
public static int[][] getMap(){
int raw = Global.ROW;
int col = Global.COL;
Maze maze = new Maze();
maze.setLen(raw-3);
maze.setWid(col-1);
maze.init();
maze.makeMaze();
//maze.printMaze();
char[][] mazeContent = maze.getMaze();
int[][] result = new int[30][30];
for (int i = 0; i < raw; i++) {
for (int j = 0; j < col; j++) {
if(j==0||j==raw-1||i==0||i==col-1||i==col-2||i==col-3){
result[i][j]=1;
} else if (mazeContent[i-1][j-1]=='■') {
result[i][j]=1;
}else if (mazeContent[i-1][j-1]=='○'){
result[i][j]=0;
}
}
}
return result;
}
public static void main(String[] args) {
int[][] re = getMap();
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 30; j++) {
System.out.print(re[i][j]+" ");
}
System.out.print("\n");
}
}
}
Algorithm.java
package algorithm;
import util.Global;
import util.State;
import java.util.List;
import java.util.Set;
/**
* 算法父类
*
* @author: lsxuan
* @email: 1146887979@qq.com
* @create: 2022-10-09 18:48
*/
public abstract class Algorithm {
/**
* 计算路径
* @param startRow
* @param startCol
* @param endRow
* @param endCol
* @return
*/
abstract public List<Point> compute(int startRow, int startCol, int endRow, int endCol);
/**
* 在ui上渲染路径
* @param road
*/
public static void drawRoad(List<Point> road) {
try {
for (int i = 1; i < road.size() - 1; i++) {
State state = (State) Global.window.getTable().getValueAt(road.get(i).row, road.get(i).col);
if (state == State.normal){
Global.window.getTable().setValueAt(State.search, road.get(i).row, road.get(i).col);
Thread.sleep(300);
}
}
Thread.sleep(1000);
} catch (InterruptedException e) {
}
Point p = road.get(road.size() - 1);
while (p.parent != null) {
p = p.parent;
State state = (State) Global.window.getTable().getValueAt(p.row, p.col);
if (state == State.normal || state == State.search)
Global.window.getTable().setValueAt(State.road, p.row, p.col);
}
}
/**
* 判断一个点是否能走
* @param row
* @param col
* @return
*/
public static boolean isWalkable(int row, int col) {
if (row < 1 || row > Global.ROW - 2 || col < 1 || col > Global.COL - 2) return false;
if (Global.window.getTable().getValueAt(row, col) == State.wall) return false;
return true;
}
/**
* 获取所有邻接的点(能走的)
* @param point
* @return
*/
public abstract Set<Point> getAdjacentPoints(Point point);
}
Point.java
package algorithm;
/**
* 表示一个点
*
* @author: lsxuan
* @email: 1146887979@qq.com
* @create: 2022-10-09 18:49
*/
public class Point {
//坐标
public int row;
public int col;
//路径上的前序结点
public Point parent;
//A*算法中的代价
public int F;
public int G;
public int H;
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("(").append(row).append(",").append(col).append(")->(").append(parent == null ? "null" : parent.row)
.append(",").append(parent == null ? "null" : parent.col).append(")").append(F).append(",").append(G)
.append(",").append(H);
return sb.toString();
}
public Point(int row, int col, int G, int H, Point parent) {
this.row = row;
this.col = col;
this.G = G;
this.H = H;
this.F = G + H;
this.parent = parent;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return row == point.row && col == point.col;
}
}
BFS.java
package algorithm;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* BFS算法
*
* @author: lsxuan
* @email: 1146887979@qq.com
* @create: 2022-10-09 18:51
*/
public class BFS extends Algorithm {
@Override
public List<Point> compute(int startRow, int startCol, int endRow, int endCol) {
//(1)把初始节点S0放入Open表, 建立一个CLOSED表,置为空;
//(2)检查Open表是否为空表,若为空,则问题无解,失败退出;
//(3)把Open表的第一个节点取出放入Closed表,并记该节点为n;
//(4)考察节点n是否为目标节点,若是则得到问题的解成功退出;
//(5)若节点n不可扩展,则转第(2)步;
//(6)扩展节点n, 将其子节点放入Open表的尾部,并为每个子节点设置指向父节点的指针, 转向第(2)步。
Point end = null;
List<Point> close = new ArrayList<Point>();
List<Point> open = new ArrayList<Point>();
Point start = new Point(startRow, startCol, 0, 10 * (Math.abs(startCol - endCol) + Math.abs(startRow - endRow)), null);
open.add(start);
while (!open.isEmpty()) {
Point min = open.get(0);
close.add(min);
System.out.println(min);
//util.Global.window.getTable().setValueAt(util.State.road,min.row,min.col);
open.remove(0);
Set<Point> adjacentPoints = getAdjacentPoints(min);
for (Point po :adjacentPoints) {
if(close.contains(po))continue;
boolean flag = false;
for (Point temp1 :
open) {
if (temp1.equals(po)) {
flag = true;
}
}
if (!flag ) {
open.add(po);
}
}
end = null;
for (Point temp :
open) {
if (temp.row == endRow && temp.col == endCol) {
end = temp;
}
}
if (end != null) {
close.add(end);
break;
}
}
if(close.get(close.size()-1).col!=endCol||close.get(close.size()-1).row!=endRow){
close=null;
}
return close;
}
@Override
public Set<Point> getAdjacentPoints(Point point) {
Set<Point> result = new HashSet<>();
if (isWalkable(point.row + 1, point.col + 1))
result.add(new Point(point.row + 1, point.col + 1,0,0,point));
if (isWalkable(point.row + 1, point.col))
result.add(new Point(point.row + 1, point.col, 0,0,point));
if (isWalkable(point.row + 1, point.col - 1))
result.add(new Point(point.row + 1, point.col - 1, 0,0,point));
if (isWalkable(point.row, point.col + 1))
result.add(new Point(point.row, point.col + 1, 0,0,point));
if (isWalkable(point.row, point.col - 1))
result.add(new Point(point.row, point.col - 1, 0,0,point));
if (isWalkable(point.row - 1, point.col + 1))
result.add(new Point(point.row - 1, point.col + 1, 0,0,point));
if (isWalkable(point.row - 1, point.col))
result.add(new Point(point.row - 1, point.col, 0,0,point));
if (isWalkable(point.row - 1, point.col - 1))
result.add(new Point(point.row - 1, point.col - 1, 0,0,point));
return result;
}
}
DFS.java
package algorithm;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* DFS算法
*
* @author: lsxuan
* @email: 1146887979@qq.com
* @create: 2022-10-09 18:50
*/
public class DFS extends Algorithm {
@Override
public List<Point> compute(int startRow, int startCol, int endRow, int endCol) {
//(1)把初始节点S0放入Open表, 建立一个CLOSED表,置为空;
//(2)检查Open表是否为空表,若为空,则问题无解,失败退出;
//(3)把Open表的最后一个节点取出放入Closed表,并记该节点为n;
//(4)考察节点n是否为目标节点,若是则得到问题的解成功退出;
//(5)若节点n不可扩展,则转第(2)步;
//(6)扩展节点n, 将其子节点放入Open表的首部,并为每个子节点设置指向父节点的指针, 转向第(2)步。
Point end = null;
List<Point> close = new ArrayList<Point>();
List<Point> open = new ArrayList<Point>();
Point start = new Point(startRow, startCol, 0, 10 * (Math.abs(startCol - endCol) + Math.abs(startRow - endRow)), null);
open.add(start);
while (!open.isEmpty()) {
Point min = open.get(open.size()-1);
close.add(min);
System.out.println(min);
//util.Global.window.getTable().setValueAt(util.State.road,min.row,min.col);
open.remove(open.size()-1);
Set<Point> adjacentPoints = getAdjacentPoints(min);
for (Point po :adjacentPoints) {
if(close.contains(po))continue;
boolean flag = false;
for (Point temp1 :
open) {
if (temp1.equals(po)) {
flag = true;
}
}
if (!flag ) {
open.add(po);
}
}
end = null;
for (Point temp :
open) {
if (temp.row == endRow && temp.col == endCol) {
end = temp;
}
}
if (end != null) {
close.add(end);
break;
}
}
if(close.get(close.size()-1).col!=endCol||close.get(close.size()-1).row!=endRow){
close=null;
}
return close;
}
@Override
public Set<Point> getAdjacentPoints(Point point) {
Set<Point> result = new HashSet<>();
if (isWalkable(point.row + 1, point.col + 1))
result.add(new Point(point.row + 1, point.col + 1,0,0,point));
if (isWalkable(point.row + 1, point.col))
result.add(new Point(point.row + 1, point.col, 0,0,point));
if (isWalkable(point.row + 1, point.col - 1))
result.add(new Point(point.row + 1, point.col - 1, 0,0,point));
if (isWalkable(point.row, point.col + 1))
result.add(new Point(point.row, point.col + 1, 0,0,point));
if (isWalkable(point.row, point.col - 1))
result.add(new Point(point.row, point.col - 1, 0,0,point));
if (isWalkable(point.row - 1, point.col + 1))
result.add(new Point(point.row - 1, point.col + 1, 0,0,point));
if (isWalkable(point.row - 1, point.col))
result.add(new Point(point.row - 1, point.col, 0,0,point));
if (isWalkable(point.row - 1, point.col - 1))
result.add(new Point(point.row - 1, point.col - 1, 0,0,point));
return result;
}
}
A.java
package algorithm;
import java.util.*;
/**
* A*算法
*
* @author: lsxuan
* @email: 1146887979@qq.com
* @create: 2022-10-09 18:49
*/
public class A extends Algorithm {
@Override
public List<Point> compute(int startRow, int startCol, int endRow, int endCol) {
//int startRow,startCol,endRow,endCol;
Point end = null;
List<Point> close = new ArrayList<Point>();
List<Point> open = new ArrayList<Point>();
Point start = new Point(startRow, startCol, 0, 10 * (Math.abs(startCol - endCol) + Math.abs(startRow - endRow)), null);
open.add(start);
while (!open.isEmpty()) {
Point min = open.get(0);
close.add(min);
System.out.println(min);
//util.Global.window.getTable().setValueAt(util.State.road,min.row,min.col);
open.remove(0);
Set<Point> adjacentPoints = getAdjacentPoints(min, endRow, endCol);
for (Point temp :
adjacentPoints) {
if (close.contains(temp)) continue;
boolean flag = false;
Point temp2 = null;
for (Point temp1 :
open) {
if (temp1.equals(temp)) {
flag = true;
temp2 = temp1;
}
}
if (flag && temp2 != null) {
if (temp.G < temp2.G) {
open.remove(temp2);
open.add(temp);
}
} else {
open.add(temp);
}
}
Collections.sort(open, new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
return Integer.compare(o1.F, o2.F);
}
});
end = null;
for (Point temp :
open) {
if (temp.row == endRow && temp.col == endCol) {
end = temp;
}
}
if (end != null) {
close.add(end);
break;
}
}
if(close.get(close.size()-1).col!=endCol||close.get(close.size()-1).row!=endRow){
close=null;
}
return close;
}
@Override
public Set<Point> getAdjacentPoints(Point point) {
return null;
}
public Set<Point> getAdjacentPoints(Point point, int endRow, int endCol) {
Set<Point> result = new HashSet<>();
if (isWalkable(point.row + 1, point.col + 1))
result.add(new Point(point.row + 1, point.col + 1, point.G + 14, 10 * (Math.abs(point.row + 1 - endRow) + Math.abs(point.col + 1 - endCol)), point));
if (isWalkable(point.row + 1, point.col))
result.add(new Point(point.row + 1, point.col, point.G + 10, 10 * (Math.abs(point.row + 1 - endRow) + Math.abs(point.col - endCol)), point));
if (isWalkable(point.row + 1, point.col - 1))
result.add(new Point(point.row + 1, point.col - 1, point.G + 14, 10 * (Math.abs(point.row + 1 - endRow) + Math.abs(point.col - 1 - endCol)), point));
if (isWalkable(point.row, point.col + 1))
result.add(new Point(point.row, point.col + 1, point.G + 10, 10 * (Math.abs(point.row - endRow) + Math.abs(point.col + 1 - endCol)), point));
if (isWalkable(point.row, point.col - 1))
result.add(new Point(point.row, point.col - 1, point.G + 10, 10 * (Math.abs(point.row - endRow) + Math.abs(point.col - 1 - endCol)), point));
if (isWalkable(point.row - 1, point.col + 1))
result.add(new Point(point.row - 1, point.col + 1, point.G + 14, 10 * (Math.abs(point.row - 1 - endRow) + Math.abs(point.col + 1 - endCol)), point));
if (isWalkable(point.row - 1, point.col))
result.add(new Point(point.row - 1, point.col, point.G + 10, 10 * (Math.abs(point.row + 1 - endRow) + Math.abs(point.col - endCol)), point));
if (isWalkable(point.row - 1, point.col - 1))
result.add(new Point(point.row - 1, point.col - 1, point.G + 14, 10 * (Math.abs(point.row - 1 - endRow) + Math.abs(point.col - 1 - endCol)), point));
return result;
}
}
ButtonActionListener.java
package listener;
import util.Action;
import util.Global;
import util.State;
import util.maze.MazeUtil;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 按钮按压事件监听
*/
public class ButtonActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//System.out.println(e.getActionCommand());
JTable table = Global.window.getTable();
String cmd = e.getActionCommand();
switch (cmd) {
case Global.SET_STAT:
Global.action = Action.setSta;
Global.window.setTipText("设置开始位置坐标");
break;
case Global.SET_END:
Global.action = Action.setEnd;
Global.window.setTipText("设置结束位置坐标");
break;
case Global.RECOVERY:
if (Global.draw != null) Global.draw.interrupt();
Global.action = Action.normal;
Global.startNum = 0;
Global.endNum = 0;
for (int i = 0; i < Global.ROW; i++) {
for (int j = 0; j < Global.COL; j++) {
table.setValueAt(State.normal, i, j);
}
}
Global.window.setTipText("恢复地图");
break;
case Global.SET_WALL:
Global.action = Action.setWall;
Global.window.setTipText("设置障碍");
break;
case Global.CHANGE_MAP:
if (Global.draw != null) Global.draw.interrupt();
Global.action = Action.normal;
Global.startNum = 0;
Global.endNum = 0;
int[][] map = MazeUtil.getMap();
for (int i = 0; i < Global.ROW; i++) {
for (int j = 0; j < Global.COL; j++) {
if (map[i][j] == 0) table.setValueAt(State.normal, i, j);
else table.setValueAt(State.wall, i, j);
}
}
Global.window.setTipText("随机生成地图");
break;
}
System.out.println(Global.action);
}
}
ListListener.java
package listener;
import util.Algorithm;
import util.Global;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/**
* ui右上角算法列表点击时间监听
*/
public class ListListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent e) {
//System.out.println(
String cmd = Global.window.getAlgorithms().getSelectedValue();
System.out.println(cmd);
switch (cmd) {
case Global.DFS:
Global.algorithm = Algorithm.DFS;
Global.window.getAlgLabel().setText("已选择DFS算法");
break;
case Global.BFS:
Global.algorithm = Algorithm.BFS;
Global.window.getAlgLabel().setText("已选择BFS算法");
break;
case Global.A:
Global.algorithm = Algorithm.A;
Global.window.getAlgLabel().setText("已选择A*算法");
break;
}
}
}
RunListener.java
package listener;
import algorithm.A;
import algorithm.BFS;
import algorithm.DFS;
import algorithm.Point;
import algorithm.Algorithm;
import util.Action;
import util.Global;
import util.State;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
/**
* run按钮的点击时间监听
*/
public class RunListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Global.window.setTipText("开始运行");
JTable table = Global.window.getTable();
for (int i = 0; i < Global.ROW; i++) {
for (int j = 0; j < Global.COL; j++) {
if(table.getValueAt(i, j) == State.road||table.getValueAt(i, j) == State.search)table.setValueAt(State.normal, i, j);
}
}
if (!(Global.endNum == 1 && Global.startNum == 1)) return;
Global.action = Action.normal;
Algorithm run = null;
switch (Global.algorithm) {
case DFS:
run = new DFS();
break;
case BFS:
run = new BFS();
break;
case A:
run = new A();
break;
}
List<Point> road = run.compute(Global.startRow, Global.startCol, Global.endRow, Global.endCol);
if(road==null){
Global.window.setTipText("此题无解");
return;
}
System.out.println(road);
Global.draw = new Thread(new java.lang.Runnable() {
@Override
public void run() {
//Global.window.setTipText("猴子向箱子寻找");
Algorithm.drawRoad(road);
}
});
Global.draw.start();
}
}
TableListener.java
package listener;
import util.Global;
import util.State;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* ui上表格的点击事件监听
*/
public class TableListener implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
int col = Global.window.getTable().getSelectedColumn();
int row = Global.window.getTable().getSelectedRow();
//System.out.println("("+x+","+y+")");
JTable table = Global.window.getTable();
switch (Global.action) {
case setSta:
if (table.getValueAt(row, col) == State.start) {
Global.startNum = 0;
table.setValueAt(State.normal, row, col);
break;
}
if (Global.startNum == 0&&table.getValueAt(row, col) == State.normal) {
if (table.getValueAt(row, col) == State.end) {
Global.endNum = 0;
}
table.setValueAt(State.start, row, col);
Global.startNum++;
Global.startRow = row;
Global.startCol = col;
Global.window.setTipText("开始位置坐标已设置");
}
break;
case setEnd:
if (table.getValueAt(row, col) == State.end) {
Global.endNum = 0;
table.setValueAt(State.normal, row, col);
break;
}
if (Global.endNum == 0&&table.getValueAt(row, col) == State.normal) {
if (table.getValueAt(row, col) == State.start) {
Global.startNum = 0;
}
table.setValueAt(State.end, row, col);
Global.endNum++;
Global.endRow = row;
Global.endCol = col;
Global.window.setTipText("结束位置坐标已设置");
}
break;
case setWall:
if(table.getValueAt(row, col) == State.wall){
table.setValueAt(State.normal, row, col);
}else {
table.setValueAt(State.wall,row,col);
}
if ( table.getValueAt(row, col) == State.start) {
Global.startNum = 0;
}
if ( table.getValueAt(row, col) == State.end) {
Global.endNum = 0;
}
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
总结
没啥总结的,就不说了