Prettied it up, comments, refactors

master
MitchellHansen 9 years ago
parent 8fc8db2d78
commit ee6ea3442d

@ -16,12 +16,13 @@ void App::Init() {
// Set up the background texture // Set up the background texture
background_texture = new sf::Texture(); background_texture = new sf::Texture();
background_texture->loadFromFile("background.png"); background_texture->loadFromFile("background.png");
backgroundSprite.setTexture(*background_texture); backgroundSprite.setTexture(*background_texture);
// Pixel array for drawing the tiles, explorer
_pixelArray = new sf::Uint8[WINDOW_WIDTH * WINDOW_HEIGHT * 4]; _pixelArray = new sf::Uint8[WINDOW_WIDTH * WINDOW_HEIGHT * 4];
pixel_array_texture.create(WINDOW_WIDTH, WINDOW_HEIGHT); pixel_array_texture.create(WINDOW_WIDTH, WINDOW_HEIGHT);
// Create the explorer, giving it a reference to the map data
explorer = new Explorer(&map); explorer = new Explorer(&map);
} }
@ -29,6 +30,8 @@ void App::Input() {
while (window->pollEvent(event)) { while (window->pollEvent(event)) {
if (event.type == sf::Event::Closed) if (event.type == sf::Event::Closed)
window->close(); window->close();
// Set the destination
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) { if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
sf::Vector2i mouse_position = sf::Mouse::getPosition(*window); sf::Vector2i mouse_position = sf::Mouse::getPosition(*window);
explorer->setDestination(sf::Vector2i(mouse_position.x/ 5, mouse_position.y/ 5)); explorer->setDestination(sf::Vector2i(mouse_position.x/ 5, mouse_position.y/ 5));
@ -49,7 +52,10 @@ void App::Input() {
} }
void App::Update(double step_size) { void App::Update(double step_size) {
Input(); Input();
// Have the explorer go one move forward
explorer->move(); explorer->move();
} }
@ -57,6 +63,7 @@ void App::Render() {
// HOUSEKEEPING // HOUSEKEEPING
// Get the physics fps for the last render cycle // Get the physics fps for the last render cycle
physics_fps = physics_frame_count * render_fps; physics_fps = physics_frame_count * render_fps;
@ -70,23 +77,28 @@ void App::Render() {
// RENDERING // RENDERING
// Clear and draw a fresh background
window->clear(sf::Color::Blue); window->clear(sf::Color::Blue);
window->draw(backgroundSprite); window->draw(backgroundSprite);
sf::Vector2i pos; // Clean up the pixel array and reset everything to 0's again
for (int i = 0; i < WINDOW_WIDTH * WINDOW_HEIGHT * 4; i++) { for (int i = 0; i < WINDOW_WIDTH * WINDOW_HEIGHT * 4; i++) {
_pixelArray[i] = 0; _pixelArray[i] = 0;
} }
// Draw the tiles // Color all the tiles
for (int x = 0; x < Map::CELLS_WIDTH; x++) { for (int x = 0; x < Map::CELLS_WIDTH; x++) {
for (int y = 0; y < Map::CELLS_HEIGHT; y++) { for (int y = 0; y < Map::CELLS_HEIGHT; y++) {
// Get the current cell position
sf::Vector2i pos;
pos.x = x; pos.x = x;
pos.y = y; pos.y = y;
sf::Color thing = map.getTile(pos)->getColor();
// Use that to find the color of the tile at that position
sf::Color thing = map.getTile(pos)->getColor();
// Fill the 4x4 pixel area taken up by the cell
for (int x2 = 1; x2 < 5; x2++) { for (int x2 = 1; x2 < 5; x2++) {
for (int y2 = 1; y2 < 5; y2++) { for (int y2 = 1; y2 < 5; y2++) {
@ -104,6 +116,7 @@ void App::Render() {
} }
// Draw the explorer // Draw the explorer
// Basically the same as above, fills 4x4 area where the explorer is located
for (int x2 = 1; x2 < 5; x2++) { for (int x2 = 1; x2 < 5; x2++) {
for (int y2 = 1; y2 < 5; y2++) { for (int y2 = 1; y2 < 5; y2++) {
@ -120,11 +133,12 @@ void App::Render() {
} }
} }
// Update and draw the pixel array
pixel_array_texture.update(_pixelArray); pixel_array_texture.update(_pixelArray);
pixel_array_sprite.setTexture(pixel_array_texture); pixel_array_sprite.setTexture(pixel_array_texture);
window->draw(pixel_array_sprite); window->draw(pixel_array_sprite);
// Finish!
window->display(); window->display();
} }

@ -3,6 +3,7 @@
#include "Map.h" #include "Map.h"
#include "Explorer.h" #include "Explorer.h"
// 2d heap allocated array structure stolen off of stackOverflow
template<typename T, int width, int height> template<typename T, int width, int height>
class MultiArray { class MultiArray {
private: private:
@ -13,8 +14,10 @@ public:
MultiArray() { data = new cols[width]; } MultiArray() { data = new cols[width]; }
~MultiArray() { delete[] data; } ~MultiArray() { delete[] data; }
}; };
class App { class App {
public: public:
// Constants // Constants
static const int WINDOW_HEIGHT = 766; static const int WINDOW_HEIGHT = 766;
static const int WINDOW_WIDTH = 1596; static const int WINDOW_WIDTH = 1596;
@ -28,18 +31,21 @@ public:
private: private:
// Map and its data
Map map; Map map;
sf::Uint8* _pixelArray;
sf::Sprite pixel_array_sprite;
sf::Texture pixel_array_texture;
// The explorer that will traverse the map
Explorer* explorer; Explorer* explorer;
// Art assets // Art assets
sf::Texture* background_texture; sf::Texture* background_texture;
sf::Sprite backgroundSprite; sf::Sprite backgroundSprite;
// Data required for hand drawing pixels
sf::Uint8* _pixelArray;
sf::Sprite pixel_array_sprite;
sf::Texture pixel_array_texture;
void Init(); void Init();
void Input(); void Input();
void Update(double step_size); void Update(double step_size);
@ -50,7 +56,7 @@ private:
// The events for the event handler // The events for the event handler
sf::Event event; sf::Event event;
// Loop management data, black magic, need to redo // ============= Loop data ==================
float time(); float time();
// Size of the physics steps to take // Size of the physics steps to take

@ -3,7 +3,7 @@
#include "Pather.h" #include "Pather.h"
Explorer::Explorer(Map* map_) { Explorer::Explorer(Map* map_) {
color = sf::Color::Blue; color = sf::Color::Yellow;
position = sf::Vector2i(6, 10); position = sf::Vector2i(6, 10);
map = map_; map = map_;
} }
@ -22,12 +22,12 @@ sf::Color Explorer::getColor() {
void Explorer::setDestination(sf::Vector2i destination_) { void Explorer::setDestination(sf::Vector2i destination_) {
// Call a* to get path
plan(destination_); plan(destination_);
} }
bool Explorer::move() { bool Explorer::move() {
// While there are moves for us to take // While there are moves for us to take
if (!movement_stack.empty()) { if (!movement_stack.empty()) {
bool valid = false; // If the next move is valid, collision bool valid = false; // If the next move is valid, collision
@ -35,9 +35,9 @@ bool Explorer::move() {
switch (x) { switch (x) {
case 0: // North case 0: // North
if (!map->getTile(position.x, position.y - 1)->isSolid()) { if (!map->getTile(position.x, position.y - 1)->isSolid()) { // If the tile isn't solid
valid = true; valid = true; // Set the move to valid
position = sf::Vector2i(position.x, position.y - 1); position = sf::Vector2i(position.x, position.y - 1); // Update the Explorers position
} }
break; break;
case 1: // East case 1: // East
@ -79,10 +79,13 @@ bool Explorer::move() {
return false; return false;
} }
// A*
bool Explorer::plan(sf::Vector2i destination_) { bool Explorer::plan(sf::Vector2i destination_) {
// Create a new pather with the map data
Pather pather(map); Pather pather(map);
movement_stack = pather.pathTo(position, destination_);
// Get the movement list from the pather
movement_stack = pather.getPathTo(position, destination_);
return true; return true;
} }

@ -5,18 +5,33 @@
class Explorer { class Explorer {
public: public:
// Constructors
Explorer(Map* map_); Explorer(Map* map_);
~Explorer(); ~Explorer();
// Getters
sf::Vector2i getPosition(); sf::Vector2i getPosition();
sf::Color getColor(); sf::Color getColor();
// Move to the specified destination
void setDestination(sf::Vector2i destination_); void setDestination(sf::Vector2i destination_);
// Follow the pathlist for one move
bool move(); bool move();
private: private:
// Color that will be drawn
sf::Color color; sf::Color color;
sf::Vector2i position; sf::Vector2i position;
// Reference to the map data
Map* map; Map* map;
// Moves list that will be filled with plan(), and executed by move()
std::deque<int> movement_stack; std::deque<int> movement_stack;
// Fills the movement stack with moves
bool plan(sf::Vector2i destination_); bool plan(sf::Vector2i destination_);
}; };

@ -10,41 +10,64 @@ Map::Map() {
Map::~Map() { Map::~Map() {
} }
Tile* Map::getTile(sf::Vector2i position_) { Tile* Map::getTile(sf::Vector2i position_) {
// If the position is within bounds
if (position_.x > CELLS_WIDTH || position_.x < 0 if (position_.x > CELLS_WIDTH || position_.x < 0
|| position_.y > CELLS_HEIGHT || position_.y < 0) { || position_.y > CELLS_HEIGHT || position_.y < 0) {
return nullptr; return nullptr;
} }
else
return tileArray[position_.x][position_.y]; // Return the value specified
return tileArray[position_.x][position_.y];
} }
bool Map::isTileSolid(sf::Vector2i position_) { bool Map::isTileSolid(sf::Vector2i position_) {
// If the position is within bounds
if (position_.x >= CELLS_WIDTH || position_.x < 0 if (position_.x >= CELLS_WIDTH || position_.x < 0
|| position_.y >= CELLS_HEIGHT || position_.y < 0) { || position_.y >= CELLS_HEIGHT || position_.y < 0) {
return true; return true; // If it isn't say that the tile is solid
} }
else else
// Return whether the tile is solid
return tileArray[position_.x][position_.y]->isSolid(); return tileArray[position_.x][position_.y]->isSolid();
} }
Tile* Map::getTile(int x_, int y_) { Tile* Map::getTile(int x_, int y_) {
return tileArray[x_][y_];
// If the position is within bounds
if (x_ > CELLS_WIDTH || x_ < 0
|| y_ > CELLS_HEIGHT || y_ < 0) {
return nullptr;
}
else
// Return the value specified
return tileArray[x_][y_];
} }
void Map::setTile(sf::Vector2i position, Tile* data) { void Map::overwriteTile(sf::Vector2i position_, Tile* data) {
delete tileArray[position.x][position.y]; // If the position is within bounds
tileArray[position.x][position.y] = data; if (position_.x >= CELLS_WIDTH || position_.x < 0
|| position_.y >= CELLS_HEIGHT || position_.y < 0) {
return; // If it isn't just return
}
else { // If it is, then delete the old data, replace it with the new
delete tileArray[position_.x][position_.y];
tileArray[position_.x][position_.y] = data;
}
} }
void Map::Init() { void Map::Init() {
// Fill up the map with a random scatter of solid and passable tiles
int q; int q;
for (int x = 0; x < CELLS_WIDTH; x++) { for (int x = 0; x < CELLS_WIDTH; x++) {
for (int y = 0; y < CELLS_HEIGHT; y++) { for (int y = 0; y < CELLS_HEIGHT; y++) {
q = rand() % 100; q = rand() % 100;
if (q > 90) { if (q > 65) {
tileArray[x][y] = new Tile(true, 100.0, sf::Color::Cyan); tileArray[x][y] = new Tile(true, 100.0, sf::Color::Cyan);
} }
else { else {

@ -4,21 +4,27 @@
class Map { class Map {
public: public:
// Width and height of the map in individual cells
static const int CELLS_HEIGHT = 153; static const int CELLS_HEIGHT = 153;
static const int CELLS_WIDTH = 319; static const int CELLS_WIDTH = 319;
// Constructors
Map(); Map();
~Map(); ~Map();
// Get the tile at the specified position, overloaded
Tile* getTile(sf::Vector2i position); Tile* getTile(sf::Vector2i position);
Tile* getTile(int x_, int y_); Tile* getTile(int x_, int y_);
bool isTileSolid(sf::Vector2i); bool isTileSolid(sf::Vector2i);
void setTile(sf::Vector2i position, Tile* data);
// completely replaces the data at the specified position
void overwriteTile(sf::Vector2i position, Tile* data);
private: private:
void Init(); void Init();
// Data
Tile* tileArray[319][153]; Tile* tileArray[319][153];
}; };

@ -1,137 +1,46 @@
#include "Pather.h" #include "Pather.h"
#include <iostream> #include <iostream>
node::node(sf::Vector2i XY, double h, int cF, int cL, node* p, Pather* pather_) {
xy = XY;
hueristic = h;
cameFrom = cF;
closedList = cL;
parent = p;
pather = pather_;
}
node::node() {
}
node::~node() {
}
void node::neighbors() {
int x = pather->getEndNodePosition().x;
int y = pather->getEndNodePosition().y;
sf::Vector2i dest0XY(xy.x, xy.y - 1); // North
if (!pather->map->isTileSolid(dest0XY) && pather->visitedMap(dest0XY.x, dest0XY.y) != 1) {
// If so, find the distance between this node and the end node, the hueristic
int tempx = (x - dest0XY.x);
int tempy = (y - dest0XY.y);
// I think dv is the hueristic??
double dv = sqrt((tempx * tempx) + (tempy * tempy));
double v = dv;
// Take that value and create a new node
pather->openList.emplace(new node(dest0XY, v, 0, 1, pather->active_node, pather), v);
// Set that tile as visited so we don't get stuck in a loop
pather->visitedMap(dest0XY.x, dest0XY.y) = 1;
}
sf::Vector2i dest1XY(xy.x + 1, xy.y); // East
if (!pather->map->isTileSolid(dest1XY) && pather->visitedMap(dest1XY.x, dest1XY.y) != 1) {
// If so, find the distance between this node and the end node, the hueristic
int tempx = (x - dest1XY.x);
int tempy = (y - dest1XY.y);
// I think dv is the hueristic??
double dv = sqrt((tempx * tempx) + (tempy * tempy));
double v = dv;
// Take that value and create a new node
pather->openList.emplace(new node(dest1XY, v, 1, 1, pather->active_node, pather), v);
// Set that tile as visited so we don't get stuck in a loop
pather->visitedMap(dest1XY.x, dest1XY.y) = 1;
}
sf::Vector2i dest2XY(xy.x, xy.y + 1); // South
if (!pather->map->isTileSolid(dest2XY) && pather->visitedMap(dest2XY.x, dest2XY.y) != 1) {
// If so, find the distance between this node and the end node, the hueristic
int tempx = (x - dest2XY.x);
int tempy = (y - dest2XY.y);
// I think dv is the hueristic??
double dv = sqrt((tempx * tempx) + (tempy * tempy));
double v = dv;
// Take that value and create a new node
pather->openList.emplace(new node(dest2XY, v, 2, 1, pather->active_node, pather), v);
// Set that tile as visited so we don't get stuck in a loop
pather->visitedMap(dest2XY.x, dest2XY.y) = 1;
}
sf::Vector2i dest3XY(xy.x - 1, xy.y); // West
if (!pather->map->isTileSolid(dest3XY) && pather->visitedMap(dest3XY.x, dest3XY.y) != 1) {
// If so, find the distance between this node and the end node, the hueristic
int tempx = (x - dest3XY.x);
int tempy = (y - dest3XY.y);
// I think dv is the hueristic??
double dv = sqrt((tempx * tempx) + (tempy * tempy));
double v = dv;
// Take that value and create a new node
pather->openList.emplace(new node(dest3XY, v, 3, 1, pather->active_node, pather), v);
// Set that tile as visited so we don't get stuck in a loop
pather->visitedMap(dest3XY.x, dest3XY.y) = 1;
}
}
Pather::Pather(Map* map_) { Pather::Pather(Map* map_) {
map = map_; map = map_;
//visitedMap = new MultiArray<int, App::WINDOW_HEIGHT, App::WINDOW_WIDTH>();
} }
Pather::~Pather() { Pather::~Pather() {
} }
sf::Vector2i Pather::getEndNodePosition() { sf::Vector2i Pather::getEndNodePosition() {
return end_node->xy; return end_node->getPosition();
} }
std::deque<int> Pather::pathTo(sf::Vector2i start, sf::Vector2i end) { node* Pather::getActiveNode() {
return active_node;
}
std::deque<int> Pather::getPathTo(sf::Vector2i start, sf::Vector2i end) {
// Clear the visited map for erroneous data // Clear the visited map of erroneous data
for (int i = 0; i < Map::CELLS_WIDTH; i++) { for (int i = 0; i < Map::CELLS_WIDTH; i++) {
for (int l = 0; l < Map::CELLS_HEIGHT; l++) { for (int l = 0; l < Map::CELLS_HEIGHT; l++) {
visitedMap(i, l) = 0; visited_map(i, l) = 0;
} }
} }
std::cout << visitedMap(10, 163);
// Place the start and end nodes // Place the start and end nodes
start_node = new node(start, 7000, 0, 0, nullptr, this); start_node = new node(start, 7000, 0, nullptr, this);
end_node = new node(end, 0, 0, 0, nullptr, this); end_node = new node(end, 0, 0, nullptr, this);
// Set the entry point, clean up any stray data from last run // Set the entry point, clean up any stray data from last run
active_node = start_node; active_node = start_node;
openList.clear(); open_list.clear();
closedList.clear(); closed_list.clear();
// Seed for the loop // Seed for the loop, hueristic is intentionally high
openList.emplace(start_node, start_node->hueristic); open_list.emplace(start_node, start_node->getHueristic());
// Set up the early exit, and enter into the loop
early_exit = false; early_exit = false;
path_list = loop(); path_list = loop();
@ -141,26 +50,29 @@ std::deque<int> Pather::pathTo(sf::Vector2i start, sf::Vector2i end) {
std::deque<int> Pather::loop() { std::deque<int> Pather::loop() {
// Damn thing keeps falling out of scope while (!open_list.empty() && !early_exit) {
while (!openList.empty() && !early_exit) { if (closed_list.size() > 1000) { // Quits when the path gets to be over 1000 long, janky
// Early exit jankyness, need to change this no_path = true; // Signal no path was found
if (closedList.size() > 1000) { early_exit = true; // Break
no_path = true;
early_exit = true;
break; break;
} }
if (active_node->xy.x == end_node->xy.x && active_node->xy.y == end_node->xy.y) {
// Check to see if we're at our destination, break if we are
if (active_node->getPosition().x == end_node->getPosition().x && active_node->getPosition().y == end_node->getPosition().y) {
early_exit = true; early_exit = true;
break; break;
} }
// If we didn't get held up before, do a round of a*
else { else {
// Find the pair with the lowest hueristic // Find the pair with the lowest hueristic
// 5/10 std::pair<node*, double> bestMin(start_node, 10000); // Get a clean value for the comparison
std::pair<node*, double> bestMin(start_node, 10000);
for (auto testMin: openList) { // Compare all the values in openList for the one with the smallest hueristic
// O(n) complexity so it can get verrrrryyyy slow
for (auto testMin: open_list) {
if (bestMin.second >= testMin.second) if (bestMin.second >= testMin.second)
bestMin = testMin; bestMin = testMin;
} }
@ -169,22 +81,23 @@ std::deque<int> Pather::loop() {
active_node = bestMin.first; active_node = bestMin.first;
// Find the neighbors for that node // Find the neighbors for that node
active_node->neighbors(); active_node->getNewNeighbors();
// Remove the active node from the openlist as you have visited it and called its neighbors // Remove the active node from the openlist as you have visited it and called its neighbors
openList.erase(active_node); open_list.erase(active_node);
// Check to see if the node has already been added to the closed list, if not, add it // Check to see if the node has already been added to the closed list, if not, add it
if (closedList.count(active_node) == 0) { if (closed_list.count(active_node) == 0) {
closedList.emplace(active_node, active_node->hueristic); closed_list.emplace(active_node, active_node->getHueristic());
} }
} }
} }
// When we're done, get the return path
std::deque<int> return_path = returnPath(); std::deque<int> return_path = returnPath();
if (no_path || return_path.empty()) { if (no_path || return_path.empty()) { // If we had an error, display it
return std::deque<int>(); return std::deque<int>();
std::cout << " no return path " << std::endl; std::cout << " no return path " << std::endl;
} }
@ -193,12 +106,14 @@ std::deque<int> Pather::loop() {
} }
std::deque<int> Pather::returnPath() { std::deque<int> Pather::returnPath() {
// Deque that will be returned
std::deque<int> path; std::deque<int> path;
while (active_node->parent != nullptr) { // Backtrack through the active_nodes, adding their cameFrom value to the deque
path.push_back(active_node->cameFrom); while (active_node->getParent() != nullptr) {
path.push_back(active_node->getCameFrom());
node* parent = active_node->parent; node* parent = active_node->getParent();
delete active_node; delete active_node;
active_node = parent; active_node = parent;
} }

@ -2,58 +2,54 @@
#include <map> #include <map>
#include "App.h" #include "App.h"
#include <unordered_map> #include <unordered_map>
#include "node.h"
class Pather;
class node {
public:
node(sf::Vector2i XY, double h, int cF, int cL, node* p, Pather* pather_);
node();
~node();
sf::Vector2i xy;
// Ugh, pointers, ugh c++
node* parent;
double hueristic;
int cameFrom;
int closedList;
Pather* pather;
void neighbors();
private:
};
class Pather { class Pather {
public: public:
// Constructor
Pather(Map* map_); Pather(Map* map_);
~Pather(); ~Pather();
// Reference to the map data
Map* map; Map* map;
std::unordered_map<node*, double> openList; // Containers for the loop, probably inefficient as hell
std::unordered_map<node*, double> closedList; std::unordered_map<node*, double> open_list;
std::unordered_map<node*, double> closed_list;
MultiArray<int, Map::CELLS_WIDTH , Map::CELLS_HEIGHT> visitedMap; // A stack allocated 2d array from a template I stole from stackOverflow
//int visitedMap[App::WINDOW_HEIGHT][App::WINDOW_WIDTH]; MultiArray<int, Map::CELLS_WIDTH , Map::CELLS_HEIGHT> visited_map;
std::deque<int> pathTo(sf::Vector2i start, sf::Vector2i end); // Return a deque with the movement info to path to the end position from the start position
std::deque<int> loop(); std::deque<int> getPathTo(sf::Vector2i start, sf::Vector2i end);
std::deque<int> returnPath();
// Returns the end node of the current path
sf::Vector2i getEndNodePosition(); sf::Vector2i getEndNodePosition();
node* start_node; // Returns the current active node
node* active_node; node* getActiveNode();
private:
// Whether we couldn't find a path
bool no_path = false; bool no_path = false;
// If we found the path and can exit early
bool early_exit; bool early_exit;
private: // Calculate the return path from back tracing the active nodes
std::deque<int> returnPath();
// The main iterative loop for a*
std::deque<int> loop();
// Movement list for the Explorer
std::deque<int> path_list; std::deque<int> path_list;
// Start positions node
node* start_node;
// Current positions node
node* active_node;
// End positions node
node* end_node; node* end_node;
}; };

@ -160,6 +160,7 @@
<ClCompile Include="Explorer.cpp" /> <ClCompile Include="Explorer.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="Map.cpp" /> <ClCompile Include="Map.cpp" />
<ClCompile Include="node.cpp" />
<ClCompile Include="Pather.cpp" /> <ClCompile Include="Pather.cpp" />
<ClCompile Include="Tile.cpp" /> <ClCompile Include="Tile.cpp" />
</ItemGroup> </ItemGroup>
@ -170,6 +171,9 @@
<ClInclude Include="Pather.h" /> <ClInclude Include="Pather.h" />
<ClInclude Include="Tile.h" /> <ClInclude Include="Tile.h" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="node.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

@ -33,6 +33,9 @@
<ClCompile Include="Pather.cpp"> <ClCompile Include="Pather.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="node.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="App.h"> <ClInclude Include="App.h">
@ -51,4 +54,7 @@
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="node.h" />
</ItemGroup>
</Project> </Project>

@ -1,11 +1,9 @@
#pragma once #include "Pather.h"
#include "node.h"
node::node(sf::Vector2i XY, int h, int cF, int cL, node* p, Pather* pather_) { node::node(sf::Vector2i XY, double h, int cF, node* p, Pather* pather_) {
xy = XY; position = XY;
hueristic = h; hueristic = h;
cameFrom = cF; came_from = cF;
closedList = cL;
parent = p; parent = p;
pather = pather_; pather = pather_;
} }
@ -16,13 +14,14 @@ node::~node() {
} }
void node::neighbors() { void node::getNewNeighbors() {
// Get the end node position for calculating distance from end(hueristic)
int x = pather->getEndNodePosition().x; int x = pather->getEndNodePosition().x;
int y = pather->getEndNodePosition().y; int y = pather->getEndNodePosition().y;
sf::Vector2i dest0XY(xy.x, xy.y - 1); // North sf::Vector2i dest0XY(position.x, position.y - 1); // North
if (!pather->map->isTileSolid(dest0XY) && pather->visitedMap[dest0XY.x][dest0XY.y] != 1) { if (!pather->map->isTileSolid(dest0XY) && pather->visited_map(dest0XY.x, dest0XY.y) != 1) {
// If so, find the distance between this node and the end node, the hueristic // If so, find the distance between this node and the end node, the hueristic
int tempx = (x - dest0XY.x); int tempx = (x - dest0XY.x);
int tempy = (y - dest0XY.y); int tempy = (y - dest0XY.y);
@ -30,17 +29,17 @@ void node::neighbors() {
// I think dv is the hueristic?? // I think dv is the hueristic??
double dv = sqrt((tempx * tempx) + (tempy * tempy)); double dv = sqrt((tempx * tempx) + (tempy * tempy));
int v = static_cast<int>(dv); double v = dv;
// Take that value and create a new node // Take that value and create a new node
pather->openList.emplace(new node(dest0XY, v, 0, 1, pather->active_node, pather), v); pather->open_list.emplace(new node(dest0XY, v, 0, pather->getActiveNode(), pather), v);
// Set that tile as visited so we don't get stuck in a loop // Set that tile as visited so we don't get stuck in a loop
pather->visitedMap[dest0XY.x][dest0XY.y] = 1; pather->visited_map(dest0XY.x, dest0XY.y) = 1;
} }
sf::Vector2i dest1XY(xy.x + 1, xy.y); // East sf::Vector2i dest1XY(position.x + 1, position.y); // East
if (!pather->map->isTileSolid(dest1XY) && pather->visitedMap[dest1XY.x][dest1XY.y] != 1) { if (!pather->map->isTileSolid(dest1XY) && pather->visited_map(dest1XY.x, dest1XY.y) != 1) {
// If so, find the distance between this node and the end node, the hueristic // If so, find the distance between this node and the end node, the hueristic
int tempx = (x - dest1XY.x); int tempx = (x - dest1XY.x);
int tempy = (y - dest1XY.y); int tempy = (y - dest1XY.y);
@ -48,17 +47,17 @@ void node::neighbors() {
// I think dv is the hueristic?? // I think dv is the hueristic??
double dv = sqrt((tempx * tempx) + (tempy * tempy)); double dv = sqrt((tempx * tempx) + (tempy * tempy));
int v = static_cast<int>(dv); double v = dv;
// Take that value and create a new node // Take that value and create a new node
pather->openList.emplace(new node(dest1XY, v, 0, 1, pather->active_node, pather), v); pather->open_list.emplace(new node(dest1XY, v, 1, pather->getActiveNode(), pather), v);
// Set that tile as visited so we don't get stuck in a loop // Set that tile as visited so we don't get stuck in a loop
pather->visitedMap[dest1XY.x][dest1XY.y] = 1; pather->visited_map(dest1XY.x, dest1XY.y) = 1;
} }
sf::Vector2i dest2XY(xy.x, xy.y + 1); // South sf::Vector2i dest2XY(position.x, position.y + 1); // South
if (!pather->map->isTileSolid(dest2XY) && pather->visitedMap[dest2XY.x][dest2XY.y] != 1) { if (!pather->map->isTileSolid(dest2XY) && pather->visited_map(dest2XY.x, dest2XY.y) != 1) {
// If so, find the distance between this node and the end node, the hueristic // If so, find the distance between this node and the end node, the hueristic
int tempx = (x - dest2XY.x); int tempx = (x - dest2XY.x);
int tempy = (y - dest2XY.y); int tempy = (y - dest2XY.y);
@ -66,17 +65,17 @@ void node::neighbors() {
// I think dv is the hueristic?? // I think dv is the hueristic??
double dv = sqrt((tempx * tempx) + (tempy * tempy)); double dv = sqrt((tempx * tempx) + (tempy * tempy));
int v = static_cast<int>(dv); double v = dv;
// Take that value and create a new node // Take that value and create a new node
pather->openList.emplace(new node(dest2XY, v, 0, 1, pather->active_node, pather), v); pather->open_list.emplace(new node(dest2XY, v, 2, pather->getActiveNode(), pather), v);
// Set that tile as visited so we don't get stuck in a loop // Set that tile as visited so we don't get stuck in a loop
pather->visitedMap[dest2XY.x][dest2XY.y] = 1; pather->visited_map(dest2XY.x, dest2XY.y) = 1;
} }
sf::Vector2i dest3XY(xy.x - 1, xy.y); // West sf::Vector2i dest3XY(position.x - 1, position.y); // West
if (!pather->map->isTileSolid(dest3XY) && pather->visitedMap[dest3XY.x][dest3XY.y] != 1) { if (!pather->map->isTileSolid(dest3XY) && pather->visited_map(dest3XY.x, dest3XY.y) != 1) {
// If so, find the distance between this node and the end node, the hueristic // If so, find the distance between this node and the end node, the hueristic
int tempx = (x - dest3XY.x); int tempx = (x - dest3XY.x);
int tempy = (y - dest3XY.y); int tempy = (y - dest3XY.y);
@ -84,12 +83,28 @@ void node::neighbors() {
// I think dv is the hueristic?? // I think dv is the hueristic??
double dv = sqrt((tempx * tempx) + (tempy * tempy)); double dv = sqrt((tempx * tempx) + (tempy * tempy));
int v = static_cast<int>(dv); double v = dv;
// Take that value and create a new node // Take that value and create a new node
pather->openList.emplace(new node(dest3XY, v, 0, 1, pather->active_node, pather), v); pather->open_list.emplace(new node(dest3XY, v, 3, pather->getActiveNode(), pather), v);
// Set that tile as visited so we don't get stuck in a loop // Set that tile as visited so we don't get stuck in a loop
pather->visitedMap[dest3XY.x][dest3XY.y] = 1; pather->visited_map(dest3XY.x, dest3XY.y) = 1;
} }
} }
sf::Vector2i node::getPosition() {
return position;
}
node* node::getParent() {
return parent;
}
double node::getHueristic() {
return hueristic;
}
int node::getCameFrom() {
return came_from;
}

@ -1,26 +1,44 @@
#pragma once #pragma once
#include <SFML/Graphics.hpp> #include <map>
#include "App.h" #include "App.h"
#include <unordered_map>
class Pather;
class node { class node {
public: public:
node(sf::Vector2i XY, int h, int cF, int cL, node* p, Pather* pather_); // XY position, hueristic value, cameFrom direction, parent, ref to pather
node(sf::Vector2i position_, double hueristic_, int came_from_, node* parent_, Pather* pather_);
node(); node();
~node(); ~node();
sf::Vector2i xy;
// Ugh, pointers, ugh c++
node* parent;
int hueristic;
int cameFrom;
int closedList;
Pather* pather;
void neighbors(); // Populate the open_list with neighbors
void getNewNeighbors();
// HAS THE ABILITY TO DELETE THE PARENT!!
node* getParent();
sf::Vector2i getPosition();
double getHueristic();
int getCameFrom();
private: private:
// Position of the node
sf::Vector2i position;
}; // The parent of the node, previous one visited
node* parent;
// How close it is to the destination
double hueristic;
// What direction the parent was
int came_from;
// Ref to pather
Pather* pather;
};
Loading…
Cancel
Save