实验三 用java语言开发迷宫

本文介绍了一个使用Java进行迷宫生成和A*算法寻路的实验。实验要求包括随机生成迷宫、玩家行走并留下足迹以及系统通过A*算法寻找路径。在前期准备中,详细阐述了深度优先遍历(DFS)生成迷宫的步骤,以及A*算法的原理。文章还展示了相关代码,并给出了实验结果。
摘要由CSDN通过智能技术生成

一、 实验要求

1、迷宫随机生成
2、玩家走迷宫,留下足迹
3、系统用A*算法寻路,输出路径 

二、前期准备

解决迷宫问题要用到两个算法,深度优先遍历(DFS)生成迷宫,A*算法寻路。那么首先要对这两种算法有清晰的了解。 

1.深度优先遍历(DFS)

 基于深度优先遍历的随机迷宫生成,我自己的理解简而言之可以分为以下几步:
a. 建立一张地图,用二维数组表示,地图上全是障碍物。然后再创建一个用来表示每个格子是否被访问过的二维数组。再创建一个用来表示路径的栈结构。
b.随机选择地图上的一点,为了方便我初始点直接取的是左上角即坐标表示为(0,0)的格子。终点的话因为不涉及到交互就暂时没有。
c.查找当前格子的邻接格(注意,这里的邻接格子都是还未被访问的)。随机选择一个邻接格子为下一 格,当前格移动到下一格,标记当前格为已访问,将当前格压入路径栈中。一直重复第三步操作。
d.在第三步操作中,如果当前格子不存在可访问的邻接格,则将栈顶的元素弹出,即退回上一步操作,如果栈为空,则结束程序,打印结果。

2.A*算法

公式表示为: f(n)=g(n)+h(n),
其中, f(n) 是从初始状态经由状态n到目标状态的代价估计,
g(n) 是在状态空间中从初始状态到状态n的实际代价,
h(n) 是从状态n到目标状态的最佳路径的估计代价。
(对于路径搜索问题,状态就是图中的节点,代价就是距离)

 三、代码展示

AStart类:

import java.util.ArrayList;
import java.util.List;

class AStart {
    public static int[][] NODES;//定义一个迷宫单元数组
    public  int STEP = 10;//设每一步的权值为10
    private ArrayList<Node> openList = new ArrayList<Node>();//维护一个开放列表
    private ArrayList<Node> closeList = new ArrayList<Node>();//维护一个关闭列表

    public AStart() {
        NODES=Maze.LabId;//初始化迷宫单元为新生成的对应地图,把Maze2类里面生成的地图传给NODES,再在此地图基础上用A*算法寻路径
        Node startNode = new Node(1, 1);//起点
        Node endNode = new Node(19, 19);//终点
        Node parent = findPath(startNode, endNode); //父节点
        ArrayList<Node> arrayList = new ArrayList<Node>();
        while (parent != null) {
            arrayList.add(new Node(parent.x, parent.y));
            parent = parent.parent;
        }

        //打印有路径的地图,在控制台输出查看
        System.out.println("\n"+"打印有路径的地图:");
        for (int i = 0; i < NODES.length; i++) {
            for (int j = 0; j < NODES.length; j++) {
                if (exists(arrayList, i, j)) {
                    NODES[i][j]=2;//标记关闭列表里的方格为2,为了方便后面在界面画系统寻路路径
                }
                System.out.print(NODES[i][j] + " ");
            }
            System.out.println();
        }
    }

    //寻找开放列表里F值最小的节点的方法
    public Node findMinFNodeInOpneList() {
        Node tempNode = openList.get(0);
        for (Node node : openList) {
            if (node.F < tempNode.F) {
                tempNode = node;
            }
        }
        return tempNode;
    }

    //遍历当前节点上下左右四个邻居的方法,
    public ArrayList<Node> findNeighborNodes(Node currentNode) {
        ArrayList<Node> arrayList = new ArrayList<Node>();
        // 只考虑上下左右,不考虑斜对角
        int topX = currentNode.x;
        int topY = currentNode.y - 1;
        if (canReach(topX, topY) && !exists(closeList, topX, topY)) {
            arrayList.add(new Node(topX, topY));
        }
        int bottomX = currentNode.x;
        int bottomY = currentNode.y + 1;
        if (canReach(bottomX, bottomY) && !exists(closeList, bottomX, bottomY)) {
            arrayList.add(new Node(bottomX, bottomY));
        }
        int leftX = currentNode.x - 1;
        int leftY = currentNode.y;
        if (canReach(leftX, leftY) && !exists(closeList, leftX, leftY)) {
            arrayList.add(new Node(leftX, leftY));
        }
        int rightX = currentNode.x + 1;
        int
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值