/// 自定义牌组构建器 — 赛前配置30张出战卡牌
pub struct DeckConfig {
name : String
character_id : String
card_ids : Array[String]
max_cards : Int
min_cards : Int
description : String
total_cost : Int
}
pub fn new_deck(name : String, character_id : String) -> DeckConfig {
{ name: name, character_id: character_id, card_ids: [], max_cards: 30, min_cards: 15, description: "", total_cost: 0 }
}
pub fn add_card_to_deck(config : DeckConfig, card_id : String) -> DeckConfig {
if config.card_ids.length() >= config.max_cards { return config }
let card = find_card_by_id(card_id)
let new_ids : Array[String] = []
let mut i = 0
while i < config.card_ids.length() { new_ids.push(config.card_ids[i]); i = i + 1 }
new_ids.push(card_id)
{ ..config, card_ids: new_ids, total_cost: config.total_cost + card.cost }
}
pub fn remove_card_from_deck(config : DeckConfig, index : Int) -> DeckConfig {
if index < 0 || index >= config.card_ids.length() { return config }
let removed_id = config.card_ids[index]
let card = find_card_by_id(removed_id)
let new_ids : Array[String] = []
let mut i = 0
while i < config.card_ids.length() {
if i != index { new_ids.push(config.card_ids[i]) }
i = i + 1
}
{ ..config, card_ids: new_ids, total_cost: config.total_cost - card.cost }
}
pub fn validate_deck(config : DeckConfig) -> String {
if config.card_ids.length() < config.min_cards {
return "Need at least " + config.min_cards.to_string() + " cards (currently " + config.card_ids.length().to_string() + ")"
}
if config.card_ids.length() > config.max_cards {
return "Max " + config.max_cards.to_string() + " cards allowed"
}
let cards = resolve_deck_cards(config)
let mut has_attack = false
let mut has_skill = false
let mut i = 0
while i < cards.length() {
if cards[i].card_type == Attack { has_attack = true }
if cards[i].card_type == Skill { has_skill = true }
i = i + 1
}
if !has_attack { return "Deck must contain at least 1 attack card" }
if !has_skill { return "Deck must contain at least 1 skill card" }
"Valid"
}
pub fn resolve_deck_cards(config : DeckConfig) -> Array[Card] {
let result : Array[Card] = []
let mut i = 0
while i < config.card_ids.length() {
let card = find_card_by_id(config.card_ids[i])
result.push(card)
i = i + 1
}
result
}
pub fn deck_average_cost(config : DeckConfig) -> Double {
if config.card_ids.length() == 0 { return 0.0 }
config.total_cost.to_double() / config.card_ids.length().to_double()
}
pub fn deck_type_distribution(config : DeckConfig) -> String {
let cards = resolve_deck_cards(config)
let mut atk = 0
let mut skl = 0
let mut abl = 0
let mut i = 0
while i < cards.length() {
match cards[i].card_type {
Attack => { atk = atk + 1 }
Skill => { skl = skl + 1 }
Ability => { abl = abl + 1 }
}
i = i + 1
}
"Attack:" + atk.to_string() + " Skill:" + skl.to_string() + " Ability:" + abl.to_string()
}
pub fn deck_cost_distribution(config : DeckConfig) -> String {
let cards = resolve_deck_cards(config)
let mut c0 = 0; let mut c1 = 0; let mut c2 = 0; let mut c3 = 0
let mut i = 0
while i < cards.length() {
match cards[i].cost {
0 => { c0 = c0 + 1 }
1 => { c1 = c1 + 1 }
2 => { c2 = c2 + 1 }
_ => { c3 = c3 + 1 }
}
i = i + 1
}
"Cost 0:" + c0.to_string() + " Cost 1:" + c1.to_string() + " Cost 2:" + c2.to_string() + " Cost 3:" + c3.to_string()
}
pub fn recommend_deck(character_id : String, archetype : String) -> DeckConfig {
let mut config = new_deck("Recommended", character_id)
let all = all_cards_with_expansion()
let mut added = 0
let mut i = 0
while i < all.length() && added < 20 {
let c = all[i]
let is_match = match character_id {
"zhong-lv" => c.id.starts_with("zl")
"xian-yin" => c.id.starts_with("xy")
_ => true
}
let is_arch = match archetype {
"fortress" => c.archetype == Fortress || c.archetype == Basic
"overload" => c.archetype == Overload || c.archetype == Basic
_ => true
}
if is_match && is_arch && c.base_damage + c.base_armor > 0 {
config = add_card_to_deck(config, c.id)
added = added + 1
}
i = i + 1
}
config = { ..config, description: "Recommended " + archetype + " deck for " + character_id }
config
}
pub fn deck_statistics(config : DeckConfig) -> String {
"Deck: " + config.name + "\n" +
"Cards: " + config.card_ids.length().to_string() + "\n" +
"Avg Cost: " + deck_average_cost(config).to_string() + "\n" +
deck_type_distribution(config) + "\n" +
deck_cost_distribution(config) + "\n" +
"Total Cost: " + config.total_cost.to_string() + "\n" +
"Status: " + validate_deck(config)
}
pub fn rename_deck(config : DeckConfig, new_name : String) -> DeckConfig {
{ ..config, name: new_name }
}
pub fn export_deck(config : DeckConfig) -> String {
let mut s = config.name + "\n"
let mut i = 0
while i < config.card_ids.length() {
s = s + config.card_ids[i] + "\n"
i = i + 1
}
s
}
pub fn import_deck(data : String, name : String, character_id : String) -> DeckConfig {
let mut config = new_deck(name, character_id)
let lines = split_by_newline(data)
let mut i = 0
while i < lines.length() {
if lines[i].length() > 0 { config = add_card_to_deck(config, lines[i]) }
i = i + 1
}
config
}
fn split_by_newline(s : String) -> Array[String] {
let result : Array[String] = []
let mut current = ""
let mut i = 0
while i < s.length() {
if s[i] == '\n' {
result.push(current)
current = ""
} else {
current = current + s[i].to_string()
}
i = i + 1
}
if current.length() > 0 { result.push(current) }
result
}
pub fn compare_decks(deck_a : DeckConfig, deck_b : DeckConfig) -> String {
let a_avg = deck_average_cost(deck_a)
let b_avg = deck_average_cost(deck_b)
let winner = if deck_a.card_ids.length() > deck_b.card_ids.length() { deck_a.name }
else if deck_b.card_ids.length() > deck_a.card_ids.length() { deck_b.name }
else if a_avg < b_avg { deck_a.name }
else { deck_b.name }
deck_a.name + ": " + deck_a.card_ids.length().to_string() + " cards (avg " + a_avg.to_string() + ")\n" +
deck_b.name + ": " + deck_b.card_ids.length().to_string() + " cards (avg " + b_avg.to_string() + ")\n" +
"Better: " + winner
}