|
@@ -12,22 +12,34 @@ pub struct Board<T> {
|
|
impl<T: Clone> Board<T> {
|
|
impl<T: Clone> Board<T> {
|
|
pub fn new_with_default(width: usize, height: usize, default: T) -> Board<T> {
|
|
pub fn new_with_default(width: usize, height: usize, default: T) -> Board<T> {
|
|
let mut storage = Vec::with_capacity(width * height);
|
|
let mut storage = Vec::with_capacity(width * height);
|
|
- for _ in 0..width*height {
|
|
|
|
|
|
+ for _ in 0..width * height {
|
|
storage.push(default.clone())
|
|
storage.push(default.clone())
|
|
}
|
|
}
|
|
- Board { width, height, storage }
|
|
|
|
|
|
+ Board {
|
|
|
|
+ width,
|
|
|
|
+ height,
|
|
|
|
+ storage,
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl<T> Board<T> {
|
|
impl<T> Board<T> {
|
|
- pub fn new_from(width: usize, height: usize, mut func: impl FnMut(usize, usize) -> T) -> Board<T> {
|
|
|
|
|
|
+ pub fn new_from(
|
|
|
|
+ width: usize,
|
|
|
|
+ height: usize,
|
|
|
|
+ mut func: impl FnMut(usize, usize) -> T,
|
|
|
|
+ ) -> Board<T> {
|
|
let mut storage = Vec::with_capacity(width * height);
|
|
let mut storage = Vec::with_capacity(width * height);
|
|
for y in 0..height {
|
|
for y in 0..height {
|
|
for x in 0..width {
|
|
for x in 0..width {
|
|
storage.push(func(x, y))
|
|
storage.push(func(x, y))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- Board { width, height, storage }
|
|
|
|
|
|
+ Board {
|
|
|
|
+ width,
|
|
|
|
+ height,
|
|
|
|
+ storage,
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/// Returns a reference to an element at the given location, or
|
|
/// Returns a reference to an element at the given location, or
|
|
@@ -124,7 +136,8 @@ impl<T> std::ops::Index<Coord> for Board<T> {
|
|
type Output = T;
|
|
type Output = T;
|
|
|
|
|
|
fn index(&self, pos: Coord) -> &Self::Output {
|
|
fn index(&self, pos: Coord) -> &Self::Output {
|
|
- self.get(pos.x, pos.y).unwrap_or_else(|| panic!("Coordinate {:?} out of range", pos))
|
|
|
|
|
|
+ self.get(pos.x, pos.y)
|
|
|
|
+ .unwrap_or_else(|| panic!("Coordinate {:?} out of range", pos))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -132,37 +145,41 @@ impl<T> std::ops::Index<(usize, usize)> for Board<T> {
|
|
type Output = T;
|
|
type Output = T;
|
|
|
|
|
|
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
|
|
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
|
|
- self.get(x, y).unwrap_or_else(|| panic!("Coordinate {:?} out of range", (x, y)))
|
|
|
|
|
|
+ self.get(x, y)
|
|
|
|
+ .unwrap_or_else(|| panic!("Coordinate {:?} out of range", (x, y)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-impl<T> std::ops::Index<[usize;2]> for Board<T> {
|
|
|
|
|
|
+impl<T> std::ops::Index<[usize; 2]> for Board<T> {
|
|
type Output = T;
|
|
type Output = T;
|
|
|
|
|
|
- fn index(&self, [x, y]: [usize;2]) -> &Self::Output {
|
|
|
|
- self.get(x, y).unwrap_or_else(|| panic!("Coordinate {:?} out of range", (x, y)))
|
|
|
|
|
|
+ fn index(&self, [x, y]: [usize; 2]) -> &Self::Output {
|
|
|
|
+ self.get(x, y)
|
|
|
|
+ .unwrap_or_else(|| panic!("Coordinate {:?} out of range", (x, y)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl<T> std::ops::IndexMut<Coord> for Board<T> {
|
|
impl<T> std::ops::IndexMut<Coord> for Board<T> {
|
|
fn index_mut(&mut self, pos: Coord) -> &mut Self::Output {
|
|
fn index_mut(&mut self, pos: Coord) -> &mut Self::Output {
|
|
- self.get_mut(pos.x, pos.y).unwrap_or_else(|| panic!("Coordinate {:?} out of range", pos))
|
|
|
|
|
|
+ self.get_mut(pos.x, pos.y)
|
|
|
|
+ .unwrap_or_else(|| panic!("Coordinate {:?} out of range", pos))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl<T> std::ops::IndexMut<(usize, usize)> for Board<T> {
|
|
impl<T> std::ops::IndexMut<(usize, usize)> for Board<T> {
|
|
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
|
|
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
|
|
- self.get_mut(x, y).unwrap_or_else(|| panic!("Coordinate {:?} out of range", (x, y)))
|
|
|
|
|
|
+ self.get_mut(x, y)
|
|
|
|
+ .unwrap_or_else(|| panic!("Coordinate {:?} out of range", (x, y)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-impl<T> std::ops::IndexMut<[usize;2]> for Board<T> {
|
|
|
|
- fn index_mut(&mut self, [x, y]: [usize;2]) -> &mut Self::Output {
|
|
|
|
- self.get_mut(x, y).unwrap_or_else(|| panic!("Coordinate {:?} out of range", (x, y)))
|
|
|
|
|
|
+impl<T> std::ops::IndexMut<[usize; 2]> for Board<T> {
|
|
|
|
+ fn index_mut(&mut self, [x, y]: [usize; 2]) -> &mut Self::Output {
|
|
|
|
+ self.get_mut(x, y)
|
|
|
|
+ .unwrap_or_else(|| panic!("Coordinate {:?} out of range", (x, y)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
/// An iterator over the elements of a `Board`. This returns values in
|
|
/// An iterator over the elements of a `Board`. This returns values in
|
|
/// row-major order but each element is also accompanied by its
|
|
/// row-major order but each element is also accompanied by its
|
|
/// indices.
|
|
/// indices.
|
|
@@ -187,7 +204,6 @@ impl<'a, T> Iterator for BoardIter<'a, T> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
/// An iterator over the elements of a `Board`. This returns values in
|
|
/// An iterator over the elements of a `Board`. This returns values in
|
|
/// row-major order but each element is also accompanied by its
|
|
/// row-major order but each element is also accompanied by its
|
|
/// indices.
|
|
/// indices.
|
|
@@ -212,7 +228,6 @@ impl<'a, T> Iterator for BoardIterMut<'a, T> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
pub struct BoardWindowIter<'a, T> {
|
|
pub struct BoardWindowIter<'a, T> {
|
|
n: usize,
|
|
n: usize,
|
|
width: usize,
|
|
width: usize,
|
|
@@ -236,8 +251,6 @@ impl<'a, T> Iterator for BoardWindowIter<'a, T> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
pub struct BoardWindowIterMut<'a, T> {
|
|
pub struct BoardWindowIterMut<'a, T> {
|
|
n: usize,
|
|
n: usize,
|
|
width: usize,
|
|
width: usize,
|
|
@@ -261,7 +274,6 @@ impl<'a, T> Iterator for BoardWindowIterMut<'a, T> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
#[cfg(test)]
|
|
#[cfg(test)]
|
|
mod test {
|
|
mod test {
|
|
use super::*;
|
|
use super::*;
|
|
@@ -339,11 +351,12 @@ mod test {
|
|
]
|
|
]
|
|
];
|
|
];
|
|
|
|
|
|
- let mut iter = b.window_iter(
|
|
|
|
- Rect {
|
|
|
|
|
|
+ let mut iter = b
|
|
|
|
+ .window_iter(Rect {
|
|
origin: [1, 1].into(),
|
|
origin: [1, 1].into(),
|
|
size: [2, 2].into(),
|
|
size: [2, 2].into(),
|
|
- }).expect("Did not find expected BoardWindowIter");
|
|
|
|
|
|
+ })
|
|
|
|
+ .expect("Did not find expected BoardWindowIter");
|
|
// in-bounds tests
|
|
// in-bounds tests
|
|
assert_eq!(iter.next(), Some((1, 1, &6)));
|
|
assert_eq!(iter.next(), Some((1, 1, &6)));
|
|
assert_eq!(iter.next(), Some((2, 1, &7)));
|
|
assert_eq!(iter.next(), Some((2, 1, &7)));
|
|
@@ -352,34 +365,36 @@ mod test {
|
|
assert_eq!(iter.next(), None);
|
|
assert_eq!(iter.next(), None);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
#[test]
|
|
#[test]
|
|
fn window_iter_mut() {
|
|
fn window_iter_mut() {
|
|
let mut b: Board<isize> = board_from_vec![
|
|
let mut b: Board<isize> = board_from_vec![
|
|
- 4,4;
|
|
|
|
- [1,2,3,4,
|
|
|
|
- 5,6,7,8,
|
|
|
|
- 8,7,6,5,
|
|
|
|
- 4,3,2,1,
|
|
|
|
- ]];
|
|
|
|
-
|
|
|
|
- let iter = b.window_iter_mut(
|
|
|
|
- Rect {
|
|
|
|
|
|
+ 4,4;
|
|
|
|
+ [1,2,3,4,
|
|
|
|
+ 5,6,7,8,
|
|
|
|
+ 8,7,6,5,
|
|
|
|
+ 4,3,2,1,
|
|
|
|
+ ]];
|
|
|
|
+
|
|
|
|
+ let iter = b
|
|
|
|
+ .window_iter_mut(Rect {
|
|
origin: [1, 1].into(),
|
|
origin: [1, 1].into(),
|
|
size: [2, 2].into(),
|
|
size: [2, 2].into(),
|
|
- }).expect("Did not find expected BoardWindowIterMut");
|
|
|
|
|
|
+ })
|
|
|
|
+ .expect("Did not find expected BoardWindowIterMut");
|
|
for (x, y, v) in iter {
|
|
for (x, y, v) in iter {
|
|
*v = -(2 * x as isize + 2 * y as isize);
|
|
*v = -(2 * x as isize + 2 * y as isize);
|
|
}
|
|
}
|
|
|
|
|
|
- assert_eq!(b, board_from_vec![
|
|
|
|
- 4,4;
|
|
|
|
- [ 1, 2, 3, 4,
|
|
|
|
- 5,-4,-6, 8,
|
|
|
|
- 8,-6,-8, 5,
|
|
|
|
- 4, 3, 2, 1,
|
|
|
|
|
|
+ assert_eq!(
|
|
|
|
+ b,
|
|
|
|
+ board_from_vec![
|
|
|
|
+ 4,4;
|
|
|
|
+ [ 1, 2, 3, 4,
|
|
|
|
+ 5,-4,-6, 8,
|
|
|
|
+ 8,-6,-8, 5,
|
|
|
|
+ 4, 3, 2, 1,
|
|
|
|
+ ]
|
|
]
|
|
]
|
|
- ]);
|
|
|
|
|
|
+ );
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|