use bevy::{prelude::*, utils::HashMap}; /// Deck and Cards pub struct DeckPlugin; impl Plugin for DeckPlugin { fn build(&self, _app: &mut App) { // Nothing yet! } } /// We expect 81 cards total #[derive(Resource)] pub(crate) struct Deck { pub cards: HashMap, } impl Deck { pub(crate) fn iter_cards() -> impl Iterator { let mut v = Vec::new(); [ItemColor::Red, ItemColor::Green, ItemColor::Purple] .iter() .for_each(|&color| { [ItemShape::Oval, ItemShape::Diamond, ItemShape::Squiggle] .iter() .for_each(|&shape| { [ItemPattern::Open, ItemPattern::Solid, ItemPattern::Striped] .iter() .for_each(|&pattern| { [ItemNumber::One, ItemNumber::Two, ItemNumber::Three] .iter() .for_each(|&number| { v.push(Card { color, shape, pattern, number, }) }); }); }); }); v.into_iter() } } /// A card describes abstractly the contents of a card /// including color of items, number of items, pattern, and shape #[derive(PartialEq, Eq, Hash, Clone, Copy, Component, Debug)] pub(crate) struct Card { pub color: ItemColor, pub number: ItemNumber, pub pattern: ItemPattern, pub shape: ItemShape, } impl Card { pub(crate) fn sprite(&self) -> (String, TextureAtlasLayout, u8) { let fname = { let col = match self.color { ItemColor::Red => "red", ItemColor::Green => "green", ItemColor::Purple => "purple", }; let pat = match self.pattern { ItemPattern::Solid => "filled", ItemPattern::Striped => "shaded", ItemPattern::Open => "open", }; let shape = match self.shape { ItemShape::Oval => "circle", ItemShape::Diamond => "diamond", ItemShape::Squiggle => "squiggle", }; format!("{}_{}_{}.png", pat, shape, col) }; let num = match self.number { ItemNumber::One => 0, ItemNumber::Two => 1, ItemNumber::Three => 2, }; let size = UVec2 { x: 20, y: 32 }; let layout = TextureAtlasLayout::from_grid(size, 3, 1, None, None); (fname, layout, num) } } impl std::fmt::Display for Card { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "{}\n{}\n{}\n{}", self.number, self.pattern, self.color, self.shape ) } } /// Item colors for the card may be red, green or purple /// All items must be the same color #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub(crate) enum ItemColor { Red, Green, Purple, } impl std::fmt::Display for ItemColor { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let color = match self { ItemColor::Red => "red", ItemColor::Green => "green", ItemColor::Purple => "purple", }; write!(f, "{}", color) } } /// A card may have 1 to 3 items #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub(crate) enum ItemNumber { One, Two, Three, } impl std::fmt::Display for ItemNumber { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let num = match self { ItemNumber::One => 1, ItemNumber::Two => 2, ItemNumber::Three => 3, }; write!(f, "{}", num) } } /// Each item can be solid, striped, or open /// a card has all of it's item as one pattern #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub(crate) enum ItemPattern { Solid, Striped, Open, } impl std::fmt::Display for ItemPattern { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let fill = match self { ItemPattern::Open => "empty", ItemPattern::Striped => "shaded", ItemPattern::Solid => "solid", }; write!(f, "{}", fill) } } /// Each item can be an oval, diamond, or squiggle /// All items on a card are one shape #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub(crate) enum ItemShape { Oval, Diamond, Squiggle, } impl std::fmt::Display for ItemShape { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let shape = match self { ItemShape::Oval => "oval", ItemShape::Diamond => "diamond", ItemShape::Squiggle => "squiggle", }; write!(f, "{}", shape) } }