refactored Djikstra's algorithm's implementation to use map cells

This commit is contained in:
devZoGok
2023-09-03 09:55:23 +03:00
parent 9ca9bf8e09
commit 4e5c539519
5 changed files with 39 additions and 39 deletions
+11
View File
@@ -20,6 +20,17 @@ using namespace gameBase;
namespace battleship{
using namespace configData;
//TODO check if edges have lower weight than impassible weight value for the Pathfinder
int Map::Cell::getEdgeWeight(int destCellId){
int weight = Pathfinder::getSingleton()->getImpassibleNodeVal();
for(Edge e : edges)
if(e.destCellId == destCellId)
weight = e.weight;
return weight;
}
Map *map = nullptr;
Map* Map::getSingleton(){
+1
View File
@@ -36,6 +36,7 @@ namespace battleship{
Cell(){}
Cell(vb01::Vector3 p, Type t, std::vector<Edge> e = std::vector<Edge>{}): pos(p), type(t), edges(e){}
int getEdgeWeight(int);
};
static Map* getSingleton();
+5 -12
View File
@@ -2,7 +2,6 @@
#include <iostream>
#include "pathfinder.h"
#include "map.h"
namespace battleship{
using namespace std;
@@ -20,21 +19,15 @@ namespace battleship{
Pathfinder::Pathfinder(){
}
vector<int> Pathfinder::findPath(u32 **weights, int size, int source, int dest){
vector<int> Pathfinder::findPath(vector<Map::Cell> &cells, int source, int dest){
int size = cells.size();
u32 distances[size];
vector<int> paths[size];
paths[source].push_back(source);
for(int i = 0; i < size; i++){
for(int i = 0; i < size; i++)
distances[i] = (i == source ? 0 : impassibleNodeVal);
for(int j = 0; j < size; j++)
if(weights[i][j] > impassibleNodeVal){
cout << "Node val higher than allowed max value\n";
exit(-1);
}
}
vector<int> checkedNodes;
while(find(checkedNodes.begin(), checkedNodes.end(), dest) == checkedNodes.end()){
@@ -60,8 +53,8 @@ namespace battleship{
for(int i = 0; i < size; i++){
bool isChecked = find(checkedNodes.begin(), checkedNodes.end(), i) != checkedNodes.end();
if(!isChecked && (distances[vertStrich] + weights[vertStrich][i] < distances[i])){
distances[i] = distances[vertStrich] + weights[vertStrich][i];
if(!isChecked && (distances[vertStrich] + cells[vertStrich].getEdgeWeight(i) < distances[i])){
distances[i] = distances[vertStrich] + cells[vertStrich].getEdgeWeight(i);
paths[i] = paths[vertStrich];
paths[i].push_back(i);
}
+3 -1
View File
@@ -1,6 +1,8 @@
#ifndef PATHFINDER_H
#define PATHFINDER_H
#include "map.h"
#include <vector>
#include <util.h>
@@ -9,7 +11,7 @@ namespace battleship{
class Pathfinder{
public:
static Pathfinder* getSingleton();
std::vector<int> findPath(vb01::u32**, int, int, int);
std::vector<int> findPath(std::vector<Map::Cell>&, int, int);
inline vb01::u32 getImpassibleNodeVal(){return impassibleNodeVal;}
inline void setImpassibleNodeVal(vb01::u32 val){this->impassibleNodeVal = val;}
private:
+19 -26
View File
@@ -1,5 +1,6 @@
#include "pathfinderTest.h"
#include "pathfinder.h"
#include "map.h"
#include <util.h>
@@ -10,36 +11,28 @@ namespace battleship{
using namespace vb01;
void PathfinderTest::testFindPath(){
int size = 7;
const u16 INF = u16(0 - 1);
//pathfinder->setImpassibleNodeVal(INF);
u32 w[size][size] = {
{0, 2, 4, INF, INF, INF, INF},
{INF, 0, 1, 9, 13, INF, INF},
{INF, 2, 0, INF, 4, 5, INF},
{INF, INF, INF, 0, INF, INF, 1},
{1, INF, INF, 1, 0, INF, 3},
{INF, INF, INF, INF, 9, 0, 2},
{INF, INF, INF, INF, INF, INF, 0}
};
u32 **weights = new u32*[size];
vector<Map::Cell> cells = vector<Map::Cell>{
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 0, 0), Map::Edge(2, 0, 1), Map::Edge(4, 0, 2)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 1, 1), Map::Edge(1, 1, 2), Map::Edge(9, 1, 3), Map::Edge(13, 1, 4)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 2, 2), Map::Edge(2, 2, 1), Map::Edge(4, 2, 4), Map::Edge(5, 2, 5)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 3, 3), Map::Edge(1, 3, 6)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 4, 4), Map::Edge(1, 4, 0), Map::Edge(1, 4, 3), Map::Edge(3, 4, 6)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 5, 5), Map::Edge(9, 5, 4), Map::Edge(2, 5, 6)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 6, 6)})
};
for(int i = 0; i < size; i++){
weights[i] = new u32[size];
int size = cells.size();
const u16 INF = u16(0 - 1);
pathfinder->setImpassibleNodeVal(INF);
vector<int> path = pathfinder->findPath(cells, 0, size - 1);
CPPUNIT_ASSERT(path == vector<int>({0, 1, 2, 4, 3, 6}));
for(int j = 0; j < size; j++)
weights[i][j] = w[i][j];
}
int sumPathWeights = 0;
vector<int> path = pathfinder->findPath(weights, size, 0, size - 1);
CPPUNIT_ASSERT(path == vector<int>({0, 1, 2, 4, 3, 6}));
for(int i = 1; i < path.size(); i++)
sumPathWeights += cells[path[i - 1]].getEdgeWeight(path[i]);
int sumPathWeights = 0;
for(int i = 1; i < size; i++)
sumPathWeights += w[path[i - 1]][path[i]];
CPPUNIT_ASSERT(sumPathWeights == 9);
CPPUNIT_ASSERT(sumPathWeights == 9);
}
void PathfinderTest::setUp(){