Created workspace
This commit is contained in:
117
canvas/src/icon_bitfield.rs
Normal file
117
canvas/src/icon_bitfield.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
use crate::Card;
|
||||
use crate::CardField;
|
||||
use crate::Icon;
|
||||
use crate::Painting;
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub(crate) struct IconBitfield {
|
||||
circle: u8,
|
||||
square: u8,
|
||||
triangle: u8,
|
||||
color: u8,
|
||||
points: u8,
|
||||
}
|
||||
|
||||
impl IconBitfield {
|
||||
pub(crate) fn get_icon_bits(&self, icon: Icon) -> u8 {
|
||||
match icon {
|
||||
Icon::Circle => self.circle,
|
||||
Icon::Square => self.square,
|
||||
Icon::Triangle => self.triangle,
|
||||
Icon::Color => self.color,
|
||||
}
|
||||
}
|
||||
pub(crate) fn get_point_bits(&self) -> u8 {
|
||||
self.points
|
||||
}
|
||||
|
||||
pub(crate) fn add_icon(&mut self, icon: Icon, index: u8) {
|
||||
let field = match icon {
|
||||
Icon::Circle => &mut self.circle,
|
||||
Icon::Square => &mut self.square,
|
||||
Icon::Triangle => &mut self.triangle,
|
||||
Icon::Color => &mut self.color,
|
||||
};
|
||||
*field |= 1 << index;
|
||||
}
|
||||
pub fn add_field(&mut self, field: CardField, index: u8) {
|
||||
debug_assert!(index < 5);
|
||||
match field {
|
||||
CardField::Icon(icon) => self.add_icon(icon, index),
|
||||
CardField::DoubleIcon((icon1, icon2)) => {
|
||||
self.add_icon(icon1, index);
|
||||
self.add_icon(icon2, index);
|
||||
}
|
||||
CardField::PointsPer(_) => self.points |= 1 << index,
|
||||
CardField::Empty => (),
|
||||
}
|
||||
}
|
||||
pub fn new(card: &Card) -> Self {
|
||||
let mut result = Self::default();
|
||||
(0u8..)
|
||||
.zip(card.field.iter())
|
||||
.for_each(|(index, field)| result.add_field(field.clone(), index));
|
||||
result
|
||||
}
|
||||
|
||||
pub fn from_painting(painting: &Painting) -> Self {
|
||||
let mut bits = Self::new(&painting[0]);
|
||||
bits.layer_below(&Self::new(&painting[1]))
|
||||
.layer_below(&Self::new(&painting[2]));
|
||||
bits
|
||||
}
|
||||
|
||||
pub fn all_fields(&self) -> u8 {
|
||||
self.circle | self.square | self.triangle | self.color | self.points
|
||||
}
|
||||
|
||||
/// Result of putting the other card below this one
|
||||
pub fn layer_below(&mut self, other: &Self) -> &mut Self {
|
||||
// 1 x 0 = 0
|
||||
// 0 x 0 = 0
|
||||
// 0 x 1 = 1
|
||||
// 1 x 1 = 0
|
||||
// Should be !a & b
|
||||
|
||||
let bitmask = !self.all_fields() & other.all_fields();
|
||||
self.circle |= other.circle & bitmask;
|
||||
self.square |= other.square & bitmask;
|
||||
self.triangle |= other.triangle & bitmask;
|
||||
self.color |= other.color & bitmask;
|
||||
self.points |= other.points & bitmask;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_field() {
|
||||
let mut x: IconBitfield = Default::default();
|
||||
x.add_icon(Icon::Circle, 2);
|
||||
let expected = IconBitfield {
|
||||
circle: 0b00100,
|
||||
..Default::default()
|
||||
};
|
||||
assert_eq!(x, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_layer_below() {
|
||||
let mut a: IconBitfield = IconBitfield {
|
||||
color: 0b00010,
|
||||
points: 0b01000,
|
||||
..Default::default()
|
||||
};
|
||||
let b = IconBitfield {
|
||||
triangle: a.get_point_bits(),
|
||||
square: 0b10000,
|
||||
..Default::default()
|
||||
};
|
||||
let expected = IconBitfield {
|
||||
color: a.get_icon_bits(Icon::Color),
|
||||
points: a.get_point_bits(),
|
||||
square: b.get_icon_bits(Icon::Square),
|
||||
..Default::default()
|
||||
};
|
||||
a.layer_below(&b);
|
||||
assert_eq!(a, expected);
|
||||
}
|
||||
Reference in New Issue
Block a user