class CwCardUtils::SynergyProbability

def prob_three_card_combo(names, draws)

Exact for 3-card combos
def prob_three_card_combo(names, draws)
  draws_clamped = clamp_draws(draws)
  copies_a = copies_by_name[names[0]]
  copies_b = copies_by_name[names[1]]
  copies_c = copies_by_name[names[2]]
  total = hypergeometric(@deck_size, draws_clamped).to_f
  miss_a = hypergeometric(@deck_size - copies_a, draws_clamped) / total
  miss_b = hypergeometric(@deck_size - copies_b, draws_clamped) / total
  miss_c = hypergeometric(@deck_size - copies_c, draws_clamped) / total
  miss_ab = hypergeometric(@deck_size - (copies_a + copies_b), draws_clamped) / total
  miss_ac = hypergeometric(@deck_size - (copies_a + copies_c), draws_clamped) / total
  miss_bc = hypergeometric(@deck_size - (copies_b + copies_c), draws_clamped) / total
  miss_abc = hypergeometric(@deck_size - (copies_a + copies_b + copies_c), draws_clamped) / total
  # Inclusion–exclusion for 3 sets
  prob = 1 - (miss_a + miss_b + miss_c) +
    (miss_ab + miss_ac + miss_bc) -
    miss_abc
  prob.clamp(0.0, 1.0)
end