精华内容
下载资源
问答
  • 2022-02-08 11:02:08

    前言

    人类建造迷宫已有5000年的历史。在世界的不同文化发展时期,这些奇特的建筑物始终吸引人们沿着弯弯曲曲、困难重重的小路吃力地行走,寻找真相。迷宫类小游戏应运而生。在游戏中,迷宫被表现为冒险舞台里,藏有各式各样奇妙与谜题或宝藏的危险区域。型态有洞窟、人工建筑物、怪物巢穴、密林或山路等。迷宫内有恶徒或凶猛的生物(真实存在或想像物体都有)徘徊,其中可能会有陷阱、不明设施、遗迹等。

    《复杂迷宫》游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。

    主要需求

    方向键控制移动,角色走出迷宫,游戏胜利。增加游戏难度和增加随机地图。

    主要设计

    1、构建游戏地图面板

    2、设定迷宫地图,包含可走的通道,不可走的墙体,还有出口位置

    3、键盘的上下左右按键,来控制角色的移动

    4、角色移动的算法,通道可走,遇到墙体不可走

    5、走到终点,有成功通关的提示。

    6、增加游戏的难度选择,难度1,难度2和难度3

    7、每次生成的地图是随机的

    8、地图大小可选择,迷宫的长在10-45之间,宽在10-90之间

    9、增加撞墙的音乐效果

    功能截图

    游戏开始页面

    image-20220129174410386

    生成难度1,10*10的迷宫地图

    image-20220129174512645

    随机地图:生成难度1,10*10的迷宫地图

    image-20220129174702816

    生成难度2,30*30的迷宫地图

    image-20220129175031301

    生成难度3,90*45的迷宫地图

    image-20220129174959062

    成功过关-效果

    image-20220129174804206

    代码实现

    窗口布局

    public class StartView extends JFrame {
        public StartView() {
            this.setTitle("复杂迷宫");
            this.setSize(240, 265);
            this.setLocationRelativeTo(null);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            this.setResizable(false);
            initialize();
            this.setVisible(true);
        }
    
        private void initialize() {
            JPanel contentPane = new JPanel();
            this.setContentPane(contentPane);
            contentPane.setLayout(null);
    
            JLabel widthLabel = new JLabel("迷宫长度:");
            JLabel heightLabel = new JLabel("迷宫高度:");
            JLabel levelLabel = new JLabel("难度:");
            JTextField widthText = new JTextField();
            JTextField heightText = new JTextField();
            JRadioButton level1 = new JRadioButton("1");
            JRadioButton level2 = new JRadioButton("2");
            JRadioButton level3 = new JRadioButton("3");
            ButtonGroup levelGroup = new ButtonGroup();
            levelGroup.add(level1);
            levelGroup.add(level2);
            levelGroup.add(level3);
            JButton run = new JButton("生成迷宫");
    
            // 设定标签位置
            widthLabel.setBounds(20, 20, 100, 30);
            heightLabel.setBounds(20, 70, 110, 30);
            widthText.setBounds(120, 20, 70, 30);
            heightText.setBounds(120, 70, 70, 30);
            levelLabel.setBounds(20, 120, 60, 30);
            level1.setBounds(80, 120, 50, 30);
            level2.setBounds(130, 120, 50, 30);
            level3.setBounds(180, 120, 50, 30);
            run.setBounds(55, 170, 120, 30);
    
            // 限制输入框只接收数字
            widthText.setDocument(new NumberTextField());
            heightText.setDocument(new NumberTextField());
    
            // 改变字体
            Font font = new Font("楷体", Font.PLAIN, 17);
            widthLabel.setFont(font);
            heightLabel.setFont(font);
            widthText.setFont(font);
            heightText.setFont(font);
            levelLabel.setFont(font);
            level1.setFont(font);
            level2.setFont(font);
            level3.setFont(font);
            run.setFont(font);
    
            // 取消按钮选中边框
            level1.setFocusPainted(false);
            level2.setFocusPainted(false);
            level3.setFocusPainted(false);
    
            // 默认选择难度3
            level3.setSelected(true);
    
            contentPane.add(widthLabel);
            contentPane.add(heightLabel);
            contentPane.add(widthText);
            contentPane.add(heightText);
            contentPane.add(levelLabel);
            contentPane.add(level1);
            contentPane.add(level2);
            contentPane.add(level3);
            contentPane.add(run);
    
            // 生成迷宫监听器
            run.addActionListener(e -> {
                // 建议宽在10-90,长在10-45之间
                if (widthText.getText().equals("")) {
                    JOptionPane.showMessageDialog(null, "长度不能为空!", "提示", JOptionPane.INFORMATION_MESSAGE);
                } else if (heightText.getText().equals("")) {
                    JOptionPane.showMessageDialog(null, "高度不能为空!", "提示", JOptionPane.INFORMATION_MESSAGE);
                } else {
                    int width = Integer.parseInt(widthText.getText());
                    int height = Integer.parseInt(heightText.getText());
                    if (width >= 10 && width <= 90 && height >= 10 && height <= 45) {
                        int level = level1.isSelected() ? 1 : level2.isSelected() ? 2 : 3;
                        MazeModel maze = new MazeModel(width, height, level);
                        this.dispose();
                        maze.draw();
                    } else {
                        JOptionPane.showMessageDialog(null, "迷宫的长必须在10-45之间,宽必须在10-90之间,请检查输入是否有误!", "错误输入", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            // 添加回车键入监听器
            KeyAdapter enterAdapter = new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        run.doClick();   // 回车即生成迷宫
                    }
                }
            };
            widthText.addKeyListener(enterAdapter);
            heightText.addKeyListener(enterAdapter);
        }
    
        public static void main(String[] args) {
            new StartView();
        }
    }
    
    
    

    迷宫的数学模型

    public class MazeModel {
        private int width;
        private int height;
        private ArrayList<MazePoint> mazePoints;
    
        /**
         * 迷宫的构造方法
         *
         * @param width  迷宫的宽度
         * @param height 迷宫的
         * @param level  1 -> 递归分割算法生成迷宫,2 -> 递归回溯算法生成迷宫,3 -> 普里姆算法生成迷宫
         */
        public MazeModel(int width, int height, int level) {
            super();
            this.width = width;
            this.height = height;
            switch (level) {
                case 1 : this.mazePoints = recursiveDivision();
                case 2 : this.mazePoints = recursiveBacktracker();
                case 3 : this.mazePoints = prim();
            }
        }
    
        /**
         * 递归回溯生成迷宫
         *
         * @return 生成的迷宫的单元格集合
         */
        private ArrayList<MazePoint> recursiveBacktracker() {
            ArrayList<MazePoint> maze = new ArrayList<>();
            // 初始化所以单元格都被强包围
            for (int h = 0; h < height; h++) {
                for (int w = 0; w < width; w++) {
                    MazePoint point = new MazePoint(w, h, true);
                    maze.add(point);
                }
            }
            // 建立一个存放操作单元格的栈
            Stack<MazePoint> stack = new Stack<>();
            // 选择(0,0)点作为起始点,开始打通迷宫
            stack.push(maze.get(0));
            maze.get(0).visited = true;
    
            Random random = new Random();
            int x;   // 操作单元格的横坐标
            int y;   // 操作单元格的纵坐标
            int direction;   // 方向
            while (!stack.empty()) {
                // 选择栈顶元素作为当前操作数
                MazePoint operatingPoint = stack.peek();
                x = operatingPoint.getX();
                y = operatingPoint.getY();
    
                direction = random.nextInt(4);
                MazePoint adjacency;
    
                switch (direction) {
    
                    case 0: // 左边
                        if ((x - 1) >= 0) {   // 判断左边是否为边缘
                            adjacency = maze.get(x - 1 + y * width);   // 判断左边单元格是否被访问过
                            if (!adjacency.visited) {
                                operatingPoint.setLeft(0);   // 打通操作单元格的左墙,和左边单元格的右墙
                                adjacency.setRight(0);
                                stack.push(adjacency);    // 将左墙入栈,作为下次循环的操作单元格
                                adjacency.visited = true;    // 将左边的单元格设置为访问过了
                                x--;   // 改变操作单元格的坐标,方便后面判断当前单元格四周是否都访问过
                            }
                        }
                        break;
                    case 1: // 右边
                        // 注释参照case0
                        if ((x + 1) < width) {
                            adjacency = maze.get(x + 1 + y * width);
                            if (!adjacency.visited) {
                                operatingPoint.setRight(0);
                                adjacency.setLeft(0);
                                stack.push(adjacency);
                                adjacency.visited = true;
                                x++;
                            }
                        }
                        break;
                    case 2: // 上边
                        // 注释参照case0
                        if ((y - 1) >= 0) {
                            adjacency = maze.get(x + (y - 1) * width);
                            if (!adjacency.visited) {
                                operatingPoint.setUp(0);
                                adjacency.setDown(0);
                                stack.push(adjacency);
                                adjacency.visited = true;
                                y--;
                            }
                        }
                        break;
                    case 3: // 下边
                        // 注释参照case0
                        if ((y + 1) < height) {
                            adjacency = maze.get(x + (y + 1) * width);
                            if (!adjacency.visited) {
                                operatingPoint.setDown(0);
                                adjacency.setUp(0);
                                stack.push(adjacency);
                                adjacency.visited = true;
                                y++;
                            }
                        }
                        break;
                }
    
                // 若操作单元格四周都被访问过,将该单元格出栈。
                if ((x - 1 < 0 || maze.get(x - 1 + y * width).visited)
                        && (x + 1 >= width || maze.get(x + 1 + y * width).visited)
                        && (y - 1 < 0 || maze.get(x + (y - 1) * width).visited)
                        && (y + 1 >= height || maze.get(x + (y + 1) * width).visited)) {
                    stack.pop();
                }
            }
    
            maze.get(0).setLeft(0);    // 左上角开墙作为入口
            maze.get(width * height - 1).setRight(0);    // 右下角开墙作为出口
            return maze;
        }
    
        /**
         * 分割迷宫区域
         *
         * @param maze  单元格集合
         * @param right 区域的宽
         * @param top   区域的高
         */
        private void divide(ArrayList<MazePoint> maze, int left, int right, int top, int down) {
            if (right - left > 0 && top - down > 0) {
                // 在区域中心”十“字筑墙
                for (int x = left, y = (top - down) / 2 + down; x <= right; x++) {
                    maze.get(x + y * this.width).setDown(1);
                    maze.get(x + (y + 1) * this.width).setUp(1);
                }
                for (int x = (right - left) / 2 + left, y = down; y <= top; y++) {
                    maze.get(x + y * this.width).setRight(1);
                    maze.get(x + 1 + y * this.width).setLeft(1);
                }
    
                // 在“十”字墙中选其中三个方向拆一面墙
                Random random = new Random();
                int direction = random.nextInt(4);
                int x = (right - left) / 2 + left;
                int y = (top - down) / 2 + down;
                int tempX;
                int tempY;
                if (direction != 0) {    // 打通一面左边的墙
                    if (x - left > left) {
                        tempX = random.nextInt(x - left + 1) + left;
                    } else {
                        tempX = left;
                    }
                    tempY = y;
                    maze.get(tempX + tempY * this.width).setDown(0);
                    maze.get(tempX + (tempY + 1) * this.width).setUp(0);
                }
                if (direction != 1) {    // 打通一面右边的墙
                    if (right - (x + 1) > x + 1) {
                        tempX = random.nextInt(right - (x + 1) + 1) + x + 1;
                    } else {
                        tempX = x + 1;
                    }
                    tempY = y;
                    maze.get(tempX + tempY * this.width).setDown(0);
                    maze.get(tempX + (tempY + 1) * this.width).setUp(0);
                }
                if (direction != 2) {    // 打通一面上面的墙
                    tempX = x;
                    if (y - down > down) {
                        tempY = random.nextInt(y - down + 1) + down;
                    } else {
                        tempY = down;
                    }
                    maze.get(tempX + tempY * this.width).setRight(0);
                    maze.get(tempX + 1 + tempY * this.width).setLeft(0);
                }
                if (direction != 3) {    // 打通一面下面的墙
                    tempX = x;
                    if (top - (y + 1) > y + 1) {
                        tempY = random.nextInt(top - (y + 1) + 1) + y + 1;
                    } else {
                        tempY = y + 1;
                    }
                    maze.get(tempX + tempY * this.width).setRight(0);
                    maze.get(tempX + 1 + tempY * this.width).setLeft(0);
                }
    
                maze.stream().limit(this.width).forEach(m -> m.setUp(1));
                maze.stream().skip((this.height - 1) * this.width).forEach(m -> m.setDown(1));
                maze.stream().filter(m -> m.getX() == 0).forEach(m -> m.setLeft(1));
                maze.stream().filter(m -> m.getX() == width - 1).forEach(m -> m.setRight(1));
                divide(maze, left, (right - left) / 2 + left, (top - down) / 2 + down, down);
                divide(maze, left, (right - left) / 2 + left, top, (top - down) / 2 + down + 1);
                divide(maze, (right - left) / 2 + left + 1, right, (top - down) / 2 + down, down);
                divide(maze, (right - left) / 2 + left + 1, right, top, (top - down) / 2 + down + 1);
            }
        }
    
        /**
         * 递归分割生成迷宫
         *
         * @return 生成的迷宫的单元格集合
         */
        private ArrayList<MazePoint> recursiveDivision() {
            // 初始化迷宫的所有单元格
            ArrayList<MazePoint> maze = new ArrayList<>();
            for (int h = 0; h < height; h++) {
                for (int w = 0; w < width; w++) {
                    MazePoint point = new MazePoint(w, h);
                    maze.add(point);
                }
            }
            divide(maze, 0, width - 1, height - 1, 0);  // 递归分割迷宫
    
            maze.get(0).setLeft(0);    // 左上角开墙作为入口
            maze.get(width * height - 1).setRight(0);    // 右下角开墙作为出口
            return maze;
        }
    
        private ArrayList<MazePoint> prim() {
            ArrayList<MazePoint> mazePoints = new ArrayList<>();
            PrimMaze primMaze = new PrimMaze(width * 2 + 1, height * 2 + 1);
            int[][] tempMaze = primMaze.getMaze();
            for (int i = 0; i < tempMaze.length; i++) {
                for (int j = 0; j < tempMaze[i].length; j++) {
                    if (i % 2 != 0 && j % 2 != 0) {
                        MazePoint mazePoint = new MazePoint(i / 2, j / 2);
                        if (tempMaze[i - 1][j] == 10) {
                            mazePoint.setLeft(1);
                        }
                        if (tempMaze[i + 1][j] == 10) {
                            mazePoint.setRight(1);
                        }
                        if (tempMaze[i][j - 1] == 11) {
                            mazePoint.setUp(1);
                        }
                        if (tempMaze[i][j + 1] == 11) {
                            mazePoint.setDown(1);
                        }
                        mazePoints.add(mazePoint);
                    }
                }
            }
            mazePoints.get(0).setLeft(0);    // 左上角开墙作为入口
            mazePoints.get(width * height - 1).setRight(0);    // 右下角开墙作为出口
            return mazePoints;
        }
    
        public void draw() {
            new PlayView(mazePoints);
        }
    
    }
    
    
    
    

    普里姆算法

    class PrimMaze {
        private int[][] maze;
    
        public int[][] getMaze() {
            return maze;
        }
    
        PrimMaze(int row, int column) {
            int row1 = row / 2;
            int column1 = column / 2;
            maze = new int[row1 * 2 + 1][column1 * 2 + 1];
            for (int x = 0; x < row1 * 2 + 1; x++)            //初始化迷宫
            {
                for (int y = 0; y < column1 * 2 + 1; y++) {
                    if (x == 0 || x == row1 * 2) {
                        maze[x][y] = -1;
                    }
                    if (y == 0 || y == column1 * 2) {
                        maze[x][y] = -1;
                    }
                }
            }
            for (int x = 1; x < row1 * 2; x++) {
                for (int y = 1; y < column1 * 2; y++) {
                    if (x % 2 == 1 || y % 2 == 1) {
                        maze[x][y] = 0;
                    }
                    if (x % 2 == 0 || y % 2 == 0) {
                        maze[x][y] = 1;
                    }
                }
            }
    
            ArrayList<int[]> list = new ArrayList<>();            //记录已连通的"路"的坐标的集合
            int[] coordinate = new int[2];        //记录未访问的点坐标
            int x = 1, y = 1;        //设置起点位置
            coordinate[0] = coordinate[1] = 1;
            list.add(coordinate);        //将起点加入已经连通的路集合
    
            //x,y表示当前访问坐标
            while (list.size() < row1 * column1)            //当所有点都已访问完时结束
            {
                boolean flag1;        //标识坐标是否已经被访问
                int[] record = {-1, -1, -1, -1};        //用于记录四周未被访问的方位,0代表上,1代表下,2代表左,3代表右
    
                if (x - 2 > 0)            //判断当前位置上方是否有路
                {
                    int[] a = new int[2];
                    a[0] = x - 2;
                    a[1] = y;
                    flag1 = judge(a, list);        //判断上方是否已经被访问
                    if (flag1) {
                        record[0] = 0;
                    }
                }
                if (x + 2 < row1 * 2)        //判断当前位置下方是否有路
                {
                    int[] a = new int[2];
                    a[0] = x + 2;
                    a[1] = y;
                    flag1 = judge(a, list);        //判断下方是否已经被访问
                    if (flag1) {
                        record[1] = 1;
                    }
                }
                if (y - 2 > 0)        //判断当前位置左方是否有路
                {
                    int[] a = new int[2];
                    a[0] = x;
                    a[1] = y - 2;
                    flag1 = judge(a, list);        //判断左方是否已经被访问
                    if (flag1) {
                        record[2] = 2;
                    }
                }
                if (y + 2 < column1 * 2)        //判断当前位置右方是否有路
                {
                    int[] a = new int[2];
                    a[0] = x;
                    a[1] = y + 2;
                    flag1 = judge(a, list);        //判断右方是否已经被访问
                    if (flag1) {
                        record[3] = 3;
                    }
                }
    
                boolean flag2 = false;            //flag2标识四周是否有未访问过的路
                for (int i = 0; i < 4; i++)        //判断当前位置的四个方位是否有未访问过的路
                {
                    if (record[i] == i) {
                        flag2 = true;        //如果有未访问过的路,跳出循环
                        break;
                    }
                }
    
                int r = new Random().nextInt(4);
                while (record[r] == r) {
                    r = new Random().nextInt(4);
                }
    
                while (record[r] != r && flag2)            //当方位标识错误且当前位置四周有未访问过的点时继续随机获取一个新的方位标识,直到标识正确
                {
                    r = new Random().nextInt(4);        //随机选取一个可以符合条件的墙并将其敲碎
                    if (record[r] == r)        //当标识正确时,敲碎两点之间的墙
                    {
                        if (r == 0) {       //当上方有未访问过的点时,敲碎上方的墙
                            maze[x - 1][y] = 0;
                        }
                        if (r == 1) {        //当下方有未访问过的点时,敲碎下方的墙
                            maze[x + 1][y] = 0;
                        }
                        if (r == 2) {         //当左方有未访问过的点时,敲碎左方的墙
                            maze[x][y - 1] = 0;
                        }
                        if (r == 3) {       //当右方有未访问过的点时,敲碎右方的墙
                            maze[x][y + 1] = 0;
                        }
                    }
                }
    
                //将与当前坐标之间的墙被敲碎的路的坐标从未被访问的集合中移出
                if (r == 0 && flag2)        //如果敲碎的是上方的墙,则将上方的路加入到已连通的路集合
                {
                    int[] b = new int[2];
                    b[0] = x - 2;
                    b[1] = y;
                    if (judge(b, list)) {
                        list.add(b);
                    }
                }
                if (r == 1 && flag2)        //如果敲碎的是下方的墙,则将下方的路加入到已连通的路集合
                {
                    int[] b = new int[2];
                    b[0] = x + 2;
                    b[1] = y;
                    if (judge(b, list)) {
                        list.add(b);
                    }
                }
                if (r == 2 && flag2)        //如果敲碎的是左方的墙,则将左方的路加入到已连通的路集合
                {
                    int[] b = new int[2];
                    b[0] = x;
                    b[1] = y - 2;
                    if (judge(b, list)) {
                        list.add(b);
                    }
                }
                if (r == 3 && flag2)        //如果敲碎的是右方的墙,则将右方的路加入到已连通的路集合
                {
                    int[] b = new int[2];
                    b[0] = x;
                    b[1] = y + 2;
                    if (judge(b, list)) {
                        list.add(b);
                    }
                }
    
    
                int i = new Random().nextInt(list.size());            //随机选取一个被连通的路坐标
                x = list.get(i)[0];                //获取路坐标
                y = list.get(i)[1];
            }
    
            for (int r = 0; r < maze.length; r++)//将方格墙转为线条墙,10表示横,11表示竖
            {
                for (int c = 0; c < maze[r].length; c++) {
                    if (r % 2 == 0 && c % 2 == 1) {
                        if (maze[r][c] != 0) {
                            maze[r][c] = 10;
                        }
                    }
                    if (r % 2 == 1 && c % 2 == 0) {
                        if (maze[r][c] != 0) {
                            maze[r][c] = 11;
                        }
                    }
                }
            }
    
        }
    
        boolean judge(int[] coordinate, ArrayList<int[]> list)            //判断路是否已经加入通路集合,已加入则返回false
        {
            boolean flag = true;
            for (int[] ints : list) {
                if (coordinate[0] == ints[0] && coordinate[1] == ints[1])            //若已访问点集合中含有该位置的坐标,表示该位置已访问过,不用重复加入该位置的坐标
                {
                    flag = false;
                    break;
                }
            }
            return flag;
        }
    }
    
    
    

    总结

    通过此次的《复杂迷宫》游戏实现,让我对swing的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。

    java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。

    源码获取

    源码下载地址:传送门------->

    可关注博主后,私聊博主免费获取
    需要技术指导,写项目程序,等更多服务请联系博主

    今天是持续写作的第 6 / 100 天。
    可以关注我,点赞我、评论我、收藏我啦。

    更多相关内容
  • 用c语言实现的可自动生成地图迷宫,含源码(vc++6.0欲调试需安装ege图形库),exe文件可运行。无闪烁,高速,asdw控制方向,可调大小。致谢原始文件。
  • 2、设定迷宫地图,包含可走的通道,不可走的墙体,还有出口位置 3、键盘的上下左右按键,来控制角色的移动 4、角色移动的算法,通道可走,遇到墙体不可走 5、走到终点,有成功通关的提示。 6、增加游戏的难度...
  • 其中不少方法来自于游戏界前辈,我根据自己的基础地图做了不少修正(毕竟迷宫地图的形式多种多样,适合自己游戏的才是最好的)。根据方案生成地图之后,还可以加上一些静态分布来丰富地图表现,大家就自行发挥啦!...

    文/兔四

    概述:文章基于一种基础的地图,来讨论三套不同的地图生成方案。

    文章不会出现跟代码相关的内容,会以较为通俗的语句和不少简单的示意图来表示迷宫的生成方案。其中不少方法来自于游戏界前辈,我根据自己的基础地图做了不少修正(毕竟迷宫和地图的形式多种多样,适合自己游戏的才是最好的)。

    根据方案生成地图之后,还可以加上一些静态分布来丰富地图表现,大家就自行发挥啦!

    地图基础

    地图的形式很多,这里我使用的地图是以tile块为单位分割的地图,地图上的tile块形式很多,但主要分成三种:

    A:陆地,可以在上面分布一些角色啦物件啦;

    B:过渡,根据物理框可以在上面移动,不过一般不会分布物件;

    C:水域,不可移动的区域,可以理解成为迷宫的“墙”;

    efbefb30e871d7423b9b78d517030581.gif

    image001.png (266.48 KB, 下载次数: 31)

    2017-6-15 14:16 上传

    在后文的迷宫生成方案里,会以水域作为分割,主要围绕陆地的分布来设计迷宫,过渡的地块根据游戏实际需要再去生成。如果你不希望地图用水域来分割,那只需要把水域改成传统的墙壁即可。

    本文用来展示的地图,面积都比较小,方便表达迷宫的生成规则。在实际游戏制作时,按需求去铺量就行。

    方案一:主路扭曲型

    1、首先,按照下图的间隔规则来生成基础的大地图,1为陆地,0为水域。

    efbefb30e871d7423b9b78d517030581.gif

    image003.png (104.04 KB, 下载次数: 40)

    2017-6-15 14:16 上传

    2、然后,选择一个靠近边缘的1作为起点,在它的周围随机找另一个黄色的1(这里的“周围”指的是上下左右4个方向,斜边不算)。找到就把他们联通,即把两个1之间的0变成陆地,这里用红色来表示。

    efbefb30e871d7423b9b78d517030581.gif

    image005.png (104.33 KB, 下载次数: 37)

    2017-6-15 14:16 上传

    3、把上一步“终”的格子作为新的一个“起”格子,不停循环第二步的过程,直到找不到周围有黄色的1。

    efbefb30e871d7423b9b78d517030581.gif

    image007.png (104.82 KB, 下载次数: 32)

    2017-6-15 14:16 上传

    4、这时候,原路往回走(即不停去找前一个格子),直到找到一个格子,这个格子周围有黄色的1,那么从这个格子开始重复前两个步骤。

    efbefb30e871d7423b9b78d517030581.gif

    image009.png (104.48 KB, 下载次数: 32)

    2017-6-15 14:16 上传

    5、接下来就是不停重复上面的步骤,找到就联通,找不到就往回走。

    efbefb30e871d7423b9b78d517030581.gif

    image011.png (105.61 KB, 下载次数: 31)

    2017-6-15 14:16 上传

    efbefb30e871d7423b9b78d517030581.gif

    image013.png (106.71 KB, 下载次数: 38)

    2017-6-15 14:16 上传

    6、填充完整个地图之后,迷宫就算是制作完成了,根据需求加上终点即可。

    efbefb30e871d7423b9b78d517030581.gif

    image015.png (108.03 KB, 下载次数: 36)

    2017-6-15 14:16 上传

    总结一下,这种方案生成的迷宫会有一条明显的主路,即一条特别长、贯穿大部分区域的路线,同时,迷宫的路线一般比较扭曲。

    方案二:自然分岔型

    这个方案的雏形来自于随机prim算法,具体步骤如下:

    1、跟方案一一样,生成一个基础地图。格子先用黄色1和灰色0来表示,暂时不区分水陆。

    2、随机取一个地图边缘的黄色1,把它标记为红色1,即变成陆地。然后把它旁边的灰色0标记成蓝色0,表示“待定”。(注意的是,大地图四周的灰色0固定不变,作为地图边缘而存在)

    efbefb30e871d7423b9b78d517030581.gif

    image017.png (98.57 KB, 下载次数: 39)

    2017-6-15 14:16 上传

    3、敲黑板了!!这里是重点!!!

    随机选一个蓝色的0(这一步很重要,会使这个方案明显区别于上一个方案),然后看红色1隔着这个蓝色0对面的格子,是否是黄色的1:

    如果是,则把对面的黄色1标记成红色1,即变成陆地,然后把蓝色0变成红色的0,即也变成陆地;

    如果不是,就把这个蓝色的0变成灰色的0。

    最后,把新创建的红色1周围的灰色0,标记成蓝色0。

    efbefb30e871d7423b9b78d517030581.gif

    image019.png (98.17 KB, 下载次数: 34)

    2017-6-15 14:16 上传

    4、继续重复上面的步骤

    efbefb30e871d7423b9b78d517030581.gif

    image021.png (99.19 KB, 下载次数: 29)

    2017-6-15 14:16 上传

    efbefb30e871d7423b9b78d517030581.gif

    image023.png (98.89 KB, 下载次数: 36)

    2017-6-15 14:16 上传

    5、对比上图和下图,这里取一个蓝色0生成一个红色1之后,新生成的红色1旁边,有两个蓝色0的两边都是红色1了,那么就根据第三步的规则,在稍后取到这些蓝色0时,就会把他们变成灰色0。

    efbefb30e871d7423b9b78d517030581.gif

    image025.png (97.92 KB, 下载次数: 39)

    2017-6-15 14:16 上传

    6、继续重复上述步骤,直到整个地图没有蓝色0了,地图就生成完毕。

    efbefb30e871d7423b9b78d517030581.gif

    image027.png (105.25 KB, 下载次数: 41)

    2017-6-15 14:16 上传

    efbefb30e871d7423b9b78d517030581.gif

    image029.png (104.6 KB, 下载次数: 42)

    2017-6-15 14:16 上传

    总结一下,对比方案一,这套方案不会出现明显的主路,迷宫相对比较自然,但迷宫的分岔路会比较多,所以迷宫可能会更复杂,即玩家需要做选择的次数可能比较多。

    方案三:块状分割型

    上述两个方案有个共同的特点,就是道路永远都是1个格子宽,如果游戏需要给地图创造一些小型地块或者更宽的道路,需要在迷宫生成之后再用各种分布的规则来丰富迷宫。

    而第三个方案则以小型地块作为出发点来设计迷宫,这套方案的雏形来自于国外大神Bob Nystrom,有兴趣的可以去查看他个人主页。

    1、首先,在大地图(还是之前那个大地图)上生成若干小型地形,保证边长是奇数且不重合就好(示意图全部使用了正方形,实际上可以做成长方形让地图更加自然)。注意顶点要在黄色1格子上即可,这里我用橙色1来表示这些小型地块。

    efbefb30e871d7423b9b78d517030581.gif

    image031.png (101.88 KB, 下载次数: 31)

    2017-6-15 14:16 上传

    2、然后,根据之前方案一的迷宫生成方案,在非小型地块的区域里,用迷宫来填充。这一步完成之后,迷宫和小型地形是分隔开来的。

    efbefb30e871d7423b9b78d517030581.gif

    image033.png (97.39 KB, 下载次数: 36)

    2017-6-15 14:16 上传

    3、在橙色1的小型地形周围,随机取点以连接黄色1,连接点的数量可以根据需要来确定,建议是不要吝啬连接点的个数,因为这种地图之下,分岔路远比前两种方案要少。

    efbefb30e871d7423b9b78d517030581.gif

    image035.png (93.28 KB, 下载次数: 32)

    2017-6-15 14:16 上传

    4、接下来是简化地图,目的是去掉一些死胡同,因为这种方案的核心在于小型地块,没有必要让玩家在迷宫的路上绕。方法是把一些3边都是灰色0的黄色1去掉即可,具体数量也根据游戏需求来制定,我这里只去掉了一部分。

    efbefb30e871d7423b9b78d517030581.gif

    image037.png (98.2 KB, 下载次数: 34)

    2017-6-15 14:16 上传

    5、最后,给地图加上出口和入口,地图就做完啦!

    efbefb30e871d7423b9b78d517030581.gif

    image039.png (99.07 KB, 下载次数: 34)

    2017-6-15 14:16 上传

    总结一下,这种方案比前两种多了小型地块,这一点比较适合设计玩家的阶段性反馈。同时地图的分岔路明显减少,玩家在这种方案下的选择次数会明显降低。另外,由于这个方案的步骤相对多且独立,所以对于设计者来讲会比较容易控制地图的结构。

    相关阅读:

    展开全文
  • 地图基础 地图的形式很多,这里我使用的地图是以tile块为单位分割的地图地图上的tile块形式很多,但主要分成三种: A:陆地,可以在上面分布一些角色啦物件啦; B:过渡,根据物理框可以在上面移动,不过...

    地图基础

     

    地图的形式很多,这里我使用的地图是以tile块为单位分割的地图,地图上的tile块形式很多,但主要分成三种:

     

    A:陆地,可以在上面分布一些角色啦物件啦;

    B:过渡,根据物理框可以在上面移动,不过一般不会分布物件;

    C:水域,不可移动的区域,可以理解成为迷宫的“墙”;

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    在后文的迷宫生成方案里,会以水域作为分割,主要围绕陆地的分布来设计迷宫,过渡的地块根据游戏实际需要再去生成。如果你不希望地图用水域来分割,那只需要把水域改成传统的墙壁即可。

     

    本文用来展示的地图,面积都比较小,方便表达迷宫的生成规则。在实际游戏制作时,按需求去铺量就行。

     

    方案一:主路扭曲型

     

    1、首先,按照下图的间隔规则来生成基础的大地图,1为陆地,0为水域。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    2、然后,选择一个靠近边缘的1作为起点,在它的周围随机找另一个黄色的1(这里的“周围”指的是上下左右4个方向,斜边不算)。找到就把他们联通,即把两个1之间的0变成陆地,这里用红色来表示。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    3、把上一步“终”的格子作为新的一个“起”格子,不停循环第二步的过程,直到找不到周围有黄色的1。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    4、这时候,原路往回走(即不停去找前一个格子),直到找到一个格子,这个格子周围有黄色的1,那么从这个格子开始重复前两个步骤。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    5、接下来就是不停重复上面的步骤,找到就联通,找不到就往回走。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    6、填充完整个地图之后,迷宫就算是制作完成了,根据需求加上终点即可。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    总结一下,这种方案生成的迷宫会有一条明显的主路,即一条特别长、贯穿大部分区域的路线,同时,迷宫的路线一般比较扭曲。

     

    方案二:自然分岔型

     

    这个方案的雏形来自于随机prim算法,具体步骤如下:

     

    1、跟方案一一样,生成一个基础地图。格子先用黄色1和灰色0来表示,暂时不区分水陆。

     

    2、随机取一个地图边缘的黄色1,把它标记为红色1,即变成陆地。然后把它旁边的灰色0标记成蓝色0,表示“待定”。(注意的是,大地图四周的灰色0固定不变,作为地图边缘而存在)

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    3、敲黑板了!!这里是重点!!!

     

    随机选一个蓝色的0(这一步很重要,会使这个方案明显区别于上一个方案),然后看红色1隔着这个蓝色0对面的格子,是否是黄色的1:

     

    • 如果是,则把对面的黄色1标记成红色1,即变成陆地,然后把蓝色0变成红色的0,即也变成陆地;

    • 如果不是,就把这个蓝色的0变成灰色的0。

     

    最后,把新创建的红色1周围的灰色0,标记成蓝色0。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    4、继续重复上面的步骤

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    5、对比上图和下图,这里取一个蓝色0生成一个红色1之后,新生成的红色1旁边,有两个蓝色0的两边都是红色1了,那么就根据第三步的规则,在稍后取到这些蓝色0时,就会把他们变成灰色0。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    6、继续重复上述步骤,直到整个地图没有蓝色0了,地图就生成完毕。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    总结一下,对比方案一,这套方案不会出现明显的主路,迷宫相对比较自然,但迷宫的分岔路会比较多,所以迷宫可能会更复杂,即玩家需要做选择的次数可能比较多。

     

    方案三:块状分割型

     

    上述两个方案有个共同的特点,就是道路永远都是1个格子宽,如果游戏需要给地图创造一些小型地块或者更宽的道路,需要在迷宫生成之后再用各种分布的规则来丰富迷宫。

     

    而第三个方案则以小型地块作为出发点来设计迷宫,这套方案的雏形来自于国外大神Bob Nystrom,有兴趣的可以去查看他个人主页。

     

    1、首先,在大地图(还是之前那个大地图)上生成若干小型地形,保证边长是奇数且不重合就好(示意图全部使用了正方形,实际上可以做成长方形让地图更加自然)。注意顶点要在黄色1格子上即可,这里我用橙色1来表示这些小型地块。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    2、然后,根据之前方案一的迷宫生成方案,在非小型地块的区域里,用迷宫来填充。这一步完成之后,迷宫和小型地形是分隔开来的。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    3、在橙色1的小型地形周围,随机取点以连接黄色1,连接点的数量可以根据需要来确定,建议是不要吝啬连接点的个数,因为这种地图之下,分岔路远比前两种方案要少。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    4、接下来是简化地图,目的是去掉一些死胡同,因为这种方案的核心在于小型地块,没有必要让玩家在迷宫的路上绕。方法是把一些3边都是灰色0的黄色1去掉即可,具体数量也根据游戏需求来制定,我这里只去掉了一部分。

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    5、最后,给地图加上出口和入口,地图就做完啦!

     

    经验分享:三套简单的迷宫地图生成方案 ...

     

     

    总结一下,这种方案比前两种多了小型地块,这一点比较适合设计玩家的阶段性反馈。同时地图的分岔路明显减少,玩家在这种方案下的选择次数会明显降低。另外,由于这个方案的步骤相对多且独立,所以对于设计者来讲会比较容易控制地图的结构。

    迷宫生成网页:http://www.mazegenerator.net/

    转载于:https://www.cnblogs.com/damowang/p/7047357.html

    展开全文
  • 迷宫问题(二)------复杂迷宫

    千次阅读 2018-08-20 16:02:24
    "迷宫地图为\n-------------------\n" ); for (row = 0 ; row ; row++) { for (col = 0 ; col ; col++) { printf ( " %d " , maze-> map [row][col]); } printf ( "\n" ); } } //检测当前节点...

    所需知识

    结构体
    递归

    ❀思路分析
    1.跟上篇比较区别在于,多通路,同出口,同入口,如何在已经找到了一个出口的情况下,如何返回来找另外一条最短路径,还是用赋值法。
    这里写图片描述
    2.探路的顺序是上左右下。
    从入口开始,通路的条件为,下一位置值为1或值大于当前位置的值,
    赋值依次加1
    每次走位置,都调用一次函数,形成递归
    这里写图片描述
    向上走为最高优先级,走不通后向右走,然后向下
    这里写图片描述
    当前位置进入死胡同,走不通,存储路径的栈弹出该错误位置。并递归到上一层,上一个节点,依此类推。退回到有其他通路可走的节点,再进入该下一位置的函数,进行递归。

    这里写图片描述
    到达出口后,将栈s中保存的这条有效路径保存到栈Path。然后再进行。该出口处函数走不通,将会退回到上一个还有其他通路的节点
    这里写图片描述
    只有节点3位置处右侧有第一次未走过的路径(11到左侧12与3到自己的右侧虽然未同一节点,但路线不同),且12>3满足通路条件,开始探路
    这里写图片描述
    走到该位置后发现,下一个位置的7<当前位置的8,死路,回退,同时出栈,这些错误位置,递归退到上一个有其他通路的路口。
    这里写图片描述
    当前位置5还有右出口。
    这里写图片描述
    再一次来到出口,与刚才存进去的栈Path里存的路径相比较,若比之小,则进行替换。
    而后继续程序,出口位置再不可走。递归返回,直到2都没有再有其他未走通路的节点。返回到入口,程序结束。

    具体实现
    //maze.h
    #define __MAZE_H__
    #ifdef __MAZE_H__
    #define ROW 6 //行,纵坐标
    #define COL 6 //列,横坐标
    
    #include <stdio.h>  //打印
    #include <stdlib.h>
    #include <assert.h>
    
    //建立一个地图
    typedef int  DataType;
    //迷宫
    typedef struct Map
    {
        DataType map[ROW][COL];
    }Map;
    //位置
    typedef struct Position
    {
        int x;
        int y;
    }Point;
    //栈
    typedef struct Stack
    {
        Point Sta[40];
        int top;//栈顶,有效数的后一位坐标
    }Stack;
    
    //初始化栈
    void InitStack(Stack * s);
    //入栈
    void PushStack(Stack * s, int x, int y);
    //出栈
    void PopStack(Stack *s);
    //取栈顶位置
    Point StackTop(Stack * s);
    //打印栈
    void PrintStack(Stack * s);
    //把栈s里的内容全部赋值给Path
    void s_Path(Stack * s, Stack * Path);
    //测试栈
    void testStack(Stack *s);
    //清空栈
    void EmptyStack(Stack *s);
    
    
    //初始化迷宫
    void InitMaze(Map * maze);
    //打印迷宫
    void PrintMap(Map * maze);
    //检测当前节点是否有通路,优先次序为上左右下,入栈
    int Pass(Map * maze, Point cur, Point next);
    //通过迷宫和入口寻找出路
    void FindExit(Map * maze, Point entry);
    //显示路线
    void PrintPath(Map * maze,Stack * Path);
    
    #endif //__MAZE_H__
    
    //maze.c
    #include "Maze.h"
    //初始化栈
    void InitStack(Stack * s)
    {
        assert(s);
        s->top = 0;
    }
    //入栈
    void PushStack(Stack * s, int x, int y)
    {
        assert(s);
        if (40 == s->top)
        {
            perror("PushStack error\n");
            return;
        }
        s->Sta[s->top].x = x;
        s->Sta[s->top].y = y;
        s->top++;
    }
    //出栈
    void PopStack(Stack *s)
    {
        if (s->top == 0)
        {
            perror("PopStack error\n");
            return;
        }
        assert(s);
        s->top--;
    }
    //取栈顶元素
    Point StackTop(Stack * s)
    {
        if (s->top == 0)
        {
            perror("StackTop error \n");
            return ;
        }
        return (s->Sta[s->top - 1]);
    }
    //打印栈
    void PrintStack(Stack * s)
    {
        for (int i = 0; i < s->top; i++)
        {
            printf(" x=%d ,y = %d \n", s->Sta[i].x, s->Sta[i].y);
        }
        printf("\n");
    }
    //清空栈 
    void EmptyStack(Stack * s)
    {
        s->top = 0;
    }
    //把栈s里的内容全部赋值给Path
    void s_Path(Stack * s, Stack * Path)
    {
        int tmp = s->top;
        while (tmp)
        {
            tmp--;
            Path->Sta[tmp] = s->Sta[tmp];
    
        }
    
        Path->top = s->top;
    }
    //测试栈
    void testStack(Stack * s)
    {
        printf("测试栈\n");
        InitStack(s);
        printf("入栈1,1、2,1、,3,3、4,3、5,7\n");
        PushStack(s, 1, 1);
        PushStack(s, 2, 1);
        PushStack(s, 3, 3);
        PushStack(s, 4, 3);
        PushStack(s, 5, 7);
        PrintStack(s);
        PopStack(s);
        printf("出栈一次\n");
        PrintStack(s);
        EmptyStack(s);
        printf("清空栈\n");
        PrintStack(s);
    }
    void InitMaze(Map * maze)
    {
        int col = 0, row = 0;
        if (maze == NULL)//非法传参,按理这里为Map类型的指针
        {
            return;
        }
        //0 0 0 0 0 0
        //1 1 1 1 0 0
        //0 0 0 1 0 0
        //0 1 1 1 1 1
        //0 0 1 0 0 0
        //0 0 0 0 0 0
        //初始化一个数组
        DataType arr[ROW][COL] = {
            { 0, 0, 0, 0, 0, 0 },
            { 0, 1, 1, 1, 0, 0 },
            { 0, 1, 0, 1, 0, 0 },
            { 0, 1, 0, 1, 0, 0 },
            { 0, 1, 1, 1, 1, 1 },
            { 0, 1, 0, 0, 0, 0 }
        };
        //把该数组的值传递给迷宫
        for (row = 0; row < ROW; row++)
        {
            for (col = 0; col < COL; col++)
            {
                maze->map[row][col] = arr[row][col];
            }
        }
    }
    void PrintMap(Map *maze)
    {
        int col = 0, row = 0;
        printf("迷宫地图为\n-------------------\n");
        for (row = 0; row < ROW; row++)
        {
            for (col = 0; col < COL; col++)
            {
                printf(" %d ", maze->map[row][col]);
            }
            printf("\n");
        }
    }
    
    //检测当前节点是否有通路,优先次序为上左右下,入栈
    int Pass(Map * maze,Point cur,Point next)
    {
        if ((cur.x>ROW-1)||(cur.y>COL-1)||(next.x>ROW-1)||(next.y>COL-1))
        {
            return 0;
        }
        if ((maze->map[next.x][next.y] == 1)||(maze ->map [next.x][next.y]>maze->map [cur.x][cur.y]))
            return 1;
        return 0;
    }
    //检测是否走出迷宫
    int YesPass(Map * maze, Point pos)
    {
        if (pos.x == 0 || pos.y == 0 || pos.x == ROW - 1 || pos.y == COL - 1)
            return 1;
        return 0;
    }
    //通过迷宫地图和入口找出口
    void FindExit(Map * maze, Point cur,Point entry, Stack * s,Stack * Path)
    {
        Point next = cur;
        //探路走起来,先赋值,再走路
        //若为入口,先赋值2
        if ((0 == s->top) && (entry.x == cur.x) && (entry.y == cur.y))
        {
            maze->map[cur.x][cur.y] = 2;
            PushStack(s, cur.x, cur.y);
        }
        //若找到了出口进行标记
        if (YesPass(maze, cur)&&((entry.x != cur.x)||(entry.y != cur.y)))
        {
            if (Path->top == 0)
            {
                s_Path(s,Path);
            }
            if (s->top < Path->top)
            {
                s_Path(s, Path);
            }
        }
        //上通路
        next.x = cur.x-1;
        next.y = next.y;
        if (Pass(maze,cur, next))
        {
            maze->map[next.x][next.y] = maze->map[cur.x][cur.y] + 1;
            PushStack(s, next.x, next.y);
            FindExit(maze, next, entry, s, Path);
        }
        //左通路
        next.x = cur.x;
        next.y = cur.y-1;
        if (Pass(maze,cur, next))
        {
            maze->map[next.x][next.y] = maze->map[cur.x][cur.y] + 1;
            PushStack(s, next.x, next.y);
            FindExit(maze, next, entry, s, Path);
        }
        //右通路
        next.x = cur.x;
        next.y = cur.y+1;
        if (Pass(maze, cur,next))
        {
            maze->map[next.x][next.y] = maze->map[cur.x][cur.y] + 1;
            PushStack(s, next.x, next.y);
            FindExit(maze, next, entry, s, Path);
        }
        //下通路
        next.x = cur.x + 1;
        next.y = cur.y;
        if (Pass(maze,cur, next))
        {
            maze->map[next.x][next.y] = maze->map[cur.x][cur.y] + 1;
            PushStack(s, next.x, next.y);
            FindExit(maze, next, entry, s, Path);
        }
        PopStack(s);
    }
    //显示路线
    void PrintPath(Map * maze,Stack * Path)
    {
        char arr[ROW][COL];
        while (Path->top)
        {
            maze->map[StackTop(Path).x][StackTop(Path).y] = 20;
            arr[StackTop(Path).x][StackTop(Path).y] = '*';
            PopStack(Path);
        }
        printf("---------------------\n");
        for (int row = 0; row < ROW; row++)
        {
            for (int col = 0; col < COL; col++)
            {
                if (maze->map[row][col] != 20)
                {
                    maze->map[row][col] = 0;
                    arr[row][col] = 1;
                }
                printf(" %c ", arr[row][col]);
            }
            printf("\n");
        }
    }
    //源.c
    #include "Maze.h"
    int main()
    {
        //给定入口
        Point e;
        e.x = 5;
        e.y = 1;
        //定义迷宫
        Map  maze;
        //定义栈存放路径
        Stack s;
        //定义栈存放最短路径
        Stack Path;
        //初始化两个栈
        InitStack(&Path);
        testStack(&s);
        //初始化迷宫
        InitMaze(&maze);
        //打印迷宫
        PrintMap(&maze);
        //通过迷宫和入口找出口
        FindExit(&maze,e, e, &s,&Path);
        //打印当前栈中保存的路径
        //PrintStack(&Path);
        //打印因为探路而改变的迷宫
        PrintMap(&maze);
        //显示路线
        PrintPath(&maze,&Path);
        printf("-----------------\n");
        system("pause");
        return 0;
    }
    
    结果

    这里写图片描述

    展开全文
  • Java-复杂迷宫求解

    2018-04-17 02:38:55
    总体的思路不太复杂:首先创建一个栈结构,可以方便的输出最短的路径,然后就是合理的运用递归的思想来进行路径的回溯。先上代码。interface Method{//实现迷宫的栈结构的接口 int MAX = 50;//栈的最大存储量,也...
  • #复杂迷宫求解(2)

    2018-08-30 20:48:22
    // pos 必须在地图中 pos位置如果是1 int IsPass ( Maze * m , Position pos ) { assert ( m ) ; if ( pos . _x >= ROW || pos . _x < 0 || pos . _y >= COL || pos . _y >= COL )...
  • 同时,通过无线数据传输,将微型机器人所获得数据显示在以LABVIEW为平台的上位机上,通过上位机进行未知区域地图的绘制,并可根据需求策划一条到达指定位置的最短路径。 比赛练习案例,创新创业比赛、青春杯、挑战杯...
  • Java实现可视化迷宫

    2021-03-06 15:12:26
    简单迷宫 复杂迷宫 项目运行文件中有两个运行脚本,Windows下直接双击win运行.bat即可,linux和Mac运行sh文件中的命令即可,喜欢用IDE的也可自行创建项目。 运行项目后,点击菜单栏左上角的Ma...
  •  初始化迷宫地图数据 --》2. 检测迷宫的入口是否有效 --》 3. 检测当前位置是否为迷宫的出口 --》4. 保存最短路径 --》5. 检测当前位置的下一步是否能够走通 --》6. 走迷宫 --》7. 具体走迷宫方式 --》8....
  • PTA迷宫探路

    2022-04-23 22:16:57
    本题目要求读入2个整数A和B,表示A行B列的迷宫迷宫中有障碍点。给定起始点和终止点,要求从起始点到终止点的最小步数。 输入格式: 输入n组如下的数: 输入2个整数A和B,表示A行B列的迷宫,然后输入一个整数C,...
  • 迷宫随机生成算法

    2022-03-23 10:04:20
    迷宫随机生成算法
  • 迷宫求解问题 我们要先初始化一个迷宫地图,这里分为两种,一类为简单迷宫(不带环),一类为复杂迷宫(带环)。具体示例如下,这里采用6*6的数组表示迷宫地图,每个位置上对应元素的值非0即1,1表示路,0表示墙;...
  • 相信大家都玩过迷宫的游戏,对于简单的迷宫,我们可以一眼就看出通路,但是对于复杂迷宫,可能要仔细寻找好久,甚至耗费数天,然后可能还要分别从入口和出口两头寻找才能找的到通路,甚至也可能找不到通路。...
  • java课程设计走迷宫.doc JAVA语言与面向对象技术课程设计报告20142015年度第1学期走迷宫迷宫目录目录21概述111课程设计目的112课程设计内容12系统需求分析221系统目标222主体功能223开发环境33系统概要设计331系统...
  • 当你置身其中,面对纷繁复杂的心灵迷宫,你需要躲避时不时袭来的怪物,就像有人每日都要面对的低落与忧伤。怪物的追捕,音效的变化,自身血量和san值降低带来的干扰影响,都会引起你的情绪。但不必就此克服,迷宫中...
  • 完整代码下载:http://xiazai.bitsCN.com/201407/tools/python-migong.rar最近研究了下迷宫的生成算法,然后做了个简单的在线迷宫游戏。游戏地址和对应的开源项目地址可以通过上面的链接...1.将迷宫地图分成多个房间...
  • 迷宫生成算法总结

    千次阅读 多人点赞 2020-01-31 11:06:54
    最近闲来无事想做一个质量高一点的进阶版的迷宫小游戏,首先就要先生成最基础的迷宫地图,因此学习并整理了一下迷宫生成算法。由于python更容易实现这些算法,因此首先使用pyhon将各种生成算法整理一遍,之后再用Qt...
  • 迷宫小游戏

    2013-04-03 15:45:48
    学习编程半年,自己写的一个可以随机生成迷宫图的迷宫游戏,每关迷宫地图都会扩大,而且迷宫只生成唯一一条可通往出口的道路。为了解决C#闪烁的问题,选择了控件加GDI+混合使用,未使用双缓冲。代码有多余的方法,也...
  • 迷宫游戏python实现

    千次阅读 多人点赞 2020-02-01 12:39:11
    迷宫算法总结篇中我总结了生成迷宫的四种算法,在这一篇文章里面我侧重迷宫游戏的实现以及可视化。 首先我使用python3中的tkinter...迷宫的长和宽:尺寸越大,生成的地图越难 迷宫生成算法:难度:kruskal算法 ...
  • 问题描述:迷宫指的是充满复杂通道,很难找到从入口或迷宫中某个位置到达出口的道路,道路复杂难辨,人进去不容易出来的事物。 要求:以二维数组模拟一个矩形迷宫,利用随机深度优先、随机广度优先或随机普里姆算法...
  • 复杂迷宫游戏的设计使用迷宫生成算法绘制和生成包括唯一解、多解和无解多种情况的精细复杂迷宫地图,且使用路径规划算法在人工智能寻路中具有较高的时间效率和空间效率。本文设计并实现了复杂迷宫环境下地图生成的...
  • 基于Python实现的机器人自动走迷宫

    千次阅读 2022-05-21 14:24:32
    游戏规则为:从起点开始,通过错综复杂迷宫,到达目标点(出口)。 在任一位置可执行动作包括:向上走 'u'、向右走 'r'、向下走 'd'、向左走 'l'。 执行不同的动作后,根据不同的情况会获得不同的奖励,具体而言...
  • 随机迷宫生成算法(一)(C++)

    千次阅读 2021-12-24 21:33:53
    迷宫生成算法可以形象的理解数据结构中图的相关知识,标准二维迷宫中,每一个方块都可以抽象为图的一个顶点,而且这个图是一个无向图,且权为一,实际写起来也没有那样复杂迷宫生成算法大体可分为四种,深度...
  • 走出迷宫-BFS详解

    2021-07-29 11:14:21
    当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单。 假设你已经得到了一个n*m的迷宫的图纸,请你找出从起点到出口的最短路。 输入格式 第一行是两个...
  • 为了更方便的设计关卡,配套开发了可视化的迷宫地图编辑器,并实现了复杂迷宫地图的深度优先生成; 迷宫游戏实现了文件的读写,实现了导出和读取玩家自制地图,并加入了通过DFS绘制迷宫出路的功能;

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,153
精华内容 861
关键字:

复杂迷宫地图

友情链接: lx.rar