8000打点の探索
打点の探索のうまい方法を考えたいあんも.icon
素朴に考えるならパンプ×頭数+素点
要求値による枝刈りができればいい
部分パンプは考えないでおく
打点
権能: 300パンプ
グレートフライ: 1400: 500パンプ
フォニクス: 3000
クローゼア: 2200
エルダム: 1600
スエン: 1300
メガラ: 500
権能グレートフライ
800 * 3 +(1400 + 3000 + 1200)
深さ優先探索
code:jl
abstract type Card end
# モンスターカードの定義
struct Monster <: Card
name::String
base_atk::Int # 素点
global_pump::Int # 全体パンプ値
max_copies::Int # 盤面に並べられる最大枚数
end
# モンスター以外のカード
struct SpellTrap <: Card
name::String
global_pump::Int # 全体パンプ値
max_copies::Int
end
モンスター最大数の扱いがまずいあんも.icon
EXゾーン
code:jl
function calculate_damage(monsters::Vector{Monster}, spells::Vector{SpellTrap})
head_count = length(monsters)
# 素点の合計
base_atk_sum = isempty(monsters) ? 0 : sum(m.base_atk for m in monsters)
# 全体パンプの合計(モンスター効果 + 魔法罠効果)
monster_pump = isempty(monsters) ? 0 : sum(m.global_pump for m in monsters)
spell_pump = isempty(spells) ? 0 : sum(s.global_pump for s in spells)
total_pump = monster_pump + spell_pump
# 素点 + (全体パンプ点数 × 頭数)
return base_atk_sum + (total_pump * head_count)
end
function find_lethal_combinations(card_pool::Vector{Card}; target=8000, max_monsters=5, max_spells=5)
results = []
# 内部関数:深さ優先探索 (DFS)
function dfs(index::Int, current_monsters::Vector{Monster}, current_spells::Vector{SpellTrap})
# 現在の盤面打点を計算
damage = calculate_damage(current_monsters, current_spells)
# 8000打点を超えていて、かつ盤面にモンスターが1体以上いるなら結果を保存
if damage >= target && !isempty(current_monsters)
# 実際の出力が見やすいように、カード名のリストを保存する
monster_names = m.name for m in current_monsters
spell_names = s.name for s in current_spells
push!(results, (damage, monster_names, spell_names))
end
# すべてのカードをチェックし終わったら終了
if index > length(card_pool)
return
end
card = card_poolindex
# このカードを盤面に「何枚出すか」を試す(0枚~最大枚数まで)
if card isa Monster
# 盤面の空き枠か、カード自体の制限のどちらか小さい方が上限
max_use = min(card.max_copies, max_monsters - length(current_monsters))
for count in 0:max_use
new_monsters = copy(current_monsters)
for _ in 1:count
push!(new_monsters, card)
end
# 次のカードへ進む
dfs(index + 1, new_monsters, current_spells)
end
elseif card isa SpellTrap
max_use = min(card.max_copies, max_spells - length(current_spells))
for count in 0:max_use
new_spells = copy(current_spells)
for _ in 1:count
push!(new_spells, card)
end
dfs(index + 1, current_monsters, new_spells)
end
end
end
# 探索の開始(1番目のカードから、盤面が空の状態でスタート)
dfs(1, Monster[], SpellTrap[])
# 重複を省いて打点順にソートして返す
unique_results = unique(results)
sort!(unique_results, by = x -> x1, rev=false)
return unique_results
end
権能: 300パンプ
グレートフライ: 1400: 500パンプ
フォニクス: 3000
クローゼア: 2200
エルダム: 1600
スエン: 1300
メガラ: 500
code:jl
pool = Card[
Monster("グレートフライ", 1400, 500, 1),
Monster("フォニクス", 3000, 0, 1),
Monster("クローゼア", 2200, 0, 1),
Monster("エルダム", 1600, 0, 1),
Monster("スエン", 1300, 0, 1),
Monster("メガラ", 500, 0, 1),
# SpellTrap("権能", 300, 1)
]
lethal_combos = find_lethal_combinations(pool, target=8000)
# 結果の表示
println("=== 8000打点以上の組み合わせ ===")
for combo in lethal_combos
damage, m_names, s_names = combo
println("打点: $damage")
println(" モンスター: ", join(m_names, ", "))
println(" 魔法罠 : ", isempty(s_names) ? "なし" : join(s_names, ", "))
println("-" ^ 30)
end