%D \module %D [ file=deadstone, %D version=2007.07.31, %D title=\CONTEXT\ User Module, %D subtitle=Dead stone calculator for go, %D author=Wolfgang Schuster, %D email=schuster.wolfgang@googlemail.com, %D date=\currentdate, %D copyright=Public Domain] \writestatus{loading}{Context User Module / Dead stone calculator for go} \unprotect %D This is the \TEX\ version of the dead stone calculator for the %D go module. They are a copy of the original idea of the algorithm %D to find dead stones with a few modifications the author needed %D to make them work. %D \macros{clearboard} %D %D The \tex{clearboard} set all fields with a intial value of~0 for %D the empty fields and a value of~3 for the margins. The command %D can also be used to clear a board and remove all set values. \def\clearboard {\dorecurse{\numexpr\boardsize+\plustwo\relax} {\edef\boardrow{\the\numexpr\recurselevel-\plusone\relax}% \dorecurse{\numexpr\boardsize+\plustwo\relax} {\edef\boardcolumn{\the\numexpr\recurselevel-\plusone\relax}% \presetcurrentstone {\ifnum\boardrow=\zerocount \plusthree \else\ifnum\boardrow=\numexpr\boardsize+\plusone\relax \plusthree \else\ifnum\boardcolumn=\zerocount \plusthree \else\ifnum\boardcolumn=\numexpr\boardsize+\plusone\relax \plusthree \else \zerocount \fi\fi\fi\fi}}}} \let\laststone\plusone %D \macros{addstone} %D %D The \tex{addstone} is the used to place a stone on the board. %D The three arguments keeps the current row, the column and the %D stone color. The values for the row and the column have to be %D a number, the stone color has do be given with the two values %D \type{B} for black and \type{W} for white. \def\addstone(#1:#2:#3)% {\global\advance\stonecount\plusone \ifx#3B \global\let\laststone\plusone \else\ifx#3W \global\let\laststone\plustwo \fi\fi \setevalue{field:\number#1:\number#2}% {\ifx#3B \plusone \else\ifx#3W \plustwo \fi\fi:\number\stonecount}} \def\blackstone {\let\stone \plusone \let\enemy \plustwo \let\wall \plusthree \let\marked\plusfour \let\dead \plusseven} \def\whitestone {\let\stone \plustwo \let\enemy \plusone \let\wall \plusthree \let\marked\plusfive \let\dead \plusseven} \def\firstofcurrentstone #1:#2\relax{\number#1} \def\secondofcurrentstone#1:#2\relax{\number#2} \def\currentstone {\@EA\@EA\@EA\@EA\@EA\@EA\@EA\firstofcurrentstone\getvalue{field:\boardrow:\boardcolumn}\relax} \def\currentstonenumber {\@EA\@EA\@EA\@EA\@EA\@EA\@EA\secondofcurrentstone\getvalue{field:\boardrow:\boardcolumn}\relax} \def\leftstone {\@EA\@EA\@EA\@EA\@EA\@EA\@EA\firstofcurrentstone\getvalue{field:\boardrow:\the\numexpr\boardcolumn-\plusone\relax}\relax} \def\rightstone {\@EA\@EA\@EA\@EA\@EA\@EA\@EA\firstofcurrentstone\getvalue{field:\boardrow:\the\numexpr\boardcolumn+\plusone\relax}\relax} \def\topstone {\@EA\@EA\@EA\@EA\@EA\@EA\@EA\firstofcurrentstone\getvalue{field:\the\numexpr\boardrow-\plusone\relax:\boardcolumn}\relax} \def\bottomstone {\@EA\@EA\@EA\@EA\@EA\@EA\@EA\firstofcurrentstone\getvalue{field:\the\numexpr\boardrow+\plusone\relax:\boardcolumn}\relax} \newif\iftracingstones \def\doprocessstones {\markstones \iftracingstones\placeterminalboard\fi \deadstones \dorecurse\deadcount\checkstones \revertstones} \def\processtones {\ifcase\laststone \or\processwhitetones\processblackstones \or\processblackstones\processwhitetones \fi} \def\processblackstones {\blackstone \doprocessstones} \def\processwhitetones {\whitestone \doprocessstones} \def\setstonemark {\setcurrentstone{\ifcase\stone\or\plusfour\or\plusfive\else\plussix\fi}} %D \macros{markstones} %D %D The first internal command is \tex{markstones}, it set the stone value %D to marked if all consitions are true, otherwise the state will remain %D with the old value and we check the next one. \def\markbottomstone {\ifcase\bottomstone \or\setstonemark \or\setstonemark \or\setstonemark \fi} \def\markrightstone {\ifcase\rightstone \or\markbottomstone \or\markbottomstone \or\markbottomstone \fi} \def\marktopstone {\ifcase\topstone \or\ifnum\stone=\plusone\else\markrightstone\fi \or\ifnum\stone=\plustwo\else\markrightstone\fi \or\markrightstone \or\ifnum\stone=\plusone\relax\markrightstone\fi \or\ifnum\stone=\plustwo\relax\markrightstone\fi \fi} \def\markstones {\dorecurse\boardsize {\edef\boardrow{\recurselevel}% \dorecurse\boardsize {\edef\boardcolumn{\recurselevel}% \ifnum\currentstone=\stone \ifcase\leftstone \or\ifnum\stone=\plusone\else\marktopstone\fi \or\ifnum\stone=\plustwo\else\marktopstone\fi \or\marktopstone \or\ifnum\stone=\plusone\relax\marktopstone\fi \or\ifnum\stone=\plustwo\relax\marktopstone\fi \fi \fi}}} %D \macros{deadstones} %D %D The \tex{deadstones} macro check the marked stones from the last %D step for a dead state. We will now state from the right bottom and %D go to the left top corner. \def\deadleftstone {\ifcase\leftstone \or\ifnum\stone=\plusone\else\setdeadstone\fi \or\ifnum\stone=\plustwo\else\setdeadstone\fi \or\setdeadstone \or\setdeadstone \or\setdeadstone \fi} \def\deadbottomstone {\ifcase\bottomstone \or\ifnum\stone=\plusone\else\deadleftstone\fi \or\ifnum\stone=\plustwo\else\deadleftstone\fi \or\deadleftstone \or\resetdeadstone \or\resetdeadstone \or\resetdeadstone \or\deadleftstone \fi} \def\deadstones {\dostepwiserecurse\boardsize\plusone\minusone {\edef\boardrow{\recurselevel}% \dostepwiserecurse\boardsize\plusone\minusone {\edef\boardcolumn{\recurselevel}% \ifnum\currentstone=\marked \ifcase\rightstone \or\ifnum\stone=\plusone\else\deadbottomstone\fi \or\ifnum\stone=\plustwo\else\deadbottomstone\fi \or\deadbottomstone \or \or \or \or\deadbottomstone \fi \fi}}} %D \macros{revertstones} %D %D The \tex{revertstones} is called after all dead stones are and we will %D make the board ready for the next move. There are still fields with the %D value marked on the board and we have to make sure they get their normal %D state with the values for stone and enemy. \def\revertstones {\dorecurse\boardsize {\edef\boardrow{\recurselevel}% \dorecurse\boardsize {\edef\boardcolumn{\recurselevel}% \ifcase\currentstone \or \or \or \or\resetstone \or\resetstone \or \or\removedeadstone \fi}}} \def\presetcurrentstone#1% {\setxvalue{field:\boardrow:\boardcolumn}{\number#1:0}} \def\setcurrentstone#1% {\setxvalue{field:\boardrow:\boardcolumn}{\number#1:\number\currentstonenumber}} \def\setdeadstone {\setcurrentstone{\plusseven}} \def\resetdeadstone {\setcurrentstone{\ifcase\stone\or\plusone\or\plustwo\else\plussix\fi}} \let\resetstone\resetdeadstone \def\keepdeadstone {\setcurrentstone{\ifcase\stone\or\plusseven\or\plusseven\else\plussix\fi}} \def\removedeadstone {\appendtodeadstonelist \setcurrentstone{\zerocount}} %D \macros{deadblackstones,deadwhitestones} %D %D The dead stones we found in one run are saved in two commalists, their names %D are \tex{deadblacktones} and \tex{deadwhitestones}. They can be used by users %D to their positions and numbers in their own macros. \def\appendtodeadstonelist {\ifcase\stone \or\expanded{\appendtocommalist{{\boardrow:\boardcolumn:\number\stone:\currentstonenumber}}}\deadblackstones \or\expanded{\appendtocommalist{{\boardrow:\boardcolumn:\number\stone:\currentstonenumber}}}\deadwhitestones \fi} \def\cleardeadstonelist {\let\deadblackstones\empty \let\deadwhitestones\empty} %D \macros{checkstones} %D %D As one of the first examples has shown sometimes still living stones %D get the value dead in the last step and we have to check for such %D a case. Tests has shown this need to be done at least two times and %D make sure this can be increased without problems users can change this %D with the counter \tex{deadcount} but you should also know increasing %D this counter will result in longer processing time. \def\checkdeadstones {\ifcase\leftstone \or\ifnum\stone=\plusone\relax\resetdeadstone\else\checktopdeadstone\fi \or\ifnum\stone=\plustwo\relax\resetdeadstone\else\checktopdeadstone\fi \or\checktopdeadstone \or\resetdeadstone \or\resetdeadstone \or\resetdeadstone \or\checktopdeadstone \fi} \def\checktopdeadstone {\ifcase\topstone \or\ifnum\stone=\plusone\relax\resetdeadstone\else\checkrightdeadstone\fi \or\ifnum\stone=\plustwo\relax\resetdeadstone\else\checkrightdeadstone\fi \or\checkrightdeadstone \or\resetdeadstone \or\resetdeadstone \or\resetdeadstone \or\checkrightdeadstone \fi} \def\checkrightdeadstone {\ifcase\rightstone \or\ifnum\stone=\plusone\relax\resetdeadstone\else\checkbottomdeadstone\fi \or\ifnum\stone=\plustwo\relax\resetdeadstone\else\checkbottomdeadstone\fi \or\checkbottomdeadstone \or\resetdeadstone \or\resetdeadstone \or\resetdeadstone \or\checkbottomdeadstone \fi} \def\checkbottomdeadstone {\ifcase\bottomstone \or\ifnum\stone=\plusone\relax\resetdeadstone\else\keepdeadstone\fi \or\ifnum\stone=\plustwo\relax\resetdeadstone\else\keepdeadstone\fi \or\keepdeadstone \or\resetdeadstone \or\resetdeadstone \or\resetdeadstone \or\keepdeadstone \fi} \def\checkstones {\dorecurse\boardsize {\edef\boardrow{\recurselevel}% \dorecurse\boardsize {\edef\boardcolumn{\recurselevel}% \ifcase\currentstone \or \or \or \or\ifnum\stone=\plusone\relax\resetdeadstone\fi \or\ifnum\stone=\plustwo\relax\resetdeadstone\fi \or \or\checkdeadstones \fi}}} \protect \endinput