Add MatBuf::fill_row(), Piece::fill()
This commit is contained in:
parent
21f6b25de0
commit
4240c91a34
|
@ -178,12 +178,8 @@ where
|
|||
data[..self.rows].copy_from_slice(mat.data());
|
||||
}
|
||||
|
||||
/// Fills in the cell at the given (x,y) coordinate. Adds new rows to the top of the
|
||||
/// matrix if necessary.
|
||||
///
|
||||
/// Panics if the buffer space cannot fit the new rows.
|
||||
pub fn set(&mut self, x: i16, y: i16) {
|
||||
if y < 0 || !(0..COLUMNS).contains(&x) {
|
||||
pub fn fill_row(&mut self, y: i16, mask: u16) {
|
||||
if y < 0 {
|
||||
// OOB coordinates are considered already set
|
||||
return;
|
||||
}
|
||||
|
@ -195,7 +191,18 @@ where
|
|||
.expect("y should be within available buffer space") = EMPTY_ROW;
|
||||
self.rows += 1;
|
||||
}
|
||||
data[y] |= 1 << x;
|
||||
data[y] |= mask;
|
||||
}
|
||||
|
||||
/// Fills in the cell at the given (x,y) coordinate. Adds new rows to the top of the
|
||||
/// matrix if necessary.
|
||||
///
|
||||
/// Panics if the buffer space cannot fit the new rows.
|
||||
#[inline]
|
||||
pub fn set(&mut self, x: i16, y: i16) {
|
||||
if (0..COLUMNS).contains(&x) {
|
||||
self.fill_row(y, 1 << x);
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes any rows that are completely filled, shifting rows above down. Returns a
|
||||
|
@ -378,10 +385,37 @@ mod test {
|
|||
assert_eq!(buf, mat);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fill() {
|
||||
let mut buf: MatBuf<[u16; 5]> = MatBuf::new();
|
||||
buf.fill_row(1, 0b110111); // a
|
||||
let mat = mat! {
|
||||
"aaa.aa....";
|
||||
"..........";
|
||||
};
|
||||
assert_eq!(buf, mat);
|
||||
buf.fill_row(3, 0b1000000000); // b
|
||||
buf.fill_row(0, u16::MAX); // c
|
||||
let mat = mat! {
|
||||
".........b";
|
||||
"..........";
|
||||
"aaa.aa....";
|
||||
"cccccccccc";
|
||||
};
|
||||
assert_eq!(buf, mat);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_set_oob() {
|
||||
let mut buf: MatBuf<[u16; 4]> = MatBuf::new();
|
||||
buf.set(0, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_fill_oob() {
|
||||
let mut buf: MatBuf<[u16; 4]> = MatBuf::new();
|
||||
buf.fill_row(4, 0b1001);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Data structures for representing pieces and shapes.
|
||||
|
||||
use crate::matrix::Mat;
|
||||
use crate::matrix::{Mat, MatBuf};
|
||||
|
||||
use core::ops::Range;
|
||||
|
||||
|
@ -150,6 +150,23 @@ impl<'c> Cells<'c> {
|
|||
false
|
||||
}
|
||||
|
||||
/// Fills in all of the cells onto the given matrix. Panics if the piece is out of
|
||||
/// bounds.
|
||||
pub fn fill<T>(&self, mat: &mut MatBuf<T>)
|
||||
where
|
||||
T: AsRef<[u16]> + AsMut<[u16]>,
|
||||
{
|
||||
assert!(
|
||||
self.x >= 0 && self.x + self.w <= mat.cols() && self.y >= 0,
|
||||
"fill() cells oob"
|
||||
);
|
||||
for (dy, &row) in self.data().iter().enumerate() {
|
||||
let y = self.y + dy as i16;
|
||||
let mask = row << self.x; // should never overflow
|
||||
mat.fill_row(y, mask);
|
||||
}
|
||||
}
|
||||
|
||||
/// Translates the cells by the given amount in both directions.
|
||||
#[inline]
|
||||
pub fn translate(&self, dx: i16, dy: i16) -> Self {
|
||||
|
@ -330,4 +347,45 @@ pub mod test {
|
|||
assert_eq!(isects(1..=9, 2, W), [__, __, __, __, __, __, __, __, xx]);
|
||||
assert_eq!(isects(1..=9, 3, W), [__; 9]);
|
||||
}
|
||||
|
||||
fn filled<I>(locs: I) -> MatBuf
|
||||
where
|
||||
I: IntoIterator,
|
||||
Loc: From<I::Item>,
|
||||
{
|
||||
let mut mat = MatBuf::new();
|
||||
for loc in locs {
|
||||
let piece = Piece {
|
||||
ty: Tri,
|
||||
loc: loc.into(),
|
||||
};
|
||||
piece.cells().fill(&mut mat);
|
||||
}
|
||||
mat
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fill() {
|
||||
let act = filled([(0, 0)]);
|
||||
let exp = mat! {
|
||||
"x.........";
|
||||
"xx........";
|
||||
};
|
||||
assert_eq!(act, exp);
|
||||
|
||||
let act = filled([(1, 1, Rot::N), (5, 0, Rot::W)]);
|
||||
let exp = mat! {
|
||||
".n........";
|
||||
".nn..w....";
|
||||
"....ww....";
|
||||
};
|
||||
assert_eq!(act, exp);
|
||||
|
||||
let act = filled([(1, 1, Rot::S), (1, 1, Rot::E)]);
|
||||
let exp = mat! {
|
||||
"sxe.......";
|
||||
".x........";
|
||||
};
|
||||
assert_eq!(act, exp);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue