001package squidpony.squidgrid;
002
003import squidpony.GwtCompatibility;
004import squidpony.squidmath.Coord;
005import squidpony.squidmath.RNG;
006
007/**
008 * A class that imitates patterns in an existing 2D boolean array and uses it to generate a new boolean array with a
009 * similar visual style. Useful for creating procedural filler around a desired path or series of known rooms. Can also
010 * convert between 2D boolean arrays (samples) and 2D char arrays (maps).
011 * Created by Tommy Ettinger on 5/14/2016, porting from https://github.com/mxgmn/ConvChain (public domain)
012 */
013public class MimicFill {
014
015    private static final int N = 3;
016
017    private MimicFill()
018    {
019
020    }
021    /**
022     * Converts a 2D char array map to a 2D boolean array, where any chars in the array or vararg yes will result in
023     * true in the returned array at that position and any other chars will result in false. The result can be given to
024     * fill() as its sample parameter.
025     * @param map a 2D char array that you want converted to a 2D boolean array
026     * @param yes an array or vararg of the chars to consider true in map
027     * @return a 2D boolean array that can be given to fill()
028     */
029    public static boolean[][] mapToSample(char[][] map, char... yes)
030    {
031        if(map == null || map.length == 0)
032            return new boolean[0][0];
033        boolean[][] sample = new boolean[map.length][map[0].length];
034        if(yes == null || yes.length == 0)
035            return sample;
036        for (int x = 0; x < map.length; x++) {
037            for (int y = 0; y < map[0].length; y++) {
038                for (int c = 0; c < yes.length; c++) {
039                    if(sample[x][y] = (map[x][y] == yes[c]))
040                        break;
041                }
042            }
043        }
044        return sample;
045    }
046
047    /**
048     * Comverts a 2D boolean array to a 2D char array, where false means the parameter no and true the parameter yes.
049     * @param sample a 2D boolean array that you want converted to a 2D char array
050     * @param yes true in sample will be mapped to this char; usually '.'
051     * @param no false in sample will be mapped to this char; usually '#'
052     * @return a 2D char array containing only the chars yes and no
053     */
054    public static char[][] sampleToMap(boolean[][] sample, char yes, char no)
055    {
056
057        if(sample == null || sample.length == 0)
058            return new char[0][0];
059        char[][] map = new char[sample.length][sample[0].length];
060        for (int x = 0; x < sample.length; x++) {
061            for (int y = 0; y < sample[0].length; y++) {
062                map[x][y] = (sample[x][y]) ? yes : no;
063            }
064        }
065        return map;
066    }
067
068    /**
069     * Runs a logical OR on each pair of booleans at the same position in left and right, and returns the result of all
070     * the OR operations as a 2D boolean array (using the minimum dimensions shared between left and right).
071     * @param left a 2D boolean array
072     * @param right another 2D boolean array
073     * @return the 2D array resulting from a logical OR on each pair of booleans at a point shared by left and right
074     */
075    public static boolean[][] orSamples(boolean[][] left, boolean[][] right)
076    {
077        if(left == null && right == null) return new boolean[0][0];
078        else if(left == null || left.length <= 0) return GwtCompatibility.copy2D(right);
079        else if(right == null || right.length <= 0) return GwtCompatibility.copy2D(left);
080
081        int width = Math.min(left.length, right.length),
082                height = Math.min(left[0].length, right[0].length);
083        boolean[][] done = new boolean[width][height];
084        for (int x = 0; x < width; x++) {
085            for (int y = 0; y < height; y++) {
086                done[x][y] = left[x][y] || right[x][y];
087            }
088        }
089        return done;
090    }
091
092
093    /**
094     * Runs a logical AND on each pair of booleans at the same position in left and right, and returns the result of all
095     * the AND operations as a 2D boolean array (using the minimum dimensions shared between left and right).
096     * @param left a 2D boolean array
097     * @param right another 2D boolean array
098     * @return the 2D array resulting from a logical AND on each pair of booleans at a point shared by left and right
099     */
100    public static boolean[][] andSamples(boolean[][] left, boolean[][] right)
101    {
102        if(left == null || right == null || left.length <= 0 || right.length <= 0) return new boolean[0][0];
103
104        int width = Math.min(left.length, right.length),
105                height = Math.min(left[0].length, right[0].length);
106        boolean[][] done = new boolean[width][height];
107        for (int x = 0; x < width; x++) {
108            for (int y = 0; y < height; y++) {
109                done[x][y] = left[x][y] && right[x][y];
110            }
111        }
112        return done;
113    }
114
115    /**
116     * Given a 2D boolean array sample (usually a final product of this class' fill() method) and an Iterable of Coord
117     * (such as a List or Set of Coord, but a Region can also work), copies sample, then marks every Coord in points as
118     * true if it is in-bounds, and returns the modified copy of sample. Does not alter the original sample. You may
119     * want to use this with techniques like drawing a long line with Bresenham, OrthoLine, or WobblyLine, potentially
120     * widening the line with Radius.expand(), and then passing the result as the Iterable of Coord. You could then make
121     * the start and end of the line into an entrance and exit and be sure the player can get from one to the other
122     * (except for Bresenham and other lines that may make diagonal movements, if the player cannot move diagonally).
123     * @param sample a 2D boolean array; will be copied, not modified directly
124     * @param points an Iterable (such as a List or Set) of Coord that will be marked as true if in-bounds
125     * @return a copy of sample with the Coords in points marked as true
126     */
127    public static boolean[][] markSample(boolean[][] sample, Iterable<Coord> points)
128    {
129        if(sample == null || sample.length <= 0)
130            return new boolean[0][0];
131        boolean[][] sample2 = GwtCompatibility.copy2D(sample);
132        int width = sample2.length, height = sample2[0].length;
133        for(Coord c : points)
134        {
135            if(c.x >= 0 && c.x < width && c.y >= 0 && c.y < height)
136            {
137                sample2[c.x][c.y] = true;
138            }
139        }
140        return sample2;
141    }
142
143    /**
144     *
145     * @param sample a 2D boolean array to mimic visually; you can use mapToSample() if you have a 2D char array
146     * @param size the side length of the square boolean array to generate
147     * @param temperature typically 0.2 works well for this, but other numbers between 0 and 1 may work
148     * @param iterations typically 3-5 works well for this; lower numbers may have slight problems with quality,
149     *                   and higher numbers make this slightly slower
150     * @param random an RNG to use for the random components of this technique
151     * @return a new 2D boolean array, width = size, height = size, mimicking the visual style of sample
152     */
153    public static boolean[][] fill(boolean[][] sample, int size, double temperature, int iterations, RNG random) {
154        boolean[][] field = new boolean[size][size];
155        double[] weights = new double[1 << (N * N)];
156
157        for (int x = 0; x < sample.length; x++) {
158            for (int y = 0; y < sample[x].length; y++) {
159                Pattern[] p = new Pattern[8];
160
161                p[0] = new Pattern(sample, x, y, N);
162                p[1] = p[0].rotate();
163                p[2] = p[1].rotate();
164                p[3] = p[2].rotate();
165                p[4] = p[0].reflect();
166                p[5] = p[1].reflect();
167                p[6] = p[2].reflect();
168                p[7] = p[3].reflect();
169
170                for (int k = 0; k < 8; k++) {
171                    weights[p[k].index()]++;
172                }
173            }
174        }
175
176        for (int k = 0; k < weights.length; k++) {
177            if (weights[k] <= 0)
178                weights[k] = 0.1;
179        }
180        for (int y = 0; y < size; y++) {
181            for (int x = 0; x < size; x++) {
182                field[x][y] = random.nextBoolean();
183            }
184        }
185
186        int i, j;
187        double p, q;
188        for (int k = 0; k < iterations * size * size; k++) {
189            i = random.nextInt(size);
190            j = random.nextInt(size);
191
192            p = 1.0;
193            for (int y = j - N + 1; y <= j + N - 1; y++)
194                for (int x = i - N + 1; x <= i + N - 1; x++) p *= weights[Pattern.index(field, x, y, N)];
195
196            field[i][j] = !field[i][j];
197
198            q = 1.0;
199            for (int y = j - N + 1; y <= j + N - 1; y++)
200                for (int x = i - N + 1; x <= i + N - 1; x++) q *= weights[Pattern.index(field, x, y, N)];
201
202
203            if (Math.pow(q / p, 1.0 / temperature) < random.nextDouble())
204                field[i][j] = !field[i][j];
205        }
206        return field;
207    }
208
209    private static class Pattern {
210        public boolean[][] data;
211
212
213        Pattern(boolean[][] exact) {
214            data = exact;
215        }
216
217        Pattern(boolean[][] field, int x, int y, int size) {
218            data = new boolean[size][size];
219            for (int i = 0; i < size; i++) {
220                for (int j = 0; j < size; j++) {
221                    data[i][j] =
222                            field[(x + i + field.length) % field.length][(y + j + field[0].length) % field[0].length];
223                }
224            }
225        }
226
227        Pattern rotate() {
228            boolean[][] next = new boolean[data.length][data.length];
229            for (int x = 0; x < data.length; x++) {
230                for (int y = 0; y < data.length; y++) {
231                    next[data.length - 1 - y][x] = data[x][y];
232                }
233            }
234            return new Pattern(next);
235        }
236
237        Pattern reflect() {
238            boolean[][] next = new boolean[data.length][data.length];
239            for (int x = 0; x < data.length; x++) {
240                for (int y = 0; y < data.length; y++) {
241                    next[data.length - 1 - x][y] = data[x][y];
242                }
243            }
244            return new Pattern(next);
245        }
246
247        int index() {
248            int result = 0;
249            for (int y = 0; y < data.length; y++) {
250                for (int x = 0; x < data.length; x++) {
251                    result += data[x][y] ? 1 << (y * data.length + x) : 0;
252                }
253            }
254            return result;
255        }
256
257        static int index(boolean[][] field, int x, int y, int size) {
258            int result = 0;
259            for (int i = 0; i < size; i++) {
260                for (int j = 0; j < size; j++) {
261                    if (field[(x + i + field.length) % field.length][(y + j + field[0].length) % field[0].length])
262                        result += 1 << (j * size + i);
263                }
264            }
265            return result;
266        }
267    }
268
269    /**
270     * Predefined sample; many small separate squares.
271     */
272    public static final boolean[][] boulders = new boolean[][]{
273            new boolean[]{true,true,true,true,true,true,true,true,true,true,true,false,false,true,true,true},
274            new boolean[]{true,true,false,false,true,true,false,false,true,true,true,false,false,true,true,true},
275            new boolean[]{true,true,false,false,true,true,false,false,true,true,true,true,true,true,true,true},
276            new boolean[]{true,true,true,true,true,true,true,true,true,false,false,true,true,false,false,true},
277            new boolean[]{true,true,true,false,false,true,false,false,true,false,false,true,true,false,false,true},
278            new boolean[]{true,true,true,false,false,true,false,false,true,true,true,true,true,true,true,true},
279            new boolean[]{false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true},
280            new boolean[]{false,false,true,true,false,false,true,false,false,true,true,true,true,true,true,true},
281            new boolean[]{true,true,true,true,false,false,true,false,false,true,true,true,false,false,true,true},
282            new boolean[]{true,false,false,true,true,true,true,true,true,true,true,true,false,false,true,true},
283            new boolean[]{true,false,false,true,false,false,true,true,true,true,true,true,true,true,true,true},
284            new boolean[]{true,true,true,true,false,false,true,true,true,false,false,true,true,true,true,true},
285            new boolean[]{true,true,true,true,true,true,true,true,true,false,false,true,false,false,true,true},
286            new boolean[]{true,false,false,true,true,true,false,false,true,true,true,true,false,false,true,true},
287            new boolean[]{true,false,false,true,true,true,false,false,true,true,true,true,true,true,true,true},
288            new boolean[]{true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true}
289    };
290
291    /**
292     * Predefined sample; a large, enclosed, organic space that usually makes large cave-like rooms,
293     */
294    public static final boolean[][] cave = new boolean[][]{
295            new boolean[]{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
296            new boolean[]{false, false, false, false, true, false, false, false, false, true, false, false, false, false, false, false},
297            new boolean[]{false, false, false, true, true, true, false, false, true, true, true, true, true, true, false, false},
298            new boolean[]{false, false, true, true, true, true, true, true, true, true, true, true, false, false, false, false},
299            new boolean[]{false, false, true, true, true, true, true, true, true, true, true, true, true, true, false, false},
300            new boolean[]{false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, false},
301            new boolean[]{false, false, false, true, true, true, true, true, true, true, true, true, true, false, false, false},
302            new boolean[]{false, false, false, false, true, true, true, true, true, true, true, true, false, false, false, false},
303            new boolean[]{false, false, false, false, true, true, true, true, true, true, true, true, true, false, false, false},
304            new boolean[]{false, false, false, true, true, true, true, true, true, true, true, true, true, true, false, false},
305            new boolean[]{false, false, true, true, true, true, true, true, true, true, true, true, true, true, false, false},
306            new boolean[]{false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, false},
307            new boolean[]{false, false, false, true, true, true, true, true, false, false, true, true, true, true, true, false},
308            new boolean[]{false, false, false, false, true, true, true, false, false, false, false, true, true, false, false, false},
309            new boolean[]{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
310            new boolean[]{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}
311    };
312
313    /**
314     * Predefined sample; several medium-sized organic spaces that usually make tight, chaotic tunnels.
315     */
316    public static final boolean[][] caves = new boolean[][]{
317            new boolean[]{false,false,false,true,false,false,false,false,false,false,false,false,true,false,false,false},
318            new boolean[]{false,false,false,true,false,false,false,false,false,false,false,true,true,false,false,false},
319            new boolean[]{false,false,true,true,true,false,false,false,false,false,false,true,true,false,false,false},
320            new boolean[]{false,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false},
321            new boolean[]{false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false},
322            new boolean[]{true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true},
323            new boolean[]{false,false,true,true,true,true,true,false,false,false,true,true,true,true,false,false},
324            new boolean[]{false,false,false,true,true,true,false,false,false,false,false,true,true,false,false,false},
325            new boolean[]{false,false,false,false,true,true,false,false,false,false,false,true,false,false,false,false},
326            new boolean[]{false,false,false,false,true,false,false,false,false,false,true,true,true,false,false,false},
327            new boolean[]{false,false,true,true,true,true,false,false,false,true,true,true,true,true,false,false},
328            new boolean[]{false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false},
329            new boolean[]{true,true,true,true,true,true,true,false,false,true,true,true,true,true,true,true},
330            new boolean[]{false,true,true,true,true,true,false,false,false,true,true,true,true,true,false,false},
331            new boolean[]{false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false},
332            new boolean[]{false,false,false,true,false,false,false,false,false,false,false,false,true,false,false,false}
333    };
334
335    /**
336     * Predefined sample; a checkerboard pattern that typically loses recognition as such after generation.
337     */
338    public static final boolean[][] chess = new boolean[][]{
339            new boolean[]{true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false},
340            new boolean[]{false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true},
341            new boolean[]{true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false},
342            new boolean[]{false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true},
343            new boolean[]{true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false},
344            new boolean[]{false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true},
345            new boolean[]{true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false},
346            new boolean[]{false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true},
347            new boolean[]{true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false},
348            new boolean[]{false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true},
349            new boolean[]{true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false},
350            new boolean[]{false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true},
351            new boolean[]{true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false},
352            new boolean[]{false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true},
353            new boolean[]{true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false},
354            new boolean[]{false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true}
355    };
356
357    /**
358     * Predefined sample; produces rectangular rooms with small corridors between them.
359     */
360    public static final boolean[][] lessRooms = new boolean[][]{
361            new boolean[]{false,false,false,true,false,false,false,false,false,false,false,false,true,false,false,false},
362            new boolean[]{false,false,false,true,false,false,false,false,false,true,true,true,true,true,true,false},
363            new boolean[]{false,false,false,true,false,false,false,false,false,true,true,true,true,true,true,false},
364            new boolean[]{false,false,false,true,false,false,false,false,false,true,true,true,true,true,true,false},
365            new boolean[]{false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false},
366            new boolean[]{true,true,true,false,false,false,false,false,false,true,true,true,true,true,true,true},
367            new boolean[]{false,false,true,false,false,false,false,false,false,true,true,true,true,true,true,false},
368            new boolean[]{false,false,true,false,false,false,false,false,false,true,true,true,true,true,true,false},
369            new boolean[]{false,false,true,false,false,false,false,false,false,false,false,true,false,false,false,false},
370            new boolean[]{false,false,true,false,false,false,false,false,false,false,false,true,false,false,false,false},
371            new boolean[]{false,false,true,true,true,true,true,true,false,false,false,true,false,false,false,false},
372            new boolean[]{true,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true},
373            new boolean[]{false,false,true,true,true,true,true,true,true,true,true,true,true,false,false,false},
374            new boolean[]{false,false,true,true,true,true,true,true,false,false,false,false,true,false,false,false},
375            new boolean[]{false,false,true,true,true,true,true,true,false,false,false,false,true,false,false,false},
376            new boolean[]{false,false,false,true,false,false,false,false,false,false,false,false,true,false,false,false}
377    };
378
379    /**
380     * Predefined sample; produces a suitable filler for a maze (but it is unlikely to connect both ends like a maze).
381     */
382    public static final boolean[][] maze = new boolean[][]{
383            new boolean[]{true,true,true,true,true,false,false,false,false,true,true,true,false,true,true,false},
384            new boolean[]{true,false,false,false,true,false,true,true,false,true,false,false,false,false,false,false},
385            new boolean[]{true,false,true,true,true,false,true,false,false,false,false,true,true,true,false,true},
386            new boolean[]{true,false,false,false,false,false,true,false,true,true,true,true,false,true,false,false},
387            new boolean[]{true,true,true,false,true,true,true,false,false,false,false,true,false,false,false,true},
388            new boolean[]{false,false,false,false,false,false,true,true,true,true,false,true,false,true,false,false},
389            new boolean[]{true,true,true,true,true,false,true,true,false,true,false,true,false,true,false,true},
390            new boolean[]{false,false,false,false,false,false,true,true,false,true,true,true,false,true,false,true},
391            new boolean[]{true,true,true,true,true,true,true,true,false,false,false,false,false,true,false,false},
392            new boolean[]{false,false,false,true,false,false,false,true,true,false,true,true,true,true,false,true},
393            new boolean[]{true,true,false,true,false,true,true,true,false,false,false,false,false,false,false,false},
394            new boolean[]{true,false,false,true,false,true,false,true,false,true,true,false,true,false,true,true},
395            new boolean[]{true,true,true,true,false,false,false,true,false,false,true,false,true,false,false,true},
396            new boolean[]{false,false,true,true,false,true,true,true,true,true,true,false,true,true,false,false},
397            new boolean[]{true,false,false,false,false,false,false,false,false,true,true,false,false,true,true,false},
398            new boolean[]{true,true,true,true,true,true,true,true,false,true,true,true,false,true,true,false}
399    };
400
401    /**
402     * Predefined sample; produces weird, large areas of "true" and "false" that suddenly change to the other.
403     */
404    public static final boolean[][] quarterBlack = new boolean[][]{
405            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
406            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
407            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
408            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
409            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
410            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
411            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
412            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
413            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
414            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
415            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
416            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
417            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
418            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
419            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
420            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true}
421    };
422
423    /**
424     * Predefined sample; produces multiple directions of flowing, river-like shapes made of "false".
425     */
426    public static final boolean[][] river = new boolean[][]{
427            new boolean[]{true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true},
428            new boolean[]{true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true},
429            new boolean[]{true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true},
430            new boolean[]{true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true},
431            new boolean[]{true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true},
432            new boolean[]{true,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true},
433            new boolean[]{true,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true},
434            new boolean[]{true,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true},
435            new boolean[]{true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true},
436            new boolean[]{true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true},
437            new boolean[]{true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true},
438            new boolean[]{true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true},
439            new boolean[]{true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,true},
440            new boolean[]{true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,true},
441            new boolean[]{true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true},
442            new boolean[]{true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true}
443    };
444
445    /**
446     * Predefined sample; produces rectangular rooms with a dense packing.
447     */
448    public static final boolean[][] rooms = new boolean[][]{
449            new boolean[]{false,false,false,true,false,false,false,false,false,false,false,false,true,false,false,false},
450            new boolean[]{false,false,false,true,false,false,false,false,false,true,true,true,true,true,true,false},
451            new boolean[]{false,true,true,true,true,true,false,false,false,true,true,true,true,true,true,false},
452            new boolean[]{false,true,true,true,true,true,false,false,false,true,true,true,true,true,true,false},
453            new boolean[]{false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false},
454            new boolean[]{true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true},
455            new boolean[]{false,true,true,true,true,true,false,false,false,true,true,true,true,true,true,false},
456            new boolean[]{false,false,true,false,false,false,false,false,false,true,true,true,true,true,true,false},
457            new boolean[]{false,false,true,false,false,false,false,false,false,false,false,true,false,false,false,false},
458            new boolean[]{false,false,true,false,false,false,false,false,false,false,false,true,false,false,false,false},
459            new boolean[]{false,false,true,true,true,true,true,true,false,false,true,true,true,true,false,false},
460            new boolean[]{true,true,true,true,true,true,true,true,false,false,true,true,true,true,true,true},
461            new boolean[]{false,false,true,true,true,true,true,true,true,true,true,true,true,true,false,false},
462            new boolean[]{false,false,true,true,true,true,true,true,false,false,true,true,true,true,false,false},
463            new boolean[]{false,false,true,true,true,true,true,true,false,false,false,false,true,false,false,false},
464            new boolean[]{false,false,false,true,false,false,false,false,false,false,false,false,true,false,false,false}
465    };
466
467    /**
468     * Predefined sample; produces an uncanny imitation of a maze with a tiny sample size.
469     */
470    public static final boolean[][] simpleMaze = new boolean[][]{
471            new boolean[]{true,true,true,true},
472            new boolean[]{true,false,false,false},
473            new boolean[]{true,false,true,false},
474            new boolean[]{true,false,false,false}
475    };
476
477    /**
478     * Predefined sample; produces mostly rectangular rooms with very few corridor-like areas.
479     */
480    public static final boolean[][] simpleRooms = new boolean[][]{
481            new boolean[]{false,false,false,false,false,true,false,false,false,false,false},
482            new boolean[]{false,false,false,false,false,true,false,false,false,false,false},
483            new boolean[]{false,false,true,true,true,true,true,true,true,false,false},
484            new boolean[]{false,false,true,true,true,true,true,true,true,false,false},
485            new boolean[]{false,false,true,true,true,true,true,true,true,false,false},
486            new boolean[]{true,true,true,true,true,true,true,true,true,true,true},
487            new boolean[]{false,false,true,true,true,true,true,true,true,false,false},
488            new boolean[]{false,false,true,true,true,true,true,true,true,false,false},
489            new boolean[]{false,false,true,true,true,true,true,true,true,false,false},
490            new boolean[]{false,false,false,false,false,true,false,false,false,false,false},
491            new boolean[]{false,false,false,false,false,true,false,false,false,false,false}
492    };
493
494    /**
495     * Predefined sample; produces largely rectangular rooms with a good amount of thin corridors.
496     */
497    public static final boolean[][] thickWalls = new boolean[][]{
498            new boolean[]{false,false,false,false,false,false,false,true,false,false,false,false,false,false,false},
499            new boolean[]{false,false,false,false,false,false,false,true,false,false,false,false,false,false,false},
500            new boolean[]{false,false,false,false,false,false,false,true,false,false,false,false,false,false,false},
501            new boolean[]{false,false,false,false,false,false,false,true,false,false,false,false,false,false,false},
502            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,false,false,false,false},
503            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,false,false,false,false},
504            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,false,false,false,false},
505            new boolean[]{true,true,true,true,true,true,true,true,true,true,true,true,true,true,true},
506            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,false,false,false,false},
507            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,false,false,false,false},
508            new boolean[]{false,false,false,false,true,true,true,true,true,true,true,false,false,false,false},
509            new boolean[]{false,false,false,false,false,false,false,true,false,false,false,false,false,false,false},
510            new boolean[]{false,false,false,false,false,false,false,true,false,false,false,false,false,false,false},
511            new boolean[]{false,false,false,false,false,false,false,true,false,false,false,false,false,false,false},
512            new boolean[]{false,false,false,false,false,false,false,true,false,false,false,false,false,false,false}
513    };
514
515    public static final boolean[][] ruins = new boolean[][]{
516            new boolean[]{false,true,false,false,false,false,false,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true},
517            new boolean[]{false,true,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,true,true},
518            new boolean[]{false,true,false,false,false,false,false,false,true,false,false,false,false,false,false,true,true,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true},
519            new boolean[]{false,true,true,true,true,true,false,false,true,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,false,true,false,false,true},
520            new boolean[]{false,true,true,true,true,true,true,false,true,false,false,false,false,false,false,true,false,false,false,true,false,false,false,false,true,true,true,true,true,false,false,true},
521            new boolean[]{false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,true,false,false,false,true,true,true,true,true,true,false,false,true},
522            new boolean[]{true,true,true,true,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,true,true,true,true},
523            new boolean[]{false,true,false,false,true,true,true,true,true,true,true,false,false,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false},
524            new boolean[]{false,true,false,false,false,false,false,false,false,false,true,true,false,true,true,true,true,true,true,false,false,false,false,false,false,false,true,true,false,false,false,false},
525            new boolean[]{false,true,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,true,true,false,false,false,false},
526            new boolean[]{true,true,true,false,false,false,true,true,true,true,true,true,true,true,false,false,true,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true},
527            new boolean[]{true,true,true,false,false,false,false,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,false,false},
528            new boolean[]{true,true,true,false,false,false,false,true,true,true,true,true,true,true,false,false,false,false,true,true,false,false,false,false,false,true,true,true,false,false,false,false},
529            new boolean[]{true,true,true,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,true,false,false,false,false,false,false,false,true,false,false,true,true},
530            new boolean[]{false,false,false,false,false,false,false,true,true,true,true,false,true,false,false,true,false,false,false,true,false,false,false,false,false,false,false,true,true,true,true,true},
531            new boolean[]{false,false,false,false,false,false,false,false,false,true,false,false,true,false,false,true,false,false,false,true,false,false,false,false,false,false,true,true,false,false,false,false},
532            new boolean[]{false,false,false,false,false,false,false,false,false,true,false,true,true,false,false,true,false,false,false,true,true,true,true,true,true,true,true,true,false,false,false,false},
533            new boolean[]{false,false,false,false,true,false,false,false,false,true,false,false,true,false,false,true,false,false,false,true,true,true,false,true,true,true,true,true,false,false,false,false},
534            new boolean[]{false,false,false,true,true,false,false,false,false,true,false,false,true,false,false,true,true,false,false,false,true,true,false,true,false,false,true,false,false,false,false,false},
535            new boolean[]{false,false,false,true,true,false,false,false,false,true,false,false,true,false,false,true,true,false,false,false,false,true,false,true,false,false,true,false,false,false,false,false},
536            new boolean[]{false,false,false,false,true,false,false,true,false,true,false,false,true,false,false,false,true,false,false,false,false,true,false,true,false,false,true,false,false,false,true,false},
537            new boolean[]{false,true,false,false,true,true,true,true,true,true,true,false,true,false,false,false,true,false,false,false,false,true,false,true,true,true,true,false,false,false,true,false},
538            new boolean[]{true,true,true,true,true,true,true,false,false,true,false,false,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,true,true},
539            new boolean[]{true,true,true,true,true,true,true,true,false,true,false,false,true,false,false,false,true,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true},
540            new boolean[]{false,false,false,false,false,false,true,false,false,true,false,false,true,false,false,false,false,true,false,false,true,true,false,false,false,false,false,false,false,false,false,false},
541            new boolean[]{false,false,false,false,false,false,true,false,false,true,true,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,true,true,true,false,false,false},
542            new boolean[]{false,false,false,false,false,false,true,false,false,false,false,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,true,true,true,false,false,false},
543            new boolean[]{true,true,true,true,true,true,true,true,false,false,false,true,true,true,false,false,false,false,false,false,true,true,true,false,false,false,true,true,true,true,true,true},
544            new boolean[]{false,false,false,false,false,false,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,false,false,true,false},
545            new boolean[]{false,false,false,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,true,true,true,false,false,false},
546            new boolean[]{false,false,false,false,false,false,false,true,true,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,true,true,true,false,false,false},
547            new boolean[]{false,true,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true},
548    };
549
550    public static final boolean[][] openRooms = new boolean[][]{
551            new boolean[]{true,true,true,true,true,true,false,true,true,true,true,true,true,false,true,true,true,true,true,true,false,false,true,true,true,true,true,true,true,true,true,true},
552            new boolean[]{true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true},
553            new boolean[]{true,true,true,true,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,true,true},
554            new boolean[]{true,true,true,true,false,false,false,true,true,true,false,false,true,true,true,true,true,true,true,true,true,true,false,true,true,false,true,true,true,false,true,true},
555            new boolean[]{true,true,false,false,false,false,false,true,true,true,true,false,true,true,true,true,true,false,false,false,false,false,false,true,true,false,true,true,true,false,true,true},
556            new boolean[]{true,true,true,true,true,false,false,false,false,true,true,false,false,false,false,false,false,false,false,true,true,true,true,true,true,false,true,true,true,false,false,false},
557            new boolean[]{true,true,true,true,true,false,false,false,false,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,false,false},
558            new boolean[]{true,true,true,true,true,false,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,false,false,false,false,false,false,true,true,false,false},
559            new boolean[]{true,true,true,true,true,false,true,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,false,true,true,true,true,false,false,false,false,false},
560            new boolean[]{true,true,true,true,true,false,true,true,false,false,true,true,true,true,false,false,false,true,true,true,true,true,false,true,true,true,true,false,false,false,false,false},
561            new boolean[]{true,true,true,true,true,false,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,false,false,false,false,false},
562            new boolean[]{true,true,true,true,true,false,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,false,false,false,false,false},
563            new boolean[]{false,false,false,false,false,false,true,true,false,true,true,true,false,false,false,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,false,false},
564            new boolean[]{true,true,true,true,true,true,true,true,false,true,true,true,false,false,false,false,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true},
565            new boolean[]{true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,false,false,false,false,false,true,true,false,true,true,true,true,true,true,true,true,true},
566            new boolean[]{false,true,true,true,true,true,false,false,false,true,true,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,false,false,true,true,false},
567            new boolean[]{false,true,true,false,false,false,false,false,true,true,true,true,true,true,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,true,true,false},
568            new boolean[]{false,true,true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,false},
569            new boolean[]{false,true,true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,false,true,true,true,true,true,true,true,true,false},
570            new boolean[]{false,false,false,false,false,true,true,true,true,true,true,true,false,true,true,true,true,true,false,true,true,true,false,true,true,true,true,true,true,true,true,false},
571            new boolean[]{true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true,false},
572            new boolean[]{true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false},
573            new boolean[]{true,true,true,true,true,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false},
574            new boolean[]{true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,true,true,true,true},
575            new boolean[]{true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,true,false,true,true,true,true,true,true,false,false,false,true,true,true,true},
576            new boolean[]{true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,true,false,true,true,true,false,false,false,false,false,false,true,true,true,true},
577            new boolean[]{true,true,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,false,true,true,true,false,true,true,true,true,false,true,true,true,true},
578            new boolean[]{true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,true,false,true,true,true,false,true,true,true,true,false,false,false,true,true},
579            new boolean[]{true,false,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,false,false,false,false,false,true,true,true,true,false,false,false,true,true},
580            new boolean[]{true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,true},
581            new boolean[]{true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,true,true,true,true,true,true,true,true,true,true},
582            new boolean[]{true,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,true,true,false,false,true,true,true,true,true,true,true,true,true,true},
583    };
584
585    public static final boolean[][][] samples = new boolean[][][]{
586            boulders, cave, caves, chess, lessRooms, maze, quarterBlack,
587            river, rooms, simpleMaze, simpleRooms, thickWalls, ruins, openRooms
588    };
589}