# switch string/commands based on “random” values to produce random cards

Update

Or is there a way to generate random number between 1 and 52 using lcg package, then associate it to one of the 52 cards from the pst-poker package. Which might be easier to achieve?

OP

Basically, I want to write something simple for generating random poker cards. It looks like I need expl3,xparse and lcg (random numbers). But I am not sure how to put them together.

\documentclass[a4paper,12pt]{article}
\usepackage[pdf]{pstricks}                %% added for pdflatex, use pdflatex -shell-escape $(NAME_PART).tex \usepackage[crop=off]{auto-pst-pdf} %% added for pdflatex, use pdflatex -shell-escape$(NAME_PART).tex
\usepackage{pst-poker}

%%%%%%%%%%% random %%%%%%%%%%%
\usepackage{xstring}
\usepackage{expl3}
\usepackage{lcg} % random number generator
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
\begin{postscript}

\Ks\tenh\sevd

\end{postscript}
\end{document}


This would produce some cards nicely for my purpose using pdflatex. Now I want to do something like a random card drawing.

The "random" process would be something like this

\reinitrand[first=1, last=100, counter=rand]
\rand\arabic{rand}
\reinitrand[first=1, last=13, counter=rand2]
\rand\arabic{rand2}


Then to "pick" the card suit, I would do rand Mod 4, so the values would be 0,1,2,3, and then I can assign the suits(strings) s/c/h/d, for spade,club,heart,dimond.

For rand2, it would be cards from A to K as defined in the package pst-poker-doc.

Lastly, putting the two strings togeher to generate keys like \Ks\tenh\sevd\Kc ect ...

I am sure there is an easier way to do this, but that's as far as I can go...

• What you want is a random sort. See tex.stackexchange.com/questions/432272/… for example. – John Kormylo Jan 13 at 1:41
• @JohnKormylo I don't really want a shuffle of the cards, I kind of just want to draw one/two or some of the cards ... – CasperYC Jan 13 at 1:45
• If you don't want to draw two aces of spades, you need a sort,. Or at least a partal sort. – John Kormylo Jan 13 at 1:47

Here's an implementation with expl3.

A “new” random integer between 13 and 64 is generated and converted to base 13, so we can use the first digit for the suit (from 1 to 4 are clubs, diamonds, hearts and spades) and the second digit for the rank (0 is ace, 1 is two and so on, a is Jack, b is Queen and c is King).

A generated integer is checked to not be among the previously generated ones (if it is a new random integer is cast and the check is performed again). Finally, the card is generated based on the two digits.

% arara: latex
% arara: dvips
% arara: ps2pdf

\documentclass{article}
\usepackage{pst-poker}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\generatecards}{m}
{% #1 = number of cards to generate
\int_compare:nTF { #1 > 52 }
{% don't generate more than 52 cards
\casperyc_cards_generate:n { 52 }
}
{
\casperyc_cards_generate:n { #1 }
}
}

\seq_new:N \l__casperyc_cards_used_seq

\cs_new_protected:Nn \casperyc_cards_generate:n
{
\seq_clear:N \l__casperyc_cards_used_seq
\prg_replicate:nn { #1 } { \casperyc_cards_randomcard: }
}

\cs_new_protected:Nn \casperyc_cards_randomcard:
{
\__casperyc_cards_format:e { \int_to_base:nn { \int_rand:nn { 13 } { 64 } } { 13 } }
}

\cs_new_protected:Nn \__casperyc_cards_format:n
{
\seq_if_in:NnTF \l__casperyc_cards_used_seq { #1 }
{% already used card, redo
\casperyc_cards_randomcard:
}
{% new card
% add to the list of used cards
\seq_put_right:Nn \l__casperyc_cards_used_seq { #1 }
% format it
\__casperyc_cards_format:nn #1
}
}
\cs_generate_variant:Nn \__casperyc_cards_format:n { e }

\cs_new_protected:Nn \__casperyc_cards_format:nn
{
\use:c
{
\__casperyc_cards_rank:n { #2 }
\__casperyc_cards_seed:n { #1 }
}~
}

\cs_new:Nn \__casperyc_cards_seed:n
{
\str_case:nn { #1 }
{
{1}{c}
{2}{d}
{3}{h}
{4}{s}
}
}
\cs_new:Nn \__casperyc_cards_rank:n
{
\str_case:nn { #1 }
{
{0}{A}
{1}{two}
{2}{tre}
{3}{four}
{4}{five}
{5}{six}
{6}{sev}
{7}{eig}
{8}{nine}
{9}{ten}
{a}{J}
{b}{Q}
{c}{K}
}
}

\ExplSyntaxOff

\begin{document}

\raggedright

\generatecards{20}

\bigskip

\generatecards{52}

\bigskip

\generatecards{200}

\end{document}


• Worked perfectly using latex. Is there a way to switch this to pdflatex so I can put this to my original file and compile with the pdflatex -shell-escape option? I have tried the normal \usepackage[crop=off]{auto-pst-pdf} option, but it didn't seem to be working. Thanks again. – CasperYC Jan 13 at 11:54
• @CasperYC No idea, but I suspect an unrelated issue deeper than just this problem. The -pics PDF file is correctly generated, as far as I can see. – egreg Jan 13 at 12:26
• I will look for more help on SE. Thanks anyway. BTW, is the expl3 still experimental? I read it somewhere last night, it was designed for, so that tex is more programmerable? I code in a lot of mathematical programmes, but since I don't really code in LaTeX that much, is it useful to learn these lines between \ExplSyntaxOn and \ExplSyntaxOff now? Are they kind of transferrable in the future for latex3 project? – CasperYC Jan 13 at 12:59
• @CasperYC A good deal of it is included in the LaTeX kernel, nowadays. – egreg Jan 13 at 14:31

Adapted from Andrews' answer from here.

It works well as far as the OP is concerned, but it can not be used in fancyhead as a footer or header.

\documentclass[a4paper,12pt]{article}

\usepackage[pdf]{pstricks}                %% added for pdflatex, use pdflatex -shell-escape $(NAME_PART).tex \usepackage[crop=off]{auto-pst-pdf} %% added for pdflatex, use pdflatex -shell-escape$(NAME_PART).tex
\usepackage{pst-poker}
\psset{inline=card}  %symbol/boxed

\usepackage{fancyhdr}
\usepackage{lipsum}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%% random %%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{pgf}
\usepackage{pgffor} % needed only for the examples
\usepackage{xparse}
%
% \DefineRandomSequence{<sequence>}: random elements with repeats
% \DefineRandomSequence*{<sequence>}: random elements without repeats
\NewDocumentCommand\DefineRandomSequence{sm}{%
\pgfmathsetseed{\number\time}% set a "random" seed based on time
\pgfmathdeclarerandomlist{myrandomlist}{#2}
\IfBooleanTF{#1}{\let\pgfsequencegenerator\pgfmathrandomitemwithoutreplacement}
{\let\pgfsequencegenerator\pgfmathrandomitem}
}
% \myitem: print random element of sequence
\newcommand\myitem{\pgfsequencegenerator\randomitem{myrandomlist}\randomitem}

\makeatletter
% Mark Wibrow: https://tex.stackexchange.com/questions/113987/how-do-i-generate-in-latex-a-list-of-random-questions-avoiding-repetitions
\def\pgfmathrandomitemwithoutreplacement#1#2{%
\pgfmath@ifundefined{pgfmath@randomlist@#2}{\pgfmath@error{Unknown random list #2'}}{%
\edef\pgfmath@randomlistlength{\csname pgfmath@randomlist@#2\endcsname}%
\ifnum\pgfmath@randomlistlength>0\relax%
\pgfmathrandominteger{\pgfmath@randomtemp}{1}{\pgfmath@randomlistlength}%
\def\pgfmath@marshal{\def#1}%
\expandafter\expandafter\expandafter\pgfmath@marshal\expandafter\expandafter\expandafter{\csname pgfmath@randomlist@#2@\pgfmath@randomtemp\endcsname}%
% Now prune.
\c@pgfmath@counta=\pgfmath@randomtemp\relax%
\c@pgfmath@countb=\c@pgfmath@counta%
\pgfmathloop%
\ifnum\c@pgfmath@counta=\pgfmath@randomlistlength\relax%
\else%
\def\pgfmath@marshal{\expandafter\global\expandafter\let\csname pgfmath@randomlist@#2@\the\c@pgfmath@counta\endcsname=}%
\expandafter\pgfmath@marshal\csname pgfmath@randomlist@#2@\the\c@pgfmath@countb\endcsname%
\repeatpgfmathloop%
\expandafter\xdef\csname pgfmath@randomlist@#2\endcsname{\the\c@pgfmath@counta}%
\else%
\pgfmath@error{Random list #2' is empty}%
\fi%
}}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
\begin{postscript}
%%
%%
%%
\pagestyle{empty}

% \DefineRandomSequence
\DefineRandomSequence*{{\As} {\Ah} {\Ad} {\Ac} {\Ks} {\Kh} {\Kd} {\Kc} {\Qs} {\Qh} {\Qd} {\Qc} {\Js} {\Jh} {\Jd} {\Jc} {\tens} {\tenh} {\tend} {\tenc} {\nines} {\nineh} {\nined} {\ninec} {\eigs} {\eigh} {\eigd} {\eigc} {\sevs} {\sevh} {\sevd} {\sevc} {\sixs} {\sixh} {\sixd} {\sixc} {\fives} {\fiveh} {\fived} {\fivec} {\fours} {\fourh} {\fourd} {\fourc} {\tres} {\treh} {\tred} {\trec} {\twos} {\twoh} {\twod} {\twoc}}

\foreach \x in {1,...,4}{\myitem\space}
\foreach \y in {1,...,8}{\myitem\space}
\foreach \z in {1,...,20}{\myitem\space}
\foreach \a in {1,...,52}{\myitem\space}

\end{postscript}
\end{document}


Worked fine with shorter lists (<52).

Or with 52 cards exactly

But won't work if you put all of them together

\foreach \x in {1,...,4}{\myitem\space}

\foreach \y in {1,...,8}{\myitem\space}

\foreach \z in {1,...,20}{\myitem\space}

\foreach \a in {1,...,52}{\myitem\space}


gives

For my purpose, this is good enough except that it doesn't work in fancyhead. It does work as intended as far as the question is concerned. So I am posting it as an answer.

\pagestyle{fancy}
\fancyhead[L]{\foreach \x in {1,...,4}{\myitem\space} }
\lipsum[3-9]
\lipsum[4-20]
`