texlive[65508] Master/texmf-dist: maze (10jan23)

commits+karl at tug.org commits+karl at tug.org
Tue Jan 10 22:15:45 CET 2023


Revision: 65508
          http://tug.org/svn/texlive?view=revision&revision=65508
Author:   karl
Date:     2023-01-10 22:15:45 +0100 (Tue, 10 Jan 2023)
Log Message:
-----------
maze (10jan23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/maze/README.md
    trunk/Master/texmf-dist/doc/latex/maze/maze.pdf
    trunk/Master/texmf-dist/doc/latex/maze/maze.tex
    trunk/Master/texmf-dist/tex/latex/maze/maze.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/maze/mazes-picture.png

Modified: trunk/Master/texmf-dist/doc/latex/maze/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/maze/README.md	2023-01-10 21:14:28 UTC (rev 65507)
+++ trunk/Master/texmf-dist/doc/latex/maze/README.md	2023-01-10 21:15:45 UTC (rev 65508)
@@ -14,7 +14,7 @@
 Copyright and License
 ---------------------
 
-    Copyright (C) 2022 by Sicheng Du <siddsc at foxmail.com>
+    Copyright (C) 2023 by Sicheng Du <siddsc at foxmail.com>
     -----------------------------------------------------------------
 
     This work may be distributed and/or modified under the

Modified: trunk/Master/texmf-dist/doc/latex/maze/maze.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/maze/maze.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/maze/maze.tex	2023-01-10 21:14:28 UTC (rev 65507)
+++ trunk/Master/texmf-dist/doc/latex/maze/maze.tex	2023-01-10 21:15:45 UTC (rev 65508)
@@ -1,33 +1,160 @@
 \documentclass{ltxdoc}
 \title{The \textsf{maze} package\footnote{~~This project is distributed under the \LaTeX~Project Public License, version 1.3c.}}
+\usepackage[margin=2cm]{geometry}
 \usepackage{graphicx}
+\usepackage{listings}
+\lstset{
+    basicstyle=\fontspec{Consolas},numbers=left,
+    numberstyle=\small,stepnumber=1,numbersep=5pt
+}
+\usepackage{xcolor}
 \usepackage{fontspec}
 \setmainfont{Times New Roman}
+\usepackage{indentfirst}
 \usepackage[misc]{ifsym}
 \author{Sicheng Du\thanks{~~\Letter~~\href{mailto:siddsc at foxmail.com}{siddsc at foxmail.com}}}
-\date{\today~~~~v1.1}
+\date{\today~~~~v1.2}
 \usepackage[colorlinks,linkcolor=purple]{hyperref}
 \usepackage{maze}
 \begin{document}
 \maketitle
+\section{Changes in this version}
+Thanks to the \TeX nicians who kindly gave valuable and earnest suggestions to this package, the version 1.2 is now released. The main changes include
+\begin{enumerate}
+\item Corrected some mistakes in this manual;
+\item Modified the format in the source code to improve compatibility;
+\item Improved the output map of the maze to make it clearer.
+\end{enumerate}
+\section{User instructions}
 The \textsf{maze} package can generate random square mazes of a specified size. You need to start from the bottom-left corner and reach the top-right corner to play it.
 \begin{macro}{\maze}
 \marg{size}\oarg{seed} is the syntax of the command that generates a maze. Thereinto
 \begin{description}
-\item[\marg{size}] controls the density of the walls inside the maze and directly influences its complexity. It must be a positive integer greater or equal to 2.
+\item[\marg{size}] controls the density of the walls inside the maze and directly influences its complexity. It must be a positive integer in the range \textbf{[2,100]}.
 
-To have the package produce a satisfactory outcome, it is recommended to input a number between 20 and 30 into \marg{text}. Over large numbers may cause \TeX~to exhaust its capacity and fail to produce anything.
+To have the package produce a satisfactory output, it is recommended to input a number between 20 and 50 into \marg{text}. Over large numbers may cause \TeX~to exhaust its capacity and fail to produce anything.
 \item[\oarg{seed}] is an optional parameter that specifies the seed for random numbers. If it is omitted, the current time (minute) will be used as the seed instead.
 \end{description}\end{macro}
 
-As an example, the following can be created by \cs{maze{30}[4]} and \cs{maze{20}[6]} respectively.
+As an example, the mazes in Figure \ref{fig:mazes} can be created by \cs{maze\{30\}[4]}, \cs{maze\{20\}[7]} and \cs{maze\{25\}}\footnote{This maze is likely to look different because of the difference of compiling time.} respectively.
 \begin{figure}[h]
-\begin{minipage}{.5\textwidth}
-\maze{30}[4]
-\end{minipage}\hfill
-\begin{minipage}{.5\textwidth}
-\maze{20}[6]
-\end{minipage}
+\centering
+\maze{30}[4]\hfill\maze{20}[7]\hfill\maze{25}
+\caption{Examples of mazes}\label{fig:mazes}
 \end{figure}
-\eject
+\clearpage
+\section{Code implementation}
+This package uses the \textsf{expl3} programming layer. Under the scope of \cs{ExplSyntaxOn} we first define some variables
+\begin{lstlisting}[firstnumber=7]
+\int_new:N\l_maze_rand_int                           % the random variable
+\int_new:N\l_maze_old_int \int_new:N\l_maze_new_int
+\dim_const:Nn\g_maze_size_dim{\linewidth}            % store the line width
+\intarray_new:Nn\g_maze_map_intarray{10000}          % map of the maze
+\intarray_new:Nn\g_walls_v_intarray{9900}            % existence of vertical
+\intarray_new:Nn\g_walls_h_intarray{9900}            % /horizontal walls
+\end{lstlisting}
+
+The internal command is defined as \cs{m at ze}. Starting with variable initialization,
+\begin{lstlisting}[firstnumber=last]
+\newcommand{\m at ze}[2]{
+  \sys_gset_rand_seed:n{#2}
+  \intarray_gzero:N\g_maze_map_intarray
+  \intarray_gzero:N\g_walls_v_intarray
+  \intarray_gzero:N\g_walls_h_intarray
+  \int_step_inline:nn{#1*#1}{
+    \intarray_gset:Nnn\g_maze_map_intarray{##1}{##1}
+  }
+  \int_step_inline:nn{#1*(#1-1)}{
+    \intarray_gset:Nnn\g_walls_v_intarray{##1}{1}
+    \intarray_gset:Nnn\g_walls_h_intarray{##1}{1}
+  }
+\end{lstlisting}
+
+Then we apply the \textit{Kruskal} algorithm to the intarray-based variant of the \textit{Union-find set}. Our loop should end when the beginning and finishing cells are connected. (so that a path exists)
+\begin{lstlisting}[firstnumber=last]
+  \bool_do_until:nn{
+    \int_compare_p:nNn{\intarray_item:Nn\g_maze_map_intarray{1}}
+    ={\intarray_item:Nn\g_maze_map_intarray{#1*#1}}
+  }{
+    \int_set:Nn\l_maze_rand_int{\int_rand:n{#1*(#1-1)}}
+    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_v_intarray{\l_maze_rand_int}}{}{
+      \int_compare:nNnTF{
+        \intarray_item:Nn\g_maze_map_intarray{
+          \l_maze_rand_int+\int_div_truncate:nn{\l_maze_rand_int-1}{#1-1}
+        }
+      }={
+        \intarray_item:Nn\g_maze_map_intarray{
+          1+\l_maze_rand_int+\int_div_truncate:nn{\l_maze_rand_int-1}{#1-1}
+        }
+        }{}{
+        \int_set:Nn\l_maze_new_int{
+          \intarray_item:Nn\g_maze_map_intarray{
+            1+\l_maze_rand_int+\int_div_truncate:nn{\l_maze_rand_int-1}{#1-1}
+          }
+        }
+        \int_set:Nn\l_maze_old_int{
+          \intarray_item:Nn\g_maze_map_intarray{
+            \l_maze_rand_int+\int_div_truncate:nn{\l_maze_rand_int-1}{#1-1}
+          }
+        }
+        \intarray_gset:Nnn\g_walls_v_intarray{\l_maze_rand_int}{0}
+        \int_step_inline:nn{#1*#1}{
+          \int_compare:nNnTF{\l_maze_old_int}={\intarray_item:Nn\g_maze_map_intarray{##1}}
+          {\intarray_gset:Nnn\g_maze_map_intarray{##1}{\l_maze_new_int}}{}
+        }
+      }
+    }
+    \int_set:Nn\l_maze_rand_int{\int_rand:n{#1*(#1-1)}}
+    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_h_intarray{\l_maze_rand_int}}{}{
+      \int_compare:nNnTF{\intarray_item:Nn\g_maze_map_intarray{\l_maze_rand_int}}
+      ={\intarray_item:Nn\g_maze_map_intarray{#1+\l_maze_rand_int}}{}{
+        \int_set:Nn\l_maze_new_int{
+          \intarray_item:Nn\g_maze_map_intarray{#1+\l_maze_rand_int}
+        }
+        \int_set:Nn\l_maze_old_int{
+          \intarray_item:Nn\g_maze_map_intarray{\l_maze_rand_int}
+        }
+        \intarray_gset:Nnn\g_walls_h_intarray{\l_maze_rand_int}{0}
+        \int_step_inline:nn{#1*#1}{
+          \int_compare:nNnTF{\l_maze_old_int}={\intarray_item:Nn\g_maze_map_intarray{##1}}
+          {\intarray_gset:Nnn\g_maze_map_intarray{##1}{\l_maze_new_int}}{}
+        }
+      }
+    }
+  }
+}
+\end{lstlisting}
+
+Lastly, we finish off by defining the user command, which outputs a map of the maze. To set the size and draw the boundaries,
+\begin{lstlisting}[firstnumber=last]
+\NewDocumentCommand\maze{mO{\c_sys_minute_int}}{
+  \m at ze{#1}{#2}
+  \setlength{\unitlength}{\fp_eval:n{.4/#1}\g_maze_size_dim}
+  \begin{picture}(#1,#1)(0,0)
+  \put(0,0){\line(0,1){#1}} \put(#1,#1){\line(0,-1){#1}}
+  \put(\int_eval:n{#1-1},#1){\line(-1,0){\int_eval:n{#1-1}}}
+  \put(1,0){\line(1,0){\int_eval:n{#1-1}}}
+\end{lstlisting}
+
+We extract from \cs{g\_walls\_h\_intarray} and \cs{g\_walls\_v\_intarray} and draw a line wherever a wall exists.
+\begin{lstlisting}[firstnumber=last]
+  \int_step_inline:nn{#1*(#1-1)}{
+    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_h_intarray{##1}}{}{
+      \put(
+        \int_mod:nn{##1-1}{#1},
+        \int_eval:n{1+\int_div_truncate:nn{##1-1}{#1}}
+      ){\line(1,0){1}}
+    }
+    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_v_intarray{##1}}{}{
+      \put(
+        \int_mod:nn{##1}{#1-1},
+        \int_div_truncate:nn{##1-1}{#1-1}
+      ){\line(0,1){1}}
+    }
+  }
+  \end{picture}
+}
+\ExplSyntaxOff
+% End of package code
+\end{lstlisting}
 \end{document}
\ No newline at end of file

Added: trunk/Master/texmf-dist/doc/latex/maze/mazes-picture.png
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/maze/mazes-picture.png
===================================================================
--- trunk/Master/texmf-dist/doc/latex/maze/mazes-picture.png	2023-01-10 21:14:28 UTC (rev 65507)
+++ trunk/Master/texmf-dist/doc/latex/maze/mazes-picture.png	2023-01-10 21:15:45 UTC (rev 65508)

Property changes on: trunk/Master/texmf-dist/doc/latex/maze/mazes-picture.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/latex/maze/maze.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/maze/maze.sty	2023-01-10 21:14:28 UTC (rev 65507)
+++ trunk/Master/texmf-dist/tex/latex/maze/maze.sty	2023-01-10 21:15:45 UTC (rev 65508)
@@ -1,62 +1,73 @@
-% Copyright (C) 2022 by Sicheng Du <siddsc at foxmail.com>
+% Copyright (C) 2023 by Sicheng Du <siddsc at foxmail.com>
 % This project is distributed under the LaTeX Project Public License, version 1.3c.
 %-------------------------%
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{maze}[1.1]
+\ProvidesPackage{maze}[1.2]
 \ExplSyntaxOn
-\int_new:N\l_rand
-\int_new:N\l_old \int_new:N\l_new
-\dim_const:Nn\g_size{\linewidth}
+\int_new:N\l_maze_rand_int
+\int_new:N\l_maze_old_int \int_new:N\l_maze_new_int
+\dim_const:Nn\g_maze_size_dim{\linewidth}
+\intarray_new:Nn\g_maze_map_intarray{10000}
+\intarray_new:Nn\g_walls_v_intarray{9900}
+\intarray_new:Nn\g_walls_h_intarray{9900}
 \newcommand{\m at ze}[2]{
   \sys_gset_rand_seed:n{#2}
-  \let\g_map\undefined
-  \let\g_walls_v\undefined\let\g_walls_h\undefined
-  \intarray_new:Nn\g_map{#1*#1}
-  \intarray_new:Nn\g_walls_v{#1*(#1-1)}
-  \intarray_new:Nn\g_walls_h{#1*(#1-1)}
+  \intarray_gzero:N\g_maze_map_intarray
+  \intarray_gzero:N\g_walls_v_intarray
+  \intarray_gzero:N\g_walls_h_intarray
   \int_step_inline:nn{#1*#1}{
-    \intarray_gset:Nnn\g_map{##1}{##1}
+    \intarray_gset:Nnn\g_maze_map_intarray{##1}{##1}
   }
   \int_step_inline:nn{#1*(#1-1)}{
-    \intarray_gset:Nnn\g_walls_v{##1}{1}
-    \intarray_gset:Nnn\g_walls_h{##1}{1}
+    \intarray_gset:Nnn\g_walls_v_intarray{##1}{1}
+    \intarray_gset:Nnn\g_walls_h_intarray{##1}{1}
   }
   \bool_do_until:nn{
-    \int_compare_p:nNn{\intarray_item:Nn\g_map{1}}
-    ={\intarray_item:Nn\g_map{#1*#1}}
+    \int_compare_p:nNn{\intarray_item:Nn\g_maze_map_intarray{1}}
+    ={\intarray_item:Nn\g_maze_map_intarray{#1*#1}}
   }{
-    \int_set:Nn\l_rand{\int_rand:n{#1*(#1-1)}}
-    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_v{\l_rand}}{}{
+    \int_set:Nn\l_maze_rand_int{\int_rand:n{#1*(#1-1)}}
+    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_v_intarray{\l_maze_rand_int}}{}{
       \int_compare:nNnTF{
-        \intarray_item:Nn\g_map{\l_rand+\int_div_truncate:nn{\l_rand-1}{#1-1}}
+        \intarray_item:Nn\g_maze_map_intarray{
+          \l_maze_rand_int+\int_div_truncate:nn{\l_maze_rand_int-1}{#1-1}
+        }
       }={
-        \intarray_item:Nn\g_map{
-          1+\l_rand+\int_div_truncate:nn{\l_rand-1}{#1-1}
+        \intarray_item:Nn\g_maze_map_intarray{
+          1+\l_maze_rand_int+\int_div_truncate:nn{\l_maze_rand_int-1}{#1-1}
         }
         }{}{
-        \int_set:Nn\l_new{
-          \intarray_item:Nn\g_map{1+\l_rand+\int_div_truncate:nn{\l_rand-1}{#1-1}}
+        \int_set:Nn\l_maze_new_int{
+          \intarray_item:Nn\g_maze_map_intarray{
+            1+\l_maze_rand_int+\int_div_truncate:nn{\l_maze_rand_int-1}{#1-1}
+          }
         }
-        \int_set:Nn\l_old{
-          \intarray_item:Nn\g_map{\l_rand+\int_div_truncate:nn{\l_rand-1}{#1-1}}
+        \int_set:Nn\l_maze_old_int{
+          \intarray_item:Nn\g_maze_map_intarray{
+            \l_maze_rand_int+\int_div_truncate:nn{\l_maze_rand_int-1}{#1-1}
+          }
         }
-        \intarray_gset:Nnn\g_walls_v{\l_rand}{0}
+        \intarray_gset:Nnn\g_walls_v_intarray{\l_maze_rand_int}{0}
         \int_step_inline:nn{#1*#1}{
-          \int_compare:nNnTF{\l_old}={\intarray_item:Nn\g_map{##1}}
-          {\intarray_gset:Nnn\g_map{##1}{\l_new}}{}
+          \int_compare:nNnTF{\l_maze_old_int}={\intarray_item:Nn\g_maze_map_intarray{##1}}
+          {\intarray_gset:Nnn\g_maze_map_intarray{##1}{\l_maze_new_int}}{}
         }
       }
     }
-    \int_set:Nn\l_rand{\int_rand:n{#1*(#1-1)}}
-    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_h{\l_rand}}{}{
-      \int_compare:nNnTF{\intarray_item:Nn\g_map{\l_rand}}
-      ={\intarray_item:Nn\g_map{#1+\l_rand}}{}{
-        \int_set:Nn\l_new{\intarray_item:Nn\g_map{#1+\l_rand}}
-        \int_set:Nn\l_old{\intarray_item:Nn\g_map{\l_rand}}
-        \intarray_gset:Nnn\g_walls_h{\l_rand}{0}
+    \int_set:Nn\l_maze_rand_int{\int_rand:n{#1*(#1-1)}}
+    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_h_intarray{\l_maze_rand_int}}{}{
+      \int_compare:nNnTF{\intarray_item:Nn\g_maze_map_intarray{\l_maze_rand_int}}
+      ={\intarray_item:Nn\g_maze_map_intarray{#1+\l_maze_rand_int}}{}{
+        \int_set:Nn\l_maze_new_int{
+          \intarray_item:Nn\g_maze_map_intarray{#1+\l_maze_rand_int}
+        }
+        \int_set:Nn\l_maze_old_int{
+          \intarray_item:Nn\g_maze_map_intarray{\l_maze_rand_int}
+        }
+        \intarray_gset:Nnn\g_walls_h_intarray{\l_maze_rand_int}{0}
         \int_step_inline:nn{#1*#1}{
-          \int_compare:nNnTF{\l_old}={\intarray_item:Nn\g_map{##1}}
-          {\intarray_gset:Nnn\g_map{##1}{\l_new}}{}
+          \int_compare:nNnTF{\l_maze_old_int}={\intarray_item:Nn\g_maze_map_intarray{##1}}
+          {\intarray_gset:Nnn\g_maze_map_intarray{##1}{\l_maze_new_int}}{}
         }
       }
     }
@@ -64,18 +75,19 @@
 }
 \NewDocumentCommand\maze{mO{\c_sys_minute_int}}{
   \m at ze{#1}{#2}
-  \setlength{\unitlength}{\fp_eval:n{.4/#1}\g_size}
-  \begin{picture}(\int_eval:n{#1+2},\int_eval:n{#1+2})(-1,-1)
-  \put(0,0){\line(0,1){#1}}\put(0,0){\line(1,0){#1}}
-  \put(#1,#1){\line(0,-1){#1}}\put(#1,#1){\line(-1,0){#1}}
+  \setlength{\unitlength}{\fp_eval:n{.4/#1}\g_maze_size_dim}
+  \begin{picture}(#1,#1)(0,0)
+  \put(0,0){\line(0,1){#1}} \put(#1,#1){\line(0,-1){#1}}
+  \put(\int_eval:n{#1-1},#1){\line(-1,0){\int_eval:n{#1-1}}}
+  \put(1,0){\line(1,0){\int_eval:n{#1-1}}}
   \int_step_inline:nn{#1*(#1-1)}{
-    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_h{##1}}{}{
+    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_h_intarray{##1}}{}{
       \put(
         \int_mod:nn{##1-1}{#1},
         \int_eval:n{1+\int_div_truncate:nn{##1-1}{#1}}
       ){\line(1,0){1}}
     }
-    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_v{##1}}{}{
+    \int_compare:nNnTF{0}={\intarray_item:Nn\g_walls_v_intarray{##1}}{}{
       \put(
         \int_mod:nn{##1}{#1-1},
         \int_div_truncate:nn{##1-1}{#1-1}
@@ -84,4 +96,5 @@
   }
   \end{picture}
 }
-\ExplSyntaxOff
\ No newline at end of file
+\ExplSyntaxOff
+% End of package code
\ No newline at end of file



More information about the tex-live-commits mailing list.