返回顶部
首页 > 资讯 > 后端开发 > Python >如何利用JAVA实现走迷宫程序
  • 656
分享到

如何利用JAVA实现走迷宫程序

2024-04-02 19:04:59 656人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

本Demo使用三个类 一个Test类 一个自定义的Stack类 一个自定义的Queue类 可以实现的功能: 1.对于一个写在文本文件中的迷宫,能够将其转换为二维数组用广度优先搜索实现

本Demo使用三个类

一个Test类

一个自定义的Stack类

一个自定义的Queue类

可以实现的功能:

1.对于一个写在文本文件中的迷宫,能够将其转换为二维数组用广度优先搜索实现查找最短路径

2.可以不定义迷宫的入口和出口,能自动查找到出入口

前提是要有一个对应路径的.txt文件

这里举个例子吧,我的是"F:/1号迷宫(0,18).txt"路径下

运行结果

示例代码

注释写的很详细,这里就不多赘述了


package com;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;


public class Test {
    public static void main(String[] args) throws Exception {
        Test test = new Test();
        //通过文件输入流得到二维数组
        char[][] arr = test.getFile("F:/1号迷宫(0,18).txt");
        System.out.println("二维数组的长度为:"+arr[0].length);
        int deep = test.getDeepByChar(arr);
        System.out.println("二维数组的深度为:"+deep);

        //找到入口位置
        int [] begin = test.begin(arr);
        System.out.println("入口位置:("+begin[0]+","+begin[1]+")");
        //找到出口位置
        int [] end = test.end(arr,deep);
        System.out.println("出口位置:("+end[0]+","+end[1]+")");
        System.out.println("=================================打印二维数组============================================");
        //打印二维数组
        test.printArr(arr,deep);
        System.out.println("=================================最短路径图展示===========================================");
        //求最短路径图
        int[][] bfs = test.bfs(arr,begin,end,deep);
        for (int i = 0; i < deep; i++) {
            for (int j = 0; j < bfs[0].length; j++) {
                System.out.print(bfs[i][j]+"\t");
            }
            System.out.println();
        }
        System.out.println("================================最短路径===============================================");
        //根据最短路径图得到最短路径
        int[][] result = test.getLoaderFromMap(bfs, begin, end, deep);
        //得到result的深度
        int deep1 = test.getDeepByInt(result);
        for (int i = 0; i < deep1; i++) {
            System.out.println("("+result[i][0]+","+result[i][1]+")\t");
        }
    }

    //求最短路径图
    public int[][] bfs(char [][] arr, int [] begin, int [] end,int deep) {
        //移动的四个方向
        int[] dx = {1, 0, -1, 0};
        int[] dy = {0, 1, 0, -1};
        //d二维数组用来表示路径图
        int[][] d = new int [deep][arr[0].length];
        //储存未进行处理的节点,这里LinkedList实现了Deque,Deque又继承了Queue
        Queue1<int[]> que = new Queue1<>();
//        Queue<int []> que = new LinkedList<>();
        //将所有的位置都初始化为最大
        for(int i = 0; i < d.length; i++) {
            for(int j = 0; j < d[0].length; j++) {
                d[i][j] = -1;
            }
        }
        //将起始点放入队列
        que.offer(begin);
        //将起始点最短路径设为0
        d[begin[0]][begin[1]] = 0;
        //一直循环直到队列为空
        while(!que.isEmpty()) {
            //取出队列中最前端的点
            int [] current = que.poll();
            //如果是终点则结束
            if(current[0] == end[0] && current[1] == end[1]){
                break;
            }
            //四个方向循环
            for(int i = 0; i < 4; i++) {
                //试探
                int nx = current[0] + dx[i];
                int ny = current[1] + dy[i];
                //判断是否可以走
                if(nx >= 0 && nx < deep && ny >= 0 && ny < d[0].length  && arr[nx][ny] == '0' && d[nx][ny] == -1) {
                    //如果可以走,则将该点的距离加1
                    d[nx][ny] = d[current[0]][current[1]] + 1;
                    //并将该点放入队列等待下次处理
                    int[] c = {nx, ny};
                    que.offer(c);
                }
            }
        }
        return d;
    }

    //根据最短路径图得到最短路径
    private int [][] getLoaderFromMap(int [][] map,int [] begin,int [] end,int deep) {
        int k = 0;//标志位
        //创建二维数组最终正序存储结果
        int[][] resultList = new int[map.length * map.length][2];
        //result数组存储每个正确位置的下标
        int[] result;
        //创建一个栈,从出口开始把位置压入栈,之后再遍历栈就是正的迷宫顺序
        Stack1<int[]> stack = new Stack1<>();
        //先把出口压入栈
        stack.push(end);
        //移动的四个方向
        int[] dx = {1, 0, -1, 0};
        int[] dy = {0, 1, 0, -1};
        //已知出口和入口,从出口逆推入口
        //只要出口没有和入口下标重合,就一直循环
        while(true){
            //获得栈中最顶层元素,不取出
            int[] current = stack.peek();
            for (int i = 0; i < 4; i++) {
                //试探
                int nx = current[0] + dx[i];
                int ny = current[1] + dy[i];
                //如果当前节点不是入口节点,就继续向前追溯
                if(map[current[0]][current[1]] != map[begin[0]][begin[1]]){
                    //判断是否可以走
                    if (nx >= 0 && nx < deep && ny >= 0 && ny < map[0].length && map[nx][ny] != -1) {
                        //从后往前追溯,前一个数值一定比后一个小1
                        if(map[nx][ny] == map[current[0]][current[1]]-1){
                            //如果可以走,将此节点入栈
                            result = new int[]{nx, ny};
                            stack.push(result);
                        }
                    }
                }else{
                    k++;
                    break;
                }
            }
            //k是为了打破最外层循环,在比较map[current[0]][current[1]] != map[begin[0]][begin[1]]时
            //如果当前节点等于入口时,就应该打破循环,但是while和for是两重循环,所以加一个标志位再打破一次
            if(k != 0){
                break;
            }
        }

        //取出栈中元素赋给resultList
        int len = stack.length();
        for(int i = 0;i < len;i++){
            result = stack.pop();
            resultList[i][0] = result[0];
            resultList[i][1] = result[1];
        }
        return resultList;
    }

    //把文件中的二进制转换为二维数组
    private char[][] getFile (String pathName) throws Exception {
        File file = new File(pathName);
        //文件不存在时抛出异常
        if (!file.exists())
            throw new RuntimeException("Not File!");
        //字符缓冲输入流//缓冲流是处理流,要先new一个字符输入流
        BufferedReader br = new BufferedReader(new FileReader(file));
        //字符串str用来存储一行数据
        String str;
        //初始化一个二维数组
        char[][] arr = new char[110][];
        //x用来记录读取的行数
        int x = 0;
        while ((str = br.readLine()) != null) {
            x++;
            //把字符串变成字符数组存储
            char[] cArr = str.toCharArray();
            //把一行字符数组加入到二维数组中
            arr[x - 1] = cArr;
        }
        br.close();
        return arr;
    }

    //找到入口位置
    private int[] begin ( char[][] arr){
        //存储起点的下标begin[0]=x,begin[1]=y
        int[] begin = new int[2];
        //用StringBuffer把数组转为字符串,方便找到其中的元素
        StringBuffer s = new StringBuffer();
        for (int i = 0; i < arr[0].length; i++) {
            s.append(arr[0][i]);
        }
        //如果入口在第一行
        //判断下标是否存在
        if (s.indexOf("0") != -1) {
            begin[0] = 0;
            begin[1] = s.indexOf("0");
            return begin;
        } else {
            //如果入口在第一列
            for (int i = 0; i < arr.length; i++) {
                if (arr[i][0] == '0') {
                    begin[0] = i;
                    begin[1] = 0;
                    return begin;
                }
            }
        }
        return begin;
    }

    //找到出口位置
    private int[] end ( char[][] arr, int deep){
        //存储出口的下标end[0]=x,end[1]=y
        int[] end = new int[2];
        //出口在最后一列上     //18是第二个表的深度
        for (int i = 0; i < deep; i++) {
            //最后一列上找到出口
            if (arr[i][arr[0].length - 1] == '0') {
                end[0] = i;
                end[1] = arr[0].length - 1;
                return end;
            }
        }
        //出口在最后一行上
        for (int i = 0; i < arr.length; i++) {
            //最后一行上找到出口    //deep为最后一行的下标
            if (arr[deep - 1][i] == '0') {
                end[0] = deep - 1;
                end[1] = i;
                return end;
            }
        }
        return end;
    }

    
    //得到二维数组有效深度
    private int getDeepByChar ( char[][] arr){
        int y = 0;//深度
        for (int i = 0; i < arr.length; i++) {
            //由于i可能越界,当i越界时就认为到达最底部,返回当前y值
            try {
                //如果第一列那行数据不为1或0,就认为此行无效
                if (arr[i][0] != '1' && arr[i][0] != '0') {
                    break;
                }
            } catch (Exception e) {
                return y;
            }
            y++;
        }
        return y;
    }

    //得到二维整形数组有效深度
    private int getDeepByInt ( int[][] arr){
        int y = 0;//深度
        for (int i = 0; i < arr.length; i++) {
            //如果遇到(0,0)的,认为已经失效
            if (arr[i][0] == 0 && arr[i][1] == 0) {
                break;
            }
            y++;
        }
        return y;
    }

    //打印二维数组
    private void printArr ( char[][] arr, int deep){
        for (int i = 0; i < arr[0].length; i++) {
            for (int j = 0; j < deep; j++) {
                try {
                    System.out.print(arr[i][j] + "\t");
                } catch (Exception e) {
                }
            }
            System.out.println();
        }
    }
}


class Queue1<E> {
    private E[] arr;//使用数组表示一个队列
    private int size;//size表示队列中有效元素个数
    private int putIndex=-1;//putIndex表示从队列中放数的索引始终从队首取,并且取得索引始终为arr[0]

    //有参构造
    protected Queue1(int initSize){
        if(initSize < 0){
            throw new IllegalArgumentException("参数错误");
        }
        arr = (E[])new Object[initSize];
        size = 0;
    }
    //无参构造,默认10个长度大小
    protected Queue1(){
        this(110);
    }

    //入队
    protected void offer(E e){
        if(size == arr.length) {
            throw new ArrayIndexOutOfBoundsException("无法进行push操作,队列已满");
        }
        arr[++putIndex] = e;
        size++;
    }

    //判断队列是否为空
    protected boolean isEmpty(){
        return size == 0?true:false;
    }

    //出队
    protected E poll() {
        if (size == 0) {
            throw new ArrayIndexOutOfBoundsException("This queue is empty!当前队列为空");
        }
        E tmp = arr[0];
        //后面的元素向前移动
        for (int i = 0; i < size - 1; i++) {
            arr[i] = arr[i + 1];
        }
        arr[size - 1] = null;
        putIndex--;
        size--;
        return tmp;
    }
}


class Stack1<E> {
    private int maxSize;//最大长度
    private int top = -1;//栈顶指针,初始指向-1
    private E[] data;//数组代替栈存放元素

    //初始化栈大小
    protected Stack1(int maxSize){
        if(maxSize > 0){
            this.maxSize = maxSize;
            //data数组对象也要初始化大小
            data = (E[])new Object[maxSize];
        }else{
            throw new IllegalArgumentException("初始化栈大小失败,参数不合法");
        }
    }

    //默认初始化大小为10
    protected Stack1(){
        //调用有参构造,传入10
        this(10);
    }

    //入栈
    protected boolean push(E e){
        //先判断栈是否已满
        if(top == maxSize-1){
            //扩容
            this.resize();
        }
        //先top++,再top = e
        data [++top] = e;
        return true;
    }

    //判断栈是否为空
    protected boolean isEmpty(){
        return top == -1;
    }

    //得到栈的长度
    protected int length(){
        return top+1;
    }
    //出栈
    protected E pop(){
        //先判断栈是否为空
        if(top == -1){
            throw new IllegalArgumentException("栈当前为空");
        }
        else{
            E e = data[top];
            //先top = null,再top--
            data[top--] = null;
            return  e;
        }
    }

    //查看栈顶元素
    protected E peek(){
        //先判断栈是否为空
        if(top == -1){
            throw new IllegalArgumentException("栈当前为空");
        }else{
            return data[top];
        }
    }

    //栈扩容,默认扩容为原来的一倍
    protected void resize(){
        int newSize = maxSize*2;
        E[] newData = (E[])new Object[newSize];
        for (int i = 0;i < data.length;i ++){
            newData[i] = data[i];
        }
        //刷新最大长度
        maxSize = newSize;
        //再把newData赋值给data数组
        data = newData;
    }
}

总结

到此这篇关于如何利用JAVA实现走迷宫程序的文章就介绍到这了,更多相关JAVA走迷宫程序内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 如何利用JAVA实现走迷宫程序

本文链接: https://lsjlt.com/news/129223.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何利用JAVA实现走迷宫程序
    本Demo使用三个类 一个Test类 一个自定义的Stack类 一个自定义的Queue类 可以实现的功能: 1.对于一个写在文本文件中的迷宫,能够将其转换为二维数组用广度优先搜索实现...
    99+
    2024-04-02
  • C++ DFS算法如何实现走迷宫自动寻路
    小编给大家分享一下C++ DFS算法如何实现走迷宫自动寻路,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!C++ DFS算法实现走迷宫自动寻路,供大家参考,具体内容...
    99+
    2023-06-15
  • Java实现可视化走迷宫小游戏的示例代码
    目录效果图数据层视图层控制层效果图 数据层 本实例需要从 .txt 文件中读取迷宫并绘制,所以先来实现文件读取IO类 MazeData.java,该程序在构造函数运行时将外部文件...
    99+
    2022-11-13
    Java走迷宫游戏 Java 迷宫游戏 Java 迷宫
  • Java如何实现经典游戏复杂迷宫
    这篇文章主要为大家展示了“Java如何实现经典游戏复杂迷宫”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java如何实现经典游戏复杂迷宫”这篇文章吧。前言人类建造迷宫已有5000年的历史。在世界...
    99+
    2023-06-29
  • 如何使用数据结构写个Html5走迷宫游戏
    这篇文章主要为大家展示了“如何使用数据结构写个Html5走迷宫游戏”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用数据结构写个Html5走迷宫游戏”这篇文...
    99+
    2024-04-02
  • Python如何实现迷宫生成器
    这篇文章主要介绍了Python如何实现迷宫生成器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python如何实现迷宫生成器文章都会有所收获,下面我们一起来看看吧。首先展示一下效果图:我们先分析一下所需的库:既...
    99+
    2023-07-02
  • Matlab利用prim算法实现迷宫的生成
    目录代码使用迷宫生成映射图多起点完整代码最近比较忙更新频率也慢了下来,今天带来一个比较有趣的可视化,基于prim算法的迷宫生成并用距离生成图片: 我通过各种向量化编程编写了一个...
    99+
    2022-11-13
    Matlab prim算法生成迷宫 Matlab prim算法 Matlab 迷宫
  • 如何使用Python实现多路径迷宫
    小编给大家分享一下如何使用Python实现多路径迷宫,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!python的数据类型有哪些python的数据类型:1. 数字类...
    99+
    2023-06-14
  • 如何实现一个canvas迷宫游戏
    小编给大家分享一下如何实现一个canvas迷宫游戏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!正文实现这个小游戏也不难,让我们想想,一个迷宫游戏有哪些基本要素。...
    99+
    2023-06-09
  • Python如何实现过迷宫小游戏
    小编给大家分享一下Python如何实现过迷宫小游戏,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!开发工具Python版本: 3.6.4相关模块:pygame模块;以及一些Python自带的模块。环境搭建安装Python并添...
    99+
    2023-06-22
  • 详解如何利用Python绘制迷宫小游戏
    目录构思绘制迷宫走出迷宫完整代码更大的挑战关于坐标系设置周末在家,儿子闹着要玩游戏,让玩吧,不利于健康,不让玩吧,扛不住他折腾,于是想,不如一起搞个小游戏玩玩! 之前给他编过猜数字 ...
    99+
    2024-04-02
  • 使用OpenCV实现迷宫解密的全过程
    目录一、你能自己走出迷宫吗?二、使用OpenCV找出出口。1、对图像进行二值化处理。2、 对二值化后的图像进行轮廓检测并标注3、对图像阈值进行处理。4、对图像进行扩展操作。...
    99+
    2024-04-02
  • 如何用Python进行编程迷宫大阵
    如何用Python进行编程迷宫大阵,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。前言由外国人编写的freegames是一个免费的开源游戏集合,这个很方便了我们的开发简单的游戏,...
    99+
    2023-06-02
  • 微信小程序如何实现九宫格
    这篇文章将为大家详细讲解有关微信小程序如何实现九宫格,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。微信小程序 九宫格实现效果图:小程序是长在微信上的,是移动端的界面,为了...
    99+
    2024-04-02
  • 如何利用CSS实现九宫格布局
    今天就跟大家聊聊有关如何利用CSS实现九宫格布局,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。最近几天刷面经常看见一道题,“九宫格布局”。自己尝试用...
    99+
    2024-04-02
  • 如何利用java实现归并排序
    什么是归并排序?归并排序是利用递归与分治的技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归方法将排好序的半子表合并成越来越大的有序序列。核心思想将两个有序的数列合并成一个大的有序的序列。通过递归,层层合并,即为归并。(推荐...
    99+
    2018-05-27
    java入门 java 归并排序
  • 微信小程序如何实现走马灯式抽奖
    今天小编给大家分享一下微信小程序如何实现走马灯式抽奖的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。先来看下效果设置奖项awa...
    99+
    2023-06-30
  • 利用Java如何实现同步线程
    利用Java如何实现同步线程?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。线程的同步是保证多线程安全访问竞争资源的一种手段。线程的同步是Java多线程编程的难点...
    99+
    2023-05-31
    java 线程 线程同步
  • 如何利用PDB实现Python程序调试
    本篇内容介绍了“如何利用PDB实现Python程序调试”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!如何进行Python程序调试 1.加入断...
    99+
    2023-06-17
  • 利用JCTools怎么实现Java并发程序
    本篇文章给大家分享的是有关利用JCTools怎么实现Java并发程序,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。非阻塞算法传统上,在可变共享状态下工作的多线程代码使用锁来确保...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作