class_name DeckGen ## Stapel: die vier Startdecks, Auffüllen aus der Sammlung, zufällige Stapel für Gegner. const CHEAP_IN_RANDOM := 12 # so viele im ersten Zug bezahlbare Karten hat ein zufälliger Stapel mindestens ## Zufälliger Stapel aus DECK_MIN verschiedenen Karten bis max_cost, mit genug billigen für den Anfang. static func random_deck(r: RandomNumberGenerator, max_cost: int = 99) -> Array: var cheap := Cards.all().filter(func(c): return c.cost <= Game.START_MANA) var rest := Cards.all().filter(func(c): return c.cost > Game.START_MANA and c.cost <= max_cost) Game.shuffle(cheap, r) Game.shuffle(rest, r) var out := [] for c in cheap.slice(0, CHEAP_IN_RANDOM) + rest + cheap.slice(CHEAP_IN_RANDOM): if out.size() >= Game.DECK_MIN: break out.append(c.id) return out ## Stapel eines Kampagnengegners: Kapitel 1 bis Kosten 3, Kapitel 2 bis 5, Kapitel 3 alles. static func opponent_deck(r: RandomNumberGenerator, chapter: int) -> Array: return random_deck(r, [3, 5, 99][clampi(chapter - 1, 0, 2)]) ## Startdeck für ein Element: die 25 Karten des Elements bis Angriff 4, dazu je fünf billige der ## anderen Elemente (DECK_MIN Karten). static func start_deck(element: String) -> Array: var out := [] for c in Cards.all(): if c.elements[0] == element and c.attack <= 4: out.append(c.id) for e in Cards.ELEMENTS: if e == element: continue var cheap := Cards.all().filter(func(c): return c.elements[0] == e and c.cost <= Game.START_MANA) cheap.sort_custom(func(a, b): return a.cost < b.cost if a.cost != b.cost else a.attack > b.attack) for c in cheap.slice(0, 5): out.append(c.id) return out ## Füllt deck aus pool (Karten-IDs) bis limit auf, die wertvollsten zuerst (Card.value in der ## Stufe aus levels: ID -> Stufe), bei gleichem Wert die teuersten; nichts doppelt. static func fill(deck: Array, pool: Array, limit: int, levels: Dictionary = {}) -> Array: var out := deck.duplicate() var cards := pool.filter(func(id): return not (id in out)).map(func(id): return Cards.by_id(id).leveled(int(levels.get(id, 0)))) cards.sort_custom(func(a, b): if a.value() != b.value(): return a.value() > b.value() return a.cost > b.cost if a.cost != b.cost else a.id < b.id) for c in cards: if out.size() >= limit: break out.append(c.id) return out ## Stärke eines Stapels: der mittlere Kartenwert (Card.value) in den Stufen aus levels, ## 100 für lauter Grundkarten bis 500 für lauter Ultimate Rare; leer: 0. static func strength(deck: Array, levels: Dictionary) -> int: if deck.is_empty(): return 0 var sum := 0 for id in deck: sum += Cards.by_id(id).leveled(int(levels.get(id, 0))).value() return roundi(float(sum) / deck.size()) static func random_opponent(life: int = Game.START_LIFE) -> Game.Player: return Game.Player.new("Gegner", false, life)