# Bingo Card Maker Free: simulation of calls needed in word bingo with 36- and 40-word lists.
# Each card: 5 x 5 with a free space and 24 random words from the list. Requires Python 3 and NumPy.

import numpy as np, json
rng=np.random.default_rng(20260917)
GAMES=20000
I=lambda r,c:r*5+c; R=range(5)
lines=[[I(r,c) for c in R] for r in R]+[[I(r,c) for r in R] for c in R]+[[I(i,i) for i in R],[I(i,4-i) for i in R]]
pats={"line":lines,"corners":[[0,4,20,24]],"blackout":[list(range(25))]}
out={}
for N in (36,40):
    out[N]={}
    res={k:{p:[] for p in (10,25)} for k in pats}
    for g in range(GAMES):
        order=rng.permutation(N)
        pos=np.empty(N,dtype=np.int16); pos[order]=np.arange(1,N+1)
        cards=np.array([rng.choice(N,24,replace=False) for _ in range(25)])
        t=np.insert(pos[cards],12,0,axis=1)
        for k,alts in pats.items():
            best=np.min(np.stack([t[:,a].max(axis=1) for a in alts],axis=1),axis=1)
            for p in (10,25): res[k][p].append(int(best[:p].min()))
    for k in pats:
        out[N][k]={p:int(np.median(res[k][p])) for p in (10,25)}
    print(N,out[N])
json.dump({"games":GAMES,"seed":20260917,"cards":"5x5 with free space, 24 random items per card","results":out},open("word_calls.json","w"),indent=1)
