about summary refs log tree commit diff stats
path: root/ext/wittle_generator/Generate.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wittle_generator/Generate.h')
-rw-r--r--ext/wittle_generator/Generate.h248
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
16typedef std::set<Point> Shape;
17
18// The main class for generating puzzles.
19class 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 */