use crate::funky::types::buffoon_card::BuffoonCard;
use crate::preludes::funky::{BCardType, MPip};
pub struct Planet {}
impl Planet {
pub const DECK_SIZE: usize = 9;
pub const DECK: [BuffoonCard; Self::DECK_SIZE] = [
card::PLUTO,
card::MERCURY,
card::URANUS,
card::VENUS,
card::SATURN,
card::JUPITER,
card::EARTH,
card::MARS,
card::NEPTUNE,
];
#[must_use]
pub fn same_planet(original: BuffoonCard, add: BuffoonCard) -> bool {
if original.card_type != BCardType::Planet || add.card_type != BCardType::Planet {
return false;
}
if let MPip::ChipsMultPlusOnHand(_, _, hand_type) = original.enhancement {
if let MPip::ChipsMultPlusOnHand(_, _, hand_type2) = add.enhancement {
hand_type == hand_type2
} else {
false
}
} else {
false
}
}
#[must_use]
pub fn add_planets(original: BuffoonCard, add: BuffoonCard) -> BuffoonCard {
if Self::same_planet(original, add) {
if let MPip::ChipsMultPlusOnHand(chips1, mult1, hand_type) = original.enhancement {
if let MPip::ChipsMultPlusOnHand(chips2, mult2, _) = add.enhancement {
let chips = chips1 + chips2;
let mult = mult1 + mult2;
let mut new_card = original;
new_card.enhancement = MPip::ChipsMultPlusOnHand(chips, mult, hand_type);
new_card
} else {
original
}
} else {
original
}
} else {
original
}
}
}
pub mod card {
use crate::funky::types::buffoon_card::{BCardType, BuffoonCard};
use crate::funky::types::edition::Edition;
use crate::funky::types::hands::HandType;
use crate::funky::types::mpip::MPip;
use crate::prelude::{Pip, PipType};
pub const PLANET_SUIT: Pip = Pip {
pip_type: PipType::Special,
weight: 1, index: 'P', symbol: '✦', value: 0, };
pub const PLUTO: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 1,
index: 'P',
symbol: '♇',
value: 1,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(10, 1, HandType::HighCard), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const MERCURY: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 2,
index: 'M',
symbol: '☿',
value: 2,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(15, 1, HandType::Pair), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const URANUS: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 3,
index: 'U',
symbol: '♅',
value: 3,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(20, 1, HandType::TwoPair), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const VENUS: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 4,
index: 'V',
symbol: '♀',
value: 4,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(20, 2, HandType::ThreeOfAKind), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const SATURN: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 5,
index: 'S',
symbol: '♄',
value: 5,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(30, 4, HandType::Straight), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const JUPITER: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 6, index: 'J',
symbol: '♃',
value: 6,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(35, 4, HandType::Flush), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const EARTH: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 7,
index: 'E',
symbol: '♁',
value: 7,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(40, 4, HandType::FullHouse), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const MARS: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 8, index: 'A', symbol: '♂',
value: 8,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(60, 7, HandType::FourOfAKind), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const NEPTUNE: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 9,
index: 'N',
symbol: '♆',
value: 9,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(40, 4, HandType::StraightFlush), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const PLANET_X: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 10, index: '❌', symbol: '❌',
value: 10,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(35, 3, HandType::FiveOfAKind), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const CERES: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 11, index: '⚳', symbol: '⚳',
value: 11,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(40, 4, HandType::FlushFive), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
pub const ERIS: BuffoonCard = BuffoonCard {
suit: PLANET_SUIT,
rank: Pip {
pip_type: PipType::Special,
weight: 12, index: 'ς',
symbol: 'ς', value: 12,
},
card_type: BCardType::Planet,
enhancement: MPip::ChipsMultPlusOnHand(50, 3, HandType::FlushFive), resell_value: 1,
edition: Edition::None,
debuffed: false,
};
}
#[cfg(test)]
#[allow(non_snake_case)]
mod funky__decks__planet_tests {
use super::*;
use crate::funky::types::hands::HandType;
use std::collections::HashSet;
const BASE_HANDS: [HandType; 9] = [
HandType::HighCard,
HandType::Pair,
HandType::TwoPair,
HandType::ThreeOfAKind,
HandType::Straight,
HandType::Flush,
HandType::FullHouse,
HandType::FourOfAKind,
HandType::StraightFlush,
];
fn hand_of(card: BuffoonCard) -> HandType {
match card.enhancement {
MPip::ChipsMultPlusOnHand(_, _, hand) => hand,
other => panic!("{card} carries {other} rather than ChipsMultPlusOnHand"),
}
}
#[test]
fn deck__size_matches_declaration() {
assert_eq!(Planet::DECK.len(), Planet::DECK_SIZE);
}
#[test]
fn deck__all_cards_are_planets() {
for card in Planet::DECK {
assert_eq!(
card.card_type,
BCardType::Planet,
"{card} in DECK is not a Planet"
);
}
}
#[test]
fn deck__every_planet_carries_a_chips_mult_plus_on_hand_effect() {
for card in Planet::DECK {
assert!(
matches!(card.enhancement, MPip::ChipsMultPlusOnHand(..)),
"{card} does not level a poker hand"
);
}
}
#[test]
fn deck__each_planet_targets_a_distinct_hand_type() {
let hands: HashSet<_> = Planet::DECK.iter().map(|c| hand_of(*c)).collect();
assert_eq!(
hands.len(),
Planet::DECK_SIZE,
"two Planets level the same hand"
);
}
#[test]
fn deck__covers_every_base_poker_hand() {
let hands: HashSet<_> = Planet::DECK.iter().map(|c| hand_of(*c)).collect();
for hand in BASE_HANDS {
assert!(
hands.contains(&hand),
"no Planet levels {hand:?} — the base deck is missing one"
);
}
}
#[test]
fn deck__resell_value_is_one() {
for card in Planet::DECK {
assert_eq!(card.resell_value, 1, "{card} should resell for $1");
}
}
#[test]
fn same_planet__is_true_only_for_the_same_hand_type() {
assert!(Planet::same_planet(card::PLUTO, card::PLUTO));
assert!(!Planet::same_planet(card::PLUTO, card::MERCURY));
}
#[test]
fn same_planet__is_false_across_card_types() {
let not_a_planet = crate::funky::decks::tarot::card::EMPRESS;
assert!(!Planet::same_planet(card::PLUTO, not_a_planet));
}
#[test]
fn add_planets__sums_chips_and_mult_of_matching_planets() {
let doubled = Planet::add_planets(card::PLUTO, card::PLUTO);
let MPip::ChipsMultPlusOnHand(chips, mult, hand) = doubled.enhancement else {
panic!("expected a leveled Pluto");
};
assert_eq!(chips, 20, "two Plutos should stack to +20 chips");
assert_eq!(mult, 2, "two Plutos should stack to +2 mult");
assert_eq!(hand, HandType::HighCard);
}
#[test]
fn add_planets__leaves_a_mismatched_planet_untouched() {
let unchanged = Planet::add_planets(card::PLUTO, card::MERCURY);
assert_eq!(unchanged.enhancement, card::PLUTO.enhancement);
}
}