gpt4 book ai didi

c++ - 如何在 C++ 中使用 A* 追溯路径?

转载 作者:行者123 更新时间:2023-11-28 01:52:24 25 4
gpt4 key购买 nike

<分区>

数周以来,我一直在尝试实现 A*,以便敌人可以在我的游戏中追逐玩家,但我无法让它发挥作用。我整个周末都在研究它,最后我什至把它的大部分内容都删掉了,然后重新写了一遍。我可以画出一条从起点到终点的路径,但我无法追溯回去,就像实际写下路径一样。我正在使用来自 SFML 的 Vector2f(有序的一对 float )和 Sprite,但那里的所有代码都非常简单,因此您真的不需要理解它。

编辑:问题出在 Node.cameFrom 上。出于某种原因,它只计算墙壁以外的任何东西。

这是 Node.h

#ifndef NODE_H
#define NODE_H
#include <SFML/Graphics.hpp>

using namespace sf;

class Node {
public:
Vector2f pos;
// Distance traveled already to reach node
int level;
// Level + estimated dist to goal
int priority;

Node *cameFrom;

Node(Vector2f npos, int lv, Vector2f dest, Node *cf=nullptr);

bool operator == (const Node &nhs) const {
return nhs.priority == priority;
}

};

#endif // NODE_H

节点.cpp

#include "Node.h"
#include <SFML/Graphics.hpp>
#include <math.h>
#include <iostream>

using namespace std;
using namespace sf;

int estimatedDist(Vector2f pos, Vector2f dest) {
return abs(dest.x - pos.x) + abs(dest.y - pos.y);
}

Node::Node(Vector2f npos, int lv, Vector2f dest, Node *cf) {
cameFrom = cf;
level = lv;
pos = npos;
priority = level + estimatedDist(pos, dest);
}

Enemy.cpp 寻路函数

bool occupies(Vector2f pos, vector<Wall> walls) {
for (unsigned w = 0; w < walls.size(); w++) {
if (walls.at(w).collisionBox.getGlobalBounds().contains(pos.x * 32, pos.y * 32)) {
return true;
}
}
return false;
}

bool nFind(Node n, vector<Node> nodes) {
for (unsigned i = 0; i < nodes.size(); i++) {
if (nodes.at(i).pos == n.pos) {
return true;
}
}
return false;
}

void Enemy::pathFind(Vector2f dest, vector<Wall> walls) {
char fullMap[32][22];
vector<Node> openSet;
vector<Node> closedSet;
int xStart, yStart;
for (unsigned y = 0; y < 22; y++) {
for (unsigned x = 0; x < 32; x++) {
if (sprite.getGlobalBounds().top >= y * 32 && sprite.getGlobalBounds().top <= (y + 1) * 32) {
if (sprite.getGlobalBounds().left >= x * 32 && sprite.getGlobalBounds().left <= (x + 1) * 32) {
xStart = x;
yStart = y;
}
} if (occupies(Vector2f(x, y), walls)) {
fullMap[x][y] = '2';
} else {
fullMap[x][y] = ' ';
}
}
}
fullMap[int(dest.x)][int(dest.y)] = 'D';
Node *current = new Node(Vector2f(xStart, yStart), 0, dest);
fullMap[int(current->pos.x)][int(current->pos.y)] = '2';
openSet.push_back(*current);

while (openSet.size() > 0) {
sort(openSet.begin(), openSet.end(), sortByPriority());
*current = openSet.front();

if (current->pos == dest) {
cout << "We gots it ";
for (unsigned y = 0; y < 22; y++) {
for (unsigned x = 0; x < 32; x++) {
if (occupies(Vector2f(x, y), walls)) {
fullMap[x][y] = '2';
} else {
fullMap[x][y] = ' ';
}
}
}
while (current->cameFrom) {
fullMap[int(current->pos.x)][int(current->pos.y)] = 'P';
current = current->cameFrom;
for (unsigned y = 0; y < 22; y++) {
for (unsigned x = 0; x < 32; x++) {
cout << fullMap[x][y];
}
cout << endl;
}
cout << endl;
} for (unsigned y = 0; y < 22; y++) {
for (unsigned x = 0; x < 32; x++) {
cout << fullMap[x][y];
}
cout << endl;
}
cout << endl;
return;
}

openSet.erase(remove(openSet.begin(), openSet.end(), *current), openSet.end());
closedSet.push_back(*current);
fullMap[int(current->pos.x)][int(current->pos.y)] = '2';

vector<Node> neighbors;

neighbors.push_back(Node(Vector2f(current->pos.x - 1, current->pos.y - 1), current->level + 1, dest));
neighbors.push_back(Node(Vector2f(current->pos.x, current->pos.y - 1), current->level + 1, dest));
neighbors.push_back(Node(Vector2f(current->pos.x + 1, current->pos.y - 1), current->level + 1, dest));
neighbors.push_back(Node(Vector2f(current->pos.x + 1, current->pos.y), current->level + 1, dest));
neighbors.push_back(Node(Vector2f(current->pos.x + 1, current->pos.y + 1), current->level + 1, dest));
neighbors.push_back(Node(Vector2f(current->pos.x, current->pos.y + 1), current->level + 1, dest));
neighbors.push_back(Node(Vector2f(current->pos.x - 1, current->pos.y + 1), current->level + 1, dest));
neighbors.push_back(Node(Vector2f(current->pos.x - 1, current->pos.y), current->level + 1, dest));

for (unsigned i = 0; i < neighbors.size(); i++) {
if (nFind(neighbors.at(i), closedSet) ||
neighbors.at(i).pos.x > 22 ||
neighbors.at(i).pos.y > 32 ||
neighbors.at(i).pos.x < 0 ||
neighbors.at(i).pos.y < 0 ||
occupies(neighbors.at(i).pos, walls)) {

continue;
} if (!nFind(neighbors.at(i), openSet)) {
openSet.push_back(neighbors.at(i));
}
neighbors.at(i).cameFrom = current;
}
}
}

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com