use crate::ids::CardId;
#[derive(Debug, Clone)]
pub struct AttackingBand {
pub attackers: Vec<CardId>,
pub blocked: Option<bool>,
}
impl AttackingBand {
pub fn new(card: CardId) -> Self {
Self {
attackers: vec![card],
blocked: None,
}
}
pub fn from_list(cards: Vec<CardId>) -> Self {
Self {
attackers: cards,
blocked: None,
}
}
pub fn get_attackers(&self) -> &[CardId] {
&self.attackers
}
pub fn add_attacker(&mut self, card: CardId) {
self.attackers.push(card);
}
pub fn remove_attacker(&mut self, card: CardId) {
self.attackers.retain(|&c| c != card);
}
pub fn contains(&self, card: CardId) -> bool {
self.attackers.contains(&card)
}
pub fn is_blocked(&self) -> Option<bool> {
self.blocked
}
pub fn set_blocked(&mut self, value: bool) {
self.blocked = Some(value);
}
pub fn is_empty(&self) -> bool {
self.attackers.is_empty()
}
pub fn is_valid_band(band: &[CardId], cards: &[crate::card::Card], share_damage: bool) -> bool {
if band.is_empty() {
return false;
}
if band.len() == 1 {
return true;
}
let banding_count = band
.iter()
.filter(|&&cid| {
let card = &cards[cid.index()];
card.has_keyword("Banding")
})
.count();
let needed = if share_damage { 1 } else { band.len() - 1 };
banding_count >= needed
}
pub fn can_join_band(&self, card: CardId, cards: &[crate::card::Card]) -> bool {
let mut new_band: Vec<CardId> = self.attackers.clone();
new_band.push(card);
Self::is_valid_band(&new_band, cards, false)
}
}
impl std::fmt::Display for AttackingBand {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let blocked_str = match self.blocked {
None => " ? ",
Some(true) => ">||",
Some(false) => ">>>",
};
write!(f, "{:?} {}", self.attackers, blocked_str)
}
}