001package squidpony.squidgrid.gui.gdx;
002
003import com.badlogic.gdx.graphics.Color;
004import com.badlogic.gdx.graphics.g2d.Batch;
005import squidpony.ArrayTools;
006import squidpony.squidmath.SeededNoise;
007
008/**
009 * Created by Tommy Ettinger on 7/9/2017.
010 */
011public class MapUtility {
012    /**
013     * Produces a Color[][] that corresponds to appropriate default colors for the usual meanings of the chars in map.
014     * <br>
015     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
016     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
017     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
018     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
019     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
020     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
021     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
022     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
023     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.
024     *
025     * @param map a char[][] containing foreground characters
026     * @return a 2D array of Colors with the same size as map, that can be used for the corresponding chars
027     */
028    public static Color[][] generateDefaultColors(char[][] map) {
029        int width = map.length;
030        int height = map[0].length;
031        Color[][] portion = new Color[width][height];
032        for (int i = 0; i < width; i++) {
033            for (int j = 0; j < height; j++) {
034                switch (map[i][j]) {
035                    case '\1':
036                    case '├':
037                    case '┤':
038                    case '┴':
039                    case '┬':
040                    case '┌':
041                    case '┐':
042                    case '└':
043                    case '┘':
044                    case '│':
045                    case '─':
046                    case '┼':
047                    case '#':
048                        portion[i][j] = SColor.LIMITED_PALETTE[2];
049                        break;
050                    case '.':
051                    case ':':
052                        portion[i][j] = SColor.LIMITED_PALETTE[3];
053                        break;
054                    case '+':
055                    case '/':
056                        portion[i][j] = SColor.LIMITED_PALETTE[4];
057                        break;
058                    case ',':
059                    case '~':
060                        portion[i][j] = SColor.LIMITED_PALETTE[5];
061                        break;
062                    case '"':
063                        portion[i][j] = SColor.LIMITED_PALETTE[20];
064                        break;
065                    case '^':
066                        portion[i][j] = SColor.LIMITED_PALETTE[6];
067                        break;
068                    default:
069                        portion[i][j] = SColor.LIMITED_PALETTE[1];
070                }
071            }
072        }
073        return portion;
074    }
075
076    /**
077     * Produces a Color[][] that corresponds to appropriate default colors for the usual meanings of the chars in map.
078     * This overload also takes a char that corresponds to deep non-water lakes (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
079     * can produce) and a Color to use for that deep liquid, as well as a char for shallow lakes and a Color for that
080     * shallow liquid.
081     * <br>
082     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
083     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
084     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
085     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
086     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
087     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
088     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
089     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
090     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.  Deep and shallow lakes of non-water will use the given
091     * Color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you don't need
092     * this overload, and {@link #generateDefaultColors(char[][])} will be fine.
093     *
094     * @param map a char[][] containing foreground characters
095     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
096     * @param deepColor the Color to use for deep parts of non-water lakes
097     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
098     * @param shallowColor  the Color to use for shallow parts of non-water lakes
099     * @return a 2D array of Colors with the same size as map, that can be used for the corresponding chars
100     */
101    public static Color[][] generateDefaultColors(char[][] map, char deepChar, Color deepColor,
102                                                 char shallowChar, Color shallowColor) {
103
104        int width = map.length;
105        int height = map[0].length;
106        Color[][] portion = new Color[width][height];
107        for (int i = 0; i < width; i++) {
108            for (int j = 0; j < height; j++) {
109                switch (map[i][j]) {
110                    case '\1':
111                    case '├':
112                    case '┤':
113                    case '┴':
114                    case '┬':
115                    case '┌':
116                    case '┐':
117                    case '└':
118                    case '┘':
119                    case '│':
120                    case '─':
121                    case '┼':
122                    case '#':
123                        portion[i][j] = SColor.LIMITED_PALETTE[2];
124                        break;
125                    case '.':
126                    case ':':
127                        portion[i][j] = SColor.LIMITED_PALETTE[3];
128                        break;
129                    case '+':
130                    case '/':
131                        portion[i][j] = SColor.LIMITED_PALETTE[4];
132                        break;
133                    case ',':
134                    case '~':
135                        portion[i][j] = SColor.LIMITED_PALETTE[5];
136                        break;
137                    case '"':
138                        portion[i][j] = SColor.LIMITED_PALETTE[20];
139                        break;
140                    case '^':
141                        portion[i][j] = SColor.LIMITED_PALETTE[6];
142                        break;
143                    default:
144                        if (map[i][j] == deepChar)
145                            portion[i][j] = deepColor;
146                        else if (map[i][j] == shallowChar)
147                            portion[i][j] = shallowColor;
148                        else portion[i][j] = SColor.LIMITED_PALETTE[1];
149                }
150            }
151        }
152        return portion;
153    }
154    /**
155     * Produces a float[][] that corresponds to appropriate default colors for the usual meanings of the chars in map.
156     * Each float represents a color in an efficient way; {@link SparseLayers} primarily uses this kind of packed float
157     * to represent colors, and {@link SquidPanel} uses it internally.
158     * <br>
159     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
160     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
161     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
162     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
163     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
164     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
165     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
166     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
167     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.
168     *
169     * @param map a char[][] containing foreground characters
170     * @return a 2D float array with the same size as map, containing packed floats that can be used for the corresponding chars
171     */
172    public static float[][] generateDefaultColorsFloat(char[][] map) {
173        return fillDefaultColorsFloat(new float[map.length][map[0].length], map);
174    }
175    /**
176     * Fills an existing float[][] with packed float colors that correspond to appropriate default colors for the usual
177     * meanings of the chars in map. Each float represents a color in an efficient way; {@link SparseLayers} primarily
178     * uses this kind of packed float to represent colors, and {@link SquidPanel} uses it internally.
179     * <br>
180     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
181     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
182     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
183     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
184     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
185     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
186     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
187     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
188     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.
189     *
190     * @param packed a float[][] that will be modified, filled with packed float colors; must match map's size
191     * @param map a char[][] containing foreground characters
192     * @return a 2D float array with the same size as map, containing packed floats that can be used for the corresponding chars
193     */
194    public static float[][] fillDefaultColorsFloat(float[][] packed, char[][] map) {
195        int width = map.length;
196        int height = map[0].length;
197        float wall = SColor.LIMITED_PALETTE[2].toFloatBits(),
198                ground = SColor.LIMITED_PALETTE[3].toFloatBits(),
199                door = SColor.LIMITED_PALETTE[4].toFloatBits(),
200                water = SColor.LIMITED_PALETTE[5].toFloatBits(),
201                grass = SColor.LIMITED_PALETTE[20].toFloatBits(),
202                trap = SColor.LIMITED_PALETTE[6].toFloatBits(),
203                other = SColor.LIMITED_PALETTE[1].toFloatBits();
204        for (int i = 0; i < width; i++) {
205            for (int j = 0; j < height; j++) {
206                switch (map[i][j]) {
207                    case '\1':
208                    case '├':
209                    case '┤':
210                    case '┴':
211                    case '┬':
212                    case '┌':
213                    case '┐':
214                    case '└':
215                    case '┘':
216                    case '│':
217                    case '─':
218                    case '┼':
219                    case '#':
220                        packed[i][j] = wall;
221                        break;
222                    case '.':
223                    case ':':
224                        packed[i][j] = ground;
225                        break;
226                    case '+':
227                    case '/':
228                        packed[i][j] = door;
229                        break;
230                    case ',':
231                    case '~':
232                        packed[i][j] = water;
233                        break;
234                    case '"':
235                        packed[i][j] = grass;
236                        break;
237                    case '^':
238                        packed[i][j] = trap;
239                        break;
240                    default:
241                        packed[i][j] = other;
242                }
243            }
244        }
245        return packed;
246    }
247    /**
248     * Produces a float[][] that corresponds to appropriate default colors for the usual meanings of the chars in map.
249     * Each float represents a color in an efficient way; {@link SparseLayers} primarily uses this kind of packed float
250     * to represent colors, and {@link SquidPanel} uses it internally. This overload also takes a char that corresponds
251     * to deep non-water lakes (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a
252     * packed float color to use for that deep liquid, as well as a char for shallow lakes and another packed float
253     * color for that shallow liquid.
254     * <br>
255     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
256     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
257     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
258     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
259     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
260     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
261     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
262     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
263     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.  Deep and shallow lakes of non-water will use the given
264     * packed float color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you
265     * don't need this overload, and {@link #generateDefaultColorsFloat(char[][])} will be fine.
266     *
267     * @param map a char[][] containing foreground characters
268     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
269     * @param deepColor the packed float color to use for deep parts of non-water lakes
270     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
271     * @param shallowColor  the packed float color to use for shallow parts of non-water lakes
272     * @return a 2D float array with the same size as map, containing packed floats that can be used for the corresponding chars
273     */
274    public static float[][] generateDefaultColorsFloat(char[][] map, char deepChar, float deepColor,
275                                                       char shallowChar, float shallowColor) {
276        return fillDefaultColorsFloat(new float[map.length][map[0].length], map, deepChar, deepColor, shallowChar, shallowColor);
277    }
278    /**
279     * Produces a float[][] that corresponds to appropriate default colors for the usual meanings of the chars in map.
280     * Each float represents a color in an efficient way; {@link SparseLayers} primarily uses this kind of packed float
281     * to represent colors, and {@link SquidPanel} uses it internally. This overload also takes a char that corresponds
282     * to deep non-water lakes (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a
283     * packed float color to use for that deep liquid, as well as a char for shallow lakes and another packed float
284     * color for that shallow liquid.
285     * <br>
286     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
287     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
288     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
289     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
290     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
291     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
292     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
293     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
294     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.  Deep and shallow lakes of non-water will use the given
295     * packed float color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you
296     * don't need this overload, and {@link #generateDefaultColorsFloat(char[][])} will be fine.
297     *
298     * @param packed a float[][] that will be modified, filled with packed float colors; must match map's size
299     * @param map a char[][] containing foreground characters
300     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
301     * @param deepColor the packed float color to use for deep parts of non-water lakes
302     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
303     * @param shallowColor  the packed float color to use for shallow parts of non-water lakes
304     * @return a 2D float array with the same size as map, containing packed floats that can be used for the corresponding chars
305     */
306    public static float[][] fillDefaultColorsFloat(float[][] packed, char[][] map, char deepChar, float deepColor,
307                                                   char shallowChar, float shallowColor) {
308        int width = map.length;
309        int height = map[0].length;
310        float wall = SColor.LIMITED_PALETTE[2].toFloatBits(),
311                ground = SColor.LIMITED_PALETTE[3].toFloatBits(),
312                door = SColor.LIMITED_PALETTE[4].toFloatBits(),
313                water = SColor.LIMITED_PALETTE[5].toFloatBits(),
314                grass = SColor.LIMITED_PALETTE[20].toFloatBits(),
315                trap = SColor.LIMITED_PALETTE[6].toFloatBits(),
316                other = SColor.LIMITED_PALETTE[1].toFloatBits();
317        for (int i = 0; i < width; i++) {
318            for (int j = 0; j < height; j++) {
319                switch (map[i][j]) {
320                    case '\1':
321                    case '├':
322                    case '┤':
323                    case '┴':
324                    case '┬':
325                    case '┌':
326                    case '┐':
327                    case '└':
328                    case '┘':
329                    case '│':
330                    case '─':
331                    case '┼':
332                    case '#':
333                        packed[i][j] = wall;
334                        break;
335                    case '.':
336                    case ':':
337                        packed[i][j] = ground;
338                        break;
339                    case '+':
340                    case '/':
341                        packed[i][j] = door;
342                        break;
343                    case ',':
344                    case '~':
345                        packed[i][j] = water;
346                        break;
347                    case '"':
348                        packed[i][j] = grass;
349                        break;
350                    case '^':
351                        packed[i][j] = trap;
352                        break;
353                    default:
354                        if (map[i][j] == deepChar)
355                            packed[i][j] = deepColor;
356                        else if (map[i][j] == shallowChar)
357                            packed[i][j] = shallowColor;
358                        else packed[i][j] = other;
359                }
360            }
361        }
362        return packed;
363    }
364    /**
365     * Produces a float[][] that corresponds to appropriate default colors for the usual meanings of the chars in map.
366     * Each float represents a color in an efficient way and the version this uses can be altered by the specified hue,
367     * saturation, and value changes; {@link SparseLayers} primarily uses this kind of packed float to represent colors,
368     * and {@link SquidPanel} uses it internally.
369     * <br>
370     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
371     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
372     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
373     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
374     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
375     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
376     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
377     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
378     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.
379     *
380     * @param map a char[][] containing foreground characters
381     * @param hueChange a float from -1f to 1f that will be added to the hues of colors this uses
382     * @param saturationChange a float from -1f to 1f that will be added to the saturation of colors this uses
383     * @param valueChange a float from -1f to 1f that will be added to the values of colors this uses
384     * @return a 2D float array with the same size as map, containing packed floats that can be used for the corresponding chars
385     */
386    public static float[][] generateDefaultColorsFloat(char[][] map, final float hueChange, final float saturationChange, final float valueChange) {
387        return fillDefaultColorsFloat(new float[map.length][map[0].length], map, hueChange, saturationChange, valueChange);
388    }
389    /**
390     * Fills an existing float[][] with packed float colors that correspond to appropriate default colors for the usual
391     * meanings of the chars in map. Each float represents a color in an efficient way and the version this uses can be
392     * altered by the specified hue, saturation, and value changes; {@link SparseLayers} primarily uses this kind of
393     * packed float to represent colors, and {@link SquidPanel} uses it internally.
394     * <br>
395     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
396     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
397     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
398     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
399     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
400     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
401     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
402     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
403     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.
404     *
405     * @param packed a float[][] that will be modified, filled with packed float colors; must match map's size
406     * @param map a char[][] containing foreground characters
407     * @param hueChange a float from -1f to 1f that will be added to the hues of colors this uses
408     * @param saturationChange a float from -1f to 1f that will be added to the saturation of colors this uses
409     * @param valueChange a float from -1f to 1f that will be added to the values of colors this uses
410     * @return a 2D float array with the same size as map, containing packed floats that can be used for the corresponding chars
411     */
412    public static float[][] fillDefaultColorsFloat(float[][] packed, char[][] map, final float hueChange, final float saturationChange, final float valueChange) {
413        int width = map.length;
414        int height = map[0].length;
415        float wall = SColor.LIMITED_PALETTE[2].toEditedFloat(hueChange, saturationChange, valueChange),
416                ground = SColor.LIMITED_PALETTE[3].toEditedFloat(hueChange, saturationChange, valueChange),
417                door = SColor.LIMITED_PALETTE[4].toEditedFloat(hueChange, saturationChange, valueChange),
418                water = SColor.LIMITED_PALETTE[5].toEditedFloat(hueChange, saturationChange, valueChange),
419                grass = SColor.LIMITED_PALETTE[20].toEditedFloat(hueChange, saturationChange, valueChange),
420                trap = SColor.LIMITED_PALETTE[6].toEditedFloat(hueChange, saturationChange, valueChange),
421                other = SColor.LIMITED_PALETTE[1].toEditedFloat(hueChange, saturationChange, valueChange);
422        for (int i = 0; i < width; i++) {
423            for (int j = 0; j < height; j++) {
424                switch (map[i][j]) {
425                    case '\1':
426                    case '├':
427                    case '┤':
428                    case '┴':
429                    case '┬':
430                    case '┌':
431                    case '┐':
432                    case '└':
433                    case '┘':
434                    case '│':
435                    case '─':
436                    case '┼':
437                    case '#':
438                        packed[i][j] = wall;
439                        break;
440                    case '.':
441                    case ':':
442                        packed[i][j] = ground;
443                        break;
444                    case '+':
445                    case '/':
446                        packed[i][j] = door;
447                        break;
448                    case ',':
449                    case '~':
450                        packed[i][j] = water;
451                        break;
452                    case '"':
453                        packed[i][j] = grass;
454                        break;
455                    case '^':
456                        packed[i][j] = trap;
457                        break;
458                    default:
459                        packed[i][j] = other;
460                }
461            }
462        }
463        return packed;
464    }
465    /**
466     * Produces a float[][] that corresponds to appropriate default colors for the usual meanings of the chars in map.
467     * Each float represents a color in an efficient way and the version this uses can be altered by the specified hue,
468     * saturation, and value changes; {@link SparseLayers} primarily uses this kind of packed float
469     * to represent colors, and {@link SquidPanel} uses it internally. This overload also takes a char that corresponds
470     * to deep non-water lakes (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a
471     * packed float color to use for that deep liquid, as well as a char for shallow lakes and another packed float
472     * color for that shallow liquid.
473     * <br>
474     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
475     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
476     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
477     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
478     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
479     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
480     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
481     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
482     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.  Deep and shallow lakes of non-water will use the given
483     * packed float color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you
484     * don't need this overload, and {@link #generateDefaultColorsFloat(char[][])} will be fine.
485     *
486     * @param map a char[][] containing foreground characters
487     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
488     * @param deepColor the packed float color to use for deep parts of non-water lakes
489     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
490     * @param shallowColor  the packed float color to use for shallow parts of non-water lakes
491     * @param hueChange a float from -1f to 1f that will be added to the hues of colors this uses
492     * @param saturationChange a float from -1f to 1f that will be added to the saturation of colors this uses
493     * @param valueChange a float from -1f to 1f that will be added to the values of colors this uses
494     * @return a 2D float array with the same size as map, containing packed floats that can be used for the corresponding chars
495     */
496    public static float[][] generateDefaultColorsFloat(char[][] map, char deepChar, float deepColor,
497                                                       char shallowChar, float shallowColor,
498                                                       final float hueChange, final float saturationChange, final float valueChange) {
499        return fillDefaultColorsFloat(new float[map.length][map[0].length], map, deepChar, deepColor, shallowChar, shallowColor, hueChange, saturationChange, valueChange);
500    }
501    /**
502     * Produces a float[][] that corresponds to appropriate default colors for the usual meanings of the chars in map.
503     * Each float represents a color in an efficient way and the version this uses can be altered by the specified hue,
504     * saturation, and value changes; {@link SparseLayers} primarily uses this kind of packed float
505     * to represent colors, and {@link SquidPanel} uses it internally. This overload also takes a char that corresponds
506     * to deep non-water lakes (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a
507     * packed float color to use for that deep liquid, as well as a char for shallow lakes and another packed float
508     * color for that shallow liquid.
509     * <br>
510     * This takes its values from {@link SColor#LIMITED_PALETTE}; if that field is changed then the colors this returns
511     * will also change. Tiles containing nothing but a floor ('.') will be silver-gray; this can be changed by editing
512     * {@code SColor.LIMITED_PALETTE[3]}. Walls are brownish-black, and can be '#' marks or box-drawing lines; this can
513     * be changed by editing {@code SColor.LIMITED_PALETTE[2]}.Doors ('+' and '/' in the map) will be rust brown; this
514     * can be changed by editing {@code SColor.LIMITED_PALETTE[4]}. Both shallow and deep water (',' and '~') will be
515     * gray-blue; this can be changed by editing {@code SColor.LIMITED_PALETTE[5]}. Traps ('^') will be shown in bright
516     * orange; this can be changed by editing {@code SColor.LIMITED_PALETTE[6]}. Grass ('"') will be the expected green;
517     * this can be changed by editing {@code SColor.LIMITED_PALETTE[20]}. Anything else will use white; this can be
518     * changed by editing {@code SColor.LIMITED_PALETTE[1]}.  Deep and shallow lakes of non-water will use the given
519     * packed float color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you
520     * don't need this overload, and {@link #generateDefaultColorsFloat(char[][])} will be fine.
521     *
522     * @param packed a float[][] that will be modified, filled with packed float colors; must match map's size
523     * @param map a char[][] containing foreground characters
524     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
525     * @param deepColor the packed float color to use for deep parts of non-water lakes
526     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
527     * @param shallowColor  the packed float color to use for shallow parts of non-water lakes
528     * @param hueChange a float from -1f to 1f that will be added to the hues of colors this uses
529     * @param saturationChange a float from -1f to 1f that will be added to the saturation of colors this uses
530     * @param valueChange a float from -1f to 1f that will be added to the values of colors this uses
531     * @return a 2D float array with the same size as map, containing packed floats that can be used for the corresponding chars
532     */
533    public static float[][] fillDefaultColorsFloat(float[][] packed, char[][] map, char deepChar, float deepColor,
534                                                   char shallowChar, float shallowColor,
535                                                   final float hueChange, final float saturationChange, final float valueChange) {
536        int width = map.length;
537        int height = map[0].length;
538        float wall = SColor.LIMITED_PALETTE[2].toEditedFloat(hueChange, saturationChange, valueChange),
539                ground = SColor.LIMITED_PALETTE[3].toEditedFloat(hueChange, saturationChange, valueChange),
540                door = SColor.LIMITED_PALETTE[4].toEditedFloat(hueChange, saturationChange, valueChange),
541                water = SColor.LIMITED_PALETTE[5].toEditedFloat(hueChange, saturationChange, valueChange),
542                grass = SColor.LIMITED_PALETTE[20].toEditedFloat(hueChange, saturationChange, valueChange),
543                trap = SColor.LIMITED_PALETTE[6].toEditedFloat(hueChange, saturationChange, valueChange),
544                other = SColor.LIMITED_PALETTE[1].toEditedFloat(hueChange, saturationChange, valueChange);
545        for (int i = 0; i < width; i++) {
546            for (int j = 0; j < height; j++) {
547                switch (map[i][j]) {
548                    case '\1':
549                    case '├':
550                    case '┤':
551                    case '┴':
552                    case '┬':
553                    case '┌':
554                    case '┐':
555                    case '└':
556                    case '┘':
557                    case '│':
558                    case '─':
559                    case '┼':
560                    case '#':
561                        packed[i][j] = wall;
562                        break;
563                    case '.':
564                    case ':':
565                        packed[i][j] = ground;
566                        break;
567                    case '+':
568                    case '/':
569                        packed[i][j] = door;
570                        break;
571                    case ',':
572                    case '~':
573                        packed[i][j] = water;
574                        break;
575                    case '"':
576                        packed[i][j] = grass;
577                        break;
578                    case '^':
579                        packed[i][j] = trap;
580                        break;
581                    default:
582                        if (map[i][j] == deepChar)
583                            packed[i][j] = deepColor;
584                        else if (map[i][j] == shallowChar)
585                            packed[i][j] = shallowColor;
586                        else packed[i][j] = other;
587                }
588            }
589        }
590        return packed;
591    }
592
593    /**
594     * Produces a Color[][] that corresponds to appropriate default background colors for the usual meanings of the
595     * chars in map. This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
596     * colors this returns will also change. Most backgrounds will be black. but deep water ('~') will be dark
597     * blue-green, shallow water (',') will be a lighter blue-green, and grass ('"') will be dark green.
598     * You can adjust the brightness of the backgrounds using {@link #generateLightnessModifiers(char[][])}, or if you
599     * want water and grass to ripple, you can use the overload {@link #generateLightnessModifiers(char[][], double)}
600     * with some rising frame count.
601     *
602     * @param map a char[][] containing foreground characters (this gets their background color)
603     * @return a 2D array of background Colors with the same size as map, that can be used for the corresponding chars
604     */
605    public static Color[][] generateDefaultBGColors(char[][] map) {
606
607        int width = map.length;
608        int height = map[0].length;
609        Color[][] portion = new Color[width][height];
610        for (int i = 0; i < width; i++) {
611            for (int j = 0; j < height; j++) {
612                switch (map[i][j]) {
613                    case '\1':
614                    case '├':
615                    case '┤':
616                    case '┴':
617                    case '┬':
618                    case '┌':
619                    case '┐':
620                    case '└':
621                    case '┘':
622                    case '│':
623                    case '─':
624                    case '┼':
625                    case '#':
626                        portion[i][j] = SColor.LIMITED_PALETTE[0];
627                        break;
628                    case '.':
629                        portion[i][j] = SColor.LIMITED_PALETTE[0];
630                        break;
631                    case ':':
632                        portion[i][j] = SColor.LIMITED_PALETTE[35];
633                        break;
634                    case '+':
635                    case '/':
636                        portion[i][j] = SColor.LIMITED_PALETTE[0];
637                        break;
638                    case ',':
639                        portion[i][j] = SColor.LIMITED_PALETTE[23];
640                        break;
641                    case '~':
642                        portion[i][j] = SColor.LIMITED_PALETTE[24];
643                        break;
644                    case '"':
645                        portion[i][j] = SColor.LIMITED_PALETTE[21];
646                        break;
647                    case '^':
648                        portion[i][j] = SColor.LIMITED_PALETTE[0];
649                        break;
650                    default:
651                        portion[i][j] = SColor.LIMITED_PALETTE[0];
652                }
653            }
654        }
655        return portion;
656    }
657
658
659    /**
660     * Produces a Color[][] that corresponds to appropriate default background colors for the usual meanings of the
661     * chars in map. This overload also takes a char that corresponds to deep non-water lakes (which
662     * {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a Color to use for that deep liquid,
663     * as well as a char for shallow lakes and a Color for that shallow liquid.
664     * <br>
665     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
666     * colors this returns will also change. Most backgrounds will be black, but deep water ('~') will be dark
667     * blue-green, shallow water (',') will be a lighter blue-green, and grass ('"') will be dark green.
668     * Deep and shallow lakes of non-water will use the given Colors. If you are using SectionDungeonGenerator to
669     * produce normal water lakes, then you don't need this overload, and
670     * {@link #generateDefaultBGColors(char[][])} will be fine.
671     * You can adjust the brightness of the backgrounds using {@link #generateLightnessModifiers(char[][])}, or if you
672     * want water, grass, and lakes to ripple, you can use the overload
673     * {@link #generateLightnessModifiers(char[][], double, char, char)} with some rising frame count.
674     *
675     * @param map a char[][] containing foreground characters (this gets their background color)
676     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
677     * @param deepColor the Color to use for deep parts of non-water lakes
678     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
679     * @param shallowColor  the Color to use for shallow parts of non-water lakes
680     * @return a 2D array of background Colors with the same size as map, that can be used for the corresponding chars
681     */
682    public static Color[][] generateDefaultBGColors(char[][] map, char deepChar, Color deepColor,
683                                                    char shallowChar, Color shallowColor) {
684
685        int width = map.length;
686        int height = map[0].length;
687        Color[][] portion = new Color[width][height];
688        for (int i = 0; i < width; i++) {
689            for (int j = 0; j < height; j++) {
690                switch (map[i][j]) {
691                    case '\1':
692                    case '├':
693                    case '┤':
694                    case '┴':
695                    case '┬':
696                    case '┌':
697                    case '┐':
698                    case '└':
699                    case '┘':
700                    case '│':
701                    case '─':
702                    case '┼':
703                    case '#':
704                        portion[i][j] = SColor.LIMITED_PALETTE[0];
705                        break;
706                    case '.':
707                        portion[i][j] = SColor.LIMITED_PALETTE[0];
708                        break;
709                    case ':':
710                        portion[i][j] = SColor.LIMITED_PALETTE[35];
711                        break;
712                    case '+':
713                    case '/':
714                        portion[i][j] = SColor.LIMITED_PALETTE[0];
715                        break;
716                    case ',':
717                        portion[i][j] = SColor.LIMITED_PALETTE[23];
718                        break;
719                    case '~':
720                        portion[i][j] = SColor.LIMITED_PALETTE[24];
721                        break;
722                    case '"':
723                        portion[i][j] = SColor.LIMITED_PALETTE[21];
724                        break;
725                    case '^':
726                        portion[i][j] = SColor.LIMITED_PALETTE[0];
727                        break;
728                    default:
729                        if (map[i][j] == deepChar)
730                            portion[i][j] = deepColor;
731                        else if (map[i][j] == shallowChar)
732                            portion[i][j] = shallowColor;
733                        else portion[i][j] = SColor.LIMITED_PALETTE[0];
734                }
735            }
736        }
737        return portion;
738    }
739
740    /**
741     * Produces a float[][] of packed float colors that corresponds to appropriate default background colors for the
742     * usual meanings of the chars in map.
743     * <br>
744     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
745     * colors this returns will also change. Most backgrounds will be black; this can be changed by editing
746     * {@code SColor.LIMITED_PALETTE[0]}. Deep water ('~') will be dark blue-green; this can be changed by editing
747     * {@code SColor.LIMITED_PALETTE[24]}. Shallow water (',') will be a lighter blue-green; this can be changed by
748     * editing {@code SColor.LIMITED_PALETTE[23]}. Grass ('"') will be dark green; this can be changed by editing
749     * {@code SColor.LIMITED_PALETTE[21]}. Bridges (':') will be a medium-dark beige color; this can be changed by
750     * editing {@code SColor.LIMITED_PALETTE[35]}. You can adjust the brightness of the backgrounds using
751     * {@link #generateLightnessModifiers(char[][])}, or if you want water and grass to ripple, you can use the overload
752     * {@link #generateLightnessModifiers(char[][], double, char, char)} with some rising frame or millisecond count.
753     *
754     * @param map a char[][] containing foreground characters (this gets their background color)
755     * @return a 2D array of background Colors with the same size as map, that can be used for the corresponding chars
756     */
757    public static float[][] generateDefaultBGColorsFloat(char[][] map) {
758        return fillDefaultBGColorsFloat(new float[map.length][map[0].length], map);
759    }
760    /**
761     * Fills an existing float[][] with packed float colors that correspond to appropriate default background colors for
762     * the usual meanings of the chars in map. The sizes of map and packed should be identical.
763     * <br>
764     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
765     * colors this returns will also change. Most backgrounds will be black; this can be changed by editing
766     * {@code SColor.LIMITED_PALETTE[0]}. Deep water ('~') will be dark blue-green; this can be changed by editing
767     * {@code SColor.LIMITED_PALETTE[24]}. Shallow water (',') will be a lighter blue-green; this can be changed by
768     * editing {@code SColor.LIMITED_PALETTE[23]}. Grass ('"') will be dark green; this can be changed by editing
769     * {@code SColor.LIMITED_PALETTE[21]}. Bridges (':') will be a medium-dark beige color; this can be changed by
770     * editing {@code SColor.LIMITED_PALETTE[35]}. You can adjust the brightness of the backgrounds using
771     * {@link #generateLightnessModifiers(char[][])}, or if you want water and grass to ripple, you can use the overload
772     * {@link #generateLightnessModifiers(char[][], double, char, char)} with some rising frame or millisecond count.
773     * @param packed a float[][] that will be modified, filled with packed float colors; must match map's size
774     * @param map a char[][] containing foreground characters (this gets their background color)
775     * @return a 2D array of background Colors with the same size as map, that can be used for the corresponding chars
776     */
777    public static float[][] fillDefaultBGColorsFloat(float[][] packed, char[][] map) {
778        int width = map.length;
779        int height = map[0].length;
780        float   bridge = SColor.LIMITED_PALETTE[35].toFloatBits(),
781                shallow_water = SColor.LIMITED_PALETTE[23].toFloatBits(),
782                deep_water = SColor.LIMITED_PALETTE[24].toFloatBits(),
783                grass = SColor.LIMITED_PALETTE[21].toFloatBits(),
784                other = SColor.LIMITED_PALETTE[0].toFloatBits();
785        for (int i = 0; i < width; i++) {
786            for (int j = 0; j < height; j++) {
787                switch (map[i][j]) {
788                    case ':':
789                        packed[i][j] = bridge;
790                        break;
791                    case ',':
792                        packed[i][j] = shallow_water;
793                        break;
794                    case '~':
795                        packed[i][j] = deep_water;
796                        break;
797                    case '"':
798                        packed[i][j] = grass;
799                        break;
800                    default:
801                        packed[i][j] = other;
802                }
803            }
804        }
805        return packed;
806    }
807
808
809    /**
810     * Produces a float[][] of packed float colors that corresponds to appropriate default background colors for the
811     * usual meanings of the chars in map. This overload also takes a char that corresponds to deep non-water lakes
812     * (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a packed float color to use
813     * for that deep liquid,  as well as a char for shallow lakes and a packed float color for that shallow liquid.
814     * <br>
815     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
816     * colors this returns will also change. Most backgrounds will be black; this can be changed by editing
817     * {@code SColor.LIMITED_PALETTE[0]}. Deep water ('~') will be dark blue-green; this can be changed by editing
818     * {@code SColor.LIMITED_PALETTE[24]}. Shallow water (',') will be a lighter blue-green; this can be changed by
819     * editing {@code SColor.LIMITED_PALETTE[23]}. Grass ('"') will be dark green; this can be changed by editing
820     * {@code SColor.LIMITED_PALETTE[21]}. Bridges (':') will be a medium-dark beige color; this can be changed by
821     * editing {@code SColor.LIMITED_PALETTE[35]}. Deep and shallow lakes of non-water will use the given packed float
822     * color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you don't need
823     * this overload, and {@link #generateDefaultBGColorsFloat(char[][])} will be fine. You can adjust the brightness of
824     * the backgrounds using {@link #generateLightnessModifiers(char[][])}, or if you want water, grass, and lakes to
825     * ripple, you can use the overload {@link #generateLightnessModifiers(char[][], double, char, char)} with some
826     * rising frame or millisecond count.
827     *
828     * @param map a char[][] containing foreground characters (this gets their background color)
829     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
830     * @param deepColor the packed float color to use for deep parts of non-water lakes
831     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
832     * @param shallowColor  the packed float color to use for shallow parts of non-water lakes
833     * @return a 2D array of background packed float colors with the same size as map, that can be used for the corresponding chars
834     */
835    public static float[][] generateDefaultBGColorsFloat(char[][] map, char deepChar, float deepColor,
836                                                         char shallowChar, float shallowColor) {
837        return fillDefaultBGColorsFloat(new float[map.length][map[0].length], map, deepChar, deepColor, shallowChar, shallowColor);
838    }
839    /**
840     * Fills an existing float[][] with packed float colors that correspond to appropriate default background colors for
841     * the usual meanings of the chars in map. This overload also takes a char that corresponds to deep non-water lakes
842     * (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a packed float color to use
843     * for that deep liquid,  as well as a char for shallow lakes and a packed float color for that shallow liquid. The
844     * sizes of packed and map should be identical.
845     * <br>
846     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
847     * colors this returns will also change. Most backgrounds will be black; this can be changed by editing
848     * {@code SColor.LIMITED_PALETTE[0]}. Deep water ('~') will be dark blue-green; this can be changed by editing
849     * {@code SColor.LIMITED_PALETTE[24]}. Shallow water (',') will be a lighter blue-green; this can be changed by
850     * editing {@code SColor.LIMITED_PALETTE[23]}. Grass ('"') will be dark green; this can be changed by editing
851     * {@code SColor.LIMITED_PALETTE[21]}. Bridges (':') will be a medium-dark beige color; this can be changed by
852     * editing {@code SColor.LIMITED_PALETTE[35]}. Deep and shallow lakes of non-water will use the given packed float
853     * color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you don't need
854     * this overload, and {@link #generateDefaultBGColorsFloat(char[][])} will be fine. You can adjust the brightness of
855     * the backgrounds using {@link #generateLightnessModifiers(char[][])}, or if you want water, grass, and lakes to
856     * ripple, you can use the overload {@link #generateLightnessModifiers(char[][], double, char, char)} with some
857     * rising frame or millisecond count.
858     * @param packed a float[][] that will be modified, filled with packed float colors; must match map's size
859     * @param map a char[][] containing foreground characters (this gets their background color)
860     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
861     * @param deepColor the packed float color to use for deep parts of non-water lakes
862     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
863     * @param shallowColor  the packed float color to use for shallow parts of non-water lakes
864     * @return a 2D array of background packed float colors with the same size as map, that can be used for the corresponding chars
865     */
866    public static float[][] fillDefaultBGColorsFloat(float[][] packed, char[][] map, char deepChar, float deepColor,
867                                                     char shallowChar, float shallowColor) {
868        int width = map.length;
869        int height = map[0].length;
870        float   bridge = SColor.LIMITED_PALETTE[35].toFloatBits(),
871                shallow_water = SColor.LIMITED_PALETTE[23].toFloatBits(),
872                deep_water = SColor.LIMITED_PALETTE[24].toFloatBits(),
873                grass = SColor.LIMITED_PALETTE[21].toFloatBits(),
874                other = SColor.LIMITED_PALETTE[0].toFloatBits();
875        for (int i = 0; i < width; i++) {
876            for (int j = 0; j < height; j++) {
877                switch (map[i][j]) {
878                    case ':':
879                        packed[i][j] = bridge;
880                        break;
881                    case ',':
882                        packed[i][j] = shallow_water;
883                        break;
884                    case '~':
885                        packed[i][j] = deep_water;
886                        break;
887                    case '"':
888                        packed[i][j] = grass;
889                        break;
890                    default:
891                        if (map[i][j] == deepChar)
892                            packed[i][j] = deepColor;
893                        else if (map[i][j] == shallowChar)
894                            packed[i][j] = shallowColor;
895                        else packed[i][j] = other;
896                }
897            }
898        }
899        return packed;
900    }
901
902    /**
903     * Produces a float[][] of packed float colors that corresponds to appropriate default background colors for the
904     * usual meanings of the chars in map. Each float represents a color in an efficient way and the version this uses
905     * can be altered by the specified hue, saturation, and value changes.
906     * <br>
907     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
908     * colors this returns will also change. Most backgrounds will be black; this can be changed by editing
909     * {@code SColor.LIMITED_PALETTE[0]}. Deep water ('~') will be dark blue-green; this can be changed by editing
910     * {@code SColor.LIMITED_PALETTE[24]}. Shallow water (',') will be a lighter blue-green; this can be changed by
911     * editing {@code SColor.LIMITED_PALETTE[23]}. Grass ('"') will be dark green; this can be changed by editing
912     * {@code SColor.LIMITED_PALETTE[21]}. Bridges (':') will be a medium-dark beige color; this can be changed by
913     * editing {@code SColor.LIMITED_PALETTE[35]}. You can adjust the brightness of the backgrounds using
914     * {@link #generateLightnessModifiers(char[][])}, or if you want water and grass to ripple, you can use the overload
915     * {@link #generateLightnessModifiers(char[][], double, char, char)} with some rising frame or millisecond count.
916     *
917     * @param map a char[][] containing foreground characters (this gets their background color)
918     * @return a 2D array of background Colors with the same size as map, that can be used for the corresponding chars
919     */
920    public static float[][] generateDefaultBGColorsFloat(char[][] map, final float hueChange, final float saturationChange, final float valueChange) {
921        return fillDefaultBGColorsFloat(new float[map.length][map[0].length], map, hueChange, saturationChange, valueChange);
922    }
923    /**
924     * Fills an existing float[][] with packed float colors that correspond to appropriate default background colors for
925     * the usual meanings of the chars in map. Each float represents a color in an efficient way and the version this
926     * uses can be altered by the specified hue, saturation, and value changes. The sizes of map and packed should be
927     * identical.
928     * <br>
929     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
930     * colors this returns will also change. Most backgrounds will be black; this can be changed by editing
931     * {@code SColor.LIMITED_PALETTE[0]}. Deep water ('~') will be dark blue-green; this can be changed by editing
932     * {@code SColor.LIMITED_PALETTE[24]}. Shallow water (',') will be a lighter blue-green; this can be changed by
933     * editing {@code SColor.LIMITED_PALETTE[23]}. Grass ('"') will be dark green; this can be changed by editing
934     * {@code SColor.LIMITED_PALETTE[21]}. Bridges (':') will be a medium-dark beige color; this can be changed by
935     * editing {@code SColor.LIMITED_PALETTE[35]}. You can adjust the brightness of the backgrounds using
936     * {@link #generateLightnessModifiers(char[][])}, or if you want water and grass to ripple, you can use the overload
937     * {@link #generateLightnessModifiers(char[][], double, char, char)} with some rising frame or millisecond count.
938     * @param packed a float[][] that will be modified, filled with packed float colors; must match map's size
939     * @param map a char[][] containing foreground characters (this gets their background color)
940     * @param hueChange a float from -1f to 1f that will be added to the hues of colors this uses
941     * @param saturationChange a float from -1f to 1f that will be added to the saturation of colors this uses
942     * @param valueChange a float from -1f to 1f that will be added to the values of colors this uses
943     * @return a 2D array of background Colors with the same size as map, that can be used for the corresponding chars
944     */
945    public static float[][] fillDefaultBGColorsFloat(float[][] packed, char[][] map, final float hueChange, final float saturationChange, final float valueChange) {
946        int width = map.length;
947        int height = map[0].length;
948        float   bridge = SColor.LIMITED_PALETTE[35].toEditedFloat(hueChange, saturationChange, valueChange),
949                shallow_water = SColor.LIMITED_PALETTE[23].toEditedFloat(hueChange, saturationChange, valueChange),
950                deep_water = SColor.LIMITED_PALETTE[24].toEditedFloat(hueChange, saturationChange, valueChange),
951                grass = SColor.LIMITED_PALETTE[21].toEditedFloat(hueChange, saturationChange, valueChange),
952                other = SColor.LIMITED_PALETTE[0].toEditedFloat(hueChange, saturationChange, valueChange);
953        for (int i = 0; i < width; i++) {
954            for (int j = 0; j < height; j++) {
955                switch (map[i][j]) {
956                    case ':':
957                        packed[i][j] = bridge;
958                        break;
959                    case ',':
960                        packed[i][j] = shallow_water;
961                        break;
962                    case '~':
963                        packed[i][j] = deep_water;
964                        break;
965                    case '"':
966                        packed[i][j] = grass;
967                        break;
968                    default:
969                        packed[i][j] = other;
970                }
971            }
972        }
973        return packed;
974    }
975
976
977    /**
978     * Produces a float[][] of packed float colors that corresponds to appropriate default background colors for the
979     * usual meanings of the chars in map. Each float represents a color in an efficient way and the version this uses
980     * can be altered by the specified hue, saturation, and value changes. This overload also takes a char that
981     * corresponds to deep non-water lakes
982     * (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a packed float color to use
983     * for that deep liquid,  as well as a char for shallow lakes and a packed float color for that shallow liquid.
984     * <br>
985     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
986     * colors this returns will also change. Most backgrounds will be black; this can be changed by editing
987     * {@code SColor.LIMITED_PALETTE[0]}. Deep water ('~') will be dark blue-green; this can be changed by editing
988     * {@code SColor.LIMITED_PALETTE[24]}. Shallow water (',') will be a lighter blue-green; this can be changed by
989     * editing {@code SColor.LIMITED_PALETTE[23]}. Grass ('"') will be dark green; this can be changed by editing
990     * {@code SColor.LIMITED_PALETTE[21]}. Bridges (':') will be a medium-dark beige color; this can be changed by
991     * editing {@code SColor.LIMITED_PALETTE[35]}. Deep and shallow lakes of non-water will use the given packed float
992     * color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you don't need
993     * this overload, and {@link #generateDefaultBGColorsFloat(char[][])} will be fine. You can adjust the brightness of
994     * the backgrounds using {@link #generateLightnessModifiers(char[][])}, or if you want water, grass, and lakes to
995     * ripple, you can use the overload {@link #generateLightnessModifiers(char[][], double, char, char)} with some
996     * rising frame or millisecond count.
997     *
998     * @param map a char[][] containing foreground characters (this gets their background color)
999     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
1000     * @param deepColor the packed float color to use for deep parts of non-water lakes
1001     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
1002     * @param shallowColor  the packed float color to use for shallow parts of non-water lakes
1003     * @param hueChange a float from -1f to 1f that will be added to the hues of colors this uses
1004     * @param saturationChange a float from -1f to 1f that will be added to the saturation of colors this uses
1005     * @param valueChange a float from -1f to 1f that will be added to the values of colors this uses
1006     * @return a 2D array of background packed float colors with the same size as map, that can be used for the corresponding chars
1007     */
1008    public static float[][] generateDefaultBGColorsFloat(char[][] map, char deepChar, float deepColor,
1009                                                         char shallowChar, float shallowColor,
1010                                                         final float hueChange, final float saturationChange, final float valueChange) {
1011        return fillDefaultBGColorsFloat(new float[map.length][map[0].length], map, deepChar, deepColor, shallowChar, shallowColor, hueChange, saturationChange, valueChange);
1012    }
1013    /**
1014     * Fills an existing float[][] with packed float colors that correspond to appropriate default background colors for
1015     * the usual meanings of the chars in map. Each float represents a color in an efficient way and the version this
1016     * uses can be altered by the specified hue, saturation, and value changes. This overload also takes a char that
1017     * corresponds to deep non-water lakes
1018     * (which {@link squidpony.squidgrid.mapping.SectionDungeonGenerator} can produce) and a packed float color to use
1019     * for that deep liquid,  as well as a char for shallow lakes and a packed float color for that shallow liquid. The
1020     * sizes of packed and map should be identical.
1021     * <br>
1022     * This takes its values from {@link SColor#LIMITED_PALETTE}, and if that field is changed then the
1023     * colors this returns will also change. Most backgrounds will be black; this can be changed by editing
1024     * {@code SColor.LIMITED_PALETTE[0]}. Deep water ('~') will be dark blue-green; this can be changed by editing
1025     * {@code SColor.LIMITED_PALETTE[24]}. Shallow water (',') will be a lighter blue-green; this can be changed by
1026     * editing {@code SColor.LIMITED_PALETTE[23]}. Grass ('"') will be dark green; this can be changed by editing
1027     * {@code SColor.LIMITED_PALETTE[21]}. Bridges (':') will be a medium-dark beige color; this can be changed by
1028     * editing {@code SColor.LIMITED_PALETTE[35]}. Deep and shallow lakes of non-water will use the given packed float
1029     * color parameters. If you are using SectionDungeonGenerator to produce normal water lakes, then you don't need
1030     * this overload, and {@link #generateDefaultBGColorsFloat(char[][])} will be fine. You can adjust the brightness of
1031     * the backgrounds using {@link #generateLightnessModifiers(char[][])}, or if you want water, grass, and lakes to
1032     * ripple, you can use the overload {@link #generateLightnessModifiers(char[][], double, char, char)} with some
1033     * rising frame or millisecond count.
1034     * @param packed a float[][] that will be modified, filled with packed float colors; must match map's size
1035     * @param map a char[][] containing foreground characters (this gets their background color)
1036     * @param deepChar the char that represents deep parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
1037     * @param deepColor the packed float color to use for deep parts of non-water lakes
1038     * @param shallowChar the char that represents shallow parts of non-water lakes, from {@link squidpony.squidgrid.mapping.SectionDungeonGenerator}
1039     * @param shallowColor  the packed float color to use for shallow parts of non-water lakes
1040     * @param hueChange a float from -1f to 1f that will be added to the hues of colors this uses
1041     * @param saturationChange a float from -1f to 1f that will be added to the saturation of colors this uses
1042     * @param valueChange a float from -1f to 1f that will be added to the values of colors this uses
1043     * @return a 2D array of background packed float colors with the same size as map, that can be used for the corresponding chars
1044     */
1045    public static float[][] fillDefaultBGColorsFloat(float[][] packed, char[][] map, char deepChar, float deepColor,
1046                                                     char shallowChar, float shallowColor,
1047                                                     final float hueChange, final float saturationChange, final float valueChange) {
1048        int width = map.length;
1049        int height = map[0].length;
1050        float   bridge = SColor.LIMITED_PALETTE[35].toEditedFloat(hueChange, saturationChange, valueChange),
1051                shallow_water = SColor.LIMITED_PALETTE[23].toEditedFloat(hueChange, saturationChange, valueChange),
1052                deep_water = SColor.LIMITED_PALETTE[24].toEditedFloat(hueChange, saturationChange, valueChange),
1053                grass = SColor.LIMITED_PALETTE[21].toEditedFloat(hueChange, saturationChange, valueChange),
1054                other = SColor.LIMITED_PALETTE[0].toEditedFloat(hueChange, saturationChange, valueChange);
1055        for (int i = 0; i < width; i++) {
1056            for (int j = 0; j < height; j++) {
1057                switch (map[i][j]) {
1058                    case ':':
1059                        packed[i][j] = bridge;
1060                        break;
1061                    case ',':
1062                        packed[i][j] = shallow_water;
1063                        break;
1064                    case '~':
1065                        packed[i][j] = deep_water;
1066                        break;
1067                    case '"':
1068                        packed[i][j] = grass;
1069                        break;
1070                    default:
1071                        if (map[i][j] == deepChar)
1072                            packed[i][j] = deepColor;
1073                        else if (map[i][j] == shallowChar)
1074                            packed[i][j] = shallowColor;
1075                        else packed[i][j] = other;
1076                }
1077            }
1078        }
1079        return packed;
1080    }
1081
1082    /**
1083     * Produces an int[][] that can be used with SquidLayers to alter the background colors.
1084     *
1085     * @param map a char[][] that you want to be find background lightness modifiers for
1086     * @return a 2D array of lightness values from -255 to 255 but usually close to 0; can be passed to SquidLayers
1087     */
1088    public static int[][] generateLightnessModifiers(char[][] map) {
1089        return fillLightnessModifiers(new int[map.length][map[0].length], map);
1090    }
1091    /**
1092     * Fills an existing int[][] with lighting values that can be used with SquidLayers to alter the background colors.
1093     *
1094     * @param map a char[][] that you want to be find background lightness modifiers for
1095     * @return a 2D array of lightness values from -255 to 255 but usually close to 0; can be passed to SquidLayers
1096     */
1097    public static int[][] fillLightnessModifiers(int[][] lights, char[][] map) {
1098        int width = map.length;
1099        int height = map[0].length;
1100        for (int i = 0; i < width; i++) {
1101            for (int j = 0; j < height; j++) {
1102                switch (map[i][j]) {
1103                    case '\1':
1104                    case '├':
1105                    case '┤':
1106                    case '┴':
1107                    case '┬':
1108                    case '┌':
1109                    case '┐':
1110                    case '└':
1111                    case '┘':
1112                    case '│':
1113                    case '─':
1114                    case '┼':
1115                    case '#':
1116                        lights[i][j] = 30;
1117                        break;
1118                    case '.':
1119                        lights[i][j] = 0;
1120                        break;
1121                    case ':':
1122                        lights[i][j] = -15;
1123                        break;
1124                    case '+':
1125                    case '/':
1126                        lights[i][j] = -10;
1127                        break;
1128                    case ',':
1129                        lights[i][j] = -40;
1130                        break;
1131                    case '~':
1132                        lights[i][j] = -85;
1133                        break;
1134                    case '"':
1135                        lights[i][j] = -110;
1136                        break;
1137                    case '^':
1138                        lights[i][j] = 40;
1139                        break;
1140                    default:
1141                        lights[i][j] = 0;
1142                }
1143            }
1144        }
1145        return lights;
1146    }
1147
1148    /**
1149     * Produces an int[][] that can be used with SquidLayers to alter the background colors, accepting a parameter for
1150     * animation frame if rippling water and waving grass using SeededNoise are desired.
1151     *
1152     * @param map   a char[][] that you want to be find background lightness modifiers for
1153     * @param frame         a counter that typically should increase by between 10.0 and 20.0 each second; higher numbers make
1154     *                      water and grass move more, and 0.013 multiplied by the current time in milliseconds works well
1155     *                      as long as only the smaller digits of the time are used; this can be accomplished with
1156     *                      {@code (System.currentTimeMillis() & 0xFFFFFF) * 0.013} .
1157     * @return a 2D array of lightness values from -255 to 255 but usually close to 0; can be passed to SquidLayers
1158     */
1159    public static int[][] generateLightnessModifiers(char[][] map, double frame) {
1160        return fillLightnessModifiers(new int[map.length][map[0].length], map, frame);
1161    }
1162
1163    /**
1164     * Fills an existing int[][] with lighting values that can be used with SquidLayers to alter the background colors,
1165     * accepting a parameter for animation frame if rippling water and waving grass using SeededNoise are desired.
1166     *
1167     * @param lights an int[][] that will be modified, filled with lighting ints; must match map's size
1168     * @param map    a char[][] that you want to be find background lightness modifiers for
1169     * @param frame         a counter that typically should increase by between 10.0 and 20.0 each second; higher numbers make
1170     *                      water and grass move more, and 0.013 multiplied by the current time in milliseconds works well
1171     *                      as long as only the smaller digits of the time are used; this can be accomplished with
1172     *                      {@code (System.currentTimeMillis() & 0xFFFFFF) * 0.013} .
1173     * @return a 2D array of lightness values from -255 to 255 but usually close to 0; can be passed to SquidLayers
1174     */
1175    public static int[][] fillLightnessModifiers(int[][] lights, char[][] map, double frame) {
1176        int width = map.length;
1177        int height = map[0].length;
1178        for (int i = 0; i < width; i++) {
1179            for (int j = 0; j < height; j++) {
1180                switch (map[i][j]) {
1181                    case '\1':
1182                    case '├':
1183                    case '┤':
1184                    case '┴':
1185                    case '┬':
1186                    case '┌':
1187                    case '┐':
1188                    case '└':
1189                    case '┘':
1190                    case '│':
1191                    case '─':
1192                    case '┼':
1193                    case '#':
1194                        lights[i][j] = 30;
1195                        break;
1196                    case '.':
1197                        lights[i][j] = 0;
1198                        break;
1199                    case ':':
1200                        lights[i][j] = -15;
1201                        break;
1202                    case '+':
1203                    case '/':
1204                        lights[i][j] = -10;
1205                        break;
1206                    case ',':
1207                        lights[i][j] = (int) (85 * (SeededNoise.noise(i * 0.16, j * 0.16, frame * 0.05, 1234567) * 0.55 - 0.7));
1208                        break;
1209                    case '~':
1210                        lights[i][j] = (int) (100 * (SeededNoise.noise(i * 0.16, j * 0.16, frame * 0.05, 1234567) * 0.4 - 0.65));
1211                        break;
1212                    case '"':
1213                        lights[i][j] = (int) (95 * (SeededNoise.noise(i * 0.16, j * 0.16, frame * 0.05, 123456789) * 0.3 - 1.5));
1214                        break;
1215                    case '^':
1216                        lights[i][j] = 40;
1217                        break;
1218                    default:
1219                        lights[i][j] = 0;
1220                }
1221            }
1222        }
1223        return lights;
1224    }
1225
1226    /**
1227     * Produces an int[][] that can be used with SquidLayers to alter the background colors, accepting a parameter for
1228     * animation frame if rippling water and waving grass using SeededNoise are desired. Also allows additional chars
1229     * to be treated like deep and shallow liquid regarding the ripple animation.
1230     *
1231     * @param map           a char[][] that you want to be find background lightness modifiers for
1232     * @param frame         a counter that typically should increase by between 10.0 and 20.0 each second; higher numbers make
1233     *                      water and grass move more, and 0.013 multiplied by the current time in milliseconds works well
1234     *                      as long as only the smaller digits of the time are used; this can be accomplished with
1235     *                      {@code (System.currentTimeMillis() & 0xFFFFFF) * 0.013} .
1236     * @param deepLiquid    a char that will be treated like deep water when animating ripples
1237     * @param shallowLiquid a char that will be treated like shallow water when animating ripples
1238     * @return a 2D array of lightness values from -255 to 255 but usually close to 0; can be passed to SquidLayers
1239     */
1240    public static int[][] generateLightnessModifiers(char[][] map, double frame, char deepLiquid, char shallowLiquid) {
1241        return fillLightnessModifiers(new int[map.length][map[0].length], map, frame, deepLiquid, shallowLiquid);
1242    }
1243    /**
1244     * Fills an existing int[][] with lighting values that can be used with SquidLayers to alter the background colors,
1245     * accepting a parameter for animation frame if rippling water and waving grass using SeededNoise are desired. Also
1246     * allows additional chars to be treated like deep and shallow liquid regarding the ripple animation.
1247     *
1248     * @param lights an int[][] that will be modified, filled with lighting ints; must match map's size
1249     * @param map           a char[][] that you want to be find background lightness modifiers for
1250     * @param frame         a counter that typically should increase by between 10.0 and 20.0 each second; higher numbers make
1251     *                      water and grass move more, and 0.013 multiplied by the current time in milliseconds works well
1252     *                      as long as only the smaller digits of the time are used; this can be accomplished with
1253     *                      {@code (System.currentTimeMillis() & 0xFFFFFF) * 0.013} .
1254     * @param deepLiquid    a char that will be treated like deep water when animating ripples
1255     * @param shallowLiquid a char that will be treated like shallow water when animating ripples
1256     * @return a 2D array of lightness values from -255 to 255 but usually close to 0; can be passed to SquidLayers
1257     */
1258    public static int[][] fillLightnessModifiers(int[][] lights, char[][] map, double frame, char deepLiquid, char shallowLiquid) {
1259        int width = map.length;
1260        int height = map[0].length;
1261        for (int i = 0; i < width; i++) {
1262            for (int j = 0; j < height; j++) {
1263                switch (map[i][j]) {
1264                    case '\1':
1265                    case '├':
1266                    case '┤':
1267                    case '┴':
1268                    case '┬':
1269                    case '┌':
1270                    case '┐':
1271                    case '└':
1272                    case '┘':
1273                    case '│':
1274                    case '─':
1275                    case '┼':
1276                    case '#':
1277                        lights[i][j] = 30;
1278                        break;
1279                    case '.':
1280                        lights[i][j] = 0;
1281                        break;
1282                    case ':':
1283                        lights[i][j] = -15;
1284                        break;
1285                    case '+':
1286                    case '/':
1287                        lights[i][j] = -10;
1288                        break;
1289                    case ',':
1290                        lights[i][j] = (int) (85 * (SeededNoise.noise(i * 0.16, j * 0.16, frame * 0.05, 1234567) * 0.55 - 0.7));
1291                        break;
1292                    case '~':
1293                        lights[i][j] = (int) (100 * (SeededNoise.noise(i * 0.16, j * 0.16, frame * 0.05, 1234567) * 0.4 - 0.65));
1294                        break;
1295                    case '"':
1296                        lights[i][j] = (int) (95 * (SeededNoise.noise(i * 0.16, j * 0.16, frame * 0.05, 123456789) * 0.3 - 1.5));
1297                        break;
1298                    case '^':
1299                        lights[i][j] = 40;
1300                        break;
1301                    default:
1302                        if (map[i][j] == deepLiquid)
1303                            lights[i][j] = (int) (180 * (SeededNoise.noise(i * 0.46, j * 0.46, frame * 0.041, 987654321) * 0.45 - 0.7));
1304                        else if (map[i][j] == shallowLiquid)
1305                            lights[i][j] = (int) (110 * (SeededNoise.noise(i * 0.56, j * 0.56, frame * 0.061, 987654321) * 0.4 - 0.65));
1306                        else lights[i][j] = 0;
1307                }
1308            }
1309        }
1310        return lights;
1311    }
1312
1313    /**
1314     * Meant to be used with {@link TextCellFactory#draw(Batch, float[][], float, float, int, int)}, this produces a
1315     * triple-width, triple-height float color array by finding the box-drawing characters in {@code map} and placing
1316     * 3x3 boxes into that triple-size array with the matching color from {@code colors} in the shape of that
1317     * box-drawing character. {@code map} and {@code colors} should be the same size. Will return a new 2D float array.
1318     * This should usually be passed to the aforementioned TextCellFactory draw method with 3 xSubCells and 3 ySubCells.
1319     * An intended purpose for this is to draw box-drawing-like blocks when the font doesn't support box-drawing
1320     * characters or those characters don't line up correctly for any reason.
1321     * @param map a 2D char array that will not be modified; box drawing characters in this will be drawn in the returned array
1322     * @param colors a 2D float array of packed float colors to use for drawing boxes (possibly produced by
1323     *               {@link #fillDefaultColorsFloat(float[][], char[][])} or other methods in this class)
1324     * @return a 2D float array that can be drawn by {@link TextCellFactory#draw(Batch, float[][], float, float, int, int)} with 3x3 subcells
1325     */
1326    public static float[][] generateLinesToBoxes(char[][] map, float[][] colors) {
1327        return fillLinesToBoxes(null, map, colors);
1328    }
1329
1330    /**
1331     * Meant to be used with {@link TextCellFactory#draw(Batch, float[][], float, float, int, int)}, this finds the
1332     * box-drawing characters in {@code map} and fills 3x3 boxes in {@code into} with the matching color from
1333     * {@code colors} in the shape of that box-drawing character. This means {@code into} must have at least 3 times the
1334     * width and height of {@code map}, and {@code map} and {@code colors} should be the same size. If {@code into} is
1335     * appropriately-sized, then this will modify {@code into} in-place; otherwise it will return a new 2D float array.
1336     * This should usually be passed to the aforementioned TextCellFactory draw method with 3 xSubCells and 3 ySubCells.
1337     * An intended purpose for this is to draw box-drawing-like blocks when the font doesn't support box-drawing
1338     * characters or those characters don't line up correctly for any reason.
1339     * @param into a 2D float array that will be cleared, then modified in-place and returned; should be 3x the width
1340     *             and 3x the height of map and colors, but if it is not (or is null) a new array will be allocated
1341     * @param map a 2D char array that will not be modified; box drawing characters in this will be drawn in into
1342     * @param colors a 2D float array of packed float colors to use for drawing boxes (possibly produced by
1343     *               {@link #fillDefaultColorsFloat(float[][], char[][])} or other methods in this class)
1344     * @return {@code into}, if modified, or a new 2D float array if into was null or incorrectly sized
1345     */
1346    public static float[][] fillLinesToBoxes(float[][] into, char[][] map, float[][] colors) {
1347        final int width = Math.min(map.length, colors.length);
1348        final int height = Math.min(map[0].length, colors[0].length);
1349        if(into == null || into.length < width * 3 || into[0].length < height * 3)
1350            into = new float[width * 3][height * 3];
1351        else
1352            ArrayTools.fill(into, 0f);
1353        for (int i = 0, x = 0; i < width; i++, x+=3) {
1354            for (int j = 0, y = 0; j < height; j++, y+=3) {
1355                switch (map[i][j]) {
1356                    case '\1':
1357                    case '#':
1358                        into[x][y] = into[x+1][y] = into[x+2][y] =
1359                                into[x][y+1] = into[x+1][y+1] = into[x+2][y+1] =
1360                                        into[x][y+2] = into[x+1][y+2] = into[x+2][y+2] = colors[i][j];
1361                        break;
1362                    case '├':
1363                        /*into[x][y] =*/ into[x+1][y] = /*into[x+2][y] =*/
1364                            /*into[x][y+1] =*/ into[x+1][y+1] = into[x+2][y+1] =
1365                            /*into[x][y+2] =*/ into[x+1][y+2] = /*into[x+2][y+2] =*/ colors[i][j];
1366                        break;
1367                    case '┤':
1368                        /*into[x][y] =*/ into[x+1][y] = /*into[x+2][y] =*/
1369                            into[x][y+1] = into[x+1][y+1] = /*into[x+2][y+1] =*/
1370                                    /*into[x][y+2] =*/ into[x+1][y+2] = /*into[x+2][y+2] =*/ colors[i][j];
1371                        break;
1372                    case '┴':
1373                        /*into[x][y] =*/ into[x+1][y] = /*into[x+2][y] =*/
1374                            into[x][y+1] = into[x+1][y+1] = into[x+2][y+1] =
1375                                    /*into[x][y+2] = into[x+1][y+2] = into[x+2][y+2] =*/ colors[i][j];
1376                        break;
1377                    case '┬':
1378                        /*into[x][y] = into[x+1][y] = into[x+2][y] =*/
1379                        into[x][y+1] = into[x+1][y+1] = into[x+2][y+1] =
1380                                /*into[x][y+2] =*/ into[x+1][y+2] = /*into[x+2][y+2] =*/ colors[i][j];
1381                        break;
1382                    case '┌':
1383                        /*into[x][y] = into[x+1][y] = into[x+2][y] =*/
1384                        /*into[x][y+1] =*/ into[x+1][y+1] = into[x+2][y+1] =
1385                            /*into[x][y+2] =*/ into[x+1][y+2] = /*into[x+2][y+2] =*/ colors[i][j];
1386                        break;
1387                    case '┐':
1388                        /*into[x][y] = into[x+1][y] = into[x+2][y] =*/
1389                        into[x][y+1] = into[x+1][y+1] = /*into[x+2][y+1] =*/
1390                                /*into[x][y+2] =*/ into[x+1][y+2] = /*into[x+2][y+2] =*/ colors[i][j];
1391                        break;
1392                    case '└':
1393                        /*into[x][y] =*/ into[x+1][y] = /*into[x+2][y] =*/
1394                            /*into[x][y+1] =*/ into[x+1][y+1] = into[x+2][y+1] =
1395                            /*into[x][y+2] = into[x+1][y+2] = into[x+2][y+2] =*/ colors[i][j];
1396                        break;
1397                    case '┘':
1398                        /*into[x][y] =*/ into[x+1][y] = /*into[x+2][y] =*/
1399                            into[x][y+1] = into[x+1][y+1] = /*into[x+2][y+1] =*/
1400                                    /*into[x][y+2] = into[x+1][y+2] = into[x+2][y+2] =*/ colors[i][j];
1401                        break;
1402                    case '│':
1403                        /*into[x][y] =*/ into[x+1][y] = /*into[x+2][y] =*/
1404                            /*into[x][y+1] =*/ into[x+1][y+1] = /*into[x+2][y+1] =*/
1405                            /*into[x][y+2] =*/ into[x+1][y+2] = /*into[x+2][y+2] =*/ colors[i][j];
1406                        break;
1407                    case '─':
1408                        into[x][y+1] = into[x+1][y+1] = into[x+2][y+1] = colors[i][j];
1409                        break;
1410                    case '╴':
1411                        into[x][y+1] = into[x+1][y+1] = colors[i][j];
1412                        break;
1413                    case '╵':
1414                        /*into[x][y] =*/ into[x+1][y] = /*into[x+2][y] =*/
1415                            /*into[x][y+1] =*/ into[x+1][y+1] = /*into[x+2][y+1] =*/ colors[i][j];
1416                        break;
1417                    case '╶':
1418                        into[x+1][y+1] = into[x+2][y+1] = colors[i][j];
1419                        break;
1420                    case '╷':
1421                            /*into[x][y+1] =*/ into[x+1][y+1] = /*into[x+2][y+1] =*/
1422                            /*into[x][y+2] =*/ into[x+1][y+2] = /*into[x+2][y+2] =*/ colors[i][j];
1423                        break;
1424                    case '┼':
1425                        /*into[x][y] =*/ into[x+1][y] = /*into[x+2][y] =*/
1426                            into[x][y+1] = into[x+1][y+1] = into[x+2][y+1] =
1427                                    /*into[x][y+2] =*/ into[x+1][y+2] = /*into[x+2][y+2] =*/ colors[i][j];
1428                        break;
1429                }
1430            }
1431        }
1432        return into;
1433    }
1434
1435}