""" Genereer willekeurige spellen, bereken dubbeldummy resultaten en schrijf een CSV met per hand: HCP, aantal A/H/V/B/10 en de verdeling. Gebruik: python3 gen_deals.py [nt|full] 'nt' -> alleen SA (snel, ~20 spellen/sec) 'full' -> alle 5 speelsoorten (~4 spellen/sec) """ import csv import random import sys import time from endplay.dds import calc_all_tables from endplay.types import Deal, Denom, Player RANKS = "AKQJT98765432" SUITS = "SHDC" HCP_VAL = {"A": 4, "K": 3, "Q": 2, "J": 1} SEATS = ("N", "E", "S", "W") STRAINS = ("C", "D", "H", "S", "N") def random_deal(rng): deck = [r + s for s in SUITS for r in RANKS] rng.shuffle(deck) return [deck[i * 13 : (i + 1) * 13] for i in range(4)] def pbn(hands): parts = [] for h in hands: suits = [] for s in SUITS: cards = sorted((c[0] for c in h if c[1] == s), key=RANKS.index) suits.append("".join(cards)) parts.append(".".join(suits)) return "N:" + " ".join(parts) def hand_stats(hand): ranks = [c[0] for c in hand] lengths = [sum(1 for c in hand if c[1] == s) for s in SUITS] return { "hcp": sum(HCP_VAL.get(r, 0) for r in ranks), "a": ranks.count("A"), "k": ranks.count("K"), "q": ranks.count("Q"), "j": ranks.count("J"), "t": ranks.count("T"), "sp": lengths[0], "he": lengths[1], "ru": lengths[2], "kl": lengths[3], } def main(): n = int(sys.argv[1]) out = sys.argv[2] seed = int(sys.argv[3]) mode = sys.argv[4] if len(sys.argv) > 4 else "nt" exclude = ( [Denom.spades, Denom.hearts, Denom.diamonds, Denom.clubs] if mode == "nt" else [] ) strains = ("N",) if mode == "nt" else STRAINS denom_of = { "C": Denom.clubs, "D": Denom.diamonds, "H": Denom.hearts, "S": Denom.spades, "N": Denom.nt, } player_of = {"N": Player.north, "E": Player.east, "S": Player.south, "W": Player.west} rng = random.Random(seed) fields = ["id"] for seat in SEATS: fields += [f"{seat}_{k}" for k in ("hcp", "a", "k", "q", "j", "t", "sp", "he", "ru", "kl")] for seat in SEATS: for st in strains: fields.append(f"tr_{seat}{st}") t0 = time.time() chunk = 200 if mode == "nt" else 32 with open(out, "w", newline="") as fh: w = csv.DictWriter(fh, fieldnames=fields) w.writeheader() done = 0 while done < n: m = min(chunk, n - done) raw = [random_deal(rng) for _ in range(m)] deals = [Deal(pbn(h)) for h in raw] tables = calc_all_tables(deals, exclude=exclude) for i, (hands, tab) in enumerate(zip(raw, tables)): row = {"id": done + i} for seat, hand in zip(SEATS, hands): for k, v in hand_stats(hand).items(): row[f"{seat}_{k}"] = v for seat in SEATS: for st in strains: row[f"tr_{seat}{st}"] = tab[denom_of[st], player_of[seat]] w.writerow(row) done += m fh.flush() el = time.time() - t0 print(f"{done}/{n} {el:.0f}s ({done/el:.1f}/s)", flush=True) if __name__ == "__main__": main()