Yeah, this really isn't wanting to work. Gonna need to probably redo everything

master
MitchellHansen 9 years ago
parent 47fee51b08
commit 17207d8294

@ -30,8 +30,14 @@ void App::Input() {
if (event.type == sf::Event::Closed) if (event.type == sf::Event::Closed)
window->close(); window->close();
if (event.type == sf::Event::KeyPressed) { if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Space) { if (event.key.code == sf::Keyboard::Q) {
explorer->setDestination(sf::Vector2i(20, 20));
}
if (event.key.code == sf::Keyboard::W) {
explorer->setDestination(sf::Vector2i(200, 200));
}
if (event.key.code == sf::Keyboard::E) {
explorer->setDestination(sf::Vector2i(100, 12));
} }
} }
} }
@ -39,6 +45,7 @@ void App::Input() {
void App::Update(double step_size) { void App::Update(double step_size) {
Input(); Input();
explorer->move();
} }
void App::Render() { void App::Render() {
@ -91,7 +98,7 @@ void App::Render() {
} }
} }
// Draw the player // Draw the explorer
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++) {

@ -3,6 +3,16 @@
#include "Map.h" #include "Map.h"
#include "Explorer.h" #include "Explorer.h"
template<typename T, int width, int height>
class MultiArray {
private:
typedef T cols[height];
cols * data;
public:
T& operator() (int x, int y) { return data[x][y]; }
MultiArray() { data = new cols[width]; }
~MultiArray() { delete[] data; }
};
class App { class App {
public: public:
// Constants // Constants

@ -1,9 +1,10 @@
#include "Explorer.h" #include "Explorer.h"
#include <iostream> #include <iostream>
#include "Pather.h"
Explorer::Explorer(Map* map_) { Explorer::Explorer(Map* map_) {
color = sf::Color::Blue; color = sf::Color::Blue;
position = sf::Vector2i(10, 10); position = sf::Vector2i(6, 10);
map = map_; map = map_;
} }
@ -19,34 +20,41 @@ sf::Color Explorer::getColor() {
return color; return color;
} }
void Explorer::setDestination(sf::Vector2i 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
int x = movement_stack.top(); int x = movement_stack.back();
switch (x) { switch (x) {
case 0:
break;
case 0: // North case 1: // North
if (!map->getTile(position.x, position.y - 1)->isSolid()) { if (!map->getTile(position.x, position.y - 1)->isSolid()) {
valid = true; valid = true;
position = sf::Vector2i(position.x, position.y - 1); position = sf::Vector2i(position.x, position.y - 1);
} }
break; break;
case 1: // East case 2: // East
if (!map->getTile(position.x + 1, position.y)->isSolid()) { if (!map->getTile(position.x + 1, position.y)->isSolid()) {
valid = true; valid = true;
position = sf::Vector2i(position.x + 1, position.y); position = sf::Vector2i(position.x + 1, position.y);
} }
break; break;
case 2: // South case 3: // South
if (!map->getTile(position.x, position.y + 1)->isSolid()) { if (!map->getTile(position.x, position.y + 1)->isSolid()) {
valid = true; valid = true;
position = sf::Vector2i(position.x, position.y + 1); position = sf::Vector2i(position.x, position.y + 1);
} }
break; break;
case 3: // West case 4: // West
if (!map->getTile(position.x - 1, position.y)->isSolid()) { if (!map->getTile(position.x - 1, position.y)->isSolid()) {
valid = true; valid = true;
position = sf::Vector2i(position.x - 1, position.y); position = sf::Vector2i(position.x - 1, position.y);
@ -58,14 +66,14 @@ bool Explorer::move() {
if (!valid) { if (!valid) {
std::cout << "Path blocked" << std::endl; std::cout << "Path blocked" << std::endl;
// Flush the moves list // Flush the moves list
while(!movement_stack.empty()) { while (!movement_stack.empty()) {
movement_stack.pop(); movement_stack.pop_back();
} }
return false; return false;
} }
// If everything went well, pop and return true // If everything went well, pop and return true
movement_stack.pop(); movement_stack.pop_back();
return true; return true;
} }
else else
@ -74,7 +82,8 @@ bool Explorer::move() {
// A* // A*
bool Explorer::plan(sf::Vector2i destination_) { bool Explorer::plan(sf::Vector2i destination_) {
Pather pather(map);
movement_stack = pather.pathTo(position, destination_);
return true; return true;
} }

@ -9,13 +9,14 @@ public:
~Explorer(); ~Explorer();
sf::Vector2i getPosition(); sf::Vector2i getPosition();
sf::Color getColor(); sf::Color getColor();
void setDestination(sf::Vector2i destination_);
bool move();
private: private:
sf::Color color; sf::Color color;
sf::Vector2i position; sf::Vector2i position;
Map* map; Map* map;
std::stack<int> movement_stack; std::deque<int> movement_stack;
bool move();
bool plan(sf::Vector2i destination_); bool plan(sf::Vector2i destination_);
}; };

@ -22,8 +22,8 @@ Tile* Map::getTile(sf::Vector2i position_) {
} }
bool Map::isTileSolid(sf::Vector2i position_) { bool Map::isTileSolid(sf::Vector2i position_) {
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;
} }
else else
@ -44,7 +44,7 @@ void Map::Init() {
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 > 70) { if (q > 90) {
tileArray[x][y] = new Tile(true, 100.0, sf::Color::Cyan); tileArray[x][y] = new Tile(true, 100.0, sf::Color::Cyan);
} }
else { else {

@ -1,7 +1,7 @@
#include "Pather.h" #include "Pather.h"
#include <iostream> #include <iostream>
node::node(sf::Vector2i XY, int h, int cF, int cL, node* p, Pather* pather_) { node::node(sf::Vector2i XY, double h, int cF, int cL, node* p, Pather* pather_) {
xy = XY; xy = XY;
hueristic = h; hueristic = h;
cameFrom = cF; cameFrom = cF;
@ -22,7 +22,7 @@ void node::neighbors() {
int y = pather->getEndNodePosition().y; int y = pather->getEndNodePosition().y;
sf::Vector2i dest0XY(xy.x, xy.y - 1); // North sf::Vector2i dest0XY(xy.x, xy.y - 1); // North
if (!pather->map->isTileSolid(dest0XY) && pather->visitedMap[dest0XY.x][dest0XY.y] != 1) { 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 // 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 +30,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->openList.emplace(new node(dest0XY, v, 3, 1, pather->active_node, 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->visitedMap(dest0XY.x, dest0XY.y) = 1;
} }
sf::Vector2i dest1XY(xy.x + 1, xy.y); // East sf::Vector2i dest1XY(xy.x + 1, xy.y); // East
if (!pather->map->isTileSolid(dest1XY) && pather->visitedMap[dest1XY.x][dest1XY.y] != 1) { 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 // 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 +48,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->openList.emplace(new node(dest1XY, v, 4, 1, pather->active_node, 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->visitedMap(dest1XY.x, dest1XY.y) = 1;
} }
sf::Vector2i dest2XY(xy.x, xy.y + 1); // South sf::Vector2i dest2XY(xy.x, xy.y + 1); // South
if (!pather->map->isTileSolid(dest2XY) && pather->visitedMap[dest2XY.x][dest2XY.y] != 1) { 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 // 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 +66,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->openList.emplace(new node(dest2XY, v, 1, 1, pather->active_node, 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->visitedMap(dest2XY.x, dest2XY.y) = 1;
} }
sf::Vector2i dest3XY(xy.x - 1, xy.y); // West sf::Vector2i dest3XY(xy.x - 1, xy.y); // West
if (!pather->map->isTileSolid(dest3XY) && pather->visitedMap[dest3XY.x][dest3XY.y] != 1) { 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 // 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,13 +84,13 @@ 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->openList.emplace(new node(dest3XY, v, 2, 1, pather->active_node, 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->visitedMap(dest3XY.x, dest3XY.y) = 1;
} }
} }
@ -98,6 +98,7 @@ void node::neighbors() {
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() {
@ -109,15 +110,18 @@ sf::Vector2i Pather::getEndNodePosition() {
std::deque<int> Pather::pathTo(sf::Vector2i start, sf::Vector2i end) { std::deque<int> Pather::pathTo(sf::Vector2i start, sf::Vector2i end) {
// Clear the visited map for erroneous data // Clear the visited map for 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; visitedMap(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, 0, 0, 0, nullptr, this); start_node = new node(start, 7000, 0, 0, nullptr, this);
end_node = new node(end, 0, 0, 0, nullptr, this); end_node = new node(end, 0, 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
@ -126,7 +130,7 @@ std::deque<int> Pather::pathTo(sf::Vector2i start, sf::Vector2i end) {
closedList.clear(); closedList.clear();
// Seed for the loop // Seed for the loop
openList.emplace(start_node, 0); openList.emplace(start_node, start_node->hueristic);
early_exit = false; early_exit = false;
path_list = loop(); path_list = loop();
@ -136,26 +140,34 @@ 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 (!openList.empty() && !early_exit) { while (!openList.empty() && !early_exit) {
// Early exit jankyness, need to change this // Early exit jankyness, need to change this
if (closedList.size() > 3000) { //if (closedList.size() > 3000) {
no_path = true; // no_path = true;
early_exit = true; // early_exit = true;
break; // break;
} //}
else if (active_node->xy.x == end_node->xy.x && end_node->xy.y == end_node->xy.y) { if (active_node->xy.x == end_node->xy.x && active_node->xy.y == end_node->xy.y) {
early_exit = true; early_exit = true;
break; break;
} }
else { else {
// Find the pair with the lowest hueristic // Find the pair with the lowest hueristic
// 5/10 // 5/10
std::pair<node*, int> bestMin; std::pair<node*, double> bestMin(start_node, 10000);
for (auto testMin: openList) { for (auto testMin: openList) {
if (bestMin.second < testMin.second) if (bestMin.second >= testMin.second)
bestMin = testMin; bestMin = testMin;
} }
// Set the new active node to the lowest hueristic that we found earlier
active_node = bestMin.first;
// Find the neighbors for that node // Find the neighbors for that node
active_node->neighbors(); active_node->neighbors();
@ -163,12 +175,11 @@ std::deque<int> Pather::loop() {
openList.erase(active_node); openList.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 (closedList.count(active_node) == 0) {
closedList.emplace(active_node, active_node->hueristic); closedList.emplace(active_node, active_node->hueristic);
} }
// Set the new active node to the lowest hueristic that we found earlier
active_node = bestMin.first;
} }
} }
@ -184,10 +195,12 @@ std::deque<int> Pather::loop() {
std::deque<int> Pather::returnPath() { std::deque<int> Pather::returnPath() {
std::deque<int> path; std::deque<int> path;
while (active_node != nullptr) { while (active_node->parent != nullptr) {
path.push_back(active_node->cameFrom); path.push_back(active_node->cameFrom);
node* parent = active_node->parent;
delete active_node; delete active_node;
active_node = active_node->parent; active_node = parent;
} }
return path; return path;

@ -8,7 +8,7 @@ class Pather;
class node { class node {
public: public:
node(sf::Vector2i XY, int h, int cF, int cL, node* p, Pather* pather_); node(sf::Vector2i XY, double h, int cF, int cL, node* p, Pather* pather_);
node(); node();
~node(); ~node();
@ -16,7 +16,7 @@ public:
// Ugh, pointers, ugh c++ // Ugh, pointers, ugh c++
node* parent; node* parent;
int hueristic; double hueristic;
int cameFrom; int cameFrom;
int closedList; int closedList;
Pather* pather; Pather* pather;
@ -33,9 +33,11 @@ public:
Map* map; Map* map;
std::unordered_map<node*, int> openList; std::unordered_map<node*, double> openList;
std::unordered_map<node*, int> closedList; std::unordered_map<node*, double> closedList;
int visitedMap[App::WINDOW_HEIGHT][App::WINDOW_WIDTH];
MultiArray<int, Map::CELLS_WIDTH , Map::CELLS_HEIGHT> visitedMap;
//int visitedMap[App::WINDOW_HEIGHT][App::WINDOW_WIDTH];
std::deque<int> pathTo(sf::Vector2i start, sf::Vector2i end); std::deque<int> pathTo(sf::Vector2i start, sf::Vector2i end);
std::deque<int> loop(); std::deque<int> loop();

@ -0,0 +1,95 @@
#pragma once
#include "node.h"
node::node(sf::Vector2i XY, int 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));
int v = static_cast<int>(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));
int v = static_cast<int>(dv);
// Take that value and create a new node
pather->openList.emplace(new node(dest1XY, v, 0, 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));
int v = static_cast<int>(dv);
// Take that value and create a new node
pather->openList.emplace(new node(dest2XY, v, 0, 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));
int v = static_cast<int>(dv);
// Take that value and create a new node
pather->openList.emplace(new node(dest3XY, v, 0, 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;
}
}

@ -0,0 +1,26 @@
#pragma once
#include <SFML/Graphics.hpp>
#include "App.h"
class node {
public:
node(sf::Vector2i XY, int h, int cF, int cL, node* p, Pather* pather_);
node();
~node();
sf::Vector2i xy;
// Ugh, pointers, ugh c++
node* parent;
int hueristic;
int cameFrom;
int closedList;
Pather* pather;
void neighbors();
private:
};
Loading…
Cancel
Save