# 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(); 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
}
Pages: 1 2 3
In Python.
import random from itertools import groupby from operator import itemgetter VALUES = list("23456789TJQKA") VALUES[8] = "10" def random_hand(): cards = list(range(52)) random.shuffle(cards) return [sorted(cards[i*13:i*13+13], reverse=True) for i in range(4)] def nr_to_card(n): suit, value = divmod(n, 13) return "CDHS"[suit], VALUES[value] def hand(side): cards = [nr_to_card(c) for c in side] cc = groupby(cards, key=itemgetter(0)) D = {k:"{:s}: {:s}".format(k, " ".join(v for s, v in g)) for k, g in cc} return [D[k] if k in D else k + ":" for k in "SHDC"] def print_bridge(hands): output = [[" "] * 80 for _ in range(15)] pos = [(0, 20), (5, 0), (5, 40), (10, 20)] seats = ["NORTH", "WEST", "EAST", "SOUTH"] for (row, col), seat, hand_ in zip(pos, seats, hands): output[row][col:col+len(seat)] = seat for i, hi in enumerate(hand(hand_)): output[row+i+1][col:col+len(hi)] = hi for o in output: print ("".join(o)) print_bridge(random_hand())Good to see you recovered!
Hereby my Python solution..
import random suits = ["S", "H", "D", "C"] values = ["2","3","4","5","6","7","8","9","10","J","Q","K","A"] # returns tuples of (suit, value) def deck(shuffle=True): def card_number_to_card_tuple(n): suit, value = divmod(n, 13) return suits[suit], values[value] all_cards = range(52) if shuffle: random.shuffle(all_cards) return map(card_number_to_card_tuple, all_cards) # returns list of 4 hands, with each hand as a dict with k=suit , v=list of values for suit k def four_hands(deck): hands = [] for hand in [deck[i*13:i*13+13] for i in range(4)]: d = dict(zip(suits, [[],[],[],[]])) for suit, value in hand: d.setdefault(suit, []).append(value) hands.append(d) return hands # prints output. Spent most time in that python format mini language.. def print_formatted(four_hands): def hand_to_string(hand): return [suit + ': ' + " ".join(hand[suit]) for suit in suits] print ' '*20 + 'NORTH' for north in hand_to_string(four_hands[0]): print ' '*20 + north print '{:<40}{:}'.format('WEST', 'EAST') for west, east in zip(hand_to_string(four_hands[1]), hand_to_string(four_hands[2])): print '{:<40}{:}'.format(west, east) for south in hand_to_string(four_hands[3]): print ' '*20 + south print_formatted(four_hands(deck()))Scala:
import scala.util.Random
type Card = Tuple2[String, String]
val color: Seq[String] = List(“S”, “H”, “D”, “C”)
val numbers: Seq[String] = (2 to 10 map { _.toString }) ++ List(“J”, “Q”, “K”, “A”)
def numberSorter(a: String, b: String): Boolean = numbers.indexOf(a) > numbers.indexOf(b)
val cards: Seq[Card] = Random.shuffle(for (c <- color; n List(filter(x, “S”), filter(x, “H”), filter(x, “D”), filter(x, “C”)))
val blockLines = blocks.map(x => (List(x._1) ++ x._2).map(x => x + ” ” * (20 – x.length())))
val north = for (i <- 0 to 4) yield " " * 20 + blockLines(0)(i) + " " * 20
val west_east = for (i <- 0 to 4) yield blockLines(1)(i) + " " * 20 + blockLines(2)(i)
val south = for (i <- 0 to 4) yield " " * 20 + blockLines(3)(i) + " " * 20
println((north ++ west_east ++ south).mkString("\r\n"))
@Paul, @Rutger: could you please tell me how do you insert your code in such a beauty way? Which website do you use?
@Andras.I am using method Third as mentioned in the “Howto: Posting Source Code”. You have to know the mnemonic for Scala (I guess it is scala). Further the tag is usefull if you want to use a link in your post. I hope this helps.
@Andras, the “a href” tag messed up part of my reply. You only have to google for this tag and see how it is used.
@Paul Thanks it works fine!
A Haskell version.
import Data.Function (on) import Data.List (groupBy, intercalate, sortOn) import Data.List.Split (chunksOf) import Data.Maybe (fromMaybe) import Data.Ord (Down(..)) import System.Random import System.Random.Shuffle (shuffle') import Control.Monad (liftM) shuffle :: (RandomGen r) => [a] -> r -> [a] shuffle xs = shuffle' xs (length xs) -- A standard deck of 52 cards, where each card is a pair consisting of a suit -- and a rank. deck :: [(Int, Int)] deck = [(s, r) | s <- [0..3], r <- [0..12]] -- Deal hands of 13 cards. Each hand consists of ordered lists of ranks grouped -- by suit. deal :: [(Int, Int)] -> [[(Int, [Int])]] deal = map (map suitify . groupBy ((==) `on` fst) . sortOn Down) . chunksOf 13 where suitify (rss@((r, _) : _)) = (r, map snd rss) showSuit :: Int -> String showSuit = (["S", "H", "D", "C"] !!) showRank :: Int -> String showRank = (ranks !!) where ranks = [ "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"] -- Each element of the result is one suit letter followed by the card ranks. showHand :: [(Int, [Int])] -> [String] showHand cs = map (\s -> showSuit s ++ ": " ++ showRanks (ranks s)) [0..3] where ranks s = fromMaybe [] $ lookup s cs showRanks = unwords . map showRank printHand :: [String] -> IO () printHand = putStrLn . intercalate "\n" -- Pad all the strings to the length of the longest. padR :: [String] -> [String] padR xs = let maxLen = maximum $ map length xs in map (padTo maxLen) xs where padTo mx s = s ++ replicate (mx - length s) ' ' -- Prepend all the strings with spaces. padL :: Int -> [String] -> [String] padL n = map (replicate n ' ' ++) -- Append corresponding elements of the lists. followedBy :: [[a]] -> [[a]] -> [[a]] followedBy = zipWith (++) main :: IO () main = do hands <- liftM (map showHand . deal . shuffle deck) getStdGen let [n, s, e, w] = zipWith (:) ["NORTH", "SOUTH", "EAST", "WEST"] hands printHand $ padL 20 n printHand $ padR w `followedBy` padL 30 e printHand $ padL 20 s$ ./bridge NORTH S: K Q 9 5 H: Q 10 D: K 9 8 3 C: 6 5 4 WEST EAST S: A 10 8 7 S: J 6 3 H: K 8 2 H: J 9 7 6 3 D: 6 4 D: Q J 7 C: 9 8 3 2 C: A Q SOUTH S: 4 2 H: A 5 4 D: A 10 5 2 C: K J 10 7[…] Bridge hands problem in C++ […]
[…] bridge hands problem on programming praxis in Common […]