2018-08-29 20:12:19 +00:00
|
|
|
import 'dart:core';
|
2018-08-29 20:13:13 +00:00
|
|
|
import 'dart:math';
|
2018-08-29 20:12:19 +00:00
|
|
|
|
|
|
|
import 'package:collection/collection.dart';
|
|
|
|
|
|
|
|
class Grid<E> extends DelegatingList<E> {
|
|
|
|
final List<E> _internal;
|
|
|
|
final width;
|
|
|
|
final height;
|
|
|
|
|
|
|
|
Grid(int width, int height) : this._(List<E>(width * height), width, height);
|
|
|
|
|
|
|
|
Grid.from(Grid<E> l)
|
|
|
|
: this._(List<E>.from(l.getRange(0, l.length)), l.width, l.height);
|
|
|
|
|
|
|
|
Grid.fromList(List<E> l, int width) : this._(l, width, l.length ~/ width);
|
|
|
|
|
|
|
|
Grid._(l, int w, int h)
|
|
|
|
: _internal = l,
|
|
|
|
width = w,
|
|
|
|
height = h,
|
|
|
|
super(l);
|
2018-08-29 20:13:13 +00:00
|
|
|
|
2018-08-30 07:43:46 +00:00
|
|
|
E get(int x, int y) {
|
2018-08-29 20:13:13 +00:00
|
|
|
int i = toIndex(x, y);
|
2018-08-30 07:43:46 +00:00
|
|
|
if (i >= length || x > width - 1) throw RangeError.index(i, this);
|
|
|
|
return _internal[i];
|
2018-08-29 20:13:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void setElement(int x, int y, E value) {
|
|
|
|
int i = toIndex(x, y);
|
|
|
|
if (i >= length) throw RangeError.index(i, this);
|
|
|
|
_internal[i] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set(int x, int y, E value) => setElement(x, y, value);
|
|
|
|
|
2018-08-30 07:52:00 +00:00
|
|
|
/// Calculate list index from coordinates
|
2018-08-30 07:41:43 +00:00
|
|
|
///
|
|
|
|
/// Can be used to get the correct index from coordinates passed in.
|
|
|
|
/// Will only calculate the index, not take into consideration any grid size
|
|
|
|
/// constraints etc; use [get] for that (generally recommended).
|
|
|
|
int toIndex(int x, int y) => (x < 0 || y < 0)
|
|
|
|
? throw RangeError("Coordinates for Grid Indexing must not be negative.")
|
|
|
|
: y * width + x;
|
2018-08-29 20:13:13 +00:00
|
|
|
|
2018-08-30 07:52:00 +00:00
|
|
|
/// Calculate coordinates from list index
|
|
|
|
///
|
|
|
|
/// Calculates the 2-D array coordinates from the corresponding list index
|
|
|
|
/// passed in. Relies on grid width to calculate coordinates. Does not check
|
|
|
|
/// against grid size constraints; use [set] for that (generally recommended).
|
|
|
|
Point<int> toCoordinates(int index) => (index < 0)
|
|
|
|
? throw RangeError("Index for Grid Coordinates must not be negative")
|
|
|
|
: Point<int>(index % width, index ~/ width);
|
2018-08-29 20:12:19 +00:00
|
|
|
}
|