% Francesco Zigliotto % The Labyrinth Package \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{labyrinth}[2014/04/12 v1.0 Labyrinths typeset with LaTeX] \RequirePackage{calc} \RequirePackage{xkeyval} \RequirePackage{picture} \newcommand\lab@addtomacro[2]{% \let\lab@oldmacro#1 \global\edef#1{\lab@oldmacro#2}} \providecommand\@nameedef[1]{% \expandafter\edef\csname #1\endcsname} \providecommand\truncdiv[2]{((#1-(#2-1)/2)/#2)} %****************************************************************** % Cat-codes of + - * %****************************************************************** \begingroup \catcode`\+=\active \catcode`\-=\active \catcode`\*=\active \gdef\lab@catcodes{% \catcode`\+=\active\def+{\lab@line}% \catcode`\-=\active\def-{\lab@noline}% \catcode`\*=\active\def*{\lab@repeat}} \endgroup \newcounter{lab@h} \newcounter{lab@v} %****************************************************************** % Labyrinth Options %****************************************************************** \newcommand*\labyrinthset{\setkeys{labyrinth}} \define@key{labyrinth}{unit}{\setlength\unitlength{#1}} \define@key{labyrinth}{thickness}{\linethickness{#1}} \define@boolkey{labyrinth}[lab@]{centered}{} \setkeys{labyrinth}{% unit=11pt,% centered=true} \newcommand*\solutionset{\setkeys{solution}} \define@boolkey{solution}[lab@]{hidden}{} \define@boolkey{solution}[lab@]{thicklines}{} \define@key{solution}{up}{\def\lab@key@u{#1}} \define@key{solution}{left}{\def\lab@key@l{#1}} \define@key{solution}{down}{\def\lab@key@d{#1}} \define@key{solution}{right}{\def\lab@key@r{#1}} \define@key{solution}{hcorr}{\def\lab@key@hcorr{#1}} \define@key{solution}{vcorr}{\def\lab@key@vcorr{#1}} \define@key{solution}{font}{\def\lab@key@font{#1}} \setkeys{solution}{% thicklines=true,% hidden=false,% up={\line(0,1){1}},% left={\line(-1,0){1}},% down={\line(0,-1){1}},% right={\line(1,0){1}},% hcorr=0.5\unitlength,% vcorr=0.5\unitlength} \@ifundefined{color} {\setkeys{solution}{font=}} {\setkeys{solution}{font=\color{red}}} %****************************************************************** % Lines Definitions %****************************************************************** \def\lab@hline{% \put(\thelab@h,\thelab@v){\line(1,0){1}}% \@namedef{(\number\numexpr\thelab@h*2+1,% \number\numexpr\thelab@v*2)}{}% \stepcounter{lab@h}}% \def\lab@vline{% \put(\thelab@h,\thelab@v){\line(0,1){1}}% \@namedef{(\number\numexpr\thelab@h*2,% \number\numexpr\thelab@v*2+1)}{}% \stepcounter{lab@h}}% \def\lab@noline{\stepcounter{lab@h}} \def\lab@repeat#1#2{% \count@=#1\relax\@whilenum\count@>\z@ \do{#2\advance\count@\m@ne}} %****************************************************************** % Labyrinth Environment %****************************************************************** \newenvironment{labyrinth}[3][]{% \iflab@centered\begin{center}\fi \setkeys{labyrinth}{#1} \def\lab@width{#2} \def\lab@height{#3} \def\h{% \setcounter{lab@h}{0}% \let\lab@line\lab@hline}% \def\v{% \addtocounter{lab@v}{-1}% \setcounter{lab@h}{0}% \let\lab@line\lab@vline}% \def\putsymbol(##1)##2{\put(##1){\makebox[\unitlength]{##2}}} \def\plus{+}\def\minus{-}\def\ast{*} \begin{picture}(#2,#3)(0,0) \setcounter{lab@v}{#3}% \lab@catcodes }{% \end{picture} \iflab@centered\end{center}\fi} %****************************************************************** % Labyrinth Solution %****************************************************************** \newcounter{lab@key@h} \newcounter{lab@key@v} \newcommand*\labyrinthsolution[1][]{% \setkeys{solution}{#1}% \lab@solution} \def\lab@solution(#1,#2)#3{% \unless\iflab@hidden \begingroup \iflab@thicklines\thicklines\fi \setcounter{lab@key@h}{#1}% \setcounter{lab@key@v}{#2}% \edef\lab@keycode{#3}% \expandafter\lab@forany\lab@keycode.% \endgroup \fi} \def\lab@forany#1{\if#1.\else\lab@key{#1}% \expandafter\lab@forany\fi} \def\lab@key#1{\@nameuse{lab@#1}} \@namedef{lab@u}{ \lab@key@put{u}\stepcounter{lab@key@v}} \@namedef{lab@l}{\lab@key@put{l}\addtocounter{lab@key@h}{-1}} \@namedef{lab@d}{\lab@key@put{d}\addtocounter{lab@key@v}{-1}} \@namedef{lab@r}{\lab@key@put{r}\stepcounter{lab@key@h}} \def\lab@key@put#1{% \put(\lab@key@h,\lab@key@v){\lab@key@font\@nameuse{lab@key@#1}}} \def\lab@key@h{\thelab@key@h\unitlength+\lab@key@hcorr} \def\lab@key@v{\thelab@key@v\unitlength+\lab@key@vcorr} %****************************************************************** % Automatic Solution %****************************************************************** \newif\iflab@isin \newcommand\lab@ifisin[2] {\def\lab@@isin##1#1##2|end@isin|% {\if|##2|\lab@isinfalse \else\lab@isintrue \fi}% \lab@@isin#2#1|end@isin|% \iflab@isin} \newcounter{lab@x} \newcounter{lab@y} \newcounter{lab@xtry} \newcounter{lab@ytry} \def\lab@f#1{% \setcounter{lab@xtry}{\thelab@x}% \setcounter{lab@ytry}{\thelab@y}% \edef\lab@f@try{\number\numexpr#1+4-\truncdiv{#1+4}{4}*4}% \@nameuse{lab:\lab@f@try}% \lab@check} \@namedef{lab:0}{\addtocounter{lab@ytry}{2}} \@namedef{lab:1}{\addtocounter{lab@xtry}{2}} \@namedef{lab:2}{\addtocounter{lab@ytry}{-2}} \@namedef{lab:3}{\addtocounter{lab@xtry}{-2}} \def\lab@step{% \lab@f{\lab@f@last+1}\iflab@ok\lab@ok\else \lab@f{\lab@f@last}\iflab@ok\lab@ok\else \lab@f{\lab@f@last-1}\iflab@ok\lab@ok\else \lab@f{\lab@f@last-2}\lab@ok\fi\fi\fi} \newif\iflab@ok \def\lab@check{% \@ifundefined{(\number\numexpr(\thelab@x+\thelab@xtry)/2,% \number\numexpr(\thelab@y+\thelab@ytry)/2)}% {\lab@oktrue}{\lab@okfalse}} \def\lab@ok{% \edef\lab@f@last{\lab@f@try}% \setcounter{lab@x}{\thelab@xtry}% \setcounter{lab@y}{\thelab@ytry}% \edef\lab@f@char{\ifcase\lab@f@last u\or r\or d\or l\fi}% \lab@addtomacro\lab@pos@list{% (\lab@f@char:\thelab@x,\thelab@y)}} \def\lab@deleted@cyc{} \def\lab@f@list{} \def\lab@del@cyc(#1:#2)#3.{% \lab@addtomacro\lab@deleted@cyc{(#1:#2)}% \lab@addtomacro\lab@f@list{#1}% \def\lab@del@@cyc##1(##2:#2){}% \lab@ifisin{:#2)}{#3}% \edef\lab@next@del@cyc{\lab@del@@cyc#3.}\else \edef\lab@next@del@cyc{#3.}\fi \if.\lab@next@del@cyc \else\expandafter\lab@del@cyc\lab@next@del@cyc\fi} \def\lab@deletecyc#1;{% \def\lab@deleted@cyc{}% \def\lab@f@list{}% \lab@del@cyc#1.% \loop\unless\ifx\lab@deleted@cyc\lab@last@deleted@cyc \let\lab@last@deleted@cyc\lab@deleted@cyc \def\lab@deleted@cyc{}% \def\lab@f@list{}% \expandafter\lab@del@cyc\lab@last@deleted@cyc.% \repeat} \@namedef{lab:u}{0} \@namedef{lab:r}{1} \@namedef{lab:d}{2} \@namedef{lab:l}{3} \newcommand*\autosolution[1][]{\lab@autokey[#1]} \def\lab@autokey[#1](#2,#3)(#4,#5)#6{% \setcounter{lab@x}{#2*2+1}% \setcounter{lab@y}{#3*2+1}% \edef\lab@f@last{\@nameuse{lab:#6}}% \lab@f\lab@f@last \setcounter{lab@x}{\thelab@xtry}% \setcounter{lab@y}{\thelab@ytry}% \edef\lab@pos@list{(#6:\thelab@x,\thelab@y)}% \edef\lab@pos@final{% (\number\numexpr#4*2+1,\number\numexpr#5*2+1)}% \loop\unless\ifx\lab@pos@final\lab@pos@current \lab@step \edef\lab@pos@current{(\thelab@x,\thelab@y)}% \repeat \expandafter\lab@deletecyc\lab@pos@list;% \labyrinthsolution[#1](#2,#3)\lab@f@list \edef\solutionpath{\lab@f@list}} \endinput