forked from OmarBazaraa/CNC-Machine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFlowSolver.h
155 lines (129 loc) · 3.53 KB
/
FlowSolver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#pragma once
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <exception>
#include <map>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
class FlowSolver
{
private:
/**
* Enum having all possible directions in Flow Game
* Note that they are in the same order of "dx" and "dy" arrays below
*/
enum direction {
DOWN,
UP,
RIGTH,
LEFT
};
/**
* Structure to hold the coordinates of a cell
*/
struct point {
int r; // Row
int c; // Column
point() {
r = c = 0;
}
point(int i, int j) {
r = i;
c = j;
}
bool operator==(const point& rhs) const {
return (r == rhs.r && c == rhs.c);
}
bool operator!=(const point& rhs) const {
return (r != rhs.r || c != rhs.c);
}
};
/**
* Structure to hold color intensity in RGB format
*/
struct colorRGB {
pair<int, pair<int, int>> vec;
colorRGB() {
}
colorRGB(int r, int g, int b) {
vec.first = r;
vec.second.first = g;
vec.second.second = b;
}
bool operator<(const colorRGB& rhs) const {
return vec < rhs.vec;
}
};
private:
const int EMPTY_BLOCK_COLOR = 0;
const int MAX_BACKGROUND_RGB = 100;
const int dx[4] = { 1, -1, 0, 0 };
const int dy[4] = { 0, 0, 1, -1 };
private:
Mat image;
int grid[25][25]; // Max 14x14 in Flow Game
int gridRowsCount, gridColsCount;
int horizontalBorderThickness, verticalBorderThickness;
int leftBorder, topBorder, bottomBorder;
int recursiveCalls = 0; // Just for statistical purposes
vector<pair<point, point>> colorPairs;
vector<vector<direction>> colorPathes;
public:
int singleBlockWidth, singleBlockHeight;
/**
* Constructor
*/
FlowSolver(const string& url);
/**
* Destructor
*/
~FlowSolver();
private:
/**
* Loads image from the given url into a matrix of colors
*/
bool loadImage(const string& url);
/**
* This function detects the game borders and the grid size
*/
void detectGameStructure();
/**
* This function fills the matrix corresponding to the image and the color pairs
*/
void initGameData();
/**
* Order color pairs in order to minimize the distance to switch from color to another
*/
void orderColorPairs(vector<pair<point, point>>& unorderedColorPairs);
public:
/**
* Prints the maze and a separation line after it
*/
void printMaze();
/**
* Prints the solution of the given maze
*/
string getSolutionPaths();
/**
* Solves the game and fills in the path of each given color in the grid
*/
void solve();
private:
/**
* Tries to solve the maze by checking all the available pathes and fills in the correct colors in the grid
* using depth first search (DFS) and backtracking
*/
bool _solve(int row, int col, int prvRow, int prvCol, int pairIdx);
/**
* Returns whether or not the given cell is inside the grid
*/
bool valid(int row, int col);
/**
* Returns whether the current grid state might be solvable
*/
bool solvable(int row, int col, int colorIdx);
};