更新
或者有没有办法使用lcg
包生成 1 到 52 之间的随机数,然后将其与包中的 52 张卡片之一关联pst-poker
。哪个可能更容易实现?
OP
基本上,我想写一些简单的程序来生成随机扑克牌。看起来我需要expl3,xparse
和lcg
(随机数)。但我不知道如何将它们组合在一起。
\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}
这将生成一些适合我用途的卡片pdflatex
。现在我想做一些类似随机抽卡的事情。
“随机”过程将是这样的
\reinitrand[first=1, last=100, counter=rand]
\rand\arabic{rand}
\reinitrand[first=1, last=13, counter=rand2]
\rand\arabic{rand2}
然后为了“挑选”牌花色,我会这样做rand Mod 4
,所以值将是 0,1,2,3,然后我可以s/c/h/d
为黑桃、梅花、红心、方块分配花色(字符串)。
对于rand2
,它将是包中定义的从A
到的卡片。K
pst-poker-doc
最后,将两个字符串放在一起来生成密钥等等\Ks\tenh\sevd\Kc
...
我确信有更简单的方法可以做到这一点,但我只能做到这些了......
答案1
下面是一个实现expl3
。
生成一个介于 13 和 64 之间的“新”随机整数并将其转换为十进制,因此我们可以使用第一位数字表示花色(1 到 4 代表梅花、方块、红心和黑桃),第二位数字表示等级(0 代表 A,1 代表 2,等等,a 代表杰克,b 代表皇后,c 代表国王)。
检查生成的整数是否与之前生成的整数相同(如果是,则生成一个新的随机整数并重新进行检查)。最后,根据这两个数字生成卡片。
% 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}
答案2
改编自 Andrews 的回答这里。
就 OP 而言,它运行良好,但不能用作fancyhead
页脚或页眉。
\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}
适用于较短的列表(<52)。
或者恰好有 52 张牌
但如果你把它们放在一起就不会起作用
\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}
给出
对于我的目的来说,这已经足够好了,只是它在 中不起作用fancyhead
。就问题而言,它确实按预期工作。所以我把它作为答案发布出来。
\pagestyle{fancy}
\fancyhead[L]{\foreach \x in {1,...,4}{\myitem\space} }
\lipsum[3-9]
\lipsum[4-20]