参考力扣信息科技提供的算法
题目
机器人在一个无限大小的网格上行走,从点 (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);
}
}