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());
|
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
|
pub fn fill_row(&mut self, y: i16, mask: u16) {
|
||||||
/// matrix if necessary.
|
if y < 0 {
|
||||||
///
|
|
||||||
/// 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) {
|
|
||||||
// OOB coordinates are considered already set
|
// OOB coordinates are considered already set
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +191,18 @@ where
|
||||||
.expect("y should be within available buffer space") = EMPTY_ROW;
|
.expect("y should be within available buffer space") = EMPTY_ROW;
|
||||||
self.rows += 1;
|
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
|
/// Removes any rows that are completely filled, shifting rows above down. Returns a
|
||||||
|
@ -378,10 +385,37 @@ mod test {
|
||||||
assert_eq!(buf, mat);
|
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]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_set_oob() {
|
fn test_set_oob() {
|
||||||
let mut buf: MatBuf<[u16; 4]> = MatBuf::new();
|
let mut buf: MatBuf<[u16; 4]> = MatBuf::new();
|
||||||
buf.set(0, 4);
|
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.
|
//! Data structures for representing pieces and shapes.
|
||||||
|
|
||||||
use crate::matrix::Mat;
|
use crate::matrix::{Mat, MatBuf};
|
||||||
|
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
|
||||||
|
@ -150,6 +150,23 @@ impl<'c> Cells<'c> {
|
||||||
false
|
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.
|
/// Translates the cells by the given amount in both directions.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn translate(&self, dx: i16, dy: i16) -> Self {
|
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, 2, W), [__, __, __, __, __, __, __, __, xx]);
|
||||||
assert_eq!(isects(1..=9, 3, W), [__; 9]);
|
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