use strum_macros::EnumIter;
use crate::card_collection::*;
use crate::hand::*;
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, EnumIter)]
pub enum Name {
Mountain, Cavern, BellTower, Forest, EarthElemental,
FountainOfLife, Swamp, GreatFlood, Island, WaterElemental,
Rainstorm, Blizzard, Smoke, Whirlwind, AirElemental,
Wildfire, Candle, Forge, Lightning, FireElemental,
Knights, ElvenArchers, LightCavalry, DwarvishInfantry, Rangers,
Collector, Beastmaster, Necromancer, WarlockLord, Enchantress,
King, Queen, Princess, Warlord, Empress,
Unicorn, Basilisk, Warhorse, Dragon, Hydra,
Warship, MagicWand, SwordOfKeth, ElvenLongbow, WarDirigible,
ShieldOfKeth, GemOfOrder, WorldTree, BookOfChanges, ProtectionRune,
Shapeshifter, Mirage, Doppelganger,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, EnumIter)]
pub enum Suit {
Land,
Flood,
Weather,
Flame,
Army,
Wizard,
Leader,
Beast,
Weapon,
Artifact,
Wild,
}
pub(crate) mod mountain; pub(crate) use mountain::MOUNTAIN;
pub(crate) mod cavern; pub(crate) use cavern::CAVERN;
pub(crate) mod bell_tower; pub(crate) use bell_tower::BELL_TOWER;
pub(crate) mod forest; pub(crate) use forest::FOREST;
pub(crate) mod earth_elemental; pub(crate) use earth_elemental::EARTH_ELEMENTAL;
pub(crate) mod fountain_of_life; pub(crate) use fountain_of_life::FOUNTAIN_OF_LIFE;
pub(crate) mod swamp; pub(crate) use swamp::SWAMP;
pub(crate) mod great_flood; pub(crate) use great_flood::GREAT_FLOOD;
pub(crate) mod island; pub(crate) use island::ISLAND;
pub(crate) mod water_elemental; pub(crate) use water_elemental::WATER_ELEMENTAL;
pub(crate) mod rainstorm; pub(crate) use rainstorm::RAINSTORM;
pub(crate) mod blizzard; pub(crate) use blizzard::BLIZZARD;
pub(crate) mod smoke; pub(crate) use smoke::SMOKE;
pub(crate) mod whirlwind; pub(crate) use whirlwind::WHIRLWIND;
pub(crate) mod air_elemental; pub(crate) use air_elemental::AIR_ELEMENTAL;
pub(crate) mod wildfire; pub(crate) use wildfire::WILDFIRE;
pub(crate) mod candle; pub(crate) use candle::CANDLE;
pub(crate) mod forge; pub(crate) use forge::FORGE;
pub(crate) mod lightning; pub(crate) use lightning::LIGHTNING;
pub(crate) mod fire_elemental; pub(crate) use fire_elemental::FIRE_ELEMENTAL;
pub(crate) mod knights; pub(crate) use knights::KNIGHTS;
pub(crate) mod elven_archers; pub(crate) use elven_archers::ELVEN_ARCHERS;
pub(crate) mod light_cavalry; pub(crate) use light_cavalry::LIGHT_CAVALRY;
pub(crate) mod dwarvish_infantry; pub(crate) use dwarvish_infantry::DWARVISH_INFANTRY;
pub(crate) mod rangers; pub(crate) use rangers::RANGERS;
pub(crate) mod collector; pub(crate) use collector::COLLECTOR;
pub(crate) mod beastmaster; pub(crate) use beastmaster::BEASTMASTER;
pub(crate) mod necromancer; pub(crate) use necromancer::NECROMANCER;
pub(crate) mod warlock_lord; pub(crate) use warlock_lord::WARLOCK_LORD;
pub(crate) mod enchantress; pub(crate) use enchantress::ENCHANTRESS;
pub(crate) mod king; pub(crate) use king::KING;
pub(crate) mod queen; pub(crate) use queen::QUEEN;
pub(crate) mod princess; pub(crate) use princess::PRINCESS;
pub(crate) mod warlord; pub(crate) use warlord::WARLORD;
pub(crate) mod empress; pub(crate) use empress::EMPRESS;
pub(crate) mod unicorn; pub(crate) use unicorn::UNICORN;
pub(crate) mod basilisk; pub(crate) use basilisk::BASILISK;
pub(crate) mod warhorse; pub(crate) use warhorse::WARHORSE;
pub(crate) mod dragon; pub(crate) use dragon::DRAGON;
pub(crate) mod hydra; pub(crate) use hydra::HYDRA;
pub(crate) mod warship; pub(crate) use warship::WARSHIP;
pub(crate) mod magic_wand; pub(crate) use magic_wand::MAGIC_WAND;
pub(crate) mod sword_of_keth; pub(crate) use sword_of_keth::SWORD_OF_KETH;
pub(crate) mod elven_longbow; pub(crate) use elven_longbow::ELVEN_LONGBOW;
pub(crate) mod war_dirigible; pub(crate) use war_dirigible::WAR_DIRIGIBLE;
pub(crate) mod shield_of_keth; pub(crate) use shield_of_keth::SHIELD_OF_KETH;
pub(crate) mod gem_of_order; pub(crate) use gem_of_order::GEM_OF_ORDER;
pub(crate) mod world_tree; pub(crate) use world_tree::WORLD_TREE;
pub(crate) mod book_of_changes; pub(crate) use book_of_changes::BOOK_OF_CHANGES;
pub(crate) mod protection_rune; pub(crate) use protection_rune::PROTECTION_RUNE;
pub(crate) mod shapeshifter; pub(crate) use shapeshifter::SHAPESHIFTER;
pub(crate) mod mirage; pub(crate) use mirage::MIRAGE;
pub(crate) mod doppelganger; pub(crate) use doppelganger::DOPPELGANGER;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Card {
pub(crate) name: Name,
pub(crate) suit: Suit,
pub(crate) strength: i16,
pub(crate) adder: Option<fn(&Vec<Card>, &CardCollection) -> Vec<Vec<Card>>>,
pub(crate) wild: Option<fn(&Vec<Card>, usize) -> Vec<Vec<Card>>>,
pub(crate) modifier: Option<fn(&Vec<Card>) -> Vec<Vec<Card>>>,
pub(crate) immunity: Option<fn(&mut CardCollection)>,
pub(crate) blanks: Option<fn(&Vec<Card>, &CardCollection, &mut CardCollection)>,
pub(crate) bonus: Option<fn(&ScoringHand) -> i16>,
pub(crate) penalty: Option<fn(&ScoringHand, &CardCollection) -> i16>,
}
use std::fmt;
impl fmt::Display for Card {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = match self.name {
Name::Mountain => "mountain",
Name::Cavern => "cavern",
Name::BellTower => "bell tower",
Name::Forest => "forest",
Name::EarthElemental => "earth elemental",
Name::FountainOfLife => "fountain of life",
Name::Swamp => "swamp",
Name::GreatFlood => "great flood",
Name::Island => "island",
Name::WaterElemental => "water elemental",
Name::Rainstorm => "rainstorm",
Name::Blizzard => "blizzard",
Name::Smoke => "smoke",
Name::Whirlwind => "whirlwind",
Name::AirElemental => "air elemental",
Name::Wildfire => "wild fire",
Name::Candle => "candle",
Name::Forge => "forge",
Name::Lightning => "lightning",
Name::FireElemental => "fire elemental",
Name::Knights => "knights",
Name::ElvenArchers => "elven archers",
Name::LightCavalry => "light cavalry",
Name::DwarvishInfantry => "dwarvish infantry",
Name::Rangers => "rangers",
Name::Collector => "collector",
Name::Beastmaster => "beastmaster",
Name::Necromancer => "necromancer",
Name::WarlockLord => "warlock lord",
Name::Enchantress => "enchantress",
Name::King => "king",
Name::Queen => "queen",
Name::Princess => "princess",
Name::Warlord => "warlord",
Name::Empress => "empress",
Name::Unicorn => "unicorn",
Name::Basilisk => "basilisk",
Name::Warhorse => "warhorse",
Name::Dragon => "dragon",
Name::Hydra => "hydra",
Name::Warship => "warship",
Name::MagicWand => "magic wand",
Name::SwordOfKeth => "sword of keth",
Name::ElvenLongbow => "elven longbow",
Name::WarDirigible => "war dirigible",
Name::ShieldOfKeth => "shield of keth",
Name::GemOfOrder => "gem of order",
Name::WorldTree => "world tree",
Name::BookOfChanges => "book of changes",
Name::ProtectionRune => "protection rune",
Name::Shapeshifter => "shapeshifter",
Name::Mirage => "mirage",
Name::Doppelganger => "doppelganger",
};
write!(f, "{}", name)
}
}
use std::str::FromStr;
impl FromStr for Card {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"mountain" => Ok(MOUNTAIN),
"cavern" => Ok(CAVERN),
"bell tower" => Ok(BELL_TOWER),
"forest" => Ok(FOREST),
"earth elemental" => Ok(EARTH_ELEMENTAL),
"fountain of life" => Ok(FOUNTAIN_OF_LIFE),
"swamp" => Ok(SWAMP),
"great flood" => Ok(GREAT_FLOOD),
"island" => Ok(ISLAND),
"water elemental" => Ok(WATER_ELEMENTAL),
"rainstorm" => Ok(RAINSTORM),
"blizzard" => Ok(BLIZZARD),
"smoke" => Ok(SMOKE),
"whirlwind" => Ok(WHIRLWIND),
"air elemental" => Ok(AIR_ELEMENTAL),
"wildfire" => Ok(WILDFIRE),
"candle" => Ok(CANDLE),
"forge" => Ok(FORGE),
"lightning" => Ok(LIGHTNING),
"fire elemental" => Ok(FIRE_ELEMENTAL),
"knights" => Ok(KNIGHTS),
"elven archers" => Ok(ELVEN_ARCHERS),
"light cavalry" => Ok(LIGHT_CAVALRY),
"dwarvish infantry" => Ok(DWARVISH_INFANTRY),
"rangers" => Ok(RANGERS),
"collector" => Ok(COLLECTOR),
"beastmaster" => Ok(BEASTMASTER),
"necromancer" => Ok(NECROMANCER),
"warlock lord" => Ok(WARLOCK_LORD),
"enchantress" => Ok(ENCHANTRESS),
"king" => Ok(KING),
"queen" => Ok(QUEEN),
"princess" => Ok(PRINCESS),
"warlord" => Ok(WARLORD),
"empress" => Ok(EMPRESS),
"unicorn" => Ok(UNICORN),
"basilisk" => Ok(BASILISK),
"warhorse" => Ok(WARHORSE),
"dragon" => Ok(DRAGON),
"hydra" => Ok(HYDRA),
"warship" => Ok(WARSHIP),
"magic wand" => Ok(MAGIC_WAND),
"sword of keth" => Ok(SWORD_OF_KETH),
"elven longbow" => Ok(ELVEN_LONGBOW),
"war dirigible" => Ok(WAR_DIRIGIBLE),
"shield of keth" => Ok(SHIELD_OF_KETH),
"gem of order" => Ok(GEM_OF_ORDER),
"world tree" => Ok(WORLD_TREE),
"book of changes" => Ok(BOOK_OF_CHANGES),
"protection rune" => Ok(PROTECTION_RUNE),
"shapeshifter" => Ok(SHAPESHIFTER),
"mirage" => Ok(MIRAGE),
"doppelganger" => Ok(DOPPELGANGER),
_ => Err("Invalid card name.".to_string()),
}
}
}
impl From<Name> for Card {
fn from(n: Name) -> Self {
match n {
Name::Mountain => MOUNTAIN,
Name::Cavern => CAVERN,
Name::BellTower => BELL_TOWER,
Name::Forest => FOREST,
Name::EarthElemental => EARTH_ELEMENTAL,
Name::FountainOfLife => FOUNTAIN_OF_LIFE,
Name::Swamp => SWAMP,
Name::GreatFlood => GREAT_FLOOD,
Name::Island => ISLAND,
Name::WaterElemental => WATER_ELEMENTAL,
Name::Rainstorm => RAINSTORM,
Name::Blizzard => BLIZZARD,
Name::Smoke => SMOKE,
Name::Whirlwind => WHIRLWIND,
Name::AirElemental => AIR_ELEMENTAL,
Name::Wildfire => WILDFIRE,
Name::Candle => CANDLE,
Name::Forge => FORGE,
Name::Lightning => LIGHTNING,
Name::FireElemental => FIRE_ELEMENTAL,
Name::Knights => KNIGHTS,
Name::ElvenArchers => ELVEN_ARCHERS,
Name::LightCavalry => LIGHT_CAVALRY,
Name::DwarvishInfantry => DWARVISH_INFANTRY,
Name::Rangers => RANGERS,
Name::Collector => COLLECTOR,
Name::Beastmaster => BEASTMASTER,
Name::Necromancer => NECROMANCER,
Name::WarlockLord => WARLOCK_LORD,
Name::Enchantress => ENCHANTRESS,
Name::King => KING,
Name::Queen => QUEEN,
Name::Princess => PRINCESS,
Name::Warlord => WARLORD,
Name::Empress => EMPRESS,
Name::Unicorn => UNICORN,
Name::Basilisk => BASILISK,
Name::Warhorse => WARHORSE,
Name::Dragon => DRAGON,
Name::Hydra => HYDRA,
Name::Warship => WARSHIP,
Name::MagicWand => MAGIC_WAND,
Name::SwordOfKeth => SWORD_OF_KETH,
Name::ElvenLongbow => ELVEN_LONGBOW,
Name::WarDirigible => WAR_DIRIGIBLE,
Name::ShieldOfKeth => SHIELD_OF_KETH,
Name::GemOfOrder => GEM_OF_ORDER,
Name::WorldTree => WORLD_TREE,
Name::BookOfChanges => BOOK_OF_CHANGES,
Name::ProtectionRune => PROTECTION_RUNE,
Name::Shapeshifter => SHAPESHIFTER,
Name::Mirage => MIRAGE,
Name::Doppelganger => DOPPELGANGER,
}
}
}
impl From<u8> for Card {
fn from(n: u8) -> Self {
match n {
0 => MOUNTAIN,
1 => CAVERN,
2 => BELL_TOWER,
3 => FOREST,
4 => EARTH_ELEMENTAL,
5 => FOUNTAIN_OF_LIFE,
6 => SWAMP,
7 => GREAT_FLOOD,
8 => ISLAND,
9 => WATER_ELEMENTAL,
10 => RAINSTORM,
11 => BLIZZARD,
12 => SMOKE,
13 => WHIRLWIND,
14 => AIR_ELEMENTAL,
15 => WILDFIRE,
16 => CANDLE,
17 => FORGE,
18 => LIGHTNING,
19 => FIRE_ELEMENTAL,
20 => KNIGHTS,
21 => ELVEN_ARCHERS,
22 => LIGHT_CAVALRY,
23 => DWARVISH_INFANTRY,
24 => RANGERS,
25 => COLLECTOR,
26 => BEASTMASTER,
27 => NECROMANCER,
28 => WARLOCK_LORD,
29 => ENCHANTRESS,
30 => KING,
31 => QUEEN,
32 => PRINCESS,
33 => WARLORD,
34 => EMPRESS,
35 => UNICORN,
36 => BASILISK,
37 => WARHORSE,
38 => DRAGON,
39 => HYDRA,
40 => WARSHIP,
41 => MAGIC_WAND,
42 => SWORD_OF_KETH,
43 => ELVEN_LONGBOW,
44 => WAR_DIRIGIBLE,
45 => SHIELD_OF_KETH,
46 => GEM_OF_ORDER,
47 => WORLD_TREE,
48 => BOOK_OF_CHANGES,
49 => PROTECTION_RUNE,
50 => SHAPESHIFTER,
51 => MIRAGE,
52 => DOPPELGANGER,
_ => panic!("Invalid card index: {}", n),
}
}
}