diff options
Diffstat (limited to 'info/laan/paradigm/paradigm.gam')
-rw-r--r-- | info/laan/paradigm/paradigm.gam | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/info/laan/paradigm/paradigm.gam b/info/laan/paradigm/paradigm.gam new file mode 100644 index 0000000000..b22198c1e0 --- /dev/null +++ b/info/laan/paradigm/paradigm.gam @@ -0,0 +1,431 @@ +%August 1995, C.G. van der laan, cgl@rc.service.rug.nl +\input blue.tex +\loadtocmacros +%\tolerance500\hbadness=499\hfuzz=5pt +\parindent=1pc +\everyverbatim{\unmc} + +\bluetitle Paradigms: It's all in the game + +\bluesubtitle Dialogue with \TeX + +\blueissue \maps{96}1 + +\beginscript + +\bluehead BLUe's Design VI + +Hi folks. +In {\oldstyle1989} Greene contributed +`Playing in \TeX's mind' to TUG {\oldstyle89}. +Having fun with \TeX{} has been on my mind all the time. +Of late, I thought of tic-tac-too as an exercise in programming +dialogues in \TeX, in a simple and elegant way, with hopefully +some paradigms emerging, suited for educational purposes. +The play is simple but nevertheless entails essential aspects +of having a dialogue with \TeX. +Below I first strip the play to the essentials and +from there build the user-friendly, but otherwise modest, code. +At the end the \TeX ing peculiarities are summarized. + +\bluehead The play + +Tic-tac-too is played by two persons on a board with $3{\times}3$ fields. +Each player marks a field in turn and the one who has first +three marks in a row has won. +\def\data{+\cs o\cs+\rs \cs o\cs+\rs o\cs \cs +} +$$\ruled\btable\data$$ + +\bluehead Prototyping + +The dialogue with \TeX{} goes through the log file, also called transcript. + +The board is represented by the defs \cs{1}, \dots\cs{9} row-wise. +Each player owns a mark called \cs{markplayer} and \cs{markopponent}. +A user is prompted to input a value\Dash 1, 2, ... or 9\Dash +which indicates the field where to put his mark. +The program keeps track of the kind of mark, via a toggle. +To end the game the user can input 0. + +The above resulted in the following bare-to-the-bones +implementation of tic-tac-too. +\beginverbatim +\def\showboard{\immediate\write0{\1\2\3} + \immediate\write0{\4\5\6} + \immediate\write0{\7\8\9}} +\def\initialize{\def\1{-}\def\2{-}\def\3{-} + \def\4{-}\def\5{-}\def\6{-} + \def\7{-}\def\8{-}\def\9{-}} +\def\play{\initialize \loop\showboard + \ifx\mark\markplayer + \let\mark\markopponent\else + \let\mark\markplayer\fi + \immediate\write0{Supply index for \mark:} + \read0to\index \expandafter + \xdef\csname\index\endcsname{\mark} +\ifnum\index>0 \repeat}%end \play +\def\markplayer{+}\def\markopponent{o} +\endlinechar-1 %TB20.18 +\play \bye +!endverbatim +Remarks. +Because of the toggling of the \cs{mark} an \cs{xdef} was needed. + +One could code that the player and opponent are both +taking care of during each traversal of the loop. +However, apart from that it makes the code longer it is also clumsy, and +if careless one has to account for multiple exits of the loop. +I assumed states in which the loop is traversed. +The next steps are not for the faint of heart. + +\bluehead Real-life version + +Given the above prototype implementation we can refine, +add more bells-and-whistles. Basically these add-ons are in two directions +\bitem improve the user interface +\bitem let the program do more, such as deciding who has won. +\smallbreak + +\bluesubhead Improving the user interface + +Explain the conventions adopted, especially what the indices stand for. + +Always nice is to allow for personalization, i.e.\ the system prompt asks for +YOU, with your name. +This entails that the players must be asked to identify themselves and that +the toggling must be extended. + +Another feature is that the program prompts the remaining indices to choose from. + +And what about robustness? I decided not to implement robustness with respect +to lowercase or uppercase y or n, for example. +I also refrained from checking whether the supplied index is allowed.\ftn +{Not that difficult, actually, + because the set of allowed indices is maintained.} + +\bluesubhead Let the program do more + +The most important aspect is to add intelligence to the program to check +for a winner. + +The play restarts automatically + +\bluesubhead The code + +The board is represented by the defs +\cs{1}, \cs{2}, \dots \cs{9}, the $3{\times}3$ board row-wise. + + +The structure of the program is similar to the prototype, +with \cs{play} elaborated and the check \cs{checkforgameend} added. +\beginverbatim +\immediate\write0{Tic-tac-too + Aug 1995, cgl@rc.service.rug.nl} +\let\ea\expandafter +\newcount\k\newcount\value\newcount\checksum +\newif\ifsol +\newtoks\set %Index set +\def\del#1{\def\lop##1#1##2\pol{\set{##1##2}} + \ea\lop\the\set\pol} +% +\def\showboard{\immediate\write0{} +\immediate\write0{\1\2\3} +\immediate\write0{\4\5\6} +\immediate\write0{\7\8\9}} +% +%Initialization +\def\initialize{\set{123456789}\solfalse + \immediate\write0{New names of players? + (default \player\space and \opponent)} + \read0to\yorn + \if y\yorn + \immediate\write0{Name player} + \read0to\player + \immediate\write0{Name opponent} + \read0to\opponent + \fi\k0 + \loop\advance\k1 + \ea\def\csname\the\k\endcsname{-} + \ifnum\k<10 + \repeat + \immediate\write0{Empty board} +}%end initialization +%Test for solution +\def\sol#1#2#3{{\advance\count#1\count#2 + \advance\count#1\count#3 + \ifnum\count#1=\checksum \global\soltrue\fi}} +\def\checkforgameend{% +\sol123\ifsol\message{\who\space won}\k0 \else +\sol456\ifsol\message{\who\space won}\k0 \else +\sol789\ifsol\message{\who\space won}\k0 \else +\sol147\ifsol\message{\who\space won}\k0 \else +\sol258\ifsol\message{\who\space won}\k0 \else +\sol369\ifsol\message{\who\space won}\k0 \else +\sol159\ifsol\message{\who\space won}\k0 \else +\sol357\ifsol\message{\who\space won}\k0 \else +\fi\fi\fi\fi\fi\fi\fi\fi} +%Play +\def\play{\initialize\begingroup +\loop\showboard + \ifx\who\player\value-1 \checksum-3 + \let\who\opponent + \let\mark\markopponent + \else\value1 \checksum3 + \let\who\player + \let\mark\markplayer + \fi + \immediate\write0{\who, supply index + for \mark:} + \immediate\write0{Choose from: \the\set. + (0 terminates)} + \read0t\ea o\csname\who\endcsname + \k\csname\who\endcsname + \ea\xdef\csname\the\k\endcsname{\mark} + \count\k\value + \checkforgameend +\ifnum\k>0 \ea\del\ea{\the\k} +\repeat\endgroup +\immediate\write0{Play another game?} +\read0to\newplayyorn +\if y\newplayyorn\ea\play\fi}%end Play +% +%Defaults +\def\player{Kees} \def\opponent{Ina} +\def\markplayer{+} \def\markopponent{o} +% +\immediate\write0{} +\immediate\write0{Board numbering} +\immediate\write0{123} +\immediate\write0{456} +\immediate\write0{789} +% +\play \bye +!endverbatim +Remark. In order to get the personalized prompts \cs{Kees}, or \cs{Ina} +the following coding was needed. +\beginverbatim +\read0t\ea o\csname\who\endcsname +!endverbatim +The few lines that follow look unnecessary complex +but are entailed by the above. + +\bluehead What more? + +It is intrigueing to ponder about adding even more intelligence. +For example to let the game prompt for obligatory moves, +or to let the program terminate when draw is inevitable, that is when there +is no possible solution left. +In order to achieve this I chose to +\bitem maintain the set of possible solutions, instead of checking all possible + solutions\ftn{This entails that non-feasible candidates are eliminated + from the set of candidate solutions.} +\bitem update the set of solutions after each move, and + look for a solution or a draw +\bitem look for obligatory moves. +\smallbreak +With respect to robustness the input can be checked for whether the index +is allowed, casu quo a y(es) or n(o). + +\beginverbatim +\immediate\write0{Tic-tac-too + Aug 1995, cgl@rc.service.rug.nl} +\let\ea\expandafter \let\nx\noexpand +\newcount\k\newcount\kk +\newcount\value\newcount\checksum +\newcount\feasible\newcount\prompt +%Solution lines +\newcount\hi\newcount\hii\newcount\hiii +\newcount\vi\newcount\vii\newcount\viii +\newcount\di\newcount\dii +\newif\ifsol +\newif\ifnotfound +%Index set and deletion from index set +\newtoks\set %Index set +\def\del#1{\def\lop##1#1##2\pol{\set{##1##2}} + \ea\lop\the\set\pol} +% +\def\showboard{\immediate\write0{} +\immediate\write0{\1\2\3} +\immediate\write0{\4\5\6} +\immediate\write0{\7\8\9}} +% +%Initialization +\def\initialize{\set{123456789}\solfalse + \hi0 \hii0 \hiii0 \vi0 \vii0\viii0 + \di0 \dii0 \feasible8 \prompt0 +%Cell no associated with solution subsets +\ea\def\csname solset1\endcsname{% + \ls\hi\ls\vi\ls\di} +\ea\def\csname solset2\endcsname{% + \ls\hi\ls\vii} +\ea\def\csname solset3\endcsname{% + \ls\hi\ls\viii\ls\dii} +\ea\def\csname solset4\endcsname{% + \ls\hii\ls\vi} +\ea\def\csname solset5\endcsname{% + \ls\hii\ls\vii\ls\di\ls\dii} +\ea\def\csname solset6\endcsname{% + \ls\hii\ls\viii} +\ea\def\csname solset7\endcsname{% + \ls\hiii\ls\vi\ls\dii} +\ea\def\csname solset8\endcsname{% + \ls\hiii\ls\vii} +\ea\def\csname solset9\endcsname{% + \ls\hiii\ls\viii\ls\di} + \immediate\write0{New names of players? + (default \player\space and \opponent)} + \read0to\yorn + \if y\yorn + \immediate\write0{Name player} + \read0to\player + \immediate\write0{Name opponent} + \read0to\opponent + \fi\k0 + \loop\advance\k1 + \ea\def\csname\the\k\endcsname{-} + \ifnum\k<10 + \repeat + \immediate\write0{Empty board} +}%end initialization +% +%Test for solution +\def\ls#1{%#1 is a solution counter + \ifnum#1=0 \advance#1\value + \else\ifnum\sign#1=\value \advance#1\value + \else\advance\feasible-1 + \delete#1 %from solution sets + \ifnum\feasible=0 \showboard + \message{***Draw***}\k0 + \fi + \fi + \fi + %Check for solution + \ifnum#1=\checksum \showboard + \message{***\who*** won}\k0 + \fi} +% +\def\sign#1{\ifnum#1>0 1\else -1\fi} +\def\solsetk{\csname solset\the\k\endcsname} +% +\def\delete#1{%#1 is a solution counter to be + %deleted from all solution sets +{\kk0 +\def\ls##1{\ifx#1##1\else\nx\ls\nx##1\fi} +\loop\advance\kk1 +\ifnum\kk<10 +\ea\xdef\csname solset\the\kk\endcsname + {\csname solset\the\kk\endcsname} +\repeat}}%end \delete +% +\def\fifo#1{\ifx#1\ofif\ofif\fi + \process#1\fifo} +\def\ofif#1\fifo{\fi} +\def\lstry#1{%#1 is a counter denoting + %a solution + \ifnum#1=0 + \else\ifnum\sign#1=\value + \advance#1\value + %Check for solution + \ifnum#1=\checksum \global\prompt\k + \fi\fi + \fi} +\def\process#1{\ifnum\prompt=0 + {\k=#1 \let\ls\lstry \solsetk}\fi} +% +\def\readprocess#1{\if#1\csname\who\endcsname + \notfoundfalse\fi} +% +\def\readindex{{\let\process\readprocess + \loop\read0t\ea o\csname\who\endcsname + %\who value in \set? + \notfoundtrue\ea\fifo\the\set0\ofif + \ifnotfound + \immediate\write0{Please supply index + from \the \set} + \repeat + \global\k\csname\who\endcsname}} +% +%Play +\def\play{\initialize\begingroup +\loop\showboard%\show\ the\solset + \ifx\who\player\value-1 \checksum-3 + \let\who\opponent + \let\mark\markopponent + \else\value1 \checksum3 + \let\who\player + \let\mark\markplayer + \fi + %Is there a winning move? + %(Prefails obligatory move) + {\prompt0 \ea\fifo\the\set\ofif + \ifnum\prompt>0 \global\prompt0 \fi} + %The idea is that the player must see it + %him/herself. Of course the program knows + %about the winning move. + %Obligatory move? (criterion 0<\prompt (<10) + \ifnum\prompt>0 \immediate\write0{Sorry \who, + obligatory move \the\prompt}\k\prompt + \else + \immediate\write0{\who, supply index + for \mark:} + \immediate\write0{Choose from: \the\set. + (0 terminates)} + \readindex + \fi + %put mark on board + \ea\xdef\csname\the\k\endcsname{\mark} + %update solutions associated with \k + \solsetk +%k=0 is stopping criterion +\ifnum\k>0 \ea\del\ea{\the\k}% + %Look ahead for obligatory move: + % Can \who gain in next turn? + \prompt0 \ea\fifo\the\set\ofif +\repeat\endgroup +\immediate\write0{Play another game?} +\read0to\newplayyorn +\if y\newplayyorn\ea\play\fi}%end Play +% +%Defaults +\def\player{Kees} \def\opponent{Ina} +\def\markplayer{+} \def\markopponent{o} +%And off we go +\immediate\write0{} +\immediate\write0{Board numbering} +\immediate\write0{123} +\immediate\write0{456} +\immediate\write0{789} +\immediate\write0{} +\play \bye +!endverbatim + +\bluehead Is this all? + +Especially the code in the last section has become complex. Should we make it more complex? +For the moment I stopped. +However, it is tempting to increase the order to {\oldstyle4}, +and to extend the play to {\oldstyle3} dimensions. +My case rest. + +\bluehead Paradigms + +The following functionalites have been encountered and a way how to code +these in \TeX{} have been worked out. +\bitem loop traversal in various states +\bitem global Boolean, \cs{global}\cs{soltrue} +\bitem maintaining an index set, + deleting an element from a set +\bitem test for an empty set +\bitem high-level parameterization, for example + a personalized prompt within a state-dependent loop +\bitem \cs{read} with a {\em reference\/} to a prompt through\\ + |\read0t\ea o\csname\who\endcsname| +\bitem check on what is read is allowed. +\smallbreak +Starting from the bare-to-bones prototype it is quite something to arrive +at a solution, which carries some intelligence and robustness \smiley. +\medskip +Have fun, and all the best. +\makesignature +\pasteuptoc +\endscript |