Last active
October 19, 2018 22:28
-
-
Save ivancea/665f312d80e41a517911a6e3dfec2e99 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <queue> | |
#include "Image.h" | |
using namespace std; | |
enum Direction { | |
UP, | |
RIGHT, | |
DOWN, | |
LEFT | |
}; | |
struct Point { | |
int x; | |
int y; | |
Point(){} | |
Point(int _x, int _y) : x(_x), y(_y) {} | |
bool operator==(const Point& point){ | |
return point.x == x && point.y == y; | |
} | |
bool operator!=(const Point& point){ | |
return !operator==(point); | |
} | |
}; | |
ostream& operator<<(ostream& os, const Point& point){ | |
return os << "(" << point.x << ", " << point.y << ")"; | |
} | |
bool isBuilding(const Image& image, Point position){ | |
return position.x >= 0 && position.y >= 0 | |
&& position.x < image.getX() && position.y < image.getY() | |
&& image.get(position.x, position.y) == sf::Color::White; | |
} | |
vector<Point> getPath(const Image& image, Point initialPosition, Direction initialDirection){ | |
vector<Point> path; | |
path.push_back(initialPosition); | |
Direction currentDirection = initialDirection; | |
Point currentPosition = initialPosition; | |
do{ | |
switch(currentDirection){ | |
case UP: | |
if(isBuilding(image, Point{currentPosition.x, currentPosition.y - 1})){ | |
currentPosition.y -= 1; | |
currentDirection = LEFT; | |
}else{ | |
currentDirection = RIGHT; | |
} | |
break; | |
case RIGHT: | |
if(isBuilding(image, Point{currentPosition.x + 1, currentPosition.y})){ | |
currentPosition.x += 1; | |
currentDirection = UP; | |
}else{ | |
currentDirection = DOWN; | |
} | |
break; | |
case DOWN: | |
if(isBuilding(image, Point{currentPosition.x, currentPosition.y + 1})){ | |
currentPosition.y += 1; | |
currentDirection = RIGHT; | |
}else{ | |
currentDirection = LEFT; | |
} | |
break; | |
case LEFT: | |
if(isBuilding(image, Point{currentPosition.x - 1, currentPosition.y})){ | |
currentPosition.x -= 1; | |
currentDirection = DOWN; | |
}else{ | |
currentDirection = UP; | |
} | |
break; | |
} | |
if(path.back() != currentPosition){ | |
path.push_back(currentPosition); | |
} | |
}while(currentPosition != initialPosition || currentDirection != initialDirection); | |
if(path.size() > 1){ | |
path.pop_back(); | |
} | |
return path; | |
} | |
void clearBuilding(Image& image, Point position){ | |
queue<Point> toProcess; | |
toProcess.push(position); | |
do{ | |
Point point = toProcess.front(); | |
toProcess.pop(); | |
if(isBuilding(image, point)){ | |
image.set(point.x, point.y, sf::Color::Red); | |
toProcess.push(Point{point.x+1, point.y}); | |
toProcess.push(Point{point.x-1, point.y}); | |
toProcess.push(Point{point.x, point.y+1}); | |
toProcess.push(Point{point.x, point.y-1}); | |
} | |
}while(toProcess.size() > 0); | |
} | |
vector<Point> getBuilding(Image& image, Point position, Direction direction){ | |
vector<Point> path = getPath(image, position, direction); | |
clearBuilding(image, position); | |
return path; | |
} | |
int main(int argc, char** argv){ | |
if(argc != 2){ | |
cout << "First argument: file path" << endl; | |
return -1; | |
} | |
Image image; | |
cout << "Loading file: " << argv[1] << endl; | |
image.loadFromBMP(argv[1]); | |
if(!image.isValid()){ | |
cout << "ERROR: Couldn't load image" << endl; | |
return 1; | |
} | |
cout << "Processing buildings..." << endl; | |
for(int i=0; i<image.getX(); i++){ | |
for(int j=0; j<image.getY(); j++){ | |
if(image.get(i,j) == sf::Color::White){ | |
vector<Point> building = getBuilding(image, Point{i, j}, UP); | |
cout << "BUILDING FOUND:" << endl; | |
for(Point point : building){ | |
cout << point << endl; | |
} | |
cout << endl; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment