You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
5.0 KiB
Rust

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<Card, Sprite>,
}
impl Deck {
pub(crate) fn iter_cards() -> impl Iterator<Item = Card> {
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)
}
}