Difference between revisions of "Camera View, Rotate, Trim and Pad a Map in Dart"
Jump to navigation
Jump to search
(initial) |
(No difference)
|
Revision as of 13:26, 16 October 2023
Dart Implementation of Map Transformations
The code below is versatile in that it is map engine agnostic.
It will trim, pad, copy and rotate about any list-of-lists.
Usage
Rotate Right
final map = '''
##########
###....###
###....###
###....###
###....###
###....###
######.###
######▒▒▒#''';
List<List<String>> mapList =
map.trim().split('\n').map((row) => row.split('')).toList();
List<List<dynamic>> result = Transform.rotateRight(mapList);
String mapString = result.map((e) => e.join('')).join('\n');
print(mapString);
// ########
// ########
// ########
// ##.....#
// ##.....#
// ##.....#
// ▒......#
// ▒#######
// ▒#######
// ########
Pad
final map = '''
##########
###....###
###....###
###....###
###....###
###....###
######.###
######▒▒▒#''';
List<List<String>> mapList =
map.trim().split('\n').map((row) => row.split('')).toList();
String getWall() => '#';
List<List<dynamic>> result = Transform.pad(mapList, 2, getWall);
String mapString = result.map((e) => e.join('')).join('\n');
print(mapString);
// ##############
// ##############
// ##############
// #####....#####
// #####....#####
// #####....#####
// #####....#####
// #####....#####
// ########.#####
// ########▒▒▒###
// ##############
// ##############
Trim
final map = '''
##############
##############
##############
#####....#####
#####....#####
#####....#####
#####....#####
#####....#####
########.#####
########▒▒▒###
##############
##############''';
List<List<String>> mapList =
map.trim().split('\n').map((row) => row.split('')).toList();
bool isOuterWall(dynamic str) => str == '#';
List<List<dynamic>> result = Transform.trim(mapListPadded, isOuterWall);
String mapString = result.map((e) => e.join('')).join('\n');
print(mapString);
// ########
// #....###
// #....###
// #....###
// #....###
// #....###
// ####.###
// ####▒▒▒#
// ########
Copy
final map = '''
##########
###....###
###....###
###....###
###....###
###....###
######.###
######▒▒▒#''';
List<List<String>> mapList =
map.trim().split('\n').map((row) => row.split('')).toList();
List<List<dynamic>> result = Transform.copy(mapList, 0, 0, 5, 5);
String mapString = result.map((e) => e.join('')).join('\n');
print(mapString);
// ######
// ###...
// ###...
// ###...
// ###...
// ###...
Dart Implementation
class Transform {
// -----------------------------------------------------------------------
// ROTATE
// -----------------------------------------------------------------------
/// Rotates to the right.
static List<List<dynamic>> rotateRight(List<List<dynamic>> target) {
List<List<dynamic>> rotatedList = [];
final width = target.first.length;
final height = target.length - 1;
for (int column = 0; column < width; column++) {
final List<dynamic> lineNew = [];
for (int row = height; row >= 0; row--) {
lineNew.add(target[row][column]);
}
rotatedList.add(lineNew);
}
return rotatedList;
}
// -----------------------------------------------------------------------
// PAD
// -----------------------------------------------------------------------
/// Pads with WALL tiles returned by [getWall].
static List<List<dynamic>> pad(
List<List<dynamic>> mapShape, int padding, dynamic Function() getWall) {
List<List<dynamic>> padded = _padTop(mapShape, padding, getWall);
padded = rotateRight(padded);
padded = _padTop(padded, padding, getWall);
padded = rotateRight(padded);
padded = _padTop(padded, padding, getWall);
padded = rotateRight(padded);
padded = _padTop(padded, padding, getWall);
padded = rotateRight(padded);
return padded;
}
/// Pads a WALL at the top
static List<List<dynamic>> _padTop(
List<List<dynamic>> other, int padding, dynamic Function() getWall) {
final width = other.first.length;
final List<List<dynamic>> mapNew = [];
mapNew.addAll(List<List<dynamic>>.generate(padding, (index) {
return List<dynamic>.generate(width, (index) => getWall.call());
}));
mapNew.addAll(other);
return mapNew;
}
// -----------------------------------------------------------------------
// TRIM
// -----------------------------------------------------------------------
/// Trims all outer WALLS down to a single outer wall.
static List<List<dynamic>> trim(
List<List<dynamic>> mapShape, bool Function(dynamic e) isOuterWall) {
List<List<dynamic>> trimmed = _trimTopInternal(mapShape, isOuterWall);
trimmed = rotateRight(trimmed);
trimmed = _trimTopInternal(trimmed, isOuterWall);
trimmed = rotateRight(trimmed);
trimmed = _trimTopInternal(trimmed, isOuterWall);
trimmed = rotateRight(trimmed);
trimmed = _trimTopInternal(trimmed, isOuterWall);
trimmed = rotateRight(trimmed);
return trimmed;
}
/// Trims WALL tiles from the top of the other elements, leaves ony one WALL.
static List<List<dynamic>> _trimTopInternal(
List<List<dynamic>> other, bool Function(dynamic e) isOuterWall) {
final List<List<dynamic>> rows = [];
int trimTop = 0;
for (int row = 0; row < other.length; row++) {
final List<dynamic> line = other.elementAt(row);
final isOnlyWallsInternal =
line.where((dynamic e) => isOuterWall.call(e)).length == line.length;
if (isOnlyWallsInternal == false) {
break;
}
trimTop = row;
}
rows.addAll(other.getRange(trimTop, other.length));
return rows;
}
// -----------------------------------------------------------------------
// COPY
// -----------------------------------------------------------------------
/// Copies the given coordinates.
///
/// `x1` and `y1` are inclusive.
static List<List<dynamic>> copy(
List<List<dynamic>> target, int x0, int y0, int x1, int y1) {
assert(x0 >= 0 && x1 < target.first.length);
assert(y0 >= 0 && y1 < target.length);
final List<List<dynamic>> copy = [];
for (int y = y0; y <= y1; y++) {
final List<dynamic> copyRow = [];
for (int x = x0; x <= x1; x++) {
copyRow.add(target[y][x]);
}
copy.add(copyRow);
}
return copy;
}
}