2

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
2

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}

enter image description here

| improve this answer | |
  • 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
1

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%
            \advance\c@pgfmath@countb by1\relax%
            \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%
                \advance\c@pgfmath@counta by1\relax%
                \advance\c@pgfmath@countb by1\relax%
            \repeatpgfmathloop%
            \advance\c@pgfmath@counta by-1\relax%
            \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).

enter image description here

Or with 52 cards exactly

enter image description here

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

enter image description here

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]

enter image description here

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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