我怎样才能将骰子放在每页的顶部?

我怎样才能将骰子放在每页的顶部?

我正在思考在旧的 RPG 书籍中听到的一个技巧,并想知道如何在 LaTeX 中做到这一点。

因此,以前在商店里很难找到 RPG 骰子(即 4、6、8、10、12 和 20 面的骰子。请注意,除了 d10 之外,所有这些骰子都是柏拉图立体),所以有一本书在每页顶部放了一系列骰子。您只需将书翻到任意一页,然后读出您想要的骰子即可。

我该如何设置一个文档,使其在每页的顶部自动掷出一定数量的骰子,并确保所有可能的掷骰结果均衡?(例如,对于 d20,一份 40 页的文档每个数字有两个,一份 25 页的文档有 20 个掷骰子,末尾有 5 页空白页)并且它们是随机分布的(例如,你不能翻到书的开头来增加掷出低分的机会)。

最好能编写任意数量的边的代码,因为我可以调整它来得到我想要的任何骰子。这主要是为了好玩,因为我认识的每个玩家都有比你挥动棍子更多的骰子,但我很好奇你会怎么做。

编辑澄清:我不需要有人帮我抽骰子:我可以使用图片,有图片包,等等。我会就此提出问题。我想要的是数字均匀分布在每一页上,并将它们随机放置在整本书中。

好的,我写了一个可能有用的快速伪代码。我不知道这是否是最好的方法,或者在 LaTeX 中是否可行,但这也许是个开始?

Pages := Number of pages
Sides := Number of sides on die
Count := Pages/Sides (rounded down)
Skip := Pages mod Sides //Might as well place the blank pages at the front
Set all pages to false
for(i = Skip to Sides)
{
    while(j := 0, j < Count, j++)
    {
        Random := Random number between 1 and Pages
        if(Page{Random} = false)
        {
            Place i on Page{Random}
            Set Page{Random} = true
        }
        else
        {
            j--
        }
}

这并不能确保公平分配,但如果我看到一堆东西,我可以重新编译。

答案1

你可以使用该background包将内容放在每个页面上,其余部分由 TikZ 完成:

代码

\documentclass{scrartcl}
\usepackage[margin=25mm]{geometry}
\usepackage{background}
\usepackage{lipsum}

\usetikzlibrary{calc,shapes.geometric}

\backgroundsetup%
{   contents=%
    {   \begin{tikzpicture}
        [   overlay,
            remember picture,
            wx/.style={draw,regular polygon, minimum size=1.5cm, above,fill=red!10,thick},
            w4820/.style={wx, regular polygon sides=3},
            w6/.style={wx, regular polygon sides=4},
            w12/.style={wx, regular polygon sides=5},
            w10/.style={wx, kite,kite vertex angles=100 and 60,minimum size=1cm},
            line join=round,
        ]
            \node[w4820] at ($(current page.north west)+(4,-2)$) {\pgfmathparse{random(1,4)}\pgfmathresult};
            \node[w6] at ($(current page.north west)+(6,-2)$) {\pgfmathparse{random(1,6)}\pgfmathresult};
            \node[w4820] at ($(current page.north west)+(8,-2)$) {\pgfmathparse{random(1,8)}\pgfmathresult};
            \node[w10] at ($(current page.north west)+(10,-2)$) {\pgfmathparse{random(1,10)}\pgfmathresult};
            \node[w12] at ($(current page.north west)+(12,-2)$) {\pgfmathparse{random(1,12)}\pgfmathresult};
            \node[w4820] at ($(current page.north west)+(14,-2)$) {\pgfmathparse{random(1,20)}\pgfmathresult};
        \end{tikzpicture}
    },
    color=black,
    angle=0,
    scale=1,
    opacity=1,
}

\begin{document}

\lipsum[1-100]

\end{document}

输出

在此处输入图片描述


编辑1

最后是自动版本。它会检查总页数,然后抽取骰子,骰子值均匀分布,如果没有空间再放一组骰子,则不再抽取。

骰子从左到右应该是 d4、d6、d8、d10、d12 和 d20。

事实证明,我认识的大多数人实际上都使用“倒置”风筝。

要使用不同的骰子,只需更改 中的 for lop 中的值\setinitialdicevalues,例如\foreach \x [count=\c] in {6,10,12,20,24,30}并在 中提供合适的样式tikzpicture,例如添加样式w24w30

代码

\documentclass{scrartcl}
\usepackage[margin=25mm]{geometry}
\usepackage{background}
\usepackage{lipsum}
\usepackage{xstring}
\usepackage{xifthen}
\usetikzlibrary{calc,shapes.geometric}

\usepackage{totcount}
\regtotcounter{page}

\newcommand{\setinitialdicevalues}
{   \xdef\dicedata{+}
    \foreach \x [count=\c] in {4,6,8,10,12,20}
    {   \pgfmathtruncatemacro{\maxsets}{(\totvalue{page}-1)/\x}
        \pgfmathtruncatemacro{\maxpage}{\maxsets*\x}
        \xdef\mytemplist{,}
        \ifthenelse{\maxsets > 0}
        {   \foreach \y in {1,...,\maxpage}
            {   \pgfmathtruncatemacro{\mytempvalue}{mod(\y-1,\x)+1}
                \xdef\mytemplist{\mytemplist\mytempvalue,}
            }
            \xdef\myrandomlist{,}
            \foreach \y in {\maxpage,...,1}
            {   \pgfmathtruncatemacro{\nei}{random(1,\y)}
                \pgfmathtruncatemacro{\neipo}{\nei+1}
                \StrBetween[\nei,\neipo]{\mytemplist}{,}{,}[\nextelement]
                \StrSubstitute[1]{\mytemplist}{,\nextelement,}{,}[\mytemplisttwo]
                \xdef\mytemplist{\mytemplisttwo}
                \xdef\myrandomlist{\myrandomlist\nextelement,}
            }
            \xdef\dicedata{\dicedata\maxpage+\myrandomlist+}
        }
        {   \xdef\dicedata{\dicedata0++}
        }
    }
    \typeout{\dicedata}
}

\newcommand{\getdicelist}[1]%
{ \pgfmathtruncatemacro{\lowerindex}{2*#1}%
    \pgfmathtruncatemacro{\upperindex}{2*#1+1}%
    \StrBetween[\lowerindex,\upperindex]{\dicedata}{+}{+}[\mytempdata]%
    \xdef\currentdicelist{\mytempdata}%
}

\backgroundsetup%
{   contents=%
    {   \begin{tikzpicture}
        [   overlay,
            remember picture,
            wx/.style={draw, minimum size=1.5cm, above,fill=red,font=\bfseries\selectfont,text=white,rounded corners=0.5mm,inner sep=1pt},
            w4/.style={wx, regular polygon, regular polygon sides=3},
            w6/.style={wx, regular polygon, regular polygon sides=4},
            w8/.style={w4},
            w10/.style={wx, kite,kite vertex angles=100 and 60,minimum size=1cm,shape border rotate=180},
            w12/.style={wx, regular polygon, regular polygon sides=5},
            w20/.style={w4},
        ]   
            \foreach \x [count=\c] in {4,6,8,10,12,20}
            {   \pgfmathtruncatemacro{\lowerindex}{2*\c-1}
                \pgfmathtruncatemacro{\upperindex}{2*\c}
                \StrBetween[\lowerindex,\upperindex]{\dicedata}{+}{+}[\currentlastpage]%
                \pgfmathtruncatemacro{\firstemptypage}{\currentlastpage+1}
                \ifthenelse{\value{page} < \firstemptypage}
                {   \pgfmathtruncatemacro{\lowerindex}{2*\c}%
                    \pgfmathtruncatemacro{\upperindex}{2*\c+1}%
                    \StrBetween[\lowerindex,\upperindex]{\dicedata}{+}{+}[\currentdicelist]%
                    \StrBetween[1,2]{\currentdicelist}{,}{,}[\mynextnumber]
                    \node[w\x] at ($(current page.north west)+(2+2*\c,-2)$) {\mynextnumber};
                    \StrSubstitute[1]{\currentdicelist}{,\mynextnumber,}{,}[\mytempdicelist]
                    \StrSubstitute[1]{\dicedata}{+\currentdicelist+}{+\mytempdicelist+}[\mytempdicedata]
                    \xdef\dicedata{\mytempdicedata}
                    %\node[w\x] at ($(current page.north west)+(2+2*\c,-2)$) {\pgfmathparse{random(1,\x)}\pgfmathresult};               
                }
                {
                }
            }
        \end{tikzpicture}
    },
    color=black,
    angle=0,
    scale=1,
    opacity=1,
}

\AtBeginDocument{\setinitialdicevalues\par\bigskip}

\begin{document}

total pages: \pgfmathparse{int(\totvalue{page}-1)}\pgfmathresult\bigskip

\lipsum[1-100]
\lipsum[1-100]
\lipsum[1-60]

\end{document}

输出

这是第 37 页中的第 31 页。因此,我们看到 d4、d6、d8 和 d12,但看不到 d10(第 30 页的最后一页)或 d20(第 20 页的最后一页)。

在此处输入图片描述

答案2

我把原来的答案替换成了骰子和预生成的头文件。首先是主文件:

\documentclass{article}
\usepackage{fancyhdr}
\usepackage{tikz}

\input{dice}% file containing shape definitions

\pagestyle{fancy}
\chead{\csname dice\Roman{page}\endcsname}

%%%%%%%%%%%%%%%%%%%%%%%%% dice macros %%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcounter{dice}

\newcommand{\createdice}[1]% #1 = tikz path
{\stepcounter{dice}
\expandafter\def\csname dice\Roman{dice}\endcsname{
\begin{tikzpicture}
\path #1;
\end{tikzpicture}
}}

% macros for nodes, #1 = dice value

\def\fourside#1{node[fourside,draw=black]{#1}}
\def\sixside#1{node[sixside,draw=black]{#1}}
\def\eightside#1{node[eightside,draw=black]{#1}}
\def\tenside#1{node[tenside,draw=black]{#1}}
\def\twelveside#1{node[twelveside,draw=black]{#1}}
\def\twentyside#1{node[twentyside,draw=black]{#1}}

\input{random}% file containing random dice throws

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

Test dice macros:\vfil

\begin{tikzpicture}
\path (0,0) \fourside{1}
 (1.5,0) \sixside{2}
 (3,0) \eightside{3}
 (4.5,0) \tenside{4}
 (6,0) \tenside{50}
 (7.5,0) \twelveside{6}
 (9,0) \twentyside{7};
\end{tikzpicture}

\vspace*{0.5in}
To draw the dodecahedron, first draw a decagon by placing a vertex
on a circle with a 1 cm diameter every $36^\circ$.
Since the bottom vertex is also part of a pentagon, given the
aspect ratio of the wide half to the narrow half (1.77)
we can compute the $y$ coordinate of the top edge of this pentagon
(-0.332 cm).
Since the two vertexes on this edge are in a straight line 
from the center at $-36^\circ$ and $-144^\circ$, 
the radius of the interior pentagon is given by
\[
r = \frac{0.332 \textrm{ cm}}{\sin(36^\circ)} = 0.349 \textrm{ cm.}
\]

To draw the icosahedron, first draw a hexagon by placing a vertex
on a circle with a 1 cm diameter every $60^\circ$.  
Except for the center triangle, every edge is foreshortened,
so we need to calculate the apparent length of one of the lines
connecting the outer hexagon to the interior triangle.

Consider a pentagonal pyramid inscribed in a 1 cm diameter circle
whose cross section is shown below
\begin{center}
\begin{tikzpicture}
\draw (0,0) coordinate(A) --node[midway,below]{0.905 cm}
 (3.62,0) coordinate(B) --node[midway,above right]{0.577 cm}
 (1.624,1.16) coordinate(C) --node[midway,above left]{0.499 cm}
 (0,0);
\draw (.5,0) arc(0:35.3:.5);
\draw (3.12,0) arc(180:149.8:.5);
\end{tikzpicture}\\
\end{center}
where a face is to the left and an edge is to the right.
Using the law of cosines, one can calculate the two angles
($35.5^\circ$ and $30.2^\circ$).  
So if the face (left) is perpendicular to the viewer, the edge (right)
will be foreshortened by $\cos(65.7^\circ)$.
Finally, if each triangle is inscribed into a circle of radius $r$,
each edge will be $2r\cos(30^\circ)$ and the total distance from the
center to the outside circle is given by
\[
r + 2r\cos(30^\circ)\cos(65.7^\circ) = 1.71 r = 0.5\textrm{ cm}
\]
and therefore $r = 0.292$ cm.

\newpage

This page intentionally left blank.
\newpage

This page intentionally left blank.

\end{document}

接下来是包含骰子定义的文件 dice.tex:

% tetrahedron

\pgfdeclareshape{fourside}{
\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

\anchor{text}   % this is used to center the text in the node
    {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\foregroundpath{ % draw border
 \pgfpathmoveto{\pgfpoint{0cm}{.3cm}}
 \pgfpathlineto{\pgfpoint{.433cm}{-.45cm}}
 \pgfpathlineto{\pgfpoint{-.433cm}{-.45cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.3cm}}
 \pgfusepath{draw}  %draw border
 \pgfusepath{draw}  %draw rectangle
}}

% cubic

\pgfdeclareshape{sixside}{
\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

\anchor{text}   % this is used to center the text in the node
    {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\foregroundpath{ % draw border
 \pgfpathrectanglecorners{\pgfpoint{.4cm}{.4cm}}{\pgfpoint{-.4cm}{-.4cm}}
 \pgfusepath{draw}  %draw rectangle
}}

% octahedron

\pgfdeclareshape{eightside}{
\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

\anchor{text}   % this is used to center the text in the node
    {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\foregroundpath{ % draw border
 \pgfpathmoveto{\pgfpoint{0cm}{.5cm}}
 \pgfpathlineto{\pgfpoint{.433cm}{.25cm}}
 \pgfpathlineto{\pgfpoint{.433cm}{-.25cm}}
 \pgfpathlineto{\pgfpoint{0cm}{-.5cm}}
 \pgfpathlineto{\pgfpoint{-.433cm}{-.25cm}}
 \pgfpathlineto{\pgfpoint{-.433cm}{.25cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.5cm}}
 \pgfpathlineto{\pgfpoint{.433cm}{-.25cm}}
 \pgfpathlineto{\pgfpoint{-.433cm}{-.25cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.5cm}}
 \pgfusepath{draw}  %draw interiaor
}}

% decahedron

\pgfdeclareshape{tenside}{
\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

\anchor{text}   % this is used to center the text in the node
    {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\foregroundpath{ % draw border
 \pgfpathmoveto{\pgfpoint{0cm}{.5cm}}
 \pgfpathlineto{\pgfpoint{.294cm}{-.154cm}}
 \pgfpathlineto{\pgfpoint{0cm}{-.3cm}}
 \pgfpathlineto{\pgfpoint{-.294cm}{-.154cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.5cm}}
 \pgfpathlineto{\pgfpoint{.475cm}{.1cm}}
 \pgfpathlineto{\pgfpoint{.475cm}{-.1cm}}
 \pgfpathlineto{\pgfpoint{0cm}{-.5cm}}
 \pgfpathlineto{\pgfpoint{-.475cm}{-.1cm}}
 \pgfpathlineto{\pgfpoint{-.475cm}{.1cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.5cm}}
 \pgfpathmoveto{\pgfpoint{.294cm}{-.154cm}}
 \pgfpathlineto{\pgfpoint{.475cm}{-.1cm}}
 \pgfpathmoveto{\pgfpoint{-.475cm}{-.1cm}}
 \pgfpathlineto{\pgfpoint{-.294cm}{-.154cm}}
 \pgfpathmoveto{\pgfpoint{0cm}{-.5cm}}
 \pgfpathlineto{\pgfpoint{0cm}{-.3cm}}
 \pgfusepath{draw}  %draw interiaor
}}

% dodecahedron

\pgfdeclareshape{twelveside}{
\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

\anchor{text}   % this is used to center the text in the node
    {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\foregroundpath{ % draw border
 \pgfpathmoveto{\pgfpoint{0cm}{.5cm}}
 \pgfpathlineto{\pgfpoint{0.294cm}{.405cm}}
 \pgfpathlineto{\pgfpoint{.475cm}{.173cm}}
 \pgfpathlineto{\pgfpoint{.475cm}{-.173cm}}
 \pgfpathlineto{\pgfpoint{.294cm}{-.405cm}}
 \pgfpathlineto{\pgfpoint{0cm}{-.5cm}}
 \pgfpathlineto{\pgfpoint{-.294cm}{-.405cm}}
 \pgfpathlineto{\pgfpoint{-.475cm}{-.173cm}}
 \pgfpathlineto{\pgfpoint{-.475cm}{.173cm}}
 \pgfpathlineto{\pgfpoint{-.294cm}{.405cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.5cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.349cm}}
 \pgfpathlineto{\pgfpoint{.332cm}{.108cm}}
 \pgfpathlineto{\pgfpoint{.205cm}{-.282cm}}
 \pgfpathlineto{\pgfpoint{-.205cm}{-.282cm}}
 \pgfpathlineto{\pgfpoint{-.332cm}{.108cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.349cm}}
 \pgfpathmoveto{\pgfpoint{.475cm}{.173cm}}
 \pgfpathlineto{\pgfpoint{.332cm}{.108cm}}
 \pgfpathmoveto{\pgfpoint{.294cm}{-.405cm}}
 \pgfpathlineto{\pgfpoint{.205cm}{-.282cm}}
 \pgfpathmoveto{\pgfpoint{-.294cm}{-.405cm}}
 \pgfpathlineto{\pgfpoint{-.205cm}{-.282cm}}
 \pgfpathmoveto{\pgfpoint{-.475cm}{.173cm}}
 \pgfpathlineto{\pgfpoint{-.332cm}{.108cm}}
 \pgfusepath{draw}  %draw interiaor
}}

% icosohedron

\pgfdeclareshape{twentyside}{
anchor{center}{\pgfpointorigin} % within the node, (0,0) is the center

anchor{text}    % this is used to center the text in the node
    {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\foregroundpath{ % draw border
 \pgfpathmoveto{\pgfpoint{0cm}{.5cm}}
 \pgfpathlineto{\pgfpoint{.454cm}{.262cm}}
 \pgfpathlineto{\pgfpoint{.454cm}{-.262cm}}
 \pgfpathlineto{\pgfpoint{0cm}{-.5cm}}
 \pgfpathlineto{\pgfpoint{-.454cm}{-.262cm}}
 \pgfpathlineto{\pgfpoint{-.454cm}{.262cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.5cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.292cm}}
 \pgfpathlineto{\pgfpoint{.253cm}{-.146cm}}
 \pgfpathlineto{\pgfpoint{-.253cm}{-.146cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.292cm}}
 \pgfpathlineto{\pgfpoint{.454cm}{.262cm}}
 \pgfpathlineto{\pgfpoint{.253cm}{-.146cm}}
 \pgfpathlineto{\pgfpoint{0cm}{-.5cm}}
 \pgfpathlineto{\pgfpoint{-.253cm}{-.146cm}}
 \pgfpathlineto{\pgfpoint{-.454cm}{.262cm}}
 \pgfpathlineto{\pgfpoint{0cm}{.292cm}}
 \pgfpathmoveto{\pgfpoint{.454cm}{-.262cm}}
 \pgfpathlineto{\pgfpoint{.253cm}{-.146cm}}
 \pgfpathmoveto{\pgfpoint{-.454cm}{-.262cm}}
 \pgfpathlineto{\pgfpoint{-.253cm}{-.146cm}}
 \pgfusepath{draw}  %draw interiaor
}}

最后是包含预生成随机骰子的文件 random.tex。这是使用 C 程序生成的,因此我可以轻松地计算出 100 和 1。虽然可以使用 LaTeX 进行计算,但为什么呢?

\createdice{\fourside{3}}
\createdice{\eightside{6}}
\createdice{\twentyside{1}}
\createdice{\twelveside{6}}
\createdice{\eightside{1}}
\createdice{\sixside{6}}
\createdice{\sixside{3}}
\createdice{\tenside{7}}
\createdice{\eightside{8}}
\createdice{\eightside{7}}
\createdice{\fourside{3}}
\createdice{\twentyside{8}}
\createdice{\eightside{3}}
\createdice{\fourside{3}}
\createdice{\fourside{1}}
\createdice{\fourside{3}}
\createdice{\tenside{0}}
\createdice{\twelveside{1}}
\createdice{\fourside{2}}
\createdice{(0,0) \tenside{20}
(1.5,0) \tenside{7}}
\createdice{\tenside{9}}
\createdice{\twelveside{2}}
\createdice{\tenside{0}}
\createdice{\twentyside{19}}
\createdice{\twelveside{10}}
\createdice{(0,0) \tenside{20}
(1.5,0) \tenside{6}}
\createdice{\fourside{4}}
\createdice{\fourside{1}}
\createdice{\twelveside{8}}
\createdice{\tenside{8}}
\createdice{(0,0) \tenside{60}
(1.5,0) \tenside{4}}
\createdice{\tenside{3}}
\createdice{\twelveside{1}}
\createdice{\eightside{8}}
\createdice{(0,0) \tenside{30}
(1.5,0) \tenside{0}}
\createdice{\fourside{3}}
\createdice{\sixside{3}}
\createdice{\eightside{5}}
\createdice{\sixside{5}}
\createdice{\twelveside{2}}
\createdice{\sixside{1}}
\createdice{\eightside{6}}
\createdice{\sixside{4}}
\createdice{\twentyside{20}}

骰子

答案3

虽然我喜欢的风格是使用 C 进行计算,使用 LaTeX 进行排版,但人们对随机数的兴趣足够浓厚,因此我决定制作自己的 LaTeX PRNG(伪随机数生成器)。

\documentclass{article}
\usepackage{fancyhdr}
\usepackage{tikz}

\input{random}% file containig PRNG
\input{dice}% file containing shape definitions

%%%%%%%%%%%%%%%%%%%%%%%%% header macro %%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcount\test

\makeatletter
\newcommand{\makedice}% random dice and random throws
{\setrand{7}
\test = \c@rand
\ifnum\test=0{
 \setrand{4}
 \advance\c@rand by\@ne
 \begin{tikzpicture}
 \path node[fourside,draw=black]{\arabic{rand}};
 \end{tikzpicture}
}
\else \ifnum\test=1{
 \setrand{6}
 \advance\c@rand by\@ne
 \begin{tikzpicture}
 \path node[sixside,draw=black]{\arabic{rand}};
 \end{tikzpicture}
}
\else \ifnum\test=2{
 \setrand{8}
 \advance\c@rand by\@ne
 \begin{tikzpicture}
 \path node[eightside,draw=black]{\arabic{rand}};
 \end{tikzpicture}
}
\else \ifnum\test=3{
 \setrand{10}
 \begin{tikzpicture}
 \path node[tenside,draw=black]{\arabic{rand}};
 \end{tikzpicture}
}
\else \ifnum\test=4{
 \setrand{10}
 \def\dice{\arabic{rand}0}
 \setrand{10}
 \begin{tikzpicture}
 \path (0,0) node[tenside,draw=black]{\dice}
  (1.5,0) node[tenside,draw=black]{\arabic{rand}};
 \end{tikzpicture}
}
\else \ifnum\test=5{
 \setrand{12}
 \advance\c@rand by\@ne
 \begin{tikzpicture}
 \path node[twelveside,draw=black]{\arabic{rand}};
 \end{tikzpicture}
}
\else {
 \setrand{20}
 \advance\c@rand by\@ne
 \begin{tikzpicture}
 \path node[twentyside,draw=black]{\scriptsize\arabic{rand}};
 \end{tikzpicture}
} \fi \fi \fi \fi \fi \fi}
\makeatother

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
\randinit
\pagestyle{fancy}
\chead{\makedice}
\setlength{\headheight}{1cm}

Test dice nodes:
\vspace{0.5in}

\begin{tikzpicture}
\path (0,0) node[fourside,draw=black]{1}
 (1.5,0) node[sixside,draw=black]{2}
 (3,0) node[eightside,draw=black]{3}
 (4.5,0) node[tenside,draw=black]{4}
 (6,0) node[tenside,draw=black]{50}
 (7.5,0) node[twelveside,draw=black]{6}
 (9,0) node[twentyside,draw=black]{\scriptsize 7};
\end{tikzpicture}
\newpage
This page intentionally left blank.
\newpage
This page intentionally left blank.
\end{document}

文件 dice.tex 与之前相同,但现在文件 random.tex 包含 PRNG。

\makeatletter
% The following is taken from \cite{Numerical Recipes in C}.
% The resulting MAX_RAND = 134456
% Proven good statistics (relatively speaking) but designed for speed.
% Added 8 entry shuffle (32 seemed a bit much).
% Output through counter rand
%
% \randinit required for initialization
% \setrand{n} outputs rand between 0 and (n-1)
% \nextrand uses same scale computed by last \setrand

\newcounter{rand}% scaled random number
\newcounter{randk}% used by shuffle

\newcount\idum
\newcount\im
\newcount\ia
\newcount\ic
\im = 134456
\ia = 8121
\ic = 28411

\newcount\temp

\def\step@rand{% computes next value for \idum (internal only)
 \global\multiply\idum by\ia
 \global\advance\idum by\ic
 \global\temp = \idum% compute idum mod im
 \global\divide\temp by\im
 \global\multiply\temp by\im
 \global\advance\idum by -\temp
}

\newcount\shuffle
\shuffle = 16807
\newcount\storeA
\newcount\storeB
\newcount\storeC
\newcount\storeD
\newcount\storeE
\newcount\storeF
\newcount\storeG
\newcount\storeH
\newcount\hold

\def\shuffle@rand{% random shuffle (internal only)
 \step@rand
 \c@randk = \idum
 \divide\c@randk by\shuffle
 \advance\c@randk by\@ne
 \global\c@rand = \csname store\Alph{randk}\endcsname
 \global\csname store\Alph{randk}\endcsname = \hold
 \global\hold = \idum
}

\newcommand{\randinit}{% required to initialize PRNG
 \global\idum = \day% seed uses number of minutes since start of month
 \global\multiply\idum by 1440
 \global\advance\idum by \time
 \step@rand% warmup
 \step@rand
 \step@rand
 \step@rand
 \global\storeA = \idum% fill shuffle array
 \step@rand
 \global\storeB = \idum
 \step@rand
 \global\storeC = \idum
 \step@rand
 \global\storeD = \idum
 \step@rand
 \global\storeE = \idum
 \step@rand
 \global\storeF = \idum
 \step@rand
 \global\storeG = \idum
 \step@rand
 \global\storeH = \idum
 \step@rand
 \global\hold = \idum
}

\newcount\scale

\newcommand{\setrand}[1]{% scales rand between 0 and (#1 -1)
 \global\scale = \@ne% To obtain unscaled numbers, use \setrand{0}
 \ifnum #1 > \z@ \ifnum #1 < \im
   \global\scale = \im% compute im/#1 rounded up
   \global\advance\scale by -\@ne
   \global\advance\scale by #1\relax
   \global\divide\scale by #1\relax
 \fi \fi
 \shuffle@rand
 \global\divide\c@rand by\scale
}

\newcommand{\nextrand}{% uses same scale as before
 \shuffle@rand
 \global\divide\c@rand by\scale
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatother

相关内容