diff options
Diffstat (limited to 'ext/wittle_generator/Generate.h')
-rw-r--r-- | ext/wittle_generator/Generate.h | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/ext/wittle_generator/Generate.h b/ext/wittle_generator/Generate.h new file mode 100644 index 0000000..c28a47d --- /dev/null +++ b/ext/wittle_generator/Generate.h | |||
@@ -0,0 +1,248 @@ | |||
1 | #ifndef GENERATE_H_0582FCEA | ||
2 | #define GENERATE_H_0582FCEA | ||
3 | |||
4 | #include <stdlib.h> | ||
5 | #include <time.h> | ||
6 | |||
7 | #include <algorithm> | ||
8 | #include <memory> | ||
9 | #include <set> | ||
10 | #include <string> | ||
11 | |||
12 | #include "Panel.h" | ||
13 | #include "PuzzleSymbols.h" | ||
14 | #include "Random.h" | ||
15 | |||
16 | typedef std::set<Point> Shape; | ||
17 | |||
18 | // The main class for generating puzzles. | ||
19 | class Generate { | ||
20 | public: | ||
21 | Generate() { | ||
22 | _width = _height = 0; | ||
23 | _areaTotal = _genTotal = _totalPuzzles = _areaPuzzles = _stoneTypes = 0; | ||
24 | _fullGaps = _bisect = _allowNonMatch = false; | ||
25 | _panel = NULL; | ||
26 | _parity = -1; | ||
27 | colorblind = false; | ||
28 | _seed = Random::rand(); | ||
29 | arrowColor = backgroundColor = successColor = {0, 0, 0, 0}; | ||
30 | resetConfig(); | ||
31 | } | ||
32 | enum Config { // See configinfo.txt for explanations of config flags. | ||
33 | None = 0, | ||
34 | FullGaps = 0x1, | ||
35 | StartEdgeOnly = 0x2, | ||
36 | DisableWrite = 0x4, | ||
37 | PreserveStructure = 0x8, | ||
38 | MakeStonesUnsolvable = 0x10, | ||
39 | SmallShapes = 0x20, | ||
40 | DisconnectShapes = 0x40, | ||
41 | ResetColors = 0x80, | ||
42 | DisableCancelShapes = 0x100, | ||
43 | RequireCancelShapes = 0x200, | ||
44 | BigShapes = 0x400, | ||
45 | SplitShapes = 0x800, | ||
46 | RequireCombineShapes = 0x1000, | ||
47 | TreehouseLayout = 0x2000, | ||
48 | TreehouseColors = 0x4000, | ||
49 | AlternateColors = 0x8000, | ||
50 | WriteColors = 0x10000, | ||
51 | Write2Color = 0x20000, | ||
52 | FixBackground = 0x40000, | ||
53 | CombineErasers = 0x80000, | ||
54 | LongPath = 0x100000, | ||
55 | ShortPath = 0x200000, | ||
56 | EnableFlash = 0x400000, | ||
57 | DecorationsOnly = 0x800000, | ||
58 | FalseParity = 0x1000000, | ||
59 | DisableDotIntersection = 0x2000000, | ||
60 | WriteDotColor = 0x4000000, | ||
61 | WriteDotColor2 = 0x8000000, | ||
62 | LongestPath = 0x10000000, | ||
63 | WriteInvisible = 0x20000000, | ||
64 | DisableReset = 0x40000000, | ||
65 | MountainFloorH = 0x80000000 | ||
66 | }; | ||
67 | |||
68 | void generate(int width, int height, PuzzleSymbols symbols); | ||
69 | |||
70 | /*void generateMaze(int id); | ||
71 | void generateMaze(int id, int numStarts, int numExits);*/ | ||
72 | void initPanel(); | ||
73 | void setPath(const std::set<Point>& path) { | ||
74 | customPath = path; | ||
75 | for (Point p : path) setSymbol(IntersectionFlags::PATH, p.first, p.second); | ||
76 | } | ||
77 | void setObstructions(const std::vector<Point>& walls) { | ||
78 | _obstructions = {walls}; | ||
79 | } | ||
80 | void setObstructions(const std::vector<std::vector<Point>>& walls) { | ||
81 | _obstructions = walls; | ||
82 | } | ||
83 | void setSymbol(Decoration::Shape symbol, int x, int y); | ||
84 | void setSymbol(IntersectionFlags symbol, int x, int y) { | ||
85 | setSymbol(static_cast<Decoration::Shape>(symbol), x, y); | ||
86 | } | ||
87 | void setGridSize(int width, int height); | ||
88 | void setSymmetry(Panel::Symmetry symmetry); | ||
89 | void write(int id); | ||
90 | void setFlag(Config option) { _config |= option; }; | ||
91 | void setFlagOnce(Config option) { | ||
92 | _config |= option; | ||
93 | _oneTimeAdd |= option; | ||
94 | }; | ||
95 | bool hasFlag(Config option) { return _config & option; }; | ||
96 | void removeFlag(Config option) { _config &= ~option; }; | ||
97 | void removeFlagOnce(Config option) { | ||
98 | _config &= ~option; | ||
99 | _oneTimeRemove |= option; | ||
100 | }; | ||
101 | void resetConfig(); | ||
102 | void seed(long seed) { | ||
103 | Random::seed(seed); | ||
104 | _seed = Random::rand(); | ||
105 | } | ||
106 | |||
107 | float pathWidth; // Controls how thick the line is on the puzzle | ||
108 | std::vector<Point> hitPoints; // The generated path will be forced to hit | ||
109 | // these points in order | ||
110 | std::set<Point> | ||
111 | openPos; // Custom set of points that can have symbols placed on | ||
112 | std::set<Point> blockPos; // Point that must be left open | ||
113 | std::set<Point> customPath; | ||
114 | Color arrowColor, backgroundColor, successColor; // For the arrow puzzles | ||
115 | |||
116 | private: | ||
117 | int get_symbol_type(int flags) { return flags & 0x700; } | ||
118 | void set_path(Point pos); | ||
119 | Point get_sym_point(Point pos) { return _panel->get_sym_point(pos); } | ||
120 | int get_parity(Point pos) { return (pos.first / 2 + pos.second / 2) % 2; } | ||
121 | void clear(); | ||
122 | void resetVars(); | ||
123 | void init_treehouse_layout(); | ||
124 | template <class T> | ||
125 | T pick_random(const std::vector<T>& vec) { | ||
126 | return vec[Random::rand() % vec.size()]; | ||
127 | } | ||
128 | template <class T> | ||
129 | T pick_random(const std::set<T>& set) { | ||
130 | auto it = set.begin(); | ||
131 | std::advance(it, Random::rand() % set.size()); | ||
132 | return *it; | ||
133 | } | ||
134 | template <class T> | ||
135 | T pop_random(const std::vector<T>& vec) { | ||
136 | int i = Random::rand() % vec.size(); | ||
137 | T item = vec[i]; | ||
138 | vec.erase(vec.begin() + i); | ||
139 | return item; | ||
140 | } | ||
141 | template <class T> | ||
142 | T pop_random(const std::set<T>& set) { | ||
143 | T item = pick_random(set); | ||
144 | set.erase(item); | ||
145 | return item; | ||
146 | } | ||
147 | bool on_edge(Point p) { | ||
148 | return (p.first == 0 || p.first + 1 == _panel->width() || p.second == 0 || | ||
149 | p.second + 1 == _panel->height()); | ||
150 | } | ||
151 | bool off_edge(Point p) { | ||
152 | return (p.first < 0 || p.first >= _panel->width() || p.second < 0 || | ||
153 | p.second >= _panel->height()); | ||
154 | } | ||
155 | static std::vector<Point> _DIRECTIONS1, _8DIRECTIONS1, _DIRECTIONS2, | ||
156 | _8DIRECTIONS2, _SHAPEDIRECTIONS, _DISCONNECT; | ||
157 | // bool generate_maze(int id, int numStarts, int numExits); | ||
158 | bool generateInternal(int width, int height, PuzzleSymbols symbols); | ||
159 | bool place_all_symbols(PuzzleSymbols& symbols); | ||
160 | bool generate_path(PuzzleSymbols& symbols); | ||
161 | bool generate_path_length(int minLength, int maxLength); | ||
162 | bool generate_path_length(int minLength) { | ||
163 | return generate_path_length(minLength, 10000); | ||
164 | }; | ||
165 | bool generate_path_regions(int minRegions); | ||
166 | bool generate_longest_path(); | ||
167 | bool generate_special_path(); | ||
168 | void erase_path(); | ||
169 | Point adjust_point(Point pos); | ||
170 | std::set<Point> get_region(Point pos); | ||
171 | std::vector<int> get_symbols_in_region(Point pos); | ||
172 | std::vector<int> get_symbols_in_region(const std::set<Point>& region); | ||
173 | bool place_start(int amount); | ||
174 | bool place_exit(int amount); | ||
175 | bool can_place_gap(Point pos); | ||
176 | bool place_gaps(int amount); | ||
177 | bool can_place_dot(Point pos, bool intersectionOnly); | ||
178 | bool place_dots(int amount, Decoration::Color color, bool intersectionOnly); | ||
179 | bool can_place_stone(const std::set<Point>& region, int color); | ||
180 | bool place_stones(int color, int amount); | ||
181 | Shape generate_shape(std::set<Point>& region, std::set<Point>& bufferRegion, | ||
182 | Point pos, int maxSize); | ||
183 | Shape generate_shape(std::set<Point>& region, Point pos, int maxSize) { | ||
184 | std::set<Point> buffer; | ||
185 | return generate_shape(region, buffer, pos, maxSize); | ||
186 | } | ||
187 | int make_shape_symbol(Shape shape, bool rotated, bool negative, int rotation, | ||
188 | int depth); | ||
189 | int make_shape_symbol(const Shape& shape, bool rotated, bool negative) { | ||
190 | return make_shape_symbol(shape, rotated, negative, -1, 0); | ||
191 | } | ||
192 | bool place_shapes(const std::vector<int>& colors, | ||
193 | const std::vector<int>& negativeColors, int amount, | ||
194 | int numRotated, int numNegative); | ||
195 | int count_color(const std::set<Point>& region, int color); | ||
196 | bool place_stars(int color, int amount); | ||
197 | bool has_star(const std::set<Point>& region, int color); | ||
198 | bool checkStarZigzag(); | ||
199 | bool place_triangles(int color, int amount, int targetCount); | ||
200 | int count_sides(Point pos); | ||
201 | bool place_arrows(int color, int amount, int targetCount); | ||
202 | int count_crossings(Point pos, Point dir); | ||
203 | bool place_erasers(const std::vector<int>& colors, | ||
204 | const std::vector<int>& eraseSymbols); | ||
205 | bool combine_shapes(std::vector<Shape>& shapes); | ||
206 | |||
207 | bool hasSymbolOrPath(const Point& pos) { | ||
208 | return hasSymbolOrPath(pos.first, pos.second); | ||
209 | } | ||
210 | bool hasSymbolOrPath(int x, int y); | ||
211 | |||
212 | std::unique_ptr<Panel> _panel; | ||
213 | std::vector<std::vector<int>> _custom_grid; | ||
214 | int _width, _height; | ||
215 | Panel::Symmetry _symmetry; | ||
216 | std::set<Point> _starts, _exits; | ||
217 | std::set<Point> _gridpos, _openpos; | ||
218 | std::set<Point> _path, _path1, _path2; | ||
219 | bool _fullGaps, _bisect; | ||
220 | int _stoneTypes; | ||
221 | int _config; | ||
222 | int _oneTimeAdd, _oneTimeRemove; | ||
223 | long _seed; | ||
224 | std::vector<Point> _splitPoints; | ||
225 | bool _allowNonMatch; // Used for multi-generator | ||
226 | int _parity; | ||
227 | std::vector<std::vector<Point>> _obstructions; | ||
228 | bool colorblind; | ||
229 | |||
230 | int _areaTotal, _genTotal, _areaPuzzles, _totalPuzzles; | ||
231 | std::wstring _areaName; | ||
232 | |||
233 | void set(int x, int y, int val) { _panel->set(x, y, val); } | ||
234 | void set(const Point& pos, int val) { | ||
235 | _panel->set(pos.first, pos.second, val); | ||
236 | } | ||
237 | |||
238 | int get(int x, int y) { return _panel->get(x, y); } | ||
239 | int get(const Point& pos) { return _panel->get(pos.first, pos.second); } | ||
240 | |||
241 | // std::vector<std::vector<int>> _panelData; | ||
242 | // std::vector<std::vector<bool>> _drawnPath; | ||
243 | |||
244 | friend class PuzzleList; | ||
245 | friend class Special; | ||
246 | }; | ||
247 | |||
248 | #endif /* end of include guard: GENERATE_H_0582FCEA */ | ||