编程模拟行走机器人(Qt/C++实现)

参考力扣信息科技提供的算法
题目
机器人在一个无限大小的网格上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令:
-2:向左转 90 度
-1:向右转 90 度
1 <= x <= 9:向前移动 x 个单位长度
在网格上有一些格子被视为障碍物。
第 i 个障碍物位于网格点 (obstacles[i][0], obstacles[i][1])
如果机器人试图走到障碍物上方,那么它将停留在障碍物的前一个网格方块上,但仍然可以继续该路线的其余部分。
返回从原点到机器人的最大欧式距离的平方。
效果图
在这里插入图片描述
头文件

#ifndef ROBOTWALKFORM_H
#define ROBOTWALKFORM_H

/*
 * 编程模拟编程机器人(C++实现)
 * 简单粗略的写一下过程,以后酌情完善
 */

#include <QWidget>
#include <QPainter>
#include <QPaintEvent>

const int GRID_TICK_COUNT = 20;
const int DIR_X[] = {0, 1, 0, -1};
const int DIR_Y[] = {1, 0, -1, 0};

class RobotWalkForm : public QWidget
{
    Q_OBJECT
public:
    explicit RobotWalkForm(QWidget *parent = nullptr);
    ~RobotWalkForm();

    void startWalking(const QVector<int> &commands, const QVector<QVector<int>> &obstacles);
    void nextStep();
protected:
    void paintEvent(QPaintEvent *event);

signals:
    void squaredDistanceChanged(int distance);

public slots:

private:
    QColor m_bgColor;                       //背景颜色
    QColor m_GridLineColor;                 //网格路径颜色
    QColor m_moveLineColor;                 //移动路径颜色

    QPixmap m_robotPixmap;                  //机器人图片
    QPixmap m_obstaclePixmap;               //障碍物图片
    QPixmap m_DestinationPixmap;            //终点图片
    QPixmap m_startPointPixmap;             //起点图片

    int m_curOrderIndex;                    //当前指令索引
    int m_curX;                             //机器人当前位置X
    int m_curY;                             //机器人当前位置Y
    int m_curDir;                           //机器人当前方向
    int m_dis;                              //机器人距原点欧氏距离
    QVector<int> m_commands;                //机器指令
    QVector<QVector<int>> m_obstacles;      //障碍物位置
    QSet<QPair<int, int>> m_setObstacles;   //障碍物集合
};

#endif // ROBOTWALKFORM_H

cpp文件

#include "robotwalkform.h"
#include <QtMath>

RobotWalkForm::RobotWalkForm(QWidget *parent) : QWidget(parent)
{
    m_bgColor = Qt::lightGray;                              //背景颜色
    m_GridLineColor = Qt::black;                            //网格路径颜色
    m_moveLineColor = Qt::green;                            //移动路径颜色

    m_robotPixmap = QPixmap(":/RES/robot.png");             //机器人图片
    m_obstaclePixmap = QPixmap(":/RES/obstacle.png");       //障碍物图片
    m_DestinationPixmap = QPixmap(":/RES/Destination.png"); //终点图片
    m_startPointPixmap = QPixmap(":/RES/startPoint.png");   //起点图片

    m_curOrderIndex = 0;                                    //当前指令索引
    m_curX = 0;                                             //机器人当前位置X
    m_curY = 0;                                             //机器人当前位置Y
    m_curDir = 0;                                           //机器人当前方向
    m_dis = 0;                                              //机器人距原点欧氏距离的平方
    m_commands.clear();
}

RobotWalkForm::~RobotWalkForm()
{

}

void RobotWalkForm::startWalking(const QVector<int> &commands, const QVector<QVector<int> > &obstacles)
{
    m_commands = commands;
    m_obstacles = obstacles;

    m_curOrderIndex = 0;
    m_curX = 0;
    m_curY = 0;
    m_curDir = 0;
    m_dis = 0;

    for (int i = 0; i < obstacles.count(); i++)
        m_setObstacles.insert(QPair<int, int>(obstacles[i][0], obstacles[i][1]));

    update();
}

void RobotWalkForm::nextStep()
{
    if (m_curOrderIndex == m_commands.count())
        return;

    if(m_commands[m_curOrderIndex] == -1)
    {  //-1:向右转 90 度
        m_curDir = (m_curDir + 1) % 4;
    }
    else if(m_commands[m_curOrderIndex] == -2)
    {  //-2:向左转 90 度
        m_curDir = (m_curDir + 3) % 4;
    }
    else
    {  //1 <= x <= 9:向前移动 x 个单位长度
        for(int j=0;j<m_commands[m_curOrderIndex];j++)
        {
            //试图走出一步,并判断是否遇到了障碍物,
            int nx = m_curX + DIR_X[m_curDir];
            int ny = m_curY + DIR_Y[m_curDir];
            //当前坐标不是障碍点,计算并与存储的最大欧式距离的平方做比较
            if (!m_setObstacles.contains(QPair<int, int>(nx, ny)))
            {
                m_curX = nx;
                m_curY = ny;
                m_dis = qMax(m_dis, m_curX * m_curX + m_curY * m_curY);
            }
            else
            {
                //是障碍点,被挡住了,停留,只能等待下一个指令,那可以跳出当前指令了
                break;
            }
        }
    }
    emit squaredDistanceChanged(m_dis);
    update();

    m_curOrderIndex++;
}

void RobotWalkForm::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    //绘制背景
    painter.setPen(Qt::NoPen);
    painter.setBrush(m_bgColor);
    painter.drawRect(rect());
    //坐标平移、缩放
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);
    painter.translate(width / 2, height / 2);
    painter.scale(side / 200.0, side / 200.0);
    //绘制网格
    painter.setPen(QPen(m_GridLineColor, 1));
    painter.setBrush(Qt::NoBrush);
    int tickWidth = 200.0 / GRID_TICK_COUNT;
    qreal startX = -100;
    qreal startY = -100;
    for (int i = 0; i <= GRID_TICK_COUNT; i++)
    {
        //纵线
        QPointF topPoint = QPointF(startX + i * tickWidth, -100);
        QPointF bottomPoint = QPointF(startX + i *tickWidth, 100);
        painter.drawLine(topPoint, bottomPoint);
        //横线
        QPointF leftPoint = QPointF(-100, startY + i * tickWidth);
        QPointF rightPoint = QPointF(100, startY + i * tickWidth);
        painter.drawLine(leftPoint, rightPoint);
    }

    //绘制原点
    if (m_curX != 0 || m_curY != 0)
    {
        painter.drawPixmap(-tickWidth / 2.0, -tickWidth / 2.0, tickWidth, tickWidth, m_startPointPixmap);
    }
    //绘制机器人方向+位置
    int rotate = 0;
    if (1 == m_curDir)
        rotate = 90;
    else if (2 == m_curDir)
        rotate = 180;
    else if (3 == m_curDir)
        rotate = 270;
    QPointF robotPos = QPointF(m_curX * tickWidth, m_curY * tickWidth);
    QPixmap robotPixmap = m_robotPixmap;
    QMatrix matrix;
    matrix.rotate(rotate);
    robotPixmap = robotPixmap.transformed(matrix, Qt::FastTransformation);
    painter.drawPixmap(robotPos.x() - tickWidth / 2.0, -(robotPos.y() + tickWidth / 2.0), tickWidth, tickWidth, robotPixmap);
    //绘制障碍物绘制
    for (int i = 0; i < m_obstacles.count(); i++)
    {
        QPointF center = QPointF(m_obstacles[i][0] * tickWidth, m_obstacles[i][1] * tickWidth);
        painter.drawPixmap(center.x() - tickWidth / 2.0, -(center.y() + tickWidth / 2.0), tickWidth, tickWidth, m_obstaclePixmap);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮生卍流年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值