写在前面

昨天生成障碍物,起点和终点的方法比较随意,今天重新想了个办法实现了生成不重复的二维坐标,将在后面进行介绍,同时完成了A*类的构建。

知识点

1:不重复二维坐标生成方法:

我将整张图的所有格点存到一个vector里面,然后将vector进行无序化,之后按顺序取出其中数据即可实现不重复的二维坐标获取,这样做主要是为了避免障碍物,起点,终点生成的随机点重复,实现如下所示(注意,#include <random>不要忘记了):

#include <random>
void Graph::set_obstacles_start_end()
{
    int total_block = graph_user_para.map_x * graph_user_para.map_y;
    obstacle = new Point[graph_user_para.obstacle_num];

    std::vector<Point> obstacle_vector;
    for (int i = 0; i < graph_user_para.map_x; i++) {
        for (int j = 0; j < graph_user_para.map_y; j++) {
            obstacle_vector.push_back(Point(i, j));
        }
    }

    std::random_device rd;
    std::mt19937 g(rd());
    std::shuffle(obstacle_vector.begin(), obstacle_vector.end(), rd);

    start = obstacle_vector[0];
    obstacle_vector.erase(obstacle_vector.begin());
    end = obstacle_vector[0];
    obstacle_vector.erase(obstacle_vector.begin());
    for (int i = 0; i < graph_user_para.obstacle_num; i++) {
        obstacle[i] = obstacle_vector[0];
        graph_user_para.map[obstacle[i].x][obstacle[i].y] = OBSTACLE;
        obstacle_vector.erase(obstacle_vector.begin());
    }

    graph_user_para.map[start.x][start.y] = START;
    graph_user_para.map[end.x][end.y] = END;


}

2:友元的使用。

友元的使用可以让其他类访问本类的私有数据。

3:C++的OOP特性只存在于编译时刻,编译之后生成的.o文件和C语言编译之后生成的.o文件一样。

图形界面变换

之前设计的地图格子太少了,所以今天我进行了更改,此时高集成度的代码的优势就体现出来了,我只修改了obstacle_num,block_size,map[60][30]这3个参数就完成了地图的修改,代码和效果如下图所示:

typedef struct _UserPara
{

    public:
        int win_width = 960;
        int win_height = 480;
        int block_size = 16;
        int obstacle_num = 400;
        int map[60][30] = { 0 };// 960/32 = 30, 480/32 = 15 
        int map_x = win_width / block_size;
        int map_y = win_height / block_size;

}UserPara;

红色方块是路径起点,绿色方块是路径终点。

A_star类设计

我单独设计了一个A_star类,并且将其做为Graph类的友类,这样A_star类就可以访问Graph类的私有变量,在A_star里面完成算法,在Graph类里进行图像显示。根据A_star算法的逻辑,我设置了如下A_star类的函数:

#pragma once
#include "Graph.h"

typedef struct _Node {
    bool in_open_set = false;
    bool in_close_set = false;
    bool walkable = true;
    Point  coordinate;
    _Node* pre = nullptr;
}Node;

class A_star
{
    public:
        A_star();
        ~A_star();
        int find_min_Fn();
        void add_closelist();
        void add_openlist();
        float get_Hn();
        float get_Gn();
        float cost();
        void get_env_node();
        bool check_end();
        void a_star();
        Point get_next();
    private:
        int Gn;
        int Hn;
        int Fn;

};

明天开始A*算法的逻辑设计。