% \iffalse
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% jj_game.cls class file,                              %%
%% Copyright (C) 2000-2016  D. P. Story                 %%
%%   dpstory@uakron.edu                                 %%
%%                                                      %%
%% 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 of the  %%
%% License, or (at your option) any later version.      %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01]
%<package>\ProvidesClass{jj_game}[2016/11/24 v3.1 jj_game Class (dps)]
%<*driver>
\documentclass{ltxdoc}
\usepackage[colorlinks,hyperindex=false]{hyperref}
%\pdfstringdefDisableCommands{\let\\\textbackslash}%
\OnlyDescription  % comment out for implementation details
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\InputIfFileExists{aebdocfmt.def}{\PackageInfo{jj_game}{Inputting aebdocfmt.def}}
    {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
     \PackageInfo{jj_game}{aebdocfmt.def cannot be found}}
\begin{document}
\def\CMD#1{\textbackslash#1}
\let\pkg\textsf
\let\opt\texttt
%\addtolength{\marginparwidth}{3pt}
  \GetFileInfo{jj_game.cls}
  \title{\pkg{jj\_game}\texorpdfstring{\\}{:} A {\LaTeX} class to construct Jeopardy-like Games}
  \author{D. P. Story\\
    Email: \texttt{dpstory@uakron.edu}}
  \date{processed \today}
  \maketitle
  \tableofcontents
  \let\Email\texttt
  \DocInput{jj_game.dtx}
\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute
    \texttt{makeindex -s gind.ist -o jj\_game.ind jj\_game.idx} on the command line and recompile
    \texttt{jj\_game.dtx}.}
\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute
    \texttt{makeindex -s gglo.ist -o jj\_game.gls jj\_game.glo} on the command line and recompile
    \texttt{jj\_game.dtx}.}
\end{document}
%</driver>
% \fi
%
% \MakeShortVerb{|}
% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{jj_game}{Inputting aebdonotindex.def}}
%    {\PackageInfo{jj_game}{cannot find aebdonotindex.def}}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
% \section{Declare Options}
%    \begin{macrocode}
\RequirePackage{xkeyval}
%    \end{macrocode}
%    Add \pkg{ifpdf} and \pkg{ifxetex} for automatic driver detection.
%    \changes{v3.1}{2016/11/24}{Add automatic driver detection for \string\pkg{ifpdf} and \string\pkg{ifxetex}}
%    \changes{v3.1}{2016/11/24}{Added support for \opt{xetex} driver. There are numerous changes to get
%    the positioning of the form fields correct. Changes are characterized by uses of \string\cs{ifxetex}
%    and \string\cs{efKern}.}
%    \begin{macrocode}
\RequirePackage{ifpdf}[2006/02/20]
\RequirePackage{ifxetex}[2006/08/21]
\newcounter{jjgdriver}
%    \end{macrocode}
% Here is the list of supported drivers:\IndexOpt{dvips}\IndexOpt{pdftex}\IndexOpt{xelex}\IndexOpt{luatex}
% \texttt{pdftex}, \texttt{luatex}, and \texttt{xetex} are automatically detected and need not be specified.
% Other less used drivers are also supported.
%    \begin{macrocode}
\DeclareOptionX{pdftex}{\setcounter{jjgdriver}{0}
    \def\jjgdriver{\@gobble}}
\DeclareOptionX{luatex}{\setcounter{jjgdriver}{0}
    \def\jjgdriver{\@gobble}}
\DeclareOptionX{dvips}{\setcounter{jjgdriver}{1}
    \def\jjgdriver{dvips}\PassOptionsToPackage{dvips}{web}}
\DeclareOptionX{dvipsone}{\setcounter{jjgdriver}{1}
    \def\jjgdriver{dvipsone}\PassOptionsToPackage{dvipsone}{web}}
\DeclareOptionX{dvipdfm}{\setcounter{jjgdriver}{2}
    \def\jjgdriver{dvipdfm}\PassOptionsToPackage{dvipdfm}{web}}
\DeclareOptionX{dvipdfmx}{\setcounter{jjgdriver}{2}
    \def\jjgdriver{dvipdfmx}\PassOptionsToPackage{dvipdfmx}{web}}
\DeclareOptionX{xetex}{\setcounter{jjgdriver}{2}
    \def\jjgdriver{\@gobble}}
%    \end{macrocode}
%    \begin{macrocode}
\DeclareOptionX*{\PassOptionsToClass{\CurrentOption}{article}}
%    \end{macrocode}
% Used for debugging:
% Where's the bug?\IndexOpt{debug}
%    \begin{macrocode}
\newif\ifdebug \debugfalse
\DeclareOptionX{debug}{\debugtrue}
%    \end{macrocode}
% This option \IndexOpt{final}\opt{final} removes window ui and other things.
%    \begin{macrocode}
\newif\iffinal \finalfalse
\DeclareOptionX{final}{\finaltrue}
%    \end{macrocode}
% Play \textbf{Double Jeopardy!}\IndexOpt{double} Double the amounts, double the fun!
%    \begin{macrocode}
\newif\ifdouble \doublefalse
\def\scaleFactor{1}
\DeclareOptionX{double}{\doubletrue\def\scaleFactor{2}}
%    \end{macrocode}
% We implement a two player game\IndexOpt{twoplayer}, by first declaring \texttt{twoplayer} as an option.
% \changes{v3.0h}{2008/11/16}{Added \texttt{twoplayer} option, as well as additional properties for
%   setting up the option.}
%    \begin{macrocode}
\newif\ifjjgtwoplayer\jjgtwoplayerfalse
\def\twoplayerGame{false}
\DeclareOptionX{twoplayer}{\jjgtwoplayertrue\def\twoplayerGame{true}}
%    \end{macrocode}
% Inputs the \IndexOpt{pro}\texttt{pro} code: uses layers, distiller 7.0 or later is required.
%    If the \texttt{pro} option is taken, then allow peeking as layers are used to hide the questions.
%    \begin{macrocode}
\DeclareOptionX{pro}{\let\jjgInputProCode\jjg@InputProCode
    \ExecuteOptionsX{allowpeeking}
    \AtBeginDocument{\@ifundefined{xBld}{\PackageError{jj_game}
    {You have specified the `pro' option, but\MessageBreak
     the aeb_pro package is not loaded with its\MessageBreak
     `uselayers' option}{See jjg_pro_ca.tex as an example of
     the correct loading\MessageBreak
     of aeb_pro}}{}}}
\def\jjg@InputProCode{\InputIfFileExists{jjgpro.def}%
    {\ClassWarning{jj_game}{Inputting code for pro option}
      \ClassWarningNoLine{jj_game}{AeB Pro required with uselayers
      option}}{\ClassWarning{jjg_game}{Cannot find jjgpro.def.
      \MessageBreak Reinstall or refresh your file name database.}}}
\let\jjgInputProCode\relax
\AtEndOfClass{\jjgInputProCode}
%    \end{macrocode}
% For credit play\IndexOpt{forcredit}. Enables a Jeopardy game to be handed in for credit. Adds security measures so
% student cannot cheat. Works best when the \texttt{pro} option is used.
%    \begin{macrocode}
\DeclareOptionX{forcredit}{%
    \let\jjImportForCreditCode\jj@ImportForCreditCode}
%    \end{macrocode}
% The normal behavior\IndexOpt{allowpeeking} of the game is that if the contestant looks ahead at a question,
% then the tile on the game board corresponding to the question viewed is hidden.
% The contestant is not allowed to answer that question. Use \opt{allowpeeking} option to remove
% this feature of the game.
% \changes{v3.0c}{2007/10/29}{
% Added the \texttt{allowpeeking} option}
%    \begin{macrocode}
\DeclareOptionX{allowpeeking}{\jjnopeekingfalse}
\newif\ifjjnopeeking \jjnopeekingtrue
%    \end{macrocode}
%    \begin{macrocode}
\let\jjImportForCreditCode\relax
\def\jj@ImportForCreditCode{\@ifpackageloaded{aeb_pro}
    {\InputIfFileExists{jjcredit.def}
    {\ClassWarning{jj_game}{Inputting forcredit code}
    \ClassWarningNoLine{jj_game}{Don't forget to use
    \string\contestantName\MessageBreak
    and \string\gameboardPrintButton}}
    {\ClassWarning{jj_game}{Cannot find jjcredit.def}}}
    {\ClassWarningNoLine{jj_game}
    {The forcredit option requires the aeb_pro package}}}
%    \end{macrocode}
% Several pre-defined designs are accessible through \IndexOpt{design}\opt{design} option. Design
% choices are \texttt{jeopardy}, \texttt{florida}, \texttt{iceland}, \texttt{hornet}, \texttt{qatar}, \texttt{norway},
%   \texttt{germany}, \texttt{bahamas}, \texttt{spain}.
%    \begin{macrocode}
\let\jjg@madedesignselection0
\define@choicekey+{jj_game.cls}{design}{jeopardy,florida,iceland,%
    hornet,qatar,norway,germany,bahamas,spain,custom}{%
    \ifx\jjg@madedesignselection0\def\jj@design@choice{#1}%
        \AtEndOfClass{\jjInputDesignChoice}%
            \global\let\jjg@madedesignselection1
            \def\jjg@useddesign{design}\else
        \ClassWarning{jj_game}{Do not use both design
            and customdesign\MessageBreak
            at the same time.\MessageBreak
            Using the \jjg@useddesign\space selection}\fi}
{\ClassWarning{jj_game}{Bad choice for design, permissible values
   are jeopardy, florida, iceland, hornet, qatar, norway, %
   germany, bahamas, spain. Try again}}
\def\jjInputDesignChoice{%
    \InputIfFileExists{design_\jj@design@choice.def}%
    {\ClassWarning{jj_game}{Inputting design choice \jj@design@choice}}%
    {\ClassWarning{jj_game}{Cannot find the file
        design_\jj@design@choice.def}}%
}
%    \end{macrocode}
% Allow the user to create his own design\IndexOpt{customdesign}. The file \verb!design_\jj@design@choice.def! then is input.
%    \begin{macrocode}
\define@key{jj_game.cls}{customdesign}{%
    \ifx\jjg@madedesignselection0\def\jj@design@choice{#1}%
    \AtEndOfClass{\jjInputDesignChoice}%
    \global\let\jjg@madedesignselection1
    \def\jjg@useddesign{customdesign}\else
    \ClassWarning{jj_game}{Do not use both design and customdesign
    \MessageBreak at the same time.\MessageBreak
    Using the \jjg@useddesign\space selection}\fi}
%    \end{macrocode}
% When the \texttt{nodesigngraphics}\IndexOpt{nodesigngraphics} option is taken,
% the effects of the commands\medskip
%\begin{verbatim}
%   \defineInstructionPageGraphic
%   \defineGameboardPageGraphic
%   \defineQuestionPagesGraphic
%\end{verbatim}
%are cancelled out.
%    \begin{macrocode}
\DeclareOptionX{nodesigngraphics}{\let\jjgdesigngraphics\endinput}
\let\jjgdesigngraphics\relax
%    \end{macrocode}
% Language \opt{lang}\IndexOpt{lang} option, languages supported are \texttt{english} and \texttt{german} options.
%    \begin{macrocode}
\define@choicekey+{jj_game.cls}{lang}[\val\nr]{english,german}
{\xdef\jjLangOpt{\nr}}{\ClassWarning{jj_game}
    {Bad choice for lang, permissible values are english and german.
     Try again.}}
\def\jjLangOpt{0}
%    \end{macrocode}
%
% Look for configuration file
%
%    \begin{macrocode}
\ifpdf\ExecuteOptionsX{pdftex}\else
    \ifxetex\ExecuteOptionsX{xetex}\else
%    \end{macrocode}
%    For backward compatibility, we \cs{let} \cs{ExecuteOptions} to
%    \cs{ExecutedOptionsX}, saving and restoring as we go.
%    \begin{macrocode}
        \let\ExecuteOptions@SAVE\ExecuteOptions
        \let\ExecuteOptions\ExecuteOptionsX
        \InputIfFileExists{jj_game.cfg}{}
        {\@ifundefined{l@tex@@@@driver}{\ExecuteOptionsX{dvips}}
            {\ExecuteOptionsX{dvipsone}}}%
        \let\ExecuteOptions\ExecuteOptions@SAVE
    \fi\fi
%    \end{macrocode}
% \subsection{Process Options}
%    \begin{macrocode}
\ProcessOptionsX
%    \end{macrocode}
% \section{Load the article class}
%    We model the \pkg{jj\_game} class after the \pkg{article} class.
%    \begin{macrocode}
\LoadClass{article}[2014/09/29]
%    \end{macrocode}
%    \section{Required Packages}
%    We do not pass the driver options \texttt{pdftex}, \texttt{luatex}, or \texttt{xetex} to \pkg{web}, because that
%    package detects these drivers as well.
%    \begin{macrocode}
\edef\x{\noexpand
    \RequirePackage[\jjgdriver,usetemplates,dvipsnames]{web}}\x
\RequirePackage[execJS]{eforms}[2016/08/29]
\RequirePackage{verbatim}
\RequirePackage{comment}
\RequirePackage{calc}
%    \end{macrocode}
% If user has chosen the \texttt{final} option, we use hyperref to set the viewer window;
% otherwise we set \verb!\let\JJinitSetup\relax!. The user who is using
% \texttt{aeb\_pro} with \texttt{jj\_game} can use the extensive controls in that package.
%    \begin{macrocode}
\iffinal
    \def\JJinitSetup{%
        \hypersetup{%
            pdfmenubar=false,
            pdftoolbar=false,
            pdffitwindow=true,
            pdfcenterwindow=true,
            pdfwindowui=false%
        }
    }
\else
    \let\JJinitSetup\relax
\fi
\AtEndOfClass{\JJinitSetup}
%    \end{macrocode}
% Process the language option, the default is english
%    \begin{macrocode}
\ifcase\jjLangOpt\relax
    \includecomment{JJLangEnglish}
    \excludecomment{JJLangGerman}
\or
    \includecomment{JJLangGerman}
    \excludecomment{JJLangEnglish}
    \AtEndOfClass{\germanLocalization}
\fi
\@ifundefined{jjImportForCreditCode}
    {\excludecomment{JJForCredit}}
    {\includecomment{JJForCredit}}
%    \end{macrocode}
% \cs{germanLocalization} consists of some definitions that specialize
% certain strings of \texttt{jj\_game}.
%    \begin{macrocode}
\def\germanLocalization{%
    \currencyHeading{\bfseries For~\EUR\theCurrencyAmt:}%
    \correctText{Richtig!}\incorrectText{Falsch!}%
    \def\jb@sepStyle{2}\def\jb@currStyle{0}%
    \def\APScore@Currency@def{"\string\\u20ac"}%
    \printButtonCaption{Drucken}%
    \printButtonLabel{Diese Seite drucken}%
    \contestantNameLabel{Student}%
    \timestampLabel{Zeitstempel}%
    \timeStampFormat{dd/mm/yy, H:MM:ss.}%
    \enterNamePlease{Bitte geben Sie Ihren Namen auf
        der ersten Seite ein, bevor Sie das Spiel beginnen!}
   \def\jb@Score{"Punkte "}
    \illegalAccessMsg{Sie haben gespickelt! Bitte w\string\344hlen
    Sie erst eine Frage vom Spielbrett, bevor Sie umbl\string\344ttern -
    diese Antwort wird nicht gewertet! \string\326ffnen Sie das
    PDF erneut und spielen Sie dieses Mal ohne zu spickeln.}
    \illegalAnswerTwiceMsg{\string\304ndern Ihrer Antwort
    ist nicht erlaubt!}

}
%    \end{macrocode}
% Default color definitions for the Jeopardy game. These will be used
% if no colors are specified.
%    \begin{macrocode}
\definecolor{defaultfillCells}{rgb}{0.98,0.92,0.73}
\def\defaultfillCells{defaultfillCells}
\definecolor{defaultfillBanner}{rgb}{0.5,0,0.5}
\def\defaultfillBanner{defaultfillBanner}
\definecolor{defaulttextBanner}{rgb}{1,1,0} % yellow
\def\defaulttextBanner{defaulttextBanner}
\definecolor{defaulttextBoard}{rgb}{1,1,0} % yellow
\def\defaulttextBoard{defaulttextBoard}
\definecolor{defaultfillInstructions}{rgb}{0.98,0.92,0.73}
\def\defaultfillInstructions{defaultfillInstructions}
\definecolor{defaultfillGameBoard}{rgb}{1,0.8,0.6}
\def\defaultfillGameBoard{defaultfillGameBoard}
\definecolor{defaultfillQuestions}{rgb}{1,0.8,0.6}
\def\defaultfillQuestions{defaultfillQuestions}
\def\defaultDollarColorAmt{blue}
\def\defaultLinkColor{webgreen}
\definecolor{jj_banner_bg}{named}{defaultfillBanner}
\definecolor{jj_banner_txt}{named}{defaulttextBanner}
\def\jj@transparent{transparent}
%    \end{macrocode}
%    \begin{macro}{\bannerTextFont}
%    \begin{macro}{\titleBanner}
% Commands for defining the banner text and font.
%    \begin{macrocode}
\newcommand{\bannerTextFont}{\sffamily\huge}
\def\bannerTextColor{\ifx\textBanner\jj@transparent
    \else\color{\textBanner}\fi}
\def\titleBanner#1{\def\@titleBanner{#1}}
\titleBanner{You are the Winner!}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\insertJJTitleBanner}
% The title banner is displayed on the first page, the text of the first page
% is the content of the \texttt{instructions} environment. If you want more than
% one page of instructions, begin an new page with \cs{newpage}, then insert
% \cs{insertJJTitleBanner} to get the start up banner to appear.
%    \begin{macrocode}
\def\insertJJTitleBanner{\newpage\jb@Banner{\@titleBanner}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\includeFootBanner}
%    \begin{macro}{\authorURL}
% Use \cs{includeFootBanner} to get a matching banner at the foot of the first page.
% The banner contains the author's name and university.  Use \cs{author} and \cs{university}
% from the web package to properly populate this command.  Use it in the preamble.
%    \begin{macrocode}
\newcommand{\includeFootBanner}{%
    \renewcommand{\@oddfoot}
    {%
        \ifnum\thepage=1\relax
        \colorbox{jj_banner_bg}{\makebox[\linewidth-2\fboxsep]{%
        \href{\jjgauthorURL}%
        {\textcolor{jj_banner_txt}{\webauthor\ \copyright\ \the\year}}%
        \hfill\textcolor{jj_banner_txt}{\webuniversity}}}\else\hfil\fi
    }%
}
\newcommand{\authorURL}[1]{\def\jjgauthorURL{#1}}
\authorURL{http://www.example.com}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
% \section{The Main Code}
% Much of the code below was adapted from the web package.
%    \begin{macrocode}
\newdimen\jb@paperheight
\newdimen\jb@tmpdimb
\jb@paperheight=\paperheight
\newdimen\@Leftmargin   \@Leftmargin=0cm
\newdimen\@Rightmargin  \@Rightmargin=0cm
\newdimen\@Topmargin    \@Topmargin=0in
\newdimen\@Bottommargin \@Bottommargin=0in
\parindent0pt
\setlength\headheight{0pt}
\setlength\headsep   {0pt}
\setlength\footskip  {0pt}
\hoffset=0pt
\voffset=0pt
\pagestyle{empty}
\def\InitLayout{%
  \setlength{\textwidth}{\paperwidth}
  \addtolength{\textwidth}{-\@Leftmargin}
  \addtolength{\textwidth}{-\@Rightmargin}
  \setlength{\textheight}{\paperheight}
  \addtolength{\textheight}{-\@Topmargin}
  \addtolength{\textheight}{-\@Bottommargin}
  \addtolength{\textheight}{-\headheight}
  \addtolength{\textheight}{-\headsep}
  \addtolength{\textheight}{-\footskip}
  \setlength{\oddsidemargin}{\@Leftmargin}
  \addtolength{\oddsidemargin}{-1in}
  \setlength{\evensidemargin}{\@Leftmargin}
  \addtolength{\evensidemargin}{-1in}
  \setlength{\topmargin}{\@Topmargin}
  \addtolength{\topmargin}{-1in}
  \setlength{\textscreenwidth}{\paperwidth}
}
\def\screensize#1#2{%
    \paperheight=#1%
    \paperwidth=#2
    \web@set@paper
    \InitLayout
}
\def\marginsize#1#2#3#4{%
    \@Leftmargin=#1
    \@Rightmargin=#2
    \@Topmargin=#3
    \@Bottommargin=#4
    \InitLayout
}
%    \end{macrocode}
% The default margin size
%    \begin{macrocode}
\marginsize{.25in}{.25in}{.25in}{.25in}
\newcount\rownum \rownum=1 % These registers keep track of the row and
\newcount\colnum \colnum=0 % column of the quizboard
\newcount\corMsgnum \corMsgnum=0 % These registers keep track of the
\newcount\errMsgnum \errMsgnum=0 % error messages
\newcount\jb@n
\newcount\jb@m
\newtoks\jb@rowtoks
\newcounter{newletter}
\newdimen\cellHeight \cellHeight=1in
\newdimen\cellWidth  \cellWidth=.5in
\newdimen\tablewidth
\newdimen\tableheight
\newcount\numCategories \numCategories=5
\newcount\numQuestions  \numQuestions=5
\newdimen\rulewidth     \rulewidth=1bp
\newdimen\extraHeight   \extraHeight=.2in
\newdimen\extraWidth    \extraWidth=0pt
%    \end{macrocode}
% Calculate the size of the screen page.
%    \begin{macrocode}
\def\calcPaperSize{%
%    \end{macrocode}
% Calculate paperwidth and \cs{tablewidth}
%    \begin{macrocode}
    \tablewidth=\numCategories\cellWidth
    \advance\tablewidth by \rulewidth
    \advance\tablewidth by \numCategories\rulewidth
    \paperwidth=\tablewidth
    \advance\paperwidth by\@Leftmargin  % two times margin
    \advance\paperwidth by\@Rightmargin % two times margin
    \advance\paperwidth by2\extraWidth  % need more width
%    \end{macrocode}
% Calculate paperheight and \cs{tableheight}
%    \begin{macrocode}
    \tableheight=\numQuestions\cellHeight
    \advance\tableheight by\cellHeight % banner
    \advance\tableheight by2\rulewidth % two rules for banner
    \advance\tableheight by\numQuestions\rulewidth
    \paperheight=\tableheight
    \advance\paperheight by\cellHeight % score
    \advance\paperheight by\@Topmargin
    \advance\paperheight by\@Bottommargin
    \advance\paperheight by\topskip
    \advance\paperheight by\extraHeight
    \screensize{\paperheight}{\paperwidth}
}
\def\verbatimwrite{\bgroup\catcode``=0 \@bsphack
  \let\do\@makeother\dospecials
  \catcode`\^^M\active \catcode`\^^I=12
  \def\verbatim@processline{%
    \immediate\write\verbatim@out
      {\the\verbatim@line}}%
  \verbatim@start}
\def\endverbatimwrite{\@esphack\egroup}
%    \end{macrocode}
% \subsection{Create Design Commands}
%    \begin{macrocode}
\def\jb@linkColor{\defaultLinkColor}
%    \end{macrocode}
%    \begin{macrocode}
\def\jj@setChoice#1#2{% this choice, default
    \ifx#1\@empty#2\else#1\fi}
\def\jj@updateChoice#1#2{%  this choice, current choice
    \ifx#1\@empty\xdef#1{#2}\else\xdef#2{#1}\fi}
%    \end{macrocode}
%    \begin{macro}{\convertToSetKeys}
% We use the \textsf{xkeyval} package to parse the key, but we have a twist: The key-values are
% given in the form of object properties \texttt{<key>:<value>}. The command
% \cs{@convertColoniiEqual} does the work. The way \cs{convertToSetKeys} is used is
% is shown below:
%\begin{verbatim}
%\define@key{dps}{fname}{\def\dpsfname{#1}}
%\define@key{dps}{mname}{\def\dpsmname{#1}}
%\define@key{dps}{lname}{\def\dpslname{#1}}
%\def\setName#1{%
%   \convertToSetKeys{dps}{#1}}
%...
%\setName {
%    fname: D.,
%    mname: P.,
%    lname: Story
%}
%\end{verbatim}
% where \cs{setName} is some command, \texttt{\#1} is the name of the
% \textsf{xkeyval} family to be used, and  \texttt{\#2} are the
% \texttt{<key>:<value>} pairs.
%    \begin{macrocode}
\newtoks\jb@tmptoks \jb@tmptoks={}
\def\jjgdummy{dummy}
\def\convertToSetKeys#1#2{%
    \def\thisxkvFamily{#1}\def\jjg@scratch{}\jb@tmptoks={}%
    \@convertColoniiEqual#2,dummy:dummy,\@nil
}
\def\@convertColoniiEqual#1:#2,#3\@nil{%
    \def\jj@rgii{#2}\ifx\jj@rgii\jjgdummy
    \edef\jj@next{\noexpand\setkeys{\thisxkvFamily}{\the\jb@tmptoks}}%
    \else\jb@tmptoks=\expandafter{\jjg@scratch,#1=#2}%
    \edef\jjg@scratch{\the\jb@tmptoks}%
    \def\jj@next{\@convertColoniiEqual#3\@nil}\fi\jj@next
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\DeclareColors}
% Macro to set the design parameters for LaTeX colors
%    \begin{macrocode}
\define@key{declcolors}{fillCells}[\defaultfillCells]%
    {\def\fillCells{#1}}
\define@key{declcolors}{fillBanner}[\defaultfillBanner]%
    {\def\fillBanner{#1}}
\define@key{declcolors}{textBanner}[\defaulttextBanner]%
    {\def\textBanner{#1}}
\define@key{declcolors}{textBoard}[\defaulttextBoard]%
    {\def\textBoard{#1}}
\define@key{declcolors}{fillInstructions}[\defaultfillInstructions]%
    {\def\fillInstructions{#1}}
\define@key{declcolors}{fillGameBoard}[\defaultfillGameBoard]%
    {\def\fillGameBoard{#1}}
\define@key{declcolors}{fillQuestions}[\defaultfillQuestions]%
    {\def\fillQuestions{#1}}
\define@key{declcolors}{dollarColor}[\defaultDollarColorAmt]%
    {\def\dollarColor{#1}}
\define@key{declcolors}{linkColor}[\defaultLinkColor]%
    {\def\@linkcolor{#1}}
\setkeys{declcolors}{fillCells,fillBanner,textBanner,textBoard,%
    fillInstructions,fillGameBoard,fillQuestions,dollarColor,linkColor}%
\def\DeclareColors#1{\convertToSetKeys{declcolors}{#1}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\APDollar}
% Macro to set the design parameters for the Dollar tile, this is the tile seen
% on the game board showing the monetary amounts of each question. The name of
% this tile is \verb!\the\rownum\the\colnum!, corresponding to the row and column
% position of the tile in the game board.
%    \begin{macrocode}
\def\APDollar@Font@def{TiRo}\def\APDollar@Size@def{20}
\def\APDollar@TextColor@def{0 0 1}\def\APDollar@BorderColor@def{0 0 0}
\def\APDollar@FillColor@def{1 0.35 1}
\define@key{apdollar}{Font}[\APDollar@Font@def]{\def\APDollar@Font{#1}}
\define@key{apdollar}{Size}[\APDollar@Size@def]{\def\APDollar@Size{#1}}
\define@key{apdollar}{TextColor}[\APDollar@TextColor@def]%
    {\def\APDollar@TextColor{#1}}
\define@key{apdollar}{BorderColor}[\APDollar@BorderColor@def]%
    {\def\APDollar@BorderColor{#1}%
    \ifx\APDollar@BorderColor\jj@transparent\gdef\APD@llarBorder{}\else
    \xdef\APD@llarBorder{\APDollar@BorderColor}\fi
}
\define@key{apdollar}{FillColor}[\APDollar@FillColor@def]%
    {\def\APDollar@FillColor{#1}%
    \ifx\APDollar@FillColor\jj@transparent\gdef\APD@llarFill{}\else
    \xdef\APD@llarFill{\APDollar@FillColor}\fi
}
\def\APD@llar{/\APDollar@Font\space\APDollar@Size\space Tf
    \APDollar@TextColor\space rg}
\setkeys{apdollar}{Font,Size,TextColor,BorderColor,FillColor}
\def\APDollar#1{\convertToSetKeys{apdollar}{#1}}
\APDollar{}
%    \end{macrocode}
%    \end{macro}
% A crude euro symbol that can be typeset in \TeX.
%    \begin{macrocode}
\newcommand\EUR{%
{\sffamily C%
\makebox[0pt][l]{\kern-.70em\mbox{--}%
}%
\makebox[0pt][l]{\kern-.68em\raisebox{.25ex}{--}}}\,%
}
%    \end{macrocode}
%    \begin{macro}{\APHidden}
% This collection of key-values set the appearance of the text field whose name
% is \texttt{GrandPoohbah}. It is a hidden text field above the game board
% extending across the list of categories. If the player attains the goal,
% the \texttt{GrandPoohbah} field becomes visible showing the \texttt{Champion} message.
%    \begin{macrocode}
\def\APHidden@Font@def{TiRo}\def\APHidden@Size@def{20}
\def\APHidden@TextColor@def{0 0 1}\def\APHidden@BorderColor@def{0 0 0}
\def\APHidden@FillColor@def{0.98 0.92 0.73}
\def\Champion@def{You are a Champion!}
\define@key{aphidden}{Champion}[\Champion@def]{\def\jb@Champion{#1}}
\define@key{aphidden}{Font}[\APHidden@Font@def]{\def\APHidden@Font{#1}}
\define@key{aphidden}{Size}[\APHidden@Size@def]{\def\APHidden@Size{#1}}
\define@key{aphidden}{TextColor}[\APHidden@TextColor@def]%
    {\def\APHidden@TextColor{#1}}
\define@key{aphidden}{BorderColor}[\APHidden@BorderColor@def]%
    {\def\APHidden@BorderColor{#1}%
    \ifx\APHidden@BorderColor\jj@transparent\gdef\APHidd@nBorder{}\else
    \xdef\APHidd@nBorder{\APHidden@BorderColor}\fi
}
\define@key{aphidden}{FillColor}[\APHidden@FillColor@def]%
    {\def\APHidden@FillColor{#1}%
    \ifx\APHidden@FillColor\jj@transparent\gdef\APHidd@nFill{}\else
    \xdef\APHidd@nFill{\APHidden@FillColor}\fi
}
\def\APHidd@n{/\APHidden@Font\space\APHidden@Size\space Tf
    \APHidden@TextColor\space rg}
\setkeys{aphidden}{Champion,Font,Size,TextColor,BorderColor,FillColor}
\def\APHidden#1{\convertToSetKeys{aphidden}{#1}}
\APHidden{}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\APRight}
% Use this command to set the key-value pairs for the appearance of the push button
% whose name is \verb!\the\rownum\the\colnum R!. When the player answers the question
% correctly, this field, initially hidden, becomes visible with a message of congratulations,
% the default message is \texttt{Right!}
%    \begin{macrocode}
\def\APRight@Font@def{TiRo}\def\APRight@Size@def{20}
\def\APRight@TextColor@def{0 0 1}\def\APRRight@Msg@def{Right!}
\def\correctText#1{\gdef\@APRightMsg{#1}}\correctText{Right!}
\define@key{apright}{Font}[\APRight@Font@def]{\def\APRight@Font{#1}}
\define@key{apright}{Size}[\APRight@Size@def]{\def\APRight@Size{#1}}
\define@key{apright}{TextColor}[\APRight@TextColor@def]%
    {\def\@APRightTextColor{#1}}
\define@key{apright}{Message}[\APRRight@Msg@def]{\def\@APRightMsg{#1}}
\def\@APRight{/\APRight@Font\space\APRight@Size\space Tf
    \@APRightTextColor\space rg}%
\setkeys{apright}{Font,Size,TextColor,Message}
\def\APRight#1{\convertToSetKeys{apright}{#1}}
\APRight{}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\APWrong}
% Use this command to set the key-value pairs for the appearance of the push button
% whose name is \verb!\the\rownum\the\colnum W!. When the player answers the question
% incorrectly, this field, initially hidden, becomes visible with a message,
% the default message is \texttt{Wrong!}
%    \begin{macrocode}
\def\APWrong@Font@def{TiRo}\def\APWrong@Size@def{20}
\def\APWrong@TextColor@def{0 0 1}\def\APRWrong@Msg@def{Wrong!}
\def\incorrectText#1{\gdef\@APWrongMsg{#1}}\incorrectText{Wrong!}
\define@key{apwrong}{Font}[\APWrong@Font@def]{\def\APWrong@Font{#1}}
\define@key{apwrong}{Size}[\APWrong@Size@def]{\def\APWrong@Size{#1}}
\define@key{apwrong}{TextColor}[\APWrong@TextColor@def]%
    {\def\@APWrongTextColor{#1}}
\define@key{apwrong}{Message}[\APRWrong@Msg@def]{\def\@APWrongMsg{#1}}
\def\@APWrong{/\APWrong@Font\space\APWrong@Size\space Tf
    \@APWrongTextColor\space rg}
\setkeys{apwrong}{Font,Size,TextColor,Message}
\def\APWrong#1{\convertToSetKeys{apwrong}{#1}}
\APWrong{}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\GameDesign}
% Use this command to set the key-value pairs for designing the game board. Setting
% these values are required for each game. There are default values, but the key-values
% that are required to be filled is are \texttt{Cat}, and \texttt{NumQuestions}. The number of Cat entries
% determines the number of categories, and \texttt{NumQuestions} determines the number of questions
% in each category.
%    \begin{macrocode}
\define@key{gamedesign}{Cat}{\global\advance\numCategories by1
    \jb@Cat#1,}
\define@key{gamedesign}{CellWidth}[1in]{\global\cellWidth=#1\relax}
\define@key{gamedesign}{CellHeight}[.5in]{\global\cellHeight=#1\relax}
\define@key{gamedesign}{NumQuestions}[5]{\global\numQuestions=#1\relax}
\define@key{gamedesign}{Goal}[3500]{\def\jb@Goal{#1}}
\define@key{gamedesign}{GoalPercentage}[0]{\def\jb@GoalPercentage{#1}}
\define@key{gamedesign}{ExtraHeight}[.2in]{\global\extraHeight=#1\relax}
\define@key{gamedesign}{ExtraWidth}[0pt]{\global\extraWidth=#1\relax}
\define@key{gamedesign}{Champion}[\Champion@def]{\def\jb@Champion{#1}}
\setkeys{gamedesign}{CellWidth,CellHeight,NumQuestions,Goal,%
    GoalPercentage,ExtraHeight,ExtraWidth,Champion}
%    \end{macrocode}
% Here is the code for \cs{GameDesign}, after gathering the key-value pairs for
% the \texttt{gamedesign} family. We set the \texttt{Goal} (if \texttt{GoalPercentage} is specified),
% then, based on the parameters, we calculate the page size for this game board.
%    \begin{macrocode}
\def\GameDesign#1{\global\numCategories=0\relax
    \convertToSetKeys{gamedesign}{#1}%
    \ifdebug
        \typeout{^^JClass jj_game Info:}
        \typeout{Number of Categories: \the\numCategories}
        \typeout{Number of Questions per Category: \the\numQuestions^^J}
    \fi
%    \end{macrocode}
%\begin{verbatim}
%   Let n = numQuestions, m = numCategories
%   100*n*(n+1)/2 = 50*n*(n+1) = total for one category
%   50*m*n*(n+1) = total money;
%   100*m*n*(n+1) = total money for double jeopardy
%\end{verbatim}
%    \begin{macrocode}
        \jb@n = \numQuestions
        \advance\jb@n by 1
        \multiply\jb@n by\numQuestions
        \multiply\jb@n by50                 % total money/category
        \multiply\jb@n by\numCategories     % total money
        \ifdouble
            \multiply\jb@n by2              % total money, double jj
        \fi
        \ifdebug
            \typeout{Total Money: \the\jb@n}
        \fi
        % See if GoalPercentage differs from the default value
        \xdef\jb@tmp{\csname 0\endcsname}%
        \xdef\jb@temp{\csname\jb@GoalPercentage\endcsname}%
        \ifx\jb@tmp\jb@temp
        \else
            \ifdebug
                \typeout{Goal Percentage Specified: \jb@GoalPercentage}
            \fi
            \multiply\jb@n by\jb@GoalPercentage
            \divide\jb@n by100
            \def\jb@Goal{\the\jb@n}
        \fi
        \xdef\Goal{\jb@Goal}
        \ifdebug
            \typeout{Goal: \Goal^^J}
        \fi
    \calcPaperSize
    \jjCancelOutAeBProCatalog
    \jjImportForCreditCode
}
\def\jjCancelOutAeBProCatalog{\iffinal\let\aeb@SetCatalog\@empty\fi}
\def\jb@Cat{\@ifnextchar[{\jb@item}{\jb@item[] }}%
\gdef\jb@item[#1]#2,{%
    \expandafter\gdef\csname Category\the\numCategories\endcsname
        {\forpbx{#1#2}}%
    \expandafter\gdef\csname category\the\numCategories\endcsname{#2}%
}%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\APScore}
% The \cs{APScore} command sets the key-value pairs for designing the score board. There
% are three score boards: for a single player, the name of the field is \texttt{Total};
% for the two player game, the names of the fields are \texttt{Total0} and \texttt{Total1}.
%    \begin{macrocode}
\def\jb@Score{""}
\def\jb@align@left{l}
\def\jb@align@center{c}
\def\jb@align@right{r}
\def\APScore@Font@def{TiRo}
\def\APScore@Size@def{20}
\def\APScore@TextColor@def{0 0 1}
\def\APScore@BorderColor@def{0 0 0}
\def\APScore@FillColor@def{0.98 0.92 0.73}
\def\APScore@CellHeight@def{\the\cellHeight}
\def\APScore@CellWidth@def{\the\cellWidth}
\def\APScore@AutoPlacement@def{true}
\def\APScore@Score@def{""}
\def\APScore@Currency@def{""}
\def\APScore@align@def{r}
\def\jb@align{r}
%
% twoplayer properties
%
\def\APScore@tp@ScaledCellWidth@def{.5}
\let\APScore@tp@ScaledCellWidth\@empty
\def\APScore@tp@HighlightBorderColor@def{1 0 0}
%
\define@key{apscore}{Font}[\APScore@Font@def]{\def\APScore@Font{#1}}
\define@key{apscore}{Size}[\APScore@Size@def]{\def\APScore@Size{#1}}
\define@key{apscore}{TextColor}[\APScore@TextColor@def]%
    {\def\APScore@TextColor{#1}}
\define@key{apscore}{BorderColor}[\APScore@BorderColor@def]%
    {\def\APScore@BorderColor{#1}%
    \ifx\APScore@BorderColor\jj@transparent\gdef\@APScoreBorder{}\else
    \xdef\@APScoreBorder{\APScore@BorderColor}\fi
}
\define@key{apscore}{FillColor}[\APScore@FillColor@def]%
    {\def\APScore@FillColor{#1}%
    \ifx\APScore@FillColor\jj@transparent\gdef\@APScoreFill{}\else
    \xdef\@APScoreFill{\APScore@FillColor}\fi
}
\define@key{apscore}{CellHeight}[\APScore@CellHeight@def]%
    {\def\@APScorecellHeight{#1}}
\define@key{apscore}{CellWidth}[\APScore@CellWidth@def]%
    {\def\@APScorecellWidth{#1}}
\define@boolkey{apscore}{AutoPlacement}[true]{}
\define@key{apscore}{Score}[\APScore@Score@def]{\def\jb@Score{#1}}
\define@key{apscore}{Currency}[\APScore@Currency@def]%
    {\def\jb@Currency{#1}}
\define@key{apscore}{align}[\APScore@align@def]{\def\jb@align{#1}}
%
% twoplayer properties
%
\define@key{apscore}{tpScaledCellWidth}%
    [\APScore@tp@ScaledCellWidth@def]%
    {\def\@APtpScaledCellWidth{#1}}
\define@key{apscore}{tpHighlightBorderColor}
    [\APScore@tp@HighlightBorderColor@def]%
    {\def\@APtpHighlightBorderColor{#1}}
\def\@APScore{/\APScore@Font\space\APScore@Size\space Tf
    \APScore@TextColor\space rg}%
%
\setkeys{apscore}{Font,Size,TextColor,BorderColor,FillColor,%
    CellHeight,CellWidth,AutoPlacement,Score,Currency,align,%
    tpScaledCellWidth,tpHighlightBorderColor}
%
\def\APScore#1{\convertToSetKeys{apscore}{#1}%
    \ifKV@apscore@AutoPlacement
        \gdef\@PlaceScoreBoard{\@@PlaceScoreBoard}
        \gdef\PlaceScoreBoard##1{%
        \message{^^J\expandafter\string\csname APScore\endcsname:
        `AutoPlacement: true', the use of \string\PlaceScoreBoard\space
        is not valid in this case!^^J^^J}}%
    \else
        \gdef\@PlaceScoreBoard{\@@@PlaceScoreBoard\@gobble}%
    \fi
    \gdef\jb@Quad{2}%
    \ifx\jb@align\jb@align@left\gdef\jb@Quad{0}%
    \else\ifx\jb@align\jb@align@center\gdef\jb@Quad{1}%
    \else\ifx\jb@align\jb@align@right\gdef\jb@Quad{2}%
    \fi\fi\fi
}
\APScore{}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\PlaceScoreBoard}
% A command for the user to place the location of the score board.
%    \begin{macrocode}
\def\@@PlaceScoreBoard#1{#1}
\long\def\PlaceScoreBoard#1{\def\@@@PlaceScoreBoard{#1}}
\PlaceScoreBoard{{\centering\vbox{\ScoreBoard}}}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\setTwoPlayerOptions}
% The following are key-value definitions for the two player game
%    \begin{macrocode}
\define@key{twoplayerKeys}{player1}[Player 1]{\def\jjg@playeri{#1}}
\define@key{twoplayerKeys}{player2}[Player 2]{\def\jjg@playerii{#1}}
\define@key{twoplayerKeys}{playerFmt}[\sffamily\small]%
    {\def\jjg@playerFmt{#1}}
\define@boolkey{twoplayerKeys}{checkbox}[true]{}
\setkeys{twoplayerKeys}{player1,player2,playerFmt,checkbox}
\newcommand{\setTwoPlayerOptions}[1]{%
    \convertToSetKeys{twoplayerKeys}{#1}}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macrocode}
\def\Rect#1{\pdf@rect{\textcolor{\@linkcolor}{#1}}}
\def\({\noexpand\(}\def\){\noexpand\)}
\def\Bbox#1#2{%
    \vbox to#2{\hbox to#1{\hfill}\vfill}%
}
\def\hmark#1{\hypertarget{#1}{}}
%    \end{macrocode}
%    \begin{macro}{\bannerTextControl}
% Use \cs{bannerTextControl} to tweak the positioning of the banner text.
%    \begin{macrocode}
\newcommand{\bannerTextControl}[1]{#1}
%    \end{macrocode}
%    \end{macro}
% Construct the running banners
%    \begin{macrocode}
\def\jb@Banner#1{\vspace*{-\topskip}\hbox{\rlap{\ifx\fillBanner
    \jj@transparent\else\color{\fillBanner}\fi
    \setbox0=\hbox{\bannerTextFont\strut}\jb@tmpdimb=\ht0
    \advance\jb@tmpdimb by6pt \jb@tmpdima=\dp0 \advance\jb@tmpdima by4pt
    {\ifx\fillBanner\jj@transparent\else
    \vrule height\jb@tmpdimb depth\jb@tmpdima width\textwidth\fi}}%
    \vbox{\noindent\centering\bannerTextFont\bannerTextColor%
        \strut\bannerTextControl{#1}}}\bigskip}
%    \end{macrocode}
%
% \subsection{Construct form fields}
% This appearance is the opening face.  Show dollar amounts. Clicking
% jumps to the corresponding question.
%    \begin{macrocode}
\def\dollarAP{%
{\ifdouble\advance\rownum by\rownum\fi\xdef\@dollarAmt{\the\rownum00}}%
\rlap{\pushButton[%
    \H{P}\W{1}\S{S}\DA{\APD@llar}\BC{\APD@llarBorder}
    \BG{\APD@llarFill}\CA{\@dollarAmt}
    \A{/S/GoTo/D (Q\the\rownum\the\colnum) \jjAdditionalCellJSActions}
]{\the\rownum\the\colnum}{\cellWidth}{\cellHeight}}}
%    \end{macrocode}
% This appearance simply says Right!  It appears if the user answers the
% question correctly.
%    \begin{macrocode}
\def\rightAP{\rlap{\efKern{0pt}{1bp}\pushButton[%
    \F{\FHidden}\H{N}\S{S}\BG{}\DA{\@APRight}\CA{\@APRightMsg}
]{\the\rownum\the\colnum R}{\cellWidth}{\cellHeight}}}
%    \end{macrocode}
% This appearance simply says Wrong!  It appears if the user answers the
% question incorrectly.
%    \begin{macrocode}
\def\wrongAP{\rlap{\efKern{0pt}{2bp}\pushButton[%
    \F{\FHidden}\H{N}\S{S}\BG{}\DA{\@APWrong}\CA{\@APWrongMsg}
]{\the\rownum\the\colnum W}{\cellWidth}{\cellHeight}}}
%    \end{macrocode}
%    \begin{macrocode}
\def\jb@nDec{0}
\def\jb@sepStyle{0}
\def\jb@negStyle{0}
\def\jb@currStyle{2}
\def\jb@Currency{""}
\def\jb@bCurrencyPrepend{true}
%    \end{macrocode}
%    \begin{macro}{\prependCurrency}
%    \begin{macro}{\appendCurrency}
% Use these to prepend, the default, or append a currency symbol, if any. These
% will appear in the \cs{ScoreBoard}.
%    \begin{macrocode}
\newcommand{\prependCurrency}{\def\jb@bCurrencyPrepend{true}}
\newcommand{\appendCurrency}{\def\jb@bCurrencyPrepend{false}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\ScoreBoard}
% This is the text field for the score board. In two player mode, there are
% two score boards, and in single player mode, there is only one.
%    \begin{macrocode}
\def\AAVAction{event.target.textColor = event.value < 0 ?
  "RGB \@APWrongTextColor".split(" ") :
  "RGB \@APRightTextColor".split(" ");\r
  this.dirty=false;}
\def\AAFAction{AFNumber_Format\(\jb@nDec, \jb@sepStyle, \jb@negStyle,
    \jb@currStyle, \jb@Currency, \jb@bCurrencyPrepend\);
    event.value = \jb@Score\space + event.value;\r
    this.dirty=false;}
\let\jjgplayerihook\@empty
\let\jjgplayeriihook\@empty
\def\ScoreBoard{\ifjjgtwoplayer
\setlength{\@tempdima}{\@APScorecellWidth}%
\setlength{\@tempdima}{%
    (\@APScorecellWidth)*\ratio{\@APtpScaledCellWidth\space pt}{1pt}}%
\ifdim\@tempdima<\cellWidth
\@tempdima=\cellWidth\fi
    \edef\BboxWidth{\the\@tempdima}%
\setlength{\@tempdima}{\@APScorecellHeight/2-4bp}%
   \edef\BboxHeight{\the\@tempdima}%
\ifKV@twoplayerKeys@checkbox
\raisebox{\BboxHeight}{\checkBox[\Ff{\FfReadOnly}%
    \textColor{\@APtpHighlightBorderColor\space rg}\BC{}%
    \symbolchoice{circle}]{ckboxPlayer0}{10bp}{10bp}{On}}\fi\space
\parbox[t]{\BboxWidth\ifxetex+4bp\fi}{\jjgplayerihook
\textField[%
    \H{N}\Q{\jb@Quad}\W{3}\S{I}\BC{\@APScoreBorder}\BG{\@APScoreFill}%
    \DA{\@APScore}\autoCenter{n}\AA{\AAValidate{\AAVAction}%
    \AAFormat{\AAFAction}}]{Total0}{\BboxWidth\ifxetex-4bp\fi}%
    {\@APScorecellHeight\ifxetex-4bp\fi}\\[-3pt]
\makebox[\linewidth][c]{\jjg@playerFmt\jjg@playeri}}\efKern{3pt}{0bp}\space
\parbox[t]{\BboxWidth\ifxetex+4bp\fi}{%
\textField[%
    \H{N}\Q{\jb@Quad}\W{3}\S{I}\BC{\@APScoreBorder}\BG{\@APScoreFill}%
    \DA{\@APScore}\autoCenter{n}\AA{\AAValidate{\AAVAction}%
    \AAFormat{\AAFAction}}%
]{Total1}{\BboxWidth\ifxetex-4bp\fi}%
    {\@APScorecellHeight\ifxetex-4bp\fi}\jjgplayeriihook\\[-3pt]
\makebox[\linewidth][c]{\jjg@playerFmt\jjg@playerii}}
\ifKV@twoplayerKeys@checkbox
\raisebox{\BboxHeight}{\checkBox[\Ff{\FfReadOnly}%
    \textColor{\@APtpHighlightBorderColor\space rg}\BC{}%
    \symbolchoice{circle}]{ckboxPlayer1}{10bp}{10bp}{On}}\fi
\else\efKern{0pt}{-3bp}\textField[%
    \H{N}\Q{\jb@Quad}\W{3}\S{I}\BC{\@APScoreBorder}%
    \BG{\@APScoreFill}\DA{\@APScore}\autoCenter{n}%
    \AA{\AAValidate{\AAVAction}\AAFormat{\AAFAction}}%
]{Total}{\@APScorecellWidth\ifxetex-4bp\fi}%
    {\@APScorecellHeight\ifxetex-4bp\fi}%
\fi}
%    \end{macrocode}
%    \end{macro}
% The pdf contents of a number rectangle: Three widgets superimposed
%    \begin{macrocode}
\def\cell{\global\advance\colnum1 \ifnum\colnum>\numCategories
    \global\colnum=1 \global\advance\rownum1 \fi
    \moveleft.5\cellWidth\hbox{\efKern{0pt}{-1bp}\dollarAP
        \efKern{0pt}{-1bp}\rightAP\efKern{0pt}{-1bp}\wrongAP}}%
%    \end{macrocode}
% This provides the background color behind the banner
%    \begin{macrocode}
\def\bgb{\ifxetex\rule{0pt}{\cellHeight+.6bp}\smash{\PoohBahBanner}\else
    \PoohBahBanner\fi\smash{\rlap{\ifx\fillBanner\jj@transparent\else
    \ifxetex\setlength{\tablewidth}{\tablewidth}%
    \setlength{\cellHeight}{\cellHeight\ifxetex+.4pt\fi}\fi
    \color{\fillBanner}{\vrule width\tablewidth height\cellHeight}\fi}}}
%    \end{macrocode}
% This provides the background color behind the number board.
%    \begin{macrocode}
\def\bgc{\smash{\rlap{{\ifx\fillCells\jj@transparent\else
    \color{\fillCells}\vrule width\tablewidth height\cellHeight\fi}}}}
%    \end{macrocode}
% The hidden banner set by \cs{APHidden} with the final message for the
% contestant attaining the goal.
%    \begin{macrocode}
\def\PoohBahBanner{\rlap{\ifxetex\advance\tablewidth-6bp\else
    \advance\tablewidth-2bp\hskip1bp\fi
\textField[%
    \Q{1}\autoCenter{n}\F{\FHidden}\W{3}\S{I}\BC{\APHidd@nBorder}%
    \BG{\APHidd@nFill}\DA{\APHidd@n}%
    \DV{\jb@Champion}\V{\jb@Champion}%
]{GrandPoohbah}{\tablewidth}{\cellHeight}}}
%    \end{macrocode}
%    \begin{macrocode}
\def\forpbx#1{\vbox to\cellHeight{%
  \hsize=\cellWidth\centering\vfill\strut\ifx\textBoard\jj@transparent
  \else\color{\textBoard}\fi#1\strut\vfill}}
\def\gameCategories{%
  \jb@n=0
  \jb@rowtoks={\bgb}%
  \loop\ifnum\jb@n<\numCategories\advance\jb@n by1
    \jb@tmptoks=\expandafter{%
        \expandafter&\csname Category\the\jb@n\endcsname&}%
    \edef\jb@temp{\the\jb@rowtoks\the\jb@tmptoks}%
    \jb@rowtoks=\expandafter{\jb@temp}%
  \repeat
  \edef\jb@temp{\the\jb@rowtoks}%
  \jb@rowtoks=\expandafter{\jb@temp\cr\\ }%
\the\jb@rowtoks}

% Hack a loop structure so I can do a double loop
\long\def\oloop #1\orepeat{%
  \def\oiterate{#1\relax  % Extra \relax
  \expandafter\oiterate\fi}%
  \oiterate
  \let\outeriterate\relax
}
\let\orepeat=\fi
%    \end{macrocode}
%    \begin{macrocode}
\def\gamebody{%
  \jb@rowtoks={}%
  \jb@m=\numQuestions
  \edef\jb@temp{}%
  \oloop\advance\jb@m-1\ifnum\jb@m>0
    \getrow
  \orepeat
  \the\jb@rowtoks}
%    \end{macrocode}
%    \begin{macrocode}
\def\getrow{%
  \jb@n=\numCategories
  \edef\jb@temp{\the\jb@rowtoks}%
  \jb@rowtoks=\expandafter{\jb@temp\bgc}%
  \loop\advance\jb@n-1\ifnum\jb@n>0
    \edef\jb@temp{\the\jb@rowtoks}%
    \jb@rowtoks=\expandafter{\jb@temp&\cell&}%
  \repeat
  \edef\jb@temp{\the\jb@rowtoks}%
  \jb@rowtoks=\expandafter{\jb@temp\cr\\ }%
}
%    \end{macrocode}
% \subsection{Construct Game Board}
% The \cs{GameBoard} is as the name suggests is the game board. We set up a
% tabular environment, then insert the \cs{gameCategories}, followed by
% the \cs{gamebody}.
%    \begin{macrocode}
\def\GameBoard{\vspace*{-\topskip}%
\begingroup
  % set up \halign environment
  \tabskip0pt\offinterlineskip\parskip0pt\parindent0pt
  \def\\{\noalign{\hrule height\rulewidth}}%
  \hbox to\textwidth\bgroup\hfill
    \vbox\bgroup\hsize=\tablewidth\hmark{GameBoard}%
      \halign{##\vrule width\rulewidth
        &&\hbox to\cellWidth{\hss\vbox to\cellHeight{\vss##\vss}\hss}%
        &\vrule width\rulewidth##\cr\noalign{\hrule height\rulewidth}%
        % Begin entering data into the different cells
        \gameCategories
        \gamebody
      }%
    \egroup\hfill
  \egroup
\endgroup\ifxetex\ifjjgtwoplayer\kern-1bp\else
    \kern2bp\fi\fi
%    \end{macrocode}
% Insert ScoreBoard
%    \begin{macrocode}
\@PlaceScoreBoard{{\centering\vbox{\ScoreBoard}}}%
\par\JJ@afterGameBoardInsertion}
\let\JJ@afterGameBoardInsertion\@empty
%    \end{macrocode}
%    \begin{macro}{\afterGameBoardInsertion}
% Use this command to insert material below the score board (hence below the game board).
%    \begin{macrocode}
\newcommand{\afterGameBoardInsertion}[1]{%
    \def\JJ@afterGameBoardInsertion{#1}}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{Begin Asking Questions}
%
%    \begin{environment}{instructions}
% The Instructions on first page.
%    \begin{macrocode}
\def\instructions
{%
    \instructionPageTemplate
    \ifx\fillInstructions\jj@transparent\else
        \textBgColor{\fillInstructions}\fi
    \jb@Banner{\@titleBanner}\par\parskip6pt
}
\def\endinstructions{\newpage}
%    \end{macrocode}
%    \end{environment}
%    \begin{macrocode}
\let\Question\relax
%    \end{macrocode}
%    \begin{environment}{Questions}
% The \texttt{Questions} environment contains the \texttt{Category} environment
% which, in turn, contains the \texttt{Questions} environments.
%    \begin{macrocode}
\def\Questions{\newpage\parskip0pt\relax\global\jb@n=0\relax
  \gameboardPageTemplate
  \ifx\fillGameBoard\jj@transparent\else
  \textBgColor{\fillGameBoard}\fi\GameBoard
  \newpage\ifx\fillQuestions\jj@transparent\else
  \textBgColor{\fillQuestions}\fi
  \rownum=0 \colnum=1 % initialize counters
  \questionPagesTemplate
}
\def\endQuestions{%
    \ifnum\jb@n=\numCategories\else
        \typeout{Number of categories is not correct!}
    \fi
    \newpage}
%    \end{macrocode}
%    \end{environment}
%    \begin{environment}{Category}
% The \texttt{Category} environment is nested within the \texttt{Questions} environment.
%    \begin{macrocode}
\def\Category#1{
    \def\currentCategory{#1}\global\advance\jb@n by1 \global\jb@m=0
    \ifdebug
    \typeout{^^JBegin Processing Category \the\jb@n: \currentCategory}
    \typeout{If '\currentCategory' is different from}
    \typeout{'\csname category\the\jb@n\endcsname',
            then your categories are out of order!}
    \fi}
\def\endCategory{
    \ifdebug
        \ifnum\jb@m=\numQuestions
        \else
            \typeout{In the '\currentCategory' category,
            the number of questions is not correct!}
        \fi
        \typeout{End Processing Category \the\jb@n:
        \the\jb@m\space of \the\numQuestions\space Questions}
    \fi
}
%    \end{macrocode}
%    \end{environment}
%    \begin{macrocode}
\let\jjAdditionalJSActions\@empty
\def\jjAdditionalCellJSActions{\Next{\JS{%
    var pushCell\the\rownum\the\colnum = true;\r
    makeNameReadOnly();}}}
\let\bJJGInsertLayer\@empty
\let\eJJGInsertLayer\@empty
%    \end{macrocode}
%    \begin{macro}{\theCurrencyAmt}
%    \begin{macrocode}
\def\theCurrencyAmt{{\count0=\the\rownum00\relax
    \multiply\count0by\scaleFactor\relax\the\count0\relax}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\aboveCurrencySkip}
%    \begin{macrocode}
\def\aboveCurrencySkip#1{\def\jj@aboveCurrencySkip{#1}}
\aboveCurrencySkip{0pt}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\currencyHeading}
%    \begin{macrocode}
\newcommand{\currencyHeading}[1]{\def\jj@currencyHeading{#1}}
\currencyHeading{\bfseries For~\$\theCurrencyAmt:}
%    \end{macrocode}
%    \end{macro}
%    \begin{environment}{Question}
% The environment for posing a question. It must appear within a \texttt{Category} environment.
%    \begin{macrocode}
\def\Question{\newpage\global\advance\jb@m by1
  \global\advance\rownum1 \ifnum\rownum>\numQuestions \global\rownum=1
  \global\advance\colnum1 \fi
  \global\advance\corMsgnum1 \ifnum\corMsgnum=8 \global\corMsgnum=1 \fi
  \edef\peekingOpenAction{\ifjjnopeeking/H true/S/Hide%
    /T (\the\rownum\the\colnum)\else\JS{;}\fi}%
  \ifcase\thejjgdriver
    \immediate\pdfobj{<< /O <<
        \peekingOpenAction\space\jjAdditionalJSActions >> >> }
    \edef\ThisPage{/AA \the\pdflastobj\space 0 R}
    \global\pdfpageattr=\expandafter{\ThisPage}%
  \or
    \literalps@out{%
         [ {ThisPage} << /AA << /O <<
            \peekingOpenAction\space\jjAdditionalJSActions >> >> >>
        /PUT pdfmark}%
  \or
    \@pdfm@mark{put @thispage << /AA << /O <<
        \peekingOpenAction\space\jjAdditionalJSActions >> >> >>}%
  \fi
  \jb@Banner{\csname category\the\colnum\endcsname}%
  \begingroup
  \vskip\jj@aboveCurrencySkip
  \parskip2pt
  \setcounter{newletter}{0}%
  \hmark{Q\the\rownum\the\colnum}\bJJGInsertLayer%
  \@ifnextchar[%
    {\let\Ans\Question@tabular\def\endQuestion{\end{tabular}%
     \eJJGInsertLayer\endgroup\newpage}\getBracArg}%
    {\let\Ans\Question@list\def\jb@numCols{1}\gdef\aeb@numCols{1}%
     \noindent\textcolor{\dollarColor}{\jj@currencyHeading}\space
     \ignorespaces%
     \def\endQuestion{\end{list}\eJJGInsertLayer\endgroup\newpage}}%
}
%    \end{macrocode}
%    \end{environment}
%    \begin{macrocode}
\def\getBracArg[#1]{\def\jb@numCols{#1}\gdef\aeb@numCols{#1}\noindent%
    \textcolor{\dollarColor}{\jj@currencyHeading}\space\ignorespaces}
%    \end{macrocode}
% \cs{jjgtmplength} is a scratch length register that can be used to calculate lengths.
%    \begin{macrocode}
\newlength{\jjgtmplength}
%    \end{macrocode}
%    \begin{macrocode}
\newlength\jb@width \settowidth{\jb@width}{\normalfont(d)}
\newdimen\jb@tmpdima
\newlength\jb@tmplength
\providecommand\PBS[1]{\let\jb@temp=\\#1\let\\=\jb@temp}
\def\makelink#1{%
\setLink[\A{\JS{qbrespond(#1,\the\rownum,\the\colnum);}
        \Next{/S/GoTo/D (GameBoard)}}
    ]{\makebox[\jb@width]{\normalfont(\hfil\alph{newletter}\hfil)\hfill}}}
%    \end{macrocode}
%    \begin{macro}{\setMClabelsep}
% \changes{v3.0}{2006/18/06}
% {
%   Added control over the separation between the MC label and subsequent text:
%   \cs{setMClabelsep} and \cs{resetMClabelsep}.
% }
%    \begin{macro}{\resetMClabelsep}
%    \begin{macro}{\eq@hspanner}
%    \begin{macro}{\eq@hspanner@default}
%   Added control over the separation between the MC label and subsequent text:
%   \cs{setMClabelsep} and \cs{resetMClabelsep}.
%    \begin{macrocode}
\def\eq@hspanner{\ }
\def\eq@hspanner@default{\ }
\def\eq@lw@l{\eq@l@l\eq@hspanner}
\def\setMClabelsep#1{\def\eq@hspanner{#1}}
\def\resetMClabelsep{\let\eq@hspanner\eq@hspanner@default}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macrocode}
\newskip\aboveanswersSkip
\setlength\aboveanswersSkip{3pt}
\def\Question@list{\vskip\aboveanswersSkip
\begin{list}{}%
{\usecounter{newletter}
   \let\Ans=\JJ@Ans@list
   \settowidth{\jb@tmplength}{\normalfont(d)}%
   \settowidth{\labelwidth}{\normalfont(d)\eq@hspanner}%
   \setlength{\parsep}{0pt}\setlength{\itemindent}{0pt}%
   \setlength{\listparindent}{\parindent}%
   \setlength{\leftmargin}{\labelwidth}%
   \setlength{\labelsep}{0pt}%
}\Ans}%
\def\JJ@Ans@list#1{\stepcounter{newletter}\item[\makelink{#1}\hfill]}%

\def\Question@tabular{%
   \vskip\aboveanswersSkip
   \setcounter{newletter}{0}%
   \let\Ans=\JJ@Ans@tabular
   \jb@tmpdima=\linewidth \divide\jb@tmpdima by\jb@numCols
   \vskip\partopsep
   \noindent\normalbaselines\tabcolsep=0pt
   \begin{tabular}{*{\jb@numCols}{p{\jb@tmpdima}}}%
\Ans}
\def\JJ@Ans@tabular#1{\leavevmode\stepcounter{newletter}%
  \PBS\raggedright
  \settowidth{\jb@tmplength}{\normalfont(d)\eq@hspanner}%
  \hangindent=\jb@tmplength\hangafter=1 %
  \makelink{#1}\eq@hspanner\ignorespaces
}
%    \end{macrocode}
%    \begin{environment}{oAnswer}
% If \textsf{exerquiz} is input, then you can pose fill in questions. Enclose
% the standard exerquiz fill in commands \cs{RespBoxMath} and \cs{RespBoxTxt}
%    \begin{macrocode}
\newenvironment{oAnswer}
{%
    \gdef\oField{oQ\the\rownum\the\colnum}%
    \gdef\curr@quiz{oQ\the\rownum\the\colnum}%
    \def\currQuiz{oQ\the\rownum\the\colnum}%
    \let\@qzsolndest\@empty
    \stepcounter{questionno}%
    \let\eqQuizType=s\gdef\eqPTs{1}\global\let\eqQT=\eq@na
    \let\solution=\solution@sq
    \let\endsolution=\endsolution@sq
    \global\let\Ans=\Question@list
%    \end{macrocode}
%    \changes{v3.1}{2016/11/23}{Added \string\cs{sq@IDTxtField} to conform to new exerquiz standards}
%    (2016/11/23) Added \cs{sq@IDTxtField} to conform to new \textsf{exerquiz} standards.
%    \begin{macrocode}
    \gdef\endQuestion{\endgroup\newpage}\sq@IDTxtField
}{}
%    \end{macrocode}
%    \end{environment}
% We need to redefine the action of \cs{RespBoxMath} and \cs{RespBoxTxt} so they behave like you
% would expect with \texttt{jj\_game}.
%    \begin{macrocode}
\def\JJ@@RespBoxMathActions
{%
    \AA{\AAKeystroke{if(event.willCommit) {\r\t
            var retn = \processJSfunc(\rbArgs,\compareJSfunc);\r
            if ( retn != null ) {\r\t
                qbrespond(retn,\the\rownum,\the\colnum)\r\t
                this.gotoNamedDest("GameBoard");\r
            }
        }}%
        \AAFormat{\eqFormatArg}%
        \AAOnFocus{\JS{var retn = null;}}%
    }
}
\def\JJ@@RespBoxTxtActions
{%
    \AA{\AAKeystroke{if(event.willCommit) {\r\t
        retn = ProcRespTxt(\rbTxtAlt);\r
        if ( retn != null ) {\r\t
            qbrespond(retn,\the\rownum,\the\colnum)\r\t
            this.gotoNamedDest("GameBoard");\r
        }
    }}%
    \AAOnFocus{\JS{var retn = null;}}
    }%
}
\def\redefineRespBoxActions{%
    \let\@@RespBoxMathActions\JJ@@RespBoxMathActions
        \let\@@RespBoxTxtActions\JJ@@RespBoxTxtActions}
%    \end{macrocode}
%    \begin{macro}{\gameboardPrintButton}
%    \begin{macro}{\printButtonEOL}
%    \begin{macro}{\printButtonCaption}
%    \begin{macro}{\printButtonLabel}
%    \begin{macro}{\contestantNameLabel}
%    \begin{macro}{\timestampLabel}
% We define a button to print the game board page, and a lot of
% helper commands that allow the author to this button field.
%    \begin{macrocode}
\newcommand{\printButtonCaption}[1]{\def\jj@printButtonCaption{#1}}
\printButtonCaption{Print}
\newcommand{\printButtonLabel}[1]{\def\jj@printButtonLabel{#1}}
\printButtonLabel{Print this page:}
\newcommand{\contestantNameLabel}[1]{\def\jjg@contestantNameLabel{#1}}
\contestantNameLabel{Student:}
\newcommand{\timestampLabel}[1]{\def\jjg@timestampLabel{#1}}
\timestampLabel{Time stamp:}
\newcommand{\printButtonEOL}[1]{\def\jjg@printButtonEOL{#1}}
\printButtonEOL{\\[1ex]}
\newcommand{\gameboardPrintButton}[1][]
{%
    \jj@printButtonLabel\space\pushButton[\CA{\jj@printButtonCaption}
    \A{\JS{%
        var pp = this.getPrintParams();\r
        pp.firstPage=this.pageNum;\r
        pp.lastPage=this.pageNum;\r
        pp.pageHandling = pp.constants.handling.shrink;\r
        var fv = pp.constants.flagValues;\r
        pp.flags |= (fv.suppressCenter | fv.suppressRotate);\r
        this.print(pp);}}#1]{printit}{}{11bp}\quad
        \jjg@contestantNameLabel\space\textField[\BC{}\Ff\FfReadOnly
            ]{jjContestantNameprint}{1.5in}{11bp}\jjg@printButtonEOL
        \jjg@timestampLabel\space\textField[\BC{}\Ff\FfReadOnly
            ]{timestamp}{1.5in}{11bp}%
}%
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\contestantName}
% A convenience macro that can be used to enter the contestant's name.
%    \begin{macrocode}
\newcommand{\contestantName}[3][\BC{}\AA{\AAKeystroke{%
    if ( event.willCommit ) {\r\t
        var f = this.getField("jjContestantNameprint");\r\t
        if ( f != null ) f.value = event.value;\r
    }
    }}]{\textField[#1]{jjContestantName}{#2}{#3}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\timeStampFormat}
% The format for the time stamp. The format is that of the formatting string for the
% Acrobat JavaScript method \texttt{util.printd()}.
%    \begin{macrocode}
\newcommand{\timeStampFormat}[1]{\def\jjTimeStampFormat{#1}}
\timeStampFormat{mm-dd-yy, H:MM:ss.}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\AtBeginDocument{\redefineRespBoxActions}
%    \end{macrocode}
%    \begin{macro}{\enterNamePlease}
% When the forcredit option is used, an alert box opens when the contestant
% did not sign in. This is the message presented on that box.
%    \begin{macrocode}
\newcommand{\enterNamePlease}[1]{\def\jjEnterNamePlease{#1}}
\enterNamePlease{Please, enter your name on the first
    page before you begin the game!}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\defineInstructionPageGraphic}
%    \begin{macro}{\defineGameboardPageGraphic}
%    \begin{macro}{\defineQuestionPagesGraphic}
% Convenience commands for inserting graphics backgrounds on the instructions page,
% the game board page and on the question pages. The single parameter is the basename
% of a graphic file supported by the driver.
%    \begin{macrocode}
\let\jjInstructionPageBG\relax
\let\jjGameBoardPageBG\relax
\let\jjQuestionPagesBG\relax
\newcommand{\defineInstructionPageGraphic}[1]{%
    \def\jjInstructionPageBG{#1}}
\newcommand{\defineGameboardPageGraphic}[1]{\def\jjGameBoardPageBG{#1}}
\newcommand{\defineQuestionPagesGraphic}[1]{\def\jjQuestionPagesBG{#1}}
\newcommand{\instructionPageTemplate}{%
    \@ifundefined{jjInstructionPageBG}{}{%
    \edef\expand@templatename{\noexpand\template{\jjInstructionPageBG}}%
        \expand@templatename}}
\newcommand{\gameboardPageTemplate}{%
    \@ifundefined{jjGameBoardPageBG}{}{%
    \edef\expand@templatename{\noexpand\template{\jjGameBoardPageBG}}%
        \expand@templatename}}
\newcommand{\questionPagesTemplate}{%
    \@ifundefined{jjQuestionPagesBG}{}{%
    \edef\expand@templatename{\noexpand\template{\jjQuestionPagesBG}}%
        \expand@templatename}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\illegalAccessMsg}
%    \begin{macro}{\illegalAnswerTwiceMsg}
% Messages that appear in alert boxes when contestant acts illegally.
%    \begin{macrocode}
\newcommand{\illegalAccessMsg}[1]{\def\jjIllegalAccessMsg{#1}}
\illegalAccessMsg{You are peeking at this question.
    Choose a question from the game board first!
    You may want to start the game over now!}
\newcommand{\illegalAnswerTwiceMsg}[1]{\def\jjIllegalAnswerTwiceMsg{#1}}
\illegalAnswerTwiceMsg{Changing your answer is not allowed!}
\newcommand{\playeriWinnerMsg}[1]{\def\jjplayeriWinner{#1}}
\playeriWinnerMsg{\jjg@playeri\space is the winner!}
\newcommand{\playeriiWinnerMsg}[1]{\def\jjplayeriiWinner{#1}}
\playeriiWinnerMsg{\jjg@playerii\space is the winner!}
\newcommand{\gameTiedMsg}[1]{\def\jjgameTied{#1}}
\gameTiedMsg{It is all tied up! You are equally matched!}
\newcommand{\bothLosersMsg}[1]{\def\jjbothlosers{#1}}
\bothLosersMsg{You two either are not trying, or
    you do not know anything about the subject!}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
% \section{JavaScript Support}
%    \begin{macrocode}
\begin{insDLJS*}[qbrespond]{jjgdljs}
\begin{newsegment}{JJG: JavaScript to Control Jeopardy}
var _processLink=true;
var twoplayerGame=\twoplayerGame;
var whichPlayer=0;
if ( twoplayerGame ) {
    var reTrimSpaces=/^\s+|\s+$/g;
    var reInsertCommas=/\b\s+\b|\b\s+(?=\.)/g;
    var tpHighlightBorderColor="\@APtpHighlightBorderColor";
    var hightLightColor=%
    tpHighlightBorderColor.replace(reTrimSpaces,"").%
replace(reInsertCommas,",");
    var aHighlightColor = ("RGB,"+hightLightColor).split(",");
    this.getField("Total"+whichPlayer).strokeColor=%
aHighlightColor;
    var ckBx = this.getField("ckboxPlayer"+whichPlayer);
    if ( ckBx != null ) %
this.getField("ckboxPlayer"+whichPlayer).checkThisBox(0,true);
    this.dirty=false;
}
function qbrespond(ans,row,col)
{
   if (_processLink) {
       \ifjjnopeeking\else this.getField(""+row+col).hidden=true;\fi
        if ( eval("typeof pushCell"+row+col) == "undefined") {
            app.alert("\jjIllegalAccessMsg");
            return null;
        }
        if ( twoplayerGame )
            var Total = this.getField("Total"+whichPlayer);
        else
            var Total = this.getField("Total");
        var p = numQuestions*(col-1)+row-1;
        if (QAed.charAt(p)==0)
        {
            QAed = QAed.substring(0,p)+1+%
   QAed.substring(p+1,totalQuestions);
            if (ans==1)
            {
                this.getField(""+row+col+'R').hidden=false;
                Total.value += \scaleFactor*row*100;
                app.alert(aCM[nCM],3);
                if (++nCM > 6) nCM=0;
            }
            else
            {
                this.getField(""+row+col+'W').hidden=false;
                var f = this.getField(""+row+col)
                Total.value -= \scaleFactor*row*100;
                app.alert(aEM[nEM],3);
                if (++nEM > 6) nEM=0;
            }
%    \end{macrocode}
% 11/13/08. After we process this question, we hide the layer containing
% the question, and reset \texttt{pushCell+row+col} to \texttt{undefined} so the layer
% will not be made visible again by the open page action.
%    \begin{macrocode}
            if ( typeof toggleSetThisLayer == "function" ) {
                toggleSetThisLayer("q"+row+col,false);
                eval("pushCell"+row+col+"=undefined");
            }
            if ( twoplayerGame ) {
                this.getField("Total"+whichPlayer).strokeColor=["G",0]
                var ckBx = this.getField("ckboxPlayer"+whichPlayer);
                if (ckBx != null ) %
this.getField("ckboxPlayer"+whichPlayer).checkThisBox(0,false);
                whichPlayer = ( whichPlayer+1) \% 2;
                this.getField("Total"+whichPlayer).strokeColor=%
aHighlightColor;
                ckBx = this.getField("ckboxPlayer"+whichPlayer);
                if (ckBx != null ) %
this.getField("ckboxPlayer"+whichPlayer).checkThisBox(0,true);

            }
%    \end{macrocode}
% The end of the game. We see if the GraphPoobah has been reached, if a two person
% game we indicate who has won.
%    \begin{macrocode}
            if ( ++NumQAed>=totalQuestions ) {
                if  (Total.value>=Goal)
                    this.getField("GrandPoohbah").hidden=false;
                if ( twoplayerGame ) {
                    var player0 = this.getField("Total0");
                    var player1 = this.getField("Total1");
                    var player0Score = Number(player0.value);
                    var player1Score = Number(player1.value);
                    if ( player0Score > player1Score ) {
                        if ( player0Score <= 0 ) {
                            player0.strokeColor = ["RGB", 1, 0, 0];
                            player1.strokeColor = ["RGB", 1, 0, 0];
                            var timer=app.setTimeOut(
                                'app.alert("\jjbothlosers")',250);
                        } else {
                            player0.strokeColor = ["RGB", 0, .6, 0];
                            player1.strokeColor = ["G",0];
                            var timer=app.setTimeOut(
                                'app.alert("\jjplayeriWinner")',250);
                        }
                    }
                    else if ( player1Score > player0Score ) {
                        if ( player1Score <= 0 ) {
                            player0.strokeColor = ["RGB", 1, 0, 0];
                            player1.strokeColor = ["RGB", 1, 0, 0];
                            var timer=app.setTimeOut(
                                'app.alert("\jjbothlosers")',250);
                        } else {
                            player1.strokeColor = ["RGB", 0, .6, 0];
                            player0.strokeColor = ["G",0];
                            var timer=app.setTimeOut(
                                'app.alert("\jjplayeriiWinner")',250);
                        }
                    }
                    else {
                        if ( player1Score <= 0 ) {
                            player0.strokeColor = ["RGB", 1, 0, 0];
                            player1.strokeColor = ["RGB", 1, 0, 0];
                            var timer=app.setTimeOut(
                                'app.alert("\jjbothlosers")',250);
                        } else {
                            player0.strokeColor = ["RGB", 0, 0, 1];
                            player1.strokeColor = ["RGB", 0, 0, 1];
                            var timer=app.setTimeOut(
                            'app.alert("\jjgameTied")',250);
                        }
                    }
                }
            }
        }
        else
            app.alert("\jjIllegalAnswerTwiceMsg");
   }
   this.dirty=false;
}
var tsfield = this.getField("timestamp");
if ( tsfield != null )
    tsfield.value = util.printd("\jjTimeStampFormat", new Date());
this.dirty=false;
function makeNameReadOnly()
{
    var f = this.getField("jjContestantName");
    if ( (f != null) && !f.readonly ) f.readonly=true;
    this.dirty=false;
}
\end{newsegment}
\begin{newsegment}{JJG: Global Variables}
var numQuestions = \the\numQuestions;
var numCategories = \the\numCategories;
var Goal = \Goal;
var totalQuestions = numQuestions * numCategories;
var QAed = "";
for (var i=0; i< totalQuestions; i++) QAed +="0";
var nEM = 0;
var nCM = 0;
var NumQAed = 0;
this.dirty=false;
\end{newsegment}
\begin{JJLangEnglish}
\begin{newsegment}{JJG: Arrays for Jeopardy for English}
var aCM = new Array
(
    "That's Right!  Way to go, Kiddo!",
    "Wonderfully Done! Congrats!",
    "Very Good! Keep up the good work!",
    "Good, good, good, good!",
    "Gee, you're smart! Try a harder one!",
    "You're pretty sharp! Continuez, s'il vous pla\356t!",
    "You're the tops! But wait...try another."
)
var aEM = new Array
(
    "That's wrong! Sorry. Try Again.",
    "Error again.  Don't guess, I'm watching!",
    "Please!  Please!  Work it out first!",
    "An error has insinuated itself into your calculations.\n"
   +"Recalibrate your thinking!",
    "Bah! Humbug!  You're haunted by Errors!",
    "Try again.  This time with order and method.",
    "Wrong again!  Use your little gray cells!"
)
this.dirty=false;
\end{newsegment}
\end{JJLangEnglish}
\begin{JJLangGerman}
\begin{newsegment}{JJG: Arrays for Jeopardy for German}
var aCM = new Array
(
    "Richtig!  So ist's recht!",
    "Gut gemacht! Gratuliere!",
    "Sehr gut! Weiter so!",
    "Gut, gut, gut, gut!",
    "Du bist sehr clever! Jetzt versuch mal eine Schwierigere!",
    "Jawoll! Continuez, s'il vous pla\356t!",
    "Spitze! Auf geht's, zu einer weiteren Aufgabe!"
)
var aEM = new Array
(
    "Leider falsch!",
    "Schon wieder falsch!  Nicht raten!",
    "Bitte denk erst nach bevor Du auf die Antwort klickst!",
    "Ein Fehler hat sich eingeschlichen. Erst denken, dann ...!",
    "Ohje! So ein Quatsch!",
    "Versuch's nochmal.  Es ist noch nicht aller Tage Abend.",
    "Schon wieder falsch!  Nutz Deine kleine grauen Zellen!"
)
this.dirty=false;
\end{newsegment}
\end{JJLangGerman}
\begin{JJForCredit}
\begin{newsegment}{JJG: JS to support forcredit}
var noNameError, fname;
function forCreditClosePage()
{
    fname = this.getField("jjContestantName");
    if ( fname != null ) {
        var JJjsCode = "if ( fname.value.replace(/\s*/g, '') == '' ) {"
            + " if ( typeof closingJJ == 'undefined' ) {"
            + " app.alert({cMsg: '\jjEnterNamePlease', %
cTitle: 'AcroTeX eDucation Bundle'});"
            + " this.pageNum = 0;"
            + " } } else { fname.readonly = true; }";
        noNameError = app.setTimeOut(JJjsCode, 15);
    }
    this.dirty=false;
}
\end{newsegment}
\end{JJForCredit}
\end{insDLJS*}
%    \end{macrocode}
%    \begin{macrocode}
\AtEndOfClass{\thisPageAction{\JS{this.dirty=false;}}{}}
%</package>
%<*jjgpro>
\def\noPrintLayer#1{%
    \literalps@out{/Print [/Print] [(xb.#1)] AddASEvent}%
    \literalps@out{(xb.#1) <<
/Print<< /PrintState/OFF >> >> SetOCGUsage}%
}
\def\bJJGInsertLayer{\xBld{q\the\rownum\the\colnum}}
\def\eJJGInsertLayer{\eBld\noPrintLayer{q\the\rownum\the\colnum}}
\def\jjAdditionalJSActions{/Next <<\JS{%
    if ( typeof pushCell\the\rownum\the\colnum\space!= "undefined")
            toggleSetThisLayer("q\the\rownum\the\colnum",true);}>>}
\begin{execJS}{lockocgs}
var o = this.getOCGs();
for (var i = 0; i < o.length; i++)
    o[i].locked = true;
\end{execJS}
%</jjgpro>
%<*jjsecurity>
\begin{willClose}
var closingJJ = true;
\end{willClose}
\begin{addJSToPageClose}
forCreditClosePage();
\end{addJSToPageClose}
%</jjsecurity>
%<*package>
%</package>
%    \end{macrocode}
%  \Finale
\endinput
