Added frontend
All checks were successful
Rust / build_and_test (push) Successful in 2m42s

This commit is contained in:
Lukas Wölfer
2025-08-21 01:27:26 +02:00
parent aa5d621e00
commit fd5f4dd2ab
26 changed files with 1375 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
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 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 fn get_point_bits(&self) -> u8 {
self.points
}
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, 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
}
}
#[cfg(test)]
mod tests {
use crate::{Icon, icon_bitfield::IconBitfield};
#[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);
}
}