# bridge - generate random bridge hands

BEGIN { split(permute(52,52), deck)           # generate a random deck
        sort(1,13); sort(14,26); sort(27,39); sort(40,52) # sort hands
        prhands()                    # format and print the four hands
}

function permute(k, n,    i, p, r) {   # generate a random permutation
    srand(1);                 # leave out "1" for more randomness
    p = " "                   # of k integers between 1 and n
    for (i = n-k+1; i <= n; i++)
        if (p ~ " " (r = int(i*rand())+1) " " )
            sub(" " r " ", " " r " " i " ", p)    # put i after r in p
        else p = " " r p                     # put r at beginning of p
    return p
}

function sort(left,right,    i,j,t) { # sort hand in deck[left..right]
    for (i = left+1; i <= right; i++)
        for (j = i; j > left && deck[j-1] < deck[j]; j--) {
            t = deck[j-1]; deck[j-1] = deck[j]; deck[j] = t
        }
}

function prhands() {                            # print the four hands
    b = sprintf("%20s", " "); b40 = sprintf("%40s", " ")
    card = 1                                  # global index into deck
    suits(13); print b "   NORTH"
    print b spds; print b hrts; print b dnds; print b clbs
    suits(26)  # create the west hand from deck[14..26]
    ws = spds substr(b40, 1, 40 - length(spds))
    wh = hrts substr(b40, 1, 40 - length(hrts))
    wd = dnds substr(b40, 1, 40 - length(dnds))
    wc = clbs substr(b40, 1, 40 - length(clbs))
    suits(39); print "   WEST" sprintf("%36s", " ") "EAST"
    print ws spds; print wh hrts; print wd dnds; print wc clbs
    suits(52); print b "   SOUTH"
    print b spds; print b hrts; print b dnds; print b clbs
}

function suits(j) {           # collect suits of hand in deck[j-12..j]
    for (spds = "S:"; deck[card] > 39 && card <= j; card++)
        spds = spds " " fvcard(deck[card])
    for (hrts = "H:"; deck[card] > 26 && card <= j; card++)
        hrts = hrts " " fvcard(deck[card])
    for (dnds = "D:"; deck[card] > 13 && card <= j; card++)
        dnds = dnds " " fvcard(deck[card])
    for (clbs = "C:"; card <= j; card++)
        clbs = clbs " " fvcard(deck[card])
}

function fvcard(i) {                    # compute face value of card i
    if (i % 13 == 0) return "A"
    else if (i % 13 == 12) return "K"
    else if (i % 13 == 11) return "Q"
    else if (i % 13 == 10) return "J"
    else return (i % 13) + 1
}
