课程设计:基于 A*搜索算法迷宫游戏开发

一.设计目标

游戏支持玩家走迷宫和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹;系统走迷宫路径要求基于 A*算法实现,输出走迷宫的最优路径并显示。设计交互友好的游戏图形界面。

二.算法思想

1.迷宫生成算法

1)深度优先遍历(生成主路扭曲型的迷宫)

1.将起点作为当前迷宫单元并标记为已访问;
2.当还存在未标记的迷宫单元,进行循环;

1.如果当前迷宫单元有未被访问过的的相邻的迷宫单元
a.随机选择一个未访问的相邻迷宫单元
b.将当前迷宫单元入栈
c.移除当前迷宫单元与相邻迷宫单元的墙
d.标记相邻迷宫单元并用它作为当前迷宫单元
2.如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空
a…栈顶的迷宫单元出栈
b.令其成为当前迷宫单元

2)prime算法(生成自然分岔型的迷宫)
在这里插入图片描述

1.随机取一个地图边缘的黄色1,把它标记为红色1,即变成通路。然后把它旁边的灰色0标记成蓝色0,表示“待定”。
2.随机选一个蓝色的0,然后看红色1隔着这个蓝色0对面的格子,是否是黄色的1:
a.如果是,则把对面的黄色1标记成红色1,即变成陆地,然后把蓝色0变成红色的0,即也变成陆地;
b.如果不是,就把这个蓝色的0变成灰色的0。
最后,把新创建的红色1周围的灰色0,标记成蓝色0。
3.继续重复上述步骤,直到整个地图没有蓝色0了,地图就生成完毕

2.迷宫寻路算法

转载:寻路算法小结
1)广度优先搜索算法

从图的某一结点出发,首先依次访问该结点的所有邻接结Vi1,Vi2,Vi3,……Vin,再按这些顶点被访问的先后次序依次访问与它们相邻接的所有未被访问的顶点,最后重复此过程,直至所有顶点均被访问位置。

2)dijkstra(迪杰斯特拉)算法

1、把V分成两组:
1)S:已求出最短路径的顶点的集合。
2)T=V-S:尚未确定最短路径的顶点集合。
2、将T中顶点按最短路径递增的次序加入到S中。

3)Greed-Best-First(最好优先贪婪算法)

起始节点记作S,目标节点记作E,对于任意节点G,从当前节点G到目标节点E的曼哈顿距离记作MG,优先队列openList中数据为(G,MG)(节点,当前节点到目标节点E的曼哈顿距离)。

1.将起始节点S放入openList,openList是一个优先队列,曼哈顿距离越小的节点,优先级越高。
2.判断openList是否为空,如果为空,搜索失败,目标节点E不可达;如果不为空,从openList中拿出优先级最高的节点G;
3.遍历节点G的上下左右四个相邻节点N1-N4,如果N在openList或closeList中,忽略节点N;否则,令N的父节点为G,计算N到E的曼哈顿距离MN,将(N,MN)放入openList。
4.判断节点G是不是目标节点E,如果是,搜索成功,获取节点G的父节点,并递归这一过程(继续获得父节点的父节点),直至找到初始节点S,从而获得从G到S的一条路径;否则,重复步骤2。

4)A*算法
转载:A*算法的介绍与动态演示

三.实现结果

在这里插入图片描述
在这里插入图片描述

四.代码实现

1.头文件
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;
2.节点类

用于表示A*算法中的节点

class Node {
   
    public int x,y;
    public Node parent;
    public Node(int x, int y) {
   
        this.x = x;
        this.y = y;
    }
    public int F;//F为估价函数
    public int G;//G代表的是从初始位置Start沿着已生成的路径到指定待检测结点移动开销
    public int H;//H表示待检测结点到目标节点B的估计移动开销
    public void calcF() {
   
        this.F = this.G + this.H;
    }//计算估价函数
}
3.主类

主类中包含了迷宫地图的生成(通过深度优先遍历实现)以及A*算法搜索路径

public class MyMaze extends JPanel implements KeyListener {
   
    //生成地图用到变量
    final static int wall =0; //代表墙
    final static int road =1; //代表空地
    static int num = 21; //迷宫长度
    int width = 20; //迷宫宽度
    static int [][] mMap; //迷宫
    boolean[][] visit; //用来标记某一格是否被访问过
    Node start = new Node(1,1); //开始节点
    Node end = new Node(num-2,num-2);//结束节点
    Node cur; //当前格
    Node next; //下一格
    Stack<Node> path = new Stack<>();//记录生成地图时遍历的顺序
    //走迷宫时用到的变量
    private Node movePerson;
    List<Integer> xPath=new ArrayList<>();//记录迷宫中行进的轨迹
    List<Integer> yPath=new ArrayList<>();
    private boolean drawPath = false;

    //A*算法使用到的变量
    public int sValue = 10;//设每一步的权值为10
    private ArrayList<Node> openList = new ArrayList<>();//维护一个开放列表
    private ArrayList<Node> closeList = new ArrayList<>();//维护一个关闭列表

    //初始化,初始化迷宫参数
    MyMaze(){
   
        mMap = new int [num][num];
        visit = new boolean[num][num];
        for (int i = 0; i < num; i = i+2) {
   //初始化地图的空格
            for (int j = 0; j < num; j=j+2){
   
                mMap[i][j] = wall;//其余均为墙
                visit[i][j] = false;
            }
        }
        for (int i = 1; i < num; i = i+2) {
   //初始化地图的空格
            for (int j = 1; j < num; j=j+2){
   
                mMap[i][j] = road;//奇数行奇数列的格子均为路
                visit[i][j] = false;
            }
        }
        visit[start.x][start.y] = true;
        mMap[start.x][start.y] = road;<
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值