% \iffalse %<*copyright> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% acromemory.sty package, %% %% Copyright (C) 2006--2020 D. P. Story %% %% dpstory@acrotex.net %% %% %% %% This program can redistributed and/or modified under %% %% the terms of the LaTeX Project Public License %% %% Distributed from CTAN archives in directory %% %% macros/latex/base/lppl.txt; either version 1.2 of %% %% the License, or (at your option) any later version. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{acromemory} % [2020/06/23 v2.0 AcroMemory (dps)] %<*driver> \documentclass{ltxdoc} \usepackage[colorlinks,hyperindex=false]{hyperref} \pdfstringdefDisableCommands{\let\\\textbackslash}% \EnableCrossrefs \CodelineIndex \RecordChanges \InputIfFileExists{aebdocfmt.def}{\PackageInfo{acromemory}{Inputting aebdocfmt.def}} {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax \PackageInfo{acromemory}{aebdocfmt.def cannot be found}} \begin{document} \bgroup\ttfamily \gdef\brpr#1{\char123\relax#1\char125\relax}\egroup \let\darg\brpr \let\env\texttt \let\opt\texttt \let\app\textsf \def\visispace{\symbol{32}} \def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}} \def\meta#1{\textsl{\texttt{#1}}} \def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}} \def\ltag{<}\def\rtag{>} \def\EXCL{!} \let\app\textsf\let\pkg\textsf \GetFileInfo{acromemory.sty} \title{The \texttt{AcroMemory} Package\texorpdfstring{\\}{: } A member of the AeB Pro family} \author{D. P. Story\\ Email: \texttt{storyd@owc.edu}} \date{processed \today} \maketitle \tableofcontents \let\Email\texttt \DocInput{acromemory.dtx} \IfFileExists{\jobname.ind}{\newpage\setupFullwidth\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute \texttt{makeindex -s gind.ist -o acromemory.ind acromemory.idx} on the command line and recompile \texttt{acromemory.dtx}.} \IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute \texttt{makeindex -s gglo.ist -o acromemory.gls acromemory.glo} on the command line and recompile \texttt{acromemory.dtx}.} \end{document} % % \fi % % \MakeShortVerb{|} % \InputIfFileExists{aebdonotindex.def}{\PackageInfo{eforms}{Inputting aebdonotindex.def}} % {\PackageInfo{eforms}{aebdonotindex.def cannot be found}} % % \section{Introduction} % % At the instigation of my erstwhile friend, J\"{u}ergen, I present to you \textsf{AcroMemory}, and % for the life of me, I can't remember why. % % Oh, yes, \textsf{AcroMemory} is a memory game in which you find the matching tiles. There are two versions % ---available as options of this package---for your enjoyment, % \texttt{acromemory1} and \texttt{acromemory2} (the default). % \begin{itemize} % \item \texttt{acromemory1}: Here you have a single game board, a rectangular region divided % by rows and columns. The total number of tiles should % be even, each tile should have a matching twin. The % game begins with all the tiles hidden. the user clicks a tile, % then another. If the tiles do not match, they become become hidden again % (you did remember the position of those tiles, didn't you?); otherwise, % they remain visible and are now read-only. The game is complete when the user, with % a lot of time on his/her hands, matches all tiles. There is a running tabulation kept % on the number of tries. There is also a button which resets the game and randomizes the % tiles. % \item \texttt{acromemory2}: For this game you have two identical rectangular images subdivided in%to tiles % (or slices) arrayed in rows and columns. The tiles for % one of the two images has been randomly re-arranged. The object of the game is to find all the % matching tiles by choosing a tiles from one image, and tile from the other image. As in the % first case, if the selected tiles do not match, they are hidden after an short interval of time % (you did remember the position of those tiles, didn't you?); otherwise, they remain visible and % are now read-only. The game is over when all tiles are matched, when this occurs, end-of-game % special effects occur that will dazzle the senses. There is an option to view a small image to % help you locate the matching tiles on the non-randomized; useful if the image is complex. There % is no reset button at this time, to play again, the user must close and open the document. % \end{itemize} % The demo files are \texttt{acromemory1.tex} and \texttt{acromemory2.tex}. These files show how to % lay out the various elements of this package. % % \paragraph*{What's New for version v2.0 (2020-06-23):} Rewrote the entire package to support all % \LaTeX\space workflows: \app{pdflatex}, \app{lualatex}, \app{xelatex}, and \app{dvips \texttt{->} distiller}. % \changes{v2.0}{2020/06/23}{Rewrote entire package in order to support all \string\LaTeX\space % workflows} % % \section{Creating the Image Tiles} % % For \texttt{acromemory2}, slicing of the image is at the very heart % of this game. You can slice an image in to rectangular tiles using % any of several applications: \app{Adobe Illustrator}, % \app{Photoshop} and \textsf{ImageReady}, for example. But these are % expensive applications; a cheap method is to use the {\LaTeX} package % \pkg{tile-graphic}.\footnote{\url{https://ctan.org/pkg/tile-graphic}} % % \begin{macrocode} %<*package> \RequirePackage{xkeyval} % \end{macrocode} % \leavevmode\IndexOpt{acromemory1} % One playing board, where you try to match identical icons. % \begin{macrocode} \DeclareOptionX{acromemory1}{\acromemoryitrue} % \end{macrocode} % \leavevmode\IndexOpt{acromemory2} % Two playing boards, one board randomized the other not. Try to find the matching icons, % one from each of the two boards. % \begin{macrocode} \DeclareOptionX{acromemory2}{\acromemoryifalse} % \end{macrocode} % \leavevmode\IndexOpt{includehelp} % Only valid when \texttt{acromemory2} is taken, this option allows you to provide a % figure showing the completed puzzle. % \begin{macrocode} \DeclareOptionX{includehelp}{\includehelptrue} % \end{macrocode} % \leavevmode\IndexOpt{draft} Draft mode, works for \app{pdflatex} and \app{lualatex} only. % \begin{macrocode} \DeclareOptionX{draft}{\PassOptionsToPackage{draft}{graphicx}} % \end{macrocode} % Declare to booleans, and process options % \begin{macrocode} \newif\ifincludehelp \includehelpfalse \newif\ifacromemoryi \acromemoryifalse \ProcessOptionsX\relax \@ifpackageloaded{eforms}{\execJSOn} {\RequirePackage[execJS]{eforms}} \RequirePackage{aeb-comment} \ifxetex\makeXasPDOff\fi \RequirePackage{icon-appr} \RequirePackage{multido} \RequirePackage{graphicx} \ifacromemoryi \def\RanIdentifier{\@gobble} \includecomment{acromemory1} \excludecomment{acromemory2} \includehelpfalse \else \def\RanIdentifier{R\@gobble} \includecomment{acromemory2} \excludecomment{acromemory1} \fi \newcount\am@nCnt % \end{macrocode} % \section{Main Macro Code} % % \begin{macro}{\bDebug} % A debugging command. When executed in the preamble, more is written to the Acrobat console % as the document is opened the first time, also, the icons are initially visible so you can % see the layout, and quickly play the game. This was used in development extensively to help % develop the JavaScript. % \begin{macrocode} \def\bDebug{\def\memDebug{true}} \def\memDebug{false} % \end{macrocode} % \end{macro} % \leavevmode\DescribeMacro\isPackage Placed prior to \cs{amEmbedTiles}, it signals % that the images are in a package file. % \begin{macrocode} \newif\if@isPackaged\@isPackagedfalse \def\isPackage{\@isPackagedtrue} \let\amIconObjs\@gobble % \end{macrocode} % \leavevmode\DescribeMacro\amEmbedTiles\hskip-\marginparsep\texttt % {[\ameta{ext}]\darg{\ameta{name}}\darg{\ameta{n-rows}}\darg{\ameta{n-cols}}\darg{\ameta{path}}} % Embed the required files for this puzzle. We require a \ameta{name}, in the off chance that some day % more than one puzzles are allowed. % \begin{macrocode} \newcommand{\amEmbedTiles}[4][]{\begingroup \gdef\amNumImages{#3}% \csarg\gdef{amGraphicPath#2}{#4}% \gdef\imageImportPath{#4}% \ifacromemoryi % \end{macrocode} % If \opt{acromemoryi} is in effect, then \texttt{\#3} is half the required icons, % each icon is placed twice, then mixed up. Anyway, we double this value going forward. % \begin{macrocode} \@tempcnta=#3\relax \multiply\@tempcnta\tw@ \xdef\nTotalTiles{\the\@tempcnta}\else \gdef\nTotalTiles{#3}\fi \def\@Ext{#1}\ifx\@Ext\@empty\def\@Ext{.pdf}\else\def\@Ext{.#1}\fi \@tempcnta\z@ \let\@embedList\@empty \let\AMIndxList\@gobble \edef\z{\noexpand\g@addto@macro\noexpand \amIconObjs{,"#2":\amNumImages}}\z \@whilenum \@tempcnta < \amNumImages \do{% \am@nCnt\@tempcnta\advance\am@nCnt\@ne \ifnum\am@nCnt<10\relax\edef\x{0\the\am@nCnt}\else \edef\x{\the\am@nCnt}\fi \edef\z{\noexpand\g@addto@macro\noexpand\AMIndxList{,"#2pic\x"}}\z \ifxetex\if@isPackaged \PackageWarning{acromemory} {There is no support for embedding packaged\MessageBreak PDFs with xelatex. Ignoring the \string\isPackage\MessageBreak command}% \@isPackagedfalse \fi\fi \ifacromemoryi \@tempcntb\@tempcnta \multiply\@tempcntb\tw@ \advance\@tempcntb\@ne \edef\z{\the\@tempcntb}\advance\@tempcntb\@ne \edef\zi{\the\@tempcntb}% \if@isPackaged \ifpdf \edef\y{\noexpand \embedIcon[name=#2pic\x,% hyopts={page=\x}]{#4_package.pdf}}% \else \edef\y{\noexpand \embedIcon[name=#2pic\x,% placement={[1]Membutton.\z,[1]Membutton.\zi},% page=\x-1]{#4_package.pdf}}% \fi \else \edef\y{\noexpand \embedIcon[name=#2pic\x,% placement={[1]Membutton.\z,[1]Membutton.\zi}]{#4_\x\@Ext}}% \fi \else \ifincludehelp\embedIcon[name=helpimage,% placement={[1]memoryhelp}]{#4\@Ext}\fi \edef\z{\the\am@nCnt}% \if@isPackaged \ifpdf \edef\y{\noexpand \embedIcon[name=#2pic\x,% hyopts={page=\x}]{#4_package.pdf}}% \else \edef\y{\noexpand \embedIcon[name=#2pic\x,% placement={[1]MemLbutton.\z,[1]MemRbutton.\z},% page=\x-1]{#4_package.pdf}}% \fi \else \edef\y{\noexpand \embedIcon[name=#2pic\x,% placement={[1]MemLbutton.\z,[1]MemRbutton.\z}% ]{#4_\x\@Ext}}% \fi \fi \expandafter\g@addto@macro\expandafter \@embedList\expandafter{\y}% \@tempcnta\am@nCnt }% do \toks@=\expandafter{\@embedList}\the\toks@ %%\typeout{!! \the\toks@}% \endgroup \global\@isPackagedfalse } % \end{macrocode} % \leavevmode\DescribeMacro\amIconPic\hskip-\marginparsep\texttt % {[\ameta{opts}]\darg{\ameta{fname}}\darg{\ameta{wd}}\darg{\ameta{ht}}} A general % purpose push button that will have icon appearances. % \begin{macrocode} \newcommand{\amIconPic}[4][]{% \I{\csOf{name}} required \pushButton[\BG{}\W{1}\S{S}#1\TP{1}%\F{\FHidden} ]{#2}{#3}{#4}} % \end{macrocode} % \DescribeMacro\insertTiles\hskip-\marginparsep % \texttt{\darg{\ameta{name}}\darg{\ameta{width}}\darg{\ameta{rows}}\darg{\ameta{cols}}} % Command for placing the tiles of a picture. We assume that the pictures are numbered % consecutively across rows. % \begin{quote} % \begin{description} % \item[\ameta{name}] The name of the graphic (a JavaScript identifier) % \item[\ameta{width}] The width of the image, the height is scaled proportionally % \item[\ameta{rows}] The number of rows % \item[\ameta{cols}] The number of columns % \end{description} % \end{quote} % \begin{macrocode} \newcommand\insertTiles[4]{\begingroup \@tempdima#2\relax \divide\@tempdima #4\relax \setbox\z@\hbox{\includegraphics[draft,width=\@tempdima]% {\@nameuse{amGraphicPath#1}}}% \edef\amTileWd{\the\wd\z@}% \setlength\@tempdima{\ht\z@+\dp\z@}% \setbox\z@\box\voidb@x \edef\amTileHt{\the\@tempdima}% \@tempdima\amTileWd\relax \multiply\@tempdima #4\relax \edef\tot@lWd{\the\@tempdima}% \@tempcnta#3\relax \multiply\@tempcnta #4\relax \divide\@tempcnta\tw@ \edef\tot@lHalfTiles{\the\@tempcnta}% \begin{minipage}{\tot@lWd}% \offinterlineskip\hbadness=10000\@tempcnta\z@ \leavevmode \rlap{\amIconPic[\BC{}\BG{}]{nullIconBtn}{0bp}{0bp}}% \multido{\i=1+1}{\tot@lHalfTiles}{% \advance\@tempcnta\@ne \edef\y{\the\@tempcnta}% \ifnum\i<10\relax \edef\x{0\i}\else \edef\x{\i}\fi \edef\iconPresets{\noexpand\IX{\noexpand\csOf{#1pic\x}}}% \amIconPic[\AAmouseup{selectTile();}\FB{true} \presets{\iconPresets}\presets{\amtile@KVs} ]{Membutton.\y}{\amTileWd}{\amTileHt}\allowbreak \advance\@tempcnta\@ne \edef\y{\the\@tempcnta}% \edef\iconPresets{\noexpand\IX{\noexpand\csOf{#1pic\x}}}% \amIconPic[\AAmouseup{selectTile();}\FB{true} \presets{\iconPresets}\presets{\amtile@KVs} ]{Membutton.\y}{\amTileWd}{\amTileHt}\allowbreak }% multido \end{minipage}% \endgroup } \def\amtileKVs#1{\def\amtile@KVs{#1}} \amtileKVs{} % \end{macrocode} % \leavevmode\DescribeMacro\insertTilesii\hskip-\marginparsep\texttt % {\darg{\ameta{name}}\darg{\ameta{width}}\darg{\ameta{n-rows}}\darg{\ameta{n-cols}}\darg{\ameta{\upshape L\string|R}}} % \begin{quote} % \begin{description} % \item[\ameta{name}] The name of the graphic (a JavaScript identifier) % \item[\ameta{width}] The width of the image, the height is scaled proportionally % \item[\ameta{rows}] The number of rows % \item[\ameta{cols}] The number of columns % \item[\ameta{\upshape L\string|R}] Indicates for Left or Right Image % \end{description} % \end{quote} % Is the common code for \cs{insertTilesL} and \cs{insertTilesR}. % \begin{macrocode} \newcommand\insertTilesii[5]{\begingroup \def\@rgv{#5}\def\as@L{L}% \@tempdima#2\relax \setbox\z@\hbox{\includegraphics[draft,width=\@tempdima]{% \@nameuse{amGraphicPath#1}}}% \edef\amImageWd{\the\wd\z@}% \setlength\@tempdima{\ht\z@+\dp\z@}% \setbox\z@\box\voidb@x \edef\amImageHt{\the\@tempdima}% % Now calculate wd and ht of a tile \@tempdima\amImageWd\relax \divide\@tempdima#4\relax \edef\amTileWd{\the\@tempdima}% \@tempdima\amImageHt\relax \divide\@tempdima#3\relax \edef\amTileHt{\the\@tempdima}% % Calculate total number of tiles \@tempcnta#3\relax \multiply\@tempcnta#4\relax \edef\Tot@lTiles{\the\@tempcnta}% % Begin minipage of width \amImageWd \begin{minipage}{\amImageWd}% \offinterlineskip\hbadness=10000\@tempcnta\z@ \leavevmode \rlap{\amIconPic[\BC{}\BG{}]{nullIconBtn}{0bp}{0bp}}% \multido{\i=1+1}{\Tot@lTiles}{% \advance\@tempcnta\@ne \edef\y{\the\@tempcnta}% \ifnum\i<10\relax \edef\x{0\i}\else \edef\x{\i}\fi \ifx\@rgv\as@L \def\muAction{nRowsAM=#3;nColsAM=#4;\string\r selectNonRandomTile(\y,\y);}\else \def\muAction{nRowsAM=#3;nColsAM=#4;\string\r selectRandomTile(randomAM[\y],\y);}\fi \edef\iconPresets{\noexpand\AAmouseup{\muAction}\noexpand \IX{\noexpand\csOf{#1pic\x}}}% \amIconPic[\presets{\iconPresets} %\FB{true} \presets{\amtile@KVs} ]{Mem#5button.\y}{\amTileWd}{\amTileHt}\allowbreak }% multido \end{minipage}\endgroup } % \end{macrocode} % \leavevmode\DescribeMacro\insertTilesL\hskip-\marginparsep\texttt % {\darg{\ameta{name}}\darg{\ameta{width}}\darg{\ameta{n-rows}}\darg{\ameta{n-cols}}} % Inserts the left-hand tiles, which is the non-randomize version of the picture. % \begin{macrocode} \newcommand\insertTilesL[4]{\ifacromemoryi \def\AM@next{\PackageWarning{acromemory} {The use of \string\insertTilesL\space is supported\MessageBreak only for the acromemory2 option}}\else \def\AM@next{\insertTilesii{#1}{#2}{#3}{#4}{L}}\fi\AM@next} % \end{macrocode} % \leavevmode\DescribeMacro\insertTilesR\hskip-\marginparsep\texttt % {\darg{\ameta{name}}\darg{\ameta{width}}\darg{\ameta{n-rows}}\darg{\ameta{n-cols}}} % Inserts the right-hand tiles, which is the randomized version of the picture. % \begin{macrocode} \newcommand\insertTilesR[4]{\ifacromemoryi \def\AM@next{\PackageWarning{acromemory} {The use of \string\insertTilesR\space is supported\MessageBreak only for the acromemory2 option}}\else \def\AM@next{\insertTilesii{#1}{#2}{#3}{#4}{R}}\fi\AM@next} % \end{macrocode} % \begin{macro}{\helpImage}\hskip-\marginparsep\texttt % {[\ameta{eform-opts}]\darg{\ameta{width}}} % When \texttt{acromemory2} option and the \texttt{includehelp} % option are taken, these commands are available. The command % \cs{helpImage} will contain an icon of the puzzle, and it width % is set by the command \cs{setHelpImageWidth}. The image is normally % hidden until the user rolls over the \cs{rolloverHelpButton}. The % icons appears with an caption under it, the content of the caption % can be entered using \cs{theHelpCaption}. % \begin{macrocode} \newcommand{\helpImage}[2][]{% \ifincludehelp{\setbox\z@\hbox{% \includegraphics[draft,width=#2]{\imageImportPath}}% \dimen\z@=\ht\z@\advance\dimen\z@14bp\ht\z@=\dimen\z@ \pushButton[\IX{\csOf{helpimage}}\TP{2} %\CA{\helpCaption} \Ff\FfReadOnly\BC{}\BG{}\S{S}#1]% {memoryhelp}{\the\wd\z@}{\the\ht\z@}}\fi } % \end{macrocode} % \end{macro} % \begin{macro}{\rolloverHelpButton} % \begin{macrocode} \newcommand{\rolloverHelpButton}[3][]{% \ifincludehelp \pushButton[\CA{Help}\BC{0 0 1}\BG{0.89 0.9 0.9} \AA{\AAMouseEnter{\JS{% var f = this.getField("memoryhelp");\r oIcon = f.buttonGetIcon(1);\r f.buttonPosition = position.iconTextV;\r f.buttonSetIcon(oIcon,0);\r f.buttonSetCaption({cCaption: "\helpCaption"});\r f.textColor=color.blue;\r }}% \AAMouseExit{\JS{% var f = this.getField("memoryhelp");\r f.buttonPosition = position.iconOnly;\r f.buttonSetIcon(nullIcon,0); }}}#1]{checkhelp}{#2}{#3}% \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\theHelpCaption} % \begin{macrocode} \def\theHelpCaption#1{\def\helpCaption{#1}} \theHelpCaption{A little help} % \end{macrocode} % \end{macro} % \begin{macro}{\messageBox}\hskip-\marginparsep\texttt % {[\ameta{opts}]\darg{\ameta{wd}}\darg{\ameta{ht}}} % A message text field, as the user works the puzzle, the progress is reported % to this field. % \begin{macrocode} \newcommand{\messageBox}[3][]{% \textField[#1\Ff\FfMultiline]{MsgBox}{#2}{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\playItAgain}\hskip-\marginparsep\texttt % {[\ameta{opts}]\darg{\ameta{wd}}\darg{\ameta{ht}}} % For the \texttt{acromemory2} option, this button can be placed to reset % the two memory boards, so the memory game can be played again. % \begin{macrocode} \newcommand{\playItAgain}[3][]{\ifacromemoryi \pushButton[\CA{Play again}#1\AAmouseup{playagain();}]% {playAgain}{#2}{#3}\fi } % \end{macrocode} % \end{macro} % \begin{macro}{\playItAgain}\hskip-\marginparsep\texttt % {[\ameta{opts}]\darg{\ameta{wd}}\darg{\ameta{ht}}} % For the \texttt{acromemory1} option, this button can be placed to reset % the game board, the icons are rearranged hand hidden again. % \begin{macrocode} \newcommand{\tryItAgain}[3][]{\ifacromemoryi\else \pushButton[\CA{Test Your Memory}#1\AAmouseup{tryAgain();}]% {testYourMemory}{#2}{#3}\fi } % \end{macrocode} % \end{macro} % % \section{Document JavaScript for \textsf{AcroMemory}} % Operational support is provide by JavaScript. % \begin{macrocode} \newcommand{\initFirstiMsg}{"Press the 'Play again' button to initialize the puzzle"} \newcommand{\initFirstiiMsg}{"Press the 'Test Your Memory' button to initialize the puzzle"} \begin{insDLJS*}{memjs} \begin{newsegment}{AcroMemory 1: Global Data and Initialization} // Global Data: var isRandomized=false; var randomAM = new Array(\nTotalTiles+1); var imageNames = new Array(\AMIndxList); imageNames.push(\AMIndxList); imageNames.unshift("null"); var dpsl = randomAM.length; var timeout = 10; var shutdown, rAE; var ok2Continue = true; var nRowsAM, nColsAM; var nCorrectAM = 0; var nAttemptsAM = 0; for (i=1; i<=\nTotalTiles; i++) randomAM[i]=i; % \end{macrocode} % We get the push button with a null icon (nullIconBtn) We get the null icon object % from it. This technique eliminates the previous need for the Acrobat application when % viewing the game. % \changes{v1.1}{2017/02/23}{use f.buttonGetIcon to get null icon object} % \begin{macrocode} var f=this.getField("nullIconBtn"); var nullIcon=f.buttonGetIcon(); var debug = \memDebug; \end{newsegment} \begin{acromemory1} \begin{newsegment}{AcroMemory 2: Initialize Pic Names} var currentChoice = ""; var currentIconName = ""; \end{newsegment} \end{acromemory1} \begin{acromemory2} \begin{newsegment}{AcroMemory 2: Initialize Pic Names} var LcurrentChoice = 0; var LcurrentTile = 0; var RcurrentChoice = 0; var RcurrentTile = 0; \end{newsegment} \end{acromemory2} \begin{newsegment}{AcroMemory 3: Bubble Sort} function clearAM() { for ( var i=1; i<=\nTotalTiles; i++ ) { var f = this.getField("Mem\RanIdentifier button."+i); f.buttonSetIcon(nullIcon); } } function mixupAM() { var i, rand; for (i=1; i<= \nTotalTiles; i++) { var rand = Math.random(); rand *= dpsl*dpsl; rand = Math.ceil(rand); rand = rand \% dpsl; if (rand == 0 ) rand = 1; temp = randomAM[i]; randomAM[i]=randomAM[rand]; randomAM[rand]=temp; } } function showAM() { for ( var i=1; i<=\nTotalTiles; i++ ) { var oIcon = this.getIcon(imageNames[randomAM[i]]); var f = this.getField("Mem\RanIdentifier button."+i); f.buttonSetIcon(oIcon); } } // Begin bubble sort function sortoutAM() { outerLoop(randomAM.length-1); } function outerLoop(i) { if ( ok2Continue && (i >= 0) ) shutdown = % app.setTimeOut("app.clearTimeOut(shutdown); % innerLoop("+i+",1);", timeout); } function innerLoop(i,j) { if ( j <= i ) { if (randomAM[j-1] > randomAM[j]) { var temp = randomAM[j-1]; randomAM[j-1] = randomAM[j]; randomAM[j] = temp; var oIcon = this.getIcon(imageNames[randomAM[j-1]]); var f = this.getField("Mem\RanIdentifier button."+(j-1)); f.buttonSetIcon(oIcon); var oIcon = this.getIcon(imageNames[randomAM[j]]); var f = this.getField("Mem\RanIdentifier button."+j); f.buttonSetIcon(oIcon); } j++ if ( ok2Continue ) shutdown = % app.setTimeOut("app.clearTimeOut(shutdown); % innerLoop("+i+","+j+");", timeout); } else { i--; outerLoop(i); } } function randomizePuzzle() { mixupAM(); for ( var i=1; i<=\nTotalTiles; i++) { var g = this.getField("Mem\RanIdentifier button."+i); var oIcon = this.getIcon(imageNames[randomAM[i]]); g.buttonSetIcon(oIcon,1); if (debug) g.buttonSetIcon(oIcon,0); } isRandomized=true; } \end{newsegment} \begin{acromemory1} \begin{newsegment}{AcroMemory 4: Tile Processing} var currentIndex=""; var currentName=""; var _bOK1=true; function selectTile() // right side randomly arranged { if(!isRandomized){ app.alert(\initFirstiMsg); return; } if (!_bOK1) return; var f = event.target; var oIcon = f.buttonGetIcon(1); f.buttonSetIcon(oIcon,0); var fname = f.name; var re1 = /Membutton\.(\d+)/; var index = re1.exec(fname); if (debug) console.println("index = " + index[1]); var thisiconName = imageNames[randomAM[index[1]]]; if (debug) console.println("thisiconName = " + thisiconName); if ( currentChoice == "" ) { currentChoice = fname; currentIconName = thisiconName; return; } if ( (thisiconName == currentIconName) ) { // right choice nCorrectAM++; nAttemptsAM++ f.readonly = true; var g = this.getField(currentChoice); g.readonly = true; reportProgress(nCorrectAM,nAttemptsAM); resetCountersAM(); } else { // wrong choice nAttemptsAM++ _bOK1=false; reportProgress(nCorrectAM,nAttemptsAM); rAE = app.setTimeOut(% "resetAfterError(\""+currentChoice+"\",\""+fname+"\");% _bOK1=true;", 1000); resetCountersAM(); } } function resetCountersAM () { currentChoice = ""; currentIconName = ""; } function resetAfterError(l,r) { try { app.clearTimeOut(rAE); } catch(e) {}; var f = this.getField(l); var g = this.getField(r); if (!debug) g.buttonSetIcon(nullIcon,0); if (!debug) f.buttonSetIcon(nullIcon,0); } function executePostGameEffects() {return;} function playagain() { for ( var i=1; i<=\nTotalTiles; i++) { var g = this.getField("Membutton."+i); g.buttonSetIcon(nullIcon,0); } g = this.getField("Membutton"); g.readonly=false; resetCountersAM(); nCorrectAM = 0; nAttemptsAM = 0; reportProgress(nCorrectAM,nAttemptsAM); randomizePuzzle(); } \end{newsegment} \end{acromemory1} \begin{acromemory2} \begin{newsegment}{AcroMemory 4: Tile Processing} // save original positions of fields var aLRect=new Array(); var aRRect=new Array(); aLRect.push("null"); aRRect.push("null"); var f=this.getField("MemLbutton"); var g=f.getArray(); for (var i=0; i % \end{macrocode} % \Finale \endinput