use crate::card::Card;
pub fn evaluate_creature(card: &Card) -> i32 {
evaluate_creature_full(card, true, true)
}
pub fn evaluate_creature_full(card: &Card, consider_pt: bool, consider_cmc: bool) -> i32 {
let mut value: i32 = 80;
if !card.is_token {
value += 20;
}
let power = if card.has_keyword("Prevent all combat damage that would be dealt by CARDNAME.")
|| card.has_keyword("Prevent all damage that would be dealt by CARDNAME.")
|| card
.has_keyword("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")
|| card.has_keyword("Prevent all damage that would be dealt to and dealt by CARDNAME.")
{
0
} else if card.toughness_assigns_damage() {
card.toughness()
} else {
card.power()
};
let toughness = card.toughness();
if consider_pt {
value += power * 15;
value += toughness * 10;
if card.has_keyword("Daybound") && card.is_double_faced() {
value += power * 10;
}
}
if consider_cmc {
value += card.mana_value() * 5;
}
if card.has_flying() {
value += power * 10;
}
if card.has_keyword("Horsemanship") {
value += power * 10;
}
if card.has_keyword("CARDNAME can't be blocked.") {
value += power * 10;
} else {
if card.has_keyword("Fear") {
value += power * 6;
}
if card.has_keyword("Intimidate") {
value += power * 6;
}
if card.has_keyword("Menace") {
value += power * 4;
}
if card.has_keyword("Skulk") {
value += power * 3;
}
}
if power > 0 {
if card.has_keyword("Double Strike") {
value += 10 + (power * 15);
} else if card.has_first_strike() {
value += 10 + (power * 5);
}
if card.has_deathtouch() {
value += 25;
}
if card.has_lifelink() {
value += power * 10;
}
if power > 1 && card.has_keyword("Trample") {
value += (power - 1) * 5;
}
if card.has_keyword("Vigilance") {
value += (power * 5) + (toughness * 5);
}
if card.has_keyword("Infect") {
value += power * 15;
} else if card.has_keyword("Wither") {
value += power * 10;
}
value += keyword_magnitude(card, "Toxic") * 5;
value += keyword_magnitude(card, "Afflict") * 5;
value += keyword_magnitude(card, "Rampage");
}
value += keyword_magnitude(card, "Annihilator") * 50;
value += keyword_magnitude(card, "Absorb") * 11;
if card.has_keyword("Outlast") {
value += 10;
}
value += keyword_magnitude(card, "Bushido") * 16;
value += keyword_count(card, "Flanking") * 15;
value += keyword_count(card, "Exalted") * 15;
value += keyword_count(card, "Melee") * 18;
value += keyword_count(card, "Prowess") * 5;
if card.has_keyword("Reach") && !card.has_flying() {
value += 5;
}
if card.has_indestructible() {
value += 70;
}
if card.has_keyword("Prevent all damage that would be dealt to CARDNAME.") {
value += 60;
} else if card.has_keyword("Prevent all combat damage that would be dealt to CARDNAME.") {
value += 50;
}
if card.has_hexproof() {
value += 35;
} else if card.has_keyword("Shroud") {
value += 30;
} else if card.has_keyword("Ward") {
value += 10;
}
if card.has_keyword("Protection") {
value += 20;
}
if card.has_keyword("Undying") || card.has_keyword("Persist") {
value += 30;
}
if card.has_defender() || card.has_keyword("CARDNAME can't attack.") {
value -= (power * 9) + 40;
}
if card.has_keyword("CARDNAME can't attack or block.") {
value = 50 + (card.mana_value() * 5); } else if card.has_keyword("CARDNAME can't block.") {
value -= 10;
}
if card.tapped && !card.can_untap() {
value = 50 + (card.mana_value() * 5); }
if !card.tapped {
value += 1; }
if card.activated_abilities.iter().any(|ab| ab.is_mana_ability) {
value += 10;
}
if card.has_keyword("Phasing") {
value -= 20.max(value / 2);
}
if card
.svars
.get("EndOfTurnLeavePlay")
.map(|v| v == "True")
.unwrap_or(false)
{
value -= 50;
}
value
}
pub fn is_useless_creature(card: &Card) -> bool {
if card.has_defender() {
return true;
}
if card.has_keyword("CARDNAME can't attack.") {
return true;
}
if card.has_keyword("CARDNAME can't attack or block.") {
return true;
}
if card.tapped && !card.can_untap() {
return true;
}
false
}
fn keyword_magnitude(card: &Card, kw: &str) -> i32 {
card.get_keyword_cost(kw)
.and_then(|s| s.parse::<i32>().ok())
.unwrap_or(0)
}
fn keyword_count(card: &Card, kw: &str) -> i32 {
card.keywords
.as_string_list()
.iter()
.filter(|k| k.starts_with(kw))
.count() as i32
}