Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm writing a playing card simulator of sorts, and everything works fine, but some Modules use a disgusting amount of variables. For Example:

randomHand[x_] := 
Module[{hand, kings, cards, suits, value, suitsK, valueK, cardList},
hand = PadLeft[IntegerDigits[RandomInteger[{1, 52}, x], 13]];
kings = Cases[hand, {___, 0}, 2];
cards = DeleteCases[hand, {___, 0}, 2];
suits = First /@ cards;
value = Last /@ cards;
suitsK = First /@ kings;
valueK = ReplaceAll[Last /@ kings, 0 -> "King"];
suits = suits /. {0 -> "Hearts", 1 -> "Diamonds", 2 -> "Clubs", 
 3 -> "Spades"};
suitsK = suitsK /. {1 -> "Hearts", 2 -> "Diamonds", 3 -> "Clubs", 
 4 -> "Spades"};
value = value /. {11 -> "Jack", 12 -> "Queen"};
cardList = Partition[Riffle[value, suits], 2];
Map[ToString[cardList[[#]][[1]]] <> " of " <> cardList[[#]][[2]] &, Range[Length[cardList]]]]

My Mathematica knowledge is not as fluent as I'd like it to be, so I'm wondering if it is bad to use so many variables, and if it is, how would I go about cleaning up the above excerpt?

share|improve this question
    
Not a direct answer to your question, but in this answer, I have a random hand dealer that you might be interested in. –  rm -rf Mar 27 at 2:21

3 Answers 3

up vote 5 down vote accepted
suits = {" of Hearts", " of Diamonds", " of Clubs", " of Spades"};
deck = Join @@ Outer[StringJoin, Join[ToString /@ Range[2, 10], 
                  {"Jack", "Queen", "King", "Ace"}], suits];
RandomSample[deck, 5]

(* {"King of Diamonds", "2 of Spades", "6 of Hearts", "5 of Clubs", "8 of Diamonds"} *)
share|improve this answer
    
@smith: Thanks for accept - please note - minor boo-boo, changed RandomChoice to RandomSample: the former is with replacement, the latter is without (which I'm sure is what you want.) –  rasher Mar 27 at 3:28
randomHand[x_] := Module[{cards, suits, value},
  cards = DeleteCases[#, {___, 0}, 2] &@
       PadLeft[IntegerDigits[RandomInteger[{1, 52}, x], 13]];
  suits = First /@ cards /. {0 -> "Hearts", 1 -> "Diamonds", 2 -> "Clubs", 3 -> "Spades"};
  value = Last /@ cards /. {11 -> "Jack", 12 -> "Queen"};
  StringJoin @@ Insert[ToString /@ #, " of ", 2] & /@ 
  Transpose[{value, suits}]
  ]
randomHand[5]
share|improve this answer
    
Yes, but this fails to account for the kings. In base 13, kings are multiples of 10 (10,20,30,40). So 1 is the leading digit for diamonds until 20, which is the king of diamonds. From my test, this is also slower than the original. –  Smith W. Mar 27 at 3:00
    
You code is not include kings.I just rewrite your code for reduce variables.And you need to randomHand[10^5] or more? –  Chenminqi Mar 27 at 3:05

Nothing special here, except it uses your idea of encoding the card using a base-13 representation:

card[n_Integer /; 1 <= n <= 52] := 
 With[{suits = {"Hearts", "Diamonds", "Clubs", "Spades"}, 
   values = Join[{"Ace"},  ToString /@ Range[2, 10], {"Jack", "Queen", "King"}]}, 
  IntegerDigits[n - 1, 13, 2] /. {s_, v_} :> 
    values[[v + 1]] <> " of " <> suits[[s + 1]]]

I don't play cards, so I don't know if there's a natural order to the values(? if that's what they're called) but I've arranged them in the order Ace, 2, 3 ... 10, Jack, Queen, King.

card[1] is "Ace of Hearts" and card[52] is "King of Spades"

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.