计算机软件实习项目三——迷宫

一、构建随机迷宫 应用不相交集合构建迷宫的算法简要描述如下:给定一个 N X N 的方格,初始时每个方格的四面都是墙(walls),如图所示,其中的 S 是迷宫的开始处,F 是迷宫的结束处。NN 迷宫的 N2 个方格 0,1,…,N2-1 初始时每个方格自己成为一个等价类,即{0},{1},…,{N2-1}。生成随机迷宫 的方法是随机选择一个内部墙(连接两个相邻方格的墙),如果该内部墙关联的 两个相邻的方格属于不同的等价类就将该墙除去,在除去该墙的同时将这两个等 价类合并。直到所有的方格都在一个等价类中,就完成了随机迷宫的生成构建随机迷宫 应用不相交集合。

二、迷宫求解

1.人为操作,通过接收键盘的输入信号实现上下左右的移动。

2.自动寻路:通过A*算法实现

A*算法:

.A*算法是一种常用的启发式搜索算法,被广泛应用于路径规划、游戏AI等领域。该算法基于最短路径优先原则,通过估计每个可能路径的代价,选择出最优解。在A*算法中,对每个节点进行评估和排序,并选择当前代价最小的节点进行扩展和探索。节点的代价由两部分组成:实际代价和启发式估价,即从起点到该节点的实际代价和从该节点到终点的估计代价之和。其中,启发式估价通常使用曼哈顿距离或欧几里得距离等方法进行计算。通过不断地扩展节点和更新代价,直到找到终点或遍历完所有节点。对于寻找路径较长或复杂的问题,A*算法可以在搜索过程中剪枝,减少搜索空间和提高效率。然而,A*算法可能存在局部最优解的问题,即搜索结果受到启发式估价的影响,容易被引导偏离全局最优解。为了解决这个问题,可以结合贪心最佳优先搜索和迭代加深搜索等方法进行改进。

Dijkstra算法

Dijkstra算法是由计算机科学家Edsger W. Dijkstra在1956年提出的。

Dijkstra算法用来寻找图形中节点之间的最短路径。

考虑这样一种场景,在一些情况下,图形中相邻节点之间的移动代价并不相等。例如,游戏中的一幅图,既有平地也有山脉,那么游戏中的角色在平地和山脉中移动的速度通常是不相等的。

在Dijkstra算法中,需要计算每一个节点距离起点的总移动代价。同时,还需要一个优先队列结构。对于所有待遍历的节点,放入优先队列中会按照代价进行排序。

在算法运行的过程中,每次都从优先队列中选出代价最小的作为下一个遍历的节点。直到到达终点为止。

源码如下:

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#define size 20
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    int n = 31;
    m_maze = new Maze();
    m_maze->set_n(n);
    m_maze->mazeInit();
    m_maze->print();
    this->setWindowTitle("迷宫");
    this->setFixedSize(620,650);
 
    connect(ui->btn_create,SIGNAL(clicked()),this,SLOT(slot_create()));
    connect(ui->btn_search,SIGNAL(clicked()),this,SLOT(slot_search()));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::slot_create()
{
    m_maze->mazeInit();
    X = 1, Y = 0;
    update();
}
 
void MainWindow::slot_search()
{
    m_maze->printPath();
    as_fg = true;
    update();
}
 
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    int n = m_maze->get_n();
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(m_maze->maze[i][j] ==1){
                painter.setPen(Qt::green);
                painter.setBrush(QBrush(Qt::green,Qt::SolidPattern));
                painter.drawRect(QRect(j*size,i*size,size,size));
            }
            else if(m_maze->maze[i][j] == 2){
                painter.setPen(Qt::blue);
                painter.setBrush(Qt::blue);
                painter.drawEllipse(j*20,i*20,20,20);
            }
            else if(m_maze->maze[i][j] == 3){
                painter.setPen(Qt::red);
                painter.setBrush(Qt::red);
                painter.drawEllipse(j*20,i*20,20,20);
            }
            else if(m_maze->maze[i][j] == 0){
                painter.setPen(Qt::black);
                painter.setBrush(QBrush(Qt::white,Qt::SolidPattern));
                painter.drawRect(QRect(j*size,i*size,size,size));
            }
            else if(m_maze->maze[i][j] == 6){
                painter.setPen(Qt::white);
                painter.setBrush(Qt::blue);
                painter.drawRect(j*20+5,i*20+5,10,10);
            }
        }
    }
}
 
void MainWindow::keyPressEvent(QKeyEvent *e)
{
    if(as_fg){
        m_maze->recoverPath();
        as_fg = false;
        update();
    }
    int tx = X, ty = Y;
    int n = m_maze->get_n();
    if(e->key()==Qt::Key_W)//上
    {
        if(X>0 && m_maze->maze[X-1][Y] != 1)
        {
            X=X-1;
        }
    }
    else if(e->key()==Qt::Key_S)//下
    {
        if(X<n-1 && m_maze->maze[X+1][Y] != 1)
        {
            X=X+1;
        }
    }
    else if(e->key()==Qt::Key_A)//左
    {
        if(Y>0 && m_maze->maze[X][Y-1] != 1)
        {
            Y=Y-1;
        }
    }
    else if(e->key()==Qt::Key_D)//右
    {
 
        if(Y<n-1 && m_maze->maze[X][Y+1] != 1)
        {
            Y=Y+1;
        }
    }
    int tmp = m_maze->maze[X][Y];
    if(tmp == 3){
        QMessageBox::information(this,"提示","到达终点",QMessageBox::Yes);
    }else{
        m_maze->maze[X][Y] = m_maze->maze[tx][ty];
        m_maze->maze[tx][ty] = tmp;
    }
    update();
}
maze.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#define size 20
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    int n = 31;
    m_maze = new Maze();
    m_maze->set_n(n);
    m_maze->mazeInit();
    m_maze->print();
    this->setWindowTitle("迷宫");
    this->setFixedSize(620,650);
 
    connect(ui->btn_create,SIGNAL(clicked()),this,SLOT(slot_create()));
    connect(ui->btn_search,SIGNAL(clicked()),this,SLOT(slot_search()));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::slot_create()
{
    m_maze->mazeInit();
    X = 1, Y = 0;
    update();
}
 
void MainWindow::slot_search()
{
    m_maze->printPath();
    as_fg = true;
    update();
}
 
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    int n = m_maze->get_n();
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(m_maze->maze[i][j] ==1){
                painter.setPen(Qt::green);
                painter.setBrush(QBrush(Qt::green,Qt::SolidPattern));
                painter.drawRect(QRect(j*size,i*size,size,size));
            }
            else if(m_maze->maze[i][j] == 2){
                painter.setPen(Qt::blue);
                painter.setBrush(Qt::blue);
                painter.drawEllipse(j*20,i*20,20,20);
            }
            else if(m_maze->maze[i][j] == 3){
                painter.setPen(Qt::red);
                painter.setBrush(Qt::red);
                painter.drawEllipse(j*20,i*20,20,20);
            }
            else if(m_maze->maze[i][j] == 0){
                painter.setPen(Qt::black);
                painter.setBrush(QBrush(Qt::white,Qt::SolidPattern));
                painter.drawRect(QRect(j*size,i*size,size,size));
            }
            else if(m_maze->maze[i][j] == 6){
                painter.setPen(Qt::white);
                painter.setBrush(Qt::blue);
                painter.drawRect(j*20+5,i*20+5,10,10);
            }
        }
    }
}
 
void MainWindow::keyPressEvent(QKeyEvent *e)
{
    if(as_fg){
        m_maze->recoverPath();
        as_fg = false;
        update();
    }
    int tx = X, ty = Y;
    int n = m_maze->get_n();
    if(e->key()==Qt::Key_W)//上
    {
        if(X>0 && m_maze->maze[X-1][Y] != 1)
        {
            X=X-1;
        }
    }
    else if(e->key()==Qt::Key_S)//下
    {
        if(X<n-1 && m_maze->maze[X+1][Y] != 1)
        {
            X=X+1;
        }
    }
    else if(e->key()==Qt::Key_A)//左
    {
        if(Y>0 && m_maze->maze[X][Y-1] != 1)
        {
            Y=Y-1;
        }
    }
    else if(e->key()==Qt::Key_D)//右
    {
 
        if(Y<n-1 && m_maze->maze[X][Y+1] != 1)
        {
            Y=Y+1;
        }
    }
    int tmp = m_maze->maze[X][Y];
    if(tmp == 3){
        QMessageBox::information(this,"提示","到达终点",QMessageBox::Yes);
    }else{
        m_maze->maze[X][Y] = m_maze->maze[tx][ty];
        m_maze->maze[tx][ty] = tmp;
    }
    update();
}
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用 C 语言实现迷宫问题的完整代码: ```c #include<stdio.h> #include<stdlib.h> #include<conio.h> #define MAX_ROW 5 #define MAX_COL 5 int maze[MAX_ROW][MAX_COL] = { {0, 1, 0, 0, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 0, 0}, {0, 1, 1, 1, 0}, {0, 0, 0, 1, 0}, }; void print_maze() { int i, j; for (i = 0; i < MAX_ROW; i++) { for (j = 0; j < MAX_COL; j++) { printf("%d ", maze[i][j]); } printf("\n"); } printf("*********\n"); } typedef struct { int row, col; } element; element stack[512]; int top = -1; void push(element item) { stack[++top] = item; } element pop() { return stack[top--]; } int is_empty() { return top == -1; } void path() { int i, row, col, next_row, next_col; element position; maze[0][0] = 2; top = 0; stack[0].row = stack[0].col = 0; while (!is_empty()) { position = pop(); row = position.row; col = position.col; printf("(%d, %d)\n", row, col); if (row == MAX_ROW - 1 && col == MAX_COL - 1) { printf("Path found!\n"); return; } if (col+1 < MAX_COL && maze[row][col+1] == 0) { // right next_row = row; next_col = col+1; maze[next_row][next_col] = 2; position.row = next_row; position.col = next_col; push(position); } if (row+1 < MAX_ROW && maze[row+1][col] == 0) { // down next_row = row+1; next_col = col; maze[next_row][next_col] = 2; position.row = next_row; position.col = next_col; push(position); } if (col-1 >= 0 && maze[row][col-1] == 0) { // left next_row = row; next_col = col-1; maze[next_row][next_col] = 2; position.row = next_row; position.col = next_col; push(position); } if (row-1 >= 0 && maze[row-1][col] == 0) { // up next_row = row-1; next_col = col; maze[next_row][next_col] = 2; position.row = next_row; position.col = next_col; push(position); } print_maze(); } printf("Path not found\n"); } int main() { path(); return 0; } ``` 在上述代码中,我们定义了一个 `maze` 数组来表示迷宫,0 表示可以通过的路,1 表示障碍物,2 表示走过的路程。我们使用栈来记录已经走过的路径,并通过 `push()` 和 `pop()` 操作来实现栈的基本功能。在 `path()` 函数中,我们从起点开始遍历迷宫,如果找到了终点,则输出 "Path found!",否则输出 "Path not found"。 我们可以通过调用 `print_maze()` 函数来输出迷宫的状态,以及调用 `path()` 函数来寻找迷宫的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值