const { fill2dArray } = require('../utils');
// tile_fg_names = {
// '0': 'Air',
// '1': 'Dirt',
// '3': 'Snow',
// '4': 'Girder',
// '5': 'Tower',
// '6': 'Stone',
// '7': 'Cement',
// '8': 'Rock',
// '9': 'Wood',
// 'a': 'Wood Stone',
// 'b': 'Cliffside',
// 'c': 'Pool Edges',
// 'd': 'Temple A',
// 'e': 'Temple B',
// 'f': 'Cliffside Alt',
// 'g': 'Reflection',
// 'G': 'Reflection Alt',
// 'h': 'Grass',
// 'i': 'Summit',
// 'j': 'Summit No Snow',
// 'k': 'Core',
// 'l': 'Deadgrass',
// 'm': 'Lost Levels',
// 'n': 'Scifi',
// 'z': 'Template',
// 'Air': '0',
// 'Dirt': '1',
// 'Snow': '3',
// 'Girder': '4',
// 'Tower': '5',
// 'Stone': '6',
// 'Cement': '7',
// 'Rock': '8',
// 'Wood': '9',
// 'Wood Stone': 'a',
// 'Cliffside': 'b',
// 'Pool Edges': 'c',
// 'Temple A': 'd',
// 'Temple B': 'e',
// 'Cliffside Alt': 'f',
// 'Reflection': 'g',
// 'Reflection Alt': 'G',
// 'Grass': 'h',
// 'Summit': 'i',
// 'Summit No Snow': 'j',
// 'Core': 'k',
// 'Deadgrass': 'l',
// 'Lost Levels': 'm',
// 'Scifi': 'n',
// 'Template': 'z'
// };
// const tile_bg_names = {
// '0': 'Air',
// '1': 'Dirt',
// '2': 'Brick',
// '3': 'Brick Ruined',
// '4': 'Wood',
// '5': 'Resort Stone',
// '6': 'Cliffside',
// '7': 'Pool',
// '8': 'Temple A',
// '9': 'Temple B',
// 'a': 'Reflection',
// 'b': 'Snow',
// 'c': 'Summit',
// 'd': 'Core',
// 'e': 'Lost Levels',
// 'z': 'Template',
// 'Air': '0',
// 'Dirt': '1',
// 'Brick': '2',
// 'Brick Ruined': '3',
// 'Wood': '4',
// 'Resort Stone': '5',
// 'Cliffside': '6',
// 'Pool': '7',
// 'Temple A': '8',
// 'Temple B': '9',
// 'Reflection': 'a',
// 'Snow': 'b',
// 'Summit': 'c',
// 'Core': 'd',
// 'Lost Levels': 'e',
// 'Template': 'z'
// };
// const valid_fg_tiles = [
// '0', '1', '3', '4', '5', '6', '7',
// '8', '9', 'a', 'b', 'c', 'd', 'e',
// 'f', 'g', 'G', 'h', 'i', 'j', 'k',
// 'l'
// ];
// const valid_bg_tiles = [
// '0', '1', '2', '3', '4', '5', '6',
// '7', '8', '9', 'a', 'b', 'c', 'd'
// ];
class Tiles {
/**
* Creates an instance of Tiles
* @constructor
* @param {Array|String} data - A 2D Array of tile values, or a String of values for a 2D Array of tiles.
* @example
* // Both calls create the same set of object tiles
* const { Tiles } = require('lucid-dream');
* const tiles1 = new Tiles([ [ 1, 2 ], [ 3, 4 ] ]);
* const tiles2 = new Tiles('12\n34\n');
* @property {Array} data - A 2D Array of tile values.
*/
constructor(data) {
if (!data || data === '') {
data = fill2dArray('0', 40, 23);
} else if (typeof data === 'string') {
const lines = data.split(/[\n\r]/).filter(l => l).map(l => l.trimEnd());
const cols = Math.max(...(lines.map(l => l.length)));
const rows = lines.length;
data = fill2dArray('0', cols, rows);
lines.forEach((line, index) => {
for (let x = 0; x < line.length; x++) {
data[index][x] = line.charAt(x);
}
});
}
this.data = data;
}
/**
* Returns `[width,height]` size of instance in pixels
* @example
* // returns `[ 32, 16 ]`
* const { Tiles } = require('lucid-dream');
* const tiles = new Tiles('1111\n2234\n');
* tiles.size();
*/
size() {
const height = this.data.length;
const width = (this.data[0] || []).length;
return [ width * 8, height * 8 ];
}
/**
* Using the 2D Array of tile data in the Tiles object, generate a minimized
* String version for encoding.
* @param {String} [emptyValue='0'] - This string is considered the "empty" value in a set of tile values and is used to determine how to minimize the resulting encoded string.
* @param {String} [separator='0'] - The separator for vales in the resulting encoded string.
* @example
* // returns '123\n120\n'
* const { Tiles } = require('lucid-dream');
* const tiles = new Tiles('1230\n1200\n');
* tiles.minimizeTilesString('0', '');
* @returns {String} The minimized encoded tile data string
*/
minimizeTilesString(emptyValue = '0', separator = ',') {
const { data } = this;
const res = [];
const [ rows, cols ] = [ data.length, data[0].length ]; // TODO: fix this
let relevantRowsCount = 0;
for (let i = 0; i < rows; i++) {
relevantRowsCount = i + 1;
if (!data[i].filter(o => o !== emptyValue).length) {
break;
}
}
for (let i = 0; i < relevantRowsCount; i++) {
const row = data[i];
let relevantCols = cols;
for (let j = 0; j < cols; j++) {
if (row[j] !== emptyValue) {
break;
}
relevantCols -= 1;
}
res.push(row.slice(0, relevantCols).join(separator));
}
return res.join('\n');
}
}
module.exports = Tiles;