java图的深度优先遍历实现随机生成迷宫

最近经常在机房看同学在玩一个走迷宫的游戏,比较有趣,自己也用java写一个实现随机生成迷宫的算法,其实就是一个图的深度优先遍历算法.基本思想就是,迷宫中的每个点都有四面墙,然后呢。

1、从任意一点开始访问(我的算法中固定是从(0,0)点开始),往四个方向中的随机一个访问(每访问到一个可访问的点,就去掉该点的那个方向的墙),被访问点继续以这种方识向下进行访问。
2、对每个被访问的点都被标识为已访问,当一个点对某个方向进行访问时我们首先会判断被访问点是否已被访问,或者触到边界.如果该点四个方向皆已访问或已无法访问,就退回上一个点。上一个点继续这个过程。

这样一次遍历下来,可以确定每个点都被访问过,而且由于每次访问的方向都是随机,这就会形成许多不同遍历情况,同时每两个点之间的路径是唯一,也就形成不同的迷宫,且是起点到终点只有唯一路径,这是由于图的深度遍历算法的特点所决定的。算法的实现上,主要是利用栈,第一次,先把第一个点压进栈里,每访问到一个点,就把该点压进栈里,我们再对栈顶的点进行四个方向的随机访问,访问到新点,又把新点压进去,一旦这个点四个方向都无法访问了,就让该点退栈,再对栈顶的点的四个方向进行访问,以此类推,直到栈里的点都全部退出了,我们的遍历就成功了,这是一个递归的过程,这个算法自然可以用递归的方法来实现,不过这里我这样做,而是手工用一个数组作为栈来实现,呵呵~~说了这么多,也不知道自己要表达的有没表达出来。不过我感觉我的具体代码设计还是写的不好,还有很多地方缺乏完善和优化,权当是算法练习,以下是两个关键类的核心代码,至于表示层的代码就不贴出来了,因为那些都很琐碎。

下面是效果图:

迷宫的类:

//作者:zhongZw
//邮箱:zhong317@126.com
package cn.zhongZw.model;
import java.util.ArrayList;
import java.util.Random;
public class MazeModel {
  private int width = 0;
  private int height = 0;
  private Random rnd = new Random(); 

  public MazeModel() {
    this.width = 50; //迷宫宽度
    this.height = 50; //迷宫高度
  }
  public int getWidth() {
    return width;
  }
  public void setWidth(int width) {
    this.width = width;
  }
  public int getHeight() {
    return height;
  }
  public void setHeight(int height) {
    this.height = height;
  }
  public MazeModel(int width, int height) {
    super();
    this.width = width;
    this.height = height;
  }
  public ArrayList < MazePoint > getMaze() {
    ArrayList < MazePoint > maze = new ArrayList < MazePoint > ();
    for (int h = 0; h < height; h++) {
      for (int w = 0; w < width; w++) {
        MazePoint point = new MazePoint(w, h);
        maze.add(point);
      }
    }
    return CreateMaze(maze);
  }
  private ArrayList < MazePoint > CreateMaze(ArrayList < MazePoint > maze) {
    int top = 0;
    int x = 0;
    int y = 0;
    ArrayList < MazePoint > team = new ArrayList < MazePoint > ();
    team.add(maze.get(x + y * width));
    while (top >= 0) {
      int[] val = new int[] {
        -1, -1, -1, -1
      };
      int times = 0;
      boolean flag = false;
      MazePoint pt = (MazePoint) team.get(top);
      x = pt.getX();
      y = pt.getY();
      pt.visted = true; 

      ro1: while (times < 4) {
        int dir = rnd.nextInt(4);
        if (val[dir] == dir)
          continue;
        else
          val[dir] = dir; 

        switch (dir) {
        case 0: // 左边
          if ((x - 1) >= 0 && maze.get(x - 1 + y * width).visted == false) {
            maze.get(x + y * width).setLeft();
            maze.get(x - 1 + y * width).setRight();
            team.add(maze.get(x - 1 + y * width));
            top++;
            flag = true;
            break ro1; 

          }
          break;
        case 1: // 右边
          if ((x + 1) < width && maze.get(x + 1 + y * width).visted == false) { 

            maze.get(x + y * width).setRight();
            maze.get(x + 1 + y * width).setLeft();
            team.add(maze.get(x + 1 + y * width));
            top++;
            flag = true;
            break ro1;
          }
          break;
        case 2: // 上边
          if ((y - 1) >= 0 && maze.get(x + (y - 1) * width).visted == false) {
            maze.get(x + y * width).setUp();
            maze.get(x + (y - 1) * width).setDown();
            team.add(maze.get(x + (y - 1) * width));
            top++;
            flag = true;
            break ro1;
          }
          break;
        case 3: // 下边
          if ((y + 1) < height && maze.get(x + (y + 1) * width).visted == false) {
            maze.get(x + y * width).setDown();
            maze.get(x + (y + 1) * width).setUp();
            team.add(maze.get(x + (y + 1) * width));
            top++;
            flag = true;
            break ro1;
          }
          break;
        }
        times += 1;
      }
      if (!flag) {
        team.remove(top);
        top -= 1;
      } 

    } 

    return maze;
  }
} 

迷宫

//作者:zhongZw
//邮箱:zhong317@126.com
package cn.zhongZw.model;
import java.util.*;
import java.lang.*;
public class MazePoint {
  private int left = 0;
  private int right = 0;
  private int up = 0;
  private int down = 0;
  private int x;
  private int y;
  public boolean visted;
  public MazePoint(int x, int y) {
    this.x = x;
    this.y = y;
  }
  public int getLeft() {
    return left;
  } 

  public void setLeft() {
    this.left = 1;
  }
  public int getRight() {
    return right;
  }
  public void setRight() {
    this.right = 1;
  }
  public int getUp() {
    return up;
  } 

  public void setUp() {
    this.up = 1;
  }
  public int getDown() {
    return down;
  } 

  public void setDown() {
    this.down = 1;
  }
  public int getX() {
    return x;
  }
  public void setX(int x) {
    this.x = x;
  }
  public int getY() {
    return y;
  }
  public void setY(int y) {
    this.y = y;
  } 

} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • java实现单词搜索迷宫游戏
  • Java编写迷宫小游戏
  • Java遗传算法之冲出迷宫
  • Java实现走迷宫回溯算法
  • 使用栈的迷宫算法java版代码
(0)

相关推荐

  • Java遗传算法之冲出迷宫

    遗传算法是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法.它能解决很多问题,比如数学方程的最大最小值,背包问题,装箱问题等.在游戏开发中遗传算法的应用也十分频繁,不少的游戏 AI 都利用遗传算法进行编码. 就个人理解,遗传算法是模拟神奇的大自然中生物"优胜劣汰"原则指导下的进化过程,好的基因有更多的机会得到繁衍,这样一来,随着繁衍的进行,生物种群会朝着一个趋势收敛.而生物繁衍过程中的基因杂交和变异会给种群提供更好的基因序列

  • Java实现走迷宫回溯算法

    以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍.设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论. (1) 根据二维数组,输出迷宫的图形. (2) 探索迷宫的四个方向:RIGHT为向右,DOWN向下,LEFT向左,UP向上,输出从入口到出口的行走路径. 例子: 左上角(1,1)为入口,右下角(8,9)为出口. 可使用回溯方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进:否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通

  • java实现单词搜索迷宫游戏

    本文实例讲述了java实现单词搜索迷宫游戏.分享给大家供大家参考.具体分析如下: 我们在杂志上,经常能够看到找单词的小游戏,在一个二维表格中,存在各种字母,我们可以从八个方向找单词.这个用计算机处理十分方便,但是,算法的好坏很重要,因为要是用蛮力算法实现,那么耗费的时间是不可想象的. 这是数据结构与问题求解Java语言描述一书中给的实现思路 完整代码如下,注释写的很明白了 import java.io.BufferedReader; import java.io.FileReader; impo

  • Java编写迷宫小游戏

    缘起: 去年(大三上学期)比较喜欢写小游戏,于是想试着写个迷宫试一下. 程序效果: 按下空格显示路径: 思考过程: 迷宫由一个一个格子组成,要求从入口到出口只有一条路径. 想了一下各种数据结构,似乎树是比较合适的,从根节点到每一个子节点都只有一条路径.假设入口是根节点,出口是树中某个子节点,那么,从根节点到该子节点的路径肯定是唯一的. 所以如果能构造一棵树把所有的格子都覆盖到,也就能够做出一个迷宫了. 另外还要求树的父节点和子节点必须是界面上相邻的格子. 在界面显示时,父节点和子节点之间共用的边

  • 使用栈的迷宫算法java版代码

    本文为大家分享了使用栈的迷宫算法java版,主要考察栈的使用,供大家参考,具体内容如下 主要思路如下: do { if(当前位置可通过) { 标记此位置已走过; 保存当前位置并入栈; if(当前位置为终点) { 程序结束; } 获取下一个位置; } else { if(栈非空) { 出栈: while(当前位置方向为4且栈非空) { 标记当前位置不可走; 出栈; } if(当前位置的方向小于4) { 方向+1; 重新入栈; 获取下一个位置; } } } } while (栈非空); java代码

  • java图的深度优先遍历实现随机生成迷宫

    最近经常在机房看同学在玩一个走迷宫的游戏,比较有趣,自己也用java写一个实现随机生成迷宫的算法,其实就是一个图的深度优先遍历算法.基本思想就是,迷宫中的每个点都有四面墙,然后呢. 1.从任意一点开始访问(我的算法中固定是从(0,0)点开始),往四个方向中的随机一个访问(每访问到一个可访问的点,就去掉该点的那个方向的墙),被访问点继续以这种方识向下进行访问. 2.对每个被访问的点都被标识为已访问,当一个点对某个方向进行访问时我们首先会判断被访问点是否已被访问,或者触到边界.如果该点四个方向皆已访

  • Java编程实现深度优先遍历与连通分量代码示例

    深度优先遍历 深度优先遍历类似于一个人走迷宫: 如图所示,从起点开始选择一条边走到下一个顶点,没到一个顶点便标记此顶点已到达. 当来到一个标记过的顶点时回退到上一个顶点,再选择一条没有到达过的顶点. 当回退到的路口已没有可走的通道时继续回退. 而连通分量,看概念:无向图G的极大连通子图称为G的连通分量( Connected Component).任何连通图的连通分量只有一个,即是其自身,非连通的无向图有多个连通分量. 下面看看具体实例: package com.dataStructure.gra

  • PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能

    本文实例讲述了PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能.分享给大家供大家参考,具体如下: <?php $n=$_REQUEST["n"]; if($n>8) { echo "{$n}太大了,影响服务器性能"; return; } define("N",$n); $d=array(); $v=array(); for($i=0;$i<=N;$i++){ $d[$i]=$v[$i]=0; } function

  • Python实现随机生成迷宫并自动寻路

    Python深搜版: 核心在于带随机的深搜(见代码第23到27行,其实也可以用22行代替这几行代码,你可以试着把第24行的数字4改大或者改小,即调整随机程度) import os import random from queue import Queue import numpy import colorama from colorama import Fore, Back, Style import sys from bmpEditor import bmp colorama.init() #

  • C++实现随机生成迷宫地牢

    可以用这个地图核心做成一个无限迷宫类的游戏 main.cpp // Author: FreeKnight 2014-09-02 #include "stdafx.h" #include <iostream> #include <string> #include <random> #include <cassert> /* 简单逻辑流程描述: 将整个地图填满土 在地图中间挖一个房间出来 选中某一房间(如果有多个的话)的墙壁 确定要修建某种新

  • Java基于深度优先遍历的随机迷宫生成算法

    这两天因为要做一个随机的地图生成系统,所以一直在研究随机迷宫生成算法,好吧,算是有一点小小的成果. 随机迷宫生成我自己的理解简而言之分为以下几步: 1.建立一张地图,我用的二维数组表示,地图上全是障碍物.然后再创建一个用来表示每个格子是否被访问过的二维数组.再创建一个用来表示路径的栈结构. 2.随机选择地图上的一点,呃为了方便我初始点直接取的是左上角即坐标表示为0,0的格子.终点的话因为不涉及到交互就暂时没有. 3.查找当前格子的邻接格(注意,这里的邻接格子都是还未被访问的,下面的代码里有写).

  • Java实现二叉树的深度优先遍历和广度优先遍历算法示例

    本文实例讲述了Java实现二叉树的深度优先遍历和广度优先遍历算法.分享给大家供大家参考,具体如下: 1. 分析 二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列. 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历.中序遍历.后序遍历.具体说明如下: 先序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树. 中序遍历:对任一子树,先遍历其左子树,然

  • PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解

    本文实例讲述了PHP实现二叉树深度优先遍历(前序.中序.后序)和广度优先遍历(层次).分享给大家供大家参考,具体如下: 前言: 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历.中序遍历.后序遍历.具体说明如下: 前序遍历:根节点->左子树->右子树 中序遍历:左子树->根节点->右子树 后序遍历:左子树->右子树->根节点 广度优先遍历:又叫层次遍历,从上往下对每一层依

  • C++控制台实现随机生成路径迷宫游戏

    本程序是在控制台下随机生成迷宫路径的一个C++程序,可以通过修改宏定义 M 和 N 的值来修改迷宫的长度和宽度,运行程序后 按1开始游戏 按2退出游戏,游戏入口在左上角,出口在右下角,人物(星星)到达右下角出口提示成功闯关. #include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h> #include<iostream.h> #include<ctime

  • C++随机生成迷宫算法

    本文实例为大家分享了C++随机生成迷宫的具体代码,供大家参考,具体内容如下 我们今天来做一个迷宫游戏.在其中有几个要领: 1.方向的控制 我们建立的迷宫是以坐标的形式出现的,越往上x坐标越小,越往左y坐标越小,这雨平面直角坐标系不同,要注意! 2.随机生成算法: void init_maze(void); //初始化迷宫 void gotoxy(int x, int y); //移动光标 void path_up(int *x, int *y); //上构路径 void path_down(in

随机推荐